Compare commits

..

12 Commits
v1.6.5 ... ax

Author SHA1 Message Date
Shelikhoo
64c2986853 Added experiment to avoid sending the termination signal
(cherry picked from commit c5357e1f000054ba5836468922cae52a830c8019)
2021-10-22 18:31:54 +08:00
Shelikhoo
778876df9e VMess AEAD based packet length
(cherry picked from commit 08221600082a79376bdc262f2ffec1a3129ae98d)
2021-10-22 18:30:30 +08:00
世界
5bf2b31883 Add hook to init and listen observatory statuses 2021-10-22 17:59:41 +08:00
世界
390a76ff61 Export instance context 2021-10-22 17:59:41 +08:00
世界
486f96838d Parse port in dns address 2021-10-22 17:59:41 +08:00
世界
710b283204 Add more default ttl 2021-10-22 17:59:41 +08:00
世界
073ba6f1c5 Add ApplySockopt 2021-10-22 17:59:41 +08:00
世界
a4f657f787 Remove unused 2021-10-22 17:59:40 +08:00
世界
ea94d07f65 Add domainStrategy to outbound &
Add preferIPv4/6 to domainStrategy
2021-10-22 17:59:27 +08:00
世界
14aa152a8a Add skipFakeDNS to inbound session 2021-10-22 17:59:26 +08:00
世界
e316cd4c66 Hook to replace DOHL dialer 2021-10-22 17:59:26 +08:00
世界
16d96aa54d Add uid and app status in routing rule 2021-10-22 17:59:26 +08:00
379 changed files with 2821 additions and 8629 deletions

View File

@@ -9,7 +9,3 @@ updates:
directory: "/" # Location of package manifests
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@@ -21,8 +21,6 @@ on:
- ".github/workflows/*.yml"
jobs:
build:
permissions:
contents: write
strategy:
matrix:
# Include amd64 on all platforms.
@@ -112,19 +110,20 @@ jobs:
CGO_ENABLED: 0
steps:
- name: Checkout codebase
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Show workflow information
id: get_filename
run: |
export _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json)
echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
echo "::set-output name=ASSET_NAME::$_NAME"
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v2
with:
go-version: 1.19
check-latest: true
go-version: ^1.17.2
- name: Get project dependencies
run: go mod download
@@ -143,11 +142,6 @@ jobs:
run: |
mkdir -p build_assets
go build -v -o build_assets/xray -trimpath -ldflags "-s -w -buildid=" ./main
- name: Build background Xray on Windows
if: matrix.goos == 'windows'
run: |
go build -v -o build_assets/wxray.exe -trimpath -ldflags "-s -w -H windowsgui -buildid=" ./main
- name: Build Mips softfloat Xray
if: matrix.goarch == 'mips' || matrix.goarch == 'mipsle'
@@ -182,9 +176,9 @@ jobs:
run: |
pushd build_assets || exit 1
touch -mt $(date +%Y01010000) *
zip -9vr ../Xray-${{ env.ASSET_NAME }}.zip .
zip -9vr ../Xray-$ASSET_NAME.zip .
popd || exit 1
FILE=./Xray-${{ env.ASSET_NAME }}.zip
FILE=./Xray-$ASSET_NAME.zip
DGST=$FILE.dgst
for METHOD in {"md5","sha1","sha256","sha512"}
do
@@ -193,20 +187,20 @@ jobs:
- name: Change the name
run: |
mv build_assets Xray-${{ env.ASSET_NAME }}
mv build_assets Xray-$ASSET_NAME
- name: Upload files to Artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v2
with:
name: Xray-${{ env.ASSET_NAME }}
name: Xray-${{ steps.get_filename.outputs.ASSET_NAME }}
path: |
./Xray-${{ env.ASSET_NAME }}/*
./Xray-${{ steps.get_filename.outputs.ASSET_NAME }}/*
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
if: github.event_name == 'release'
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./Xray-${{ env.ASSET_NAME }}.zip*
file: ./Xray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip*
tag: ${{ github.ref }}
file_glob: true

View File

@@ -19,8 +19,6 @@ on:
jobs:
test:
permissions:
contents: read
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -28,12 +26,11 @@ jobs:
os: [windows-latest, ubuntu-latest, macos-latest]
steps:
- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v2
with:
go-version: 1.19
check-latest: true
go-version: ^1.17.2
- name: Checkout codebase
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Prepare geo*dat
if: ${{ matrix.os != 'windows-latest' }}

4
.gitignore vendored
View File

@@ -18,11 +18,11 @@
.idea
*.zip
*.tar.gz
xray
v2ray
v2ctl
mockgen
vprotogen
!infra/vprotogen/
errorgen
!common/errors/errorgen/
*.dat
.vscode

View File

@@ -1,6 +1,6 @@
# Project X
[Project X](https://github.com/XTLS) originates from XTLS protocol, provides a set of network tools such as [Xray-core](https://github.com/XTLS/Xray-core).
[Project X](https://github.com/XTLS) originates from XTLS protocol, provides a set of network tools such as [Xray-core](https://github.com/XTLS/Xray-core) and [Xray-flutter](https://github.com/XTLS/Xray-flutter).
## License
@@ -13,6 +13,7 @@
- [Xray-script](https://github.com/kirin10000/Xray-script)
- Docker
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
- Xray-docker
- One Click
- [ProxySU](https://github.com/proxysu/ProxySU)
- [v2ray-agent](https://github.com/mack-a/v2ray-agent)
@@ -26,9 +27,6 @@
- [(Tap) Repository 0](https://github.com/N4FA/homebrew-xray)
- [(Tap) Repository 1](https://github.com/xiruizhao/homebrew-xray)
## Contributing
[Code Of Conduct](https://github.com/XTLS/Xray-core/blob/main/CODE_OF_CONDUCT.md)
## Usage
[Xray-examples](https://github.com/XTLS/Xray-examples) / [VLESS-TCP-XTLS-WHATEVER](https://github.com/XTLS/Xray-examples/tree/main/VLESS-TCP-XTLS-WHATEVER)
@@ -42,17 +40,16 @@
- [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray))
- Windows
- [v2rayN](https://github.com/2dust/v2rayN)
- [Qv2ray](https://github.com/Qv2ray/Qv2ray) (This project had been archived and currently inactive)
- [Netch (NetFilter & TUN/TAP)](https://github.com/NetchX/Netch) (This project had been archived and currently inactive)
- [Qv2ray](https://github.com/Qv2ray/Qv2ray) (This project had been archived and currently inactive)
- [Netch (NetFilter & TUN/TAP)](https://github.com/NetchX/Netch)
- Android
- [v2rayNG](https://github.com/2dust/v2rayNG)
- [AnXray](https://github.com/XTLS/AnXray)
- [Kitsunebi](https://github.com/rurirei/Kitsunebi/tree/release_xtls)
- iOS & macOS (with M1 chip)
- [Shadowrocket](https://apps.apple.com/app/shadowrocket/id932747118)
- [Stash](https://apps.apple.com/app/stash/id1596063349)
- macOS (Intel chip & M1 chip)
- [Qv2ray](https://github.com/Qv2ray/Qv2ray) (This project had been archived and currently inactive)
- [V2RayXS](https://github.com/tzmax/V2RayXS)
## Credits
@@ -61,30 +58,26 @@ This repo relies on the following third-party projects:
- Special thanks:
- [v2fly/v2ray-core](https://github.com/v2fly/v2ray-core)
- In production:
- [ghodss/yaml](https://github.com/ghodss/yaml)
- [gorilla/websocket](https://github.com/gorilla/websocket)
- [lucas-clemente/quic-go](https://github.com/lucas-clemente/quic-go)
- [pelletier/go-toml](https://github.com/pelletier/go-toml)
- [pires/go-proxyproto](https://github.com/pires/go-proxyproto)
- [refraction-networking/utls](https://github.com/refraction-networking/utls)
- [seiflotfy/cuckoofilter](https://github.com/seiflotfy/cuckoofilter)
- [google/starlark-go](https://github.com/google/starlark-go)
- For testing only:
- [miekg/dns](https://github.com/miekg/dns)
- [stretchr/testify](https://github.com/stretchr/testify)
- [h12w/socks](https://github.com/h12w/socks)
## Compilation
### Windows
```bash
```
go build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main
```
### Linux / macOS
```bash
```
go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
```

View File

@@ -7,11 +7,12 @@ import (
"net"
"sync"
"google.golang.org/grpc"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/signal/done"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/outbound"
"google.golang.org/grpc"
)
// Commander is a Xray feature that provides gRPC methods to external clients.

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/commander/config.proto

View File

@@ -37,7 +37,7 @@ func (l *OutboundListener) Accept() (net.Conn, error) {
}
}
// Close implements net.Listener.
// Close implement net.Listener.
func (l *OutboundListener) Close() error {
common.Must(l.done.Close())
L:

View File

@@ -3,9 +3,10 @@ package commander
import (
"context"
"github.com/xtls/xray-core/common"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"github.com/xtls/xray-core/common"
)
// Service is a Commander service.

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/dispatcher/config.proto

View File

@@ -4,7 +4,7 @@ package dispatcher
import (
"context"
"fmt"
"github.com/xtls/xray-core/features/dns"
"strings"
"sync"
"time"
@@ -16,7 +16,6 @@ import (
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/outbound"
"github.com/xtls/xray-core/features/policy"
"github.com/xtls/xray-core/features/routing"
@@ -93,17 +92,13 @@ type DefaultDispatcher struct {
router routing.Router
policy policy.Manager
stats stats.Manager
dns dns.Client
fdns dns.FakeDNSEngine
hosts dns.HostsLookup
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
d := new(DefaultDispatcher)
if err := core.RequireFeatures(ctx, func(om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager, dc dns.Client) error {
core.RequireFeatures(ctx, func(fdns dns.FakeDNSEngine) {
d.fdns = fdns
})
return d.Init(config.(*Config), om, router, pm, sm, dc)
}); err != nil {
return nil, err
@@ -113,12 +108,14 @@ func init() {
}
// Init initializes DefaultDispatcher.
func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager, dns dns.Client) error {
func (d *DefaultDispatcher) Init(config *Config, om outbound.Manager, router routing.Router, pm policy.Manager, sm stats.Manager, dc dns.Client) error {
d.ohm = om
d.router = router
d.policy = pm
d.stats = sm
d.dns = dns
if hosts, ok := dc.(dns.HostsLookup); ok {
d.hosts = hosts
}
return nil
}
@@ -135,77 +132,10 @@ func (*DefaultDispatcher) Start() error {
// Close implements common.Closable.
func (*DefaultDispatcher) Close() error { return nil }
func (d *DefaultDispatcher) getLink(ctx context.Context, network net.Network, sniffing session.SniffingRequest) (*transport.Link, *transport.Link) {
downOpt := pipe.OptionsFromContext(ctx)
upOpt := downOpt
if network == net.Network_UDP {
var ip2domain *sync.Map // net.IP.String() => domain, this map is used by server side when client turn on fakedns
// Client will send domain address in the buffer.UDP.Address, server record all possible target IP addrs.
// When target replies, server will restore the domain and send back to client.
// Note: this map is not global but per connection context
upOpt = append(upOpt, pipe.OnTransmission(func(mb buf.MultiBuffer) buf.MultiBuffer {
for i, buffer := range mb {
if buffer.UDP == nil {
continue
}
addr := buffer.UDP.Address
if addr.Family().IsIP() {
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && fkr0.IsIPInIPPool(addr) && sniffing.Enabled {
domain := fkr0.GetDomainFromFakeDNS(addr)
if len(domain) > 0 {
buffer.UDP.Address = net.DomainAddress(domain)
newError("[fakedns client] override with domain: ", domain, " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx))
} else {
newError("[fakedns client] failed to find domain! :", addr.String(), " for xUDP buffer at ", i).AtWarning().WriteToLog(session.ExportIDToError(ctx))
}
}
} else {
if ip2domain == nil {
ip2domain = new(sync.Map)
newError("[fakedns client] create a new map").WriteToLog(session.ExportIDToError(ctx))
}
domain := addr.Domain()
ips, err := d.dns.LookupIP(domain, dns.IPOption{true, true, false})
if err == nil {
for _, ip := range ips {
ip2domain.Store(ip.String(), domain)
}
newError("[fakedns client] candidate ip: "+fmt.Sprintf("%v", ips), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx))
} else {
newError("[fakedns client] failed to look up IP for ", domain, " for xUDP buffer at ", i).Base(err).WriteToLog(session.ExportIDToError(ctx))
}
}
}
return mb
}))
downOpt = append(downOpt, pipe.OnTransmission(func(mb buf.MultiBuffer) buf.MultiBuffer {
for i, buffer := range mb {
if buffer.UDP == nil {
continue
}
addr := buffer.UDP.Address
if addr.Family().IsIP() {
if ip2domain == nil {
continue
}
if domain, found := ip2domain.Load(addr.IP().String()); found {
buffer.UDP.Address = net.DomainAddress(domain.(string))
newError("[fakedns client] restore domain: ", domain.(string), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx))
}
} else {
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok {
fakeIp := fkr0.GetFakeIPForDomain(addr.Domain())
buffer.UDP.Address = fakeIp[0]
newError("[fakedns client] restore FakeIP: ", buffer.UDP, fmt.Sprintf("%v", fakeIp), " for xUDP buffer at ", i).WriteToLog(session.ExportIDToError(ctx))
}
}
}
return mb
}))
}
uplinkReader, uplinkWriter := pipe.New(upOpt...)
downlinkReader, downlinkWriter := pipe.New(downOpt...)
func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *transport.Link) {
opt := pipe.OptionsFromContext(ctx)
uplinkReader, uplinkWriter := pipe.New(opt...)
downlinkReader, downlinkWriter := pipe.New(opt...)
inboundLink := &transport.Link{
Reader: downlinkReader,
@@ -248,16 +178,17 @@ func (d *DefaultDispatcher) getLink(ctx context.Context, network net.Network, sn
return inboundLink, outboundLink
}
func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResult, request session.SniffingRequest, destination net.Destination) bool {
func shouldOverride(ctx context.Context, result SniffResult, request session.SniffingRequest, destination net.Destination) bool {
domain := result.Domain()
if domain == "" {
return false
}
for _, d := range request.ExcludeForDomain {
if strings.ToLower(domain) == d {
return false
}
}
var fakeDNSEngine dns.FakeDNSEngine
core.RequireFeatures(ctx, func(fdns dns.FakeDNSEngine) {
fakeDNSEngine = fdns
})
protocolString := result.Protocol()
if resComp, ok := result.(SnifferResultComposite); ok {
protocolString = resComp.ProtocolForDomainResult()
@@ -266,7 +197,7 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
if strings.HasPrefix(protocolString, p) {
return true
}
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
destination.Address.Family().IsIP() && fkr0.IsIPInIPPool(destination.Address) {
newError("Using sniffer ", protocolString, " since the fake DNS missed").WriteToLog(session.ExportIDToError(ctx))
return true
@@ -290,27 +221,45 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
Target: destination,
}
ctx = session.ContextWithOutbound(ctx, ob)
inbound, outbound := d.getLink(ctx)
content := session.ContentFromContext(ctx)
if content == nil {
content = new(session.Content)
ctx = session.ContextWithContent(ctx, content)
}
sniffingRequest := content.SniffingRequest
inbound, outbound := d.getLink(ctx, destination.Network, sniffingRequest)
if !sniffingRequest.Enabled {
switch {
case !sniffingRequest.Enabled:
go d.routedDispatch(ctx, outbound, destination)
} else {
case destination.Network != net.Network_TCP:
// Only metadata sniff will be used for non tcp connection
result, err := sniffer(ctx, nil, true)
if err == nil {
content.Protocol = result.Protocol()
if shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain()
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain)
if sniffingRequest.RouteOnly && result.Protocol() != "fakedns" {
ob.RouteTarget = destination
} else {
ob.Target = destination
}
}
}
go d.routedDispatch(ctx, outbound, destination)
default:
go func() {
cReader := &cachedReader{
reader: outbound.Reader.(*pipe.Reader),
}
outbound.Reader = cReader
result, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly, destination.Network)
result, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly)
if err == nil {
content.Protocol = result.Protocol()
}
if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
if err == nil && shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain()
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain)
@@ -341,19 +290,37 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De
ctx = session.ContextWithContent(ctx, content)
}
sniffingRequest := content.SniffingRequest
if !sniffingRequest.Enabled {
switch {
case !sniffingRequest.Enabled:
go d.routedDispatch(ctx, outbound, destination)
} else {
case destination.Network != net.Network_TCP:
// Only metadata sniff will be used for non tcp connection
result, err := sniffer(ctx, nil, true)
if err == nil {
content.Protocol = result.Protocol()
if shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain()
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain)
if sniffingRequest.RouteOnly && result.Protocol() != "fakedns" {
ob.RouteTarget = destination
} else {
ob.Target = destination
}
}
}
go d.routedDispatch(ctx, outbound, destination)
default:
go func() {
cReader := &cachedReader{
reader: outbound.Reader.(*pipe.Reader),
}
outbound.Reader = cReader
result, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly, destination.Network)
result, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly)
if err == nil {
content.Protocol = result.Protocol()
}
if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
if err == nil && shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain()
newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain)
@@ -366,11 +333,10 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De
d.routedDispatch(ctx, outbound, destination)
}()
}
return nil
}
func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, network net.Network) (SniffResult, error) {
func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool) (SniffResult, error) {
payload := buf.New()
defer payload.Release()
@@ -396,7 +362,7 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
cReader.Cache(payload)
if !payload.IsEmpty() {
result, err := sniffer.Sniff(ctx, payload.Bytes(), network)
result, err := sniffer.Sniff(ctx, payload.Bytes())
if err != common.ErrNoClue {
return result, err
}
@@ -418,8 +384,8 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
ob := session.OutboundFromContext(ctx)
if hosts, ok := d.dns.(dns.HostsLookup); ok && destination.Address.Family().IsDomain() {
proxied := hosts.LookupHosts(ob.Target.String())
if d.hosts != nil && destination.Address.Family().IsDomain() {
proxied := d.hosts.LookupHosts(ob.Target.String())
if proxied != nil {
ro := ob.RouteTarget == destination
destination.Address = *proxied
@@ -433,13 +399,9 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
var handler outbound.Handler
routingLink := routing_session.AsRoutingContext(ctx)
inTag := routingLink.GetInboundTag()
isPickRoute := 0
if forcedOutboundTag := session.GetForcedOutboundTagFromContext(ctx); forcedOutboundTag != "" {
ctx = session.SetForcedOutboundTagToContext(ctx, "")
if h := d.ohm.GetHandler(forcedOutboundTag); h != nil {
isPickRoute = 1
newError("taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
handler = h
} else {
@@ -449,14 +411,13 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
return
}
} else if d.router != nil {
if route, err := d.router.PickRoute(routingLink); err == nil {
outTag := route.GetOutboundTag()
if h := d.ohm.GetHandler(outTag); h != nil {
isPickRoute = 2
newError("taking detour [", outTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
if route, err := d.router.PickRoute(routing_session.AsRoutingContext(ctx)); err == nil {
tag := route.GetOutboundTag()
if h := d.ohm.GetHandler(tag); h != nil {
newError("taking detour [", tag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
handler = h
} else {
newError("non existing outTag: ", outTag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
newError("non existing outTag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
}
} else {
newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx))
@@ -476,15 +437,7 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil {
if tag := handler.Tag(); tag != "" {
if inTag == "" {
accessMessage.Detour = tag
} else if isPickRoute == 1 {
accessMessage.Detour = inTag + " ==> " + tag
} else if isPickRoute == 2 {
accessMessage.Detour = inTag + " -> " + tag
} else {
accessMessage.Detour = inTag + " >> " + tag
}
accessMessage.Detour = tag
}
log.Record(accessMessage)
}

View File

@@ -11,16 +11,15 @@ import (
"github.com/xtls/xray-core/features/dns"
)
// newFakeDNSSniffer Creates a Fake DNS metadata sniffer
// newFakeDNSSniffer Create a Fake DNS metadata sniffer
func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) {
var fakeDNSEngine dns.FakeDNSEngine
{
fakeDNSEngineFeat := core.MustFromContext(ctx).GetFeature((*dns.FakeDNSEngine)(nil))
if fakeDNSEngineFeat != nil {
fakeDNSEngine = fakeDNSEngineFeat.(dns.FakeDNSEngine)
}
err := core.RequireFeatures(ctx, func(fdns dns.FakeDNSEngine) {
fakeDNSEngine = fdns
})
if err != nil {
return protocolSnifferWithMetadata{}, err
}
if fakeDNSEngine == nil {
errNotInit := newError("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
return protocolSnifferWithMetadata{}, errNotInit
@@ -85,8 +84,7 @@ func (f DNSThenOthersSniffResult) Domain() string {
}
func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWithMetadata, others []protocolSnifferWithMetadata) (
protocolSnifferWithMetadata, error,
) { // nolint: unparam
protocolSnifferWithMetadata, error) { // nolint: unparam
// ctx may be used in the future
_ = ctx
return protocolSnifferWithMetadata{

View File

@@ -4,10 +4,8 @@ import (
"context"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol/bittorrent"
"github.com/xtls/xray-core/common/protocol/http"
"github.com/xtls/xray-core/common/protocol/quic"
"github.com/xtls/xray-core/common/protocol/tls"
)
@@ -24,7 +22,6 @@ type protocolSnifferWithMetadata struct {
// for both TCP and UDP connections
// It will not be shown as a traffic type for routing unless there is no other successful sniffing.
metadataSniffer bool
network net.Network
}
type Sniffer struct {
@@ -34,11 +31,9 @@ type Sniffer struct {
func NewSniffer(ctx context.Context) *Sniffer {
ret := &Sniffer{
sniffer: []protocolSnifferWithMetadata{
{func(c context.Context, b []byte) (SniffResult, error) { return http.SniffHTTP(b) }, false, net.Network_TCP},
{func(c context.Context, b []byte) (SniffResult, error) { return tls.SniffTLS(b) }, false, net.Network_TCP},
{func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) }, false, net.Network_TCP},
{func(c context.Context, b []byte) (SniffResult, error) { return quic.SniffQUIC(b) }, false, net.Network_UDP},
{func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffUTP(b) }, false, net.Network_UDP},
{func(c context.Context, b []byte) (SniffResult, error) { return http.SniffHTTP(b) }, false},
{func(c context.Context, b []byte) (SniffResult, error) { return tls.SniffTLS(b) }, false},
{func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) }, false},
},
}
if sniffer, err := newFakeDNSSniffer(ctx); err == nil {
@@ -54,11 +49,11 @@ func NewSniffer(ctx context.Context) *Sniffer {
var errUnknownContent = newError("unknown content")
func (s *Sniffer) Sniff(c context.Context, payload []byte, network net.Network) (SniffResult, error) {
func (s *Sniffer) Sniff(c context.Context, payload []byte) (SniffResult, error) {
var pendingSniffer []protocolSnifferWithMetadata
for _, si := range s.sniffer {
s := si.protocolSniffer
if si.metadataSniffer || si.network != network {
if si.metadataSniffer {
continue
}
result, err := s(c, payload)

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/dns/config.proto

View File

@@ -1,22 +1,19 @@
package dns
import (
"context"
"encoding/binary"
"strings"
"time"
"golang.org/x/net/dns/dnsmessage"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core"
dns_feature "github.com/xtls/xray-core/features/dns"
"golang.org/x/net/dns/dnsmessage"
)
// Fqdn normalizes domain make sure it ends with '.'
// Fqdn normalize domain make sure it ends with '.'
func Fqdn(domain string) string {
if len(domain) > 0 && strings.HasSuffix(domain, ".") {
return domain
@@ -166,7 +163,7 @@ func buildReqMsgs(domain string, option dns_feature.IPOption, reqIDGen func() ui
return reqs
}
// parseResponse parses DNS answers from the returned payload
// parseResponse parse DNS answers from the returned payload
func parseResponse(payload []byte) (*IPRecord, error) {
var parser dnsmessage.Parser
h, err := parser.Start(payload)
@@ -181,7 +178,7 @@ func parseResponse(payload []byte) (*IPRecord, error) {
ipRecord := &IPRecord{
ReqID: h.ID,
RCode: h.RCode,
Expire: now.Add(time.Second * 600),
Expire: now.Add(time.Minute * 30),
}
L:
@@ -229,19 +226,3 @@ L:
return ipRecord, nil
}
// toDnsContext create a new background context with parent inbound, session and dns log
func toDnsContext(ctx context.Context, addr string) context.Context {
dnsCtx := core.ToBackgroundDetachedContext(ctx)
if inbound := session.InboundFromContext(ctx); inbound != nil {
dnsCtx = session.ContextWithInbound(dnsCtx, inbound)
}
dnsCtx = session.ContextWithContent(dnsCtx, session.ContentFromContext(ctx))
dnsCtx = log.ContextWithAccessMessage(dnsCtx, &log.AccessMessage{
From: "DNS",
To: addr,
Status: log.AccessAccepted,
Reason: "",
})
return dnsCtx
}

View File

@@ -7,10 +7,11 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/miekg/dns"
"golang.org/x/net/dns/dnsmessage"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
dns_feature "github.com/xtls/xray-core/features/dns"
"golang.org/x/net/dns/dnsmessage"
)
func Test_parseResponse(t *testing.T) {

View File

@@ -5,7 +5,6 @@ import (
"math"
"math/big"
gonet "net"
"sync"
"time"
"github.com/xtls/xray-core/common"
@@ -17,7 +16,6 @@ import (
type Holder struct {
domainToIP cache.Lru
ipRange *gonet.IPNet
mu *sync.Mutex
config *FakeDnsPool
}
@@ -51,7 +49,6 @@ func (fkdns *Holder) Start() error {
func (fkdns *Holder) Close() error {
fkdns.domainToIP = nil
fkdns.ipRange = nil
fkdns.mu = nil
return nil
}
@@ -70,7 +67,7 @@ func NewFakeDNSHolder() (*Holder, error) {
}
func NewFakeDNSHolderConfigOnly(conf *FakeDnsPool) (*Holder, error) {
return &Holder{nil, nil, nil, conf}, nil
return &Holder{nil, nil, conf}, nil
}
func (fkdns *Holder) initializeFromConfig() error {
@@ -92,14 +89,11 @@ func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
}
fkdns.domainToIP = cache.NewLru(lruSize)
fkdns.ipRange = ipRange
fkdns.mu = new(sync.Mutex)
return nil
}
// GetFakeIPForDomain checks and generates a fake IP for a domain name
// GetFakeIPForDomain check and generate a fake IP for a domain name
func (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address {
fkdns.mu.Lock()
defer fkdns.mu.Unlock()
if v, ok := fkdns.domainToIP.Get(domain); ok {
return []net.Address{v.(net.Address)}
}
@@ -129,7 +123,7 @@ func (fkdns *Holder) GetFakeIPForDomain(domain string) []net.Address {
return []net.Address{ip}
}
// GetDomainFromFakeDNS checks if an IP is a fake IP and have corresponding domain name
// GetDomainFromFakeDNS check if an IP is a fake IP and have corresponding domain name
func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string {
if !ip.Family().IsIP() || !fkdns.ipRange.Contains(ip.IP()) {
return ""

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/dns/fakedns/fakedns.proto

View File

@@ -1,16 +1,16 @@
package fakedns
import (
gonet "net"
"strconv"
"testing"
gonet "net"
"github.com/stretchr/testify/assert"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/uuid"
"github.com/xtls/xray-core/features/dns"
"golang.org/x/sync/errgroup"
)
var ipPrefix = "198.1"
@@ -67,31 +67,6 @@ func TestFakeDnsHolderCreateMappingManySingleDomain(t *testing.T) {
assert.Equal(t, addr[0].IP().String(), addr2[0].IP().String())
}
func TestGetFakeIPForDomainConcurrently(t *testing.T) {
fkdns, err := NewFakeDNSHolder()
common.Must(err)
total := 200
addr := make([][]net.Address, total)
var errg errgroup.Group
for i := 0; i < total; i++ {
errg.Go(testGetFakeIP(i, addr, fkdns))
}
errg.Wait()
for i := 0; i < total; i++ {
for j := i + 1; j < total; j++ {
assert.NotEqual(t, addr[i][0].IP().String(), addr[j][0].IP().String())
}
}
}
func testGetFakeIP(index int, addr [][]net.Address, fkdns *Holder) func() error {
return func() error {
addr[index] = fkdns.GetFakeIPForDomain("fakednstest" + strconv.Itoa(index) + ".example.com")
return nil
}
}
func TestFakeDnsHolderCreateMappingAndRollOver(t *testing.T) {
fkdns, err := NewFakeDNSHolderConfigOnly(&FakeDnsPool{
IpPool: dns.FakeIPv4Pool,
@@ -173,31 +148,31 @@ func TestFakeDNSMulti(t *testing.T) {
})
t.Run("allocateTwoAddressForTwoPool", func(t *testing.T) {
address := fakeMulti.GetFakeIPForDomain("fakednstest.example.com")
address := fakeMulti.GetFakeIPForDomain("fakednstest.v2fly.org")
assert.Len(t, address, 2, "should be 2 address one for each pool")
t.Run("eachOfThemShouldResolve:0", func(t *testing.T) {
domain := fakeMulti.GetDomainFromFakeDNS(address[0])
assert.Equal(t, "fakednstest.example.com", domain)
assert.Equal(t, "fakednstest.v2fly.org", domain)
})
t.Run("eachOfThemShouldResolve:1", func(t *testing.T) {
domain := fakeMulti.GetDomainFromFakeDNS(address[1])
assert.Equal(t, "fakednstest.example.com", domain)
assert.Equal(t, "fakednstest.v2fly.org", domain)
})
})
t.Run("understandIPTypeSelector", func(t *testing.T) {
t.Run("ipv4", func(t *testing.T) {
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv4.example.com", true, false)
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv4.v2fly.org", true, false)
assert.Len(t, address, 1, "should be 1 address")
assert.True(t, address[0].Family().IsIPv4())
})
t.Run("ipv6", func(t *testing.T) {
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv6.example.com", false, true)
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv6.v2fly.org", false, true)
assert.Len(t, address, 1, "should be 1 address")
assert.True(t, address[0].Family().IsIPv6())
})
t.Run("ipv46", func(t *testing.T) {
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv46.example.com", true, true)
address := fakeMulti.GetFakeIPForDomain3("fakednstestipv46.v2fly.org", true, true)
assert.Len(t, address, 2, "should be 2 address")
assert.True(t, address[0].Family().IsIPv4())
assert.True(t, address[1].Family().IsIPv6())

View File

@@ -186,7 +186,7 @@ func (c *Client) Name() string {
return c.server.Name()
}
// QueryIP sends DNS query to the name server with the client's IP.
// QueryIP send DNS query to the name server with the client's IP.
func (c *Client) QueryIP(ctx context.Context, domain string, option dns.IPOption, disableCache bool) ([]net.IP, error) {
ctx, cancel := context.WithTimeout(ctx, 4*time.Second)
ips, err := c.server.QueryIP(ctx, domain, c.clientIP, option, disableCache)

View File

@@ -11,6 +11,8 @@ import (
"sync/atomic"
"time"
"golang.org/x/net/dns/dnsmessage"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
@@ -22,7 +24,6 @@ import (
dns_feature "github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/transport/internet"
"golang.org/x/net/dns/dnsmessage"
)
// DoHNameServer implemented DNS over HTTPS (RFC8484) Wire Format,
@@ -52,11 +53,23 @@ func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher) (*DoHNameServ
TLSHandshakeTimeout: 30 * time.Second,
ForceAttemptHTTP2: true,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
dispatcherCtx := context.Background()
dest, err := net.ParseDestination(network + ":" + addr)
if err != nil {
return nil, err
}
link, err := s.dispatcher.Dispatch(toDnsContext(ctx, s.dohURL), dest)
dispatcherCtx = session.ContextWithContent(dispatcherCtx, session.ContentFromContext(ctx))
dispatcherCtx = session.ContextWithInbound(dispatcherCtx, session.InboundFromContext(ctx))
dispatcherCtx = log.ContextWithAccessMessage(dispatcherCtx, &log.AccessMessage{
From: "DoH",
To: s.dohURL,
Status: log.AccessAccepted,
Reason: "",
})
link, err := s.dispatcher.Dispatch(dispatcherCtx, dest)
select {
case <-ctx.Done():
return nil, ctx.Err()
@@ -101,9 +114,9 @@ func NewDoHLocalNameServer(url *url.URL) *DoHNameServer {
if err != nil {
return nil, err
}
conn, err := internet.DialSystem(ctx, dest, nil)
conn, err := internet.DialSystemDNS(ctx, dest, nil)
log.Record(&log.AccessMessage{
From: "DNS",
From: "DoH",
To: s.dohURL,
Status: log.AccessAccepted,
Detour: "local",

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
. "github.com/xtls/xray-core/app/dns"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"

View File

@@ -3,11 +3,10 @@ package dns
import (
"context"
"strings"
"time"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns/localdns"
)
@@ -20,7 +19,6 @@ const errEmptyResponse = "No address associated with hostname"
// QueryIP implements Server.
func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) {
start := time.Now()
ips, err = s.client.LookupIP(domain, option)
if err != nil && strings.HasSuffix(err.Error(), errEmptyResponse) {
@@ -29,7 +27,6 @@ func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, op
if len(ips) > 0 {
newError("Localhost got answer: ", domain, " -> ", ips).AtInfo().WriteToLog()
log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
}
return

View File

@@ -5,9 +5,10 @@ import (
"testing"
"time"
"github.com/xtls/xray-core/common/net"
. "github.com/xtls/xray-core/app/dns"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns"
)

View File

@@ -10,7 +10,6 @@ import (
"github.com/lucas-clemente/quic-go"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol/dns"
"github.com/xtls/xray-core/common/session"
@@ -37,7 +36,7 @@ type QUICNameServer struct {
reqID uint32
name string
destination *net.Destination
connection quic.Connection
session quic.Session
}
// NewQUICNameServer creates DNS-over-QUIC client object for local resolving
@@ -194,7 +193,7 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
conn, err := s.openStream(dnsCtx)
if err != nil {
newError("failed to open quic connection").Base(err).AtError().WriteToLog()
newError("failed to open quic session").Base(err).AtError().WriteToLog()
return
}
@@ -276,7 +275,6 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
ips, err := s.findIPsForDomain(fqdn, option)
if err != errRecordNotFound {
newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err
}
}
@@ -308,12 +306,10 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
close(done)
}()
s.sendQuery(ctx, fqdn, clientIP, option)
start := time.Now()
for {
ips, err := s.findIPsForDomain(fqdn, option)
if err != errRecordNotFound {
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
return ips, err
}
@@ -325,7 +321,7 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
}
}
func isActive(s quic.Connection) bool {
func isActive(s quic.Session) bool {
select {
case <-s.Context().Done():
return false
@@ -334,17 +330,17 @@ func isActive(s quic.Connection) bool {
}
}
func (s *QUICNameServer) getConnection() (quic.Connection, error) {
var conn quic.Connection
func (s *QUICNameServer) getSession() (quic.Session, error) {
var session quic.Session
s.RLock()
conn = s.connection
if conn != nil && isActive(conn) {
session = s.session
if session != nil && isActive(session) {
s.RUnlock()
return conn, nil
return session, nil
}
if conn != nil {
// we're recreating the connection, let's create a new one
_ = conn.CloseWithError(0, "")
if session != nil {
// we're recreating the session, let's create a new one
_ = session.CloseWithError(0, "")
}
s.RUnlock()
@@ -352,48 +348,42 @@ func (s *QUICNameServer) getConnection() (quic.Connection, error) {
defer s.Unlock()
var err error
conn, err = s.openConnection()
session, err = s.openSession()
if err != nil {
// This does not look too nice, but QUIC (or maybe quic-go)
// doesn't seem stable enough.
// Maybe retransmissions aren't fully implemented in quic-go?
// Anyways, the simple solution is to make a second try when
// it fails to open the QUIC connection.
conn, err = s.openConnection()
// it fails to open the QUIC session.
session, err = s.openSession()
if err != nil {
return nil, err
}
}
s.connection = conn
return conn, nil
s.session = session
return session, nil
}
func (s *QUICNameServer) openConnection() (quic.Connection, error) {
func (s *QUICNameServer) openSession() (quic.Session, error) {
tlsConfig := tls.Config{}
quicConfig := &quic.Config{
HandshakeIdleTimeout: handshakeTimeout,
}
conn, err := quic.DialAddrContext(context.Background(), s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto("http/1.1", http2.NextProtoTLS, NextProtoDQ)), quicConfig)
log.Record(&log.AccessMessage{
From: "DNS",
To: s.destination,
Status: log.AccessAccepted,
Detour: "local",
})
session, err := quic.DialAddrContext(context.Background(), s.destination.NetAddr(), tlsConfig.GetTLSConfig(tls.WithNextProto("http/1.1", http2.NextProtoTLS, NextProtoDQ)), quicConfig)
if err != nil {
return nil, err
}
return conn, nil
return session, nil
}
func (s *QUICNameServer) openStream(ctx context.Context) (quic.Stream, error) {
conn, err := s.getConnection()
session, err := s.getSession()
if err != nil {
return nil, err
}
// open a new stream
return conn.OpenStreamSync(ctx)
return session.OpenStreamSync(ctx)
}

View File

@@ -6,11 +6,13 @@ import (
"testing"
"time"
"github.com/xtls/xray-core/features/dns"
"github.com/google/go-cmp/cmp"
. "github.com/xtls/xray-core/app/dns"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns"
)
func TestQUICNameServer(t *testing.T) {

View File

@@ -9,9 +9,10 @@ import (
"sync/atomic"
"time"
"golang.org/x/net/dns/dnsmessage"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/common/protocol/dns"
@@ -21,7 +22,6 @@ import (
dns_feature "github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/transport/internet"
"golang.org/x/net/dns/dnsmessage"
)
// TCPNameServer implemented DNS over TCP (RFC7766).
@@ -44,7 +44,7 @@ func NewTCPNameServer(url *url.URL, dispatcher routing.Dispatcher) (*TCPNameServ
}
s.dial = func(ctx context.Context) (net.Conn, error) {
link, err := dispatcher.Dispatch(toDnsContext(ctx, s.destination.String()), *s.destination)
link, err := dispatcher.Dispatch(ctx, *s.destination)
if err != nil {
return nil, err
}
@@ -315,7 +315,6 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net
ips, err := s.findIPsForDomain(fqdn, option)
if err != errRecordNotFound {
newError(s.name, " cache HIT ", domain, " -> ", ips).Base(err).AtDebug().WriteToLog()
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err
}
}
@@ -347,12 +346,10 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net
close(done)
}()
s.sendQuery(ctx, fqdn, clientIP, option)
start := time.Now()
for {
ips, err := s.findIPsForDomain(fqdn, option)
if err != errRecordNotFound {
log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
return ips, err
}

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/google/go-cmp/cmp"
. "github.com/xtls/xray-core/app/dns"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"

View File

@@ -7,6 +7,8 @@ import (
"sync/atomic"
"time"
"golang.org/x/net/dns/dnsmessage"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net"
@@ -18,7 +20,6 @@ import (
dns_feature "github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/transport/internet/udp"
"golang.org/x/net/dns/dnsmessage"
)
// ClassicNameServer implemented traditional UDP DNS.
@@ -194,7 +195,21 @@ func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, client
for _, req := range reqs {
s.addPendingRequest(req)
b, _ := dns.PackMessage(req.msg)
s.udpServer.Dispatch(toDnsContext(ctx, s.address.String()), *s.address, b)
udpCtx := context.Background()
if inbound := session.InboundFromContext(ctx); inbound != nil {
udpCtx = session.ContextWithInbound(udpCtx, inbound)
}
udpCtx = session.ContextWithContent(udpCtx, &session.Content{
Protocol: "dns",
})
udpCtx = log.ContextWithAccessMessage(udpCtx, &log.AccessMessage{
From: "DNS",
To: s.address,
Status: log.AccessAccepted,
Reason: "",
})
s.udpServer.Dispatch(udpCtx, *s.address, b)
}
}

View File

@@ -5,10 +5,11 @@ package command
import (
"context"
grpc "google.golang.org/grpc"
"github.com/xtls/xray-core/app/log"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/core"
grpc "google.golang.org/grpc"
)
type LoggerServer struct {

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/log/command/config.proto

View File

@@ -1,8 +1,4 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.18.0
// source: app/log/command/config.proto
package command

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/log/config.proto

View File

@@ -2,7 +2,7 @@ package log
import (
"sync"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/log"
)

View File

@@ -5,6 +5,7 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/xtls/xray-core/app/log"
"github.com/xtls/xray-core/common"
clog "github.com/xtls/xray-core/common/log"

View File

@@ -1,149 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v3.18.0
// source: app/metrics/config.proto
package metrics
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Config is the settings for metrics.
type Config struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Tag of the outbound handler that handles metrics http connections.
Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
}
func (x *Config) Reset() {
*x = Config{}
if protoimpl.UnsafeEnabled {
mi := &file_app_metrics_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_metrics_config_proto_msgTypes[0]
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 Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
return file_app_metrics_config_proto_rawDescGZIP(), []int{0}
}
func (x *Config) GetTag() string {
if x != nil {
return x.Tag
}
return ""
}
var File_app_metrics_config_proto protoreflect.FileDescriptor
var file_app_metrics_config_proto_rawDesc = []byte{
0x0a, 0x18, 0x61, 0x70, 0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x63, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x1a, 0x0a, 0x06,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x42, 0x52, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78,
0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70,
0x70, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0xaa, 0x02, 0x10, 0x58, 0x72, 0x61, 0x79,
0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_app_metrics_config_proto_rawDescOnce sync.Once
file_app_metrics_config_proto_rawDescData = file_app_metrics_config_proto_rawDesc
)
func file_app_metrics_config_proto_rawDescGZIP() []byte {
file_app_metrics_config_proto_rawDescOnce.Do(func() {
file_app_metrics_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_metrics_config_proto_rawDescData)
})
return file_app_metrics_config_proto_rawDescData
}
var file_app_metrics_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_app_metrics_config_proto_goTypes = []interface{}{
(*Config)(nil), // 0: xray.app.metrics.Config
}
var file_app_metrics_config_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_app_metrics_config_proto_init() }
func file_app_metrics_config_proto_init() {
if File_app_metrics_config_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_app_metrics_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Config); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_metrics_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_app_metrics_config_proto_goTypes,
DependencyIndexes: file_app_metrics_config_proto_depIdxs,
MessageInfos: file_app_metrics_config_proto_msgTypes,
}.Build()
File_app_metrics_config_proto = out.File
file_app_metrics_config_proto_rawDesc = nil
file_app_metrics_config_proto_goTypes = nil
file_app_metrics_config_proto_depIdxs = nil
}

View File

@@ -1,13 +0,0 @@
syntax = "proto3";
package xray.app.metrics;
option csharp_namespace = "Xray.App.Metrics";
option go_package = "github.com/xtls/xray-core/app/metrics";
option java_package = "com.xray.app.metrics";
option java_multiple_files = true;
// Config is the settings for metrics.
message Config {
// Tag of the outbound handler that handles metrics http connections.
string tag = 1;
}

View File

@@ -1,9 +0,0 @@
package metrics
import "github.com/xtls/xray-core/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@@ -1,118 +0,0 @@
package metrics
import (
"context"
"expvar"
"net/http"
_ "net/http/pprof"
"strings"
"github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/app/stats"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/signal/done"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/extension"
"github.com/xtls/xray-core/features/outbound"
feature_stats "github.com/xtls/xray-core/features/stats"
)
type MetricsHandler struct {
ohm outbound.Manager
statsManager feature_stats.Manager
observatory extension.Observatory
tag string
}
// NewMetricsHandler creates a new MetricsHandler based on the given config.
func NewMetricsHandler(ctx context.Context, config *Config) (*MetricsHandler, error) {
c := &MetricsHandler{
tag: config.Tag,
}
common.Must(core.RequireFeatures(ctx, func(om outbound.Manager, sm feature_stats.Manager) {
c.statsManager = sm
c.ohm = om
}))
expvar.Publish("stats", expvar.Func(func() interface{} {
manager, ok := c.statsManager.(*stats.Manager)
if !ok {
return nil
}
resp := map[string]map[string]map[string]int64{
"inbound": {},
"outbound": {},
"user": {},
}
manager.VisitCounters(func(name string, counter feature_stats.Counter) bool {
nameSplit := strings.Split(name, ">>>")
typeName, tagOrUser, direction := nameSplit[0], nameSplit[1], nameSplit[3]
if item, found := resp[typeName][tagOrUser]; found {
item[direction] = counter.Value()
} else {
resp[typeName][tagOrUser] = map[string]int64{
direction: counter.Value(),
}
}
return true
})
return resp
}))
expvar.Publish("observatory", expvar.Func(func() interface{} {
if c.observatory == nil {
common.Must(core.RequireFeatures(ctx, func(observatory extension.Observatory) error {
c.observatory = observatory
return nil
}))
if c.observatory == nil {
return nil
}
}
resp := map[string]*observatory.OutboundStatus{}
if o, err := c.observatory.GetObservation(context.Background()); err != nil {
return err
} else {
for _, x := range o.(*observatory.ObservationResult).GetStatus() {
resp[x.OutboundTag] = x
}
}
return resp
}))
return c, nil
}
func (p *MetricsHandler) Type() interface{} {
return (*MetricsHandler)(nil)
}
func (p *MetricsHandler) Start() error {
listener := &OutboundListener{
buffer: make(chan net.Conn, 4),
done: done.New(),
}
go func() {
if err := http.Serve(listener, http.DefaultServeMux); err != nil {
newError("failed to start metrics server").Base(err).AtError().WriteToLog()
}
}()
if err := p.ohm.RemoveHandler(context.Background(), p.tag); err != nil {
newError("failed to remove existing handler").WriteToLog()
}
return p.ohm.AddHandler(context.Background(), &Outbound{
tag: p.tag,
listener: listener,
})
}
func (p *MetricsHandler) Close() error {
return nil
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
return NewMetricsHandler(ctx, cfg.(*Config))
}))
}

View File

@@ -1,109 +0,0 @@
package metrics
import (
"context"
"sync"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/common/signal/done"
"github.com/xtls/xray-core/transport"
)
// OutboundListener is a net.Listener for listening metrics http connections.
type OutboundListener struct {
buffer chan net.Conn
done *done.Instance
}
func (l *OutboundListener) add(conn net.Conn) {
select {
case l.buffer <- conn:
case <-l.done.Wait():
conn.Close()
default:
conn.Close()
}
}
// Accept implements net.Listener.
func (l *OutboundListener) Accept() (net.Conn, error) {
select {
case <-l.done.Wait():
return nil, newError("listen closed")
case c := <-l.buffer:
return c, nil
}
}
// Close implement net.Listener.
func (l *OutboundListener) Close() error {
common.Must(l.done.Close())
L:
for {
select {
case c := <-l.buffer:
c.Close()
default:
break L
}
}
return nil
}
// Addr implements net.Listener.
func (l *OutboundListener) Addr() net.Addr {
return &net.TCPAddr{
IP: net.IP{0, 0, 0, 0},
Port: 0,
}
}
// Outbound is an outbound.Handler that handles metrics http connections.
type Outbound struct {
tag string
listener *OutboundListener
access sync.RWMutex
closed bool
}
// Dispatch implements outbound.Handler.
func (co *Outbound) Dispatch(ctx context.Context, link *transport.Link) {
co.access.RLock()
if co.closed {
common.Interrupt(link.Reader)
common.Interrupt(link.Writer)
co.access.RUnlock()
return
}
closeSignal := done.New()
c := cnc.NewConnection(cnc.ConnectionInputMulti(link.Writer), cnc.ConnectionOutputMulti(link.Reader), cnc.ConnectionOnClose(closeSignal))
co.listener.add(c)
co.access.RUnlock()
<-closeSignal.Wait()
}
// Tag implements outbound.Handler.
func (co *Outbound) Tag() string {
return co.tag
}
// Start implements common.Runnable.
func (co *Outbound) Start() error {
co.access.Lock()
co.closed = false
co.access.Unlock()
return nil
}
// Close implements common.Closable.
func (co *Outbound) Close() error {
co.access.Lock()
defer co.access.Unlock()
co.closed = true
return co.listener.Close()
}

View File

@@ -1,50 +0,0 @@
//go:build !confonly
// +build !confonly
package command
import (
"context"
"github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/common"
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/extension"
"google.golang.org/grpc"
)
type service struct {
UnimplementedObservatoryServiceServer
v *core.Instance
observatory extension.Observatory
}
func (s *service) GetOutboundStatus(ctx context.Context, request *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) {
resp, err := s.observatory.GetObservation(ctx)
if err != nil {
return nil, err
}
retdata := resp.(*observatory.ObservationResult)
return &GetOutboundStatusResponse{
Status: retdata,
}, nil
}
func (s *service) Register(server *grpc.Server) {
RegisterObservatoryServiceServer(server, s)
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
s := core.MustFromContext(ctx)
sv := &service{v: s}
err := s.RequireFeatures(func(Observatory extension.Observatory) {
sv.observatory = Observatory
})
if err != nil {
return nil, err
}
return sv, nil
}))
}

View File

@@ -1,278 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc v3.18.0
// source: app/observatory/command/command.proto
package command
import (
observatory "github.com/xtls/xray-core/app/observatory"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type GetOutboundStatusRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *GetOutboundStatusRequest) Reset() {
*x = GetOutboundStatusRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_app_observatory_command_command_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetOutboundStatusRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetOutboundStatusRequest) ProtoMessage() {}
func (x *GetOutboundStatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[0]
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 GetOutboundStatusRequest.ProtoReflect.Descriptor instead.
func (*GetOutboundStatusRequest) Descriptor() ([]byte, []int) {
return file_app_observatory_command_command_proto_rawDescGZIP(), []int{0}
}
type GetOutboundStatusResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Status *observatory.ObservationResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
}
func (x *GetOutboundStatusResponse) Reset() {
*x = GetOutboundStatusResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_app_observatory_command_command_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *GetOutboundStatusResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetOutboundStatusResponse) ProtoMessage() {}
func (x *GetOutboundStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[1]
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 GetOutboundStatusResponse.ProtoReflect.Descriptor instead.
func (*GetOutboundStatusResponse) Descriptor() ([]byte, []int) {
return file_app_observatory_command_command_proto_rawDescGZIP(), []int{1}
}
func (x *GetOutboundStatusResponse) GetStatus() *observatory.ObservationResult {
if x != nil {
return x.Status
}
return nil
}
type Config struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Config) Reset() {
*x = Config{}
if protoimpl.UnsafeEnabled {
mi := &file_app_observatory_command_command_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[2]
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 Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
return file_app_observatory_command_command_proto_rawDescGZIP(), []int{2}
}
var File_app_observatory_command_command_proto protoreflect.FileDescriptor
var file_app_observatory_command_command_proto_rawDesc = []byte{
0x0a, 0x25, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72,
0x79, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0x1c, 0x61, 0x70, 0x70, 0x2f,
0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x63, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x4f,
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x22, 0x61, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x44, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x2c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4f, 0x62,
0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x08, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x32, 0xa7, 0x01, 0x0a, 0x12, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72,
0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x90, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74,
0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b,
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f,
0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65,
0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e,
0x47, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x80, 0x01, 0x0a, 0x25,
0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x01, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f,
0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0xaa, 0x02, 0x21, 0x58, 0x72, 0x61,
0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72,
0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_app_observatory_command_command_proto_rawDescOnce sync.Once
file_app_observatory_command_command_proto_rawDescData = file_app_observatory_command_command_proto_rawDesc
)
func file_app_observatory_command_command_proto_rawDescGZIP() []byte {
file_app_observatory_command_command_proto_rawDescOnce.Do(func() {
file_app_observatory_command_command_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_observatory_command_command_proto_rawDescData)
})
return file_app_observatory_command_command_proto_rawDescData
}
var file_app_observatory_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_app_observatory_command_command_proto_goTypes = []interface{}{
(*GetOutboundStatusRequest)(nil), // 0: xray.core.app.observatory.command.GetOutboundStatusRequest
(*GetOutboundStatusResponse)(nil), // 1: xray.core.app.observatory.command.GetOutboundStatusResponse
(*Config)(nil), // 2: xray.core.app.observatory.command.Config
(*observatory.ObservationResult)(nil), // 3: xray.core.app.observatory.ObservationResult
}
var file_app_observatory_command_command_proto_depIdxs = []int32{
3, // 0: xray.core.app.observatory.command.GetOutboundStatusResponse.status:type_name -> xray.core.app.observatory.ObservationResult
0, // 1: xray.core.app.observatory.command.ObservatoryService.GetOutboundStatus:input_type -> xray.core.app.observatory.command.GetOutboundStatusRequest
1, // 2: xray.core.app.observatory.command.ObservatoryService.GetOutboundStatus:output_type -> xray.core.app.observatory.command.GetOutboundStatusResponse
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_app_observatory_command_command_proto_init() }
func file_app_observatory_command_command_proto_init() {
if File_app_observatory_command_command_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_app_observatory_command_command_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetOutboundStatusRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_command_command_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetOutboundStatusResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_command_command_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Config); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_observatory_command_command_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_app_observatory_command_command_proto_goTypes,
DependencyIndexes: file_app_observatory_command_command_proto_depIdxs,
MessageInfos: file_app_observatory_command_command_proto_msgTypes,
}.Build()
File_app_observatory_command_command_proto = out.File
file_app_observatory_command_command_proto_rawDesc = nil
file_app_observatory_command_command_proto_goTypes = nil
file_app_observatory_command_command_proto_depIdxs = nil
}

View File

@@ -1,24 +0,0 @@
syntax = "proto3";
package xray.core.app.observatory.command;
option csharp_namespace = "Xray.Core.App.Observatory.Command";
option go_package = "github.com/xtls/xray-core/app/observatory/command";
option java_package = "com.xray.core.app.observatory.command";
option java_multiple_files = true;
import "app/observatory/config.proto";
message GetOutboundStatusRequest {
}
message GetOutboundStatusResponse {
xray.core.app.observatory.ObservationResult status = 1;
}
service ObservatoryService {
rpc GetOutboundStatus(GetOutboundStatusRequest)
returns (GetOutboundStatusResponse) {}
}
message Config {}

View File

@@ -1,105 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.18.0
// source: app/observatory/command/command.proto
package command
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// ObservatoryServiceClient is the client API for ObservatoryService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type ObservatoryServiceClient interface {
GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error)
}
type observatoryServiceClient struct {
cc grpc.ClientConnInterface
}
func NewObservatoryServiceClient(cc grpc.ClientConnInterface) ObservatoryServiceClient {
return &observatoryServiceClient{cc}
}
func (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error) {
out := new(GetOutboundStatusResponse)
err := c.cc.Invoke(ctx, "/xray.core.app.observatory.command.ObservatoryService/GetOutboundStatus", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ObservatoryServiceServer is the server API for ObservatoryService service.
// All implementations must embed UnimplementedObservatoryServiceServer
// for forward compatibility
type ObservatoryServiceServer interface {
GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error)
mustEmbedUnimplementedObservatoryServiceServer()
}
// UnimplementedObservatoryServiceServer must be embedded to have forward compatible implementations.
type UnimplementedObservatoryServiceServer struct {
}
func (UnimplementedObservatoryServiceServer) GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetOutboundStatus not implemented")
}
func (UnimplementedObservatoryServiceServer) mustEmbedUnimplementedObservatoryServiceServer() {}
// UnsafeObservatoryServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ObservatoryServiceServer will
// result in compilation errors.
type UnsafeObservatoryServiceServer interface {
mustEmbedUnimplementedObservatoryServiceServer()
}
func RegisterObservatoryServiceServer(s grpc.ServiceRegistrar, srv ObservatoryServiceServer) {
s.RegisterService(&ObservatoryService_ServiceDesc, srv)
}
func _ObservatoryService_GetOutboundStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetOutboundStatusRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ObservatoryServiceServer).GetOutboundStatus(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/xray.core.app.observatory.command.ObservatoryService/GetOutboundStatus",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ObservatoryServiceServer).GetOutboundStatus(ctx, req.(*GetOutboundStatusRequest))
}
return interceptor(ctx, in, info, handler)
}
// ObservatoryService_ServiceDesc is the grpc.ServiceDesc for ObservatoryService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ObservatoryService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "xray.core.app.observatory.command.ObservatoryService",
HandlerType: (*ObservatoryServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetOutboundStatus",
Handler: _ObservatoryService_GetOutboundStatus_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "app/observatory/command/command.proto",
}

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/observatory/config.proto
@@ -73,23 +73,23 @@ type OutboundStatus struct {
unknownFields protoimpl.UnknownFields
// @Document Whether this outbound is usable
// @Restriction ReadOnlyForUser
//@Restriction ReadOnlyForUser
Alive bool `protobuf:"varint,1,opt,name=alive,proto3" json:"alive,omitempty"`
// @Document The time for probe request to finish.
// @Type time.ms
// @Restriction ReadOnlyForUser
//@Type time.ms
//@Restriction ReadOnlyForUser
Delay int64 `protobuf:"varint,2,opt,name=delay,proto3" json:"delay,omitempty"`
// @Document The last error caused this outbound failed to relay probe request
// @Restriction NotMachineReadable
//@Restriction NotMachineReadable
LastErrorReason string `protobuf:"bytes,3,opt,name=last_error_reason,json=lastErrorReason,proto3" json:"last_error_reason,omitempty"`
// @Document The outbound tag for this Server
// @Type id.outboundTag
//@Type id.outboundTag
OutboundTag string `protobuf:"bytes,4,opt,name=outbound_tag,json=outboundTag,proto3" json:"outbound_tag,omitempty"`
// @Document The time this outbound is known to be alive
// @Type id.outboundTag
//@Type id.outboundTag
LastSeenTime int64 `protobuf:"varint,5,opt,name=last_seen_time,json=lastSeenTime,proto3" json:"last_seen_time,omitempty"`
// @Document The time this outbound is tried
// @Type id.outboundTag
//@Type id.outboundTag
LastTryTime int64 `protobuf:"varint,6,opt,name=last_try_time,json=lastTryTime,proto3" json:"last_try_time,omitempty"`
}
@@ -173,14 +173,14 @@ type ProbeResult struct {
unknownFields protoimpl.UnknownFields
// @Document Whether this outbound is usable
// @Restriction ReadOnlyForUser
//@Restriction ReadOnlyForUser
Alive bool `protobuf:"varint,1,opt,name=alive,proto3" json:"alive,omitempty"`
// @Document The time for probe request to finish.
// @Type time.ms
// @Restriction ReadOnlyForUser
//@Type time.ms
//@Restriction ReadOnlyForUser
Delay int64 `protobuf:"varint,2,opt,name=delay,proto3" json:"delay,omitempty"`
// @Document The error caused this outbound failed to relay probe request
// @Restriction NotMachineReadable
//@Restriction NotMachineReadable
LastErrorReason string `protobuf:"bytes,3,opt,name=last_error_reason,json=lastErrorReason,proto3" json:"last_error_reason,omitempty"`
}
@@ -243,7 +243,7 @@ type Intensity struct {
unknownFields protoimpl.UnknownFields
// @Document The time interval for a probe request in ms.
// @Type time.ms
//@Type time.ms
ProbeInterval uint32 `protobuf:"varint,1,opt,name=probe_interval,json=probeInterval,proto3" json:"probe_interval,omitempty"`
}

View File

@@ -2,6 +2,7 @@ package observatory
import (
"context"
"github.com/xtls/xray-core/core"
"net"
"net/http"
"net/url"
@@ -10,12 +11,12 @@ import (
"time"
"github.com/golang/protobuf/proto"
"github.com/xtls/xray-core/common"
v2net "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal/done"
"github.com/xtls/xray-core/common/task"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/extension"
"github.com/xtls/xray-core/features/outbound"
"github.com/xtls/xray-core/transport/internet/tagged"
@@ -31,6 +32,8 @@ type Observer struct {
finished *done.Instance
ohm outbound.Manager
StatusUpdate func(result *OutboundStatus)
}
func (o *Observer) GetObservation(ctx context.Context) (proto.Message, error) {
@@ -65,45 +68,22 @@ func (o *Observer) background() {
}
outbounds := hs.Select(o.config.SubjectSelector)
sort.Strings(outbounds)
o.updateStatus(outbounds)
sleepTime := time.Second * 10
if o.config.ProbeInterval != 0 {
sleepTime = time.Duration(o.config.ProbeInterval)
}
if !o.config.EnableConcurrency {
sort.Strings(outbounds)
for _, v := range outbounds {
result := o.probe(v)
o.updateStatusForResult(v, &result)
if o.finished.Done() {
return
}
time.Sleep(sleepTime)
}
continue
}
ch := make(chan struct{}, len(outbounds))
for _, v := range outbounds {
go func(v string) {
result := o.probe(v)
o.updateStatusForResult(v, &result)
ch <- struct{}{}
}(v)
}
for range outbounds {
select {
case <-ch:
case <-o.finished.Wait():
result := o.probe(v)
o.updateStatusForResult(v, &result)
if o.finished.Done() {
return
}
sleepTime := time.Second * 10
if o.config.ProbeInterval != 0 {
sleepTime = time.Duration(o.config.ProbeInterval)
}
time.Sleep(sleepTime)
}
time.Sleep(sleepTime)
}
}
@@ -124,7 +104,7 @@ func (o *Observer) probe(outbound string) ProbeResult {
DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {
var connection net.Conn
taskErr := task.Run(ctx, func() error {
// MUST use Xray's built in context system
// MUST use V2Fly's built in context system
dest, err := v2net.ParseDestination(network + ":" + addr)
if err != nil {
return newError("cannot understand address").Base(err)
@@ -155,7 +135,7 @@ func (o *Observer) probe(outbound string) ProbeResult {
var GETTime time.Duration
err := task.Run(o.ctx, func() error {
startTime := time.Now()
probeURL := "https://www.google.com/generate_204"
probeURL := "https://api.v2fly.org/checkConnection.svgz"
if o.config.ProbeUrl != "" {
probeURL = o.config.ProbeUrl
}
@@ -205,6 +185,10 @@ func (o *Observer) updateStatusForResult(outbound string, result *ProbeResult) {
status.LastErrorReason = result.LastErrorReason
status.Delay = 99999999
}
if o.StatusUpdate != nil {
o.StatusUpdate(status)
}
}
func (o *Observer) findStatusLocationLockHolderOnly(outbound string) int {

View File

@@ -0,0 +1,12 @@
package observatory
func (o *Observer) UpdateStatus(result *OutboundStatus) {
o.statusLock.Lock()
defer o.statusLock.Unlock()
if location := o.findStatusLocationLockHolderOnly(result.OutboundTag); location != -1 {
o.status[location] = result
} else {
o.status = append(o.status, result)
}
}

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/policy/config.proto

View File

@@ -3,12 +3,13 @@ package command
import (
"context"
grpc "google.golang.org/grpc"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/inbound"
"github.com/xtls/xray-core/features/outbound"
"github.com/xtls/xray-core/proxy"
grpc "google.golang.org/grpc"
)
// InboundOperation is the interface for operations that applies to inbound handlers.

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/proxyman/command/command.proto

View File

@@ -1,8 +1,4 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.18.0
// source: app/proxyman/command/command.proto
package command

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/proxyman/config.proto
@@ -69,6 +69,64 @@ func (KnownProtocols) EnumDescriptor() ([]byte, []int) {
return file_app_proxyman_config_proto_rawDescGZIP(), []int{0}
}
type DomainStrategy int32
const (
DomainStrategy_AS_IS DomainStrategy = 0
DomainStrategy_USE_IP DomainStrategy = 1
DomainStrategy_USE_IP4 DomainStrategy = 2
DomainStrategy_USE_IP6 DomainStrategy = 3
DomainStrategy_PREFER_IP4 DomainStrategy = 4
DomainStrategy_PREFER_IP6 DomainStrategy = 5
)
// Enum value maps for DomainStrategy.
var (
DomainStrategy_name = map[int32]string{
0: "AS_IS",
1: "USE_IP",
2: "USE_IP4",
3: "USE_IP6",
4: "PREFER_IP4",
5: "PREFER_IP6",
}
DomainStrategy_value = map[string]int32{
"AS_IS": 0,
"USE_IP": 1,
"USE_IP4": 2,
"USE_IP6": 3,
"PREFER_IP4": 4,
"PREFER_IP6": 5,
}
)
func (x DomainStrategy) Enum() *DomainStrategy {
p := new(DomainStrategy)
*p = x
return p
}
func (x DomainStrategy) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (DomainStrategy) Descriptor() protoreflect.EnumDescriptor {
return file_app_proxyman_config_proto_enumTypes[1].Descriptor()
}
func (DomainStrategy) Type() protoreflect.EnumType {
return &file_app_proxyman_config_proto_enumTypes[1]
}
func (x DomainStrategy) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use DomainStrategy.Descriptor instead.
func (DomainStrategy) EnumDescriptor() ([]byte, []int) {
return file_app_proxyman_config_proto_rawDescGZIP(), []int{1}
}
type AllocationStrategy_Type int32
const (
@@ -105,11 +163,11 @@ func (x AllocationStrategy_Type) String() string {
}
func (AllocationStrategy_Type) Descriptor() protoreflect.EnumDescriptor {
return file_app_proxyman_config_proto_enumTypes[1].Descriptor()
return file_app_proxyman_config_proto_enumTypes[2].Descriptor()
}
func (AllocationStrategy_Type) Type() protoreflect.EnumType {
return &file_app_proxyman_config_proto_enumTypes[1]
return &file_app_proxyman_config_proto_enumTypes[2]
}
func (x AllocationStrategy_Type) Number() protoreflect.EnumNumber {
@@ -238,8 +296,7 @@ type SniffingConfig struct {
DestinationOverride []string `protobuf:"bytes,2,rep,name=destination_override,json=destinationOverride,proto3" json:"destination_override,omitempty"`
DomainsExcluded []string `protobuf:"bytes,3,rep,name=domains_excluded,json=domainsExcluded,proto3" json:"domains_excluded,omitempty"`
// Whether should only try to sniff metadata without waiting for client input.
// Can be used to support SMTP like protocol where server send the first
// message.
// Can be used to support SMTP like protocol where server send the first message.
MetadataOnly bool `protobuf:"varint,4,opt,name=metadata_only,json=metadataOnly,proto3" json:"metadata_only,omitempty"`
RouteOnly bool `protobuf:"varint,5,opt,name=route_only,json=routeOnly,proto3" json:"route_only,omitempty"`
}
@@ -316,8 +373,8 @@ type ReceiverConfig struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// PortList specifies the ports which the Receiver should listen on.
PortList *net.PortList `protobuf:"bytes,1,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
// PortRange specifies the ports which the Receiver should listen on.
PortRange *net.PortRange `protobuf:"bytes,1,opt,name=port_range,json=portRange,proto3" json:"port_range,omitempty"`
// Listen specifies the IP address that the Receiver should listen on.
Listen *net.IPOrDomain `protobuf:"bytes,2,opt,name=listen,proto3" json:"listen,omitempty"`
AllocationStrategy *AllocationStrategy `protobuf:"bytes,3,opt,name=allocation_strategy,json=allocationStrategy,proto3" json:"allocation_strategy,omitempty"`
@@ -363,9 +420,9 @@ func (*ReceiverConfig) Descriptor() ([]byte, []int) {
return file_app_proxyman_config_proto_rawDescGZIP(), []int{3}
}
func (x *ReceiverConfig) GetPortList() *net.PortList {
func (x *ReceiverConfig) GetPortRange() *net.PortRange {
if x != nil {
return x.PortList
return x.PortRange
}
return nil
}
@@ -524,6 +581,7 @@ type SenderConfig struct {
StreamSettings *internet.StreamConfig `protobuf:"bytes,2,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"`
ProxySettings *internet.ProxyConfig `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3" json:"proxy_settings,omitempty"`
MultiplexSettings *MultiplexingConfig `protobuf:"bytes,4,opt,name=multiplex_settings,json=multiplexSettings,proto3" json:"multiplex_settings,omitempty"`
DomainStrategy DomainStrategy `protobuf:"varint,5,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.app.proxyman.DomainStrategy" json:"domain_strategy,omitempty"`
}
func (x *SenderConfig) Reset() {
@@ -586,6 +644,13 @@ func (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
return nil
}
func (x *SenderConfig) GetDomainStrategy() DomainStrategy {
if x != nil {
return x.DomainStrategy
}
return DomainStrategy_AS_IS
}
type MultiplexingConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -791,86 +856,97 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x6f,
0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x8d, 0x04, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f,
0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72,
0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12,
0x33, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65,
0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x6c, 0x69,
0x73, 0x74, 0x65, 0x6e, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f,
0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x61,
0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x4e, 0x0a, 0x0f,
0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x90, 0x04, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f,
0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f,
0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e,
0x67, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52,
0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x56, 0x0a, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x63,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x12, 0x61, 0x6c, 0x6c,
0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12,
0x4e, 0x0a, 0x0f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e,
0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
0x65, 0x74, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x0e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12,
0x40, 0x0a, 0x1c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, 0x72,
0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x4e, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72,
0x72, 0x69, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4b,
0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x42, 0x02, 0x18,
0x01, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
0x65, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65,
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e,
0x2e, 0x53, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52,
0x10, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
0x73, 0x4a, 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74,
0x61, 0x67, 0x12, 0x4d, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x73,
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69,
0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52,
0x10, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
0x73, 0x12, 0x47, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69,
0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54,
0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x6f,
0x78, 0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, 0x75,
0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xfc, 0x02, 0x0a,
0x0c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a,
0x03, 0x76, 0x69, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f,
0x72, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x03, 0x76, 0x69, 0x61, 0x12, 0x4e, 0x0a, 0x0f,
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61,
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x40, 0x0a, 0x1c,
0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c,
0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01,
0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69,
0x6e, 0x61, 0x6c, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e,
0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64,
0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4b, 0x6e, 0x6f, 0x77,
0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x4e,
0x0a, 0x11, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69,
0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x6e,
0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, 0x73, 0x6e,
0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4a, 0x04,
0x08, 0x06, 0x10, 0x07, 0x22, 0xc0, 0x01, 0x0a, 0x14, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a,
0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12,
0x4d, 0x0a, 0x11, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74,
0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e,
0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x10, 0x72, 0x65,
0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x47,
0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65,
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x53,
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb0, 0x02, 0x0a, 0x0c, 0x53, 0x65,
0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x03, 0x76, 0x69,
0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f,
0x6d, 0x61, 0x69, 0x6e, 0x52, 0x03, 0x76, 0x69, 0x61, 0x12, 0x4e, 0x0a, 0x0f, 0x73, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x73, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4b, 0x0a, 0x0e, 0x70, 0x72, 0x6f,
0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f,
0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x78,
0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x53, 0x65,
0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70,
0x6c, 0x65, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72,
0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78,
0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69,
0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x50, 0x0a, 0x12,
0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b,
0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x2a, 0x23,
0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73,
0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x4c,
0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x26,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f,
0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72,
0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70,
0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x72, 0x65, 0x61, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4b, 0x0a, 0x0e,
0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x50,
0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78,
0x79, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x54, 0x0a, 0x12, 0x6d, 0x75, 0x6c,
0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70,
0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75,
0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12,
0x4a, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x44, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x50, 0x0a, 0x12, 0x4d,
0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63,
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x2a, 0x23, 0x0a,
0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12,
0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53,
0x10, 0x01, 0x2a, 0x61, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x53, 0x5f, 0x49, 0x53, 0x10, 0x00, 0x12,
0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55,
0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f,
0x49, 0x50, 0x36, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x5f,
0x49, 0x50, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x5f,
0x49, 0x50, 0x36, 0x10, 0x05, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01,
0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c,
0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f,
0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e,
0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -885,48 +961,50 @@ func file_app_proxyman_config_proto_rawDescGZIP() []byte {
return file_app_proxyman_config_proto_rawDescData
}
var file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
var file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_app_proxyman_config_proto_goTypes = []interface{}{
(KnownProtocols)(0), // 0: xray.app.proxyman.KnownProtocols
(AllocationStrategy_Type)(0), // 1: xray.app.proxyman.AllocationStrategy.Type
(*InboundConfig)(nil), // 2: xray.app.proxyman.InboundConfig
(*AllocationStrategy)(nil), // 3: xray.app.proxyman.AllocationStrategy
(*SniffingConfig)(nil), // 4: xray.app.proxyman.SniffingConfig
(*ReceiverConfig)(nil), // 5: xray.app.proxyman.ReceiverConfig
(*InboundHandlerConfig)(nil), // 6: xray.app.proxyman.InboundHandlerConfig
(*OutboundConfig)(nil), // 7: xray.app.proxyman.OutboundConfig
(*SenderConfig)(nil), // 8: xray.app.proxyman.SenderConfig
(*MultiplexingConfig)(nil), // 9: xray.app.proxyman.MultiplexingConfig
(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 10: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
(*AllocationStrategy_AllocationStrategyRefresh)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
(*net.PortList)(nil), // 12: xray.common.net.PortList
(*net.IPOrDomain)(nil), // 13: xray.common.net.IPOrDomain
(*internet.StreamConfig)(nil), // 14: xray.transport.internet.StreamConfig
(*serial.TypedMessage)(nil), // 15: xray.common.serial.TypedMessage
(*internet.ProxyConfig)(nil), // 16: xray.transport.internet.ProxyConfig
(DomainStrategy)(0), // 1: xray.app.proxyman.DomainStrategy
(AllocationStrategy_Type)(0), // 2: xray.app.proxyman.AllocationStrategy.Type
(*InboundConfig)(nil), // 3: xray.app.proxyman.InboundConfig
(*AllocationStrategy)(nil), // 4: xray.app.proxyman.AllocationStrategy
(*SniffingConfig)(nil), // 5: xray.app.proxyman.SniffingConfig
(*ReceiverConfig)(nil), // 6: xray.app.proxyman.ReceiverConfig
(*InboundHandlerConfig)(nil), // 7: xray.app.proxyman.InboundHandlerConfig
(*OutboundConfig)(nil), // 8: xray.app.proxyman.OutboundConfig
(*SenderConfig)(nil), // 9: xray.app.proxyman.SenderConfig
(*MultiplexingConfig)(nil), // 10: xray.app.proxyman.MultiplexingConfig
(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
(*AllocationStrategy_AllocationStrategyRefresh)(nil), // 12: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
(*net.PortRange)(nil), // 13: xray.common.net.PortRange
(*net.IPOrDomain)(nil), // 14: xray.common.net.IPOrDomain
(*internet.StreamConfig)(nil), // 15: xray.transport.internet.StreamConfig
(*serial.TypedMessage)(nil), // 16: xray.common.serial.TypedMessage
(*internet.ProxyConfig)(nil), // 17: xray.transport.internet.ProxyConfig
}
var file_app_proxyman_config_proto_depIdxs = []int32{
1, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type
10, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
11, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
12, // 3: xray.app.proxyman.ReceiverConfig.port_list:type_name -> xray.common.net.PortList
13, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain
3, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy
14, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
2, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type
11, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
12, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
13, // 3: xray.app.proxyman.ReceiverConfig.port_range:type_name -> xray.common.net.PortRange
14, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain
4, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy
15, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
0, // 7: xray.app.proxyman.ReceiverConfig.domain_override:type_name -> xray.app.proxyman.KnownProtocols
4, // 8: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig
15, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage
15, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage
13, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain
14, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
16, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig
9, // 14: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig
15, // [15:15] is the sub-list for method output_type
15, // [15:15] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
5, // 8: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig
16, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage
16, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage
14, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain
15, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
17, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig
10, // 14: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig
1, // 15: xray.app.proxyman.SenderConfig.domain_strategy:type_name -> xray.app.proxyman.DomainStrategy
16, // [16:16] is the sub-list for method output_type
16, // [16:16] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
}
func init() { file_app_proxyman_config_proto_init() }
@@ -1061,7 +1139,7 @@ func file_app_proxyman_config_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_proxyman_config_proto_rawDesc,
NumEnums: 2,
NumEnums: 3,
NumMessages: 10,
NumExtensions: 0,
NumServices: 0,

View File

@@ -27,13 +27,17 @@ message AllocationStrategy {
Type type = 1;
message AllocationStrategyConcurrency { uint32 value = 1; }
message AllocationStrategyConcurrency {
uint32 value = 1;
}
// Number of handlers (ports) running in parallel.
// Default value is 3 if unset.
AllocationStrategyConcurrency concurrency = 2;
message AllocationStrategyRefresh { uint32 value = 1; }
message AllocationStrategyRefresh {
uint32 value = 1;
}
// Number of minutes before a handler is regenerated.
// Default value is 5 if unset.
@@ -55,16 +59,15 @@ message SniffingConfig {
repeated string domains_excluded = 3;
// Whether should only try to sniff metadata without waiting for client input.
// Can be used to support SMTP like protocol where server send the first
// message.
// Can be used to support SMTP like protocol where server send the first message.
bool metadata_only = 4;
bool route_only = 5;
}
message ReceiverConfig {
// PortList specifies the ports which the Receiver should listen on.
xray.common.net.PortList port_list = 1;
// PortRange specifies the ports which the Receiver should listen on.
xray.common.net.PortRange port_range = 1;
// Listen specifies the IP address that the Receiver should listen on.
xray.common.net.IPOrDomain listen = 2;
AllocationStrategy allocation_strategy = 3;
@@ -73,7 +76,7 @@ message ReceiverConfig {
reserved 6;
// Override domains for the given protocol.
// Deprecated. Use sniffing_settings.
repeated KnownProtocols domain_override = 7 [ deprecated = true ];
repeated KnownProtocols domain_override = 7 [deprecated = true];
SniffingConfig sniffing_settings = 8;
}
@@ -85,12 +88,22 @@ message InboundHandlerConfig {
message OutboundConfig {}
enum DomainStrategy {
AS_IS = 0;
USE_IP = 1;
USE_IP4 = 2;
USE_IP6 = 3;
PREFER_IP4 = 4;
PREFER_IP6 = 5;
}
message SenderConfig {
// Send traffic through the given IP. Only IP is allowed.
xray.common.net.IPOrDomain via = 1;
xray.transport.internet.StreamConfig stream_settings = 2;
xray.transport.internet.ProxyConfig proxy_settings = 3;
MultiplexingConfig multiplex_settings = 4;
DomainStrategy domain_strategy = 5;
}
message MultiplexingConfig {

View File

@@ -67,7 +67,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
uplinkCounter, downlinkCounter := getStatCounter(core.MustFromContext(ctx), tag)
nl := p.Network()
pl := receiverConfig.PortList
pr := receiverConfig.PortRange
address := receiverConfig.Listen.AsAddress()
if address == nil {
address = net.AnyIP
@@ -87,7 +87,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
}
mss.SocketSettings.ReceiveOriginalDestAddress = true
}
if pl == nil {
if pr == nil {
if net.HasNetwork(nl, net.Network_UNIX) {
newError("creating unix domain socket worker on ", address).AtDebug().WriteToLog()
@@ -105,43 +105,41 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
h.workers = append(h.workers, worker)
}
}
if pl != nil {
for _, pr := range pl.Range {
for port := pr.From; port <= pr.To; port++ {
if net.HasNetwork(nl, net.Network_TCP) {
newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog()
if pr != nil {
for port := pr.From; port <= pr.To; port++ {
if net.HasNetwork(nl, net.Network_TCP) {
newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog()
worker := &tcpWorker{
address: address,
port: net.Port(port),
proxy: p,
stream: mss,
recvOrigDest: receiverConfig.ReceiveOriginalDestination,
tag: tag,
dispatcher: h.mux,
sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
ctx: ctx,
}
h.workers = append(h.workers, worker)
worker := &tcpWorker{
address: address,
port: net.Port(port),
proxy: p,
stream: mss,
recvOrigDest: receiverConfig.ReceiveOriginalDestination,
tag: tag,
dispatcher: h.mux,
sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
ctx: ctx,
}
h.workers = append(h.workers, worker)
}
if net.HasNetwork(nl, net.Network_UDP) {
worker := &udpWorker{
tag: tag,
proxy: p,
address: address,
port: net.Port(port),
dispatcher: h.mux,
sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
stream: mss,
ctx: ctx,
}
h.workers = append(h.workers, worker)
if net.HasNetwork(nl, net.Network_UDP) {
worker := &udpWorker{
tag: tag,
proxy: p,
address: address,
port: net.Port(port),
dispatcher: h.mux,
sniffingConfig: receiverConfig.GetEffectiveSniffingSettings(),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
stream: mss,
ctx: ctx,
}
h.workers = append(h.workers, worker)
}
}
}

View File

@@ -69,18 +69,15 @@ func NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *p
}
func (h *DynamicInboundHandler) allocatePort() net.Port {
allPorts := []int32{}
for _, pr := range h.receiverConfig.PortList.Range {
for i := pr.From; i <= pr.To; i++ {
allPorts = append(allPorts, int32(i))
}
}
from := int(h.receiverConfig.PortRange.From)
delta := int(h.receiverConfig.PortRange.To) - from + 1
h.portMutex.Lock()
defer h.portMutex.Unlock()
for {
r := dice.Roll(len(allPorts))
port := net.Port(allPorts[r])
r := dice.Roll(delta)
port := net.Port(from + r)
_, used := h.portsInUse[port]
if !used {
h.portsInUse[port] = true

View File

@@ -6,6 +6,8 @@ import (
"sync/atomic"
"time"
"github.com/xtls/xray-core/transport/internet/stat"
"github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
@@ -18,7 +20,6 @@ import (
"github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/proxy"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/stat"
"github.com/xtls/xray-core/transport/internet/tcp"
"github.com/xtls/xray-core/transport/internet/udp"
"github.com/xtls/xray-core/transport/pipe"
@@ -108,7 +109,9 @@ func (w *tcpWorker) callback(conn stat.Connection) {
newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
cancel()
conn.Close()
if err := conn.Close(); err != nil {
newError("failed to close connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
}
}
func (w *tcpWorker) Proxy() proxy.Inbound {

View File

@@ -2,9 +2,8 @@ package outbound
import (
"context"
"errors"
"io"
"os"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/transport/internet/stat"
"github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common"
@@ -19,7 +18,6 @@ import (
"github.com/xtls/xray-core/proxy"
"github.com/xtls/xray-core/transport"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/stat"
"github.com/xtls/xray-core/transport/internet/tls"
"github.com/xtls/xray-core/transport/pipe"
)
@@ -56,18 +54,20 @@ type Handler struct {
streamSettings *internet.MemoryStreamConfig
proxy proxy.Outbound
outboundManager outbound.Manager
dnsClient dns.Client
mux *mux.ClientManager
uplinkCounter stats.Counter
downlinkCounter stats.Counter
}
// NewHandler creates a new Handler based on the given configuration.
// NewHandler create a new Handler based on the given configuration.
func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbound.Handler, error) {
v := core.MustFromContext(ctx)
uplinkCounter, downlinkCounter := getStatCounter(v, config.Tag)
h := &Handler{
tag: config.Tag,
outboundManager: v.GetFeature(outbound.ManagerType()).(outbound.Manager),
dnsClient: v.GetFeature(dns.ClientType()).(dns.Client),
uplinkCounter: uplinkCounter,
downlinkCounter: downlinkCounter,
}
@@ -138,23 +138,53 @@ func (h *Handler) Tag() string {
func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
if h.mux != nil && (h.mux.Enabled || session.MuxPreferedFromContext(ctx)) {
if err := h.mux.Dispatch(ctx, link); err != nil {
err := newError("failed to process mux outbound traffic").Base(err)
session.SubmitOutboundErrorToOriginator(ctx, err)
err.WriteToLog(session.ExportIDToError(ctx))
newError("failed to process mux outbound traffic").Base(err).WriteToLog(session.ExportIDToError(ctx))
common.Interrupt(link.Writer)
}
} else {
err := h.proxy.Process(ctx, link, h)
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrClosedPipe) || errors.Is(err, context.Canceled) {
err = nil
outbound := session.OutboundFromContext(ctx)
destination := outbound.Target
var domainString string
if destination.Address.Family().IsDomain() {
domainString = destination.Address.Domain()
} else if outbound.RouteTarget.Address != nil && outbound.RouteTarget.Address.Family().IsDomain() {
domainString = outbound.RouteTarget.Address.Domain()
} else {
domainString = ""
}
if h.senderSettings != nil && h.senderSettings.DomainStrategy != proxyman.DomainStrategy_AS_IS && domainString != "" {
var ips []net.IP
var err error
option := dns.IPOption{
IPv4Enable: true,
IPv6Enable: true,
FakeEnable: false,
}
switch h.senderSettings.DomainStrategy {
case proxyman.DomainStrategy_USE_IP4:
option.IPv6Enable = false
case proxyman.DomainStrategy_USE_IP6:
option.IPv4Enable = false
}
ips, err = h.dnsClient.LookupIP(domainString, option)
if err == nil {
switch h.senderSettings.DomainStrategy {
case proxyman.DomainStrategy_PREFER_IP4:
ips = reorderAddresses(ips, false)
case proxyman.DomainStrategy_PREFER_IP6:
ips = reorderAddresses(ips, true)
}
destination.Address = net.IPAddress(ips[0])
outbound.Target = destination
}
}
err := h.proxy.Process(ctx, link, h)
if err != nil {
// Ensure outbound ray is properly closed.
err := newError("failed to process outbound traffic").Base(err)
session.SubmitOutboundErrorToOriginator(ctx, err)
err.WriteToLog(session.ExportIDToError(ctx))
newError("failed to process outbound traffic").Base(err).WriteToLog(session.ExportIDToError(ctx))
common.Interrupt(link.Writer)
} else {
common.Must(common.Close(link.Writer))
@@ -163,6 +193,18 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
}
}
func reorderAddresses(ips []net.IP, preferIPv6 bool) []net.IP {
var result []net.IP
for i := 0; i < 2; i++ {
for _, ip := range ips {
if (preferIPv6 == (i == 0)) == (ip.To4() == nil) {
result = append(result, ip)
}
}
}
return result
}
// Address implements internet.Dialer.
func (h *Handler) Address() net.Address {
if h.senderSettings == nil || h.senderSettings.Via == nil {
@@ -211,10 +253,6 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
}
}
if conn, err := h.getUoTConnection(ctx, dest); err != os.ErrInvalid {
return conn, err
}
conn, err := internet.Dial(ctx, dest, h.streamSettings)
return h.getStatCouterConnection(conn), err
}

View File

@@ -4,6 +4,8 @@ import (
"context"
"testing"
"github.com/xtls/xray-core/transport/internet/stat"
"github.com/xtls/xray-core/app/policy"
. "github.com/xtls/xray-core/app/proxyman/outbound"
"github.com/xtls/xray-core/app/stats"
@@ -12,7 +14,6 @@ import (
core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/outbound"
"github.com/xtls/xray-core/proxy/freedom"
"github.com/xtls/xray-core/transport/internet/stat"
)
func TestInterfaces(t *testing.T) {

View File

@@ -1,23 +0,0 @@
package outbound
import (
"context"
"os"
"github.com/sagernet/sing/common/uot"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/stat"
)
func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) {
if !dest.Address.Family().IsDomain() || dest.Address.Domain() != uot.UOTMagicAddress {
return nil, os.ErrInvalid
}
packetConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings)
if err != nil {
return nil, newError("unable to listen socket").Base(err)
}
conn := uot.NewServerConn(packetConn)
return h.getStatCouterConnection(conn), nil
}

View File

@@ -5,6 +5,7 @@ import (
"time"
"github.com/golang/protobuf/proto"
"github.com/xtls/xray-core/common/mux"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/reverse/config.proto

View File

@@ -6,6 +6,7 @@ import (
"time"
"github.com/golang/protobuf/proto"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/mux"

View File

@@ -14,7 +14,7 @@ import (
)
const (
internalDomain = "reverse.internal.v2fly.org" // make reverse proxy compatible with v2fly
internalDomain = "reverse.internal.example.com"
)
func isDomain(dest net.Destination, domain string) bool {

View File

@@ -44,7 +44,6 @@ func (b *Balancer) PickOutbound() (string, error) {
}
return tag, nil
}
func (b *Balancer) InjectContext(ctx context.Context) {
if contextReceiver, ok := b.strategy.(extension.ContextReceiver); ok {
contextReceiver.InjectContext(ctx)

View File

@@ -6,11 +6,12 @@ import (
"context"
"time"
"google.golang.org/grpc"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/features/stats"
"google.golang.org/grpc"
)
// routingServer is an implementation of RoutingService.

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/router/command/command.proto
@@ -163,19 +163,18 @@ func (x *RoutingContext) GetOutboundTag() string {
// opened by xray-core.
// * FieldSelectors selects a subset of fields in routing statistics to return.
// Valid selectors:
// - inbound: Selects connection's inbound tag.
// - network: Selects connection's network.
// - ip: Equivalent as "ip_source" and "ip_target", selects both source and
// target IP.
// - port: Equivalent as "port_source" and "port_target", selects both source
// and target port.
// - domain: Selects target domain.
// - protocol: Select connection's protocol.
// - user: Select connection's inbound user email.
// - attributes: Select connection's additional attributes.
// - outbound: Equivalent as "outbound" and "outbound_group", select both
// outbound tag and outbound group tags.
//
// - inbound: Selects connection's inbound tag.
// - network: Selects connection's network.
// - ip: Equivalent as "ip_source" and "ip_target", selects both source and
// target IP.
// - port: Equivalent as "port_source" and "port_target", selects both source
// and target port.
// - domain: Selects target domain.
// - protocol: Select connection's protocol.
// - user: Select connection's inbound user email.
// - attributes: Select connection's additional attributes.
// - outbound: Equivalent as "outbound" and "outbound_group", select both
// outbound tag and outbound group tags.
// * If FieldSelectors is left empty, all fields will be returned.
type SubscribeRoutingStatsRequest struct {
state protoimpl.MessageState

View File

@@ -1,8 +1,4 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.18.0
// source: app/router/command/command.proto
package command

View File

@@ -8,6 +8,9 @@ import (
"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
"github.com/xtls/xray-core/app/router"
. "github.com/xtls/xray-core/app/router/command"
"github.com/xtls/xray-core/app/stats"
@@ -15,8 +18,6 @@ import (
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/routing"
"github.com/xtls/xray-core/testing/mocks"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
)
func TestServiceSubscribeRoutingStats(t *testing.T) {
@@ -283,7 +284,7 @@ func TestSerivceTestRoute(t *testing.T) {
r := new(router.Router)
mockCtl := gomock.NewController(t)
defer mockCtl.Finish()
common.Must(r.Init(context.TODO(), &router.Config{
common.Must(r.Init(&router.Config{
Rule: []*router.RoutingRule{
{
InboundTag: []string{"in"},

View File

@@ -28,6 +28,14 @@ func (c routingContext) GetTargetPort() net.Port {
return net.Port(c.RoutingContext.GetTargetPort())
}
func (c routingContext) GetUid() uint32 {
return 0
}
func (c routingContext) GetAppStatus() []string {
return nil
}
// GetSkipDNSResolve is a mock implementation here to match the interface,
// SkipDNSResolve is set from dns module, no use if coming from a protobuf object?
// TODO: please confirm @Vigilans

View File

@@ -3,11 +3,12 @@ package router
import (
"strings"
"go.starlark.net/starlark"
"go.starlark.net/syntax"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/strmatcher"
"github.com/xtls/xray-core/features/routing"
"go.starlark.net/starlark"
"go.starlark.net/syntax"
)
type Condition interface {
@@ -332,3 +333,49 @@ func (m *AttributeMatcher) Apply(ctx routing.Context) bool {
}
return m.Match(attributes)
}
type UidMatcher struct {
uidList map[uint32]bool
}
func NewUidMatcher(list *net.UidList) *UidMatcher {
m := UidMatcher{uidList: map[uint32]bool{}}
for _, uid := range list.Uid {
m.uidList[uid] = true
}
return &m
}
func (u UidMatcher) Apply(ctx routing.Context) bool {
return u.uidList[ctx.GetUid()]
}
type AppStatusMatcher struct {
appStatus map[string]bool
}
func NewAppStatusMatcher(appStatus []string) *AppStatusMatcher {
m := &AppStatusMatcher{
appStatus: map[string]bool{},
}
for _, status := range appStatus {
m.appStatus[status] = true
}
return m
}
// Apply implements Condition.
func (m *AppStatusMatcher) Apply(ctx routing.Context) bool {
status := ctx.GetAppStatus()
if len(status) == 0 {
return false
}
for _, s := range status {
if !m.appStatus[s] {
return false
}
}
return true
}

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/golang/protobuf/proto"
"github.com/xtls/xray-core/app/router"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"

View File

@@ -7,6 +7,7 @@ import (
"testing"
"github.com/golang/protobuf/proto"
. "github.com/xtls/xray-core/app/router"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"

View File

@@ -150,6 +150,14 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
conds.Add(cond)
}
if rr.UidList != nil && len(rr.UidList.Uid) > 0 {
conds.Add(NewUidMatcher(rr.UidList))
}
if len(rr.AppStatus) > 0 {
conds.Add(NewAppStatusMatcher(rr.AppStatus))
}
if conds.Len() == 0 {
return nil, newError("this rule has no effective fields").AtWarning()
}
@@ -158,21 +166,9 @@ func (rr *RoutingRule) BuildCondition() (Condition, error) {
}
func (br *BalancingRule) Build(ohm outbound.Manager) (*Balancer, error) {
switch br.Strategy {
case "leastPing":
return &Balancer{
selectors: br.OutboundSelector,
strategy: &LeastPingStrategy{},
ohm: ohm,
}, nil
case "random":
fallthrough
default:
return &Balancer{
selectors: br.OutboundSelector,
strategy: &RandomStrategy{},
ohm: ohm,
}, nil
}
return &Balancer{
selectors: br.OutboundSelector,
strategy: &RandomStrategy{},
ohm: ohm,
}, nil
}

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/router/config.proto
@@ -477,7 +477,6 @@ type RoutingRule struct {
unknownFields protoimpl.UnknownFields
// Types that are assignable to TargetTag:
//
// *RoutingRule_Tag
// *RoutingRule_BalancingTag
TargetTag isRoutingRule_TargetTag `protobuf_oneof:"target_tag"`
@@ -520,6 +519,8 @@ type RoutingRule struct {
Protocol []string `protobuf:"bytes,9,rep,name=protocol,proto3" json:"protocol,omitempty"`
Attributes string `protobuf:"bytes,15,opt,name=attributes,proto3" json:"attributes,omitempty"`
DomainMatcher string `protobuf:"bytes,17,opt,name=domain_matcher,json=domainMatcher,proto3" json:"domain_matcher,omitempty"`
UidList *net.UidList `protobuf:"bytes,18,opt,name=uid_list,json=uidList,proto3" json:"uid_list,omitempty"`
AppStatus []string `protobuf:"bytes,19,rep,name=app_status,json=appStatus,proto3" json:"app_status,omitempty"`
}
func (x *RoutingRule) Reset() {
@@ -684,6 +685,20 @@ func (x *RoutingRule) GetDomainMatcher() string {
return ""
}
func (x *RoutingRule) GetUidList() *net.UidList {
if x != nil {
return x.UidList
}
return nil
}
func (x *RoutingRule) GetAppStatus() []string {
if x != nil {
return x.AppStatus
}
return nil
}
type isRoutingRule_TargetTag interface {
isRoutingRule_TargetTag()
}
@@ -835,7 +850,6 @@ type Domain_Attribute struct {
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// Types that are assignable to TypedValue:
//
// *Domain_Attribute_BoolValue
// *Domain_Attribute_IntValue
TypedValue isDomain_Attribute_TypedValue `protobuf_oneof:"typed_value"`
@@ -925,133 +939,139 @@ var file_app_router_config_proto_rawDesc = []byte{
0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x1a, 0x15, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x02, 0x0a, 0x06,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x54, 0x79,
0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f,
0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69,
0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x1a,
0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f,
0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d,
0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a,
0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00,
0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10,
0x03, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65,
0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69,
0x78, 0x22, 0x7a, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x29, 0x0a,
0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49,
0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65,
0x72, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a,
0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x05, 0x65, 0x6e,
0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49,
0x50, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x5d, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53,
0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63,
0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52,
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3d, 0x0a, 0x0b, 0x47, 0x65, 0x6f, 0x53, 0x69,
0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x52,
0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xb5, 0x06, 0x0a, 0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69,
0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61,
0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28,
0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x54, 0x61,
0x67, 0x12, 0x2f, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x12, 0x2d, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x04, 0x63, 0x69, 0x64,
0x72, 0x12, 0x2c, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12,
0x3d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x42,
0x02, 0x18, 0x01, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x36,
0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x08, 0x70, 0x6f,
0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e,
0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x63, 0x69, 0x64, 0x72,
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x63, 0x6f, 0x6d,
0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x75, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0xb3, 0x02, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x12, 0x3f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72,
0x69, 0x62, 0x75, 0x74, 0x65, 0x1a, 0x6c, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x42, 0x0d, 0x0a, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x22, 0x32, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x50,
0x6c, 0x61, 0x69, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10,
0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x02, 0x12, 0x08, 0x0a,
0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x03, 0x22, 0x2e, 0x0a, 0x04, 0x43, 0x49, 0x44, 0x52, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12,
0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x7a, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50,
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43,
0x6f, 0x64, 0x65, 0x12, 0x29, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75,
0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x23,
0x0a, 0x0d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18,
0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x4d, 0x61,
0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74,
0x12, 0x2c, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x5d,
0x0a, 0x07, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2f, 0x0a, 0x06,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3d, 0x0a,
0x0b, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x05,
0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65,
0x6f, 0x53, 0x69, 0x74, 0x65, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x89, 0x07, 0x0a,
0x0b, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x03,
0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x74, 0x61, 0x67,
0x12, 0x25, 0x0a, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61,
0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x61, 0x6c, 0x61, 0x6e,
0x63, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2d, 0x0a, 0x04, 0x63, 0x69, 0x64, 0x72,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x49, 0x44, 0x52, 0x42, 0x02, 0x18,
0x01, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x69, 0x64, 0x72, 0x12, 0x39, 0x0a,
0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72,
0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x43, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x10, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x0e, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a,
0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x03, 0x28,
0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b,
0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52,
0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74,
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61,
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72,
0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x6a,
0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12,
0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61,
0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65,
0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75,
0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a,
0x0a, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f,
0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26,
0x01, 0x52, 0x04, 0x63, 0x69, 0x64, 0x72, 0x12, 0x2c, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70,
0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05,
0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x3d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x72, 0x61,
0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x52,
0x61, 0x6e, 0x67, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x73,
0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x0c,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73, 0x74,
0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x69, 0x73,
0x74, 0x12, 0x34, 0x0a, 0x08, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x18, 0x0d, 0x20,
0x03, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x08, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x12, 0x3a, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43,
0x49, 0x44, 0x52, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43,
0x69, 0x64, 0x72, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x67, 0x65,
0x6f, 0x69, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49,
0x50, 0x52, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x47, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x43,
0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69,
0x73, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x4c,
0x69, 0x73, 0x74, 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c,
0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69,
0x6c, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x45, 0x6d, 0x61,
0x69, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61,
0x67, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x54, 0x61, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18,
0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12,
0x25, 0x0a, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65,
0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d,
0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x08, 0x75, 0x69, 0x64, 0x5f, 0x6c, 0x69,
0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x55, 0x69, 0x64, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x07, 0x75, 0x69, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61,
0x70, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x13, 0x20, 0x03, 0x28, 0x09, 0x52,
0x09, 0x61, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x74, 0x61,
0x72, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x61, 0x67, 0x22, 0x6a, 0x0a, 0x0d, 0x42, 0x61, 0x6c, 0x61,
0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x2b, 0x0a, 0x11, 0x6f,
0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72,
0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x4f, 0x0a, 0x0f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c,
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72,
0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x30, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75,
0x6c, 0x65, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61,
0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74,
0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65,
0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22,
0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67,
0x79, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55,
0x73, 0x65, 0x49, 0x70, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f,
0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e,
0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50,
0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74,
0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70,
0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41,
0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x75,
0x6c, 0x65, 0x12, 0x45, 0x0a, 0x0e, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x5f,
0x72, 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x78, 0x72, 0x61,
0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x6c,
0x61, 0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x62, 0x61, 0x6c, 0x61,
0x6e, 0x63, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x22, 0x47, 0x0a, 0x0e, 0x44, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x41,
0x73, 0x49, 0x73, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x73, 0x65, 0x49, 0x70, 0x10, 0x01,
0x12, 0x10, 0x0a, 0x0c, 0x49, 0x70, 0x49, 0x66, 0x4e, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68,
0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x70, 0x4f, 0x6e, 0x44, 0x65, 0x6d, 0x61, 0x6e, 0x64,
0x10, 0x03, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61,
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x72, 0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x6f, 0x75,
0x74, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1085,6 +1105,7 @@ var file_app_router_config_proto_goTypes = []interface{}{
(*net.PortList)(nil), // 13: xray.common.net.PortList
(*net.NetworkList)(nil), // 14: xray.common.net.NetworkList
(net.Network)(0), // 15: xray.common.net.Network
(*net.UidList)(nil), // 16: xray.common.net.UidList
}
var file_app_router_config_proto_depIdxs = []int32{
0, // 0: xray.app.router.Domain.type:type_name -> xray.app.router.Domain.Type
@@ -1103,14 +1124,15 @@ var file_app_router_config_proto_depIdxs = []int32{
3, // 13: xray.app.router.RoutingRule.source_cidr:type_name -> xray.app.router.CIDR
4, // 14: xray.app.router.RoutingRule.source_geoip:type_name -> xray.app.router.GeoIP
13, // 15: xray.app.router.RoutingRule.source_port_list:type_name -> xray.common.net.PortList
1, // 16: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy
8, // 17: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule
9, // 18: xray.app.router.Config.balancing_rule:type_name -> xray.app.router.BalancingRule
19, // [19:19] is the sub-list for method output_type
19, // [19:19] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
16, // 16: xray.app.router.RoutingRule.uid_list:type_name -> xray.common.net.UidList
1, // 17: xray.app.router.Config.domain_strategy:type_name -> xray.app.router.Config.DomainStrategy
8, // 18: xray.app.router.Config.rule:type_name -> xray.app.router.RoutingRule
9, // 19: xray.app.router.Config.balancing_rule:type_name -> xray.app.router.BalancingRule
20, // [20:20] is the sub-list for method output_type
20, // [20:20] is the sub-list for method input_type
20, // [20:20] is the sub-list for extension type_name
20, // [20:20] is the sub-list for extension extendee
0, // [0:20] is the sub-list for field type_name
}
func init() { file_app_router_config_proto_init() }

View File

@@ -8,6 +8,7 @@ option java_multiple_files = true;
import "common/net/port.proto";
import "common/net/network.proto";
import "common/net/uid.proto";
// Domain for routing decision.
message Domain {
@@ -122,6 +123,10 @@ message RoutingRule {
string attributes = 15;
string domain_matcher = 17;
xray.common.net.UidList uid_list = 18;
repeated string app_status = 19;
}
message BalancingRule {

View File

@@ -29,7 +29,7 @@ type Route struct {
}
// Init initializes the Router.
func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm outbound.Manager) error {
func (r *Router) Init(config *Config, d dns.Client, ohm outbound.Manager) error {
r.domainStrategy = config.DomainStrategy
r.dns = d
@@ -39,7 +39,6 @@ func (r *Router) Init(ctx context.Context, config *Config, d dns.Client, ohm out
if err != nil {
return err
}
balancer.InjectContext(ctx)
r.balancers[rule.Tag] = balancer
}
@@ -122,7 +121,7 @@ func (*Router) Close() error {
return nil
}
// Type implements common.HasType.
// Type implement common.HasType.
func (*Router) Type() interface{} {
return routing.RouterType()
}
@@ -141,7 +140,7 @@ func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
r := new(Router)
if err := core.RequireFeatures(ctx, func(d dns.Client, ohm outbound.Manager) error {
return r.Init(ctx, config.(*Config), d, ohm)
return r.Init(config.(*Config), d, ohm)
}); err != nil {
return nil, err
}

View File

@@ -4,12 +4,14 @@ import (
"context"
"testing"
"github.com/xtls/xray-core/features/dns"
"github.com/golang/mock/gomock"
. "github.com/xtls/xray-core/app/router"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/features/dns"
"github.com/xtls/xray-core/features/outbound"
routing_session "github.com/xtls/xray-core/features/routing/session"
"github.com/xtls/xray-core/testing/mocks"
@@ -40,7 +42,7 @@ func TestSimpleRouter(t *testing.T) {
mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
r := new(Router)
common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
common.Must(r.Init(config, mockDNS, &mockOutboundManager{
Manager: mockOhm,
HandlerSelector: mockHs,
}))
@@ -81,7 +83,7 @@ func TestSimpleBalancer(t *testing.T) {
mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"})
r := new(Router)
common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
common.Must(r.Init(config, mockDNS, &mockOutboundManager{
Manager: mockOhm,
HandlerSelector: mockHs,
}))
@@ -123,7 +125,7 @@ func TestIPOnDemand(t *testing.T) {
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
r := new(Router)
common.Must(r.Init(context.TODO(), config, mockDNS, nil))
common.Must(r.Init(config, mockDNS, nil))
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
@@ -162,7 +164,7 @@ func TestIPIfNonMatchDomain(t *testing.T) {
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
r := new(Router)
common.Must(r.Init(context.TODO(), config, mockDNS, nil))
common.Must(r.Init(config, mockDNS, nil))
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
@@ -196,7 +198,7 @@ func TestIPIfNonMatchIP(t *testing.T) {
mockDNS := mocks.NewDNSClient(mockCtl)
r := new(Router)
common.Must(r.Init(context.TODO(), config, mockDNS, nil))
common.Must(r.Init(config, mockDNS, nil))
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))

View File

@@ -2,10 +2,10 @@ package router
import (
"context"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/extension"
)
@@ -15,17 +15,14 @@ type LeastPingStrategy struct {
}
func (l *LeastPingStrategy) InjectContext(ctx context.Context) {
common.Must(core.RequireFeatures(ctx, func(observatory extension.Observatory) error {
l.observatory = observatory
return nil
}))
l.ctx = ctx
}
func (l *LeastPingStrategy) PickOutbound(strings []string) string {
if l.observatory == nil {
common.Must(core.RequireFeatures(l.ctx, func(observatory extension.Observatory) error {
l.observatory = observatory
return nil
}))
}
observeReport, err := l.observatory.GetObservation(l.ctx)
if err != nil {
newError("cannot get observe report").Base(err).WriteToLog()
@@ -39,13 +36,12 @@ func (l *LeastPingStrategy) PickOutbound(strings []string) string {
for _, v := range status {
if outboundsList.contains(v.OutboundTag) && v.Alive && v.Delay < leastPing {
selectedOutboundName = v.OutboundTag
leastPing = v.Delay
}
}
return selectedOutboundName
}
// No way to understand observeReport
//No way to understand observeReport
return ""
}

View File

@@ -7,12 +7,13 @@ import (
"runtime"
"time"
grpc "google.golang.org/grpc"
"github.com/xtls/xray-core/app/stats"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/strmatcher"
"github.com/xtls/xray-core/core"
feature_stats "github.com/xtls/xray-core/features/stats"
grpc "google.golang.org/grpc"
)
// statsServer is an implementation of StatsService.

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/stats/command/command.proto

View File

@@ -1,8 +1,4 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.18.0
// source: app/stats/command/command.proto
package command

View File

@@ -6,6 +6,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/xtls/xray-core/app/stats"
. "github.com/xtls/xray-core/app/stats/command"
"github.com/xtls/xray-core/common"

View File

@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc-gen-go v1.27.1
// protoc v3.18.0
// source: app/stats/config.proto

View File

@@ -9,7 +9,7 @@ import (
const replayFilterCapacity = 100000
// ReplayFilter checks for replay attacks.
// ReplayFilter check for replay attacks.
type ReplayFilter struct {
lock sync.Mutex
poolA *cuckoo.Filter
@@ -31,7 +31,7 @@ func (filter *ReplayFilter) Interval() int64 {
return filter.interval
}
// Check determines if there are duplicate records.
// Check determine if there are duplicate records.
func (filter *ReplayFilter) Check(sum []byte) bool {
filter.lock.Lock()
defer filter.lock.Unlock()

View File

@@ -18,11 +18,10 @@ var pool = bytespool.GetPool(Size)
// the buffer into an internal buffer pool, in order to recreate a buffer more
// quickly.
type Buffer struct {
v []byte
start int32
end int32
unmanaged bool
UDP *net.Destination
v []byte
start int32
end int32
UDP *net.Destination
}
// New creates a Buffer with 0 length and 8K capacity.
@@ -39,7 +38,6 @@ func New() *Buffer {
}
}
// NewExisted creates a managed, standard size Buffer with an existed bytearray
func NewExisted(b []byte) *Buffer {
if cap(b) < Size {
panic("Invalid buffer")
@@ -56,15 +54,6 @@ func NewExisted(b []byte) *Buffer {
}
}
// FromBytes creates a Buffer with an existed bytearray
func FromBytes(b []byte) *Buffer {
return &Buffer{
v: b,
end: int32(len(b)),
unmanaged: true,
}
}
// StackNew creates a new Buffer object on stack.
// This method is for buffers that is released in the same function.
func StackNew() Buffer {
@@ -82,7 +71,7 @@ func StackNew() Buffer {
// Release recycles the buffer into an internal buffer pool.
func (b *Buffer) Release() {
if b == nil || b.v == nil || b.unmanaged {
if b == nil || b.v == nil {
return
}
@@ -223,28 +212,6 @@ func (b *Buffer) WriteString(s string) (int, error) {
return b.Write([]byte(s))
}
// ReadByte implements io.ByteReader
func (b *Buffer) ReadByte() (byte, error) {
if b.start == b.end {
return 0, io.EOF
}
nb := b.v[b.start]
b.start++
return nb, nil
}
// ReadBytes implements bufio.Reader.ReadBytes
func (b *Buffer) ReadBytes(length int32) ([]byte, error) {
if b.end-b.start < length {
return nil, io.EOF
}
nb := b.v[b.start : b.start+length]
b.start += length
return nb, nil
}
// Read implements io.Reader.Read().
func (b *Buffer) Read(data []byte) (int, error) {
if b.Len() == 0 {

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/xtls/xray-core/common"
. "github.com/xtls/xray-core/common/buf"
)

View File

@@ -48,7 +48,7 @@ func (e readError) Error() string {
return e.error.Error()
}
func (e readError) Unwrap() error {
func (e readError) Inner() error {
return e.error
}
@@ -66,7 +66,7 @@ func (e writeError) Error() string {
return e.error.Error()
}
func (e writeError) Unwrap() error {
func (e writeError) Inner() error {
return e.error
}

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/golang/mock/gomock"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/testing/mocks"

View File

@@ -53,7 +53,7 @@ func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {
return dest
}
// ReleaseMulti releases all content of the MultiBuffer, and returns an empty MultiBuffer.
// ReleaseMulti release all content of the MultiBuffer, and returns an empty MultiBuffer.
func ReleaseMulti(mb MultiBuffer) MultiBuffer {
for i := range mb {
mb[i].Release()
@@ -203,19 +203,6 @@ func SplitSize(mb MultiBuffer, size int32) (MultiBuffer, MultiBuffer) {
return mb, r
}
// SplitMulti splits the beginning of the MultiBuffer into first one, the index i and after into second one
func SplitMulti(mb MultiBuffer, i int) (MultiBuffer, MultiBuffer) {
mb2 := make(MultiBuffer, 0, len(mb))
if i < len(mb) && i >= 0 {
mb2 = append(mb2, mb[i:]...)
for j := i; j < len(mb); j++ {
mb[j] = nil
}
mb = mb[:i]
}
return mb, mb2
}
// WriteMultiBuffer writes all buffers from the MultiBuffer to the Writer one by one, and return error if any, with leftover MultiBuffer.
func WriteMultiBuffer(writer io.Writer, mb MultiBuffer) (MultiBuffer, error) {
for {
@@ -248,7 +235,7 @@ func (mb MultiBuffer) Len() int32 {
return size
}
// IsEmpty returns true if the MultiBuffer has no content.
// IsEmpty return true if the MultiBuffer has no content.
func (mb MultiBuffer) IsEmpty() bool {
for _, b := range mb {
if !b.IsEmpty() {
@@ -296,14 +283,14 @@ func (c *MultiBufferContainer) Write(b []byte) (int, error) {
return len(b), nil
}
// WriteMultiBuffer implements Writer.
// WriteMultiBuffer implement Writer.
func (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {
mb, _ := MergeMulti(c.MultiBuffer, b)
c.MultiBuffer = mb
return nil
}
// Close implements io.Closer.
// Close implement io.Closer.
func (c *MultiBufferContainer) Close() error {
c.MultiBuffer = ReleaseMulti(c.MultiBuffer)
return nil

View File

@@ -8,6 +8,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/xtls/xray-core/common"
. "github.com/xtls/xray-core/common/buf"
)

View File

@@ -7,8 +7,9 @@ import (
"io"
"syscall"
"github.com/xtls/xray-core/common/platform"
"github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/common/platform"
)
type allocStrategy struct {

View File

@@ -9,10 +9,12 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/sync/errgroup"
"github.com/xtls/xray-core/common"
. "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/testing/servers/tcp"
"golang.org/x/sync/errgroup"
)
func TestReadvReader(t *testing.T) {

View File

@@ -5,9 +5,10 @@ import (
"net"
"sync"
"github.com/xtls/xray-core/features/stats"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/features/stats"
)
// BufferToBytesWriter is a Writer that writes alloc.Buffer into underlying writer.

View File

@@ -8,6 +8,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/xtls/xray-core/common"
. "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/transport/pipe"

2
common/cache/lru.go vendored
View File

@@ -26,7 +26,7 @@ type lruElement struct {
value interface{}
}
// NewLru initializes a lru cache
// NewLru init a lru cache
func NewLru(cap int) Lru {
return &lru{
capacity: cap,

View File

@@ -2,8 +2,8 @@ package crypto
import (
"crypto/cipher"
"crypto/rand"
"io"
"math/rand"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
@@ -39,6 +39,10 @@ func GenerateIncreasingNonce(nonce []byte) BytesGenerator {
}
}
func GenerateInitialAEADNonce() BytesGenerator {
return GenerateIncreasingNonce([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
}
func GenerateAEADNonceWithSize(nonceSize int) BytesGenerator {
c := make([]byte, nonceSize)
for i := 0; i < nonceSize; i++ {
@@ -265,8 +269,7 @@ func (w *AuthenticationWriter) seal(b []byte) (*buf.Buffer, error) {
return nil, err
}
if paddingSize > 0 {
// These paddings will send in clear text.
// To avoid leakage of PRNG internal state, a cryptographically secure PRNG should be used.
// With size of the chunk and padding length encrypted, the content of padding doesn't matter much.
paddingBytes := eb.Extend(paddingSize)
common.Must2(rand.Read(paddingBytes))
}

View File

@@ -9,6 +9,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf"
. "github.com/xtls/xray-core/common/crypto"

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/xtls/xray-core/common"
. "github.com/xtls/xray-core/common/crypto"
)

View File

@@ -1,10 +0,0 @@
package drain
import "io"
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
type Drainer interface {
AcknowledgeReceive(size int)
Drain(reader io.Reader) error
}

View File

@@ -1,62 +0,0 @@
package drain
import (
"io"
"io/ioutil"
"github.com/xtls/xray-core/common/dice"
)
type BehaviorSeedLimitedDrainer struct {
DrainSize int
}
func NewBehaviorSeedLimitedDrainer(behaviorSeed int64, drainFoundation, maxBaseDrainSize, maxRandDrain int) (Drainer, error) {
behaviorRand := dice.NewDeterministicDice(behaviorSeed)
BaseDrainSize := behaviorRand.Roll(maxBaseDrainSize)
RandDrainMax := behaviorRand.Roll(maxRandDrain) + 1
RandDrainRolled := dice.Roll(RandDrainMax)
DrainSize := drainFoundation + BaseDrainSize + RandDrainRolled
return &BehaviorSeedLimitedDrainer{DrainSize: DrainSize}, nil
}
func (d *BehaviorSeedLimitedDrainer) AcknowledgeReceive(size int) {
d.DrainSize -= size
}
func (d *BehaviorSeedLimitedDrainer) Drain(reader io.Reader) error {
if d.DrainSize > 0 {
err := drainReadN(reader, d.DrainSize)
if err == nil {
return newError("drained connection")
}
return newError("unable to drain connection").Base(err)
}
return nil
}
func drainReadN(reader io.Reader, n int) error {
_, err := io.CopyN(ioutil.Discard, reader, int64(n))
return err
}
func WithError(drainer Drainer, reader io.Reader, err error) error {
drainErr := drainer.Drain(reader)
if drainErr == nil {
return err
}
return newError(drainErr).Base(err)
}
type NopDrainer struct{}
func (n NopDrainer) AcknowledgeReceive(size int) {
}
func (n NopDrainer) Drain(reader io.Reader) error {
return nil
}
func NewNopDrainer() Drainer {
return &NopDrainer{}
}

Some files were not shown because too many files have changed in this diff Show More