diff --git a/docker/Dockerfile b/docker/Dockerfile index af2931fe..5e1198b1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -136,7 +136,7 @@ FROM base_pfring as conjure COPY sysconfig/conjure.conf /opt/conjure/sysconfig/ COPY scripts/ /opt/conjure/scripts/ -RUN apt update && apt install -yq libzmq3-dev iproute2 +RUN apt update && apt install -yq libzmq3-dev iproute2 ethtool COPY --from=dev_img /opt/conjure/bin/ /opt/conjure/bin/ # ENTRYPOINT /bin/bash diff --git a/docker/README.md b/docker/README.md index fa38c8f1..be3243a1 100644 --- a/docker/README.md +++ b/docker/README.md @@ -154,7 +154,7 @@ CJ_IP4_ADDR=127.0.0.1 CJ_IP6_ADDR=[::1] # application -CJ_STATION_CONFIG=/var/lib/conjure/application_config.toml +CJ_STATION_CONFIG=/var/lib/conjure/app_config.toml PHANTOM_SUBNET_LOCATION=/var/lib/conjure/phantom_subnets.toml # registration server @@ -269,4 +269,4 @@ For detailed and up-to-date installation instructions refer to official ntop doc - Encountered err when creating Reg: Failed to select phantom IP address: generation number not recognized - Make sure conjure/docker/phantom_subnets.toml contains the client's generations - - Can be caused by clients using API trying to connect, since API is enabled by default. Can be disabled by removing `[[connect_sockets]]` entry for the API from `conjure/application/config.toml` + - Can be caused by clients using API trying to connect, since API is enabled by default. Can be disabled by removing `[[connect_sockets]]` entry for the API from `cmd/application/app_config.toml` diff --git a/go.mod b/go.mod index ee99955c..60385a47 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/BurntSushi/toml v1.3.2 github.com/flynn/noise v1.0.0 github.com/go-redis/redis/v8 v8.11.5 + github.com/golang/protobuf v1.5.3 github.com/google/gopacket v1.1.19 github.com/gorilla/mux v1.8.0 github.com/hashicorp/golang-lru v1.0.2 @@ -20,7 +21,6 @@ require ( github.com/pion/stun v0.6.1 github.com/pion/transport/v2 v2.2.3 github.com/refraction-networking/ed25519 v0.1.2 - github.com/refraction-networking/gotapdance v1.7.1 github.com/refraction-networking/obfs4 v0.1.2 github.com/refraction-networking/utls v1.3.3 github.com/sirupsen/logrus v1.9.3 @@ -40,11 +40,11 @@ require ( github.com/dchest/siphash v1.2.3 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gaukas/godicttls v0.0.4 // indirect - github.com/klauspost/compress v1.16.7 // indirect - github.com/onsi/gomega v1.27.6 // indirect - github.com/oschwald/maxminddb-golang v1.12.0 // indirect + github.com/klauspost/compress v1.17.0 // indirect + github.com/oschwald/maxminddb-golang v1.11.0 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/refraction-networking/gotapdance v1.7.3 // indirect github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 // indirect golang.org/x/text v0.13.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -55,3 +55,5 @@ replace github.com/pion/dtls/v2 => github.com/mingyech/dtls/v2 v2.0.0 replace github.com/pion/transport/v2 => github.com/mingyech/transport/v2 v2.0.0 replace github.com/refraction-networking/gotapdance => github.com/refraction-networking/gotapdance v1.7.3-0.20230914182507-7d8ccbce6eb2 + +replace github.com/refraction-networking/utls => ../utls \ No newline at end of file diff --git a/go.sum b/go.sum index e9958738..52fe8a72 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67d github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -27,8 +29,8 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= -github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -46,12 +48,11 @@ github.com/mroth/weightedrand v1.0.0 h1:V8JeHChvl2MP1sAoXq4brElOcza+jxLkRuwvtQu8 github.com/mroth/weightedrand v1.0.0/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= -github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc= github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y= -github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs= -github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY= +github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0= +github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg= github.com/pebbe/zmq4 v1.2.10 h1:wQkqRZ3CZeABIeidr3e8uQZMMH5YAykA/WN0L5zkd1c= github.com/pebbe/zmq4 v1.2.10/go.mod h1:nqnPueOapVhE2wItZ0uOErngczsJdLOGkebMxaO8r48= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -73,6 +74,8 @@ github.com/refraction-networking/gotapdance v1.7.3-0.20230914182507-7d8ccbce6eb2 github.com/refraction-networking/gotapdance v1.7.3-0.20230914182507-7d8ccbce6eb2/go.mod h1:svhsxN8LGv3FSL1RKLFXG74tWEXQ8m1xb9rFEZF2abk= github.com/refraction-networking/obfs4 v0.1.2 h1:J842O4fGSkd2W8ogYj0KN6gqVVY+Cpqodw9qFGL7wVU= github.com/refraction-networking/obfs4 v0.1.2/go.mod h1:wAl/+gWiLsrcykJA3nKJHx89f5/gXGM8UKvty7+mvbM= +github.com/refraction-networking/utls v1.3.3-0.20230716160308-d1757c6b7716 h1:FXRAIzKKDmI/eYkfBW+1Lvg97Vc7rx7ia0xKBEY98BI= +github.com/refraction-networking/utls v1.3.3-0.20230716160308-d1757c6b7716/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvjQpqP7L2vcm/9KUfm/E= github.com/refraction-networking/utls v1.3.3 h1:f/TBLX7KBciRyFH3bwupp+CE4fzoYKCirhdRcC490sw= github.com/refraction-networking/utls v1.3.3/go.mod h1:DlecWW1LMlMJu+9qpzzQqdHDT/C2LAe03EdpLUz/RL8= github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 h1:ML7ZNtcln5UBo5Wv7RIv9Xg3Pr5VuRCWLFXEwda54Y4= @@ -150,6 +153,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o= google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -157,6 +161,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.work.sum b/go.work.sum index 78fd0c56..721c6ca8 100644 --- a/go.work.sum +++ b/go.work.sum @@ -20,6 +20,7 @@ github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNu github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y= diff --git a/internal/testutils/tests.go b/internal/testutils/tests.go index 961226a4..d7934b28 100644 --- a/internal/testutils/tests.go +++ b/internal/testutils/tests.go @@ -9,6 +9,7 @@ import ( "github.com/refraction-networking/conjure/internal/conjurepath" "github.com/refraction-networking/conjure/pkg/core" dd "github.com/refraction-networking/conjure/pkg/station/lib" + "github.com/refraction-networking/conjure/pkg/transports" pb "github.com/refraction-networking/conjure/proto" "google.golang.org/grpc/test/bufconn" "google.golang.org/protobuf/reflect/protoreflect" @@ -25,7 +26,7 @@ var TestSubnetPath = conjurepath.Root + "/internal/test_assets/phantom_subnets.t // SetupPhantomConnections registers one session with the provided transport and // registration manager using a pre-determined kay and phantom subnet file. -func SetupPhantomConnections(manager *dd.RegistrationManager, transport pb.TransportType, params protoreflect.ProtoMessage, libver uint) (clientToPhantom net.Conn, serverFromPhantom net.Conn, reg *dd.DecoyRegistration) { +func SetupPhantomConnections(manager *dd.RegistrationManager, transport pb.TransportType, params protoreflect.ProtoMessage, libver uint) (clientToPhantom net.Conn, serverFromPhantom net.Conn, reg transports.Registration) { return SetupPhantomConnectionsSecret(manager, transport, params, SharedSecret, libver, TestSubnetPath) } diff --git a/internal/transport_integration_test.go b/internal/transport_integration_test.go index dccdca71..022e55f7 100644 --- a/internal/transport_integration_test.go +++ b/internal/transport_integration_test.go @@ -22,6 +22,7 @@ import ( "github.com/refraction-networking/conjure/pkg/transports/wrapping/min" "github.com/refraction-networking/conjure/pkg/transports/wrapping/obfs4" "github.com/refraction-networking/conjure/pkg/transports/wrapping/prefix" + "github.com/refraction-networking/conjure/pkg/transports/wrapping/utls" pb "github.com/refraction-networking/conjure/proto" "github.com/refraction-networking/ed25519" "github.com/refraction-networking/ed25519/extra25519" @@ -76,6 +77,15 @@ func TestTransportsEndToEnd(t *testing.T) { &min.ClientTransport{}, genericParamPermutations, }, + { + func(privKey [32]byte) lib.WrappingTransport { + tr, err := utls.New(privKey) + require.Nil(t, err) + return tr + }, + &utls.ClientTransport{}, + utlsClientParamPermutations, + }, } for _, testCase := range testCases { t.Run(testCase.clientTransport.Name(), func(t *testing.T) { @@ -223,7 +233,7 @@ func (p *genericParams) String() string { return fmt.Sprintf("randDstPort: %t", p.GetRandomizeDstPort()) } -// ClientParamPermutations returns a list of client parameters for inclusions in tests that require +// prefixClientParamPermutations returns a list of client parameters for inclusions in tests that require // variance. func prefixClientParamPermutations() []TestParams { paramSet := []TestParams{} @@ -242,3 +252,20 @@ func prefixClientParamPermutations() []TestParams { } return paramSet } + +// utlsClientParamPermutations returns a list of client parameters for inclusions in tests that require +// variance. +func utlsClientParamPermutations() []TestParams { + paramSet := []TestParams{} + for _, chID := range []int32{0, 1, 2, 3, 4, 5} { + for _, rand := range []bool{true, false} { + var p int32 = int32(chID) + params := &utls.ClientParams{ + ClientHelloID: p, + RandomizeDstPort: rand, + } + paramSet = append(paramSet, params) + } + } + return paramSet +} diff --git a/pkg/transports/wrapping/min/min_test.go b/pkg/transports/wrapping/min/min_test.go index fcffe5d1..c492fb68 100644 --- a/pkg/transports/wrapping/min/min_test.go +++ b/pkg/transports/wrapping/min/min_test.go @@ -29,7 +29,10 @@ func TestSuccessfulWrap(t *testing.T) { defer sfp.Close() require.NotNil(t, reg) - hmacID := core.ConjureHMAC(reg.Keys.SharedSecret, "MinTrasportHMACString") + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + + hmacID := core.ConjureHMAC(reg.SharedSecret(), "MinTrasportHMACString") message := []byte(`test message!`) _, err := c2p.Write(append(hmacID, message...)) @@ -40,7 +43,7 @@ func TestSuccessfulWrap(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, wrapped, err := transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, wrapped, err := transport.WrapConnection(&buffer, sfp, *phantom, manager) require.Nil(t, err, "error getting wrapped connection") received := make([]byte, len(message)) @@ -56,6 +59,9 @@ func TestUnsuccessfulWrap(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + // No real reason for sending the shared secret; it's just 32 bytes // (same length as HMAC ID) that should have no significance. _, err := c2p.Write(tests.SharedSecret) @@ -66,7 +72,7 @@ func TestUnsuccessfulWrap(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } @@ -80,6 +86,9 @@ func TestTryAgain(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + var buf [32]byte var buffer bytes.Buffer for _, b := range tests.SharedSecret[:31] { @@ -89,7 +98,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrTryAgain) { t.Fatalf("expected ErrTryAgain, got %v", err) } @@ -100,7 +109,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } diff --git a/pkg/transports/wrapping/obfs4/obfs4_test.go b/pkg/transports/wrapping/obfs4/obfs4_test.go index 84aab1f3..9ff402b8 100644 --- a/pkg/transports/wrapping/obfs4/obfs4_test.go +++ b/pkg/transports/wrapping/obfs4/obfs4_test.go @@ -64,9 +64,12 @@ func TestSuccessfulWrap(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + wrappedc2p := make(chan net.Conn) stateDir := "" - keys := reg.Keys.TransportKeys.(Obfs4Keys) + keys := reg.TransportKeys().(Obfs4Keys) go wrapConnection(c2p, keys.NodeID.Hex(), keys.PublicKey.Hex(), wrappedc2p, stateDir) var buf [4096]byte @@ -76,7 +79,7 @@ func TestSuccessfulWrap(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, wrappedsfp, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, wrappedsfp, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if errors.Is(err, transports.ErrTryAgain) { continue } else if err != nil { @@ -191,6 +194,9 @@ func TestUnsuccessfulWrap(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + _, err = io.Copy(c2p, io.LimitReader(rand.New(rand.NewSource(0)), 8192)) require.Nil(t, err) @@ -199,7 +205,7 @@ func TestUnsuccessfulWrap(t *testing.T) { n, _ := io.ReadFull(sfp, buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } @@ -213,6 +219,9 @@ func TestTryAgain(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + r := rand.New(rand.NewSource(0)) var buf [8192]byte var buffer bytes.Buffer @@ -225,7 +234,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrTryAgain) { t.Fatalf("expected ErrTryAgain, got %v", err) } @@ -236,7 +245,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } diff --git a/pkg/transports/wrapping/prefix/prefix_test.go b/pkg/transports/wrapping/prefix/prefix_test.go index 8016c5c2..02d22f9e 100644 --- a/pkg/transports/wrapping/prefix/prefix_test.go +++ b/pkg/transports/wrapping/prefix/prefix_test.go @@ -52,7 +52,10 @@ func TestSuccessfulWrap(t *testing.T) { defer sfp.Close() require.NotNil(t, reg) - hmacID := core.ConjureHMAC(reg.Keys.SharedSecret, "PrefixTransportHMACString") + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + + hmacID := core.ConjureHMAC(reg.SharedSecret(), "PrefixTransportHMACString") for id, prefix := range defaultPrefixes { // if prefix.fn != nil { @@ -70,7 +73,7 @@ func TestSuccessfulWrap(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer := bytes.NewBuffer(buf[:n]) - _, wrapped, err := transport.WrapConnection(buffer, sfp, reg.PhantomIp, manager) + _, wrapped, err := transport.WrapConnection(buffer, sfp, *phantom, manager) if id != idx { require.ErrorIs(t, err, ErrIncorrectPrefix) continue @@ -102,6 +105,9 @@ func TestUnsuccessfulWrap(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + // Write enough bytes that it can tell the message is definitively not associated with any prefix randMsg := make([]byte, 100) n, _ := rand.Read(randMsg) @@ -114,7 +120,7 @@ func TestUnsuccessfulWrap(t *testing.T) { buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } @@ -136,6 +142,9 @@ func TestTryAgain(t *testing.T) { defer c2p.Close() defer sfp.Close() + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + msgBuf := make([]byte, 100) // Start out matching an expected prefix // Should match Min prefix until 64 bytes and GET prefix until 64+16 bytes @@ -150,7 +159,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrTryAgain) { t.Fatalf("expected ErrTryAgain, got %v", err) } @@ -161,7 +170,7 @@ func TestTryAgain(t *testing.T) { n, _ := sfp.Read(buf[:]) buffer.Write(buf[:n]) - _, _, err = transport.WrapConnection(&buffer, sfp, reg.PhantomIp, manager) + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) if !errors.Is(err, transports.ErrNotTransport) { t.Fatalf("expected ErrNotTransport, got %v", err) } @@ -434,6 +443,9 @@ func TestPrefixEndToEnd(t *testing.T) { require.NotNil(t, reg) sch := make(chan struct{}, 1) + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + go func() { var c net.Conn var err error @@ -450,7 +462,7 @@ func TestPrefixEndToEnd(t *testing.T) { } received.Write(buf[:n]) - _, c, err = transport.WrapConnection(&received, sfp, reg.PhantomIp, manager) + _, c, err = transport.WrapConnection(&received, sfp, *phantom, manager) if err == nil { break } else if !errors.Is(err, transports.ErrTryAgain) { @@ -471,7 +483,7 @@ func TestPrefixEndToEnd(t *testing.T) { clientPrefix, err := TryFromID(PrefixID(p)) require.Nil(t, err) ClientTransport := &ClientTransport{Prefix: clientPrefix, parameters: params} - err = ClientTransport.PrepareKeys(curve25519Public, reg.Keys.SharedSecret, reg.Keys.TransportReader) + err = ClientTransport.PrepareKeys(curve25519Public, reg.SharedSecret(), reg.TransportReader()) require.Nil(t, err) clientConn, err := ClientTransport.WrapConn(c2p) require.Nil(t, err, "error getting wrapped connection") diff --git a/pkg/transports/wrapping/utls/certs.go b/pkg/transports/wrapping/utls/certs.go new file mode 100644 index 00000000..15f4fdfb --- /dev/null +++ b/pkg/transports/wrapping/utls/certs.go @@ -0,0 +1,205 @@ +package utls + +import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "crypto/x509/pkix" + "encoding/hex" + "fmt" + "io" + "math/big" + "time" + + tls "github.com/refraction-networking/utls" + "golang.org/x/crypto/hkdf" +) + +func publicKey(priv any) any { + switch k := priv.(type) { + case *rsa.PrivateKey: + return &k.PublicKey + case *ecdsa.PrivateKey: + return &k.PublicKey + case ed25519.PrivateKey: + return k.Public().(ed25519.PublicKey) + default: + return nil + } +} + +func genKey(r io.Reader, ecdsaCurve string, ed25519Key bool, rsaBits int) (priv any, err error) { + switch ecdsaCurve { + case "": + if ed25519Key { + _, priv, err = ed25519.GenerateKey(r) + } else { + priv, err = rsa.GenerateKey(r, rsaBits) + } + case "P224": + priv, err = ecdsa.GenerateKey(elliptic.P224(), r) + case "P256": + priv, err = ecdsa.GenerateKey(elliptic.P256(), r) + case "P384": + priv, err = ecdsa.GenerateKey(elliptic.P384(), r) + case "P521": + priv, err = ecdsa.GenerateKey(elliptic.P521(), r) + default: + err = fmt.Errorf("Unrecognized elliptic curve: %q", ecdsaCurve) + } + if err != nil { + err = fmt.Errorf("Failed to generate private key: %v", err) + } + return +} + +type not1Reader struct { + r io.Reader +} + +func (n1r *not1Reader) Read(p []byte) (n int, err error) { + + if len(p) == 1 { + // err = io.EOF + return 1, nil + } + + return n1r.r.Read(p) +} + +// func clientHelloRandomFromSeed(seed []byte) ([handshake.RandomBytesLength]byte, error) { +// randSource := hkdf.New(sha256.New, seed, nil, nil) +// randomBytes := [handshake.RandomBytesLength]byte{} + +// _, err := io.ReadFull(randSource, randomBytes[:]) +// if err != nil { +// return [handshake.RandomBytesLength]byte{}, err +// } + +// return randomBytes, nil +// } + +// getPrivkey creates ECDSA private key used in DTLS Certificates +func getPrivkey(seed []byte) (*ecdsa.PrivateKey, error) { + randSource := hkdf.New(sha256.New, seed, nil, nil) + + privkey, err := ecdsa.GenerateKey(elliptic.P256(), ¬1Reader{r: randSource}) + if err != nil { + return &ecdsa.PrivateKey{}, err + } + return privkey, nil +} + +// getX509Tpl creates x509 template for x509 Certificates generation used in DTLS Certificates. +func getX509Tpl(seed []byte) (*x509.Certificate, error) { + randSource := hkdf.New(sha256.New, seed, nil, nil) + + maxBigInt := new(big.Int) + maxBigInt.Exp(big.NewInt(2), big.NewInt(130), nil).Sub(maxBigInt, big.NewInt(1)) + serialNumber, err := rand.Int(randSource, maxBigInt) + if err != nil { + return &x509.Certificate{}, err + } + + // Make the Certificate valid from UTC today till next month. + utcNow := time.Now().UTC() + validFrom := time.Date(utcNow.Year(), utcNow.Month(), utcNow.Day(), 0, 0, 0, 0, time.UTC) + validUntil := validFrom.AddDate(0, 1, 0) + + // random CN + cnBytes := make([]byte, 8) + _, err = io.ReadFull(randSource, cnBytes) + if err != nil { + return &x509.Certificate{}, fmt.Errorf("failed to generate common name: %w", err) + } + cn := hex.EncodeToString(cnBytes) + + return &x509.Certificate{ + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageClientAuth, + x509.ExtKeyUsageServerAuth, + }, + BasicConstraintsValid: true, + NotBefore: validFrom, + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + NotAfter: validUntil, + SerialNumber: serialNumber, + SignatureAlgorithm: x509.ECDSAWithSHA256, + Version: 2, + Subject: pkix.Name{CommonName: cn}, + DNSNames: []string{cn}, + IsCA: true, + }, nil +} + +func newCertificate(seed []byte) (*tls.Certificate, error) { + privkey, err := getPrivkey(seed) + if err != nil { + return &tls.Certificate{}, err + } + + tpl, err := getX509Tpl(seed) + if err != nil { + return &tls.Certificate{}, err + } + + randSource := hkdf.New(sha256.New, seed, nil, nil) + + certDER, err := x509.CreateCertificate(randSource, tpl, tpl, privkey.Public(), privkey) + if err != nil { + return &tls.Certificate{}, err + } + + return &tls.Certificate{ + Certificate: [][]byte{certDER}, + PrivateKey: privkey, + }, nil +} + +func buildSymmetricVerifier(psk []byte) func(cs tls.ConnectionState) error { + return func(cs tls.ConnectionState) error { + expected, err := newCertificate(psk) + if err != nil { + return fmt.Errorf("error creating expected certificate: %w", err) + } + // expected.Leaf.KeyUsage |= x509.KeyUsageCertSign + + if !cs.DidResume { + return fmt.Errorf("expected session resumption") + } + + if len(cs.PeerCertificates) != 1 { + return fmt.Errorf("expected 1 peer certificate, got %v", len(cs.PeerCertificates)) + } + + if len(expected.Certificate) != 1 { + return fmt.Errorf("expected 1 pre-established cert, got %v", len(expected.Certificate)) + } + + expectedCert, err := x509.ParseCertificate(expected.Certificate[0]) + if err != nil { + return fmt.Errorf("error parsing peer certificate: %v", err) + } + + err = verifyCert(cs.PeerCertificates[0], expectedCert) + if err != nil { + return fmt.Errorf("error verifying peer certificate: %v", err) + } + + return nil + } +} + +func verifyCert(incoming, correct *x509.Certificate) error { + correct.KeyUsage |= x509.KeyUsageCertSign // CheckSignature have requirements for the KeyUsage field + err := incoming.CheckSignatureFrom(correct) + if err != nil { + return fmt.Errorf("error verifying certificate signature: %v", err) + } + + return nil +} diff --git a/pkg/transports/wrapping/utls/certs_test.go b/pkg/transports/wrapping/utls/certs_test.go new file mode 100644 index 00000000..2cf82004 --- /dev/null +++ b/pkg/transports/wrapping/utls/certs_test.go @@ -0,0 +1,103 @@ +package utls + +// func Test_generateKeyAndCert(t *testing.T) { +// // get our ca and server certificate +// serverTLSConf, clientTLSConf, err := certSetup() +// if err != nil { +// panic(err) +// } + +// srv := &http.Server{ +// TLSConfig: &serverTLSConf, +// ReadTimeout: time.Minute, +// WriteTimeout: time.Minute, +// } +// go func() { +// err := srv.ListenAndServeTLS("", "") +// if err != nil { +// t.Fail() +// return +// } +// }() + +// // set up the httptest.Server using our certificate signed by our CA +// server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// fmt.Fprintln(w, "success!") +// })) +// server.TLS = serverTLSConf +// server.StartTLS() +// defer server.Close() + +// // communicate with the server using an http.Client configured to trust our CA +// transport := &http.Transport{ +// TLSClientConfig: clientTLSConf, +// } +// http := http.Client{ +// Transport: transport, +// } +// resp, err := http.Get(server.URL) +// if err != nil { +// panic(err) +// } + +// // verify the response +// respBodyBytes, err := ioutil.ReadAll(resp.Body) +// if err != nil { +// panic(err) +// } +// body := strings.TrimSpace(string(respBodyBytes[:])) +// require.Equal(t, "success!", body) +// } + +// func readerFromKey(key [32]byte) io.Reader { +// hkdfReader := hkdf.New(sha256.New, key[:], []byte("cert testing string"), nil) +// return hkdfReader +// } + +// func TestUTLSMakeConnWithCompleteHandshake(t *testing.T) { +// serverConn, clientConn := net.Pipe() + +// masterSecret := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47} +// clientRandom := []byte{40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71} +// serverRandom := []byte{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111} +// serverTlS := tls.MakeConnWithCompleteHandshake(serverConn, tls.VersionTLS12, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +// masterSecret, clientRandom, serverRandom, false) +// clientTlS := tls.MakeConnWithCompleteHandshake(clientConn, tls.VersionTLS12, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, +// masterSecret, clientRandom, serverRandom, true) + +// clientMsg := []byte("Hello, world!") +// serverMsg := []byte("Test response!") + +// go func() { +// clientTlS.Write(clientMsg) +// resp := make([]byte, 20) +// read, err := clientTlS.Read(resp) +// if !bytes.Equal(resp[:read], serverMsg) { +// t.Errorf("client expected to receive: %v, got %v\n", +// serverMsg, resp[:read]) +// } +// if err != nil { +// t.Errorf("error reading client: %+v\n", err) +// } +// clientConn.Close() +// }() + +// buf := make([]byte, 20) +// read, err := serverTlS.Read(buf) +// if !bytes.Equal(buf[:read], clientMsg) { +// t.Errorf("server expected to receive: %v, got %v\n", +// clientMsg, buf[:read]) +// } +// if err != nil { +// t.Errorf("error reading client: %+v\n", err) +// } + +// serverTlS.Write(serverMsg) +// } + +// func TestUTLSMakeConnWithCompleteHandshake(t *testing.T) { +// config := tls.Config{} +// clientCert, serverCert, err := certsFromSeed(config.PSK) +// require.Nil(t, err) + +// } diff --git a/pkg/transports/wrapping/utls/client.go b/pkg/transports/wrapping/utls/client.go new file mode 100644 index 00000000..1e3dfff1 --- /dev/null +++ b/pkg/transports/wrapping/utls/client.go @@ -0,0 +1,204 @@ +package utls + +import ( + "context" + "crypto/rand" + "fmt" + "io" + "net" + + "github.com/refraction-networking/conjure/pkg/core" + "github.com/refraction-networking/conjure/pkg/transports" + pb "github.com/refraction-networking/conjure/proto" + tls "github.com/refraction-networking/utls" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" +) + +// ClientParams is a struct that can be used to set parameters for the client side +// without relying on the raw protobuf. +type ClientParams struct { + // RandomizeDstPort indicates whether the client should randomize the destination port + RandomizeDstPort bool + + // SNI is the server name indication to send to the server + SNI string + + // ClientHelloID allows the user to choose the uTLS client hello fingerprint after which + // to model the TLS client hello that open's their session. + ClientHelloID int32 +} + +func (cp *ClientParams) GetParams() any { + return &pb.UTLSTransportParams{ + RandomizeDstPort: proto.Bool(cp.RandomizeDstPort), + Sni: []byte(cp.SNI), + ChId: proto.Int32(cp.ClientHelloID), + } +} + +func (cp *ClientParams) String() string { + return fmt.Sprintf("RandomizeDstPort: %t, SNI: %s, CH_ID: %d", cp.RandomizeDstPort, cp.SNI, cp.ClientHelloID) +} + +// ClientTransport implements the client side transport interface for the Min transport. The +// significant difference is that there is an instance of this structure per client session, where +// the station side Transport struct has one instance to be re-used for all sessions. +// +// External libraries must set parameters through SetParams using uTLSTransportParams. +type ClientTransport struct { + // Parameters are fields that will be shared with the station in the registration + Parameters *pb.UTLSTransportParams + + // // state tracks fields internal to the registrar that survive for the lifetime + // // of the transport session without being shared - i.e. local derived keys. + // state any + TagObfuscator transports.Obfuscator + + hmacID []byte + stationPublicKey [32]byte + rand io.Reader +} + +// Name returns a string identifier for the Transport for logging +func (*ClientTransport) Name() string { + return "min" +} + +// String returns a string identifier for the Transport for logging (including string formatters) +func (*ClientTransport) String() string { + return "min" +} + +// ID provides an identifier that will be sent to the conjure station during the registration so +// that the station knows what transport to expect connecting to the chosen phantom. +func (*ClientTransport) ID() pb.TransportType { + return pb.TransportType_Min +} + +// GetParams returns a generic protobuf with any parameters from both the registration and the +// transport. +func (t *ClientTransport) GetParams() (proto.Message, error) { + return t.Parameters, nil +} + +// ParseParams gives the specific transport an option to parse a generic object into parameters +// provided by the station in the registration response during registration. +func (t *ClientTransport) ParseParams(data *anypb.Any) (any, error) { + if data == nil { + return nil, nil + } + + var m = &pb.UTLSTransportParams{} + err := transports.UnmarshalAnypbTo(data, m) + return m, err +} + +func (*ClientTransport) Prepare(ctx context.Context, dialer func(ctx context.Context, network, laddr, raddr string) (net.Conn, error)) error { + return nil +} + +// SetParams allows the caller to set parameters associated with the transport, returning an +// error if the provided generic message is not compatible. +func (t *ClientTransport) SetParams(p any, unchecked ...bool) error { + params, ok := p.(*pb.UTLSTransportParams) + if !ok { + return fmt.Errorf("unable to parse params") + } + t.Parameters = params + + return nil +} + +// GetDstPort returns the destination port that the client should open the phantom connection to +func (t *ClientTransport) GetDstPort(seed []byte) (uint16, error) { + if t.Parameters == nil || !t.Parameters.GetRandomizeDstPort() { + return defaultPort, nil + } + + return transports.PortSelectorRange(portRangeMin, portRangeMax, seed) +} + +// PrepareKeys provides an opportunity for the transport to integrate the station public key +// as well as bytes from the deterministic random generator associated with the registration +// that this ClientTransport is attached to. +func (t *ClientTransport) PrepareKeys(pubkey [32]byte, sharedSecret []byte, dRand io.Reader) error { + t.hmacID = core.ConjureHMAC(sharedSecret, "PrefixTransportHMACString") + t.stationPublicKey = pubkey + t.rand = dRand + return nil +} + +// WrapConn returns a net.Conn connection given a context and ConjureReg +func (t *ClientTransport) WrapConn(conn net.Conn) (net.Conn, error) { + + if t.TagObfuscator == nil { + t.TagObfuscator = transports.CTRObfuscator{} + } + + randVal := [32]byte{} + n, err := rand.Read(randVal[:]) + if err != nil { + return nil, err + } else if n != 32 { + return nil, fmt.Errorf("ecpected 32 bytes of randmom, received %d", n) + } + + if t.Parameters == nil { + return nil, fmt.Errorf("missinf parameters") + } + + cert, err := newCertificate(randVal[:]) + if err != nil { + return nil, err + } + + serverConfig := &tls.Config{ + Certificates: []tls.Certificate{*cert}, + MinVersion: tls.VersionTLS10, + MaxVersion: tls.VersionTLS12, + SessionTicketsDisabled: false, + ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: buildSymmetricVerifier(randVal[:]), + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + } + + serverSession, err := tls.ForgeServerSessionState(randVal[:], serverConfig, tls.HelloChrome_Auto) + if err != nil { + return nil, err + } + + sessionTicket, err := serverSession.MakeEncryptedTicket(randVal, &tls.Config{}) + if err != nil { + return nil, err + } + + // Create a session ticket that wasn't actually issued by the server. + sessionState := tls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12), + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + randVal[:], + nil, nil) + + config := &tls.Config{ + ServerName: string(t.Parameters.Sni), + Certificates: []tls.Certificate{*cert}, + // VerifyConnection: buildSymmetricVerifier(randVal[:]), + } + clientTLSConn := tls.UClient(conn, config, tls.HelloGolang) + if err != nil { + return nil, err + } + + //[ ] TODO: set the random as sessionID and CH random + + err = clientTLSConn.BuildHandshakeState() + if err != nil { + return nil, err + } + // SetSessionState sets the session ticket, which may be preshared or fake. + err = clientTLSConn.SetSessionState(sessionState) + if err != nil { + return nil, err + } + return clientTLSConn, nil +} diff --git a/pkg/transports/wrapping/utls/utls.go b/pkg/transports/wrapping/utls/utls.go new file mode 100644 index 00000000..00f3f800 --- /dev/null +++ b/pkg/transports/wrapping/utls/utls.go @@ -0,0 +1,234 @@ +package utls + +import ( + "bytes" + "encoding/binary" + "fmt" + "math" + "net" + "regexp" + + "github.com/refraction-networking/conjure/pkg/core" + "github.com/refraction-networking/conjure/pkg/transports" + pb "github.com/refraction-networking/conjure/proto" + tls "github.com/refraction-networking/utls" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" +) + +const ( + httpPrefixRegexString = "" + httpPrefixMinLen = 32 + hmacString = "UTLSTransportHMACString" +) + +const ( + // Earliest client library version ID that supports destination port randomization + randomizeDstPortMinVersion uint = 3 + + // port range boundaries for prefix transport when randomizing + portRangeMin = 1024 + portRangeMax = 65535 + minTagLength = 32 + + defaultPort = 443 + + tlsCHPrefix = "\x16\x03\x01" + tlsCHHeaderLen = 5 +) + +// NOTE: using a regex is probably not necessary +var tlsHeaderRegex = regexp.MustCompile(`^\x16\x03\x01(.{2})`) + +// Transport provides a struct implementing the Transport, WrappingTransport, +// PortRandomizingTransport, and FixedPortTransport interfaces. +type Transport struct { + TagObfuscator transports.Obfuscator + Privkey [32]byte +} + +// New Given a private key this builds the server side transport. +func New(privkey [32]byte) (*Transport, error) { + return &Transport{ + Privkey: privkey, + TagObfuscator: &transports.CTRObfuscator{}, + }, nil +} + +// Name returns the human-friendly name of the transport, implementing the +// Transport interface.. +func (Transport) Name() string { return "UTLSTransport" } + +// LogPrefix returns the prefix used when including this transport in logs, +// implementing the Transport interface. +func (Transport) LogPrefix() string { return "UTLS" } + +// GetIdentifier takes in a registration and returns an identifier for it. This +// identifier should be unique for each registration on a given phantom; +// registrations on different phantoms can have the same identifier. +func (Transport) GetIdentifier(d transports.Registration) string { + return string(core.ConjureHMAC(d.SharedSecret(), hmacString)) +} + +// GetProto returns the next layer protocol that the transport uses. Implements +// the Transport interface. +func (Transport) GetProto() pb.IPProto { + return pb.IPProto_Tcp +} + +// ParseParams gives the specific transport an option to parse a generic object +// into parameters provided by the client during registration. +func (Transport) ParseParams(libVersion uint, data *anypb.Any) (any, error) { + if data == nil { + return nil, nil + } + + var m = &pb.UTLSTransportParams{} + err := anypb.UnmarshalTo(data, m, proto.UnmarshalOptions{}) + return m, err +} + +// ParamStrings returns an array of tag string that will be added to tunStats when a proxy +// session is closed. +func (Transport) ParamStrings(p any) []string { + return []string{} +} + +// GetDstPort Given the library version, a seed, and a generic object +// containing parameters the transport should be able to return the +// destination port that a clients phantom connection will attempt to reach +func (Transport) GetDstPort(libVersion uint, seed []byte, params any) (uint16, error) { + + if libVersion < randomizeDstPortMinVersion { + return 0, transports.ErrTransportNotSupported + } + + if params == nil { + return defaultPort, nil + } + + parameters, ok := params.(*pb.GenericTransportParams) + if !ok { + return 0, fmt.Errorf("bad parameters provided") + } + + if parameters.GetRandomizeDstPort() { + return transports.PortSelectorRange(portRangeMin, portRangeMax, seed) + } + + return defaultPort, nil +} + +func (t Transport) tryFindReg(data *bytes.Buffer, originalDst net.IP, regManager transports.RegManager) (transports.Registration, error) { + dataLen := data.Len() + + if dataLen == 0 { + return nil, transports.ErrTryAgain + } else if dataLen < tlsCHHeaderLen { + // If we don't have enough bytes to check for the clientHello, check if we can rule it out + // based on the fixed tls header bytes we expect. + n := int(math.Min(float64(dataLen), float64(len(tlsCHPrefix)))) + if !bytes.Equal(data.Bytes()[:n], []byte(tlsCHPrefix)[:n]) { + return nil, transports.ErrNotTransport + } + return nil, transports.ErrTryAgain + } + + // 160301{len:2}{clientHello:len} + out := tlsHeaderRegex.FindSubmatch(data.Bytes()) + if len(out) < 2 { + return nil, transports.ErrNotTransport + } + + // First match is the whole pattern, the second should be the group, and based on the regex it + // should always be the two bytes that we can parse into a u16 for ClientHello length. + chLen := binary.BigEndian.Uint16(out[1]) + if dataLen < tlsCHHeaderLen+int(chLen) { + return nil, transports.ErrTryAgain + } + + ch := tls.UnmarshalClientHello(data.Bytes()[tlsCHHeaderLen:dataLen]) + if ch == nil { + // We assume that one MTU is enough for the clientHello. If we have read the declared + // ClientHello length OR more than 1 MTU and still haven't found our registration then we + // probably wont find it. + if dataLen >= tlsCHHeaderLen+int(chLen) || dataLen > 1500 { + return nil, fmt.Errorf("%w: failed to unmarshal tls", transports.ErrNotTransport) + // fmt.Printf("failed to read request\n%s\n", err) + } + return nil, transports.ErrTryAgain + } + + obfuscatedID := append(ch.Random, ch.SessionId...) + + hmacID, err := t.TagObfuscator.TryReveal(obfuscatedID, t.Privkey) + if err != nil || hmacID == nil { + return nil, transports.ErrNotTransport + } + + reg, ok := regManager.GetRegistrations(originalDst)[string(hmacID)] + if !ok { + return nil, transports.ErrNotTransport + } + + return reg, nil +} + +// WrapConnection attempts to wrap the given connection in the transport. It takes the information +// gathered so far on the connection in data, attempts to identify itself, and if it positively +// identifies itself wraps the connection in the transport, returning a connection that's ready to +// be used by others. +// +// If the returned error is nil or non-nil and non-{ transports.ErrTryAgain, +// transports.ErrNotTransport }, the caller may no longer use data or conn. +func (t Transport) WrapConnection(data *bytes.Buffer, c net.Conn, originalDst net.IP, regManager transports.RegManager) (transports.Registration, net.Conn, error) { + reg, err := t.tryFindReg(data, originalDst, regManager) + if err != nil { + return nil, nil, err + } + + secret := reg.SharedSecret() + + cert, err := newCertificate(secret) + config := &tls.Config{ + Certificates: []tls.Certificate{*cert}, + MinVersion: tls.VersionTLS10, + MaxVersion: tls.VersionTLS12, + SessionTicketsDisabled: false, + ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: buildSymmetricVerifier(secret), + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + } + + s32 := [32]byte{} + copy(s32[:], secret) + config.SetSessionTicketKeys([][32]byte{s32}) + + return reg, tls.Server(c, config), err +} + +func xorBytes(a, b []byte) []byte { + if len(a) != len(b) { + return []byte{} + } + + n := make([]byte, len(a)) + for i := 0; i < len(a); i++ { + n[i] = a[i] ^ b[i] + } + + return n +} + +// [X] Fill PSK in client and session cache in station to ensure resumption of legit sessions. +// +// [ ] for TLS 1.2 Use session ticket and encrypt the conjure session ID under the stations pubkey. +// +// [ ] params for uTLS hello id and SNI +// +// [-] Can we leave certs / private keys out if using psk / session resumption? NO +// [X] Alternatively, can we generate the private key dynamically after finding the registration? YES +// +// +// [ ] for TLS 1.3 Use session ticket / PSK: +// - golang crypto/tls does not implement tls 1.3 PSK resumption, so we would have to add it. diff --git a/pkg/transports/wrapping/utls/utls_test.go b/pkg/transports/wrapping/utls/utls_test.go new file mode 100644 index 00000000..1fbaa892 --- /dev/null +++ b/pkg/transports/wrapping/utls/utls_test.go @@ -0,0 +1,548 @@ +package utls + +import ( + "bytes" + "crypto/rand" + "encoding/base64" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "io" + "net" + "net/http" + "os" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/anypb" + + "github.com/refraction-networking/conjure/internal/conjurepath" + tests "github.com/refraction-networking/conjure/internal/testutils" + "github.com/refraction-networking/conjure/pkg/core" + "github.com/refraction-networking/conjure/pkg/transports" + pb "github.com/refraction-networking/conjure/proto" + tls "github.com/refraction-networking/utls" +) + +var testSubnetPath = conjurepath.Root + "/internal/test_assets/phantom_subnets.toml" + +func connect(conn net.Conn, reg transports.Registration) (net.Conn, error) { + // TODO: put these in params + helloID := tls.HelloChrome_62 + config := tls.Config{ServerName: "", InsecureSkipVerify: true} + + uTLSConn := tls.UClient(conn, &config, helloID) + hmacID := core.ConjureHMAC(reg.SharedSecret(), hmacString) + + newRand := make([]byte, 32) + _, err := rand.Read(newRand) + if err != nil { + return nil, err + } + + err = uTLSConn.BuildHandshakeState() // Apply our client hello ID + if err != nil { + return nil, err + } + err = uTLSConn.SetClientRandom(newRand) + if err != nil { + return nil, err + } + // fmt.Printf("clientRandom set - handshaking %s\n", hex.EncodeToString(hmacID)) + + uTLSConn.HandshakeState.Hello.SessionId = xorBytes(hmacID, newRand) + + err = uTLSConn.MarshalClientHello() // apply the updated ch random value + if err != nil { + return nil, err + } + + return uTLSConn, uTLSConn.Handshake() +} + +func TestByteRegex(t *testing.T) { + testCases := []struct { + s string + l uint16 + }{ + {s: "16030100e2000000", l: 226}, + {s: "160301ff00000000", l: 65280}, + } + + badCases := []string{ + "15030100e2000000", + "160301ff", + "0016030100e2000000", + } + + for _, c := range testCases { + b, err := hex.DecodeString(c.s) + require.Nil(t, err) + + out := tlsHeaderRegex.FindSubmatch(b) + // for _, x := range out { + // t.Logf("%s", hex.EncodeToString(x)) + // } + require.Equal(t, 2, len(out)) + require.Equal(t, 2, len(out[1])) + u := binary.BigEndian.Uint16(out[1]) + require.Equal(t, c.l, u) + } + for _, c := range badCases { + b, err := hex.DecodeString(c) + require.Nil(t, err) + + out := tlsHeaderRegex.FindSubmatch(b) + require.Equal(t, 0, len(out)) + } +} + +func TestSuccessfulWrap(t *testing.T) { + os.Setenv("PHANTOM_SUBNET_LOCATION", testSubnetPath) + + var transport Transport + manager := tests.SetupRegistrationManager(tests.Transport{Index: pb.TransportType_Prefix, Transport: transport}) + c2p, sfp, reg := tests.SetupPhantomConnections(manager, pb.TransportType_Prefix, nil, randomizeDstPortMinVersion) + defer c2p.Close() + defer sfp.Close() + require.NotNil(t, reg) + + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + message := []byte(`test message!`) + + go func() { + var buf [1501]byte + + var wrapped net.Conn + var err error + for { + n, err := sfp.Read(buf[:]) + if err != nil { + panic("station read error") + } + + reg, wrapped, err = transport.WrapConnection(bytes.NewBuffer(buf[:n]), sfp, *phantom, manager) + if errors.Is(err, transports.ErrNotTransport) { + panic("failed to find registration") + } else if errors.Is(err, transports.ErrTransportNotSupported) { + panic("transport supposed to be supported but isn't") + } else if err == nil { + break + } // on transports.ErrTryAgain it should continue loop. + } + + stationReceived := make([]byte, len(message)) + _, err = io.ReadFull(wrapped, stationReceived) + if err != nil { + panic(fmt.Sprintf("failed ReadFull: %s %s", stationReceived, err)) + } + _, err = wrapped.Write(stationReceived) + if err != nil { + panic("failed Write") + } + }() + + clientConn, err := connect(c2p, reg) + require.Nil(t, err) + + _, err = clientConn.Write(message) + require.Nil(t, err) + + received := make([]byte, len(message)) + _, err = io.ReadFull(clientConn, received) + require.Nil(t, err, "failed reading from connection") + require.True(t, bytes.Equal(message, received)) +} + +func TestUnsuccessfulWrap(t *testing.T) { + var transport Transport + manager := tests.SetupRegistrationManager(tests.Transport{Index: pb.TransportType_Prefix, Transport: transport}) + c2p, sfp, reg := tests.SetupPhantomConnections(manager, pb.TransportType_Prefix, nil, randomizeDstPortMinVersion) + defer c2p.Close() + defer sfp.Close() + + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + + message := []byte(`test message!`) + + // No real reason for sending the shared secret; it's just 32 bytes + // (same length as HMAC ID) that should have no significance. + req, err := http.NewRequest(http.MethodGet, "/", bytes.NewReader(message)) + require.Nil(t, err) + req.Header.Add("X-Ignore", base64.StdEncoding.EncodeToString(tests.SharedSecret)) + err = req.Write(c2p) + require.Nil(t, err) + + var buf [128]byte + var buffer bytes.Buffer + n, _ := sfp.Read(buf[:]) + buffer.Write(buf[:n]) + + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) + require.ErrorIs(t, err, transports.ErrNotTransport) +} + +func TestTryAgain(t *testing.T) { + var transport Transport + var err error + manager := tests.SetupRegistrationManager(tests.Transport{Index: pb.TransportType_Prefix, Transport: transport}) + c2p, sfp, reg := tests.SetupPhantomConnections(manager, pb.TransportType_Prefix, nil, randomizeDstPortMinVersion) + defer c2p.Close() + defer sfp.Close() + + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + + var buffer bytes.Buffer + + // The only way that we should be able to get ErrTryAgain is if it was + // called on a read with 0 bytes + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) + require.ErrorIs(t, err, transports.ErrTryAgain) + message := []byte(`test message!`) + + // No real reason for sending the shared secret; it's just 32 bytes + // (same length as HMAC ID) that should have no significance. + req, err := http.NewRequest(http.MethodGet, "/", bytes.NewReader(message)) + require.Nil(t, err) + req.Header.Add("X-Ignore", base64.StdEncoding.EncodeToString(tests.SharedSecret)) + err = req.Write(c2p) + require.Nil(t, err) + + var buf [128]byte + n, _ := sfp.Read(buf[:]) + buffer.Write(buf[:n]) + + _, _, err = transport.WrapConnection(&buffer, sfp, *phantom, manager) + require.ErrorIs(t, err, transports.ErrNotTransport) +} + +func TestSuccessfulWrapLargeMessage(t *testing.T) { + os.Setenv("PHANTOM_SUBNET_LOCATION", testSubnetPath) + + var transport Transport + manager := tests.SetupRegistrationManager(tests.Transport{Index: pb.TransportType_Prefix, Transport: transport}) + c2p, sfp, reg := tests.SetupPhantomConnections(manager, pb.TransportType_Prefix, nil, randomizeDstPortMinVersion) + defer c2p.Close() + defer sfp.Close() + require.NotNil(t, reg) + + phantom := reg.PhantomIP() + require.NotNil(t, phantom) + + message := make([]byte, 10000) + _, err := rand.Read(message) + require.Nil(t, err) + + go func() { + var buf [1501]byte + + var wrapped net.Conn + var err error + for { + n, err := sfp.Read(buf[:]) + if err != nil { + panic("station read error") + } + + reg, wrapped, err = transport.WrapConnection(bytes.NewBuffer(buf[:n]), sfp, *phantom, manager) + if errors.Is(err, transports.ErrNotTransport) { + panic("failed to find registration") + } else if errors.Is(err, transports.ErrTransportNotSupported) { + panic("transport supposed to be supported but isn't") + } else if err == nil { + break + } // on transports.ErrTryAgain it should continue loop. + } + + stationReceived := make([]byte, len(message)) + _, err = io.ReadFull(wrapped, stationReceived) + if err != nil { + panic(fmt.Sprintf("failed ReadFull: %s %s", stationReceived, err)) + } + _, err = wrapped.Write(stationReceived) + if err != nil { + panic("failed Write") + } + }() + + clientConn, err := connect(c2p, reg) + require.Nil(t, err) + + _, err = clientConn.Write(message) + require.Nil(t, err) + + received := make([]byte, len(message)) + n, err := io.ReadFull(clientConn, received) + require.Nil(t, err, "failed reading from connection") + require.True(t, bytes.Equal(message[:n], received)) +} + +func TestTryParamsToDstPort(t *testing.T) { + clv := randomizeDstPortMinVersion + seed, _ := hex.DecodeString("0000000000000000000000000000000000") + + cases := []struct { + r bool + p uint16 + }{{true, 58047}, {false, defaultPort}} + + for _, testCase := range cases { + ct := ClientTransport{Parameters: &pb.UTLSTransportParams{RandomizeDstPort: &testCase.r}} + var transport Transport + + pms, err := ct.GetParams() + require.Nil(t, err) + rawParams, err := anypb.New(pms) + require.Nil(t, err) + + params, err := transport.ParseParams(clv, rawParams) + require.Nil(t, err) + + port, err := transport.GetDstPort(clv, seed, params) + require.Nil(t, err) + require.Equal(t, testCase.p, port) + } +} + +func TestUtlsSessionResumption(t *testing.T) { + var err error + c2p, sfp := net.Pipe() + + message := []byte(`test message!`) + + randVal := [32]byte{} + n, err := rand.Read(randVal[:]) + require.Nil(t, err) + require.Equal(t, 32, n) + domainName := "abc.def.com" + + cert, err := newCertificate(randVal[:]) + require.Nil(t, err) + serverConfig := &tls.Config{ + Certificates: []tls.Certificate{*cert}, + MinVersion: tls.VersionTLS10, + MaxVersion: tls.VersionTLS12, + SessionTicketsDisabled: false, + ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: buildSymmetricVerifier(randVal[:]), + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + } + + go func() { + config := *serverConfig + + config.SetSessionTicketKeys([][32]byte{randVal}) + + wrapped := tls.Server(sfp, &config) + + stationReceived := make([]byte, len(message)) + _, err := io.ReadFull(wrapped, stationReceived) + if err != nil { + t.Logf("failed ReadFull: %s %s", stationReceived, err) + t.Logf("%v", config.CipherSuites) + t.Fail() + return + } + _, err = wrapped.Write(stationReceived) + if err != nil { + t.Logf("failed Write") + t.Fail() + return + } + }() + + serverSession, err := tls.ForgeServerSessionState(randVal[:], serverConfig, tls.HelloChrome_Auto) + require.Nil(t, err) + + sessionTicket, err := serverSession.MakeEncryptedTicket(randVal, &tls.Config{}) + require.Nil(t, err) + + // Create a session ticket that wasn't actually issued by the server. + sessionState := tls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12), + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + randVal[:], + nil, nil) + + config := &tls.Config{ + ServerName: domainName, + Certificates: []tls.Certificate{*cert}, + // VerifyConnection: buildSymmetricVerifier(randVal[:]), + } + clientTLSConn := tls.UClient(c2p, config, tls.HelloGolang) + require.NotNil(t, clientTLSConn) + + err = clientTLSConn.BuildHandshakeState() + require.Nil(t, err) + + // SetSessionState sets the session ticket, which may be preshared or fake. + err = clientTLSConn.SetSessionState(sessionState) + require.Nil(t, err) + + _, err = clientTLSConn.Write(message) + require.Nil(t, err) + + received := make([]byte, len(message)) + _, err = io.ReadFull(clientTLSConn, received) + require.Nil(t, err, "failed reading from connection") + require.True(t, bytes.Equal(message, received)) +} + +func TestUtlsSessionResumptionTCP(t *testing.T) { + var err error + listenAddr := &net.TCPAddr{ + IP: net.IPv6loopback, + Port: 4443, + } + message := []byte(`test message!`) + + randVal := [32]byte{} + n, err := rand.Read(randVal[:]) + require.Nil(t, err) + require.Equal(t, 32, n) + domainName := "abc.def.com" + ordering := make(chan struct{}) + cert, err := newCertificate(randVal[:]) + require.Nil(t, err) + + serverConfig := &tls.Config{ + Certificates: []tls.Certificate{*cert}, + MinVersion: tls.VersionTLS10, + MaxVersion: tls.VersionTLS12, + SessionTicketsDisabled: false, + ClientAuth: tls.RequireAnyClientCert, + VerifyConnection: buildSymmetricVerifier(randVal[:]), + CipherSuites: []uint16{tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, + } + + go func() { + config := *serverConfig + + config.SetSessionTicketKeys([][32]byte{randVal}) + + l, err := net.ListenTCP("tcp", listenAddr) + if err != nil { + t.Fail() + ordering <- struct{}{} + return + } + defer l.Close() + + ordering <- struct{}{} + + sfc, err := l.Accept() + if err != nil { + t.Fail() + return + } + + wrapped := tls.Server(sfc, &config) + + stationReceived := make([]byte, len(message)) + _, err = io.ReadFull(wrapped, stationReceived) + if err != nil { + t.Logf("failed ReadFull: %s %s", stationReceived, err) + t.Logf("%v", config.CipherSuites) + t.Fail() + return + } + _, err = wrapped.Write(stationReceived) + if err != nil { + t.Logf("failed Write") + t.Fail() + return + } + }() + + serverSession, err := tls.ForgeServerSessionState(randVal[:], serverConfig, tls.HelloChrome_Auto) + require.Nil(t, err) + + sessionTicket, err := serverSession.MakeEncryptedTicket(randVal, &tls.Config{}) + require.Nil(t, err) + + // Create a session ticket that wasn't actually issued by the server. + sessionState := tls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12), + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + randVal[:], + nil, nil) + + config := &tls.Config{ + ServerName: domainName, + Certificates: []tls.Certificate{*cert}, + // VerifyConnection: buildSymmetricVerifier(randVal[:]), + } + + <-ordering + c2p, err := net.Dial("tcp", listenAddr.String()) + require.Nil(t, err) + + clientTLSConn := tls.UClient(c2p, config, tls.HelloGolang) + require.NotNil(t, clientTLSConn) + + err = clientTLSConn.BuildHandshakeState() + require.Nil(t, err) + + // SetSessionState sets the session ticket, which may be preshared or fake. + err = clientTLSConn.SetSessionState(sessionState) + require.Nil(t, err) + + _, err = clientTLSConn.Write(message) + require.Nil(t, err) + + received := make([]byte, len(message)) + _, err = io.ReadFull(clientTLSConn, received) + require.Nil(t, err, "failed reading from connection") + require.True(t, bytes.Equal(message, received)) +} + +// const ( +// // ticketKeyNameLen is the number of bytes of identifier that is prepended to +// // an encrypted session ticket in order to identify the key used to encrypt it. +// ticketKeyNameLen = 16 +// ) +// +// // returns the session state and the marshalled sessionTicket, or an error should one occur. +// func forgeSession(secret [32]byte, chID tls.ClientHelloID, r io.Reader) (*tls.ClientSessionState, []byte, error) { +// key := tls.TicketKeyFromBytes(secret) +// serverState, err := tls.ForgeServerSessionState(secret[:], chID) +// if err != nil { +// return nil, nil, err +// } +// stateBytes, err := serverState.Marshal() +// if err != nil { +// return nil, nil, err +// } + +// encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(stateBytes)+sha256.Size) +// keyName := encrypted[:ticketKeyNameLen] +// iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] +// macBytes := encrypted[len(encrypted)-sha256.Size:] + +// if _, err := io.ReadFull(r, iv); err != nil { +// return nil, nil, err +// } + +// copy(keyName, key.KeyName[:]) +// block, err := aes.NewCipher(key.AesKey[:]) +// if err != nil { +// return nil, nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) +// } +// cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], stateBytes) + +// mac := hmac.New(sha256.New, key.HmacKey[:]) +// mac.Write(encrypted[:len(encrypted)-sha256.Size]) +// mac.Sum(macBytes[:0]) + +// state := tls.MakeClientSessionState(encrypted, uint16(tls.VersionTLS12), +// tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, +// secret[:], +// nil, nil) + +// return state, encrypted, nil +// } + +// https://github.com/refraction-networking/utls/blob/c785bd3a1e8dd394d36526a2f3f118a21fc002c5/handshake_server_tls13.go#L736 +// https://github.com/refraction-networking/utls/blob/c785bd3a1e8dd394d36526a2f3f118a21fc002c5/handshake_server.go#L769 diff --git a/proto/signalling.pb.go b/proto/signalling.pb.go index 02784c36..b8a37d74 100644 --- a/proto/signalling.pb.go +++ b/proto/signalling.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v4.24.2 +// protoc-gen-go v1.27.1 +// protoc v3.12.4 // source: signalling.proto // TODO: We're using proto2 because it's the default on Ubuntu 16.04. @@ -11,9 +11,9 @@ package proto import ( + any "github.com/golang/protobuf/ptypes/any" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -1645,7 +1645,7 @@ type ClientToStation struct { Stats *SessionStats `protobuf:"bytes,11,opt,name=stats" json:"stats,omitempty"` // NullTransport, MinTransport, Obfs4Transport, etc. Transport type we want from phantom proxy Transport *TransportType `protobuf:"varint,12,opt,name=transport,enum=proto.TransportType" json:"transport,omitempty"` - TransportParams *anypb.Any `protobuf:"bytes,13,opt,name=transport_params,json=transportParams" json:"transport_params,omitempty"` + TransportParams *any.Any `protobuf:"bytes,13,opt,name=transport_params,json=transportParams" json:"transport_params,omitempty"` // Station is only required to check this variable during session initialization. // If set, station must facilitate connection to said target by itself, i.e. write into squid // socket an HTTP/SOCKS/any other connection request. @@ -1762,7 +1762,7 @@ func (x *ClientToStation) GetTransport() TransportType { return TransportType_Null } -func (x *ClientToStation) GetTransportParams() *anypb.Any { +func (x *ClientToStation) GetTransportParams() *any.Any { if x != nil { return x.TransportParams } @@ -1818,6 +1818,88 @@ func (x *ClientToStation) GetPadding() []byte { return nil } +type UTLSTransportParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChId *int32 `protobuf:"varint,1,opt,name=ch_id,json=chId" json:"ch_id,omitempty"` + ChSpec []byte `protobuf:"bytes,2,opt,name=ch_spec,json=chSpec" json:"ch_spec,omitempty"` + Ciphersuite *int32 `protobuf:"varint,3,opt,name=ciphersuite" json:"ciphersuite,omitempty"` + Sni []byte `protobuf:"bytes,8,opt,name=sni" json:"sni,omitempty"` + // Indicates whether the client has elected to use destination port randomization. Should be + // checked against selected transport to ensure that destination port randomization is + // supported. + RandomizeDstPort *bool `protobuf:"varint,13,opt,name=randomize_dst_port,json=randomizeDstPort" json:"randomize_dst_port,omitempty"` +} + +func (x *UTLSTransportParams) Reset() { + *x = UTLSTransportParams{} + if protoimpl.UnsafeEnabled { + mi := &file_signalling_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UTLSTransportParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UTLSTransportParams) ProtoMessage() {} + +func (x *UTLSTransportParams) ProtoReflect() protoreflect.Message { + mi := &file_signalling_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UTLSTransportParams.ProtoReflect.Descriptor instead. +func (*UTLSTransportParams) Descriptor() ([]byte, []int) { + return file_signalling_proto_rawDescGZIP(), []int{15} +} + +func (x *UTLSTransportParams) GetChId() int32 { + if x != nil && x.ChId != nil { + return *x.ChId + } + return 0 +} + +func (x *UTLSTransportParams) GetChSpec() []byte { + if x != nil { + return x.ChSpec + } + return nil +} + +func (x *UTLSTransportParams) GetCiphersuite() int32 { + if x != nil && x.Ciphersuite != nil { + return *x.Ciphersuite + } + return 0 +} + +func (x *UTLSTransportParams) GetSni() []byte { + if x != nil { + return x.Sni + } + return nil +} + +func (x *UTLSTransportParams) GetRandomizeDstPort() bool { + if x != nil && x.RandomizeDstPort != nil { + return *x.RandomizeDstPort + } + return false +} + type PrefixTransportParams struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1838,7 +1920,7 @@ type PrefixTransportParams struct { func (x *PrefixTransportParams) Reset() { *x = PrefixTransportParams{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[15] + mi := &file_signalling_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1851,7 +1933,7 @@ func (x *PrefixTransportParams) String() string { func (*PrefixTransportParams) ProtoMessage() {} func (x *PrefixTransportParams) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[15] + mi := &file_signalling_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1864,7 +1946,7 @@ func (x *PrefixTransportParams) ProtoReflect() protoreflect.Message { // Deprecated: Use PrefixTransportParams.ProtoReflect.Descriptor instead. func (*PrefixTransportParams) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{15} + return file_signalling_proto_rawDescGZIP(), []int{16} } func (x *PrefixTransportParams) GetPrefixId() int32 { @@ -1909,7 +1991,7 @@ type GenericTransportParams struct { func (x *GenericTransportParams) Reset() { *x = GenericTransportParams{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[16] + mi := &file_signalling_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1922,7 +2004,7 @@ func (x *GenericTransportParams) String() string { func (*GenericTransportParams) ProtoMessage() {} func (x *GenericTransportParams) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[16] + mi := &file_signalling_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1935,7 +2017,7 @@ func (x *GenericTransportParams) ProtoReflect() protoreflect.Message { // Deprecated: Use GenericTransportParams.ProtoReflect.Descriptor instead. func (*GenericTransportParams) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{16} + return file_signalling_proto_rawDescGZIP(), []int{17} } func (x *GenericTransportParams) GetRandomizeDstPort() bool { @@ -1975,7 +2057,7 @@ type C2SWrapper struct { func (x *C2SWrapper) Reset() { *x = C2SWrapper{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[17] + mi := &file_signalling_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1988,7 +2070,7 @@ func (x *C2SWrapper) String() string { func (*C2SWrapper) ProtoMessage() {} func (x *C2SWrapper) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[17] + mi := &file_signalling_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2001,7 +2083,7 @@ func (x *C2SWrapper) ProtoReflect() protoreflect.Message { // Deprecated: Use C2SWrapper.ProtoReflect.Descriptor instead. func (*C2SWrapper) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{17} + return file_signalling_proto_rawDescGZIP(), []int{18} } func (x *C2SWrapper) GetSharedSecret() []byte { @@ -2077,7 +2159,7 @@ type SessionStats struct { func (x *SessionStats) Reset() { *x = SessionStats{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[18] + mi := &file_signalling_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2090,7 +2172,7 @@ func (x *SessionStats) String() string { func (*SessionStats) ProtoMessage() {} func (x *SessionStats) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[18] + mi := &file_signalling_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2103,7 +2185,7 @@ func (x *SessionStats) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionStats.ProtoReflect.Descriptor instead. func (*SessionStats) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{18} + return file_signalling_proto_rawDescGZIP(), []int{19} } func (x *SessionStats) GetFailedDecoysAmount() uint32 { @@ -2158,7 +2240,7 @@ type StationToDetector struct { func (x *StationToDetector) Reset() { *x = StationToDetector{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[19] + mi := &file_signalling_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2171,7 +2253,7 @@ func (x *StationToDetector) String() string { func (*StationToDetector) ProtoMessage() {} func (x *StationToDetector) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[19] + mi := &file_signalling_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2184,7 +2266,7 @@ func (x *StationToDetector) ProtoReflect() protoreflect.Message { // Deprecated: Use StationToDetector.ProtoReflect.Descriptor instead. func (*StationToDetector) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{19} + return file_signalling_proto_rawDescGZIP(), []int{20} } func (x *StationToDetector) GetPhantomIp() string { @@ -2255,13 +2337,13 @@ type RegistrationResponse struct { // ClientConf field (optional) ClientConf *ClientConf `protobuf:"bytes,6,opt,name=clientConf" json:"clientConf,omitempty"` // Transport Params to if `allow_registrar_overrides` is set. - TransportParams *anypb.Any `protobuf:"bytes,10,opt,name=transport_params,json=transportParams" json:"transport_params,omitempty"` + TransportParams *any.Any `protobuf:"bytes,10,opt,name=transport_params,json=transportParams" json:"transport_params,omitempty"` } func (x *RegistrationResponse) Reset() { *x = RegistrationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[20] + mi := &file_signalling_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2274,7 +2356,7 @@ func (x *RegistrationResponse) String() string { func (*RegistrationResponse) ProtoMessage() {} func (x *RegistrationResponse) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[20] + mi := &file_signalling_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2287,7 +2369,7 @@ func (x *RegistrationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegistrationResponse.ProtoReflect.Descriptor instead. func (*RegistrationResponse) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{20} + return file_signalling_proto_rawDescGZIP(), []int{21} } func (x *RegistrationResponse) GetIpv4Addr() uint32 { @@ -2332,7 +2414,7 @@ func (x *RegistrationResponse) GetClientConf() *ClientConf { return nil } -func (x *RegistrationResponse) GetTransportParams() *anypb.Any { +func (x *RegistrationResponse) GetTransportParams() *any.Any { if x != nil { return x.TransportParams } @@ -2353,7 +2435,7 @@ type DnsResponse struct { func (x *DnsResponse) Reset() { *x = DnsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_signalling_proto_msgTypes[21] + mi := &file_signalling_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2366,7 +2448,7 @@ func (x *DnsResponse) String() string { func (*DnsResponse) ProtoMessage() {} func (x *DnsResponse) ProtoReflect() protoreflect.Message { - mi := &file_signalling_proto_msgTypes[21] + mi := &file_signalling_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2379,7 +2461,7 @@ func (x *DnsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DnsResponse.ProtoReflect.Descriptor instead. func (*DnsResponse) Descriptor() ([]byte, []int) { - return file_signalling_proto_rawDescGZIP(), []int{21} + return file_signalling_proto_rawDescGZIP(), []int{22} } func (x *DnsResponse) GetSuccess() bool { @@ -2588,174 +2670,184 @@ var file_signalling_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x52, 0x54, 0x43, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x52, 0x0c, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0xaa, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x49, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, - 0x6d, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x46, 0x6c, 0x75, 0x73, - 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x61, 0x6e, 0x64, 0x6f, - 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x73, - 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x46, 0x0a, 0x16, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x07, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0xa5, 0x01, 0x0a, 0x13, 0x55, 0x54, 0x4c, + 0x53, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x13, 0x0a, 0x05, 0x63, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x63, 0x68, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x63, 0x68, 0x5f, 0x73, 0x70, 0x65, 0x63, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x68, 0x53, 0x70, 0x65, 0x63, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x73, 0x75, 0x69, 0x74, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x73, 0x6e, 0x69, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, + 0x6e, 0x69, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x5f, + 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, + 0x22, 0xaa, 0x01, 0x0a, 0x15, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, + 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, + 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x63, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x61, 0x6e, - 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xc2, 0x03, - 0x0a, 0x0a, 0x43, 0x32, 0x53, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x12, 0x49, 0x0a, 0x14, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x6f, - 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4a, 0x0a, 0x13, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, - 0x65, 0x63, 0x6f, 0x79, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x50, 0x0a, 0x15, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x14, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, 0x70, 0x42, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x10, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x65, - 0x63, 0x6f, 0x79, 0x73, 0x5f, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x12, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x44, 0x65, 0x63, 0x6f, 0x79, 0x73, 0x41, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18, 0x1f, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x54, - 0x6f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x74, 0x74, 0x5f, - 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0c, 0x72, 0x74, 0x74, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, - 0x0a, 0x0c, 0x74, 0x6c, 0x73, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x18, 0x26, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6c, 0x73, 0x54, 0x6f, 0x44, 0x65, 0x63, 0x6f, 0x79, - 0x12, 0x20, 0x0a, 0x0c, 0x74, 0x63, 0x70, 0x5f, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x79, - 0x18, 0x27, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x63, 0x70, 0x54, 0x6f, 0x44, 0x65, 0x63, - 0x6f, 0x79, 0x22, 0x82, 0x02, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, - 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x68, 0x61, 0x6e, - 0x74, 0x6f, 0x6d, 0x5f, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x68, - 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x49, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x5f, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x49, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x4e, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, - 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, - 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, 0x72, 0x63, 0x50, 0x6f, 0x72, - 0x74, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x70, 0x76, 0x34, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x07, 0x52, 0x08, 0x69, 0x70, 0x76, 0x34, 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, - 0x69, 0x70, 0x76, 0x36, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, - 0x69, 0x70, 0x76, 0x36, 0x61, 0x64, 0x64, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, - 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x61, 0x6e, - 0x64, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x31, 0x0a, - 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x12, 0x3f, 0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x22, 0xac, 0x01, 0x0a, 0x0b, 0x44, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x66, 0x5f, 0x6f, 0x75, 0x74, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x63, 0x6f, 0x6e, 0x66, 0x4f, 0x75, 0x74, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x16, - 0x62, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x15, 0x62, 0x69, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2a, 0x2b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x41, - 0x45, 0x53, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x31, 0x32, 0x38, 0x10, 0x5a, 0x12, 0x0f, 0x0a, 0x0b, - 0x41, 0x45, 0x53, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x32, 0x35, 0x36, 0x10, 0x5b, 0x2a, 0x29, 0x0a, - 0x0c, 0x44, 0x6e, 0x73, 0x52, 0x65, 0x67, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, - 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4f, 0x54, 0x10, 0x02, 0x12, - 0x07, 0x0a, 0x03, 0x44, 0x4f, 0x48, 0x10, 0x03, 0x2a, 0xe7, 0x01, 0x0a, 0x0e, 0x43, 0x32, 0x53, - 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x43, - 0x32, 0x53, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x00, 0x12, 0x14, - 0x0a, 0x10, 0x43, 0x32, 0x53, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, - 0x49, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x32, 0x53, 0x5f, 0x53, 0x45, 0x53, 0x53, - 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, - 0x0b, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x32, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x5f, - 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, - 0x32, 0x53, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, - 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x32, 0x53, 0x5f, 0x59, 0x49, 0x45, 0x4c, 0x44, 0x5f, - 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x32, 0x53, 0x5f, - 0x41, 0x43, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x05, - 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x32, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x5f, 0x55, - 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x4e, - 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x32, 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, - 0xff, 0x01, 0x2a, 0x98, 0x01, 0x0a, 0x0e, 0x53, 0x32, 0x43, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x32, 0x43, 0x5f, 0x4e, 0x4f, 0x5f, - 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x32, 0x43, 0x5f, - 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x01, 0x12, 0x1b, - 0x0a, 0x17, 0x53, 0x32, 0x43, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15, 0x53, - 0x32, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x52, 0x4d, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4e, - 0x4e, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x32, 0x43, 0x5f, 0x53, 0x45, - 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x03, 0x12, 0x0e, 0x0a, - 0x09, 0x53, 0x32, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0xff, 0x01, 0x2a, 0xac, 0x01, - 0x0a, 0x0e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x53, 0x32, 0x43, - 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x11, - 0x0a, 0x0d, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x54, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, - 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x50, 0x4f, - 0x52, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, - 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, - 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, - 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x43, 0x4f, 0x59, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x4c, - 0x4f, 0x41, 0x44, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, - 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x64, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4c, 0x49, 0x45, - 0x4e, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x65, 0x2a, 0x82, 0x01, 0x0a, - 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, - 0x0a, 0x04, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x69, 0x6e, 0x10, - 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x62, 0x66, 0x73, 0x34, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, - 0x44, 0x54, 0x4c, 0x53, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x75, 0x54, 0x4c, 0x53, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, - 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x53, 0x4d, - 0x10, 0x07, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x54, 0x45, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x51, - 0x75, 0x69, 0x63, 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x57, 0x65, 0x62, 0x72, 0x74, 0x63, 0x10, - 0x63, 0x2a, 0x86, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x73, 0x70, - 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65, 0x74, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x10, 0x02, - 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, - 0x63, 0x61, 0x6e, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x50, 0x49, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, - 0x4e, 0x53, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x44, 0x4e, 0x53, 0x10, 0x06, 0x2a, 0x40, 0x0a, 0x11, 0x53, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, - 0x4e, 0x65, 0x77, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x10, - 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x10, 0x03, 0x2a, 0x24, 0x0a, 0x07, - 0x49, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x6e, 0x6b, 0x10, 0x00, - 0x12, 0x07, 0x0a, 0x03, 0x54, 0x63, 0x70, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x64, 0x70, - 0x10, 0x02, + 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x46, 0x0a, + 0x16, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, + 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x61, 0x6e, 0x64, 0x6f, + 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x10, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x69, 0x7a, 0x65, 0x44, 0x73, + 0x74, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xc2, 0x03, 0x0a, 0x0a, 0x43, 0x32, 0x53, 0x57, 0x72, 0x61, + 0x70, 0x70, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x49, 0x0a, 0x14, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4a, 0x0a, 0x13, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0x31, 0x0a, 0x14, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x64, 0x65, 0x63, 0x6f, + 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x50, 0x0a, 0x15, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x14, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x65, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0c, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2a, + 0x0a, 0x10, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x52, 0x65, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xdd, 0x01, 0x0a, 0x0c, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x66, + 0x61, 0x69, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x73, 0x5f, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x66, 0x61, 0x69, 0x6c, 0x65, + 0x64, 0x44, 0x65, 0x63, 0x6f, 0x79, 0x73, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x31, 0x0a, + 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x12, 0x24, 0x0a, 0x0e, 0x72, 0x74, 0x74, 0x5f, 0x74, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x72, 0x74, 0x74, 0x54, 0x6f, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0c, 0x74, 0x6c, 0x73, 0x5f, 0x74, 0x6f, + 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6c, + 0x73, 0x54, 0x6f, 0x44, 0x65, 0x63, 0x6f, 0x79, 0x12, 0x20, 0x0a, 0x0c, 0x74, 0x63, 0x70, 0x5f, + 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x63, 0x6f, 0x79, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, + 0x74, 0x63, 0x70, 0x54, 0x6f, 0x44, 0x65, 0x63, 0x6f, 0x79, 0x22, 0x82, 0x02, 0x0a, 0x11, 0x53, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x68, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x5f, 0x69, 0x70, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x68, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x49, 0x70, 0x12, + 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x1d, 0x0a, 0x0a, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4e, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x6f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, + 0x0a, 0x08, 0x73, 0x72, 0x63, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x73, 0x72, 0x63, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x05, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x49, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x97, 0x02, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x70, 0x76, 0x34, + 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x08, 0x69, 0x70, 0x76, 0x34, + 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x70, 0x76, 0x36, 0x61, 0x64, 0x64, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x69, 0x70, 0x76, 0x36, 0x61, 0x64, 0x64, 0x72, + 0x12, 0x19, 0x0a, 0x08, 0x64, 0x73, 0x74, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x64, 0x73, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x52, 0x0a, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x3f, 0x0a, 0x10, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x6f, 0x72, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xac, 0x01, 0x0a, 0x0b, 0x44, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, + 0x66, 0x5f, 0x6f, 0x75, 0x74, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x63, 0x6f, 0x6e, 0x66, 0x4f, 0x75, 0x74, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x16, 0x62, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x52, 0x15, 0x62, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x2b, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x47, 0x43, 0x4d, 0x5f, 0x31, + 0x32, 0x38, 0x10, 0x5a, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x45, 0x53, 0x5f, 0x47, 0x43, 0x4d, 0x5f, + 0x32, 0x35, 0x36, 0x10, 0x5b, 0x2a, 0x29, 0x0a, 0x0c, 0x44, 0x6e, 0x73, 0x52, 0x65, 0x67, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x01, 0x12, 0x07, + 0x0a, 0x03, 0x44, 0x4f, 0x54, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4f, 0x48, 0x10, 0x03, + 0x2a, 0xe7, 0x01, 0x0a, 0x0e, 0x43, 0x32, 0x53, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x32, 0x53, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x48, + 0x41, 0x4e, 0x47, 0x45, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x32, 0x53, 0x5f, 0x53, 0x45, + 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, + 0x43, 0x32, 0x53, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x56, 0x45, + 0x52, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x0b, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x32, 0x53, + 0x5f, 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, + 0x54, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x32, 0x53, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, + 0x4f, 0x4e, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x32, + 0x53, 0x5f, 0x59, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x04, + 0x12, 0x16, 0x0a, 0x12, 0x43, 0x32, 0x53, 0x5f, 0x41, 0x43, 0x51, 0x55, 0x49, 0x52, 0x45, 0x5f, + 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x05, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x32, 0x53, 0x5f, + 0x45, 0x58, 0x50, 0x45, 0x43, 0x54, 0x5f, 0x55, 0x50, 0x4c, 0x4f, 0x41, 0x44, 0x4f, 0x4e, 0x4c, + 0x59, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x4e, 0x10, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x32, + 0x53, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0xff, 0x01, 0x2a, 0x98, 0x01, 0x0a, 0x0e, 0x53, + 0x32, 0x43, 0x5f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, + 0x0d, 0x53, 0x32, 0x43, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x00, + 0x12, 0x14, 0x0a, 0x10, 0x53, 0x32, 0x43, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x49, 0x4e, 0x49, 0x54, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x32, 0x43, 0x5f, 0x53, 0x45, + 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x54, 0x5f, 0x49, 0x4e, 0x49, + 0x54, 0x10, 0x0b, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x32, 0x43, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, + 0x52, 0x4d, 0x5f, 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x10, 0x02, 0x12, 0x15, + 0x0a, 0x11, 0x53, 0x32, 0x43, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x43, 0x4c, + 0x4f, 0x53, 0x45, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x32, 0x43, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0xff, 0x01, 0x2a, 0xac, 0x01, 0x0a, 0x0e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x53, 0x32, 0x43, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x54, + 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4c, 0x49, + 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, + 0x0a, 0x0f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, + 0x4c, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x49, + 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, 0x43, + 0x4f, 0x59, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x05, 0x12, 0x11, 0x0a, + 0x0d, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x64, + 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, + 0x55, 0x54, 0x10, 0x65, 0x2a, 0x82, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x75, 0x6c, 0x6c, 0x10, 0x00, + 0x12, 0x07, 0x0a, 0x03, 0x4d, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x62, 0x66, + 0x73, 0x34, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x54, 0x4c, 0x53, 0x10, 0x03, 0x12, 0x0a, + 0x0a, 0x06, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x75, 0x54, + 0x4c, 0x53, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x10, 0x06, + 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x53, 0x4d, 0x10, 0x07, 0x12, 0x07, 0x0a, 0x03, 0x46, 0x54, + 0x45, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x63, 0x10, 0x09, 0x12, 0x0a, 0x0a, + 0x06, 0x57, 0x65, 0x62, 0x72, 0x74, 0x63, 0x10, 0x63, 0x2a, 0x86, 0x01, 0x0a, 0x12, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x10, 0x01, 0x12, + 0x07, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x65, 0x74, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x65, 0x73, 0x63, 0x61, 0x6e, 0x10, 0x03, 0x12, 0x14, 0x0a, + 0x10, 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x50, + 0x49, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4e, 0x53, 0x10, 0x05, 0x12, 0x14, 0x0a, 0x10, + 0x42, 0x69, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x44, 0x4e, 0x53, + 0x10, 0x06, 0x2a, 0x40, 0x0a, 0x11, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x65, 0x77, 0x10, 0x01, 0x12, 0x0a, 0x0a, + 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x10, 0x03, 0x2a, 0x24, 0x0a, 0x07, 0x49, 0x50, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x0a, 0x03, 0x55, 0x6e, 0x6b, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x63, 0x70, 0x10, + 0x01, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x64, 0x70, 0x10, 0x02, } var ( @@ -2771,7 +2863,7 @@ func file_signalling_proto_rawDescGZIP() []byte { } var file_signalling_proto_enumTypes = make([]protoimpl.EnumInfo, 9) -var file_signalling_proto_msgTypes = make([]protoimpl.MessageInfo, 22) +var file_signalling_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_signalling_proto_goTypes = []interface{}{ (KeyType)(0), // 0: proto.KeyType (DnsRegMethod)(0), // 1: proto.DnsRegMethod @@ -2797,14 +2889,15 @@ var file_signalling_proto_goTypes = []interface{}{ (*StationToClient)(nil), // 21: proto.StationToClient (*RegistrationFlags)(nil), // 22: proto.RegistrationFlags (*ClientToStation)(nil), // 23: proto.ClientToStation - (*PrefixTransportParams)(nil), // 24: proto.PrefixTransportParams - (*GenericTransportParams)(nil), // 25: proto.GenericTransportParams - (*C2SWrapper)(nil), // 26: proto.C2SWrapper - (*SessionStats)(nil), // 27: proto.SessionStats - (*StationToDetector)(nil), // 28: proto.StationToDetector - (*RegistrationResponse)(nil), // 29: proto.RegistrationResponse - (*DnsResponse)(nil), // 30: proto.DnsResponse - (*anypb.Any)(nil), // 31: google.protobuf.Any + (*UTLSTransportParams)(nil), // 24: proto.UTLSTransportParams + (*PrefixTransportParams)(nil), // 25: proto.PrefixTransportParams + (*GenericTransportParams)(nil), // 26: proto.GenericTransportParams + (*C2SWrapper)(nil), // 27: proto.C2SWrapper + (*SessionStats)(nil), // 28: proto.SessionStats + (*StationToDetector)(nil), // 29: proto.StationToDetector + (*RegistrationResponse)(nil), // 30: proto.RegistrationResponse + (*DnsResponse)(nil), // 31: proto.DnsResponse + (*any.Any)(nil), // 32: google.protobuf.Any } var file_signalling_proto_depIdxs = []int32{ 0, // 0: proto.PubKey.type:type_name -> proto.KeyType @@ -2825,19 +2918,19 @@ var file_signalling_proto_depIdxs = []int32{ 11, // 15: proto.StationToClient.config_info:type_name -> proto.ClientConf 4, // 16: proto.StationToClient.err_reason:type_name -> proto.ErrorReasonS2C 2, // 17: proto.ClientToStation.state_transition:type_name -> proto.C2S_Transition - 27, // 18: proto.ClientToStation.stats:type_name -> proto.SessionStats + 28, // 18: proto.ClientToStation.stats:type_name -> proto.SessionStats 5, // 19: proto.ClientToStation.transport:type_name -> proto.TransportType - 31, // 20: proto.ClientToStation.transport_params:type_name -> google.protobuf.Any + 32, // 20: proto.ClientToStation.transport_params:type_name -> google.protobuf.Any 22, // 21: proto.ClientToStation.flags:type_name -> proto.RegistrationFlags 18, // 22: proto.ClientToStation.webrtc_signal:type_name -> proto.WebRTCSignal 23, // 23: proto.C2SWrapper.registration_payload:type_name -> proto.ClientToStation 6, // 24: proto.C2SWrapper.registration_source:type_name -> proto.RegistrationSource - 29, // 25: proto.C2SWrapper.registration_response:type_name -> proto.RegistrationResponse + 30, // 25: proto.C2SWrapper.registration_response:type_name -> proto.RegistrationResponse 7, // 26: proto.StationToDetector.operation:type_name -> proto.StationOperations 8, // 27: proto.StationToDetector.proto:type_name -> proto.IPProto 11, // 28: proto.RegistrationResponse.clientConf:type_name -> proto.ClientConf - 31, // 29: proto.RegistrationResponse.transport_params:type_name -> google.protobuf.Any - 29, // 30: proto.DnsResponse.bidirectional_response:type_name -> proto.RegistrationResponse + 32, // 29: proto.RegistrationResponse.transport_params:type_name -> google.protobuf.Any + 30, // 30: proto.DnsResponse.bidirectional_response:type_name -> proto.RegistrationResponse 31, // [31:31] is the sub-list for method output_type 31, // [31:31] is the sub-list for method input_type 31, // [31:31] is the sub-list for extension type_name @@ -3032,7 +3125,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PrefixTransportParams); i { + switch v := v.(*UTLSTransportParams); i { case 0: return &v.state case 1: @@ -3044,7 +3137,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GenericTransportParams); i { + switch v := v.(*PrefixTransportParams); i { case 0: return &v.state case 1: @@ -3056,7 +3149,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*C2SWrapper); i { + switch v := v.(*GenericTransportParams); i { case 0: return &v.state case 1: @@ -3068,7 +3161,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SessionStats); i { + switch v := v.(*C2SWrapper); i { case 0: return &v.state case 1: @@ -3080,7 +3173,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StationToDetector); i { + switch v := v.(*SessionStats); i { case 0: return &v.state case 1: @@ -3092,7 +3185,7 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RegistrationResponse); i { + switch v := v.(*StationToDetector); i { case 0: return &v.state case 1: @@ -3104,6 +3197,18 @@ func file_signalling_proto_init() { } } file_signalling_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RegistrationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_signalling_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DnsResponse); i { case 0: return &v.state @@ -3122,7 +3227,7 @@ func file_signalling_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_signalling_proto_rawDesc, NumEnums: 9, - NumMessages: 22, + NumMessages: 23, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/signalling.proto b/proto/signalling.proto index bc5e47a1..db588775 100644 --- a/proto/signalling.proto +++ b/proto/signalling.proto @@ -297,6 +297,21 @@ message ClientToStation { } +message UTLSTransportParams { + optional int32 ch_id = 1; + + optional bytes ch_spec = 2; + + optional int32 ciphersuite = 3; + + optional bytes sni = 8; + + // Indicates whether the client has elected to use destination port randomization. Should be + // checked against selected transport to ensure that destination port randomization is + // supported. + optional bool randomize_dst_port = 13; +} + message PrefixTransportParams { // Prefix Identifier optional int32 prefix_id = 1; diff --git a/proto/signalling.rs b/proto/signalling.rs index 22fee424..f85a1cc2 100644 --- a/proto/signalling.rs +++ b/proto/signalling.rs @@ -2302,49 +2302,227 @@ impl ::protobuf::reflect::ProtobufValue for WebRTCSignal { } #[derive(PartialEq,Clone,Default,Debug)] -// @@protoc_insertion_point(message:proto.DTLSTransportParams) -pub struct DTLSTransportParams { +// @@protoc_insertion_point(message:proto.Addr) +pub struct Addr { // message fields - // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_port) - pub src_port: ::std::option::Option, - // @@protoc_insertion_point(field:proto.DTLSTransportParams.randomize_dst_port) - pub randomize_dst_port: ::std::option::Option, + // @@protoc_insertion_point(field:proto.Addr.IP) + pub IP: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:proto.Addr.Port) + pub Port: ::std::option::Option, // special fields - // @@protoc_insertion_point(special_field:proto.DTLSTransportParams.special_fields) + // @@protoc_insertion_point(special_field:proto.Addr.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a DTLSTransportParams { - fn default() -> &'a DTLSTransportParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a Addr { + fn default() -> &'a Addr { + ::default_instance() } } -impl DTLSTransportParams { - pub fn new() -> DTLSTransportParams { +impl Addr { + pub fn new() -> Addr { ::std::default::Default::default() } - // optional uint32 src_port = 1; + // optional bytes IP = 1; - pub fn src_port(&self) -> u32 { - self.src_port.unwrap_or(0) + pub fn IP(&self) -> &[u8] { + match self.IP.as_ref() { + Some(v) => v, + None => &[], + } } - pub fn clear_src_port(&mut self) { - self.src_port = ::std::option::Option::None; + pub fn clear_IP(&mut self) { + self.IP = ::std::option::Option::None; } - pub fn has_src_port(&self) -> bool { - self.src_port.is_some() + pub fn has_IP(&self) -> bool { + self.IP.is_some() } // Param is passed by value, moved - pub fn set_src_port(&mut self, v: u32) { - self.src_port = ::std::option::Option::Some(v); + pub fn set_IP(&mut self, v: ::std::vec::Vec) { + self.IP = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_IP(&mut self) -> &mut ::std::vec::Vec { + if self.IP.is_none() { + self.IP = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.IP.as_mut().unwrap() + } + + // Take field + pub fn take_IP(&mut self) -> ::std::vec::Vec { + self.IP.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional uint32 Port = 2; + + pub fn Port(&self) -> u32 { + self.Port.unwrap_or(0) + } + + pub fn clear_Port(&mut self) { + self.Port = ::std::option::Option::None; + } + + pub fn has_Port(&self) -> bool { + self.Port.is_some() + } + + // Param is passed by value, moved + pub fn set_Port(&mut self, v: u32) { + self.Port = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "IP", + |m: &Addr| { &m.IP }, + |m: &mut Addr| { &mut m.IP }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "Port", + |m: &Addr| { &m.Port }, + |m: &mut Addr| { &mut m.Port }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "Addr", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for Addr { + const NAME: &'static str = "Addr"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.IP = ::std::option::Option::Some(is.read_bytes()?); + }, + 16 => { + self.Port = ::std::option::Option::Some(is.read_uint32()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.IP.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.Port { + my_size += ::protobuf::rt::uint32_size(2, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.IP.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.Port { + os.write_uint32(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> Addr { + Addr::new() + } + + fn clear(&mut self) { + self.IP = ::std::option::Option::None; + self.Port = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static Addr { + static instance: Addr = Addr { + IP: ::std::option::Option::None, + Port: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for Addr { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("Addr").unwrap()).clone() + } +} + +impl ::std::fmt::Display for Addr { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Addr { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:proto.DTLSTransportParams) +pub struct DTLSTransportParams { + // message fields + // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_addr4) + pub src_addr4: ::protobuf::MessageField, + // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_addr6) + pub src_addr6: ::protobuf::MessageField, + // @@protoc_insertion_point(field:proto.DTLSTransportParams.randomize_dst_port) + pub randomize_dst_port: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:proto.DTLSTransportParams.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a DTLSTransportParams { + fn default() -> &'a DTLSTransportParams { + ::default_instance() + } +} + +impl DTLSTransportParams { + pub fn new() -> DTLSTransportParams { + ::std::default::Default::default() } - // optional bool randomize_dst_port = 2; + // optional bool randomize_dst_port = 3; pub fn randomize_dst_port(&self) -> bool { self.randomize_dst_port.unwrap_or(false) @@ -2364,12 +2542,17 @@ impl DTLSTransportParams { } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); + let mut fields = ::std::vec::Vec::with_capacity(3); let mut oneofs = ::std::vec::Vec::with_capacity(0); - fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( - "src_port", - |m: &DTLSTransportParams| { &m.src_port }, - |m: &mut DTLSTransportParams| { &mut m.src_port }, + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, Addr>( + "src_addr4", + |m: &DTLSTransportParams| { &m.src_addr4 }, + |m: &mut DTLSTransportParams| { &mut m.src_addr4 }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, Addr>( + "src_addr6", + |m: &DTLSTransportParams| { &m.src_addr6 }, + |m: &mut DTLSTransportParams| { &mut m.src_addr6 }, )); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "randomize_dst_port", @@ -2394,10 +2577,13 @@ impl ::protobuf::Message for DTLSTransportParams { fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { while let Some(tag) = is.read_raw_tag_or_eof()? { match tag { - 8 => { - self.src_port = ::std::option::Option::Some(is.read_uint32()?); + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.src_addr4)?; }, - 16 => { + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.src_addr6)?; + }, + 24 => { self.randomize_dst_port = ::std::option::Option::Some(is.read_bool()?); }, tag => { @@ -2412,8 +2598,13 @@ impl ::protobuf::Message for DTLSTransportParams { #[allow(unused_variables)] fn compute_size(&self) -> u64 { let mut my_size = 0; - if let Some(v) = self.src_port { - my_size += ::protobuf::rt::uint32_size(1, v); + if let Some(v) = self.src_addr4.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.src_addr6.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; } if let Some(v) = self.randomize_dst_port { my_size += 1 + 1; @@ -2424,11 +2615,14 @@ impl ::protobuf::Message for DTLSTransportParams { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { - if let Some(v) = self.src_port { - os.write_uint32(1, v)?; + if let Some(v) = self.src_addr4.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if let Some(v) = self.src_addr6.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; } if let Some(v) = self.randomize_dst_port { - os.write_bool(2, v)?; + os.write_bool(3, v)?; } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) @@ -2447,14 +2641,16 @@ impl ::protobuf::Message for DTLSTransportParams { } fn clear(&mut self) { - self.src_port = ::std::option::Option::None; + self.src_addr4.clear(); + self.src_addr6.clear(); self.randomize_dst_port = ::std::option::Option::None; self.special_fields.clear(); } fn default_instance() -> &'static DTLSTransportParams { static instance: DTLSTransportParams = DTLSTransportParams { - src_port: ::std::option::Option::None, + src_addr4: ::protobuf::MessageField::none(), + src_addr6: ::protobuf::MessageField::none(), randomize_dst_port: ::std::option::Option::None, special_fields: ::protobuf::SpecialFields::new(), }; @@ -3911,6 +4107,332 @@ impl ::protobuf::reflect::ProtobufValue for ClientToStation { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:proto.UTLSTransportParams) +pub struct UTLSTransportParams { + // message fields + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ch_id) + pub ch_id: ::std::option::Option, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ch_spec) + pub ch_spec: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ciphersuite) + pub ciphersuite: ::std::option::Option, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.sni) + pub sni: ::std::option::Option<::std::vec::Vec>, + /// Indicates whether the client has elected to use destination port randomization. Should be + /// checked against selected transport to ensure that destination port randomization is + /// supported. + // @@protoc_insertion_point(field:proto.UTLSTransportParams.randomize_dst_port) + pub randomize_dst_port: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:proto.UTLSTransportParams.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a UTLSTransportParams { + fn default() -> &'a UTLSTransportParams { + ::default_instance() + } +} + +impl UTLSTransportParams { + pub fn new() -> UTLSTransportParams { + ::std::default::Default::default() + } + + // optional int32 ch_id = 1; + + pub fn ch_id(&self) -> i32 { + self.ch_id.unwrap_or(0) + } + + pub fn clear_ch_id(&mut self) { + self.ch_id = ::std::option::Option::None; + } + + pub fn has_ch_id(&self) -> bool { + self.ch_id.is_some() + } + + // Param is passed by value, moved + pub fn set_ch_id(&mut self, v: i32) { + self.ch_id = ::std::option::Option::Some(v); + } + + // optional bytes ch_spec = 2; + + pub fn ch_spec(&self) -> &[u8] { + match self.ch_spec.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ch_spec(&mut self) { + self.ch_spec = ::std::option::Option::None; + } + + pub fn has_ch_spec(&self) -> bool { + self.ch_spec.is_some() + } + + // Param is passed by value, moved + pub fn set_ch_spec(&mut self, v: ::std::vec::Vec) { + self.ch_spec = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ch_spec(&mut self) -> &mut ::std::vec::Vec { + if self.ch_spec.is_none() { + self.ch_spec = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ch_spec.as_mut().unwrap() + } + + // Take field + pub fn take_ch_spec(&mut self) -> ::std::vec::Vec { + self.ch_spec.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional int32 ciphersuite = 3; + + pub fn ciphersuite(&self) -> i32 { + self.ciphersuite.unwrap_or(0) + } + + pub fn clear_ciphersuite(&mut self) { + self.ciphersuite = ::std::option::Option::None; + } + + pub fn has_ciphersuite(&self) -> bool { + self.ciphersuite.is_some() + } + + // Param is passed by value, moved + pub fn set_ciphersuite(&mut self, v: i32) { + self.ciphersuite = ::std::option::Option::Some(v); + } + + // optional bytes sni = 8; + + pub fn sni(&self) -> &[u8] { + match self.sni.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_sni(&mut self) { + self.sni = ::std::option::Option::None; + } + + pub fn has_sni(&self) -> bool { + self.sni.is_some() + } + + // Param is passed by value, moved + pub fn set_sni(&mut self, v: ::std::vec::Vec) { + self.sni = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sni(&mut self) -> &mut ::std::vec::Vec { + if self.sni.is_none() { + self.sni = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.sni.as_mut().unwrap() + } + + // Take field + pub fn take_sni(&mut self) -> ::std::vec::Vec { + self.sni.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional bool randomize_dst_port = 13; + + pub fn randomize_dst_port(&self) -> bool { + self.randomize_dst_port.unwrap_or(false) + } + + pub fn clear_randomize_dst_port(&mut self) { + self.randomize_dst_port = ::std::option::Option::None; + } + + pub fn has_randomize_dst_port(&self) -> bool { + self.randomize_dst_port.is_some() + } + + // Param is passed by value, moved + pub fn set_randomize_dst_port(&mut self, v: bool) { + self.randomize_dst_port = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(5); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ch_id", + |m: &UTLSTransportParams| { &m.ch_id }, + |m: &mut UTLSTransportParams| { &mut m.ch_id }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ch_spec", + |m: &UTLSTransportParams| { &m.ch_spec }, + |m: &mut UTLSTransportParams| { &mut m.ch_spec }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ciphersuite", + |m: &UTLSTransportParams| { &m.ciphersuite }, + |m: &mut UTLSTransportParams| { &mut m.ciphersuite }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "sni", + |m: &UTLSTransportParams| { &m.sni }, + |m: &mut UTLSTransportParams| { &mut m.sni }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "randomize_dst_port", + |m: &UTLSTransportParams| { &m.randomize_dst_port }, + |m: &mut UTLSTransportParams| { &mut m.randomize_dst_port }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "UTLSTransportParams", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for UTLSTransportParams { + const NAME: &'static str = "UTLSTransportParams"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.ch_id = ::std::option::Option::Some(is.read_int32()?); + }, + 18 => { + self.ch_spec = ::std::option::Option::Some(is.read_bytes()?); + }, + 24 => { + self.ciphersuite = ::std::option::Option::Some(is.read_int32()?); + }, + 66 => { + self.sni = ::std::option::Option::Some(is.read_bytes()?); + }, + 104 => { + self.randomize_dst_port = ::std::option::Option::Some(is.read_bool()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.ch_id { + my_size += ::protobuf::rt::int32_size(1, v); + } + if let Some(v) = self.ch_spec.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + if let Some(v) = self.ciphersuite { + my_size += ::protobuf::rt::int32_size(3, v); + } + if let Some(v) = self.sni.as_ref() { + my_size += ::protobuf::rt::bytes_size(8, &v); + } + if let Some(v) = self.randomize_dst_port { + my_size += 1 + 1; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.ch_id { + os.write_int32(1, v)?; + } + if let Some(v) = self.ch_spec.as_ref() { + os.write_bytes(2, v)?; + } + if let Some(v) = self.ciphersuite { + os.write_int32(3, v)?; + } + if let Some(v) = self.sni.as_ref() { + os.write_bytes(8, v)?; + } + if let Some(v) = self.randomize_dst_port { + os.write_bool(13, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> UTLSTransportParams { + UTLSTransportParams::new() + } + + fn clear(&mut self) { + self.ch_id = ::std::option::Option::None; + self.ch_spec = ::std::option::Option::None; + self.ciphersuite = ::std::option::Option::None; + self.sni = ::std::option::Option::None; + self.randomize_dst_port = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static UTLSTransportParams { + static instance: UTLSTransportParams = UTLSTransportParams { + ch_id: ::std::option::Option::None, + ch_spec: ::std::option::Option::None, + ciphersuite: ::std::option::Option::None, + sni: ::std::option::Option::None, + randomize_dst_port: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for UTLSTransportParams { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("UTLSTransportParams").unwrap()).clone() + } +} + +impl ::std::fmt::Display for UTLSTransportParams { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UTLSTransportParams { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + #[derive(PartialEq,Clone,Default,Debug)] // @@protoc_insertion_point(message:proto.PrefixTransportParams) pub struct PrefixTransportParams { @@ -6806,55 +7328,62 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\x20\x02(\rR\x04type\x129\n\ncandidates\x18\x02\x20\x03(\x0b2\x19.pr\ oto.WebRTCICECandidateR\ncandidates\"F\n\x0cWebRTCSignal\x12\x12\n\x04se\ ed\x18\x01\x20\x02(\tR\x04seed\x12\"\n\x03sdp\x18\x02\x20\x02(\x0b2\x10.\ - proto.WebRTCSDPR\x03sdp\"^\n\x13DTLSTransportParams\x12\x19\n\x08src_por\ - t\x18\x01\x20\x01(\rR\x07srcPort\x12,\n\x12randomize_dst_port\x18\x02\ - \x20\x01(\x08R\x10randomizeDstPort\"\xc2\x02\n\x0fStationToClient\x12)\n\ - \x10protocol_version\x18\x01\x20\x01(\rR\x0fprotocolVersion\x12@\n\x10st\ - ate_transition\x18\x02\x20\x01(\x0e2\x15.proto.S2C_TransitionR\x0fstateT\ - ransition\x122\n\x0bconfig_info\x18\x03\x20\x01(\x0b2\x11.proto.ClientCo\ - nfR\nconfigInfo\x124\n\nerr_reason\x18\x04\x20\x01(\x0e2\x15.proto.Error\ - ReasonS2CR\terrReason\x12\x1f\n\x0btmp_backoff\x18\x05\x20\x01(\rR\ntmpB\ - ackoff\x12\x1d\n\nstation_id\x18\x06\x20\x01(\tR\tstationId\x12\x18\n\ - \x07padding\x18d\x20\x01(\x0cR\x07padding\"\xaf\x01\n\x11RegistrationFla\ - gs\x12\x1f\n\x0bupload_only\x18\x01\x20\x01(\x08R\nuploadOnly\x12\x1d\n\ - \ndark_decoy\x18\x02\x20\x01(\x08R\tdarkDecoy\x12!\n\x0cproxy_header\x18\ - \x03\x20\x01(\x08R\x0bproxyHeader\x12\x17\n\x07use_TIL\x18\x04\x20\x01(\ - \x08R\x06useTIL\x12\x1e\n\nprescanned\x18\x05\x20\x01(\x08R\nprescanned\ - \"\xa8\x06\n\x0fClientToStation\x12)\n\x10protocol_version\x18\x01\x20\ - \x01(\rR\x0fprotocolVersion\x122\n\x15decoy_list_generation\x18\x02\x20\ - \x01(\rR\x13decoyListGeneration\x12@\n\x10state_transition\x18\x03\x20\ - \x01(\x0e2\x15.proto.C2S_TransitionR\x0fstateTransition\x12\x1f\n\x0bupl\ - oad_sync\x18\x04\x20\x01(\x04R\nuploadSync\x12,\n\x12client_lib_version\ - \x18\x05\x20\x01(\rR\x10clientLibVersion\x12>\n\x1bdisable_registrar_ove\ - rrides\x18\x06\x20\x01(\x08R\x19disableRegistrarOverrides\x12#\n\rfailed\ - _decoys\x18\n\x20\x03(\tR\x0cfailedDecoys\x12)\n\x05stats\x18\x0b\x20\ - \x01(\x0b2\x13.proto.SessionStatsR\x05stats\x122\n\ttransport\x18\x0c\ - \x20\x01(\x0e2\x14.proto.TransportTypeR\ttransport\x12?\n\x10transport_p\ - arams\x18\r\x20\x01(\x0b2\x14.google.protobuf.AnyR\x0ftransportParams\ - \x12%\n\x0ecovert_address\x18\x14\x20\x01(\tR\rcovertAddress\x127\n\x18m\ - asked_decoy_server_name\x18\x15\x20\x01(\tR\x15maskedDecoyServerName\x12\ - \x1d\n\nv6_support\x18\x16\x20\x01(\x08R\tv6Support\x12\x1d\n\nv4_suppor\ - t\x18\x17\x20\x01(\x08R\tv4Support\x12.\n\x05flags\x18\x18\x20\x01(\x0b2\ - \x18.proto.RegistrationFlagsR\x05flags\x128\n\rwebrtc_signal\x18\x1f\x20\ - \x01(\x0b2\x13.proto.WebRTCSignalR\x0cwebrtcSignal\x12\x18\n\x07padding\ - \x18d\x20\x01(\x0cR\x07padding\"\xaa\x01\n\x15PrefixTransportParams\x12\ - \x1b\n\tprefix_id\x18\x01\x20\x01(\x05R\x08prefixId\x12\x16\n\x06prefix\ - \x18\x02\x20\x01(\x0cR\x06prefix\x12.\n\x13custom_flush_policy\x18\x03\ - \x20\x01(\x05R\x11customFlushPolicy\x12,\n\x12randomize_dst_port\x18\r\ - \x20\x01(\x08R\x10randomizeDstPort\"F\n\x16GenericTransportParams\x12,\n\ - \x12randomize_dst_port\x18\r\x20\x01(\x08R\x10randomizeDstPort\"\xc2\x03\ - \n\nC2SWrapper\x12#\n\rshared_secret\x18\x01\x20\x01(\x0cR\x0csharedSecr\ - et\x12I\n\x14registration_payload\x18\x03\x20\x01(\x0b2\x16.proto.Client\ - ToStationR\x13registrationPayload\x12J\n\x13registration_source\x18\x04\ - \x20\x01(\x0e2\x19.proto.RegistrationSourceR\x12registrationSource\x121\ - \n\x14registration_address\x18\x06\x20\x01(\x0cR\x13registrationAddress\ - \x12#\n\rdecoy_address\x18\x07\x20\x01(\x0cR\x0cdecoyAddress\x12P\n\x15r\ - egistration_response\x18\x08\x20\x01(\x0b2\x1b.proto.RegistrationRespons\ - eR\x14registrationResponse\x12\"\n\x0cRegRespBytes\x18\t\x20\x01(\x0cR\ - \x0cRegRespBytes\x12*\n\x10RegRespSignature\x18\n\x20\x01(\x0cR\x10RegRe\ - spSignature\"\xdd\x01\n\x0cSessionStats\x120\n\x14failed_decoys_amount\ - \x18\x14\x20\x01(\rR\x12failedDecoysAmount\x121\n\x15total_time_to_conne\ - ct\x18\x1f\x20\x01(\rR\x12totalTimeToConnect\x12$\n\x0ertt_to_station\ + proto.WebRTCSDPR\x03sdp\"*\n\x04Addr\x12\x0e\n\x02IP\x18\x01\x20\x01(\ + \x0cR\x02IP\x12\x12\n\x04Port\x18\x02\x20\x01(\rR\x04Port\"\x97\x01\n\ + \x13DTLSTransportParams\x12(\n\tsrc_addr4\x18\x01\x20\x01(\x0b2\x0b.prot\ + o.AddrR\x08srcAddr4\x12(\n\tsrc_addr6\x18\x02\x20\x01(\x0b2\x0b.proto.Ad\ + drR\x08srcAddr6\x12,\n\x12randomize_dst_port\x18\x03\x20\x01(\x08R\x10ra\ + ndomizeDstPort\"\xc2\x02\n\x0fStationToClient\x12)\n\x10protocol_version\ + \x18\x01\x20\x01(\rR\x0fprotocolVersion\x12@\n\x10state_transition\x18\ + \x02\x20\x01(\x0e2\x15.proto.S2C_TransitionR\x0fstateTransition\x122\n\ + \x0bconfig_info\x18\x03\x20\x01(\x0b2\x11.proto.ClientConfR\nconfigInfo\ + \x124\n\nerr_reason\x18\x04\x20\x01(\x0e2\x15.proto.ErrorReasonS2CR\terr\ + Reason\x12\x1f\n\x0btmp_backoff\x18\x05\x20\x01(\rR\ntmpBackoff\x12\x1d\ + \n\nstation_id\x18\x06\x20\x01(\tR\tstationId\x12\x18\n\x07padding\x18d\ + \x20\x01(\x0cR\x07padding\"\xaf\x01\n\x11RegistrationFlags\x12\x1f\n\x0b\ + upload_only\x18\x01\x20\x01(\x08R\nuploadOnly\x12\x1d\n\ndark_decoy\x18\ + \x02\x20\x01(\x08R\tdarkDecoy\x12!\n\x0cproxy_header\x18\x03\x20\x01(\ + \x08R\x0bproxyHeader\x12\x17\n\x07use_TIL\x18\x04\x20\x01(\x08R\x06useTI\ + L\x12\x1e\n\nprescanned\x18\x05\x20\x01(\x08R\nprescanned\"\xa8\x06\n\ + \x0fClientToStation\x12)\n\x10protocol_version\x18\x01\x20\x01(\rR\x0fpr\ + otocolVersion\x122\n\x15decoy_list_generation\x18\x02\x20\x01(\rR\x13dec\ + oyListGeneration\x12@\n\x10state_transition\x18\x03\x20\x01(\x0e2\x15.pr\ + oto.C2S_TransitionR\x0fstateTransition\x12\x1f\n\x0bupload_sync\x18\x04\ + \x20\x01(\x04R\nuploadSync\x12,\n\x12client_lib_version\x18\x05\x20\x01(\ + \rR\x10clientLibVersion\x12>\n\x1bdisable_registrar_overrides\x18\x06\ + \x20\x01(\x08R\x19disableRegistrarOverrides\x12#\n\rfailed_decoys\x18\n\ + \x20\x03(\tR\x0cfailedDecoys\x12)\n\x05stats\x18\x0b\x20\x01(\x0b2\x13.p\ + roto.SessionStatsR\x05stats\x122\n\ttransport\x18\x0c\x20\x01(\x0e2\x14.\ + proto.TransportTypeR\ttransport\x12?\n\x10transport_params\x18\r\x20\x01\ + (\x0b2\x14.google.protobuf.AnyR\x0ftransportParams\x12%\n\x0ecovert_addr\ + ess\x18\x14\x20\x01(\tR\rcovertAddress\x127\n\x18masked_decoy_server_nam\ + e\x18\x15\x20\x01(\tR\x15maskedDecoyServerName\x12\x1d\n\nv6_support\x18\ + \x16\x20\x01(\x08R\tv6Support\x12\x1d\n\nv4_support\x18\x17\x20\x01(\x08\ + R\tv4Support\x12.\n\x05flags\x18\x18\x20\x01(\x0b2\x18.proto.Registratio\ + nFlagsR\x05flags\x128\n\rwebrtc_signal\x18\x1f\x20\x01(\x0b2\x13.proto.W\ + ebRTCSignalR\x0cwebrtcSignal\x12\x18\n\x07padding\x18d\x20\x01(\x0cR\x07\ + padding\"\xa5\x01\n\x13UTLSTransportParams\x12\x13\n\x05ch_id\x18\x01\ + \x20\x01(\x05R\x04chId\x12\x17\n\x07ch_spec\x18\x02\x20\x01(\x0cR\x06chS\ + pec\x12\x20\n\x0bciphersuite\x18\x03\x20\x01(\x05R\x0bciphersuite\x12\ + \x10\n\x03sni\x18\x08\x20\x01(\x0cR\x03sni\x12,\n\x12randomize_dst_port\ + \x18\r\x20\x01(\x08R\x10randomizeDstPort\"\xaa\x01\n\x15PrefixTransportP\ + arams\x12\x1b\n\tprefix_id\x18\x01\x20\x01(\x05R\x08prefixId\x12\x16\n\ + \x06prefix\x18\x02\x20\x01(\x0cR\x06prefix\x12.\n\x13custom_flush_policy\ + \x18\x03\x20\x01(\x05R\x11customFlushPolicy\x12,\n\x12randomize_dst_port\ + \x18\r\x20\x01(\x08R\x10randomizeDstPort\"F\n\x16GenericTransportParams\ + \x12,\n\x12randomize_dst_port\x18\r\x20\x01(\x08R\x10randomizeDstPort\"\ + \xc2\x03\n\nC2SWrapper\x12#\n\rshared_secret\x18\x01\x20\x01(\x0cR\x0csh\ + aredSecret\x12I\n\x14registration_payload\x18\x03\x20\x01(\x0b2\x16.prot\ + o.ClientToStationR\x13registrationPayload\x12J\n\x13registration_source\ + \x18\x04\x20\x01(\x0e2\x19.proto.RegistrationSourceR\x12registrationSour\ + ce\x121\n\x14registration_address\x18\x06\x20\x01(\x0cR\x13registrationA\ + ddress\x12#\n\rdecoy_address\x18\x07\x20\x01(\x0cR\x0cdecoyAddress\x12P\ + \n\x15registration_response\x18\x08\x20\x01(\x0b2\x1b.proto.Registration\ + ResponseR\x14registrationResponse\x12\"\n\x0cRegRespBytes\x18\t\x20\x01(\ + \x0cR\x0cRegRespBytes\x12*\n\x10RegRespSignature\x18\n\x20\x01(\x0cR\x10\ + RegRespSignature\"\xdd\x01\n\x0cSessionStats\x120\n\x14failed_decoys_amo\ + unt\x18\x14\x20\x01(\rR\x12failedDecoysAmount\x121\n\x15total_time_to_co\ + nnect\x18\x1f\x20\x01(\rR\x12totalTimeToConnect\x12$\n\x0ertt_to_station\ \x18!\x20\x01(\rR\x0crttToStation\x12\x20\n\x0ctls_to_decoy\x18&\x20\x01\ (\rR\ntlsToDecoy\x12\x20\n\x0ctcp_to_decoy\x18'\x20\x01(\rR\ntcpToDecoy\ \"\x82\x02\n\x11StationToDetector\x12\x1d\n\nphantom_ip\x18\x01\x20\x01(\ @@ -6900,7 +7429,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ectionalDNS\x10\x06*@\n\x11StationOperations\x12\x0b\n\x07Unknown\x10\0\ \x12\x07\n\x03New\x10\x01\x12\n\n\x06Update\x10\x02\x12\t\n\x05Clear\x10\ \x03*$\n\x07IPProto\x12\x07\n\x03Unk\x10\0\x12\x07\n\x03Tcp\x10\x01\x12\ - \x07\n\x03Udp\x10\x02J\x81\x90\x01\n\x07\x12\x05\0\0\xa8\x03\x01\n\x08\n\ + \x07\n\x03Udp\x10\x02J\xc7\x96\x01\n\x07\x12\x05\0\0\xbd\x03\x01\n\x08\n\ \x01\x0c\x12\x03\0\0\x12\n\xb0\x01\n\x01\x02\x12\x03\x06\0\x0e2\xa5\x01\ \x20TODO:\x20We're\x20using\x20proto2\x20because\x20it's\x20the\x20defau\ lt\x20on\x20Ubuntu\x2016.04.\n\x20At\x20some\x20point\x20we\x20will\x20w\ @@ -7192,385 +7721,422 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\r\n\x05\x04\t\x02\x01\x06\x12\x04\xbf\x01\r\x16\n\r\n\x05\x04\t\x02\ \x01\x01\x12\x04\xbf\x01\x17\x1a\n\r\n\x05\x04\t\x02\x01\x03\x12\x04\xbf\ \x01\x1d\x1e\n\x0c\n\x02\x04\n\x12\x06\xc2\x01\0\xc5\x01\x01\n\x0b\n\x03\ - \x04\n\x01\x12\x04\xc2\x01\x08\x1b\n\x0c\n\x04\x04\n\x02\0\x12\x04\xc3\ - \x01\x04!\n\r\n\x05\x04\n\x02\0\x04\x12\x04\xc3\x01\x04\x0c\n\r\n\x05\ - \x04\n\x02\0\x05\x12\x04\xc3\x01\r\x13\n\r\n\x05\x04\n\x02\0\x01\x12\x04\ - \xc3\x01\x14\x1c\n\r\n\x05\x04\n\x02\0\x03\x12\x04\xc3\x01\x1f\x20\n\x0c\ - \n\x04\x04\n\x02\x01\x12\x04\xc4\x01\x04)\n\r\n\x05\x04\n\x02\x01\x04\ + \x04\n\x01\x12\x04\xc2\x01\x08\x0c\n\x0c\n\x04\x04\n\x02\0\x12\x04\xc3\ + \x01\x04\x1a\n\r\n\x05\x04\n\x02\0\x04\x12\x04\xc3\x01\x04\x0c\n\r\n\x05\ + \x04\n\x02\0\x05\x12\x04\xc3\x01\r\x12\n\r\n\x05\x04\n\x02\0\x01\x12\x04\ + \xc3\x01\x13\x15\n\r\n\x05\x04\n\x02\0\x03\x12\x04\xc3\x01\x18\x19\n\x0c\ + \n\x04\x04\n\x02\x01\x12\x04\xc4\x01\x04\x1d\n\r\n\x05\x04\n\x02\x01\x04\ \x12\x04\xc4\x01\x04\x0c\n\r\n\x05\x04\n\x02\x01\x05\x12\x04\xc4\x01\r\ - \x11\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\xc4\x01\x12$\n\r\n\x05\x04\n\ - \x02\x01\x03\x12\x04\xc4\x01'(\n\x0c\n\x02\x04\x0b\x12\x06\xc7\x01\0\xde\ - \x01\x01\n\x0b\n\x03\x04\x0b\x01\x12\x04\xc7\x01\x08\x17\nO\n\x04\x04\ - \x0b\x02\0\x12\x04\xc9\x01\x04)\x1aA\x20Should\x20accompany\x20(at\x20le\ - ast)\x20SESSION_INIT\x20and\x20CONFIRM_RECONNECT.\n\n\r\n\x05\x04\x0b\ - \x02\0\x04\x12\x04\xc9\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\0\x05\x12\x04\ - \xc9\x01\r\x13\n\r\n\x05\x04\x0b\x02\0\x01\x12\x04\xc9\x01\x14$\n\r\n\ - \x05\x04\x0b\x02\0\x03\x12\x04\xc9\x01'(\nv\n\x04\x04\x0b\x02\x01\x12\ - \x04\xcd\x01\x041\x1ah\x20There\x20might\x20be\x20a\x20state\x20transiti\ - on.\x20May\x20be\x20absent;\x20absence\x20should\x20be\n\x20treated\x20i\ - dentically\x20to\x20NO_CHANGE.\n\n\r\n\x05\x04\x0b\x02\x01\x04\x12\x04\ - \xcd\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x01\x06\x12\x04\xcd\x01\r\x1b\n\r\ - \n\x05\x04\x0b\x02\x01\x01\x12\x04\xcd\x01\x1c,\n\r\n\x05\x04\x0b\x02\ - \x01\x03\x12\x04\xcd\x01/0\nc\n\x04\x04\x0b\x02\x02\x12\x04\xd1\x01\x04(\ - \x1aU\x20The\x20station\x20can\x20send\x20client\x20config\x20info\x20pi\ - ggybacked\n\x20on\x20any\x20message,\x20as\x20it\x20sees\x20fit\n\n\r\n\ - \x05\x04\x0b\x02\x02\x04\x12\x04\xd1\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\ - \x02\x06\x12\x04\xd1\x01\r\x17\n\r\n\x05\x04\x0b\x02\x02\x01\x12\x04\xd1\ - \x01\x18#\n\r\n\x05\x04\x0b\x02\x02\x03\x12\x04\xd1\x01&'\nP\n\x04\x04\ - \x0b\x02\x03\x12\x04\xd4\x01\x04+\x1aB\x20If\x20state_transition\x20==\ - \x20S2C_ERROR,\x20this\x20field\x20is\x20the\x20explanation.\n\n\r\n\x05\ - \x04\x0b\x02\x03\x04\x12\x04\xd4\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x03\ - \x06\x12\x04\xd4\x01\r\x1b\n\r\n\x05\x04\x0b\x02\x03\x01\x12\x04\xd4\x01\ - \x1c&\n\r\n\x05\x04\x0b\x02\x03\x03\x12\x04\xd4\x01)*\nQ\n\x04\x04\x0b\ - \x02\x04\x12\x04\xd7\x01\x04$\x1aC\x20Signals\x20client\x20to\x20stop\ - \x20connecting\x20for\x20following\x20amount\x20of\x20seconds\n\n\r\n\ - \x05\x04\x0b\x02\x04\x04\x12\x04\xd7\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\ - \x04\x05\x12\x04\xd7\x01\r\x13\n\r\n\x05\x04\x0b\x02\x04\x01\x12\x04\xd7\ - \x01\x14\x1f\n\r\n\x05\x04\x0b\x02\x04\x03\x12\x04\xd7\x01\"#\nK\n\x04\ - \x04\x0b\x02\x05\x12\x04\xda\x01\x04#\x1a=\x20Sent\x20in\x20SESSION_INIT\ - ,\x20identifies\x20the\x20station\x20that\x20picked\x20up\n\n\r\n\x05\ - \x04\x0b\x02\x05\x04\x12\x04\xda\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x05\ - \x05\x12\x04\xda\x01\r\x13\n\r\n\x05\x04\x0b\x02\x05\x01\x12\x04\xda\x01\ - \x14\x1e\n\r\n\x05\x04\x0b\x02\x05\x03\x12\x04\xda\x01!\"\nG\n\x04\x04\ - \x0b\x02\x06\x12\x04\xdd\x01\x04!\x1a9\x20Random-sized\x20junk\x20to\x20\ - defeat\x20packet\x20size\x20fingerprinting.\n\n\r\n\x05\x04\x0b\x02\x06\ - \x04\x12\x04\xdd\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x06\x05\x12\x04\xdd\ - \x01\r\x12\n\r\n\x05\x04\x0b\x02\x06\x01\x12\x04\xdd\x01\x13\x1a\n\r\n\ - \x05\x04\x0b\x02\x06\x03\x12\x04\xdd\x01\x1d\x20\n\x0c\n\x02\x04\x0c\x12\ - \x06\xe0\x01\0\xe6\x01\x01\n\x0b\n\x03\x04\x0c\x01\x12\x04\xe0\x01\x08\ - \x19\n\x0c\n\x04\x04\x0c\x02\0\x12\x04\xe1\x01\x08&\n\r\n\x05\x04\x0c\ - \x02\0\x04\x12\x04\xe1\x01\x08\x10\n\r\n\x05\x04\x0c\x02\0\x05\x12\x04\ - \xe1\x01\x11\x15\n\r\n\x05\x04\x0c\x02\0\x01\x12\x04\xe1\x01\x16!\n\r\n\ - \x05\x04\x0c\x02\0\x03\x12\x04\xe1\x01$%\n\x0c\n\x04\x04\x0c\x02\x01\x12\ - \x04\xe2\x01\x08%\n\r\n\x05\x04\x0c\x02\x01\x04\x12\x04\xe2\x01\x08\x10\ - \n\r\n\x05\x04\x0c\x02\x01\x05\x12\x04\xe2\x01\x11\x15\n\r\n\x05\x04\x0c\ - \x02\x01\x01\x12\x04\xe2\x01\x16\x20\n\r\n\x05\x04\x0c\x02\x01\x03\x12\ - \x04\xe2\x01#$\n\x0c\n\x04\x04\x0c\x02\x02\x12\x04\xe3\x01\x08'\n\r\n\ - \x05\x04\x0c\x02\x02\x04\x12\x04\xe3\x01\x08\x10\n\r\n\x05\x04\x0c\x02\ - \x02\x05\x12\x04\xe3\x01\x11\x15\n\r\n\x05\x04\x0c\x02\x02\x01\x12\x04\ - \xe3\x01\x16\"\n\r\n\x05\x04\x0c\x02\x02\x03\x12\x04\xe3\x01%&\n\x0c\n\ - \x04\x04\x0c\x02\x03\x12\x04\xe4\x01\x04\x1e\n\r\n\x05\x04\x0c\x02\x03\ - \x04\x12\x04\xe4\x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x03\x05\x12\x04\xe4\ - \x01\r\x11\n\r\n\x05\x04\x0c\x02\x03\x01\x12\x04\xe4\x01\x12\x19\n\r\n\ - \x05\x04\x0c\x02\x03\x03\x12\x04\xe4\x01\x1c\x1d\n\x0c\n\x04\x04\x0c\x02\ - \x04\x12\x04\xe5\x01\x04!\n\r\n\x05\x04\x0c\x02\x04\x04\x12\x04\xe5\x01\ - \x04\x0c\n\r\n\x05\x04\x0c\x02\x04\x05\x12\x04\xe5\x01\r\x11\n\r\n\x05\ - \x04\x0c\x02\x04\x01\x12\x04\xe5\x01\x12\x1c\n\r\n\x05\x04\x0c\x02\x04\ - \x03\x12\x04\xe5\x01\x1f\x20\n\x0c\n\x02\x04\r\x12\x06\xe8\x01\0\xa2\x02\ - \x01\n\x0b\n\x03\x04\r\x01\x12\x04\xe8\x01\x08\x17\n\x0c\n\x04\x04\r\x02\ - \0\x12\x04\xe9\x01\x04)\n\r\n\x05\x04\r\x02\0\x04\x12\x04\xe9\x01\x04\ - \x0c\n\r\n\x05\x04\r\x02\0\x05\x12\x04\xe9\x01\r\x13\n\r\n\x05\x04\r\x02\ - \0\x01\x12\x04\xe9\x01\x14$\n\r\n\x05\x04\r\x02\0\x03\x12\x04\xe9\x01'(\ - \n\xd0\x01\n\x04\x04\r\x02\x01\x12\x04\xee\x01\x04.\x1a\xc1\x01\x20The\ - \x20client\x20reports\x20its\x20decoy\x20list's\x20version\x20number\x20\ - here,\x20which\x20the\n\x20station\x20can\x20use\x20to\x20decide\x20whet\ - her\x20to\x20send\x20an\x20updated\x20one.\x20The\x20station\n\x20should\ - \x20always\x20send\x20a\x20list\x20if\x20this\x20field\x20is\x20set\x20t\ - o\x200.\n\n\r\n\x05\x04\r\x02\x01\x04\x12\x04\xee\x01\x04\x0c\n\r\n\x05\ - \x04\r\x02\x01\x05\x12\x04\xee\x01\r\x13\n\r\n\x05\x04\r\x02\x01\x01\x12\ - \x04\xee\x01\x14)\n\r\n\x05\x04\r\x02\x01\x03\x12\x04\xee\x01,-\n\x0c\n\ - \x04\x04\r\x02\x02\x12\x04\xf0\x01\x041\n\r\n\x05\x04\r\x02\x02\x04\x12\ - \x04\xf0\x01\x04\x0c\n\r\n\x05\x04\r\x02\x02\x06\x12\x04\xf0\x01\r\x1b\n\ - \r\n\x05\x04\r\x02\x02\x01\x12\x04\xf0\x01\x1c,\n\r\n\x05\x04\r\x02\x02\ - \x03\x12\x04\xf0\x01/0\n\x80\x01\n\x04\x04\r\x02\x03\x12\x04\xf4\x01\x04\ - $\x1ar\x20The\x20position\x20in\x20the\x20overall\x20session's\x20upload\ - \x20sequence\x20where\x20the\x20current\n\x20YIELD=>ACQUIRE\x20switchove\ - r\x20is\x20happening.\n\n\r\n\x05\x04\r\x02\x03\x04\x12\x04\xf4\x01\x04\ - \x0c\n\r\n\x05\x04\r\x02\x03\x05\x12\x04\xf4\x01\r\x13\n\r\n\x05\x04\r\ - \x02\x03\x01\x12\x04\xf4\x01\x14\x1f\n\r\n\x05\x04\r\x02\x03\x03\x12\x04\ - \xf4\x01\"#\ng\n\x04\x04\r\x02\x04\x12\x04\xf8\x01\x04+\x1aY\x20High\x20\ - level\x20client\x20library\x20version\x20used\x20for\x20indicating\x20fe\ - ature\x20support,\x20or\n\x20lack\x20therof.\n\n\r\n\x05\x04\r\x02\x04\ - \x04\x12\x04\xf8\x01\x04\x0c\n\r\n\x05\x04\r\x02\x04\x05\x12\x04\xf8\x01\ - \r\x13\n\r\n\x05\x04\r\x02\x04\x01\x12\x04\xf8\x01\x14&\n\r\n\x05\x04\r\ - \x02\x04\x03\x12\x04\xf8\x01)*\n\xa5\x02\n\x04\x04\r\x02\x05\x12\x04\xfd\ - \x01\x042\x1a\x96\x02\x20Indicates\x20whether\x20the\x20client\x20will\ - \x20allow\x20the\x20registrar\x20to\x20provide\x20alternative\x20paramet\ - ers\x20that\n\x20may\x20work\x20better\x20in\x20substitute\x20for\x20the\ - \x20deterministically\x20selected\x20parameters.\x20This\x20only\x20work\ - s\n\x20for\x20bidirectional\x20registration\x20methods\x20where\x20the\ - \x20client\x20receives\x20a\x20RegistrationResponse.\n\n\r\n\x05\x04\r\ - \x02\x05\x04\x12\x04\xfd\x01\x04\x0c\n\r\n\x05\x04\r\x02\x05\x05\x12\x04\ - \xfd\x01\r\x11\n\r\n\x05\x04\r\x02\x05\x01\x12\x04\xfd\x01\x12-\n\r\n\ - \x05\x04\r\x02\x05\x03\x12\x04\xfd\x0101\nq\n\x04\x04\r\x02\x06\x12\x04\ - \x81\x02\x04'\x1ac\x20List\x20of\x20decoys\x20that\x20client\x20have\x20\ - unsuccessfully\x20tried\x20in\x20current\x20session.\n\x20Could\x20be\ - \x20sent\x20in\x20chunks\n\n\r\n\x05\x04\r\x02\x06\x04\x12\x04\x81\x02\ - \x04\x0c\n\r\n\x05\x04\r\x02\x06\x05\x12\x04\x81\x02\r\x13\n\r\n\x05\x04\ - \r\x02\x06\x01\x12\x04\x81\x02\x14!\n\r\n\x05\x04\r\x02\x06\x03\x12\x04\ - \x81\x02$&\n\x0c\n\x04\x04\r\x02\x07\x12\x04\x83\x02\x04%\n\r\n\x05\x04\ - \r\x02\x07\x04\x12\x04\x83\x02\x04\x0c\n\r\n\x05\x04\r\x02\x07\x06\x12\ - \x04\x83\x02\r\x19\n\r\n\x05\x04\r\x02\x07\x01\x12\x04\x83\x02\x1a\x1f\n\ - \r\n\x05\x04\r\x02\x07\x03\x12\x04\x83\x02\"$\nk\n\x04\x04\r\x02\x08\x12\ - \x04\x86\x02\x04*\x1a]\x20NullTransport,\x20MinTransport,\x20Obfs4Transp\ - ort,\x20etc.\x20Transport\x20type\x20we\x20want\x20from\x20phantom\x20pr\ - oxy\n\n\r\n\x05\x04\r\x02\x08\x04\x12\x04\x86\x02\x04\x0c\n\r\n\x05\x04\ - \r\x02\x08\x06\x12\x04\x86\x02\r\x1a\n\r\n\x05\x04\r\x02\x08\x01\x12\x04\ - \x86\x02\x1b$\n\r\n\x05\x04\r\x02\x08\x03\x12\x04\x86\x02')\n\x0c\n\x04\ - \x04\r\x02\t\x12\x04\x88\x02\x047\n\r\n\x05\x04\r\x02\t\x04\x12\x04\x88\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\t\x06\x12\x04\x88\x02\r\x20\n\r\n\x05\ - \x04\r\x02\t\x01\x12\x04\x88\x02!1\n\r\n\x05\x04\r\x02\t\x03\x12\x04\x88\ - \x0246\n\xc8\x03\n\x04\x04\r\x02\n\x12\x04\x90\x02\x04(\x1a\xb9\x03\x20S\ - tation\x20is\x20only\x20required\x20to\x20check\x20this\x20variable\x20d\ - uring\x20session\x20initialization.\n\x20If\x20set,\x20station\x20must\ - \x20facilitate\x20connection\x20to\x20said\x20target\x20by\x20itself,\ - \x20i.e.\x20write\x20into\x20squid\n\x20socket\x20an\x20HTTP/SOCKS/any\ - \x20other\x20connection\x20request.\n\x20covert_address\x20must\x20have\ - \x20exactly\x20one\x20':'\x20colon,\x20that\x20separates\x20host\x20(lit\ - eral\x20IP\x20address\x20or\n\x20resolvable\x20hostname)\x20and\x20port\ - \n\x20TODO:\x20make\x20it\x20required\x20for\x20initialization,\x20and\ - \x20stop\x20connecting\x20any\x20client\x20straight\x20to\x20squid?\n\n\ - \r\n\x05\x04\r\x02\n\x04\x12\x04\x90\x02\x04\x0c\n\r\n\x05\x04\r\x02\n\ - \x05\x12\x04\x90\x02\r\x13\n\r\n\x05\x04\r\x02\n\x01\x12\x04\x90\x02\x14\ - \"\n\r\n\x05\x04\r\x02\n\x03\x12\x04\x90\x02%'\nR\n\x04\x04\r\x02\x0b\ - \x12\x04\x93\x02\x042\x1aD\x20Used\x20in\x20dark\x20decoys\x20to\x20sign\ - al\x20which\x20dark\x20decoy\x20it\x20will\x20connect\x20to.\n\n\r\n\x05\ - \x04\r\x02\x0b\x04\x12\x04\x93\x02\x04\x0c\n\r\n\x05\x04\r\x02\x0b\x05\ - \x12\x04\x93\x02\r\x13\n\r\n\x05\x04\r\x02\x0b\x01\x12\x04\x93\x02\x14,\ - \n\r\n\x05\x04\r\x02\x0b\x03\x12\x04\x93\x02/1\nR\n\x04\x04\r\x02\x0c\ - \x12\x04\x96\x02\x04\"\x1aD\x20Used\x20to\x20indicate\x20to\x20server\ - \x20if\x20client\x20is\x20registering\x20v4,\x20v6\x20or\x20both\n\n\r\n\ - \x05\x04\r\x02\x0c\x04\x12\x04\x96\x02\x04\x0c\n\r\n\x05\x04\r\x02\x0c\ - \x05\x12\x04\x96\x02\r\x11\n\r\n\x05\x04\r\x02\x0c\x01\x12\x04\x96\x02\ - \x12\x1c\n\r\n\x05\x04\r\x02\x0c\x03\x12\x04\x96\x02\x1f!\n\x0c\n\x04\ - \x04\r\x02\r\x12\x04\x97\x02\x04\"\n\r\n\x05\x04\r\x02\r\x04\x12\x04\x97\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\r\x05\x12\x04\x97\x02\r\x11\n\r\n\x05\ - \x04\r\x02\r\x01\x12\x04\x97\x02\x12\x1c\n\r\n\x05\x04\r\x02\r\x03\x12\ - \x04\x97\x02\x1f!\nD\n\x04\x04\r\x02\x0e\x12\x04\x9a\x02\x04*\x1a6\x20A\ - \x20collection\x20of\x20optional\x20flags\x20for\x20the\x20registration.\ - \n\n\r\n\x05\x04\r\x02\x0e\x04\x12\x04\x9a\x02\x04\x0c\n\r\n\x05\x04\r\ - \x02\x0e\x06\x12\x04\x9a\x02\r\x1e\n\r\n\x05\x04\r\x02\x0e\x01\x12\x04\ - \x9a\x02\x1f$\n\r\n\x05\x04\r\x02\x0e\x03\x12\x04\x9a\x02')\nq\n\x04\x04\ - \r\x02\x0f\x12\x04\x9e\x02\x04-\x1ac\x20Transport\x20Extensions\n\x20TOD\ - O(jmwample)\x20-\x20move\x20to\x20WebRTC\x20specific\x20transport\x20par\ - ams\x20protobuf\x20message.\n\n\r\n\x05\x04\r\x02\x0f\x04\x12\x04\x9e\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\x0f\x06\x12\x04\x9e\x02\r\x19\n\r\n\x05\ - \x04\r\x02\x0f\x01\x12\x04\x9e\x02\x1a'\n\r\n\x05\x04\r\x02\x0f\x03\x12\ - \x04\x9e\x02*,\nG\n\x04\x04\r\x02\x10\x12\x04\xa1\x02\x04!\x1a9\x20Rando\ - m-sized\x20junk\x20to\x20defeat\x20packet\x20size\x20fingerprinting.\n\n\ - \r\n\x05\x04\r\x02\x10\x04\x12\x04\xa1\x02\x04\x0c\n\r\n\x05\x04\r\x02\ - \x10\x05\x12\x04\xa1\x02\r\x12\n\r\n\x05\x04\r\x02\x10\x01\x12\x04\xa1\ - \x02\x13\x1a\n\r\n\x05\x04\r\x02\x10\x03\x12\x04\xa1\x02\x1d\x20\n\x0c\n\ - \x02\x04\x0e\x12\x06\xa5\x02\0\xb7\x02\x01\n\x0b\n\x03\x04\x0e\x01\x12\ - \x04\xa5\x02\x08\x1d\n!\n\x04\x04\x0e\x02\0\x12\x04\xa7\x02\x04!\x1a\x13\ - \x20Prefix\x20Identifier\n\n\r\n\x05\x04\x0e\x02\0\x04\x12\x04\xa7\x02\ - \x04\x0c\n\r\n\x05\x04\x0e\x02\0\x05\x12\x04\xa7\x02\r\x12\n\r\n\x05\x04\ - \x0e\x02\0\x01\x12\x04\xa7\x02\x13\x1c\n\r\n\x05\x04\x0e\x02\0\x03\x12\ - \x04\xa7\x02\x1f\x20\n\xc4\x01\n\x04\x04\x0e\x02\x01\x12\x04\xab\x02\x04\ - \x1e\x1a\xb5\x01\x20Prefix\x20bytes\x20(optional\x20-\x20usually\x20sent\ - \x20from\x20station\x20to\x20client\x20as\x20override\x20if\x20allowed\ - \x20by\x20C2S)\n\x20as\x20the\x20station\x20cannot\x20take\x20this\x20in\ - to\x20account\x20when\x20attempting\x20to\x20identify\x20a\x20connection\ - .\n\n\r\n\x05\x04\x0e\x02\x01\x04\x12\x04\xab\x02\x04\x0c\n\r\n\x05\x04\ - \x0e\x02\x01\x05\x12\x04\xab\x02\r\x12\n\r\n\x05\x04\x0e\x02\x01\x01\x12\ - \x04\xab\x02\x13\x19\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xab\x02\x1c\ - \x1d\n\x0c\n\x04\x04\x0e\x02\x02\x12\x04\xac\x02\x04+\n\r\n\x05\x04\x0e\ - \x02\x02\x04\x12\x04\xac\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x02\x05\x12\ - \x04\xac\x02\r\x12\n\r\n\x05\x04\x0e\x02\x02\x01\x12\x04\xac\x02\x13&\n\ - \r\n\x05\x04\x0e\x02\x02\x03\x12\x04\xac\x02)*\n\xed\x02\n\x04\x04\x0e\ - \x02\x03\x12\x04\xb6\x02\x04*\x1a\xbc\x01\x20Indicates\x20whether\x20the\ - \x20client\x20has\x20elected\x20to\x20use\x20destination\x20port\x20rand\ - omization.\x20Should\x20be\n\x20checked\x20against\x20selected\x20transp\ - ort\x20to\x20ensure\x20that\x20destination\x20port\x20randomization\x20i\ - s\n\x20supported.\n2\x9f\x01\x20//\x20potential\x20future\x20fields\n\ - \x20obfuscator\x20ID\n\x20tagEncoder\x20ID\x20(¶ms?,\x20e.g.\x20form\ - at-base64\x20/\x20padding)\n\x20streamEncoder\x20ID\x20(¶ms?,\x20e.g\ - .\x20foramat-base64\x20/\x20padding)\n\n\r\n\x05\x04\x0e\x02\x03\x04\x12\ - \x04\xb6\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x03\x05\x12\x04\xb6\x02\r\x11\ - \n\r\n\x05\x04\x0e\x02\x03\x01\x12\x04\xb6\x02\x12$\n\r\n\x05\x04\x0e\ - \x02\x03\x03\x12\x04\xb6\x02')\n\x0c\n\x02\x04\x0f\x12\x06\xb9\x02\0\xbe\ - \x02\x01\n\x0b\n\x03\x04\x0f\x01\x12\x04\xb9\x02\x08\x1e\n\xcb\x01\n\x04\ - \x04\x0f\x02\0\x12\x04\xbd\x02\x04*\x1a\xbc\x01\x20Indicates\x20whether\ - \x20the\x20client\x20has\x20elected\x20to\x20use\x20destination\x20port\ - \x20randomization.\x20Should\x20be\n\x20checked\x20against\x20selected\ - \x20transport\x20to\x20ensure\x20that\x20destination\x20port\x20randomiz\ - ation\x20is\n\x20supported.\n\n\r\n\x05\x04\x0f\x02\0\x04\x12\x04\xbd\ - \x02\x04\x0c\n\r\n\x05\x04\x0f\x02\0\x05\x12\x04\xbd\x02\r\x11\n\r\n\x05\ - \x04\x0f\x02\0\x01\x12\x04\xbd\x02\x12$\n\r\n\x05\x04\x0f\x02\0\x03\x12\ - \x04\xbd\x02')\n\x0c\n\x02\x05\x06\x12\x06\xc0\x02\0\xc8\x02\x01\n\x0b\n\ - \x03\x05\x06\x01\x12\x04\xc0\x02\x05\x17\n\x0c\n\x04\x05\x06\x02\0\x12\ - \x04\xc1\x02\x02\x12\n\r\n\x05\x05\x06\x02\0\x01\x12\x04\xc1\x02\x02\r\n\ - \r\n\x05\x05\x06\x02\0\x02\x12\x04\xc1\x02\x10\x11\n\x0c\n\x04\x05\x06\ - \x02\x01\x12\x04\xc2\x02\x08\x15\n\r\n\x05\x05\x06\x02\x01\x01\x12\x04\ - \xc2\x02\x08\x10\n\r\n\x05\x05\x06\x02\x01\x02\x12\x04\xc2\x02\x13\x14\n\ - \x0c\n\x04\x05\x06\x02\x02\x12\x04\xc3\x02\x08\x10\n\r\n\x05\x05\x06\x02\ - \x02\x01\x12\x04\xc3\x02\x08\x0b\n\r\n\x05\x05\x06\x02\x02\x02\x12\x04\ - \xc3\x02\x0e\x0f\n\x0c\n\x04\x05\x06\x02\x03\x12\x04\xc4\x02\x02\x16\n\r\ - \n\x05\x05\x06\x02\x03\x01\x12\x04\xc4\x02\x02\x11\n\r\n\x05\x05\x06\x02\ - \x03\x02\x12\x04\xc4\x02\x14\x15\n\x0c\n\x04\x05\x06\x02\x04\x12\x04\xc5\ - \x02\x02\x17\n\r\n\x05\x05\x06\x02\x04\x01\x12\x04\xc5\x02\x02\x12\n\r\n\ - \x05\x05\x06\x02\x04\x02\x12\x04\xc5\x02\x15\x16\n\x0c\n\x04\x05\x06\x02\ - \x05\x12\x04\xc6\x02\x02\n\n\r\n\x05\x05\x06\x02\x05\x01\x12\x04\xc6\x02\ - \x02\x05\n\r\n\x05\x05\x06\x02\x05\x02\x12\x04\xc6\x02\x08\t\n\x0c\n\x04\ - \x05\x06\x02\x06\x12\x04\xc7\x02\x02\x17\n\r\n\x05\x05\x06\x02\x06\x01\ - \x12\x04\xc7\x02\x02\x12\n\r\n\x05\x05\x06\x02\x06\x02\x12\x04\xc7\x02\ - \x15\x16\n\x0c\n\x02\x04\x10\x12\x06\xca\x02\0\xe2\x02\x01\n\x0b\n\x03\ - \x04\x10\x01\x12\x04\xca\x02\x08\x12\n\x0c\n\x04\x04\x10\x02\0\x12\x04\ - \xcb\x02\x02#\n\r\n\x05\x04\x10\x02\0\x04\x12\x04\xcb\x02\x02\n\n\r\n\ - \x05\x04\x10\x02\0\x05\x12\x04\xcb\x02\x0b\x10\n\r\n\x05\x04\x10\x02\0\ - \x01\x12\x04\xcb\x02\x11\x1e\n\r\n\x05\x04\x10\x02\0\x03\x12\x04\xcb\x02\ - !\"\n\x0c\n\x04\x04\x10\x02\x01\x12\x04\xcc\x02\x024\n\r\n\x05\x04\x10\ - \x02\x01\x04\x12\x04\xcc\x02\x02\n\n\r\n\x05\x04\x10\x02\x01\x06\x12\x04\ - \xcc\x02\x0b\x1a\n\r\n\x05\x04\x10\x02\x01\x01\x12\x04\xcc\x02\x1b/\n\r\ - \n\x05\x04\x10\x02\x01\x03\x12\x04\xcc\x0223\n\x0c\n\x04\x04\x10\x02\x02\ - \x12\x04\xcd\x02\x026\n\r\n\x05\x04\x10\x02\x02\x04\x12\x04\xcd\x02\x02\ - \n\n\r\n\x05\x04\x10\x02\x02\x06\x12\x04\xcd\x02\x0b\x1d\n\r\n\x05\x04\ - \x10\x02\x02\x01\x12\x04\xcd\x02\x1e1\n\r\n\x05\x04\x10\x02\x02\x03\x12\ - \x04\xcd\x0245\nC\n\x04\x04\x10\x02\x03\x12\x04\xd0\x02\x02*\x1a5\x20cli\ - ent\x20source\x20address\x20when\x20receiving\x20a\x20registration\n\n\r\ - \n\x05\x04\x10\x02\x03\x04\x12\x04\xd0\x02\x02\n\n\r\n\x05\x04\x10\x02\ - \x03\x05\x12\x04\xd0\x02\x0b\x10\n\r\n\x05\x04\x10\x02\x03\x01\x12\x04\ - \xd0\x02\x11%\n\r\n\x05\x04\x10\x02\x03\x03\x12\x04\xd0\x02()\nH\n\x04\ - \x04\x10\x02\x04\x12\x04\xd3\x02\x02#\x1a:\x20Decoy\x20address\x20used\ - \x20when\x20registering\x20over\x20Decoy\x20registrar\n\n\r\n\x05\x04\ - \x10\x02\x04\x04\x12\x04\xd3\x02\x02\n\n\r\n\x05\x04\x10\x02\x04\x05\x12\ - \x04\xd3\x02\x0b\x10\n\r\n\x05\x04\x10\x02\x04\x01\x12\x04\xd3\x02\x11\ - \x1e\n\r\n\x05\x04\x10\x02\x04\x03\x12\x04\xd3\x02!\"\n\xeb\x05\n\x04\ - \x04\x10\x02\x05\x12\x04\xdf\x02\x02:\x1a\xdc\x05\x20The\x20next\x20thre\ - e\x20fields\x20allow\x20an\x20independent\x20registrar\x20(trusted\x20by\ - \x20a\x20station\x20w/\x20a\x20zmq\x20keypair)\x20to\n\x20share\x20the\ - \x20registration\x20overrides\x20that\x20it\x20assigned\x20to\x20the\x20\ - client\x20with\x20the\x20station(s).\n\x20Registration\x20Respose\x20is\ - \x20here\x20to\x20allow\x20a\x20parsed\x20object\x20with\x20direct\x20ac\ - cess\x20to\x20the\x20fields\x20within.\n\x20RegRespBytes\x20provides\x20\ - a\x20serialized\x20verion\x20of\x20the\x20Registration\x20response\x20so\ - \x20that\x20the\x20signature\x20of\n\x20the\x20Bidirectional\x20registra\ - r\x20can\x20be\x20validated\x20before\x20a\x20station\x20applies\x20any\ - \x20overrides\x20present\x20in\n\x20the\x20Registration\x20Response.\n\n\ - \x20If\x20you\x20are\x20reading\x20this\x20in\x20the\x20future\x20and\ - \x20you\x20want\x20to\x20extend\x20the\x20functionality\x20here\x20it\ - \x20might\n\x20make\x20sense\x20to\x20make\x20the\x20RegistrationRespons\ - e\x20that\x20is\x20sent\x20to\x20the\x20client\x20a\x20distinct\x20messa\ - ge\x20from\n\x20the\x20one\x20that\x20gets\x20sent\x20to\x20the\x20stati\ - ons.\n\n\r\n\x05\x04\x10\x02\x05\x04\x12\x04\xdf\x02\x02\n\n\r\n\x05\x04\ - \x10\x02\x05\x06\x12\x04\xdf\x02\x0b\x1f\n\r\n\x05\x04\x10\x02\x05\x01\ - \x12\x04\xdf\x02\x205\n\r\n\x05\x04\x10\x02\x05\x03\x12\x04\xdf\x0289\n\ - \x0c\n\x04\x04\x10\x02\x06\x12\x04\xe0\x02\x02\"\n\r\n\x05\x04\x10\x02\ - \x06\x04\x12\x04\xe0\x02\x02\n\n\r\n\x05\x04\x10\x02\x06\x05\x12\x04\xe0\ - \x02\x0b\x10\n\r\n\x05\x04\x10\x02\x06\x01\x12\x04\xe0\x02\x11\x1d\n\r\n\ - \x05\x04\x10\x02\x06\x03\x12\x04\xe0\x02\x20!\n\x0c\n\x04\x04\x10\x02\ - \x07\x12\x04\xe1\x02\x02'\n\r\n\x05\x04\x10\x02\x07\x04\x12\x04\xe1\x02\ - \x02\n\n\r\n\x05\x04\x10\x02\x07\x05\x12\x04\xe1\x02\x0b\x10\n\r\n\x05\ - \x04\x10\x02\x07\x01\x12\x04\xe1\x02\x11!\n\r\n\x05\x04\x10\x02\x07\x03\ - \x12\x04\xe1\x02$&\n\x0c\n\x02\x04\x11\x12\x06\xe4\x02\0\xf0\x02\x01\n\ - \x0b\n\x03\x04\x11\x01\x12\x04\xe4\x02\x08\x14\n9\n\x04\x04\x11\x02\0\ - \x12\x04\xe5\x02\x04.\"+\x20how\x20many\x20decoys\x20were\x20tried\x20be\ - fore\x20success\n\n\r\n\x05\x04\x11\x02\0\x04\x12\x04\xe5\x02\x04\x0c\n\ - \r\n\x05\x04\x11\x02\0\x05\x12\x04\xe5\x02\r\x13\n\r\n\x05\x04\x11\x02\0\ - \x01\x12\x04\xe5\x02\x14(\n\r\n\x05\x04\x11\x02\0\x03\x12\x04\xe5\x02+-\ - \nm\n\x04\x04\x11\x02\x01\x12\x04\xea\x02\x04/\x1a\x1e\x20Applicable\x20\ - to\x20whole\x20session:\n\"\x1a\x20includes\x20failed\x20attempts\n2#\ - \x20Timings\x20below\x20are\x20in\x20milliseconds\n\n\r\n\x05\x04\x11\ - \x02\x01\x04\x12\x04\xea\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x01\x05\x12\ - \x04\xea\x02\r\x13\n\r\n\x05\x04\x11\x02\x01\x01\x12\x04\xea\x02\x14)\n\ - \r\n\x05\x04\x11\x02\x01\x03\x12\x04\xea\x02,.\nR\n\x04\x04\x11\x02\x02\ - \x12\x04\xed\x02\x04(\x1a\x1f\x20Last\x20(i.e.\x20successful)\x20decoy:\ - \n\"#\x20measured\x20during\x20initial\x20handshake\n\n\r\n\x05\x04\x11\ - \x02\x02\x04\x12\x04\xed\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x02\x05\x12\ - \x04\xed\x02\r\x13\n\r\n\x05\x04\x11\x02\x02\x01\x12\x04\xed\x02\x14\"\n\ - \r\n\x05\x04\x11\x02\x02\x03\x12\x04\xed\x02%'\n%\n\x04\x04\x11\x02\x03\ - \x12\x04\xee\x02\x04&\"\x17\x20includes\x20tcp\x20to\x20decoy\n\n\r\n\ - \x05\x04\x11\x02\x03\x04\x12\x04\xee\x02\x04\x0c\n\r\n\x05\x04\x11\x02\ - \x03\x05\x12\x04\xee\x02\r\x13\n\r\n\x05\x04\x11\x02\x03\x01\x12\x04\xee\ - \x02\x14\x20\n\r\n\x05\x04\x11\x02\x03\x03\x12\x04\xee\x02#%\nB\n\x04\ - \x04\x11\x02\x04\x12\x04\xef\x02\x04&\"4\x20measured\x20when\x20establis\ - hing\x20tcp\x20connection\x20to\x20decot\n\n\r\n\x05\x04\x11\x02\x04\x04\ - \x12\x04\xef\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x04\x05\x12\x04\xef\x02\r\ - \x13\n\r\n\x05\x04\x11\x02\x04\x01\x12\x04\xef\x02\x14\x20\n\r\n\x05\x04\ - \x11\x02\x04\x03\x12\x04\xef\x02#%\n\x0c\n\x02\x05\x07\x12\x06\xf2\x02\0\ - \xf7\x02\x01\n\x0b\n\x03\x05\x07\x01\x12\x04\xf2\x02\x05\x16\n\x0c\n\x04\ - \x05\x07\x02\0\x12\x04\xf3\x02\x04\x10\n\r\n\x05\x05\x07\x02\0\x01\x12\ - \x04\xf3\x02\x04\x0b\n\r\n\x05\x05\x07\x02\0\x02\x12\x04\xf3\x02\x0e\x0f\ - \n\x0c\n\x04\x05\x07\x02\x01\x12\x04\xf4\x02\x04\x0c\n\r\n\x05\x05\x07\ - \x02\x01\x01\x12\x04\xf4\x02\x04\x07\n\r\n\x05\x05\x07\x02\x01\x02\x12\ - \x04\xf4\x02\n\x0b\n\x0c\n\x04\x05\x07\x02\x02\x12\x04\xf5\x02\x04\x0f\n\ - \r\n\x05\x05\x07\x02\x02\x01\x12\x04\xf5\x02\x04\n\n\r\n\x05\x05\x07\x02\ - \x02\x02\x12\x04\xf5\x02\r\x0e\n\x0c\n\x04\x05\x07\x02\x03\x12\x04\xf6\ - \x02\x04\x0e\n\r\n\x05\x05\x07\x02\x03\x01\x12\x04\xf6\x02\x04\t\n\r\n\ - \x05\x05\x07\x02\x03\x02\x12\x04\xf6\x02\x0c\r\n\x0c\n\x02\x05\x08\x12\ - \x06\xf9\x02\0\xfd\x02\x01\n\x0b\n\x03\x05\x08\x01\x12\x04\xf9\x02\x05\ - \x0c\n\x0c\n\x04\x05\x08\x02\0\x12\x04\xfa\x02\x04\x0c\n\r\n\x05\x05\x08\ - \x02\0\x01\x12\x04\xfa\x02\x04\x07\n\r\n\x05\x05\x08\x02\0\x02\x12\x04\ - \xfa\x02\n\x0b\n\x0c\n\x04\x05\x08\x02\x01\x12\x04\xfb\x02\x04\x0c\n\r\n\ - \x05\x05\x08\x02\x01\x01\x12\x04\xfb\x02\x04\x07\n\r\n\x05\x05\x08\x02\ - \x01\x02\x12\x04\xfb\x02\n\x0b\n\x0c\n\x04\x05\x08\x02\x02\x12\x04\xfc\ - \x02\x04\x0c\n\r\n\x05\x05\x08\x02\x02\x01\x12\x04\xfc\x02\x04\x07\n\r\n\ - \x05\x05\x08\x02\x02\x02\x12\x04\xfc\x02\n\x0b\n\x0c\n\x02\x04\x12\x12\ - \x06\xff\x02\0\x8a\x03\x01\n\x0b\n\x03\x04\x12\x01\x12\x04\xff\x02\x08\ - \x19\n\x0c\n\x04\x04\x12\x02\0\x12\x04\x80\x03\x04#\n\r\n\x05\x04\x12\ - \x02\0\x04\x12\x04\x80\x03\x04\x0c\n\r\n\x05\x04\x12\x02\0\x05\x12\x04\ - \x80\x03\r\x13\n\r\n\x05\x04\x12\x02\0\x01\x12\x04\x80\x03\x14\x1e\n\r\n\ - \x05\x04\x12\x02\0\x03\x12\x04\x80\x03!\"\n\x0c\n\x04\x04\x12\x02\x01\ - \x12\x04\x81\x03\x04\"\n\r\n\x05\x04\x12\x02\x01\x04\x12\x04\x81\x03\x04\ - \x0c\n\r\n\x05\x04\x12\x02\x01\x05\x12\x04\x81\x03\r\x13\n\r\n\x05\x04\ - \x12\x02\x01\x01\x12\x04\x81\x03\x14\x1d\n\r\n\x05\x04\x12\x02\x01\x03\ - \x12\x04\x81\x03\x20!\n\x0c\n\x04\x04\x12\x02\x02\x12\x04\x83\x03\x04#\n\ - \r\n\x05\x04\x12\x02\x02\x04\x12\x04\x83\x03\x04\x0c\n\r\n\x05\x04\x12\ - \x02\x02\x05\x12\x04\x83\x03\r\x13\n\r\n\x05\x04\x12\x02\x02\x01\x12\x04\ - \x83\x03\x14\x1e\n\r\n\x05\x04\x12\x02\x02\x03\x12\x04\x83\x03!\"\n\x0c\ - \n\x04\x04\x12\x02\x03\x12\x04\x85\x03\x04-\n\r\n\x05\x04\x12\x02\x03\ - \x04\x12\x04\x85\x03\x04\x0c\n\r\n\x05\x04\x12\x02\x03\x06\x12\x04\x85\ - \x03\r\x1e\n\r\n\x05\x04\x12\x02\x03\x01\x12\x04\x85\x03\x1f(\n\r\n\x05\ - \x04\x12\x02\x03\x03\x12\x04\x85\x03+,\n\x0c\n\x04\x04\x12\x02\x04\x12\ - \x04\x87\x03\x04\"\n\r\n\x05\x04\x12\x02\x04\x04\x12\x04\x87\x03\x04\x0c\ - \n\r\n\x05\x04\x12\x02\x04\x05\x12\x04\x87\x03\r\x13\n\r\n\x05\x04\x12\ - \x02\x04\x01\x12\x04\x87\x03\x14\x1c\n\r\n\x05\x04\x12\x02\x04\x03\x12\ - \x04\x87\x03\x1f!\n\x0c\n\x04\x04\x12\x02\x05\x12\x04\x88\x03\x04\"\n\r\ - \n\x05\x04\x12\x02\x05\x04\x12\x04\x88\x03\x04\x0c\n\r\n\x05\x04\x12\x02\ - \x05\x05\x12\x04\x88\x03\r\x13\n\r\n\x05\x04\x12\x02\x05\x01\x12\x04\x88\ - \x03\x14\x1c\n\r\n\x05\x04\x12\x02\x05\x03\x12\x04\x88\x03\x1f!\n\x0c\n\ - \x04\x04\x12\x02\x06\x12\x04\x89\x03\x04\x20\n\r\n\x05\x04\x12\x02\x06\ - \x04\x12\x04\x89\x03\x04\x0c\n\r\n\x05\x04\x12\x02\x06\x06\x12\x04\x89\ - \x03\r\x14\n\r\n\x05\x04\x12\x02\x06\x01\x12\x04\x89\x03\x15\x1a\n\r\n\ - \x05\x04\x12\x02\x06\x03\x12\x04\x89\x03\x1d\x1f\nT\n\x02\x04\x13\x12\ - \x06\x8d\x03\0\xa1\x03\x01\x1aF\x20Adding\x20message\x20response\x20from\ - \x20Station\x20to\x20Client\x20for\x20bidirectional\x20API\n\n\x0b\n\x03\ - \x04\x13\x01\x12\x04\x8d\x03\x08\x1c\n\x0c\n\x04\x04\x13\x02\0\x12\x04\ - \x8e\x03\x02\x20\n\r\n\x05\x04\x13\x02\0\x04\x12\x04\x8e\x03\x02\n\n\r\n\ - \x05\x04\x13\x02\0\x05\x12\x04\x8e\x03\x0b\x12\n\r\n\x05\x04\x13\x02\0\ - \x01\x12\x04\x8e\x03\x13\x1b\n\r\n\x05\x04\x13\x02\0\x03\x12\x04\x8e\x03\ - \x1e\x1f\n?\n\x04\x04\x13\x02\x01\x12\x04\x90\x03\x02\x1e\x1a1\x20The\ - \x20128-bit\x20ipv6\x20address,\x20in\x20network\x20byte\x20order\n\n\r\ - \n\x05\x04\x13\x02\x01\x04\x12\x04\x90\x03\x02\n\n\r\n\x05\x04\x13\x02\ - \x01\x05\x12\x04\x90\x03\x0b\x10\n\r\n\x05\x04\x13\x02\x01\x01\x12\x04\ - \x90\x03\x11\x19\n\r\n\x05\x04\x13\x02\x01\x03\x12\x04\x90\x03\x1c\x1d\n\ - ,\n\x04\x04\x13\x02\x02\x12\x04\x93\x03\x02\x1f\x1a\x1e\x20Respond\x20wi\ - th\x20randomized\x20port\n\n\r\n\x05\x04\x13\x02\x02\x04\x12\x04\x93\x03\ - \x02\n\n\r\n\x05\x04\x13\x02\x02\x05\x12\x04\x93\x03\x0b\x11\n\r\n\x05\ - \x04\x13\x02\x02\x01\x12\x04\x93\x03\x12\x1a\n\r\n\x05\x04\x13\x02\x02\ - \x03\x12\x04\x93\x03\x1d\x1e\nd\n\x04\x04\x13\x02\x03\x12\x04\x97\x03\ - \x02\"\x1aV\x20Future:\x20station\x20provides\x20client\x20with\x20secre\ - t,\x20want\x20chanel\x20present\n\x20Leave\x20null\x20for\x20now\n\n\r\n\ - \x05\x04\x13\x02\x03\x04\x12\x04\x97\x03\x02\n\n\r\n\x05\x04\x13\x02\x03\ - \x05\x12\x04\x97\x03\x0b\x10\n\r\n\x05\x04\x13\x02\x03\x01\x12\x04\x97\ - \x03\x11\x1d\n\r\n\x05\x04\x13\x02\x03\x03\x12\x04\x97\x03\x20!\nA\n\x04\ - \x04\x13\x02\x04\x12\x04\x9a\x03\x02\x1c\x1a3\x20If\x20registration\x20w\ - rong,\x20populate\x20this\x20error\x20string\n\n\r\n\x05\x04\x13\x02\x04\ - \x04\x12\x04\x9a\x03\x02\n\n\r\n\x05\x04\x13\x02\x04\x05\x12\x04\x9a\x03\ - \x0b\x11\n\r\n\x05\x04\x13\x02\x04\x01\x12\x04\x9a\x03\x12\x17\n\r\n\x05\ - \x04\x13\x02\x04\x03\x12\x04\x9a\x03\x1a\x1b\n+\n\x04\x04\x13\x02\x05\ - \x12\x04\x9d\x03\x02%\x1a\x1d\x20ClientConf\x20field\x20(optional)\n\n\r\ - \n\x05\x04\x13\x02\x05\x04\x12\x04\x9d\x03\x02\n\n\r\n\x05\x04\x13\x02\ - \x05\x06\x12\x04\x9d\x03\x0b\x15\n\r\n\x05\x04\x13\x02\x05\x01\x12\x04\ - \x9d\x03\x16\x20\n\r\n\x05\x04\x13\x02\x05\x03\x12\x04\x9d\x03#$\nJ\n\ - \x04\x04\x13\x02\x06\x12\x04\xa0\x03\x025\x1a<\x20Transport\x20Params\ - \x20to\x20if\x20`allow_registrar_overrides`\x20is\x20set.\n\n\r\n\x05\ - \x04\x13\x02\x06\x04\x12\x04\xa0\x03\x02\n\n\r\n\x05\x04\x13\x02\x06\x06\ - \x12\x04\xa0\x03\x0b\x1e\n\r\n\x05\x04\x13\x02\x06\x01\x12\x04\xa0\x03\ - \x1f/\n\r\n\x05\x04\x13\x02\x06\x03\x12\x04\xa0\x0324\n!\n\x02\x04\x14\ - \x12\x06\xa4\x03\0\xa8\x03\x01\x1a\x13\x20response\x20from\x20dns\n\n\ - \x0b\n\x03\x04\x14\x01\x12\x04\xa4\x03\x08\x13\n\x0c\n\x04\x04\x14\x02\0\ - \x12\x04\xa5\x03\x04\x1e\n\r\n\x05\x04\x14\x02\0\x04\x12\x04\xa5\x03\x04\ - \x0c\n\r\n\x05\x04\x14\x02\0\x05\x12\x04\xa5\x03\r\x11\n\r\n\x05\x04\x14\ - \x02\0\x01\x12\x04\xa5\x03\x12\x19\n\r\n\x05\x04\x14\x02\0\x03\x12\x04\ - \xa5\x03\x1c\x1d\n\x0c\n\x04\x04\x14\x02\x01\x12\x04\xa6\x03\x04*\n\r\n\ - \x05\x04\x14\x02\x01\x04\x12\x04\xa6\x03\x04\x0c\n\r\n\x05\x04\x14\x02\ - \x01\x05\x12\x04\xa6\x03\r\x11\n\r\n\x05\x04\x14\x02\x01\x01\x12\x04\xa6\ - \x03\x12%\n\r\n\x05\x04\x14\x02\x01\x03\x12\x04\xa6\x03()\n\x0c\n\x04\ - \x04\x14\x02\x02\x12\x04\xa7\x03\x04=\n\r\n\x05\x04\x14\x02\x02\x04\x12\ - \x04\xa7\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x02\x06\x12\x04\xa7\x03\r!\n\ - \r\n\x05\x04\x14\x02\x02\x01\x12\x04\xa7\x03\"8\n\r\n\x05\x04\x14\x02\ - \x02\x03\x12\x04\xa7\x03;<\ + \x13\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\xc4\x01\x14\x18\n\r\n\x05\x04\n\ + \x02\x01\x03\x12\x04\xc4\x01\x1b\x1c\n\x0c\n\x02\x04\x0b\x12\x06\xc7\x01\ + \0\xcb\x01\x01\n\x0b\n\x03\x04\x0b\x01\x12\x04\xc7\x01\x08\x1b\n\x0c\n\ + \x04\x04\x0b\x02\0\x12\x04\xc8\x01\x04\x20\n\r\n\x05\x04\x0b\x02\0\x04\ + \x12\x04\xc8\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\0\x06\x12\x04\xc8\x01\r\ + \x11\n\r\n\x05\x04\x0b\x02\0\x01\x12\x04\xc8\x01\x12\x1b\n\r\n\x05\x04\ + \x0b\x02\0\x03\x12\x04\xc8\x01\x1e\x1f\n\x0c\n\x04\x04\x0b\x02\x01\x12\ + \x04\xc9\x01\x04\x20\n\r\n\x05\x04\x0b\x02\x01\x04\x12\x04\xc9\x01\x04\ + \x0c\n\r\n\x05\x04\x0b\x02\x01\x06\x12\x04\xc9\x01\r\x11\n\r\n\x05\x04\ + \x0b\x02\x01\x01\x12\x04\xc9\x01\x12\x1b\n\r\n\x05\x04\x0b\x02\x01\x03\ + \x12\x04\xc9\x01\x1e\x1f\n\x0c\n\x04\x04\x0b\x02\x02\x12\x04\xca\x01\x04\ + )\n\r\n\x05\x04\x0b\x02\x02\x04\x12\x04\xca\x01\x04\x0c\n\r\n\x05\x04\ + \x0b\x02\x02\x05\x12\x04\xca\x01\r\x11\n\r\n\x05\x04\x0b\x02\x02\x01\x12\ + \x04\xca\x01\x12$\n\r\n\x05\x04\x0b\x02\x02\x03\x12\x04\xca\x01'(\n\x0c\ + \n\x02\x04\x0c\x12\x06\xcd\x01\0\xe4\x01\x01\n\x0b\n\x03\x04\x0c\x01\x12\ + \x04\xcd\x01\x08\x17\nO\n\x04\x04\x0c\x02\0\x12\x04\xcf\x01\x04)\x1aA\ + \x20Should\x20accompany\x20(at\x20least)\x20SESSION_INIT\x20and\x20CONFI\ + RM_RECONNECT.\n\n\r\n\x05\x04\x0c\x02\0\x04\x12\x04\xcf\x01\x04\x0c\n\r\ + \n\x05\x04\x0c\x02\0\x05\x12\x04\xcf\x01\r\x13\n\r\n\x05\x04\x0c\x02\0\ + \x01\x12\x04\xcf\x01\x14$\n\r\n\x05\x04\x0c\x02\0\x03\x12\x04\xcf\x01'(\ + \nv\n\x04\x04\x0c\x02\x01\x12\x04\xd3\x01\x041\x1ah\x20There\x20might\ + \x20be\x20a\x20state\x20transition.\x20May\x20be\x20absent;\x20absence\ + \x20should\x20be\n\x20treated\x20identically\x20to\x20NO_CHANGE.\n\n\r\n\ + \x05\x04\x0c\x02\x01\x04\x12\x04\xd3\x01\x04\x0c\n\r\n\x05\x04\x0c\x02\ + \x01\x06\x12\x04\xd3\x01\r\x1b\n\r\n\x05\x04\x0c\x02\x01\x01\x12\x04\xd3\ + \x01\x1c,\n\r\n\x05\x04\x0c\x02\x01\x03\x12\x04\xd3\x01/0\nc\n\x04\x04\ + \x0c\x02\x02\x12\x04\xd7\x01\x04(\x1aU\x20The\x20station\x20can\x20send\ + \x20client\x20config\x20info\x20piggybacked\n\x20on\x20any\x20message,\ + \x20as\x20it\x20sees\x20fit\n\n\r\n\x05\x04\x0c\x02\x02\x04\x12\x04\xd7\ + \x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x02\x06\x12\x04\xd7\x01\r\x17\n\r\n\ + \x05\x04\x0c\x02\x02\x01\x12\x04\xd7\x01\x18#\n\r\n\x05\x04\x0c\x02\x02\ + \x03\x12\x04\xd7\x01&'\nP\n\x04\x04\x0c\x02\x03\x12\x04\xda\x01\x04+\x1a\ + B\x20If\x20state_transition\x20==\x20S2C_ERROR,\x20this\x20field\x20is\ + \x20the\x20explanation.\n\n\r\n\x05\x04\x0c\x02\x03\x04\x12\x04\xda\x01\ + \x04\x0c\n\r\n\x05\x04\x0c\x02\x03\x06\x12\x04\xda\x01\r\x1b\n\r\n\x05\ + \x04\x0c\x02\x03\x01\x12\x04\xda\x01\x1c&\n\r\n\x05\x04\x0c\x02\x03\x03\ + \x12\x04\xda\x01)*\nQ\n\x04\x04\x0c\x02\x04\x12\x04\xdd\x01\x04$\x1aC\ + \x20Signals\x20client\x20to\x20stop\x20connecting\x20for\x20following\ + \x20amount\x20of\x20seconds\n\n\r\n\x05\x04\x0c\x02\x04\x04\x12\x04\xdd\ + \x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x04\x05\x12\x04\xdd\x01\r\x13\n\r\n\ + \x05\x04\x0c\x02\x04\x01\x12\x04\xdd\x01\x14\x1f\n\r\n\x05\x04\x0c\x02\ + \x04\x03\x12\x04\xdd\x01\"#\nK\n\x04\x04\x0c\x02\x05\x12\x04\xe0\x01\x04\ + #\x1a=\x20Sent\x20in\x20SESSION_INIT,\x20identifies\x20the\x20station\ + \x20that\x20picked\x20up\n\n\r\n\x05\x04\x0c\x02\x05\x04\x12\x04\xe0\x01\ + \x04\x0c\n\r\n\x05\x04\x0c\x02\x05\x05\x12\x04\xe0\x01\r\x13\n\r\n\x05\ + \x04\x0c\x02\x05\x01\x12\x04\xe0\x01\x14\x1e\n\r\n\x05\x04\x0c\x02\x05\ + \x03\x12\x04\xe0\x01!\"\nG\n\x04\x04\x0c\x02\x06\x12\x04\xe3\x01\x04!\ + \x1a9\x20Random-sized\x20junk\x20to\x20defeat\x20packet\x20size\x20finge\ + rprinting.\n\n\r\n\x05\x04\x0c\x02\x06\x04\x12\x04\xe3\x01\x04\x0c\n\r\n\ + \x05\x04\x0c\x02\x06\x05\x12\x04\xe3\x01\r\x12\n\r\n\x05\x04\x0c\x02\x06\ + \x01\x12\x04\xe3\x01\x13\x1a\n\r\n\x05\x04\x0c\x02\x06\x03\x12\x04\xe3\ + \x01\x1d\x20\n\x0c\n\x02\x04\r\x12\x06\xe6\x01\0\xec\x01\x01\n\x0b\n\x03\ + \x04\r\x01\x12\x04\xe6\x01\x08\x19\n\x0c\n\x04\x04\r\x02\0\x12\x04\xe7\ + \x01\x08&\n\r\n\x05\x04\r\x02\0\x04\x12\x04\xe7\x01\x08\x10\n\r\n\x05\ + \x04\r\x02\0\x05\x12\x04\xe7\x01\x11\x15\n\r\n\x05\x04\r\x02\0\x01\x12\ + \x04\xe7\x01\x16!\n\r\n\x05\x04\r\x02\0\x03\x12\x04\xe7\x01$%\n\x0c\n\ + \x04\x04\r\x02\x01\x12\x04\xe8\x01\x08%\n\r\n\x05\x04\r\x02\x01\x04\x12\ + \x04\xe8\x01\x08\x10\n\r\n\x05\x04\r\x02\x01\x05\x12\x04\xe8\x01\x11\x15\ + \n\r\n\x05\x04\r\x02\x01\x01\x12\x04\xe8\x01\x16\x20\n\r\n\x05\x04\r\x02\ + \x01\x03\x12\x04\xe8\x01#$\n\x0c\n\x04\x04\r\x02\x02\x12\x04\xe9\x01\x08\ + '\n\r\n\x05\x04\r\x02\x02\x04\x12\x04\xe9\x01\x08\x10\n\r\n\x05\x04\r\ + \x02\x02\x05\x12\x04\xe9\x01\x11\x15\n\r\n\x05\x04\r\x02\x02\x01\x12\x04\ + \xe9\x01\x16\"\n\r\n\x05\x04\r\x02\x02\x03\x12\x04\xe9\x01%&\n\x0c\n\x04\ + \x04\r\x02\x03\x12\x04\xea\x01\x04\x1e\n\r\n\x05\x04\r\x02\x03\x04\x12\ + \x04\xea\x01\x04\x0c\n\r\n\x05\x04\r\x02\x03\x05\x12\x04\xea\x01\r\x11\n\ + \r\n\x05\x04\r\x02\x03\x01\x12\x04\xea\x01\x12\x19\n\r\n\x05\x04\r\x02\ + \x03\x03\x12\x04\xea\x01\x1c\x1d\n\x0c\n\x04\x04\r\x02\x04\x12\x04\xeb\ + \x01\x04!\n\r\n\x05\x04\r\x02\x04\x04\x12\x04\xeb\x01\x04\x0c\n\r\n\x05\ + \x04\r\x02\x04\x05\x12\x04\xeb\x01\r\x11\n\r\n\x05\x04\r\x02\x04\x01\x12\ + \x04\xeb\x01\x12\x1c\n\r\n\x05\x04\r\x02\x04\x03\x12\x04\xeb\x01\x1f\x20\ + \n\x0c\n\x02\x04\x0e\x12\x06\xee\x01\0\xa8\x02\x01\n\x0b\n\x03\x04\x0e\ + \x01\x12\x04\xee\x01\x08\x17\n\x0c\n\x04\x04\x0e\x02\0\x12\x04\xef\x01\ + \x04)\n\r\n\x05\x04\x0e\x02\0\x04\x12\x04\xef\x01\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\0\x05\x12\x04\xef\x01\r\x13\n\r\n\x05\x04\x0e\x02\0\x01\x12\x04\ + \xef\x01\x14$\n\r\n\x05\x04\x0e\x02\0\x03\x12\x04\xef\x01'(\n\xd0\x01\n\ + \x04\x04\x0e\x02\x01\x12\x04\xf4\x01\x04.\x1a\xc1\x01\x20The\x20client\ + \x20reports\x20its\x20decoy\x20list's\x20version\x20number\x20here,\x20w\ + hich\x20the\n\x20station\x20can\x20use\x20to\x20decide\x20whether\x20to\ + \x20send\x20an\x20updated\x20one.\x20The\x20station\n\x20should\x20alway\ + s\x20send\x20a\x20list\x20if\x20this\x20field\x20is\x20set\x20to\x200.\n\ + \n\r\n\x05\x04\x0e\x02\x01\x04\x12\x04\xf4\x01\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x01\x05\x12\x04\xf4\x01\r\x13\n\r\n\x05\x04\x0e\x02\x01\x01\x12\x04\ + \xf4\x01\x14)\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xf4\x01,-\n\x0c\n\ + \x04\x04\x0e\x02\x02\x12\x04\xf6\x01\x041\n\r\n\x05\x04\x0e\x02\x02\x04\ + \x12\x04\xf6\x01\x04\x0c\n\r\n\x05\x04\x0e\x02\x02\x06\x12\x04\xf6\x01\r\ + \x1b\n\r\n\x05\x04\x0e\x02\x02\x01\x12\x04\xf6\x01\x1c,\n\r\n\x05\x04\ + \x0e\x02\x02\x03\x12\x04\xf6\x01/0\n\x80\x01\n\x04\x04\x0e\x02\x03\x12\ + \x04\xfa\x01\x04$\x1ar\x20The\x20position\x20in\x20the\x20overall\x20ses\ + sion's\x20upload\x20sequence\x20where\x20the\x20current\n\x20YIELD=>ACQU\ + IRE\x20switchover\x20is\x20happening.\n\n\r\n\x05\x04\x0e\x02\x03\x04\ + \x12\x04\xfa\x01\x04\x0c\n\r\n\x05\x04\x0e\x02\x03\x05\x12\x04\xfa\x01\r\ + \x13\n\r\n\x05\x04\x0e\x02\x03\x01\x12\x04\xfa\x01\x14\x1f\n\r\n\x05\x04\ + \x0e\x02\x03\x03\x12\x04\xfa\x01\"#\ng\n\x04\x04\x0e\x02\x04\x12\x04\xfe\ + \x01\x04+\x1aY\x20High\x20level\x20client\x20library\x20version\x20used\ + \x20for\x20indicating\x20feature\x20support,\x20or\n\x20lack\x20therof.\ + \n\n\r\n\x05\x04\x0e\x02\x04\x04\x12\x04\xfe\x01\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\x04\x05\x12\x04\xfe\x01\r\x13\n\r\n\x05\x04\x0e\x02\x04\x01\x12\ + \x04\xfe\x01\x14&\n\r\n\x05\x04\x0e\x02\x04\x03\x12\x04\xfe\x01)*\n\xa5\ + \x02\n\x04\x04\x0e\x02\x05\x12\x04\x83\x02\x042\x1a\x96\x02\x20Indicates\ + \x20whether\x20the\x20client\x20will\x20allow\x20the\x20registrar\x20to\ + \x20provide\x20alternative\x20parameters\x20that\n\x20may\x20work\x20bet\ + ter\x20in\x20substitute\x20for\x20the\x20deterministically\x20selected\ + \x20parameters.\x20This\x20only\x20works\n\x20for\x20bidirectional\x20re\ + gistration\x20methods\x20where\x20the\x20client\x20receives\x20a\x20Regi\ + strationResponse.\n\n\r\n\x05\x04\x0e\x02\x05\x04\x12\x04\x83\x02\x04\ + \x0c\n\r\n\x05\x04\x0e\x02\x05\x05\x12\x04\x83\x02\r\x11\n\r\n\x05\x04\ + \x0e\x02\x05\x01\x12\x04\x83\x02\x12-\n\r\n\x05\x04\x0e\x02\x05\x03\x12\ + \x04\x83\x0201\nq\n\x04\x04\x0e\x02\x06\x12\x04\x87\x02\x04'\x1ac\x20Lis\ + t\x20of\x20decoys\x20that\x20client\x20have\x20unsuccessfully\x20tried\ + \x20in\x20current\x20session.\n\x20Could\x20be\x20sent\x20in\x20chunks\n\ + \n\r\n\x05\x04\x0e\x02\x06\x04\x12\x04\x87\x02\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x06\x05\x12\x04\x87\x02\r\x13\n\r\n\x05\x04\x0e\x02\x06\x01\x12\x04\ + \x87\x02\x14!\n\r\n\x05\x04\x0e\x02\x06\x03\x12\x04\x87\x02$&\n\x0c\n\ + \x04\x04\x0e\x02\x07\x12\x04\x89\x02\x04%\n\r\n\x05\x04\x0e\x02\x07\x04\ + \x12\x04\x89\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x07\x06\x12\x04\x89\x02\r\ + \x19\n\r\n\x05\x04\x0e\x02\x07\x01\x12\x04\x89\x02\x1a\x1f\n\r\n\x05\x04\ + \x0e\x02\x07\x03\x12\x04\x89\x02\"$\nk\n\x04\x04\x0e\x02\x08\x12\x04\x8c\ + \x02\x04*\x1a]\x20NullTransport,\x20MinTransport,\x20Obfs4Transport,\x20\ + etc.\x20Transport\x20type\x20we\x20want\x20from\x20phantom\x20proxy\n\n\ + \r\n\x05\x04\x0e\x02\x08\x04\x12\x04\x8c\x02\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x08\x06\x12\x04\x8c\x02\r\x1a\n\r\n\x05\x04\x0e\x02\x08\x01\x12\x04\ + \x8c\x02\x1b$\n\r\n\x05\x04\x0e\x02\x08\x03\x12\x04\x8c\x02')\n\x0c\n\ + \x04\x04\x0e\x02\t\x12\x04\x8e\x02\x047\n\r\n\x05\x04\x0e\x02\t\x04\x12\ + \x04\x8e\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\t\x06\x12\x04\x8e\x02\r\x20\n\ + \r\n\x05\x04\x0e\x02\t\x01\x12\x04\x8e\x02!1\n\r\n\x05\x04\x0e\x02\t\x03\ + \x12\x04\x8e\x0246\n\xc8\x03\n\x04\x04\x0e\x02\n\x12\x04\x96\x02\x04(\ + \x1a\xb9\x03\x20Station\x20is\x20only\x20required\x20to\x20check\x20this\ + \x20variable\x20during\x20session\x20initialization.\n\x20If\x20set,\x20\ + station\x20must\x20facilitate\x20connection\x20to\x20said\x20target\x20b\ + y\x20itself,\x20i.e.\x20write\x20into\x20squid\n\x20socket\x20an\x20HTTP\ + /SOCKS/any\x20other\x20connection\x20request.\n\x20covert_address\x20mus\ + t\x20have\x20exactly\x20one\x20':'\x20colon,\x20that\x20separates\x20hos\ + t\x20(literal\x20IP\x20address\x20or\n\x20resolvable\x20hostname)\x20and\ + \x20port\n\x20TODO:\x20make\x20it\x20required\x20for\x20initialization,\ + \x20and\x20stop\x20connecting\x20any\x20client\x20straight\x20to\x20squi\ + d?\n\n\r\n\x05\x04\x0e\x02\n\x04\x12\x04\x96\x02\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\n\x05\x12\x04\x96\x02\r\x13\n\r\n\x05\x04\x0e\x02\n\x01\x12\x04\ + \x96\x02\x14\"\n\r\n\x05\x04\x0e\x02\n\x03\x12\x04\x96\x02%'\nR\n\x04\ + \x04\x0e\x02\x0b\x12\x04\x99\x02\x042\x1aD\x20Used\x20in\x20dark\x20deco\ + ys\x20to\x20signal\x20which\x20dark\x20decoy\x20it\x20will\x20connect\ + \x20to.\n\n\r\n\x05\x04\x0e\x02\x0b\x04\x12\x04\x99\x02\x04\x0c\n\r\n\ + \x05\x04\x0e\x02\x0b\x05\x12\x04\x99\x02\r\x13\n\r\n\x05\x04\x0e\x02\x0b\ + \x01\x12\x04\x99\x02\x14,\n\r\n\x05\x04\x0e\x02\x0b\x03\x12\x04\x99\x02/\ + 1\nR\n\x04\x04\x0e\x02\x0c\x12\x04\x9c\x02\x04\"\x1aD\x20Used\x20to\x20i\ + ndicate\x20to\x20server\x20if\x20client\x20is\x20registering\x20v4,\x20v\ + 6\x20or\x20both\n\n\r\n\x05\x04\x0e\x02\x0c\x04\x12\x04\x9c\x02\x04\x0c\ + \n\r\n\x05\x04\x0e\x02\x0c\x05\x12\x04\x9c\x02\r\x11\n\r\n\x05\x04\x0e\ + \x02\x0c\x01\x12\x04\x9c\x02\x12\x1c\n\r\n\x05\x04\x0e\x02\x0c\x03\x12\ + \x04\x9c\x02\x1f!\n\x0c\n\x04\x04\x0e\x02\r\x12\x04\x9d\x02\x04\"\n\r\n\ + \x05\x04\x0e\x02\r\x04\x12\x04\x9d\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\r\ + \x05\x12\x04\x9d\x02\r\x11\n\r\n\x05\x04\x0e\x02\r\x01\x12\x04\x9d\x02\ + \x12\x1c\n\r\n\x05\x04\x0e\x02\r\x03\x12\x04\x9d\x02\x1f!\nD\n\x04\x04\ + \x0e\x02\x0e\x12\x04\xa0\x02\x04*\x1a6\x20A\x20collection\x20of\x20optio\ + nal\x20flags\x20for\x20the\x20registration.\n\n\r\n\x05\x04\x0e\x02\x0e\ + \x04\x12\x04\xa0\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x0e\x06\x12\x04\xa0\ + \x02\r\x1e\n\r\n\x05\x04\x0e\x02\x0e\x01\x12\x04\xa0\x02\x1f$\n\r\n\x05\ + \x04\x0e\x02\x0e\x03\x12\x04\xa0\x02')\nq\n\x04\x04\x0e\x02\x0f\x12\x04\ + \xa4\x02\x04-\x1ac\x20Transport\x20Extensions\n\x20TODO(jmwample)\x20-\ + \x20move\x20to\x20WebRTC\x20specific\x20transport\x20params\x20protobuf\ + \x20message.\n\n\r\n\x05\x04\x0e\x02\x0f\x04\x12\x04\xa4\x02\x04\x0c\n\r\ + \n\x05\x04\x0e\x02\x0f\x06\x12\x04\xa4\x02\r\x19\n\r\n\x05\x04\x0e\x02\ + \x0f\x01\x12\x04\xa4\x02\x1a'\n\r\n\x05\x04\x0e\x02\x0f\x03\x12\x04\xa4\ + \x02*,\nG\n\x04\x04\x0e\x02\x10\x12\x04\xa7\x02\x04!\x1a9\x20Random-size\ + d\x20junk\x20to\x20defeat\x20packet\x20size\x20fingerprinting.\n\n\r\n\ + \x05\x04\x0e\x02\x10\x04\x12\x04\xa7\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\ + \x10\x05\x12\x04\xa7\x02\r\x12\n\r\n\x05\x04\x0e\x02\x10\x01\x12\x04\xa7\ + \x02\x13\x1a\n\r\n\x05\x04\x0e\x02\x10\x03\x12\x04\xa7\x02\x1d\x20\n\x0c\ + \n\x02\x04\x0f\x12\x06\xab\x02\0\xb8\x02\x01\n\x0b\n\x03\x04\x0f\x01\x12\ + \x04\xab\x02\x08\x1b\n\x0c\n\x04\x04\x0f\x02\0\x12\x04\xac\x02\x04\x1d\n\ + \r\n\x05\x04\x0f\x02\0\x04\x12\x04\xac\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\ + \0\x05\x12\x04\xac\x02\r\x12\n\r\n\x05\x04\x0f\x02\0\x01\x12\x04\xac\x02\ + \x13\x18\n\r\n\x05\x04\x0f\x02\0\x03\x12\x04\xac\x02\x1b\x1c\n\x0c\n\x04\ + \x04\x0f\x02\x01\x12\x04\xae\x02\x04\x1f\n\r\n\x05\x04\x0f\x02\x01\x04\ + \x12\x04\xae\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\x01\x05\x12\x04\xae\x02\r\ + \x12\n\r\n\x05\x04\x0f\x02\x01\x01\x12\x04\xae\x02\x13\x1a\n\r\n\x05\x04\ + \x0f\x02\x01\x03\x12\x04\xae\x02\x1d\x1e\n\x0c\n\x04\x04\x0f\x02\x02\x12\ + \x04\xb0\x02\x04#\n\r\n\x05\x04\x0f\x02\x02\x04\x12\x04\xb0\x02\x04\x0c\ + \n\r\n\x05\x04\x0f\x02\x02\x05\x12\x04\xb0\x02\r\x12\n\r\n\x05\x04\x0f\ + \x02\x02\x01\x12\x04\xb0\x02\x13\x1e\n\r\n\x05\x04\x0f\x02\x02\x03\x12\ + \x04\xb0\x02!\"\n\x0c\n\x04\x04\x0f\x02\x03\x12\x04\xb2\x02\x04\x1b\n\r\ + \n\x05\x04\x0f\x02\x03\x04\x12\x04\xb2\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\ + \x03\x05\x12\x04\xb2\x02\r\x12\n\r\n\x05\x04\x0f\x02\x03\x01\x12\x04\xb2\ + \x02\x13\x16\n\r\n\x05\x04\x0f\x02\x03\x03\x12\x04\xb2\x02\x19\x1a\n\xcb\ + \x01\n\x04\x04\x0f\x02\x04\x12\x04\xb7\x02\x04*\x1a\xbc\x01\x20Indicates\ + \x20whether\x20the\x20client\x20has\x20elected\x20to\x20use\x20destinati\ + on\x20port\x20randomization.\x20Should\x20be\n\x20checked\x20against\x20\ + selected\x20transport\x20to\x20ensure\x20that\x20destination\x20port\x20\ + randomization\x20is\n\x20supported.\n\n\r\n\x05\x04\x0f\x02\x04\x04\x12\ + \x04\xb7\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\x04\x05\x12\x04\xb7\x02\r\x11\ + \n\r\n\x05\x04\x0f\x02\x04\x01\x12\x04\xb7\x02\x12$\n\r\n\x05\x04\x0f\ + \x02\x04\x03\x12\x04\xb7\x02')\n\x0c\n\x02\x04\x10\x12\x06\xba\x02\0\xcc\ + \x02\x01\n\x0b\n\x03\x04\x10\x01\x12\x04\xba\x02\x08\x1d\n!\n\x04\x04\ + \x10\x02\0\x12\x04\xbc\x02\x04!\x1a\x13\x20Prefix\x20Identifier\n\n\r\n\ + \x05\x04\x10\x02\0\x04\x12\x04\xbc\x02\x04\x0c\n\r\n\x05\x04\x10\x02\0\ + \x05\x12\x04\xbc\x02\r\x12\n\r\n\x05\x04\x10\x02\0\x01\x12\x04\xbc\x02\ + \x13\x1c\n\r\n\x05\x04\x10\x02\0\x03\x12\x04\xbc\x02\x1f\x20\n\xc4\x01\n\ + \x04\x04\x10\x02\x01\x12\x04\xc0\x02\x04\x1e\x1a\xb5\x01\x20Prefix\x20by\ + tes\x20(optional\x20-\x20usually\x20sent\x20from\x20station\x20to\x20cli\ + ent\x20as\x20override\x20if\x20allowed\x20by\x20C2S)\n\x20as\x20the\x20s\ + tation\x20cannot\x20take\x20this\x20into\x20account\x20when\x20attemptin\ + g\x20to\x20identify\x20a\x20connection.\n\n\r\n\x05\x04\x10\x02\x01\x04\ + \x12\x04\xc0\x02\x04\x0c\n\r\n\x05\x04\x10\x02\x01\x05\x12\x04\xc0\x02\r\ + \x12\n\r\n\x05\x04\x10\x02\x01\x01\x12\x04\xc0\x02\x13\x19\n\r\n\x05\x04\ + \x10\x02\x01\x03\x12\x04\xc0\x02\x1c\x1d\n\x0c\n\x04\x04\x10\x02\x02\x12\ + \x04\xc1\x02\x04+\n\r\n\x05\x04\x10\x02\x02\x04\x12\x04\xc1\x02\x04\x0c\ + \n\r\n\x05\x04\x10\x02\x02\x05\x12\x04\xc1\x02\r\x12\n\r\n\x05\x04\x10\ + \x02\x02\x01\x12\x04\xc1\x02\x13&\n\r\n\x05\x04\x10\x02\x02\x03\x12\x04\ + \xc1\x02)*\n\xed\x02\n\x04\x04\x10\x02\x03\x12\x04\xcb\x02\x04*\x1a\xbc\ + \x01\x20Indicates\x20whether\x20the\x20client\x20has\x20elected\x20to\ + \x20use\x20destination\x20port\x20randomization.\x20Should\x20be\n\x20ch\ + ecked\x20against\x20selected\x20transport\x20to\x20ensure\x20that\x20des\ + tination\x20port\x20randomization\x20is\n\x20supported.\n2\x9f\x01\x20//\ + \x20potential\x20future\x20fields\n\x20obfuscator\x20ID\n\x20tagEncoder\ + \x20ID\x20(¶ms?,\x20e.g.\x20format-base64\x20/\x20padding)\n\x20stre\ + amEncoder\x20ID\x20(¶ms?,\x20e.g.\x20foramat-base64\x20/\x20padding)\ + \n\n\r\n\x05\x04\x10\x02\x03\x04\x12\x04\xcb\x02\x04\x0c\n\r\n\x05\x04\ + \x10\x02\x03\x05\x12\x04\xcb\x02\r\x11\n\r\n\x05\x04\x10\x02\x03\x01\x12\ + \x04\xcb\x02\x12$\n\r\n\x05\x04\x10\x02\x03\x03\x12\x04\xcb\x02')\n\x0c\ + \n\x02\x04\x11\x12\x06\xce\x02\0\xd3\x02\x01\n\x0b\n\x03\x04\x11\x01\x12\ + \x04\xce\x02\x08\x1e\n\xcb\x01\n\x04\x04\x11\x02\0\x12\x04\xd2\x02\x04*\ + \x1a\xbc\x01\x20Indicates\x20whether\x20the\x20client\x20has\x20elected\ + \x20to\x20use\x20destination\x20port\x20randomization.\x20Should\x20be\n\ + \x20checked\x20against\x20selected\x20transport\x20to\x20ensure\x20that\ + \x20destination\x20port\x20randomization\x20is\n\x20supported.\n\n\r\n\ + \x05\x04\x11\x02\0\x04\x12\x04\xd2\x02\x04\x0c\n\r\n\x05\x04\x11\x02\0\ + \x05\x12\x04\xd2\x02\r\x11\n\r\n\x05\x04\x11\x02\0\x01\x12\x04\xd2\x02\ + \x12$\n\r\n\x05\x04\x11\x02\0\x03\x12\x04\xd2\x02')\n\x0c\n\x02\x05\x06\ + \x12\x06\xd5\x02\0\xdd\x02\x01\n\x0b\n\x03\x05\x06\x01\x12\x04\xd5\x02\ + \x05\x17\n\x0c\n\x04\x05\x06\x02\0\x12\x04\xd6\x02\x02\x12\n\r\n\x05\x05\ + \x06\x02\0\x01\x12\x04\xd6\x02\x02\r\n\r\n\x05\x05\x06\x02\0\x02\x12\x04\ + \xd6\x02\x10\x11\n\x0c\n\x04\x05\x06\x02\x01\x12\x04\xd7\x02\x08\x15\n\r\ + \n\x05\x05\x06\x02\x01\x01\x12\x04\xd7\x02\x08\x10\n\r\n\x05\x05\x06\x02\ + \x01\x02\x12\x04\xd7\x02\x13\x14\n\x0c\n\x04\x05\x06\x02\x02\x12\x04\xd8\ + \x02\x08\x10\n\r\n\x05\x05\x06\x02\x02\x01\x12\x04\xd8\x02\x08\x0b\n\r\n\ + \x05\x05\x06\x02\x02\x02\x12\x04\xd8\x02\x0e\x0f\n\x0c\n\x04\x05\x06\x02\ + \x03\x12\x04\xd9\x02\x02\x16\n\r\n\x05\x05\x06\x02\x03\x01\x12\x04\xd9\ + \x02\x02\x11\n\r\n\x05\x05\x06\x02\x03\x02\x12\x04\xd9\x02\x14\x15\n\x0c\ + \n\x04\x05\x06\x02\x04\x12\x04\xda\x02\x02\x17\n\r\n\x05\x05\x06\x02\x04\ + \x01\x12\x04\xda\x02\x02\x12\n\r\n\x05\x05\x06\x02\x04\x02\x12\x04\xda\ + \x02\x15\x16\n\x0c\n\x04\x05\x06\x02\x05\x12\x04\xdb\x02\x02\n\n\r\n\x05\ + \x05\x06\x02\x05\x01\x12\x04\xdb\x02\x02\x05\n\r\n\x05\x05\x06\x02\x05\ + \x02\x12\x04\xdb\x02\x08\t\n\x0c\n\x04\x05\x06\x02\x06\x12\x04\xdc\x02\ + \x02\x17\n\r\n\x05\x05\x06\x02\x06\x01\x12\x04\xdc\x02\x02\x12\n\r\n\x05\ + \x05\x06\x02\x06\x02\x12\x04\xdc\x02\x15\x16\n\x0c\n\x02\x04\x12\x12\x06\ + \xdf\x02\0\xf7\x02\x01\n\x0b\n\x03\x04\x12\x01\x12\x04\xdf\x02\x08\x12\n\ + \x0c\n\x04\x04\x12\x02\0\x12\x04\xe0\x02\x02#\n\r\n\x05\x04\x12\x02\0\ + \x04\x12\x04\xe0\x02\x02\n\n\r\n\x05\x04\x12\x02\0\x05\x12\x04\xe0\x02\ + \x0b\x10\n\r\n\x05\x04\x12\x02\0\x01\x12\x04\xe0\x02\x11\x1e\n\r\n\x05\ + \x04\x12\x02\0\x03\x12\x04\xe0\x02!\"\n\x0c\n\x04\x04\x12\x02\x01\x12\ + \x04\xe1\x02\x024\n\r\n\x05\x04\x12\x02\x01\x04\x12\x04\xe1\x02\x02\n\n\ + \r\n\x05\x04\x12\x02\x01\x06\x12\x04\xe1\x02\x0b\x1a\n\r\n\x05\x04\x12\ + \x02\x01\x01\x12\x04\xe1\x02\x1b/\n\r\n\x05\x04\x12\x02\x01\x03\x12\x04\ + \xe1\x0223\n\x0c\n\x04\x04\x12\x02\x02\x12\x04\xe2\x02\x026\n\r\n\x05\ + \x04\x12\x02\x02\x04\x12\x04\xe2\x02\x02\n\n\r\n\x05\x04\x12\x02\x02\x06\ + \x12\x04\xe2\x02\x0b\x1d\n\r\n\x05\x04\x12\x02\x02\x01\x12\x04\xe2\x02\ + \x1e1\n\r\n\x05\x04\x12\x02\x02\x03\x12\x04\xe2\x0245\nC\n\x04\x04\x12\ + \x02\x03\x12\x04\xe5\x02\x02*\x1a5\x20client\x20source\x20address\x20whe\ + n\x20receiving\x20a\x20registration\n\n\r\n\x05\x04\x12\x02\x03\x04\x12\ + \x04\xe5\x02\x02\n\n\r\n\x05\x04\x12\x02\x03\x05\x12\x04\xe5\x02\x0b\x10\ + \n\r\n\x05\x04\x12\x02\x03\x01\x12\x04\xe5\x02\x11%\n\r\n\x05\x04\x12\ + \x02\x03\x03\x12\x04\xe5\x02()\nH\n\x04\x04\x12\x02\x04\x12\x04\xe8\x02\ + \x02#\x1a:\x20Decoy\x20address\x20used\x20when\x20registering\x20over\ + \x20Decoy\x20registrar\n\n\r\n\x05\x04\x12\x02\x04\x04\x12\x04\xe8\x02\ + \x02\n\n\r\n\x05\x04\x12\x02\x04\x05\x12\x04\xe8\x02\x0b\x10\n\r\n\x05\ + \x04\x12\x02\x04\x01\x12\x04\xe8\x02\x11\x1e\n\r\n\x05\x04\x12\x02\x04\ + \x03\x12\x04\xe8\x02!\"\n\xeb\x05\n\x04\x04\x12\x02\x05\x12\x04\xf4\x02\ + \x02:\x1a\xdc\x05\x20The\x20next\x20three\x20fields\x20allow\x20an\x20in\ + dependent\x20registrar\x20(trusted\x20by\x20a\x20station\x20w/\x20a\x20z\ + mq\x20keypair)\x20to\n\x20share\x20the\x20registration\x20overrides\x20t\ + hat\x20it\x20assigned\x20to\x20the\x20client\x20with\x20the\x20station(s\ + ).\n\x20Registration\x20Respose\x20is\x20here\x20to\x20allow\x20a\x20par\ + sed\x20object\x20with\x20direct\x20access\x20to\x20the\x20fields\x20with\ + in.\n\x20RegRespBytes\x20provides\x20a\x20serialized\x20verion\x20of\x20\ + the\x20Registration\x20response\x20so\x20that\x20the\x20signature\x20of\ + \n\x20the\x20Bidirectional\x20registrar\x20can\x20be\x20validated\x20bef\ + ore\x20a\x20station\x20applies\x20any\x20overrides\x20present\x20in\n\ + \x20the\x20Registration\x20Response.\n\n\x20If\x20you\x20are\x20reading\ + \x20this\x20in\x20the\x20future\x20and\x20you\x20want\x20to\x20extend\ + \x20the\x20functionality\x20here\x20it\x20might\n\x20make\x20sense\x20to\ + \x20make\x20the\x20RegistrationResponse\x20that\x20is\x20sent\x20to\x20t\ + he\x20client\x20a\x20distinct\x20message\x20from\n\x20the\x20one\x20that\ + \x20gets\x20sent\x20to\x20the\x20stations.\n\n\r\n\x05\x04\x12\x02\x05\ + \x04\x12\x04\xf4\x02\x02\n\n\r\n\x05\x04\x12\x02\x05\x06\x12\x04\xf4\x02\ + \x0b\x1f\n\r\n\x05\x04\x12\x02\x05\x01\x12\x04\xf4\x02\x205\n\r\n\x05\ + \x04\x12\x02\x05\x03\x12\x04\xf4\x0289\n\x0c\n\x04\x04\x12\x02\x06\x12\ + \x04\xf5\x02\x02\"\n\r\n\x05\x04\x12\x02\x06\x04\x12\x04\xf5\x02\x02\n\n\ + \r\n\x05\x04\x12\x02\x06\x05\x12\x04\xf5\x02\x0b\x10\n\r\n\x05\x04\x12\ + \x02\x06\x01\x12\x04\xf5\x02\x11\x1d\n\r\n\x05\x04\x12\x02\x06\x03\x12\ + \x04\xf5\x02\x20!\n\x0c\n\x04\x04\x12\x02\x07\x12\x04\xf6\x02\x02'\n\r\n\ + \x05\x04\x12\x02\x07\x04\x12\x04\xf6\x02\x02\n\n\r\n\x05\x04\x12\x02\x07\ + \x05\x12\x04\xf6\x02\x0b\x10\n\r\n\x05\x04\x12\x02\x07\x01\x12\x04\xf6\ + \x02\x11!\n\r\n\x05\x04\x12\x02\x07\x03\x12\x04\xf6\x02$&\n\x0c\n\x02\ + \x04\x13\x12\x06\xf9\x02\0\x85\x03\x01\n\x0b\n\x03\x04\x13\x01\x12\x04\ + \xf9\x02\x08\x14\n9\n\x04\x04\x13\x02\0\x12\x04\xfa\x02\x04.\"+\x20how\ + \x20many\x20decoys\x20were\x20tried\x20before\x20success\n\n\r\n\x05\x04\ + \x13\x02\0\x04\x12\x04\xfa\x02\x04\x0c\n\r\n\x05\x04\x13\x02\0\x05\x12\ + \x04\xfa\x02\r\x13\n\r\n\x05\x04\x13\x02\0\x01\x12\x04\xfa\x02\x14(\n\r\ + \n\x05\x04\x13\x02\0\x03\x12\x04\xfa\x02+-\nm\n\x04\x04\x13\x02\x01\x12\ + \x04\xff\x02\x04/\x1a\x1e\x20Applicable\x20to\x20whole\x20session:\n\"\ + \x1a\x20includes\x20failed\x20attempts\n2#\x20Timings\x20below\x20are\ + \x20in\x20milliseconds\n\n\r\n\x05\x04\x13\x02\x01\x04\x12\x04\xff\x02\ + \x04\x0c\n\r\n\x05\x04\x13\x02\x01\x05\x12\x04\xff\x02\r\x13\n\r\n\x05\ + \x04\x13\x02\x01\x01\x12\x04\xff\x02\x14)\n\r\n\x05\x04\x13\x02\x01\x03\ + \x12\x04\xff\x02,.\nR\n\x04\x04\x13\x02\x02\x12\x04\x82\x03\x04(\x1a\x1f\ + \x20Last\x20(i.e.\x20successful)\x20decoy:\n\"#\x20measured\x20during\ + \x20initial\x20handshake\n\n\r\n\x05\x04\x13\x02\x02\x04\x12\x04\x82\x03\ + \x04\x0c\n\r\n\x05\x04\x13\x02\x02\x05\x12\x04\x82\x03\r\x13\n\r\n\x05\ + \x04\x13\x02\x02\x01\x12\x04\x82\x03\x14\"\n\r\n\x05\x04\x13\x02\x02\x03\ + \x12\x04\x82\x03%'\n%\n\x04\x04\x13\x02\x03\x12\x04\x83\x03\x04&\"\x17\ + \x20includes\x20tcp\x20to\x20decoy\n\n\r\n\x05\x04\x13\x02\x03\x04\x12\ + \x04\x83\x03\x04\x0c\n\r\n\x05\x04\x13\x02\x03\x05\x12\x04\x83\x03\r\x13\ + \n\r\n\x05\x04\x13\x02\x03\x01\x12\x04\x83\x03\x14\x20\n\r\n\x05\x04\x13\ + \x02\x03\x03\x12\x04\x83\x03#%\nB\n\x04\x04\x13\x02\x04\x12\x04\x84\x03\ + \x04&\"4\x20measured\x20when\x20establishing\x20tcp\x20connection\x20to\ + \x20decot\n\n\r\n\x05\x04\x13\x02\x04\x04\x12\x04\x84\x03\x04\x0c\n\r\n\ + \x05\x04\x13\x02\x04\x05\x12\x04\x84\x03\r\x13\n\r\n\x05\x04\x13\x02\x04\ + \x01\x12\x04\x84\x03\x14\x20\n\r\n\x05\x04\x13\x02\x04\x03\x12\x04\x84\ + \x03#%\n\x0c\n\x02\x05\x07\x12\x06\x87\x03\0\x8c\x03\x01\n\x0b\n\x03\x05\ + \x07\x01\x12\x04\x87\x03\x05\x16\n\x0c\n\x04\x05\x07\x02\0\x12\x04\x88\ + \x03\x04\x10\n\r\n\x05\x05\x07\x02\0\x01\x12\x04\x88\x03\x04\x0b\n\r\n\ + \x05\x05\x07\x02\0\x02\x12\x04\x88\x03\x0e\x0f\n\x0c\n\x04\x05\x07\x02\ + \x01\x12\x04\x89\x03\x04\x0c\n\r\n\x05\x05\x07\x02\x01\x01\x12\x04\x89\ + \x03\x04\x07\n\r\n\x05\x05\x07\x02\x01\x02\x12\x04\x89\x03\n\x0b\n\x0c\n\ + \x04\x05\x07\x02\x02\x12\x04\x8a\x03\x04\x0f\n\r\n\x05\x05\x07\x02\x02\ + \x01\x12\x04\x8a\x03\x04\n\n\r\n\x05\x05\x07\x02\x02\x02\x12\x04\x8a\x03\ + \r\x0e\n\x0c\n\x04\x05\x07\x02\x03\x12\x04\x8b\x03\x04\x0e\n\r\n\x05\x05\ + \x07\x02\x03\x01\x12\x04\x8b\x03\x04\t\n\r\n\x05\x05\x07\x02\x03\x02\x12\ + \x04\x8b\x03\x0c\r\n\x0c\n\x02\x05\x08\x12\x06\x8e\x03\0\x92\x03\x01\n\ + \x0b\n\x03\x05\x08\x01\x12\x04\x8e\x03\x05\x0c\n\x0c\n\x04\x05\x08\x02\0\ + \x12\x04\x8f\x03\x04\x0c\n\r\n\x05\x05\x08\x02\0\x01\x12\x04\x8f\x03\x04\ + \x07\n\r\n\x05\x05\x08\x02\0\x02\x12\x04\x8f\x03\n\x0b\n\x0c\n\x04\x05\ + \x08\x02\x01\x12\x04\x90\x03\x04\x0c\n\r\n\x05\x05\x08\x02\x01\x01\x12\ + \x04\x90\x03\x04\x07\n\r\n\x05\x05\x08\x02\x01\x02\x12\x04\x90\x03\n\x0b\ + \n\x0c\n\x04\x05\x08\x02\x02\x12\x04\x91\x03\x04\x0c\n\r\n\x05\x05\x08\ + \x02\x02\x01\x12\x04\x91\x03\x04\x07\n\r\n\x05\x05\x08\x02\x02\x02\x12\ + \x04\x91\x03\n\x0b\n\x0c\n\x02\x04\x14\x12\x06\x94\x03\0\x9f\x03\x01\n\ + \x0b\n\x03\x04\x14\x01\x12\x04\x94\x03\x08\x19\n\x0c\n\x04\x04\x14\x02\0\ + \x12\x04\x95\x03\x04#\n\r\n\x05\x04\x14\x02\0\x04\x12\x04\x95\x03\x04\ + \x0c\n\r\n\x05\x04\x14\x02\0\x05\x12\x04\x95\x03\r\x13\n\r\n\x05\x04\x14\ + \x02\0\x01\x12\x04\x95\x03\x14\x1e\n\r\n\x05\x04\x14\x02\0\x03\x12\x04\ + \x95\x03!\"\n\x0c\n\x04\x04\x14\x02\x01\x12\x04\x96\x03\x04\"\n\r\n\x05\ + \x04\x14\x02\x01\x04\x12\x04\x96\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x01\ + \x05\x12\x04\x96\x03\r\x13\n\r\n\x05\x04\x14\x02\x01\x01\x12\x04\x96\x03\ + \x14\x1d\n\r\n\x05\x04\x14\x02\x01\x03\x12\x04\x96\x03\x20!\n\x0c\n\x04\ + \x04\x14\x02\x02\x12\x04\x98\x03\x04#\n\r\n\x05\x04\x14\x02\x02\x04\x12\ + \x04\x98\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x02\x05\x12\x04\x98\x03\r\x13\ + \n\r\n\x05\x04\x14\x02\x02\x01\x12\x04\x98\x03\x14\x1e\n\r\n\x05\x04\x14\ + \x02\x02\x03\x12\x04\x98\x03!\"\n\x0c\n\x04\x04\x14\x02\x03\x12\x04\x9a\ + \x03\x04-\n\r\n\x05\x04\x14\x02\x03\x04\x12\x04\x9a\x03\x04\x0c\n\r\n\ + \x05\x04\x14\x02\x03\x06\x12\x04\x9a\x03\r\x1e\n\r\n\x05\x04\x14\x02\x03\ + \x01\x12\x04\x9a\x03\x1f(\n\r\n\x05\x04\x14\x02\x03\x03\x12\x04\x9a\x03+\ + ,\n\x0c\n\x04\x04\x14\x02\x04\x12\x04\x9c\x03\x04\"\n\r\n\x05\x04\x14\ + \x02\x04\x04\x12\x04\x9c\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x04\x05\x12\ + \x04\x9c\x03\r\x13\n\r\n\x05\x04\x14\x02\x04\x01\x12\x04\x9c\x03\x14\x1c\ + \n\r\n\x05\x04\x14\x02\x04\x03\x12\x04\x9c\x03\x1f!\n\x0c\n\x04\x04\x14\ + \x02\x05\x12\x04\x9d\x03\x04\"\n\r\n\x05\x04\x14\x02\x05\x04\x12\x04\x9d\ + \x03\x04\x0c\n\r\n\x05\x04\x14\x02\x05\x05\x12\x04\x9d\x03\r\x13\n\r\n\ + \x05\x04\x14\x02\x05\x01\x12\x04\x9d\x03\x14\x1c\n\r\n\x05\x04\x14\x02\ + \x05\x03\x12\x04\x9d\x03\x1f!\n\x0c\n\x04\x04\x14\x02\x06\x12\x04\x9e\ + \x03\x04\x20\n\r\n\x05\x04\x14\x02\x06\x04\x12\x04\x9e\x03\x04\x0c\n\r\n\ + \x05\x04\x14\x02\x06\x06\x12\x04\x9e\x03\r\x14\n\r\n\x05\x04\x14\x02\x06\ + \x01\x12\x04\x9e\x03\x15\x1a\n\r\n\x05\x04\x14\x02\x06\x03\x12\x04\x9e\ + \x03\x1d\x1f\nT\n\x02\x04\x15\x12\x06\xa2\x03\0\xb6\x03\x01\x1aF\x20Addi\ + ng\x20message\x20response\x20from\x20Station\x20to\x20Client\x20for\x20b\ + idirectional\x20API\n\n\x0b\n\x03\x04\x15\x01\x12\x04\xa2\x03\x08\x1c\n\ + \x0c\n\x04\x04\x15\x02\0\x12\x04\xa3\x03\x02\x20\n\r\n\x05\x04\x15\x02\0\ + \x04\x12\x04\xa3\x03\x02\n\n\r\n\x05\x04\x15\x02\0\x05\x12\x04\xa3\x03\ + \x0b\x12\n\r\n\x05\x04\x15\x02\0\x01\x12\x04\xa3\x03\x13\x1b\n\r\n\x05\ + \x04\x15\x02\0\x03\x12\x04\xa3\x03\x1e\x1f\n?\n\x04\x04\x15\x02\x01\x12\ + \x04\xa5\x03\x02\x1e\x1a1\x20The\x20128-bit\x20ipv6\x20address,\x20in\ + \x20network\x20byte\x20order\n\n\r\n\x05\x04\x15\x02\x01\x04\x12\x04\xa5\ + \x03\x02\n\n\r\n\x05\x04\x15\x02\x01\x05\x12\x04\xa5\x03\x0b\x10\n\r\n\ + \x05\x04\x15\x02\x01\x01\x12\x04\xa5\x03\x11\x19\n\r\n\x05\x04\x15\x02\ + \x01\x03\x12\x04\xa5\x03\x1c\x1d\n,\n\x04\x04\x15\x02\x02\x12\x04\xa8\ + \x03\x02\x1f\x1a\x1e\x20Respond\x20with\x20randomized\x20port\n\n\r\n\ + \x05\x04\x15\x02\x02\x04\x12\x04\xa8\x03\x02\n\n\r\n\x05\x04\x15\x02\x02\ + \x05\x12\x04\xa8\x03\x0b\x11\n\r\n\x05\x04\x15\x02\x02\x01\x12\x04\xa8\ + \x03\x12\x1a\n\r\n\x05\x04\x15\x02\x02\x03\x12\x04\xa8\x03\x1d\x1e\nd\n\ + \x04\x04\x15\x02\x03\x12\x04\xac\x03\x02\"\x1aV\x20Future:\x20station\ + \x20provides\x20client\x20with\x20secret,\x20want\x20chanel\x20present\n\ + \x20Leave\x20null\x20for\x20now\n\n\r\n\x05\x04\x15\x02\x03\x04\x12\x04\ + \xac\x03\x02\n\n\r\n\x05\x04\x15\x02\x03\x05\x12\x04\xac\x03\x0b\x10\n\r\ + \n\x05\x04\x15\x02\x03\x01\x12\x04\xac\x03\x11\x1d\n\r\n\x05\x04\x15\x02\ + \x03\x03\x12\x04\xac\x03\x20!\nA\n\x04\x04\x15\x02\x04\x12\x04\xaf\x03\ + \x02\x1c\x1a3\x20If\x20registration\x20wrong,\x20populate\x20this\x20err\ + or\x20string\n\n\r\n\x05\x04\x15\x02\x04\x04\x12\x04\xaf\x03\x02\n\n\r\n\ + \x05\x04\x15\x02\x04\x05\x12\x04\xaf\x03\x0b\x11\n\r\n\x05\x04\x15\x02\ + \x04\x01\x12\x04\xaf\x03\x12\x17\n\r\n\x05\x04\x15\x02\x04\x03\x12\x04\ + \xaf\x03\x1a\x1b\n+\n\x04\x04\x15\x02\x05\x12\x04\xb2\x03\x02%\x1a\x1d\ + \x20ClientConf\x20field\x20(optional)\n\n\r\n\x05\x04\x15\x02\x05\x04\ + \x12\x04\xb2\x03\x02\n\n\r\n\x05\x04\x15\x02\x05\x06\x12\x04\xb2\x03\x0b\ + \x15\n\r\n\x05\x04\x15\x02\x05\x01\x12\x04\xb2\x03\x16\x20\n\r\n\x05\x04\ + \x15\x02\x05\x03\x12\x04\xb2\x03#$\nJ\n\x04\x04\x15\x02\x06\x12\x04\xb5\ + \x03\x025\x1a<\x20Transport\x20Params\x20to\x20if\x20`allow_registrar_ov\ + errides`\x20is\x20set.\n\n\r\n\x05\x04\x15\x02\x06\x04\x12\x04\xb5\x03\ + \x02\n\n\r\n\x05\x04\x15\x02\x06\x06\x12\x04\xb5\x03\x0b\x1e\n\r\n\x05\ + \x04\x15\x02\x06\x01\x12\x04\xb5\x03\x1f/\n\r\n\x05\x04\x15\x02\x06\x03\ + \x12\x04\xb5\x0324\n!\n\x02\x04\x16\x12\x06\xb9\x03\0\xbd\x03\x01\x1a\ + \x13\x20response\x20from\x20dns\n\n\x0b\n\x03\x04\x16\x01\x12\x04\xb9\ + \x03\x08\x13\n\x0c\n\x04\x04\x16\x02\0\x12\x04\xba\x03\x04\x1e\n\r\n\x05\ + \x04\x16\x02\0\x04\x12\x04\xba\x03\x04\x0c\n\r\n\x05\x04\x16\x02\0\x05\ + \x12\x04\xba\x03\r\x11\n\r\n\x05\x04\x16\x02\0\x01\x12\x04\xba\x03\x12\ + \x19\n\r\n\x05\x04\x16\x02\0\x03\x12\x04\xba\x03\x1c\x1d\n\x0c\n\x04\x04\ + \x16\x02\x01\x12\x04\xbb\x03\x04*\n\r\n\x05\x04\x16\x02\x01\x04\x12\x04\ + \xbb\x03\x04\x0c\n\r\n\x05\x04\x16\x02\x01\x05\x12\x04\xbb\x03\r\x11\n\r\ + \n\x05\x04\x16\x02\x01\x01\x12\x04\xbb\x03\x12%\n\r\n\x05\x04\x16\x02\ + \x01\x03\x12\x04\xbb\x03()\n\x0c\n\x04\x04\x16\x02\x02\x12\x04\xbc\x03\ + \x04=\n\r\n\x05\x04\x16\x02\x02\x04\x12\x04\xbc\x03\x04\x0c\n\r\n\x05\ + \x04\x16\x02\x02\x06\x12\x04\xbc\x03\r!\n\r\n\x05\x04\x16\x02\x02\x01\ + \x12\x04\xbc\x03\"8\n\r\n\x05\x04\x16\x02\x02\x03\x12\x04\xbc\x03;<\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -7589,7 +8155,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(1); deps.push(::protobuf::well_known_types::any::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(21); + let mut messages = ::std::vec::Vec::with_capacity(23); messages.push(PubKey::generated_message_descriptor_data()); messages.push(TLSDecoySpec::generated_message_descriptor_data()); messages.push(ClientConf::generated_message_descriptor_data()); @@ -7600,10 +8166,12 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(WebRTCICECandidate::generated_message_descriptor_data()); messages.push(WebRTCSDP::generated_message_descriptor_data()); messages.push(WebRTCSignal::generated_message_descriptor_data()); + messages.push(Addr::generated_message_descriptor_data()); messages.push(DTLSTransportParams::generated_message_descriptor_data()); messages.push(StationToClient::generated_message_descriptor_data()); messages.push(RegistrationFlags::generated_message_descriptor_data()); messages.push(ClientToStation::generated_message_descriptor_data()); + messages.push(UTLSTransportParams::generated_message_descriptor_data()); messages.push(PrefixTransportParams::generated_message_descriptor_data()); messages.push(GenericTransportParams::generated_message_descriptor_data()); messages.push(C2SWrapper::generated_message_descriptor_data()); diff --git a/src/signalling.rs b/src/signalling.rs index 22fee424..f85a1cc2 100644 --- a/src/signalling.rs +++ b/src/signalling.rs @@ -2302,49 +2302,227 @@ impl ::protobuf::reflect::ProtobufValue for WebRTCSignal { } #[derive(PartialEq,Clone,Default,Debug)] -// @@protoc_insertion_point(message:proto.DTLSTransportParams) -pub struct DTLSTransportParams { +// @@protoc_insertion_point(message:proto.Addr) +pub struct Addr { // message fields - // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_port) - pub src_port: ::std::option::Option, - // @@protoc_insertion_point(field:proto.DTLSTransportParams.randomize_dst_port) - pub randomize_dst_port: ::std::option::Option, + // @@protoc_insertion_point(field:proto.Addr.IP) + pub IP: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:proto.Addr.Port) + pub Port: ::std::option::Option, // special fields - // @@protoc_insertion_point(special_field:proto.DTLSTransportParams.special_fields) + // @@protoc_insertion_point(special_field:proto.Addr.special_fields) pub special_fields: ::protobuf::SpecialFields, } -impl<'a> ::std::default::Default for &'a DTLSTransportParams { - fn default() -> &'a DTLSTransportParams { - ::default_instance() +impl<'a> ::std::default::Default for &'a Addr { + fn default() -> &'a Addr { + ::default_instance() } } -impl DTLSTransportParams { - pub fn new() -> DTLSTransportParams { +impl Addr { + pub fn new() -> Addr { ::std::default::Default::default() } - // optional uint32 src_port = 1; + // optional bytes IP = 1; - pub fn src_port(&self) -> u32 { - self.src_port.unwrap_or(0) + pub fn IP(&self) -> &[u8] { + match self.IP.as_ref() { + Some(v) => v, + None => &[], + } } - pub fn clear_src_port(&mut self) { - self.src_port = ::std::option::Option::None; + pub fn clear_IP(&mut self) { + self.IP = ::std::option::Option::None; } - pub fn has_src_port(&self) -> bool { - self.src_port.is_some() + pub fn has_IP(&self) -> bool { + self.IP.is_some() } // Param is passed by value, moved - pub fn set_src_port(&mut self, v: u32) { - self.src_port = ::std::option::Option::Some(v); + pub fn set_IP(&mut self, v: ::std::vec::Vec) { + self.IP = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_IP(&mut self) -> &mut ::std::vec::Vec { + if self.IP.is_none() { + self.IP = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.IP.as_mut().unwrap() + } + + // Take field + pub fn take_IP(&mut self) -> ::std::vec::Vec { + self.IP.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional uint32 Port = 2; + + pub fn Port(&self) -> u32 { + self.Port.unwrap_or(0) + } + + pub fn clear_Port(&mut self) { + self.Port = ::std::option::Option::None; + } + + pub fn has_Port(&self) -> bool { + self.Port.is_some() + } + + // Param is passed by value, moved + pub fn set_Port(&mut self, v: u32) { + self.Port = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "IP", + |m: &Addr| { &m.IP }, + |m: &mut Addr| { &mut m.IP }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "Port", + |m: &Addr| { &m.Port }, + |m: &mut Addr| { &mut m.Port }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "Addr", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for Addr { + const NAME: &'static str = "Addr"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.IP = ::std::option::Option::Some(is.read_bytes()?); + }, + 16 => { + self.Port = ::std::option::Option::Some(is.read_uint32()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.IP.as_ref() { + my_size += ::protobuf::rt::bytes_size(1, &v); + } + if let Some(v) = self.Port { + my_size += ::protobuf::rt::uint32_size(2, v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.IP.as_ref() { + os.write_bytes(1, v)?; + } + if let Some(v) = self.Port { + os.write_uint32(2, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> Addr { + Addr::new() + } + + fn clear(&mut self) { + self.IP = ::std::option::Option::None; + self.Port = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static Addr { + static instance: Addr = Addr { + IP: ::std::option::Option::None, + Port: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for Addr { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("Addr").unwrap()).clone() + } +} + +impl ::std::fmt::Display for Addr { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for Addr { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:proto.DTLSTransportParams) +pub struct DTLSTransportParams { + // message fields + // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_addr4) + pub src_addr4: ::protobuf::MessageField, + // @@protoc_insertion_point(field:proto.DTLSTransportParams.src_addr6) + pub src_addr6: ::protobuf::MessageField, + // @@protoc_insertion_point(field:proto.DTLSTransportParams.randomize_dst_port) + pub randomize_dst_port: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:proto.DTLSTransportParams.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a DTLSTransportParams { + fn default() -> &'a DTLSTransportParams { + ::default_instance() + } +} + +impl DTLSTransportParams { + pub fn new() -> DTLSTransportParams { + ::std::default::Default::default() } - // optional bool randomize_dst_port = 2; + // optional bool randomize_dst_port = 3; pub fn randomize_dst_port(&self) -> bool { self.randomize_dst_port.unwrap_or(false) @@ -2364,12 +2542,17 @@ impl DTLSTransportParams { } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); + let mut fields = ::std::vec::Vec::with_capacity(3); let mut oneofs = ::std::vec::Vec::with_capacity(0); - fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( - "src_port", - |m: &DTLSTransportParams| { &m.src_port }, - |m: &mut DTLSTransportParams| { &mut m.src_port }, + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, Addr>( + "src_addr4", + |m: &DTLSTransportParams| { &m.src_addr4 }, + |m: &mut DTLSTransportParams| { &mut m.src_addr4 }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, Addr>( + "src_addr6", + |m: &DTLSTransportParams| { &m.src_addr6 }, + |m: &mut DTLSTransportParams| { &mut m.src_addr6 }, )); fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( "randomize_dst_port", @@ -2394,10 +2577,13 @@ impl ::protobuf::Message for DTLSTransportParams { fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { while let Some(tag) = is.read_raw_tag_or_eof()? { match tag { - 8 => { - self.src_port = ::std::option::Option::Some(is.read_uint32()?); + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.src_addr4)?; }, - 16 => { + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.src_addr6)?; + }, + 24 => { self.randomize_dst_port = ::std::option::Option::Some(is.read_bool()?); }, tag => { @@ -2412,8 +2598,13 @@ impl ::protobuf::Message for DTLSTransportParams { #[allow(unused_variables)] fn compute_size(&self) -> u64 { let mut my_size = 0; - if let Some(v) = self.src_port { - my_size += ::protobuf::rt::uint32_size(1, v); + if let Some(v) = self.src_addr4.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + if let Some(v) = self.src_addr6.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; } if let Some(v) = self.randomize_dst_port { my_size += 1 + 1; @@ -2424,11 +2615,14 @@ impl ::protobuf::Message for DTLSTransportParams { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { - if let Some(v) = self.src_port { - os.write_uint32(1, v)?; + if let Some(v) = self.src_addr4.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + if let Some(v) = self.src_addr6.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; } if let Some(v) = self.randomize_dst_port { - os.write_bool(2, v)?; + os.write_bool(3, v)?; } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) @@ -2447,14 +2641,16 @@ impl ::protobuf::Message for DTLSTransportParams { } fn clear(&mut self) { - self.src_port = ::std::option::Option::None; + self.src_addr4.clear(); + self.src_addr6.clear(); self.randomize_dst_port = ::std::option::Option::None; self.special_fields.clear(); } fn default_instance() -> &'static DTLSTransportParams { static instance: DTLSTransportParams = DTLSTransportParams { - src_port: ::std::option::Option::None, + src_addr4: ::protobuf::MessageField::none(), + src_addr6: ::protobuf::MessageField::none(), randomize_dst_port: ::std::option::Option::None, special_fields: ::protobuf::SpecialFields::new(), }; @@ -3911,6 +4107,332 @@ impl ::protobuf::reflect::ProtobufValue for ClientToStation { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +#[derive(PartialEq,Clone,Default,Debug)] +// @@protoc_insertion_point(message:proto.UTLSTransportParams) +pub struct UTLSTransportParams { + // message fields + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ch_id) + pub ch_id: ::std::option::Option, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ch_spec) + pub ch_spec: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.ciphersuite) + pub ciphersuite: ::std::option::Option, + // @@protoc_insertion_point(field:proto.UTLSTransportParams.sni) + pub sni: ::std::option::Option<::std::vec::Vec>, + /// Indicates whether the client has elected to use destination port randomization. Should be + /// checked against selected transport to ensure that destination port randomization is + /// supported. + // @@protoc_insertion_point(field:proto.UTLSTransportParams.randomize_dst_port) + pub randomize_dst_port: ::std::option::Option, + // special fields + // @@protoc_insertion_point(special_field:proto.UTLSTransportParams.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a UTLSTransportParams { + fn default() -> &'a UTLSTransportParams { + ::default_instance() + } +} + +impl UTLSTransportParams { + pub fn new() -> UTLSTransportParams { + ::std::default::Default::default() + } + + // optional int32 ch_id = 1; + + pub fn ch_id(&self) -> i32 { + self.ch_id.unwrap_or(0) + } + + pub fn clear_ch_id(&mut self) { + self.ch_id = ::std::option::Option::None; + } + + pub fn has_ch_id(&self) -> bool { + self.ch_id.is_some() + } + + // Param is passed by value, moved + pub fn set_ch_id(&mut self, v: i32) { + self.ch_id = ::std::option::Option::Some(v); + } + + // optional bytes ch_spec = 2; + + pub fn ch_spec(&self) -> &[u8] { + match self.ch_spec.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_ch_spec(&mut self) { + self.ch_spec = ::std::option::Option::None; + } + + pub fn has_ch_spec(&self) -> bool { + self.ch_spec.is_some() + } + + // Param is passed by value, moved + pub fn set_ch_spec(&mut self, v: ::std::vec::Vec) { + self.ch_spec = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_ch_spec(&mut self) -> &mut ::std::vec::Vec { + if self.ch_spec.is_none() { + self.ch_spec = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.ch_spec.as_mut().unwrap() + } + + // Take field + pub fn take_ch_spec(&mut self) -> ::std::vec::Vec { + self.ch_spec.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional int32 ciphersuite = 3; + + pub fn ciphersuite(&self) -> i32 { + self.ciphersuite.unwrap_or(0) + } + + pub fn clear_ciphersuite(&mut self) { + self.ciphersuite = ::std::option::Option::None; + } + + pub fn has_ciphersuite(&self) -> bool { + self.ciphersuite.is_some() + } + + // Param is passed by value, moved + pub fn set_ciphersuite(&mut self, v: i32) { + self.ciphersuite = ::std::option::Option::Some(v); + } + + // optional bytes sni = 8; + + pub fn sni(&self) -> &[u8] { + match self.sni.as_ref() { + Some(v) => v, + None => &[], + } + } + + pub fn clear_sni(&mut self) { + self.sni = ::std::option::Option::None; + } + + pub fn has_sni(&self) -> bool { + self.sni.is_some() + } + + // Param is passed by value, moved + pub fn set_sni(&mut self, v: ::std::vec::Vec) { + self.sni = ::std::option::Option::Some(v); + } + + // Mutable pointer to the field. + // If field is not initialized, it is initialized with default value first. + pub fn mut_sni(&mut self) -> &mut ::std::vec::Vec { + if self.sni.is_none() { + self.sni = ::std::option::Option::Some(::std::vec::Vec::new()); + } + self.sni.as_mut().unwrap() + } + + // Take field + pub fn take_sni(&mut self) -> ::std::vec::Vec { + self.sni.take().unwrap_or_else(|| ::std::vec::Vec::new()) + } + + // optional bool randomize_dst_port = 13; + + pub fn randomize_dst_port(&self) -> bool { + self.randomize_dst_port.unwrap_or(false) + } + + pub fn clear_randomize_dst_port(&mut self) { + self.randomize_dst_port = ::std::option::Option::None; + } + + pub fn has_randomize_dst_port(&self) -> bool { + self.randomize_dst_port.is_some() + } + + // Param is passed by value, moved + pub fn set_randomize_dst_port(&mut self, v: bool) { + self.randomize_dst_port = ::std::option::Option::Some(v); + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(5); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ch_id", + |m: &UTLSTransportParams| { &m.ch_id }, + |m: &mut UTLSTransportParams| { &mut m.ch_id }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ch_spec", + |m: &UTLSTransportParams| { &m.ch_spec }, + |m: &mut UTLSTransportParams| { &mut m.ch_spec }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "ciphersuite", + |m: &UTLSTransportParams| { &m.ciphersuite }, + |m: &mut UTLSTransportParams| { &mut m.ciphersuite }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "sni", + |m: &UTLSTransportParams| { &m.sni }, + |m: &mut UTLSTransportParams| { &mut m.sni }, + )); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "randomize_dst_port", + |m: &UTLSTransportParams| { &m.randomize_dst_port }, + |m: &mut UTLSTransportParams| { &mut m.randomize_dst_port }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "UTLSTransportParams", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for UTLSTransportParams { + const NAME: &'static str = "UTLSTransportParams"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 8 => { + self.ch_id = ::std::option::Option::Some(is.read_int32()?); + }, + 18 => { + self.ch_spec = ::std::option::Option::Some(is.read_bytes()?); + }, + 24 => { + self.ciphersuite = ::std::option::Option::Some(is.read_int32()?); + }, + 66 => { + self.sni = ::std::option::Option::Some(is.read_bytes()?); + }, + 104 => { + self.randomize_dst_port = ::std::option::Option::Some(is.read_bool()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.ch_id { + my_size += ::protobuf::rt::int32_size(1, v); + } + if let Some(v) = self.ch_spec.as_ref() { + my_size += ::protobuf::rt::bytes_size(2, &v); + } + if let Some(v) = self.ciphersuite { + my_size += ::protobuf::rt::int32_size(3, v); + } + if let Some(v) = self.sni.as_ref() { + my_size += ::protobuf::rt::bytes_size(8, &v); + } + if let Some(v) = self.randomize_dst_port { + my_size += 1 + 1; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.ch_id { + os.write_int32(1, v)?; + } + if let Some(v) = self.ch_spec.as_ref() { + os.write_bytes(2, v)?; + } + if let Some(v) = self.ciphersuite { + os.write_int32(3, v)?; + } + if let Some(v) = self.sni.as_ref() { + os.write_bytes(8, v)?; + } + if let Some(v) = self.randomize_dst_port { + os.write_bool(13, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> UTLSTransportParams { + UTLSTransportParams::new() + } + + fn clear(&mut self) { + self.ch_id = ::std::option::Option::None; + self.ch_spec = ::std::option::Option::None; + self.ciphersuite = ::std::option::Option::None; + self.sni = ::std::option::Option::None; + self.randomize_dst_port = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static UTLSTransportParams { + static instance: UTLSTransportParams = UTLSTransportParams { + ch_id: ::std::option::Option::None, + ch_spec: ::std::option::Option::None, + ciphersuite: ::std::option::Option::None, + sni: ::std::option::Option::None, + randomize_dst_port: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for UTLSTransportParams { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("UTLSTransportParams").unwrap()).clone() + } +} + +impl ::std::fmt::Display for UTLSTransportParams { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for UTLSTransportParams { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + #[derive(PartialEq,Clone,Default,Debug)] // @@protoc_insertion_point(message:proto.PrefixTransportParams) pub struct PrefixTransportParams { @@ -6806,55 +7328,62 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01\x20\x02(\rR\x04type\x129\n\ncandidates\x18\x02\x20\x03(\x0b2\x19.pr\ oto.WebRTCICECandidateR\ncandidates\"F\n\x0cWebRTCSignal\x12\x12\n\x04se\ ed\x18\x01\x20\x02(\tR\x04seed\x12\"\n\x03sdp\x18\x02\x20\x02(\x0b2\x10.\ - proto.WebRTCSDPR\x03sdp\"^\n\x13DTLSTransportParams\x12\x19\n\x08src_por\ - t\x18\x01\x20\x01(\rR\x07srcPort\x12,\n\x12randomize_dst_port\x18\x02\ - \x20\x01(\x08R\x10randomizeDstPort\"\xc2\x02\n\x0fStationToClient\x12)\n\ - \x10protocol_version\x18\x01\x20\x01(\rR\x0fprotocolVersion\x12@\n\x10st\ - ate_transition\x18\x02\x20\x01(\x0e2\x15.proto.S2C_TransitionR\x0fstateT\ - ransition\x122\n\x0bconfig_info\x18\x03\x20\x01(\x0b2\x11.proto.ClientCo\ - nfR\nconfigInfo\x124\n\nerr_reason\x18\x04\x20\x01(\x0e2\x15.proto.Error\ - ReasonS2CR\terrReason\x12\x1f\n\x0btmp_backoff\x18\x05\x20\x01(\rR\ntmpB\ - ackoff\x12\x1d\n\nstation_id\x18\x06\x20\x01(\tR\tstationId\x12\x18\n\ - \x07padding\x18d\x20\x01(\x0cR\x07padding\"\xaf\x01\n\x11RegistrationFla\ - gs\x12\x1f\n\x0bupload_only\x18\x01\x20\x01(\x08R\nuploadOnly\x12\x1d\n\ - \ndark_decoy\x18\x02\x20\x01(\x08R\tdarkDecoy\x12!\n\x0cproxy_header\x18\ - \x03\x20\x01(\x08R\x0bproxyHeader\x12\x17\n\x07use_TIL\x18\x04\x20\x01(\ - \x08R\x06useTIL\x12\x1e\n\nprescanned\x18\x05\x20\x01(\x08R\nprescanned\ - \"\xa8\x06\n\x0fClientToStation\x12)\n\x10protocol_version\x18\x01\x20\ - \x01(\rR\x0fprotocolVersion\x122\n\x15decoy_list_generation\x18\x02\x20\ - \x01(\rR\x13decoyListGeneration\x12@\n\x10state_transition\x18\x03\x20\ - \x01(\x0e2\x15.proto.C2S_TransitionR\x0fstateTransition\x12\x1f\n\x0bupl\ - oad_sync\x18\x04\x20\x01(\x04R\nuploadSync\x12,\n\x12client_lib_version\ - \x18\x05\x20\x01(\rR\x10clientLibVersion\x12>\n\x1bdisable_registrar_ove\ - rrides\x18\x06\x20\x01(\x08R\x19disableRegistrarOverrides\x12#\n\rfailed\ - _decoys\x18\n\x20\x03(\tR\x0cfailedDecoys\x12)\n\x05stats\x18\x0b\x20\ - \x01(\x0b2\x13.proto.SessionStatsR\x05stats\x122\n\ttransport\x18\x0c\ - \x20\x01(\x0e2\x14.proto.TransportTypeR\ttransport\x12?\n\x10transport_p\ - arams\x18\r\x20\x01(\x0b2\x14.google.protobuf.AnyR\x0ftransportParams\ - \x12%\n\x0ecovert_address\x18\x14\x20\x01(\tR\rcovertAddress\x127\n\x18m\ - asked_decoy_server_name\x18\x15\x20\x01(\tR\x15maskedDecoyServerName\x12\ - \x1d\n\nv6_support\x18\x16\x20\x01(\x08R\tv6Support\x12\x1d\n\nv4_suppor\ - t\x18\x17\x20\x01(\x08R\tv4Support\x12.\n\x05flags\x18\x18\x20\x01(\x0b2\ - \x18.proto.RegistrationFlagsR\x05flags\x128\n\rwebrtc_signal\x18\x1f\x20\ - \x01(\x0b2\x13.proto.WebRTCSignalR\x0cwebrtcSignal\x12\x18\n\x07padding\ - \x18d\x20\x01(\x0cR\x07padding\"\xaa\x01\n\x15PrefixTransportParams\x12\ - \x1b\n\tprefix_id\x18\x01\x20\x01(\x05R\x08prefixId\x12\x16\n\x06prefix\ - \x18\x02\x20\x01(\x0cR\x06prefix\x12.\n\x13custom_flush_policy\x18\x03\ - \x20\x01(\x05R\x11customFlushPolicy\x12,\n\x12randomize_dst_port\x18\r\ - \x20\x01(\x08R\x10randomizeDstPort\"F\n\x16GenericTransportParams\x12,\n\ - \x12randomize_dst_port\x18\r\x20\x01(\x08R\x10randomizeDstPort\"\xc2\x03\ - \n\nC2SWrapper\x12#\n\rshared_secret\x18\x01\x20\x01(\x0cR\x0csharedSecr\ - et\x12I\n\x14registration_payload\x18\x03\x20\x01(\x0b2\x16.proto.Client\ - ToStationR\x13registrationPayload\x12J\n\x13registration_source\x18\x04\ - \x20\x01(\x0e2\x19.proto.RegistrationSourceR\x12registrationSource\x121\ - \n\x14registration_address\x18\x06\x20\x01(\x0cR\x13registrationAddress\ - \x12#\n\rdecoy_address\x18\x07\x20\x01(\x0cR\x0cdecoyAddress\x12P\n\x15r\ - egistration_response\x18\x08\x20\x01(\x0b2\x1b.proto.RegistrationRespons\ - eR\x14registrationResponse\x12\"\n\x0cRegRespBytes\x18\t\x20\x01(\x0cR\ - \x0cRegRespBytes\x12*\n\x10RegRespSignature\x18\n\x20\x01(\x0cR\x10RegRe\ - spSignature\"\xdd\x01\n\x0cSessionStats\x120\n\x14failed_decoys_amount\ - \x18\x14\x20\x01(\rR\x12failedDecoysAmount\x121\n\x15total_time_to_conne\ - ct\x18\x1f\x20\x01(\rR\x12totalTimeToConnect\x12$\n\x0ertt_to_station\ + proto.WebRTCSDPR\x03sdp\"*\n\x04Addr\x12\x0e\n\x02IP\x18\x01\x20\x01(\ + \x0cR\x02IP\x12\x12\n\x04Port\x18\x02\x20\x01(\rR\x04Port\"\x97\x01\n\ + \x13DTLSTransportParams\x12(\n\tsrc_addr4\x18\x01\x20\x01(\x0b2\x0b.prot\ + o.AddrR\x08srcAddr4\x12(\n\tsrc_addr6\x18\x02\x20\x01(\x0b2\x0b.proto.Ad\ + drR\x08srcAddr6\x12,\n\x12randomize_dst_port\x18\x03\x20\x01(\x08R\x10ra\ + ndomizeDstPort\"\xc2\x02\n\x0fStationToClient\x12)\n\x10protocol_version\ + \x18\x01\x20\x01(\rR\x0fprotocolVersion\x12@\n\x10state_transition\x18\ + \x02\x20\x01(\x0e2\x15.proto.S2C_TransitionR\x0fstateTransition\x122\n\ + \x0bconfig_info\x18\x03\x20\x01(\x0b2\x11.proto.ClientConfR\nconfigInfo\ + \x124\n\nerr_reason\x18\x04\x20\x01(\x0e2\x15.proto.ErrorReasonS2CR\terr\ + Reason\x12\x1f\n\x0btmp_backoff\x18\x05\x20\x01(\rR\ntmpBackoff\x12\x1d\ + \n\nstation_id\x18\x06\x20\x01(\tR\tstationId\x12\x18\n\x07padding\x18d\ + \x20\x01(\x0cR\x07padding\"\xaf\x01\n\x11RegistrationFlags\x12\x1f\n\x0b\ + upload_only\x18\x01\x20\x01(\x08R\nuploadOnly\x12\x1d\n\ndark_decoy\x18\ + \x02\x20\x01(\x08R\tdarkDecoy\x12!\n\x0cproxy_header\x18\x03\x20\x01(\ + \x08R\x0bproxyHeader\x12\x17\n\x07use_TIL\x18\x04\x20\x01(\x08R\x06useTI\ + L\x12\x1e\n\nprescanned\x18\x05\x20\x01(\x08R\nprescanned\"\xa8\x06\n\ + \x0fClientToStation\x12)\n\x10protocol_version\x18\x01\x20\x01(\rR\x0fpr\ + otocolVersion\x122\n\x15decoy_list_generation\x18\x02\x20\x01(\rR\x13dec\ + oyListGeneration\x12@\n\x10state_transition\x18\x03\x20\x01(\x0e2\x15.pr\ + oto.C2S_TransitionR\x0fstateTransition\x12\x1f\n\x0bupload_sync\x18\x04\ + \x20\x01(\x04R\nuploadSync\x12,\n\x12client_lib_version\x18\x05\x20\x01(\ + \rR\x10clientLibVersion\x12>\n\x1bdisable_registrar_overrides\x18\x06\ + \x20\x01(\x08R\x19disableRegistrarOverrides\x12#\n\rfailed_decoys\x18\n\ + \x20\x03(\tR\x0cfailedDecoys\x12)\n\x05stats\x18\x0b\x20\x01(\x0b2\x13.p\ + roto.SessionStatsR\x05stats\x122\n\ttransport\x18\x0c\x20\x01(\x0e2\x14.\ + proto.TransportTypeR\ttransport\x12?\n\x10transport_params\x18\r\x20\x01\ + (\x0b2\x14.google.protobuf.AnyR\x0ftransportParams\x12%\n\x0ecovert_addr\ + ess\x18\x14\x20\x01(\tR\rcovertAddress\x127\n\x18masked_decoy_server_nam\ + e\x18\x15\x20\x01(\tR\x15maskedDecoyServerName\x12\x1d\n\nv6_support\x18\ + \x16\x20\x01(\x08R\tv6Support\x12\x1d\n\nv4_support\x18\x17\x20\x01(\x08\ + R\tv4Support\x12.\n\x05flags\x18\x18\x20\x01(\x0b2\x18.proto.Registratio\ + nFlagsR\x05flags\x128\n\rwebrtc_signal\x18\x1f\x20\x01(\x0b2\x13.proto.W\ + ebRTCSignalR\x0cwebrtcSignal\x12\x18\n\x07padding\x18d\x20\x01(\x0cR\x07\ + padding\"\xa5\x01\n\x13UTLSTransportParams\x12\x13\n\x05ch_id\x18\x01\ + \x20\x01(\x05R\x04chId\x12\x17\n\x07ch_spec\x18\x02\x20\x01(\x0cR\x06chS\ + pec\x12\x20\n\x0bciphersuite\x18\x03\x20\x01(\x05R\x0bciphersuite\x12\ + \x10\n\x03sni\x18\x08\x20\x01(\x0cR\x03sni\x12,\n\x12randomize_dst_port\ + \x18\r\x20\x01(\x08R\x10randomizeDstPort\"\xaa\x01\n\x15PrefixTransportP\ + arams\x12\x1b\n\tprefix_id\x18\x01\x20\x01(\x05R\x08prefixId\x12\x16\n\ + \x06prefix\x18\x02\x20\x01(\x0cR\x06prefix\x12.\n\x13custom_flush_policy\ + \x18\x03\x20\x01(\x05R\x11customFlushPolicy\x12,\n\x12randomize_dst_port\ + \x18\r\x20\x01(\x08R\x10randomizeDstPort\"F\n\x16GenericTransportParams\ + \x12,\n\x12randomize_dst_port\x18\r\x20\x01(\x08R\x10randomizeDstPort\"\ + \xc2\x03\n\nC2SWrapper\x12#\n\rshared_secret\x18\x01\x20\x01(\x0cR\x0csh\ + aredSecret\x12I\n\x14registration_payload\x18\x03\x20\x01(\x0b2\x16.prot\ + o.ClientToStationR\x13registrationPayload\x12J\n\x13registration_source\ + \x18\x04\x20\x01(\x0e2\x19.proto.RegistrationSourceR\x12registrationSour\ + ce\x121\n\x14registration_address\x18\x06\x20\x01(\x0cR\x13registrationA\ + ddress\x12#\n\rdecoy_address\x18\x07\x20\x01(\x0cR\x0cdecoyAddress\x12P\ + \n\x15registration_response\x18\x08\x20\x01(\x0b2\x1b.proto.Registration\ + ResponseR\x14registrationResponse\x12\"\n\x0cRegRespBytes\x18\t\x20\x01(\ + \x0cR\x0cRegRespBytes\x12*\n\x10RegRespSignature\x18\n\x20\x01(\x0cR\x10\ + RegRespSignature\"\xdd\x01\n\x0cSessionStats\x120\n\x14failed_decoys_amo\ + unt\x18\x14\x20\x01(\rR\x12failedDecoysAmount\x121\n\x15total_time_to_co\ + nnect\x18\x1f\x20\x01(\rR\x12totalTimeToConnect\x12$\n\x0ertt_to_station\ \x18!\x20\x01(\rR\x0crttToStation\x12\x20\n\x0ctls_to_decoy\x18&\x20\x01\ (\rR\ntlsToDecoy\x12\x20\n\x0ctcp_to_decoy\x18'\x20\x01(\rR\ntcpToDecoy\ \"\x82\x02\n\x11StationToDetector\x12\x1d\n\nphantom_ip\x18\x01\x20\x01(\ @@ -6900,7 +7429,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ectionalDNS\x10\x06*@\n\x11StationOperations\x12\x0b\n\x07Unknown\x10\0\ \x12\x07\n\x03New\x10\x01\x12\n\n\x06Update\x10\x02\x12\t\n\x05Clear\x10\ \x03*$\n\x07IPProto\x12\x07\n\x03Unk\x10\0\x12\x07\n\x03Tcp\x10\x01\x12\ - \x07\n\x03Udp\x10\x02J\x81\x90\x01\n\x07\x12\x05\0\0\xa8\x03\x01\n\x08\n\ + \x07\n\x03Udp\x10\x02J\xc7\x96\x01\n\x07\x12\x05\0\0\xbd\x03\x01\n\x08\n\ \x01\x0c\x12\x03\0\0\x12\n\xb0\x01\n\x01\x02\x12\x03\x06\0\x0e2\xa5\x01\ \x20TODO:\x20We're\x20using\x20proto2\x20because\x20it's\x20the\x20defau\ lt\x20on\x20Ubuntu\x2016.04.\n\x20At\x20some\x20point\x20we\x20will\x20w\ @@ -7192,385 +7721,422 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \n\r\n\x05\x04\t\x02\x01\x06\x12\x04\xbf\x01\r\x16\n\r\n\x05\x04\t\x02\ \x01\x01\x12\x04\xbf\x01\x17\x1a\n\r\n\x05\x04\t\x02\x01\x03\x12\x04\xbf\ \x01\x1d\x1e\n\x0c\n\x02\x04\n\x12\x06\xc2\x01\0\xc5\x01\x01\n\x0b\n\x03\ - \x04\n\x01\x12\x04\xc2\x01\x08\x1b\n\x0c\n\x04\x04\n\x02\0\x12\x04\xc3\ - \x01\x04!\n\r\n\x05\x04\n\x02\0\x04\x12\x04\xc3\x01\x04\x0c\n\r\n\x05\ - \x04\n\x02\0\x05\x12\x04\xc3\x01\r\x13\n\r\n\x05\x04\n\x02\0\x01\x12\x04\ - \xc3\x01\x14\x1c\n\r\n\x05\x04\n\x02\0\x03\x12\x04\xc3\x01\x1f\x20\n\x0c\ - \n\x04\x04\n\x02\x01\x12\x04\xc4\x01\x04)\n\r\n\x05\x04\n\x02\x01\x04\ + \x04\n\x01\x12\x04\xc2\x01\x08\x0c\n\x0c\n\x04\x04\n\x02\0\x12\x04\xc3\ + \x01\x04\x1a\n\r\n\x05\x04\n\x02\0\x04\x12\x04\xc3\x01\x04\x0c\n\r\n\x05\ + \x04\n\x02\0\x05\x12\x04\xc3\x01\r\x12\n\r\n\x05\x04\n\x02\0\x01\x12\x04\ + \xc3\x01\x13\x15\n\r\n\x05\x04\n\x02\0\x03\x12\x04\xc3\x01\x18\x19\n\x0c\ + \n\x04\x04\n\x02\x01\x12\x04\xc4\x01\x04\x1d\n\r\n\x05\x04\n\x02\x01\x04\ \x12\x04\xc4\x01\x04\x0c\n\r\n\x05\x04\n\x02\x01\x05\x12\x04\xc4\x01\r\ - \x11\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\xc4\x01\x12$\n\r\n\x05\x04\n\ - \x02\x01\x03\x12\x04\xc4\x01'(\n\x0c\n\x02\x04\x0b\x12\x06\xc7\x01\0\xde\ - \x01\x01\n\x0b\n\x03\x04\x0b\x01\x12\x04\xc7\x01\x08\x17\nO\n\x04\x04\ - \x0b\x02\0\x12\x04\xc9\x01\x04)\x1aA\x20Should\x20accompany\x20(at\x20le\ - ast)\x20SESSION_INIT\x20and\x20CONFIRM_RECONNECT.\n\n\r\n\x05\x04\x0b\ - \x02\0\x04\x12\x04\xc9\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\0\x05\x12\x04\ - \xc9\x01\r\x13\n\r\n\x05\x04\x0b\x02\0\x01\x12\x04\xc9\x01\x14$\n\r\n\ - \x05\x04\x0b\x02\0\x03\x12\x04\xc9\x01'(\nv\n\x04\x04\x0b\x02\x01\x12\ - \x04\xcd\x01\x041\x1ah\x20There\x20might\x20be\x20a\x20state\x20transiti\ - on.\x20May\x20be\x20absent;\x20absence\x20should\x20be\n\x20treated\x20i\ - dentically\x20to\x20NO_CHANGE.\n\n\r\n\x05\x04\x0b\x02\x01\x04\x12\x04\ - \xcd\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x01\x06\x12\x04\xcd\x01\r\x1b\n\r\ - \n\x05\x04\x0b\x02\x01\x01\x12\x04\xcd\x01\x1c,\n\r\n\x05\x04\x0b\x02\ - \x01\x03\x12\x04\xcd\x01/0\nc\n\x04\x04\x0b\x02\x02\x12\x04\xd1\x01\x04(\ - \x1aU\x20The\x20station\x20can\x20send\x20client\x20config\x20info\x20pi\ - ggybacked\n\x20on\x20any\x20message,\x20as\x20it\x20sees\x20fit\n\n\r\n\ - \x05\x04\x0b\x02\x02\x04\x12\x04\xd1\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\ - \x02\x06\x12\x04\xd1\x01\r\x17\n\r\n\x05\x04\x0b\x02\x02\x01\x12\x04\xd1\ - \x01\x18#\n\r\n\x05\x04\x0b\x02\x02\x03\x12\x04\xd1\x01&'\nP\n\x04\x04\ - \x0b\x02\x03\x12\x04\xd4\x01\x04+\x1aB\x20If\x20state_transition\x20==\ - \x20S2C_ERROR,\x20this\x20field\x20is\x20the\x20explanation.\n\n\r\n\x05\ - \x04\x0b\x02\x03\x04\x12\x04\xd4\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x03\ - \x06\x12\x04\xd4\x01\r\x1b\n\r\n\x05\x04\x0b\x02\x03\x01\x12\x04\xd4\x01\ - \x1c&\n\r\n\x05\x04\x0b\x02\x03\x03\x12\x04\xd4\x01)*\nQ\n\x04\x04\x0b\ - \x02\x04\x12\x04\xd7\x01\x04$\x1aC\x20Signals\x20client\x20to\x20stop\ - \x20connecting\x20for\x20following\x20amount\x20of\x20seconds\n\n\r\n\ - \x05\x04\x0b\x02\x04\x04\x12\x04\xd7\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\ - \x04\x05\x12\x04\xd7\x01\r\x13\n\r\n\x05\x04\x0b\x02\x04\x01\x12\x04\xd7\ - \x01\x14\x1f\n\r\n\x05\x04\x0b\x02\x04\x03\x12\x04\xd7\x01\"#\nK\n\x04\ - \x04\x0b\x02\x05\x12\x04\xda\x01\x04#\x1a=\x20Sent\x20in\x20SESSION_INIT\ - ,\x20identifies\x20the\x20station\x20that\x20picked\x20up\n\n\r\n\x05\ - \x04\x0b\x02\x05\x04\x12\x04\xda\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x05\ - \x05\x12\x04\xda\x01\r\x13\n\r\n\x05\x04\x0b\x02\x05\x01\x12\x04\xda\x01\ - \x14\x1e\n\r\n\x05\x04\x0b\x02\x05\x03\x12\x04\xda\x01!\"\nG\n\x04\x04\ - \x0b\x02\x06\x12\x04\xdd\x01\x04!\x1a9\x20Random-sized\x20junk\x20to\x20\ - defeat\x20packet\x20size\x20fingerprinting.\n\n\r\n\x05\x04\x0b\x02\x06\ - \x04\x12\x04\xdd\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\x06\x05\x12\x04\xdd\ - \x01\r\x12\n\r\n\x05\x04\x0b\x02\x06\x01\x12\x04\xdd\x01\x13\x1a\n\r\n\ - \x05\x04\x0b\x02\x06\x03\x12\x04\xdd\x01\x1d\x20\n\x0c\n\x02\x04\x0c\x12\ - \x06\xe0\x01\0\xe6\x01\x01\n\x0b\n\x03\x04\x0c\x01\x12\x04\xe0\x01\x08\ - \x19\n\x0c\n\x04\x04\x0c\x02\0\x12\x04\xe1\x01\x08&\n\r\n\x05\x04\x0c\ - \x02\0\x04\x12\x04\xe1\x01\x08\x10\n\r\n\x05\x04\x0c\x02\0\x05\x12\x04\ - \xe1\x01\x11\x15\n\r\n\x05\x04\x0c\x02\0\x01\x12\x04\xe1\x01\x16!\n\r\n\ - \x05\x04\x0c\x02\0\x03\x12\x04\xe1\x01$%\n\x0c\n\x04\x04\x0c\x02\x01\x12\ - \x04\xe2\x01\x08%\n\r\n\x05\x04\x0c\x02\x01\x04\x12\x04\xe2\x01\x08\x10\ - \n\r\n\x05\x04\x0c\x02\x01\x05\x12\x04\xe2\x01\x11\x15\n\r\n\x05\x04\x0c\ - \x02\x01\x01\x12\x04\xe2\x01\x16\x20\n\r\n\x05\x04\x0c\x02\x01\x03\x12\ - \x04\xe2\x01#$\n\x0c\n\x04\x04\x0c\x02\x02\x12\x04\xe3\x01\x08'\n\r\n\ - \x05\x04\x0c\x02\x02\x04\x12\x04\xe3\x01\x08\x10\n\r\n\x05\x04\x0c\x02\ - \x02\x05\x12\x04\xe3\x01\x11\x15\n\r\n\x05\x04\x0c\x02\x02\x01\x12\x04\ - \xe3\x01\x16\"\n\r\n\x05\x04\x0c\x02\x02\x03\x12\x04\xe3\x01%&\n\x0c\n\ - \x04\x04\x0c\x02\x03\x12\x04\xe4\x01\x04\x1e\n\r\n\x05\x04\x0c\x02\x03\ - \x04\x12\x04\xe4\x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x03\x05\x12\x04\xe4\ - \x01\r\x11\n\r\n\x05\x04\x0c\x02\x03\x01\x12\x04\xe4\x01\x12\x19\n\r\n\ - \x05\x04\x0c\x02\x03\x03\x12\x04\xe4\x01\x1c\x1d\n\x0c\n\x04\x04\x0c\x02\ - \x04\x12\x04\xe5\x01\x04!\n\r\n\x05\x04\x0c\x02\x04\x04\x12\x04\xe5\x01\ - \x04\x0c\n\r\n\x05\x04\x0c\x02\x04\x05\x12\x04\xe5\x01\r\x11\n\r\n\x05\ - \x04\x0c\x02\x04\x01\x12\x04\xe5\x01\x12\x1c\n\r\n\x05\x04\x0c\x02\x04\ - \x03\x12\x04\xe5\x01\x1f\x20\n\x0c\n\x02\x04\r\x12\x06\xe8\x01\0\xa2\x02\ - \x01\n\x0b\n\x03\x04\r\x01\x12\x04\xe8\x01\x08\x17\n\x0c\n\x04\x04\r\x02\ - \0\x12\x04\xe9\x01\x04)\n\r\n\x05\x04\r\x02\0\x04\x12\x04\xe9\x01\x04\ - \x0c\n\r\n\x05\x04\r\x02\0\x05\x12\x04\xe9\x01\r\x13\n\r\n\x05\x04\r\x02\ - \0\x01\x12\x04\xe9\x01\x14$\n\r\n\x05\x04\r\x02\0\x03\x12\x04\xe9\x01'(\ - \n\xd0\x01\n\x04\x04\r\x02\x01\x12\x04\xee\x01\x04.\x1a\xc1\x01\x20The\ - \x20client\x20reports\x20its\x20decoy\x20list's\x20version\x20number\x20\ - here,\x20which\x20the\n\x20station\x20can\x20use\x20to\x20decide\x20whet\ - her\x20to\x20send\x20an\x20updated\x20one.\x20The\x20station\n\x20should\ - \x20always\x20send\x20a\x20list\x20if\x20this\x20field\x20is\x20set\x20t\ - o\x200.\n\n\r\n\x05\x04\r\x02\x01\x04\x12\x04\xee\x01\x04\x0c\n\r\n\x05\ - \x04\r\x02\x01\x05\x12\x04\xee\x01\r\x13\n\r\n\x05\x04\r\x02\x01\x01\x12\ - \x04\xee\x01\x14)\n\r\n\x05\x04\r\x02\x01\x03\x12\x04\xee\x01,-\n\x0c\n\ - \x04\x04\r\x02\x02\x12\x04\xf0\x01\x041\n\r\n\x05\x04\r\x02\x02\x04\x12\ - \x04\xf0\x01\x04\x0c\n\r\n\x05\x04\r\x02\x02\x06\x12\x04\xf0\x01\r\x1b\n\ - \r\n\x05\x04\r\x02\x02\x01\x12\x04\xf0\x01\x1c,\n\r\n\x05\x04\r\x02\x02\ - \x03\x12\x04\xf0\x01/0\n\x80\x01\n\x04\x04\r\x02\x03\x12\x04\xf4\x01\x04\ - $\x1ar\x20The\x20position\x20in\x20the\x20overall\x20session's\x20upload\ - \x20sequence\x20where\x20the\x20current\n\x20YIELD=>ACQUIRE\x20switchove\ - r\x20is\x20happening.\n\n\r\n\x05\x04\r\x02\x03\x04\x12\x04\xf4\x01\x04\ - \x0c\n\r\n\x05\x04\r\x02\x03\x05\x12\x04\xf4\x01\r\x13\n\r\n\x05\x04\r\ - \x02\x03\x01\x12\x04\xf4\x01\x14\x1f\n\r\n\x05\x04\r\x02\x03\x03\x12\x04\ - \xf4\x01\"#\ng\n\x04\x04\r\x02\x04\x12\x04\xf8\x01\x04+\x1aY\x20High\x20\ - level\x20client\x20library\x20version\x20used\x20for\x20indicating\x20fe\ - ature\x20support,\x20or\n\x20lack\x20therof.\n\n\r\n\x05\x04\r\x02\x04\ - \x04\x12\x04\xf8\x01\x04\x0c\n\r\n\x05\x04\r\x02\x04\x05\x12\x04\xf8\x01\ - \r\x13\n\r\n\x05\x04\r\x02\x04\x01\x12\x04\xf8\x01\x14&\n\r\n\x05\x04\r\ - \x02\x04\x03\x12\x04\xf8\x01)*\n\xa5\x02\n\x04\x04\r\x02\x05\x12\x04\xfd\ - \x01\x042\x1a\x96\x02\x20Indicates\x20whether\x20the\x20client\x20will\ - \x20allow\x20the\x20registrar\x20to\x20provide\x20alternative\x20paramet\ - ers\x20that\n\x20may\x20work\x20better\x20in\x20substitute\x20for\x20the\ - \x20deterministically\x20selected\x20parameters.\x20This\x20only\x20work\ - s\n\x20for\x20bidirectional\x20registration\x20methods\x20where\x20the\ - \x20client\x20receives\x20a\x20RegistrationResponse.\n\n\r\n\x05\x04\r\ - \x02\x05\x04\x12\x04\xfd\x01\x04\x0c\n\r\n\x05\x04\r\x02\x05\x05\x12\x04\ - \xfd\x01\r\x11\n\r\n\x05\x04\r\x02\x05\x01\x12\x04\xfd\x01\x12-\n\r\n\ - \x05\x04\r\x02\x05\x03\x12\x04\xfd\x0101\nq\n\x04\x04\r\x02\x06\x12\x04\ - \x81\x02\x04'\x1ac\x20List\x20of\x20decoys\x20that\x20client\x20have\x20\ - unsuccessfully\x20tried\x20in\x20current\x20session.\n\x20Could\x20be\ - \x20sent\x20in\x20chunks\n\n\r\n\x05\x04\r\x02\x06\x04\x12\x04\x81\x02\ - \x04\x0c\n\r\n\x05\x04\r\x02\x06\x05\x12\x04\x81\x02\r\x13\n\r\n\x05\x04\ - \r\x02\x06\x01\x12\x04\x81\x02\x14!\n\r\n\x05\x04\r\x02\x06\x03\x12\x04\ - \x81\x02$&\n\x0c\n\x04\x04\r\x02\x07\x12\x04\x83\x02\x04%\n\r\n\x05\x04\ - \r\x02\x07\x04\x12\x04\x83\x02\x04\x0c\n\r\n\x05\x04\r\x02\x07\x06\x12\ - \x04\x83\x02\r\x19\n\r\n\x05\x04\r\x02\x07\x01\x12\x04\x83\x02\x1a\x1f\n\ - \r\n\x05\x04\r\x02\x07\x03\x12\x04\x83\x02\"$\nk\n\x04\x04\r\x02\x08\x12\ - \x04\x86\x02\x04*\x1a]\x20NullTransport,\x20MinTransport,\x20Obfs4Transp\ - ort,\x20etc.\x20Transport\x20type\x20we\x20want\x20from\x20phantom\x20pr\ - oxy\n\n\r\n\x05\x04\r\x02\x08\x04\x12\x04\x86\x02\x04\x0c\n\r\n\x05\x04\ - \r\x02\x08\x06\x12\x04\x86\x02\r\x1a\n\r\n\x05\x04\r\x02\x08\x01\x12\x04\ - \x86\x02\x1b$\n\r\n\x05\x04\r\x02\x08\x03\x12\x04\x86\x02')\n\x0c\n\x04\ - \x04\r\x02\t\x12\x04\x88\x02\x047\n\r\n\x05\x04\r\x02\t\x04\x12\x04\x88\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\t\x06\x12\x04\x88\x02\r\x20\n\r\n\x05\ - \x04\r\x02\t\x01\x12\x04\x88\x02!1\n\r\n\x05\x04\r\x02\t\x03\x12\x04\x88\ - \x0246\n\xc8\x03\n\x04\x04\r\x02\n\x12\x04\x90\x02\x04(\x1a\xb9\x03\x20S\ - tation\x20is\x20only\x20required\x20to\x20check\x20this\x20variable\x20d\ - uring\x20session\x20initialization.\n\x20If\x20set,\x20station\x20must\ - \x20facilitate\x20connection\x20to\x20said\x20target\x20by\x20itself,\ - \x20i.e.\x20write\x20into\x20squid\n\x20socket\x20an\x20HTTP/SOCKS/any\ - \x20other\x20connection\x20request.\n\x20covert_address\x20must\x20have\ - \x20exactly\x20one\x20':'\x20colon,\x20that\x20separates\x20host\x20(lit\ - eral\x20IP\x20address\x20or\n\x20resolvable\x20hostname)\x20and\x20port\ - \n\x20TODO:\x20make\x20it\x20required\x20for\x20initialization,\x20and\ - \x20stop\x20connecting\x20any\x20client\x20straight\x20to\x20squid?\n\n\ - \r\n\x05\x04\r\x02\n\x04\x12\x04\x90\x02\x04\x0c\n\r\n\x05\x04\r\x02\n\ - \x05\x12\x04\x90\x02\r\x13\n\r\n\x05\x04\r\x02\n\x01\x12\x04\x90\x02\x14\ - \"\n\r\n\x05\x04\r\x02\n\x03\x12\x04\x90\x02%'\nR\n\x04\x04\r\x02\x0b\ - \x12\x04\x93\x02\x042\x1aD\x20Used\x20in\x20dark\x20decoys\x20to\x20sign\ - al\x20which\x20dark\x20decoy\x20it\x20will\x20connect\x20to.\n\n\r\n\x05\ - \x04\r\x02\x0b\x04\x12\x04\x93\x02\x04\x0c\n\r\n\x05\x04\r\x02\x0b\x05\ - \x12\x04\x93\x02\r\x13\n\r\n\x05\x04\r\x02\x0b\x01\x12\x04\x93\x02\x14,\ - \n\r\n\x05\x04\r\x02\x0b\x03\x12\x04\x93\x02/1\nR\n\x04\x04\r\x02\x0c\ - \x12\x04\x96\x02\x04\"\x1aD\x20Used\x20to\x20indicate\x20to\x20server\ - \x20if\x20client\x20is\x20registering\x20v4,\x20v6\x20or\x20both\n\n\r\n\ - \x05\x04\r\x02\x0c\x04\x12\x04\x96\x02\x04\x0c\n\r\n\x05\x04\r\x02\x0c\ - \x05\x12\x04\x96\x02\r\x11\n\r\n\x05\x04\r\x02\x0c\x01\x12\x04\x96\x02\ - \x12\x1c\n\r\n\x05\x04\r\x02\x0c\x03\x12\x04\x96\x02\x1f!\n\x0c\n\x04\ - \x04\r\x02\r\x12\x04\x97\x02\x04\"\n\r\n\x05\x04\r\x02\r\x04\x12\x04\x97\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\r\x05\x12\x04\x97\x02\r\x11\n\r\n\x05\ - \x04\r\x02\r\x01\x12\x04\x97\x02\x12\x1c\n\r\n\x05\x04\r\x02\r\x03\x12\ - \x04\x97\x02\x1f!\nD\n\x04\x04\r\x02\x0e\x12\x04\x9a\x02\x04*\x1a6\x20A\ - \x20collection\x20of\x20optional\x20flags\x20for\x20the\x20registration.\ - \n\n\r\n\x05\x04\r\x02\x0e\x04\x12\x04\x9a\x02\x04\x0c\n\r\n\x05\x04\r\ - \x02\x0e\x06\x12\x04\x9a\x02\r\x1e\n\r\n\x05\x04\r\x02\x0e\x01\x12\x04\ - \x9a\x02\x1f$\n\r\n\x05\x04\r\x02\x0e\x03\x12\x04\x9a\x02')\nq\n\x04\x04\ - \r\x02\x0f\x12\x04\x9e\x02\x04-\x1ac\x20Transport\x20Extensions\n\x20TOD\ - O(jmwample)\x20-\x20move\x20to\x20WebRTC\x20specific\x20transport\x20par\ - ams\x20protobuf\x20message.\n\n\r\n\x05\x04\r\x02\x0f\x04\x12\x04\x9e\ - \x02\x04\x0c\n\r\n\x05\x04\r\x02\x0f\x06\x12\x04\x9e\x02\r\x19\n\r\n\x05\ - \x04\r\x02\x0f\x01\x12\x04\x9e\x02\x1a'\n\r\n\x05\x04\r\x02\x0f\x03\x12\ - \x04\x9e\x02*,\nG\n\x04\x04\r\x02\x10\x12\x04\xa1\x02\x04!\x1a9\x20Rando\ - m-sized\x20junk\x20to\x20defeat\x20packet\x20size\x20fingerprinting.\n\n\ - \r\n\x05\x04\r\x02\x10\x04\x12\x04\xa1\x02\x04\x0c\n\r\n\x05\x04\r\x02\ - \x10\x05\x12\x04\xa1\x02\r\x12\n\r\n\x05\x04\r\x02\x10\x01\x12\x04\xa1\ - \x02\x13\x1a\n\r\n\x05\x04\r\x02\x10\x03\x12\x04\xa1\x02\x1d\x20\n\x0c\n\ - \x02\x04\x0e\x12\x06\xa5\x02\0\xb7\x02\x01\n\x0b\n\x03\x04\x0e\x01\x12\ - \x04\xa5\x02\x08\x1d\n!\n\x04\x04\x0e\x02\0\x12\x04\xa7\x02\x04!\x1a\x13\ - \x20Prefix\x20Identifier\n\n\r\n\x05\x04\x0e\x02\0\x04\x12\x04\xa7\x02\ - \x04\x0c\n\r\n\x05\x04\x0e\x02\0\x05\x12\x04\xa7\x02\r\x12\n\r\n\x05\x04\ - \x0e\x02\0\x01\x12\x04\xa7\x02\x13\x1c\n\r\n\x05\x04\x0e\x02\0\x03\x12\ - \x04\xa7\x02\x1f\x20\n\xc4\x01\n\x04\x04\x0e\x02\x01\x12\x04\xab\x02\x04\ - \x1e\x1a\xb5\x01\x20Prefix\x20bytes\x20(optional\x20-\x20usually\x20sent\ - \x20from\x20station\x20to\x20client\x20as\x20override\x20if\x20allowed\ - \x20by\x20C2S)\n\x20as\x20the\x20station\x20cannot\x20take\x20this\x20in\ - to\x20account\x20when\x20attempting\x20to\x20identify\x20a\x20connection\ - .\n\n\r\n\x05\x04\x0e\x02\x01\x04\x12\x04\xab\x02\x04\x0c\n\r\n\x05\x04\ - \x0e\x02\x01\x05\x12\x04\xab\x02\r\x12\n\r\n\x05\x04\x0e\x02\x01\x01\x12\ - \x04\xab\x02\x13\x19\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xab\x02\x1c\ - \x1d\n\x0c\n\x04\x04\x0e\x02\x02\x12\x04\xac\x02\x04+\n\r\n\x05\x04\x0e\ - \x02\x02\x04\x12\x04\xac\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x02\x05\x12\ - \x04\xac\x02\r\x12\n\r\n\x05\x04\x0e\x02\x02\x01\x12\x04\xac\x02\x13&\n\ - \r\n\x05\x04\x0e\x02\x02\x03\x12\x04\xac\x02)*\n\xed\x02\n\x04\x04\x0e\ - \x02\x03\x12\x04\xb6\x02\x04*\x1a\xbc\x01\x20Indicates\x20whether\x20the\ - \x20client\x20has\x20elected\x20to\x20use\x20destination\x20port\x20rand\ - omization.\x20Should\x20be\n\x20checked\x20against\x20selected\x20transp\ - ort\x20to\x20ensure\x20that\x20destination\x20port\x20randomization\x20i\ - s\n\x20supported.\n2\x9f\x01\x20//\x20potential\x20future\x20fields\n\ - \x20obfuscator\x20ID\n\x20tagEncoder\x20ID\x20(¶ms?,\x20e.g.\x20form\ - at-base64\x20/\x20padding)\n\x20streamEncoder\x20ID\x20(¶ms?,\x20e.g\ - .\x20foramat-base64\x20/\x20padding)\n\n\r\n\x05\x04\x0e\x02\x03\x04\x12\ - \x04\xb6\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x03\x05\x12\x04\xb6\x02\r\x11\ - \n\r\n\x05\x04\x0e\x02\x03\x01\x12\x04\xb6\x02\x12$\n\r\n\x05\x04\x0e\ - \x02\x03\x03\x12\x04\xb6\x02')\n\x0c\n\x02\x04\x0f\x12\x06\xb9\x02\0\xbe\ - \x02\x01\n\x0b\n\x03\x04\x0f\x01\x12\x04\xb9\x02\x08\x1e\n\xcb\x01\n\x04\ - \x04\x0f\x02\0\x12\x04\xbd\x02\x04*\x1a\xbc\x01\x20Indicates\x20whether\ - \x20the\x20client\x20has\x20elected\x20to\x20use\x20destination\x20port\ - \x20randomization.\x20Should\x20be\n\x20checked\x20against\x20selected\ - \x20transport\x20to\x20ensure\x20that\x20destination\x20port\x20randomiz\ - ation\x20is\n\x20supported.\n\n\r\n\x05\x04\x0f\x02\0\x04\x12\x04\xbd\ - \x02\x04\x0c\n\r\n\x05\x04\x0f\x02\0\x05\x12\x04\xbd\x02\r\x11\n\r\n\x05\ - \x04\x0f\x02\0\x01\x12\x04\xbd\x02\x12$\n\r\n\x05\x04\x0f\x02\0\x03\x12\ - \x04\xbd\x02')\n\x0c\n\x02\x05\x06\x12\x06\xc0\x02\0\xc8\x02\x01\n\x0b\n\ - \x03\x05\x06\x01\x12\x04\xc0\x02\x05\x17\n\x0c\n\x04\x05\x06\x02\0\x12\ - \x04\xc1\x02\x02\x12\n\r\n\x05\x05\x06\x02\0\x01\x12\x04\xc1\x02\x02\r\n\ - \r\n\x05\x05\x06\x02\0\x02\x12\x04\xc1\x02\x10\x11\n\x0c\n\x04\x05\x06\ - \x02\x01\x12\x04\xc2\x02\x08\x15\n\r\n\x05\x05\x06\x02\x01\x01\x12\x04\ - \xc2\x02\x08\x10\n\r\n\x05\x05\x06\x02\x01\x02\x12\x04\xc2\x02\x13\x14\n\ - \x0c\n\x04\x05\x06\x02\x02\x12\x04\xc3\x02\x08\x10\n\r\n\x05\x05\x06\x02\ - \x02\x01\x12\x04\xc3\x02\x08\x0b\n\r\n\x05\x05\x06\x02\x02\x02\x12\x04\ - \xc3\x02\x0e\x0f\n\x0c\n\x04\x05\x06\x02\x03\x12\x04\xc4\x02\x02\x16\n\r\ - \n\x05\x05\x06\x02\x03\x01\x12\x04\xc4\x02\x02\x11\n\r\n\x05\x05\x06\x02\ - \x03\x02\x12\x04\xc4\x02\x14\x15\n\x0c\n\x04\x05\x06\x02\x04\x12\x04\xc5\ - \x02\x02\x17\n\r\n\x05\x05\x06\x02\x04\x01\x12\x04\xc5\x02\x02\x12\n\r\n\ - \x05\x05\x06\x02\x04\x02\x12\x04\xc5\x02\x15\x16\n\x0c\n\x04\x05\x06\x02\ - \x05\x12\x04\xc6\x02\x02\n\n\r\n\x05\x05\x06\x02\x05\x01\x12\x04\xc6\x02\ - \x02\x05\n\r\n\x05\x05\x06\x02\x05\x02\x12\x04\xc6\x02\x08\t\n\x0c\n\x04\ - \x05\x06\x02\x06\x12\x04\xc7\x02\x02\x17\n\r\n\x05\x05\x06\x02\x06\x01\ - \x12\x04\xc7\x02\x02\x12\n\r\n\x05\x05\x06\x02\x06\x02\x12\x04\xc7\x02\ - \x15\x16\n\x0c\n\x02\x04\x10\x12\x06\xca\x02\0\xe2\x02\x01\n\x0b\n\x03\ - \x04\x10\x01\x12\x04\xca\x02\x08\x12\n\x0c\n\x04\x04\x10\x02\0\x12\x04\ - \xcb\x02\x02#\n\r\n\x05\x04\x10\x02\0\x04\x12\x04\xcb\x02\x02\n\n\r\n\ - \x05\x04\x10\x02\0\x05\x12\x04\xcb\x02\x0b\x10\n\r\n\x05\x04\x10\x02\0\ - \x01\x12\x04\xcb\x02\x11\x1e\n\r\n\x05\x04\x10\x02\0\x03\x12\x04\xcb\x02\ - !\"\n\x0c\n\x04\x04\x10\x02\x01\x12\x04\xcc\x02\x024\n\r\n\x05\x04\x10\ - \x02\x01\x04\x12\x04\xcc\x02\x02\n\n\r\n\x05\x04\x10\x02\x01\x06\x12\x04\ - \xcc\x02\x0b\x1a\n\r\n\x05\x04\x10\x02\x01\x01\x12\x04\xcc\x02\x1b/\n\r\ - \n\x05\x04\x10\x02\x01\x03\x12\x04\xcc\x0223\n\x0c\n\x04\x04\x10\x02\x02\ - \x12\x04\xcd\x02\x026\n\r\n\x05\x04\x10\x02\x02\x04\x12\x04\xcd\x02\x02\ - \n\n\r\n\x05\x04\x10\x02\x02\x06\x12\x04\xcd\x02\x0b\x1d\n\r\n\x05\x04\ - \x10\x02\x02\x01\x12\x04\xcd\x02\x1e1\n\r\n\x05\x04\x10\x02\x02\x03\x12\ - \x04\xcd\x0245\nC\n\x04\x04\x10\x02\x03\x12\x04\xd0\x02\x02*\x1a5\x20cli\ - ent\x20source\x20address\x20when\x20receiving\x20a\x20registration\n\n\r\ - \n\x05\x04\x10\x02\x03\x04\x12\x04\xd0\x02\x02\n\n\r\n\x05\x04\x10\x02\ - \x03\x05\x12\x04\xd0\x02\x0b\x10\n\r\n\x05\x04\x10\x02\x03\x01\x12\x04\ - \xd0\x02\x11%\n\r\n\x05\x04\x10\x02\x03\x03\x12\x04\xd0\x02()\nH\n\x04\ - \x04\x10\x02\x04\x12\x04\xd3\x02\x02#\x1a:\x20Decoy\x20address\x20used\ - \x20when\x20registering\x20over\x20Decoy\x20registrar\n\n\r\n\x05\x04\ - \x10\x02\x04\x04\x12\x04\xd3\x02\x02\n\n\r\n\x05\x04\x10\x02\x04\x05\x12\ - \x04\xd3\x02\x0b\x10\n\r\n\x05\x04\x10\x02\x04\x01\x12\x04\xd3\x02\x11\ - \x1e\n\r\n\x05\x04\x10\x02\x04\x03\x12\x04\xd3\x02!\"\n\xeb\x05\n\x04\ - \x04\x10\x02\x05\x12\x04\xdf\x02\x02:\x1a\xdc\x05\x20The\x20next\x20thre\ - e\x20fields\x20allow\x20an\x20independent\x20registrar\x20(trusted\x20by\ - \x20a\x20station\x20w/\x20a\x20zmq\x20keypair)\x20to\n\x20share\x20the\ - \x20registration\x20overrides\x20that\x20it\x20assigned\x20to\x20the\x20\ - client\x20with\x20the\x20station(s).\n\x20Registration\x20Respose\x20is\ - \x20here\x20to\x20allow\x20a\x20parsed\x20object\x20with\x20direct\x20ac\ - cess\x20to\x20the\x20fields\x20within.\n\x20RegRespBytes\x20provides\x20\ - a\x20serialized\x20verion\x20of\x20the\x20Registration\x20response\x20so\ - \x20that\x20the\x20signature\x20of\n\x20the\x20Bidirectional\x20registra\ - r\x20can\x20be\x20validated\x20before\x20a\x20station\x20applies\x20any\ - \x20overrides\x20present\x20in\n\x20the\x20Registration\x20Response.\n\n\ - \x20If\x20you\x20are\x20reading\x20this\x20in\x20the\x20future\x20and\ - \x20you\x20want\x20to\x20extend\x20the\x20functionality\x20here\x20it\ - \x20might\n\x20make\x20sense\x20to\x20make\x20the\x20RegistrationRespons\ - e\x20that\x20is\x20sent\x20to\x20the\x20client\x20a\x20distinct\x20messa\ - ge\x20from\n\x20the\x20one\x20that\x20gets\x20sent\x20to\x20the\x20stati\ - ons.\n\n\r\n\x05\x04\x10\x02\x05\x04\x12\x04\xdf\x02\x02\n\n\r\n\x05\x04\ - \x10\x02\x05\x06\x12\x04\xdf\x02\x0b\x1f\n\r\n\x05\x04\x10\x02\x05\x01\ - \x12\x04\xdf\x02\x205\n\r\n\x05\x04\x10\x02\x05\x03\x12\x04\xdf\x0289\n\ - \x0c\n\x04\x04\x10\x02\x06\x12\x04\xe0\x02\x02\"\n\r\n\x05\x04\x10\x02\ - \x06\x04\x12\x04\xe0\x02\x02\n\n\r\n\x05\x04\x10\x02\x06\x05\x12\x04\xe0\ - \x02\x0b\x10\n\r\n\x05\x04\x10\x02\x06\x01\x12\x04\xe0\x02\x11\x1d\n\r\n\ - \x05\x04\x10\x02\x06\x03\x12\x04\xe0\x02\x20!\n\x0c\n\x04\x04\x10\x02\ - \x07\x12\x04\xe1\x02\x02'\n\r\n\x05\x04\x10\x02\x07\x04\x12\x04\xe1\x02\ - \x02\n\n\r\n\x05\x04\x10\x02\x07\x05\x12\x04\xe1\x02\x0b\x10\n\r\n\x05\ - \x04\x10\x02\x07\x01\x12\x04\xe1\x02\x11!\n\r\n\x05\x04\x10\x02\x07\x03\ - \x12\x04\xe1\x02$&\n\x0c\n\x02\x04\x11\x12\x06\xe4\x02\0\xf0\x02\x01\n\ - \x0b\n\x03\x04\x11\x01\x12\x04\xe4\x02\x08\x14\n9\n\x04\x04\x11\x02\0\ - \x12\x04\xe5\x02\x04.\"+\x20how\x20many\x20decoys\x20were\x20tried\x20be\ - fore\x20success\n\n\r\n\x05\x04\x11\x02\0\x04\x12\x04\xe5\x02\x04\x0c\n\ - \r\n\x05\x04\x11\x02\0\x05\x12\x04\xe5\x02\r\x13\n\r\n\x05\x04\x11\x02\0\ - \x01\x12\x04\xe5\x02\x14(\n\r\n\x05\x04\x11\x02\0\x03\x12\x04\xe5\x02+-\ - \nm\n\x04\x04\x11\x02\x01\x12\x04\xea\x02\x04/\x1a\x1e\x20Applicable\x20\ - to\x20whole\x20session:\n\"\x1a\x20includes\x20failed\x20attempts\n2#\ - \x20Timings\x20below\x20are\x20in\x20milliseconds\n\n\r\n\x05\x04\x11\ - \x02\x01\x04\x12\x04\xea\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x01\x05\x12\ - \x04\xea\x02\r\x13\n\r\n\x05\x04\x11\x02\x01\x01\x12\x04\xea\x02\x14)\n\ - \r\n\x05\x04\x11\x02\x01\x03\x12\x04\xea\x02,.\nR\n\x04\x04\x11\x02\x02\ - \x12\x04\xed\x02\x04(\x1a\x1f\x20Last\x20(i.e.\x20successful)\x20decoy:\ - \n\"#\x20measured\x20during\x20initial\x20handshake\n\n\r\n\x05\x04\x11\ - \x02\x02\x04\x12\x04\xed\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x02\x05\x12\ - \x04\xed\x02\r\x13\n\r\n\x05\x04\x11\x02\x02\x01\x12\x04\xed\x02\x14\"\n\ - \r\n\x05\x04\x11\x02\x02\x03\x12\x04\xed\x02%'\n%\n\x04\x04\x11\x02\x03\ - \x12\x04\xee\x02\x04&\"\x17\x20includes\x20tcp\x20to\x20decoy\n\n\r\n\ - \x05\x04\x11\x02\x03\x04\x12\x04\xee\x02\x04\x0c\n\r\n\x05\x04\x11\x02\ - \x03\x05\x12\x04\xee\x02\r\x13\n\r\n\x05\x04\x11\x02\x03\x01\x12\x04\xee\ - \x02\x14\x20\n\r\n\x05\x04\x11\x02\x03\x03\x12\x04\xee\x02#%\nB\n\x04\ - \x04\x11\x02\x04\x12\x04\xef\x02\x04&\"4\x20measured\x20when\x20establis\ - hing\x20tcp\x20connection\x20to\x20decot\n\n\r\n\x05\x04\x11\x02\x04\x04\ - \x12\x04\xef\x02\x04\x0c\n\r\n\x05\x04\x11\x02\x04\x05\x12\x04\xef\x02\r\ - \x13\n\r\n\x05\x04\x11\x02\x04\x01\x12\x04\xef\x02\x14\x20\n\r\n\x05\x04\ - \x11\x02\x04\x03\x12\x04\xef\x02#%\n\x0c\n\x02\x05\x07\x12\x06\xf2\x02\0\ - \xf7\x02\x01\n\x0b\n\x03\x05\x07\x01\x12\x04\xf2\x02\x05\x16\n\x0c\n\x04\ - \x05\x07\x02\0\x12\x04\xf3\x02\x04\x10\n\r\n\x05\x05\x07\x02\0\x01\x12\ - \x04\xf3\x02\x04\x0b\n\r\n\x05\x05\x07\x02\0\x02\x12\x04\xf3\x02\x0e\x0f\ - \n\x0c\n\x04\x05\x07\x02\x01\x12\x04\xf4\x02\x04\x0c\n\r\n\x05\x05\x07\ - \x02\x01\x01\x12\x04\xf4\x02\x04\x07\n\r\n\x05\x05\x07\x02\x01\x02\x12\ - \x04\xf4\x02\n\x0b\n\x0c\n\x04\x05\x07\x02\x02\x12\x04\xf5\x02\x04\x0f\n\ - \r\n\x05\x05\x07\x02\x02\x01\x12\x04\xf5\x02\x04\n\n\r\n\x05\x05\x07\x02\ - \x02\x02\x12\x04\xf5\x02\r\x0e\n\x0c\n\x04\x05\x07\x02\x03\x12\x04\xf6\ - \x02\x04\x0e\n\r\n\x05\x05\x07\x02\x03\x01\x12\x04\xf6\x02\x04\t\n\r\n\ - \x05\x05\x07\x02\x03\x02\x12\x04\xf6\x02\x0c\r\n\x0c\n\x02\x05\x08\x12\ - \x06\xf9\x02\0\xfd\x02\x01\n\x0b\n\x03\x05\x08\x01\x12\x04\xf9\x02\x05\ - \x0c\n\x0c\n\x04\x05\x08\x02\0\x12\x04\xfa\x02\x04\x0c\n\r\n\x05\x05\x08\ - \x02\0\x01\x12\x04\xfa\x02\x04\x07\n\r\n\x05\x05\x08\x02\0\x02\x12\x04\ - \xfa\x02\n\x0b\n\x0c\n\x04\x05\x08\x02\x01\x12\x04\xfb\x02\x04\x0c\n\r\n\ - \x05\x05\x08\x02\x01\x01\x12\x04\xfb\x02\x04\x07\n\r\n\x05\x05\x08\x02\ - \x01\x02\x12\x04\xfb\x02\n\x0b\n\x0c\n\x04\x05\x08\x02\x02\x12\x04\xfc\ - \x02\x04\x0c\n\r\n\x05\x05\x08\x02\x02\x01\x12\x04\xfc\x02\x04\x07\n\r\n\ - \x05\x05\x08\x02\x02\x02\x12\x04\xfc\x02\n\x0b\n\x0c\n\x02\x04\x12\x12\ - \x06\xff\x02\0\x8a\x03\x01\n\x0b\n\x03\x04\x12\x01\x12\x04\xff\x02\x08\ - \x19\n\x0c\n\x04\x04\x12\x02\0\x12\x04\x80\x03\x04#\n\r\n\x05\x04\x12\ - \x02\0\x04\x12\x04\x80\x03\x04\x0c\n\r\n\x05\x04\x12\x02\0\x05\x12\x04\ - \x80\x03\r\x13\n\r\n\x05\x04\x12\x02\0\x01\x12\x04\x80\x03\x14\x1e\n\r\n\ - \x05\x04\x12\x02\0\x03\x12\x04\x80\x03!\"\n\x0c\n\x04\x04\x12\x02\x01\ - \x12\x04\x81\x03\x04\"\n\r\n\x05\x04\x12\x02\x01\x04\x12\x04\x81\x03\x04\ - \x0c\n\r\n\x05\x04\x12\x02\x01\x05\x12\x04\x81\x03\r\x13\n\r\n\x05\x04\ - \x12\x02\x01\x01\x12\x04\x81\x03\x14\x1d\n\r\n\x05\x04\x12\x02\x01\x03\ - \x12\x04\x81\x03\x20!\n\x0c\n\x04\x04\x12\x02\x02\x12\x04\x83\x03\x04#\n\ - \r\n\x05\x04\x12\x02\x02\x04\x12\x04\x83\x03\x04\x0c\n\r\n\x05\x04\x12\ - \x02\x02\x05\x12\x04\x83\x03\r\x13\n\r\n\x05\x04\x12\x02\x02\x01\x12\x04\ - \x83\x03\x14\x1e\n\r\n\x05\x04\x12\x02\x02\x03\x12\x04\x83\x03!\"\n\x0c\ - \n\x04\x04\x12\x02\x03\x12\x04\x85\x03\x04-\n\r\n\x05\x04\x12\x02\x03\ - \x04\x12\x04\x85\x03\x04\x0c\n\r\n\x05\x04\x12\x02\x03\x06\x12\x04\x85\ - \x03\r\x1e\n\r\n\x05\x04\x12\x02\x03\x01\x12\x04\x85\x03\x1f(\n\r\n\x05\ - \x04\x12\x02\x03\x03\x12\x04\x85\x03+,\n\x0c\n\x04\x04\x12\x02\x04\x12\ - \x04\x87\x03\x04\"\n\r\n\x05\x04\x12\x02\x04\x04\x12\x04\x87\x03\x04\x0c\ - \n\r\n\x05\x04\x12\x02\x04\x05\x12\x04\x87\x03\r\x13\n\r\n\x05\x04\x12\ - \x02\x04\x01\x12\x04\x87\x03\x14\x1c\n\r\n\x05\x04\x12\x02\x04\x03\x12\ - \x04\x87\x03\x1f!\n\x0c\n\x04\x04\x12\x02\x05\x12\x04\x88\x03\x04\"\n\r\ - \n\x05\x04\x12\x02\x05\x04\x12\x04\x88\x03\x04\x0c\n\r\n\x05\x04\x12\x02\ - \x05\x05\x12\x04\x88\x03\r\x13\n\r\n\x05\x04\x12\x02\x05\x01\x12\x04\x88\ - \x03\x14\x1c\n\r\n\x05\x04\x12\x02\x05\x03\x12\x04\x88\x03\x1f!\n\x0c\n\ - \x04\x04\x12\x02\x06\x12\x04\x89\x03\x04\x20\n\r\n\x05\x04\x12\x02\x06\ - \x04\x12\x04\x89\x03\x04\x0c\n\r\n\x05\x04\x12\x02\x06\x06\x12\x04\x89\ - \x03\r\x14\n\r\n\x05\x04\x12\x02\x06\x01\x12\x04\x89\x03\x15\x1a\n\r\n\ - \x05\x04\x12\x02\x06\x03\x12\x04\x89\x03\x1d\x1f\nT\n\x02\x04\x13\x12\ - \x06\x8d\x03\0\xa1\x03\x01\x1aF\x20Adding\x20message\x20response\x20from\ - \x20Station\x20to\x20Client\x20for\x20bidirectional\x20API\n\n\x0b\n\x03\ - \x04\x13\x01\x12\x04\x8d\x03\x08\x1c\n\x0c\n\x04\x04\x13\x02\0\x12\x04\ - \x8e\x03\x02\x20\n\r\n\x05\x04\x13\x02\0\x04\x12\x04\x8e\x03\x02\n\n\r\n\ - \x05\x04\x13\x02\0\x05\x12\x04\x8e\x03\x0b\x12\n\r\n\x05\x04\x13\x02\0\ - \x01\x12\x04\x8e\x03\x13\x1b\n\r\n\x05\x04\x13\x02\0\x03\x12\x04\x8e\x03\ - \x1e\x1f\n?\n\x04\x04\x13\x02\x01\x12\x04\x90\x03\x02\x1e\x1a1\x20The\ - \x20128-bit\x20ipv6\x20address,\x20in\x20network\x20byte\x20order\n\n\r\ - \n\x05\x04\x13\x02\x01\x04\x12\x04\x90\x03\x02\n\n\r\n\x05\x04\x13\x02\ - \x01\x05\x12\x04\x90\x03\x0b\x10\n\r\n\x05\x04\x13\x02\x01\x01\x12\x04\ - \x90\x03\x11\x19\n\r\n\x05\x04\x13\x02\x01\x03\x12\x04\x90\x03\x1c\x1d\n\ - ,\n\x04\x04\x13\x02\x02\x12\x04\x93\x03\x02\x1f\x1a\x1e\x20Respond\x20wi\ - th\x20randomized\x20port\n\n\r\n\x05\x04\x13\x02\x02\x04\x12\x04\x93\x03\ - \x02\n\n\r\n\x05\x04\x13\x02\x02\x05\x12\x04\x93\x03\x0b\x11\n\r\n\x05\ - \x04\x13\x02\x02\x01\x12\x04\x93\x03\x12\x1a\n\r\n\x05\x04\x13\x02\x02\ - \x03\x12\x04\x93\x03\x1d\x1e\nd\n\x04\x04\x13\x02\x03\x12\x04\x97\x03\ - \x02\"\x1aV\x20Future:\x20station\x20provides\x20client\x20with\x20secre\ - t,\x20want\x20chanel\x20present\n\x20Leave\x20null\x20for\x20now\n\n\r\n\ - \x05\x04\x13\x02\x03\x04\x12\x04\x97\x03\x02\n\n\r\n\x05\x04\x13\x02\x03\ - \x05\x12\x04\x97\x03\x0b\x10\n\r\n\x05\x04\x13\x02\x03\x01\x12\x04\x97\ - \x03\x11\x1d\n\r\n\x05\x04\x13\x02\x03\x03\x12\x04\x97\x03\x20!\nA\n\x04\ - \x04\x13\x02\x04\x12\x04\x9a\x03\x02\x1c\x1a3\x20If\x20registration\x20w\ - rong,\x20populate\x20this\x20error\x20string\n\n\r\n\x05\x04\x13\x02\x04\ - \x04\x12\x04\x9a\x03\x02\n\n\r\n\x05\x04\x13\x02\x04\x05\x12\x04\x9a\x03\ - \x0b\x11\n\r\n\x05\x04\x13\x02\x04\x01\x12\x04\x9a\x03\x12\x17\n\r\n\x05\ - \x04\x13\x02\x04\x03\x12\x04\x9a\x03\x1a\x1b\n+\n\x04\x04\x13\x02\x05\ - \x12\x04\x9d\x03\x02%\x1a\x1d\x20ClientConf\x20field\x20(optional)\n\n\r\ - \n\x05\x04\x13\x02\x05\x04\x12\x04\x9d\x03\x02\n\n\r\n\x05\x04\x13\x02\ - \x05\x06\x12\x04\x9d\x03\x0b\x15\n\r\n\x05\x04\x13\x02\x05\x01\x12\x04\ - \x9d\x03\x16\x20\n\r\n\x05\x04\x13\x02\x05\x03\x12\x04\x9d\x03#$\nJ\n\ - \x04\x04\x13\x02\x06\x12\x04\xa0\x03\x025\x1a<\x20Transport\x20Params\ - \x20to\x20if\x20`allow_registrar_overrides`\x20is\x20set.\n\n\r\n\x05\ - \x04\x13\x02\x06\x04\x12\x04\xa0\x03\x02\n\n\r\n\x05\x04\x13\x02\x06\x06\ - \x12\x04\xa0\x03\x0b\x1e\n\r\n\x05\x04\x13\x02\x06\x01\x12\x04\xa0\x03\ - \x1f/\n\r\n\x05\x04\x13\x02\x06\x03\x12\x04\xa0\x0324\n!\n\x02\x04\x14\ - \x12\x06\xa4\x03\0\xa8\x03\x01\x1a\x13\x20response\x20from\x20dns\n\n\ - \x0b\n\x03\x04\x14\x01\x12\x04\xa4\x03\x08\x13\n\x0c\n\x04\x04\x14\x02\0\ - \x12\x04\xa5\x03\x04\x1e\n\r\n\x05\x04\x14\x02\0\x04\x12\x04\xa5\x03\x04\ - \x0c\n\r\n\x05\x04\x14\x02\0\x05\x12\x04\xa5\x03\r\x11\n\r\n\x05\x04\x14\ - \x02\0\x01\x12\x04\xa5\x03\x12\x19\n\r\n\x05\x04\x14\x02\0\x03\x12\x04\ - \xa5\x03\x1c\x1d\n\x0c\n\x04\x04\x14\x02\x01\x12\x04\xa6\x03\x04*\n\r\n\ - \x05\x04\x14\x02\x01\x04\x12\x04\xa6\x03\x04\x0c\n\r\n\x05\x04\x14\x02\ - \x01\x05\x12\x04\xa6\x03\r\x11\n\r\n\x05\x04\x14\x02\x01\x01\x12\x04\xa6\ - \x03\x12%\n\r\n\x05\x04\x14\x02\x01\x03\x12\x04\xa6\x03()\n\x0c\n\x04\ - \x04\x14\x02\x02\x12\x04\xa7\x03\x04=\n\r\n\x05\x04\x14\x02\x02\x04\x12\ - \x04\xa7\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x02\x06\x12\x04\xa7\x03\r!\n\ - \r\n\x05\x04\x14\x02\x02\x01\x12\x04\xa7\x03\"8\n\r\n\x05\x04\x14\x02\ - \x02\x03\x12\x04\xa7\x03;<\ + \x13\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\xc4\x01\x14\x18\n\r\n\x05\x04\n\ + \x02\x01\x03\x12\x04\xc4\x01\x1b\x1c\n\x0c\n\x02\x04\x0b\x12\x06\xc7\x01\ + \0\xcb\x01\x01\n\x0b\n\x03\x04\x0b\x01\x12\x04\xc7\x01\x08\x1b\n\x0c\n\ + \x04\x04\x0b\x02\0\x12\x04\xc8\x01\x04\x20\n\r\n\x05\x04\x0b\x02\0\x04\ + \x12\x04\xc8\x01\x04\x0c\n\r\n\x05\x04\x0b\x02\0\x06\x12\x04\xc8\x01\r\ + \x11\n\r\n\x05\x04\x0b\x02\0\x01\x12\x04\xc8\x01\x12\x1b\n\r\n\x05\x04\ + \x0b\x02\0\x03\x12\x04\xc8\x01\x1e\x1f\n\x0c\n\x04\x04\x0b\x02\x01\x12\ + \x04\xc9\x01\x04\x20\n\r\n\x05\x04\x0b\x02\x01\x04\x12\x04\xc9\x01\x04\ + \x0c\n\r\n\x05\x04\x0b\x02\x01\x06\x12\x04\xc9\x01\r\x11\n\r\n\x05\x04\ + \x0b\x02\x01\x01\x12\x04\xc9\x01\x12\x1b\n\r\n\x05\x04\x0b\x02\x01\x03\ + \x12\x04\xc9\x01\x1e\x1f\n\x0c\n\x04\x04\x0b\x02\x02\x12\x04\xca\x01\x04\ + )\n\r\n\x05\x04\x0b\x02\x02\x04\x12\x04\xca\x01\x04\x0c\n\r\n\x05\x04\ + \x0b\x02\x02\x05\x12\x04\xca\x01\r\x11\n\r\n\x05\x04\x0b\x02\x02\x01\x12\ + \x04\xca\x01\x12$\n\r\n\x05\x04\x0b\x02\x02\x03\x12\x04\xca\x01'(\n\x0c\ + \n\x02\x04\x0c\x12\x06\xcd\x01\0\xe4\x01\x01\n\x0b\n\x03\x04\x0c\x01\x12\ + \x04\xcd\x01\x08\x17\nO\n\x04\x04\x0c\x02\0\x12\x04\xcf\x01\x04)\x1aA\ + \x20Should\x20accompany\x20(at\x20least)\x20SESSION_INIT\x20and\x20CONFI\ + RM_RECONNECT.\n\n\r\n\x05\x04\x0c\x02\0\x04\x12\x04\xcf\x01\x04\x0c\n\r\ + \n\x05\x04\x0c\x02\0\x05\x12\x04\xcf\x01\r\x13\n\r\n\x05\x04\x0c\x02\0\ + \x01\x12\x04\xcf\x01\x14$\n\r\n\x05\x04\x0c\x02\0\x03\x12\x04\xcf\x01'(\ + \nv\n\x04\x04\x0c\x02\x01\x12\x04\xd3\x01\x041\x1ah\x20There\x20might\ + \x20be\x20a\x20state\x20transition.\x20May\x20be\x20absent;\x20absence\ + \x20should\x20be\n\x20treated\x20identically\x20to\x20NO_CHANGE.\n\n\r\n\ + \x05\x04\x0c\x02\x01\x04\x12\x04\xd3\x01\x04\x0c\n\r\n\x05\x04\x0c\x02\ + \x01\x06\x12\x04\xd3\x01\r\x1b\n\r\n\x05\x04\x0c\x02\x01\x01\x12\x04\xd3\ + \x01\x1c,\n\r\n\x05\x04\x0c\x02\x01\x03\x12\x04\xd3\x01/0\nc\n\x04\x04\ + \x0c\x02\x02\x12\x04\xd7\x01\x04(\x1aU\x20The\x20station\x20can\x20send\ + \x20client\x20config\x20info\x20piggybacked\n\x20on\x20any\x20message,\ + \x20as\x20it\x20sees\x20fit\n\n\r\n\x05\x04\x0c\x02\x02\x04\x12\x04\xd7\ + \x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x02\x06\x12\x04\xd7\x01\r\x17\n\r\n\ + \x05\x04\x0c\x02\x02\x01\x12\x04\xd7\x01\x18#\n\r\n\x05\x04\x0c\x02\x02\ + \x03\x12\x04\xd7\x01&'\nP\n\x04\x04\x0c\x02\x03\x12\x04\xda\x01\x04+\x1a\ + B\x20If\x20state_transition\x20==\x20S2C_ERROR,\x20this\x20field\x20is\ + \x20the\x20explanation.\n\n\r\n\x05\x04\x0c\x02\x03\x04\x12\x04\xda\x01\ + \x04\x0c\n\r\n\x05\x04\x0c\x02\x03\x06\x12\x04\xda\x01\r\x1b\n\r\n\x05\ + \x04\x0c\x02\x03\x01\x12\x04\xda\x01\x1c&\n\r\n\x05\x04\x0c\x02\x03\x03\ + \x12\x04\xda\x01)*\nQ\n\x04\x04\x0c\x02\x04\x12\x04\xdd\x01\x04$\x1aC\ + \x20Signals\x20client\x20to\x20stop\x20connecting\x20for\x20following\ + \x20amount\x20of\x20seconds\n\n\r\n\x05\x04\x0c\x02\x04\x04\x12\x04\xdd\ + \x01\x04\x0c\n\r\n\x05\x04\x0c\x02\x04\x05\x12\x04\xdd\x01\r\x13\n\r\n\ + \x05\x04\x0c\x02\x04\x01\x12\x04\xdd\x01\x14\x1f\n\r\n\x05\x04\x0c\x02\ + \x04\x03\x12\x04\xdd\x01\"#\nK\n\x04\x04\x0c\x02\x05\x12\x04\xe0\x01\x04\ + #\x1a=\x20Sent\x20in\x20SESSION_INIT,\x20identifies\x20the\x20station\ + \x20that\x20picked\x20up\n\n\r\n\x05\x04\x0c\x02\x05\x04\x12\x04\xe0\x01\ + \x04\x0c\n\r\n\x05\x04\x0c\x02\x05\x05\x12\x04\xe0\x01\r\x13\n\r\n\x05\ + \x04\x0c\x02\x05\x01\x12\x04\xe0\x01\x14\x1e\n\r\n\x05\x04\x0c\x02\x05\ + \x03\x12\x04\xe0\x01!\"\nG\n\x04\x04\x0c\x02\x06\x12\x04\xe3\x01\x04!\ + \x1a9\x20Random-sized\x20junk\x20to\x20defeat\x20packet\x20size\x20finge\ + rprinting.\n\n\r\n\x05\x04\x0c\x02\x06\x04\x12\x04\xe3\x01\x04\x0c\n\r\n\ + \x05\x04\x0c\x02\x06\x05\x12\x04\xe3\x01\r\x12\n\r\n\x05\x04\x0c\x02\x06\ + \x01\x12\x04\xe3\x01\x13\x1a\n\r\n\x05\x04\x0c\x02\x06\x03\x12\x04\xe3\ + \x01\x1d\x20\n\x0c\n\x02\x04\r\x12\x06\xe6\x01\0\xec\x01\x01\n\x0b\n\x03\ + \x04\r\x01\x12\x04\xe6\x01\x08\x19\n\x0c\n\x04\x04\r\x02\0\x12\x04\xe7\ + \x01\x08&\n\r\n\x05\x04\r\x02\0\x04\x12\x04\xe7\x01\x08\x10\n\r\n\x05\ + \x04\r\x02\0\x05\x12\x04\xe7\x01\x11\x15\n\r\n\x05\x04\r\x02\0\x01\x12\ + \x04\xe7\x01\x16!\n\r\n\x05\x04\r\x02\0\x03\x12\x04\xe7\x01$%\n\x0c\n\ + \x04\x04\r\x02\x01\x12\x04\xe8\x01\x08%\n\r\n\x05\x04\r\x02\x01\x04\x12\ + \x04\xe8\x01\x08\x10\n\r\n\x05\x04\r\x02\x01\x05\x12\x04\xe8\x01\x11\x15\ + \n\r\n\x05\x04\r\x02\x01\x01\x12\x04\xe8\x01\x16\x20\n\r\n\x05\x04\r\x02\ + \x01\x03\x12\x04\xe8\x01#$\n\x0c\n\x04\x04\r\x02\x02\x12\x04\xe9\x01\x08\ + '\n\r\n\x05\x04\r\x02\x02\x04\x12\x04\xe9\x01\x08\x10\n\r\n\x05\x04\r\ + \x02\x02\x05\x12\x04\xe9\x01\x11\x15\n\r\n\x05\x04\r\x02\x02\x01\x12\x04\ + \xe9\x01\x16\"\n\r\n\x05\x04\r\x02\x02\x03\x12\x04\xe9\x01%&\n\x0c\n\x04\ + \x04\r\x02\x03\x12\x04\xea\x01\x04\x1e\n\r\n\x05\x04\r\x02\x03\x04\x12\ + \x04\xea\x01\x04\x0c\n\r\n\x05\x04\r\x02\x03\x05\x12\x04\xea\x01\r\x11\n\ + \r\n\x05\x04\r\x02\x03\x01\x12\x04\xea\x01\x12\x19\n\r\n\x05\x04\r\x02\ + \x03\x03\x12\x04\xea\x01\x1c\x1d\n\x0c\n\x04\x04\r\x02\x04\x12\x04\xeb\ + \x01\x04!\n\r\n\x05\x04\r\x02\x04\x04\x12\x04\xeb\x01\x04\x0c\n\r\n\x05\ + \x04\r\x02\x04\x05\x12\x04\xeb\x01\r\x11\n\r\n\x05\x04\r\x02\x04\x01\x12\ + \x04\xeb\x01\x12\x1c\n\r\n\x05\x04\r\x02\x04\x03\x12\x04\xeb\x01\x1f\x20\ + \n\x0c\n\x02\x04\x0e\x12\x06\xee\x01\0\xa8\x02\x01\n\x0b\n\x03\x04\x0e\ + \x01\x12\x04\xee\x01\x08\x17\n\x0c\n\x04\x04\x0e\x02\0\x12\x04\xef\x01\ + \x04)\n\r\n\x05\x04\x0e\x02\0\x04\x12\x04\xef\x01\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\0\x05\x12\x04\xef\x01\r\x13\n\r\n\x05\x04\x0e\x02\0\x01\x12\x04\ + \xef\x01\x14$\n\r\n\x05\x04\x0e\x02\0\x03\x12\x04\xef\x01'(\n\xd0\x01\n\ + \x04\x04\x0e\x02\x01\x12\x04\xf4\x01\x04.\x1a\xc1\x01\x20The\x20client\ + \x20reports\x20its\x20decoy\x20list's\x20version\x20number\x20here,\x20w\ + hich\x20the\n\x20station\x20can\x20use\x20to\x20decide\x20whether\x20to\ + \x20send\x20an\x20updated\x20one.\x20The\x20station\n\x20should\x20alway\ + s\x20send\x20a\x20list\x20if\x20this\x20field\x20is\x20set\x20to\x200.\n\ + \n\r\n\x05\x04\x0e\x02\x01\x04\x12\x04\xf4\x01\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x01\x05\x12\x04\xf4\x01\r\x13\n\r\n\x05\x04\x0e\x02\x01\x01\x12\x04\ + \xf4\x01\x14)\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xf4\x01,-\n\x0c\n\ + \x04\x04\x0e\x02\x02\x12\x04\xf6\x01\x041\n\r\n\x05\x04\x0e\x02\x02\x04\ + \x12\x04\xf6\x01\x04\x0c\n\r\n\x05\x04\x0e\x02\x02\x06\x12\x04\xf6\x01\r\ + \x1b\n\r\n\x05\x04\x0e\x02\x02\x01\x12\x04\xf6\x01\x1c,\n\r\n\x05\x04\ + \x0e\x02\x02\x03\x12\x04\xf6\x01/0\n\x80\x01\n\x04\x04\x0e\x02\x03\x12\ + \x04\xfa\x01\x04$\x1ar\x20The\x20position\x20in\x20the\x20overall\x20ses\ + sion's\x20upload\x20sequence\x20where\x20the\x20current\n\x20YIELD=>ACQU\ + IRE\x20switchover\x20is\x20happening.\n\n\r\n\x05\x04\x0e\x02\x03\x04\ + \x12\x04\xfa\x01\x04\x0c\n\r\n\x05\x04\x0e\x02\x03\x05\x12\x04\xfa\x01\r\ + \x13\n\r\n\x05\x04\x0e\x02\x03\x01\x12\x04\xfa\x01\x14\x1f\n\r\n\x05\x04\ + \x0e\x02\x03\x03\x12\x04\xfa\x01\"#\ng\n\x04\x04\x0e\x02\x04\x12\x04\xfe\ + \x01\x04+\x1aY\x20High\x20level\x20client\x20library\x20version\x20used\ + \x20for\x20indicating\x20feature\x20support,\x20or\n\x20lack\x20therof.\ + \n\n\r\n\x05\x04\x0e\x02\x04\x04\x12\x04\xfe\x01\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\x04\x05\x12\x04\xfe\x01\r\x13\n\r\n\x05\x04\x0e\x02\x04\x01\x12\ + \x04\xfe\x01\x14&\n\r\n\x05\x04\x0e\x02\x04\x03\x12\x04\xfe\x01)*\n\xa5\ + \x02\n\x04\x04\x0e\x02\x05\x12\x04\x83\x02\x042\x1a\x96\x02\x20Indicates\ + \x20whether\x20the\x20client\x20will\x20allow\x20the\x20registrar\x20to\ + \x20provide\x20alternative\x20parameters\x20that\n\x20may\x20work\x20bet\ + ter\x20in\x20substitute\x20for\x20the\x20deterministically\x20selected\ + \x20parameters.\x20This\x20only\x20works\n\x20for\x20bidirectional\x20re\ + gistration\x20methods\x20where\x20the\x20client\x20receives\x20a\x20Regi\ + strationResponse.\n\n\r\n\x05\x04\x0e\x02\x05\x04\x12\x04\x83\x02\x04\ + \x0c\n\r\n\x05\x04\x0e\x02\x05\x05\x12\x04\x83\x02\r\x11\n\r\n\x05\x04\ + \x0e\x02\x05\x01\x12\x04\x83\x02\x12-\n\r\n\x05\x04\x0e\x02\x05\x03\x12\ + \x04\x83\x0201\nq\n\x04\x04\x0e\x02\x06\x12\x04\x87\x02\x04'\x1ac\x20Lis\ + t\x20of\x20decoys\x20that\x20client\x20have\x20unsuccessfully\x20tried\ + \x20in\x20current\x20session.\n\x20Could\x20be\x20sent\x20in\x20chunks\n\ + \n\r\n\x05\x04\x0e\x02\x06\x04\x12\x04\x87\x02\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x06\x05\x12\x04\x87\x02\r\x13\n\r\n\x05\x04\x0e\x02\x06\x01\x12\x04\ + \x87\x02\x14!\n\r\n\x05\x04\x0e\x02\x06\x03\x12\x04\x87\x02$&\n\x0c\n\ + \x04\x04\x0e\x02\x07\x12\x04\x89\x02\x04%\n\r\n\x05\x04\x0e\x02\x07\x04\ + \x12\x04\x89\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x07\x06\x12\x04\x89\x02\r\ + \x19\n\r\n\x05\x04\x0e\x02\x07\x01\x12\x04\x89\x02\x1a\x1f\n\r\n\x05\x04\ + \x0e\x02\x07\x03\x12\x04\x89\x02\"$\nk\n\x04\x04\x0e\x02\x08\x12\x04\x8c\ + \x02\x04*\x1a]\x20NullTransport,\x20MinTransport,\x20Obfs4Transport,\x20\ + etc.\x20Transport\x20type\x20we\x20want\x20from\x20phantom\x20proxy\n\n\ + \r\n\x05\x04\x0e\x02\x08\x04\x12\x04\x8c\x02\x04\x0c\n\r\n\x05\x04\x0e\ + \x02\x08\x06\x12\x04\x8c\x02\r\x1a\n\r\n\x05\x04\x0e\x02\x08\x01\x12\x04\ + \x8c\x02\x1b$\n\r\n\x05\x04\x0e\x02\x08\x03\x12\x04\x8c\x02')\n\x0c\n\ + \x04\x04\x0e\x02\t\x12\x04\x8e\x02\x047\n\r\n\x05\x04\x0e\x02\t\x04\x12\ + \x04\x8e\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\t\x06\x12\x04\x8e\x02\r\x20\n\ + \r\n\x05\x04\x0e\x02\t\x01\x12\x04\x8e\x02!1\n\r\n\x05\x04\x0e\x02\t\x03\ + \x12\x04\x8e\x0246\n\xc8\x03\n\x04\x04\x0e\x02\n\x12\x04\x96\x02\x04(\ + \x1a\xb9\x03\x20Station\x20is\x20only\x20required\x20to\x20check\x20this\ + \x20variable\x20during\x20session\x20initialization.\n\x20If\x20set,\x20\ + station\x20must\x20facilitate\x20connection\x20to\x20said\x20target\x20b\ + y\x20itself,\x20i.e.\x20write\x20into\x20squid\n\x20socket\x20an\x20HTTP\ + /SOCKS/any\x20other\x20connection\x20request.\n\x20covert_address\x20mus\ + t\x20have\x20exactly\x20one\x20':'\x20colon,\x20that\x20separates\x20hos\ + t\x20(literal\x20IP\x20address\x20or\n\x20resolvable\x20hostname)\x20and\ + \x20port\n\x20TODO:\x20make\x20it\x20required\x20for\x20initialization,\ + \x20and\x20stop\x20connecting\x20any\x20client\x20straight\x20to\x20squi\ + d?\n\n\r\n\x05\x04\x0e\x02\n\x04\x12\x04\x96\x02\x04\x0c\n\r\n\x05\x04\ + \x0e\x02\n\x05\x12\x04\x96\x02\r\x13\n\r\n\x05\x04\x0e\x02\n\x01\x12\x04\ + \x96\x02\x14\"\n\r\n\x05\x04\x0e\x02\n\x03\x12\x04\x96\x02%'\nR\n\x04\ + \x04\x0e\x02\x0b\x12\x04\x99\x02\x042\x1aD\x20Used\x20in\x20dark\x20deco\ + ys\x20to\x20signal\x20which\x20dark\x20decoy\x20it\x20will\x20connect\ + \x20to.\n\n\r\n\x05\x04\x0e\x02\x0b\x04\x12\x04\x99\x02\x04\x0c\n\r\n\ + \x05\x04\x0e\x02\x0b\x05\x12\x04\x99\x02\r\x13\n\r\n\x05\x04\x0e\x02\x0b\ + \x01\x12\x04\x99\x02\x14,\n\r\n\x05\x04\x0e\x02\x0b\x03\x12\x04\x99\x02/\ + 1\nR\n\x04\x04\x0e\x02\x0c\x12\x04\x9c\x02\x04\"\x1aD\x20Used\x20to\x20i\ + ndicate\x20to\x20server\x20if\x20client\x20is\x20registering\x20v4,\x20v\ + 6\x20or\x20both\n\n\r\n\x05\x04\x0e\x02\x0c\x04\x12\x04\x9c\x02\x04\x0c\ + \n\r\n\x05\x04\x0e\x02\x0c\x05\x12\x04\x9c\x02\r\x11\n\r\n\x05\x04\x0e\ + \x02\x0c\x01\x12\x04\x9c\x02\x12\x1c\n\r\n\x05\x04\x0e\x02\x0c\x03\x12\ + \x04\x9c\x02\x1f!\n\x0c\n\x04\x04\x0e\x02\r\x12\x04\x9d\x02\x04\"\n\r\n\ + \x05\x04\x0e\x02\r\x04\x12\x04\x9d\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\r\ + \x05\x12\x04\x9d\x02\r\x11\n\r\n\x05\x04\x0e\x02\r\x01\x12\x04\x9d\x02\ + \x12\x1c\n\r\n\x05\x04\x0e\x02\r\x03\x12\x04\x9d\x02\x1f!\nD\n\x04\x04\ + \x0e\x02\x0e\x12\x04\xa0\x02\x04*\x1a6\x20A\x20collection\x20of\x20optio\ + nal\x20flags\x20for\x20the\x20registration.\n\n\r\n\x05\x04\x0e\x02\x0e\ + \x04\x12\x04\xa0\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\x0e\x06\x12\x04\xa0\ + \x02\r\x1e\n\r\n\x05\x04\x0e\x02\x0e\x01\x12\x04\xa0\x02\x1f$\n\r\n\x05\ + \x04\x0e\x02\x0e\x03\x12\x04\xa0\x02')\nq\n\x04\x04\x0e\x02\x0f\x12\x04\ + \xa4\x02\x04-\x1ac\x20Transport\x20Extensions\n\x20TODO(jmwample)\x20-\ + \x20move\x20to\x20WebRTC\x20specific\x20transport\x20params\x20protobuf\ + \x20message.\n\n\r\n\x05\x04\x0e\x02\x0f\x04\x12\x04\xa4\x02\x04\x0c\n\r\ + \n\x05\x04\x0e\x02\x0f\x06\x12\x04\xa4\x02\r\x19\n\r\n\x05\x04\x0e\x02\ + \x0f\x01\x12\x04\xa4\x02\x1a'\n\r\n\x05\x04\x0e\x02\x0f\x03\x12\x04\xa4\ + \x02*,\nG\n\x04\x04\x0e\x02\x10\x12\x04\xa7\x02\x04!\x1a9\x20Random-size\ + d\x20junk\x20to\x20defeat\x20packet\x20size\x20fingerprinting.\n\n\r\n\ + \x05\x04\x0e\x02\x10\x04\x12\x04\xa7\x02\x04\x0c\n\r\n\x05\x04\x0e\x02\ + \x10\x05\x12\x04\xa7\x02\r\x12\n\r\n\x05\x04\x0e\x02\x10\x01\x12\x04\xa7\ + \x02\x13\x1a\n\r\n\x05\x04\x0e\x02\x10\x03\x12\x04\xa7\x02\x1d\x20\n\x0c\ + \n\x02\x04\x0f\x12\x06\xab\x02\0\xb8\x02\x01\n\x0b\n\x03\x04\x0f\x01\x12\ + \x04\xab\x02\x08\x1b\n\x0c\n\x04\x04\x0f\x02\0\x12\x04\xac\x02\x04\x1d\n\ + \r\n\x05\x04\x0f\x02\0\x04\x12\x04\xac\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\ + \0\x05\x12\x04\xac\x02\r\x12\n\r\n\x05\x04\x0f\x02\0\x01\x12\x04\xac\x02\ + \x13\x18\n\r\n\x05\x04\x0f\x02\0\x03\x12\x04\xac\x02\x1b\x1c\n\x0c\n\x04\ + \x04\x0f\x02\x01\x12\x04\xae\x02\x04\x1f\n\r\n\x05\x04\x0f\x02\x01\x04\ + \x12\x04\xae\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\x01\x05\x12\x04\xae\x02\r\ + \x12\n\r\n\x05\x04\x0f\x02\x01\x01\x12\x04\xae\x02\x13\x1a\n\r\n\x05\x04\ + \x0f\x02\x01\x03\x12\x04\xae\x02\x1d\x1e\n\x0c\n\x04\x04\x0f\x02\x02\x12\ + \x04\xb0\x02\x04#\n\r\n\x05\x04\x0f\x02\x02\x04\x12\x04\xb0\x02\x04\x0c\ + \n\r\n\x05\x04\x0f\x02\x02\x05\x12\x04\xb0\x02\r\x12\n\r\n\x05\x04\x0f\ + \x02\x02\x01\x12\x04\xb0\x02\x13\x1e\n\r\n\x05\x04\x0f\x02\x02\x03\x12\ + \x04\xb0\x02!\"\n\x0c\n\x04\x04\x0f\x02\x03\x12\x04\xb2\x02\x04\x1b\n\r\ + \n\x05\x04\x0f\x02\x03\x04\x12\x04\xb2\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\ + \x03\x05\x12\x04\xb2\x02\r\x12\n\r\n\x05\x04\x0f\x02\x03\x01\x12\x04\xb2\ + \x02\x13\x16\n\r\n\x05\x04\x0f\x02\x03\x03\x12\x04\xb2\x02\x19\x1a\n\xcb\ + \x01\n\x04\x04\x0f\x02\x04\x12\x04\xb7\x02\x04*\x1a\xbc\x01\x20Indicates\ + \x20whether\x20the\x20client\x20has\x20elected\x20to\x20use\x20destinati\ + on\x20port\x20randomization.\x20Should\x20be\n\x20checked\x20against\x20\ + selected\x20transport\x20to\x20ensure\x20that\x20destination\x20port\x20\ + randomization\x20is\n\x20supported.\n\n\r\n\x05\x04\x0f\x02\x04\x04\x12\ + \x04\xb7\x02\x04\x0c\n\r\n\x05\x04\x0f\x02\x04\x05\x12\x04\xb7\x02\r\x11\ + \n\r\n\x05\x04\x0f\x02\x04\x01\x12\x04\xb7\x02\x12$\n\r\n\x05\x04\x0f\ + \x02\x04\x03\x12\x04\xb7\x02')\n\x0c\n\x02\x04\x10\x12\x06\xba\x02\0\xcc\ + \x02\x01\n\x0b\n\x03\x04\x10\x01\x12\x04\xba\x02\x08\x1d\n!\n\x04\x04\ + \x10\x02\0\x12\x04\xbc\x02\x04!\x1a\x13\x20Prefix\x20Identifier\n\n\r\n\ + \x05\x04\x10\x02\0\x04\x12\x04\xbc\x02\x04\x0c\n\r\n\x05\x04\x10\x02\0\ + \x05\x12\x04\xbc\x02\r\x12\n\r\n\x05\x04\x10\x02\0\x01\x12\x04\xbc\x02\ + \x13\x1c\n\r\n\x05\x04\x10\x02\0\x03\x12\x04\xbc\x02\x1f\x20\n\xc4\x01\n\ + \x04\x04\x10\x02\x01\x12\x04\xc0\x02\x04\x1e\x1a\xb5\x01\x20Prefix\x20by\ + tes\x20(optional\x20-\x20usually\x20sent\x20from\x20station\x20to\x20cli\ + ent\x20as\x20override\x20if\x20allowed\x20by\x20C2S)\n\x20as\x20the\x20s\ + tation\x20cannot\x20take\x20this\x20into\x20account\x20when\x20attemptin\ + g\x20to\x20identify\x20a\x20connection.\n\n\r\n\x05\x04\x10\x02\x01\x04\ + \x12\x04\xc0\x02\x04\x0c\n\r\n\x05\x04\x10\x02\x01\x05\x12\x04\xc0\x02\r\ + \x12\n\r\n\x05\x04\x10\x02\x01\x01\x12\x04\xc0\x02\x13\x19\n\r\n\x05\x04\ + \x10\x02\x01\x03\x12\x04\xc0\x02\x1c\x1d\n\x0c\n\x04\x04\x10\x02\x02\x12\ + \x04\xc1\x02\x04+\n\r\n\x05\x04\x10\x02\x02\x04\x12\x04\xc1\x02\x04\x0c\ + \n\r\n\x05\x04\x10\x02\x02\x05\x12\x04\xc1\x02\r\x12\n\r\n\x05\x04\x10\ + \x02\x02\x01\x12\x04\xc1\x02\x13&\n\r\n\x05\x04\x10\x02\x02\x03\x12\x04\ + \xc1\x02)*\n\xed\x02\n\x04\x04\x10\x02\x03\x12\x04\xcb\x02\x04*\x1a\xbc\ + \x01\x20Indicates\x20whether\x20the\x20client\x20has\x20elected\x20to\ + \x20use\x20destination\x20port\x20randomization.\x20Should\x20be\n\x20ch\ + ecked\x20against\x20selected\x20transport\x20to\x20ensure\x20that\x20des\ + tination\x20port\x20randomization\x20is\n\x20supported.\n2\x9f\x01\x20//\ + \x20potential\x20future\x20fields\n\x20obfuscator\x20ID\n\x20tagEncoder\ + \x20ID\x20(¶ms?,\x20e.g.\x20format-base64\x20/\x20padding)\n\x20stre\ + amEncoder\x20ID\x20(¶ms?,\x20e.g.\x20foramat-base64\x20/\x20padding)\ + \n\n\r\n\x05\x04\x10\x02\x03\x04\x12\x04\xcb\x02\x04\x0c\n\r\n\x05\x04\ + \x10\x02\x03\x05\x12\x04\xcb\x02\r\x11\n\r\n\x05\x04\x10\x02\x03\x01\x12\ + \x04\xcb\x02\x12$\n\r\n\x05\x04\x10\x02\x03\x03\x12\x04\xcb\x02')\n\x0c\ + \n\x02\x04\x11\x12\x06\xce\x02\0\xd3\x02\x01\n\x0b\n\x03\x04\x11\x01\x12\ + \x04\xce\x02\x08\x1e\n\xcb\x01\n\x04\x04\x11\x02\0\x12\x04\xd2\x02\x04*\ + \x1a\xbc\x01\x20Indicates\x20whether\x20the\x20client\x20has\x20elected\ + \x20to\x20use\x20destination\x20port\x20randomization.\x20Should\x20be\n\ + \x20checked\x20against\x20selected\x20transport\x20to\x20ensure\x20that\ + \x20destination\x20port\x20randomization\x20is\n\x20supported.\n\n\r\n\ + \x05\x04\x11\x02\0\x04\x12\x04\xd2\x02\x04\x0c\n\r\n\x05\x04\x11\x02\0\ + \x05\x12\x04\xd2\x02\r\x11\n\r\n\x05\x04\x11\x02\0\x01\x12\x04\xd2\x02\ + \x12$\n\r\n\x05\x04\x11\x02\0\x03\x12\x04\xd2\x02')\n\x0c\n\x02\x05\x06\ + \x12\x06\xd5\x02\0\xdd\x02\x01\n\x0b\n\x03\x05\x06\x01\x12\x04\xd5\x02\ + \x05\x17\n\x0c\n\x04\x05\x06\x02\0\x12\x04\xd6\x02\x02\x12\n\r\n\x05\x05\ + \x06\x02\0\x01\x12\x04\xd6\x02\x02\r\n\r\n\x05\x05\x06\x02\0\x02\x12\x04\ + \xd6\x02\x10\x11\n\x0c\n\x04\x05\x06\x02\x01\x12\x04\xd7\x02\x08\x15\n\r\ + \n\x05\x05\x06\x02\x01\x01\x12\x04\xd7\x02\x08\x10\n\r\n\x05\x05\x06\x02\ + \x01\x02\x12\x04\xd7\x02\x13\x14\n\x0c\n\x04\x05\x06\x02\x02\x12\x04\xd8\ + \x02\x08\x10\n\r\n\x05\x05\x06\x02\x02\x01\x12\x04\xd8\x02\x08\x0b\n\r\n\ + \x05\x05\x06\x02\x02\x02\x12\x04\xd8\x02\x0e\x0f\n\x0c\n\x04\x05\x06\x02\ + \x03\x12\x04\xd9\x02\x02\x16\n\r\n\x05\x05\x06\x02\x03\x01\x12\x04\xd9\ + \x02\x02\x11\n\r\n\x05\x05\x06\x02\x03\x02\x12\x04\xd9\x02\x14\x15\n\x0c\ + \n\x04\x05\x06\x02\x04\x12\x04\xda\x02\x02\x17\n\r\n\x05\x05\x06\x02\x04\ + \x01\x12\x04\xda\x02\x02\x12\n\r\n\x05\x05\x06\x02\x04\x02\x12\x04\xda\ + \x02\x15\x16\n\x0c\n\x04\x05\x06\x02\x05\x12\x04\xdb\x02\x02\n\n\r\n\x05\ + \x05\x06\x02\x05\x01\x12\x04\xdb\x02\x02\x05\n\r\n\x05\x05\x06\x02\x05\ + \x02\x12\x04\xdb\x02\x08\t\n\x0c\n\x04\x05\x06\x02\x06\x12\x04\xdc\x02\ + \x02\x17\n\r\n\x05\x05\x06\x02\x06\x01\x12\x04\xdc\x02\x02\x12\n\r\n\x05\ + \x05\x06\x02\x06\x02\x12\x04\xdc\x02\x15\x16\n\x0c\n\x02\x04\x12\x12\x06\ + \xdf\x02\0\xf7\x02\x01\n\x0b\n\x03\x04\x12\x01\x12\x04\xdf\x02\x08\x12\n\ + \x0c\n\x04\x04\x12\x02\0\x12\x04\xe0\x02\x02#\n\r\n\x05\x04\x12\x02\0\ + \x04\x12\x04\xe0\x02\x02\n\n\r\n\x05\x04\x12\x02\0\x05\x12\x04\xe0\x02\ + \x0b\x10\n\r\n\x05\x04\x12\x02\0\x01\x12\x04\xe0\x02\x11\x1e\n\r\n\x05\ + \x04\x12\x02\0\x03\x12\x04\xe0\x02!\"\n\x0c\n\x04\x04\x12\x02\x01\x12\ + \x04\xe1\x02\x024\n\r\n\x05\x04\x12\x02\x01\x04\x12\x04\xe1\x02\x02\n\n\ + \r\n\x05\x04\x12\x02\x01\x06\x12\x04\xe1\x02\x0b\x1a\n\r\n\x05\x04\x12\ + \x02\x01\x01\x12\x04\xe1\x02\x1b/\n\r\n\x05\x04\x12\x02\x01\x03\x12\x04\ + \xe1\x0223\n\x0c\n\x04\x04\x12\x02\x02\x12\x04\xe2\x02\x026\n\r\n\x05\ + \x04\x12\x02\x02\x04\x12\x04\xe2\x02\x02\n\n\r\n\x05\x04\x12\x02\x02\x06\ + \x12\x04\xe2\x02\x0b\x1d\n\r\n\x05\x04\x12\x02\x02\x01\x12\x04\xe2\x02\ + \x1e1\n\r\n\x05\x04\x12\x02\x02\x03\x12\x04\xe2\x0245\nC\n\x04\x04\x12\ + \x02\x03\x12\x04\xe5\x02\x02*\x1a5\x20client\x20source\x20address\x20whe\ + n\x20receiving\x20a\x20registration\n\n\r\n\x05\x04\x12\x02\x03\x04\x12\ + \x04\xe5\x02\x02\n\n\r\n\x05\x04\x12\x02\x03\x05\x12\x04\xe5\x02\x0b\x10\ + \n\r\n\x05\x04\x12\x02\x03\x01\x12\x04\xe5\x02\x11%\n\r\n\x05\x04\x12\ + \x02\x03\x03\x12\x04\xe5\x02()\nH\n\x04\x04\x12\x02\x04\x12\x04\xe8\x02\ + \x02#\x1a:\x20Decoy\x20address\x20used\x20when\x20registering\x20over\ + \x20Decoy\x20registrar\n\n\r\n\x05\x04\x12\x02\x04\x04\x12\x04\xe8\x02\ + \x02\n\n\r\n\x05\x04\x12\x02\x04\x05\x12\x04\xe8\x02\x0b\x10\n\r\n\x05\ + \x04\x12\x02\x04\x01\x12\x04\xe8\x02\x11\x1e\n\r\n\x05\x04\x12\x02\x04\ + \x03\x12\x04\xe8\x02!\"\n\xeb\x05\n\x04\x04\x12\x02\x05\x12\x04\xf4\x02\ + \x02:\x1a\xdc\x05\x20The\x20next\x20three\x20fields\x20allow\x20an\x20in\ + dependent\x20registrar\x20(trusted\x20by\x20a\x20station\x20w/\x20a\x20z\ + mq\x20keypair)\x20to\n\x20share\x20the\x20registration\x20overrides\x20t\ + hat\x20it\x20assigned\x20to\x20the\x20client\x20with\x20the\x20station(s\ + ).\n\x20Registration\x20Respose\x20is\x20here\x20to\x20allow\x20a\x20par\ + sed\x20object\x20with\x20direct\x20access\x20to\x20the\x20fields\x20with\ + in.\n\x20RegRespBytes\x20provides\x20a\x20serialized\x20verion\x20of\x20\ + the\x20Registration\x20response\x20so\x20that\x20the\x20signature\x20of\ + \n\x20the\x20Bidirectional\x20registrar\x20can\x20be\x20validated\x20bef\ + ore\x20a\x20station\x20applies\x20any\x20overrides\x20present\x20in\n\ + \x20the\x20Registration\x20Response.\n\n\x20If\x20you\x20are\x20reading\ + \x20this\x20in\x20the\x20future\x20and\x20you\x20want\x20to\x20extend\ + \x20the\x20functionality\x20here\x20it\x20might\n\x20make\x20sense\x20to\ + \x20make\x20the\x20RegistrationResponse\x20that\x20is\x20sent\x20to\x20t\ + he\x20client\x20a\x20distinct\x20message\x20from\n\x20the\x20one\x20that\ + \x20gets\x20sent\x20to\x20the\x20stations.\n\n\r\n\x05\x04\x12\x02\x05\ + \x04\x12\x04\xf4\x02\x02\n\n\r\n\x05\x04\x12\x02\x05\x06\x12\x04\xf4\x02\ + \x0b\x1f\n\r\n\x05\x04\x12\x02\x05\x01\x12\x04\xf4\x02\x205\n\r\n\x05\ + \x04\x12\x02\x05\x03\x12\x04\xf4\x0289\n\x0c\n\x04\x04\x12\x02\x06\x12\ + \x04\xf5\x02\x02\"\n\r\n\x05\x04\x12\x02\x06\x04\x12\x04\xf5\x02\x02\n\n\ + \r\n\x05\x04\x12\x02\x06\x05\x12\x04\xf5\x02\x0b\x10\n\r\n\x05\x04\x12\ + \x02\x06\x01\x12\x04\xf5\x02\x11\x1d\n\r\n\x05\x04\x12\x02\x06\x03\x12\ + \x04\xf5\x02\x20!\n\x0c\n\x04\x04\x12\x02\x07\x12\x04\xf6\x02\x02'\n\r\n\ + \x05\x04\x12\x02\x07\x04\x12\x04\xf6\x02\x02\n\n\r\n\x05\x04\x12\x02\x07\ + \x05\x12\x04\xf6\x02\x0b\x10\n\r\n\x05\x04\x12\x02\x07\x01\x12\x04\xf6\ + \x02\x11!\n\r\n\x05\x04\x12\x02\x07\x03\x12\x04\xf6\x02$&\n\x0c\n\x02\ + \x04\x13\x12\x06\xf9\x02\0\x85\x03\x01\n\x0b\n\x03\x04\x13\x01\x12\x04\ + \xf9\x02\x08\x14\n9\n\x04\x04\x13\x02\0\x12\x04\xfa\x02\x04.\"+\x20how\ + \x20many\x20decoys\x20were\x20tried\x20before\x20success\n\n\r\n\x05\x04\ + \x13\x02\0\x04\x12\x04\xfa\x02\x04\x0c\n\r\n\x05\x04\x13\x02\0\x05\x12\ + \x04\xfa\x02\r\x13\n\r\n\x05\x04\x13\x02\0\x01\x12\x04\xfa\x02\x14(\n\r\ + \n\x05\x04\x13\x02\0\x03\x12\x04\xfa\x02+-\nm\n\x04\x04\x13\x02\x01\x12\ + \x04\xff\x02\x04/\x1a\x1e\x20Applicable\x20to\x20whole\x20session:\n\"\ + \x1a\x20includes\x20failed\x20attempts\n2#\x20Timings\x20below\x20are\ + \x20in\x20milliseconds\n\n\r\n\x05\x04\x13\x02\x01\x04\x12\x04\xff\x02\ + \x04\x0c\n\r\n\x05\x04\x13\x02\x01\x05\x12\x04\xff\x02\r\x13\n\r\n\x05\ + \x04\x13\x02\x01\x01\x12\x04\xff\x02\x14)\n\r\n\x05\x04\x13\x02\x01\x03\ + \x12\x04\xff\x02,.\nR\n\x04\x04\x13\x02\x02\x12\x04\x82\x03\x04(\x1a\x1f\ + \x20Last\x20(i.e.\x20successful)\x20decoy:\n\"#\x20measured\x20during\ + \x20initial\x20handshake\n\n\r\n\x05\x04\x13\x02\x02\x04\x12\x04\x82\x03\ + \x04\x0c\n\r\n\x05\x04\x13\x02\x02\x05\x12\x04\x82\x03\r\x13\n\r\n\x05\ + \x04\x13\x02\x02\x01\x12\x04\x82\x03\x14\"\n\r\n\x05\x04\x13\x02\x02\x03\ + \x12\x04\x82\x03%'\n%\n\x04\x04\x13\x02\x03\x12\x04\x83\x03\x04&\"\x17\ + \x20includes\x20tcp\x20to\x20decoy\n\n\r\n\x05\x04\x13\x02\x03\x04\x12\ + \x04\x83\x03\x04\x0c\n\r\n\x05\x04\x13\x02\x03\x05\x12\x04\x83\x03\r\x13\ + \n\r\n\x05\x04\x13\x02\x03\x01\x12\x04\x83\x03\x14\x20\n\r\n\x05\x04\x13\ + \x02\x03\x03\x12\x04\x83\x03#%\nB\n\x04\x04\x13\x02\x04\x12\x04\x84\x03\ + \x04&\"4\x20measured\x20when\x20establishing\x20tcp\x20connection\x20to\ + \x20decot\n\n\r\n\x05\x04\x13\x02\x04\x04\x12\x04\x84\x03\x04\x0c\n\r\n\ + \x05\x04\x13\x02\x04\x05\x12\x04\x84\x03\r\x13\n\r\n\x05\x04\x13\x02\x04\ + \x01\x12\x04\x84\x03\x14\x20\n\r\n\x05\x04\x13\x02\x04\x03\x12\x04\x84\ + \x03#%\n\x0c\n\x02\x05\x07\x12\x06\x87\x03\0\x8c\x03\x01\n\x0b\n\x03\x05\ + \x07\x01\x12\x04\x87\x03\x05\x16\n\x0c\n\x04\x05\x07\x02\0\x12\x04\x88\ + \x03\x04\x10\n\r\n\x05\x05\x07\x02\0\x01\x12\x04\x88\x03\x04\x0b\n\r\n\ + \x05\x05\x07\x02\0\x02\x12\x04\x88\x03\x0e\x0f\n\x0c\n\x04\x05\x07\x02\ + \x01\x12\x04\x89\x03\x04\x0c\n\r\n\x05\x05\x07\x02\x01\x01\x12\x04\x89\ + \x03\x04\x07\n\r\n\x05\x05\x07\x02\x01\x02\x12\x04\x89\x03\n\x0b\n\x0c\n\ + \x04\x05\x07\x02\x02\x12\x04\x8a\x03\x04\x0f\n\r\n\x05\x05\x07\x02\x02\ + \x01\x12\x04\x8a\x03\x04\n\n\r\n\x05\x05\x07\x02\x02\x02\x12\x04\x8a\x03\ + \r\x0e\n\x0c\n\x04\x05\x07\x02\x03\x12\x04\x8b\x03\x04\x0e\n\r\n\x05\x05\ + \x07\x02\x03\x01\x12\x04\x8b\x03\x04\t\n\r\n\x05\x05\x07\x02\x03\x02\x12\ + \x04\x8b\x03\x0c\r\n\x0c\n\x02\x05\x08\x12\x06\x8e\x03\0\x92\x03\x01\n\ + \x0b\n\x03\x05\x08\x01\x12\x04\x8e\x03\x05\x0c\n\x0c\n\x04\x05\x08\x02\0\ + \x12\x04\x8f\x03\x04\x0c\n\r\n\x05\x05\x08\x02\0\x01\x12\x04\x8f\x03\x04\ + \x07\n\r\n\x05\x05\x08\x02\0\x02\x12\x04\x8f\x03\n\x0b\n\x0c\n\x04\x05\ + \x08\x02\x01\x12\x04\x90\x03\x04\x0c\n\r\n\x05\x05\x08\x02\x01\x01\x12\ + \x04\x90\x03\x04\x07\n\r\n\x05\x05\x08\x02\x01\x02\x12\x04\x90\x03\n\x0b\ + \n\x0c\n\x04\x05\x08\x02\x02\x12\x04\x91\x03\x04\x0c\n\r\n\x05\x05\x08\ + \x02\x02\x01\x12\x04\x91\x03\x04\x07\n\r\n\x05\x05\x08\x02\x02\x02\x12\ + \x04\x91\x03\n\x0b\n\x0c\n\x02\x04\x14\x12\x06\x94\x03\0\x9f\x03\x01\n\ + \x0b\n\x03\x04\x14\x01\x12\x04\x94\x03\x08\x19\n\x0c\n\x04\x04\x14\x02\0\ + \x12\x04\x95\x03\x04#\n\r\n\x05\x04\x14\x02\0\x04\x12\x04\x95\x03\x04\ + \x0c\n\r\n\x05\x04\x14\x02\0\x05\x12\x04\x95\x03\r\x13\n\r\n\x05\x04\x14\ + \x02\0\x01\x12\x04\x95\x03\x14\x1e\n\r\n\x05\x04\x14\x02\0\x03\x12\x04\ + \x95\x03!\"\n\x0c\n\x04\x04\x14\x02\x01\x12\x04\x96\x03\x04\"\n\r\n\x05\ + \x04\x14\x02\x01\x04\x12\x04\x96\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x01\ + \x05\x12\x04\x96\x03\r\x13\n\r\n\x05\x04\x14\x02\x01\x01\x12\x04\x96\x03\ + \x14\x1d\n\r\n\x05\x04\x14\x02\x01\x03\x12\x04\x96\x03\x20!\n\x0c\n\x04\ + \x04\x14\x02\x02\x12\x04\x98\x03\x04#\n\r\n\x05\x04\x14\x02\x02\x04\x12\ + \x04\x98\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x02\x05\x12\x04\x98\x03\r\x13\ + \n\r\n\x05\x04\x14\x02\x02\x01\x12\x04\x98\x03\x14\x1e\n\r\n\x05\x04\x14\ + \x02\x02\x03\x12\x04\x98\x03!\"\n\x0c\n\x04\x04\x14\x02\x03\x12\x04\x9a\ + \x03\x04-\n\r\n\x05\x04\x14\x02\x03\x04\x12\x04\x9a\x03\x04\x0c\n\r\n\ + \x05\x04\x14\x02\x03\x06\x12\x04\x9a\x03\r\x1e\n\r\n\x05\x04\x14\x02\x03\ + \x01\x12\x04\x9a\x03\x1f(\n\r\n\x05\x04\x14\x02\x03\x03\x12\x04\x9a\x03+\ + ,\n\x0c\n\x04\x04\x14\x02\x04\x12\x04\x9c\x03\x04\"\n\r\n\x05\x04\x14\ + \x02\x04\x04\x12\x04\x9c\x03\x04\x0c\n\r\n\x05\x04\x14\x02\x04\x05\x12\ + \x04\x9c\x03\r\x13\n\r\n\x05\x04\x14\x02\x04\x01\x12\x04\x9c\x03\x14\x1c\ + \n\r\n\x05\x04\x14\x02\x04\x03\x12\x04\x9c\x03\x1f!\n\x0c\n\x04\x04\x14\ + \x02\x05\x12\x04\x9d\x03\x04\"\n\r\n\x05\x04\x14\x02\x05\x04\x12\x04\x9d\ + \x03\x04\x0c\n\r\n\x05\x04\x14\x02\x05\x05\x12\x04\x9d\x03\r\x13\n\r\n\ + \x05\x04\x14\x02\x05\x01\x12\x04\x9d\x03\x14\x1c\n\r\n\x05\x04\x14\x02\ + \x05\x03\x12\x04\x9d\x03\x1f!\n\x0c\n\x04\x04\x14\x02\x06\x12\x04\x9e\ + \x03\x04\x20\n\r\n\x05\x04\x14\x02\x06\x04\x12\x04\x9e\x03\x04\x0c\n\r\n\ + \x05\x04\x14\x02\x06\x06\x12\x04\x9e\x03\r\x14\n\r\n\x05\x04\x14\x02\x06\ + \x01\x12\x04\x9e\x03\x15\x1a\n\r\n\x05\x04\x14\x02\x06\x03\x12\x04\x9e\ + \x03\x1d\x1f\nT\n\x02\x04\x15\x12\x06\xa2\x03\0\xb6\x03\x01\x1aF\x20Addi\ + ng\x20message\x20response\x20from\x20Station\x20to\x20Client\x20for\x20b\ + idirectional\x20API\n\n\x0b\n\x03\x04\x15\x01\x12\x04\xa2\x03\x08\x1c\n\ + \x0c\n\x04\x04\x15\x02\0\x12\x04\xa3\x03\x02\x20\n\r\n\x05\x04\x15\x02\0\ + \x04\x12\x04\xa3\x03\x02\n\n\r\n\x05\x04\x15\x02\0\x05\x12\x04\xa3\x03\ + \x0b\x12\n\r\n\x05\x04\x15\x02\0\x01\x12\x04\xa3\x03\x13\x1b\n\r\n\x05\ + \x04\x15\x02\0\x03\x12\x04\xa3\x03\x1e\x1f\n?\n\x04\x04\x15\x02\x01\x12\ + \x04\xa5\x03\x02\x1e\x1a1\x20The\x20128-bit\x20ipv6\x20address,\x20in\ + \x20network\x20byte\x20order\n\n\r\n\x05\x04\x15\x02\x01\x04\x12\x04\xa5\ + \x03\x02\n\n\r\n\x05\x04\x15\x02\x01\x05\x12\x04\xa5\x03\x0b\x10\n\r\n\ + \x05\x04\x15\x02\x01\x01\x12\x04\xa5\x03\x11\x19\n\r\n\x05\x04\x15\x02\ + \x01\x03\x12\x04\xa5\x03\x1c\x1d\n,\n\x04\x04\x15\x02\x02\x12\x04\xa8\ + \x03\x02\x1f\x1a\x1e\x20Respond\x20with\x20randomized\x20port\n\n\r\n\ + \x05\x04\x15\x02\x02\x04\x12\x04\xa8\x03\x02\n\n\r\n\x05\x04\x15\x02\x02\ + \x05\x12\x04\xa8\x03\x0b\x11\n\r\n\x05\x04\x15\x02\x02\x01\x12\x04\xa8\ + \x03\x12\x1a\n\r\n\x05\x04\x15\x02\x02\x03\x12\x04\xa8\x03\x1d\x1e\nd\n\ + \x04\x04\x15\x02\x03\x12\x04\xac\x03\x02\"\x1aV\x20Future:\x20station\ + \x20provides\x20client\x20with\x20secret,\x20want\x20chanel\x20present\n\ + \x20Leave\x20null\x20for\x20now\n\n\r\n\x05\x04\x15\x02\x03\x04\x12\x04\ + \xac\x03\x02\n\n\r\n\x05\x04\x15\x02\x03\x05\x12\x04\xac\x03\x0b\x10\n\r\ + \n\x05\x04\x15\x02\x03\x01\x12\x04\xac\x03\x11\x1d\n\r\n\x05\x04\x15\x02\ + \x03\x03\x12\x04\xac\x03\x20!\nA\n\x04\x04\x15\x02\x04\x12\x04\xaf\x03\ + \x02\x1c\x1a3\x20If\x20registration\x20wrong,\x20populate\x20this\x20err\ + or\x20string\n\n\r\n\x05\x04\x15\x02\x04\x04\x12\x04\xaf\x03\x02\n\n\r\n\ + \x05\x04\x15\x02\x04\x05\x12\x04\xaf\x03\x0b\x11\n\r\n\x05\x04\x15\x02\ + \x04\x01\x12\x04\xaf\x03\x12\x17\n\r\n\x05\x04\x15\x02\x04\x03\x12\x04\ + \xaf\x03\x1a\x1b\n+\n\x04\x04\x15\x02\x05\x12\x04\xb2\x03\x02%\x1a\x1d\ + \x20ClientConf\x20field\x20(optional)\n\n\r\n\x05\x04\x15\x02\x05\x04\ + \x12\x04\xb2\x03\x02\n\n\r\n\x05\x04\x15\x02\x05\x06\x12\x04\xb2\x03\x0b\ + \x15\n\r\n\x05\x04\x15\x02\x05\x01\x12\x04\xb2\x03\x16\x20\n\r\n\x05\x04\ + \x15\x02\x05\x03\x12\x04\xb2\x03#$\nJ\n\x04\x04\x15\x02\x06\x12\x04\xb5\ + \x03\x025\x1a<\x20Transport\x20Params\x20to\x20if\x20`allow_registrar_ov\ + errides`\x20is\x20set.\n\n\r\n\x05\x04\x15\x02\x06\x04\x12\x04\xb5\x03\ + \x02\n\n\r\n\x05\x04\x15\x02\x06\x06\x12\x04\xb5\x03\x0b\x1e\n\r\n\x05\ + \x04\x15\x02\x06\x01\x12\x04\xb5\x03\x1f/\n\r\n\x05\x04\x15\x02\x06\x03\ + \x12\x04\xb5\x0324\n!\n\x02\x04\x16\x12\x06\xb9\x03\0\xbd\x03\x01\x1a\ + \x13\x20response\x20from\x20dns\n\n\x0b\n\x03\x04\x16\x01\x12\x04\xb9\ + \x03\x08\x13\n\x0c\n\x04\x04\x16\x02\0\x12\x04\xba\x03\x04\x1e\n\r\n\x05\ + \x04\x16\x02\0\x04\x12\x04\xba\x03\x04\x0c\n\r\n\x05\x04\x16\x02\0\x05\ + \x12\x04\xba\x03\r\x11\n\r\n\x05\x04\x16\x02\0\x01\x12\x04\xba\x03\x12\ + \x19\n\r\n\x05\x04\x16\x02\0\x03\x12\x04\xba\x03\x1c\x1d\n\x0c\n\x04\x04\ + \x16\x02\x01\x12\x04\xbb\x03\x04*\n\r\n\x05\x04\x16\x02\x01\x04\x12\x04\ + \xbb\x03\x04\x0c\n\r\n\x05\x04\x16\x02\x01\x05\x12\x04\xbb\x03\r\x11\n\r\ + \n\x05\x04\x16\x02\x01\x01\x12\x04\xbb\x03\x12%\n\r\n\x05\x04\x16\x02\ + \x01\x03\x12\x04\xbb\x03()\n\x0c\n\x04\x04\x16\x02\x02\x12\x04\xbc\x03\ + \x04=\n\r\n\x05\x04\x16\x02\x02\x04\x12\x04\xbc\x03\x04\x0c\n\r\n\x05\ + \x04\x16\x02\x02\x06\x12\x04\xbc\x03\r!\n\r\n\x05\x04\x16\x02\x02\x01\ + \x12\x04\xbc\x03\"8\n\r\n\x05\x04\x16\x02\x02\x03\x12\x04\xbc\x03;<\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -7589,7 +8155,7 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { let generated_file_descriptor = generated_file_descriptor_lazy.get(|| { let mut deps = ::std::vec::Vec::with_capacity(1); deps.push(::protobuf::well_known_types::any::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(21); + let mut messages = ::std::vec::Vec::with_capacity(23); messages.push(PubKey::generated_message_descriptor_data()); messages.push(TLSDecoySpec::generated_message_descriptor_data()); messages.push(ClientConf::generated_message_descriptor_data()); @@ -7600,10 +8166,12 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(WebRTCICECandidate::generated_message_descriptor_data()); messages.push(WebRTCSDP::generated_message_descriptor_data()); messages.push(WebRTCSignal::generated_message_descriptor_data()); + messages.push(Addr::generated_message_descriptor_data()); messages.push(DTLSTransportParams::generated_message_descriptor_data()); messages.push(StationToClient::generated_message_descriptor_data()); messages.push(RegistrationFlags::generated_message_descriptor_data()); messages.push(ClientToStation::generated_message_descriptor_data()); + messages.push(UTLSTransportParams::generated_message_descriptor_data()); messages.push(PrefixTransportParams::generated_message_descriptor_data()); messages.push(GenericTransportParams::generated_message_descriptor_data()); messages.push(C2SWrapper::generated_message_descriptor_data());