Compare commits

..

No commits in common. "main" and "v1.8.7" have entirely different histories.
main ... v1.8.7

588 changed files with 13425 additions and 17431 deletions

View File

@ -1,87 +0,0 @@
name: Bug report
description: "Submit Xray-core bug"
body:
- type: checkboxes
attributes:
label: Integrity requirements
description: |-
Please check all of the following options to prove that you have read and understood the requirements, otherwise this issue will be closed.
options:
- label: I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
required: true
- label: I provided the complete config and logs, rather than just providing the truncated parts based on my own judgment.
required: true
- label: I searched issues and did not find any similar issues.
required: true
- label: The problem can be successfully reproduced in the latest Release
required: true
- type: textarea
attributes:
label: Description
description: |-
Please provide a detailed description of the error. And the information you think valuable.
If the problem occurs after the update, please provide the **specific** version
validations:
required: true
- type: textarea
attributes:
label: Reproduction Method
description: |-
Based on the configuration you provided below, provide the method to reproduce the bug.
validations:
required: true
- type: markdown
attributes:
value: |-
## Configuration and Log Section
### For config
Please provide the configuration files that can reproduce the problem, including the server and client.
Don't just paste a big exported config file here. Eliminate useless inbound/outbound, rules, options, this can help determine the problem, if you really want to get help.
### For logs
Please set the log level to debug and dnsLog to true first.
Restart Xray-core, then operate according to the reproduction method, try to reduce the irrelevant part in the log.
Remember to delete parts with personal information (such as UUID and IP).
Provide the log of Xray-core, not the log output by the panel or other things.
### Finally
After removing parts that do not affect reproduction, provide the actual running **complete** file, do not only provide inbound or outbound or a few lines of logs based on your own judgment.
Put the content between the preset ```<details><pre><code>``` ```</code></pre></details>``` in the text box.
If the problem is very clear that only related to one end (such as core startup failure/crash after correctly writing the config according to the documents), N/A can be filled in for unnecessary areas below.
- type: textarea
attributes:
label: Client config
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: Server config
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: Client log
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: Server log
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true

View File

@ -1,87 +0,0 @@
name: bug反馈
description: "提交 Xray-core bug"
body:
- type: checkboxes
attributes:
label: 完整性要求
description: |-
请勾选以下所有选项以证明您已经阅读并理解了以下要求,否则该 issue 将被关闭。
options:
- label: 我保证阅读了文档,了解所有我编写的配置文件项的含义,而不是大量堆砌看似有用的选项或默认值。
required: true
- label: 我提供了完整的配置文件和日志,而不是出于自己的判断只给出截取的部分。
required: true
- label: 我搜索了 issues, 没有发现已提出的类似问题。
required: true
- label: 问题在 Release 最新的版本上可以成功复现
required: true
- type: textarea
attributes:
label: 描述
description: |-
请提供错误的详细描述。以及你认为有价值的信息。
如果问题在更新后出现,请提供**具体**出现问题的版本号。
validations:
required: true
- type: textarea
attributes:
label: 重现方式
description: |-
基于你下面提供的配置提供重现BUG方法。
validations:
required: true
- type: markdown
attributes:
value: |-
## 配置与日志部分
### 对于配置文件
请提供可以重现问题的配置文件,包括服务端和客户端。
不要直接在这里黏贴一大段导出的 config 文件。去掉无用的出入站、规则、选项,这可以帮助确定问题,如果你真的想得到帮助。
### 对于日志
请先将日志等级设置为 debug, dnsLog 设置为true.
重启 Xray-core ,再按复现方式操作,尽量减少日志中的无关部分。
记得删除有关个人信息如UUID与IP的部分。
提供 Xray-core 的日志,而不是面板或者别的东西输出的日志。
### 最后
在去掉不影响复现的部分后,提供实际运行的**完整**文件,不要出于自己的判断只提供入站出站或者几行日志。
把内容放在文本框预置的 ```<details><pre><code>``` 和 ```</code></pre></details>``` 中间。
如果问题十分明确只出现在某一端(如按文档正确编写配置后核心启动失败/崩溃)可以在下面不需要的项目填入N/A.
- type: textarea
attributes:
label: 客户端配置
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: 服务端配置
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: 客户端日志
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true
- type: textarea
attributes:
label: 服务端日志
value: |-
<details><pre><code>
</code></pre></details>
validations:
required: true

View File

@ -1,4 +0,0 @@
contact_links:
- name: Community Support and Questions
url: https://github.com/XTLS/Xray-core/discussions
about: Please ask and answer questions there. The issue tracker is for issues with core.

View File

@ -2,27 +2,21 @@
FROM --platform=$BUILDPLATFORM golang:alpine AS build FROM --platform=$BUILDPLATFORM golang:alpine AS build
WORKDIR /src WORKDIR /src
COPY . . COPY . .
ARG TARGETOS ARG TARGETOS TARGETARCH
ARG TARGETARCH
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
ADD https://github.com/v2fly/geoip/releases/latest/download/geoip.dat /v2fly/geoip.dat
ADD https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat /v2fly/geosite.dat
ADD https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat /loyalsoldier/geoip.dat
ADD https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat /loyalsoldier/geosite.dat
# chainguard/static contains only tzdata and ca-certificates, can be built with multiarch static binaries. FROM --platform=${TARGETPLATFORM} alpine:latest
FROM --platform=linux/amd64 chainguard/static:latest
WORKDIR /var/log/xray
COPY .github/docker/files/config.json /etc/xray/config.json
COPY --from=build --chmod=755 /src/xray /usr/bin/xray
USER root
WORKDIR /root WORKDIR /root
VOLUME /etc/xray COPY .github/docker/files/config.json /etc/xray/config.json
ARG TZ=Asia/Shanghai COPY --from=build /src/xray /usr/bin/xray
ENV TZ=$TZ RUN set -ex \
ENTRYPOINT [ "/usr/bin/xray" ] && apk add --no-cache tzdata ca-certificates \
CMD [ "-confdir", "/etc/xray/" ] && mkdir -p /var/log/xray /usr/share/xray \
&& chmod +x /usr/bin/xray \
&& wget -O /usr/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat \
&& wget -O /usr/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
ARG flavor=v2fly VOLUME /etc/xray
COPY --from=build --chmod=644 /$flavor /usr/share/xray ENV TZ=Asia/Shanghai
ENTRYPOINT [ "/usr/bin/xray" ]
CMD [ "-config", "/etc/xray/config.json" ]

View File

@ -1,8 +1,6 @@
name: Build docker image name: Build docker image
on: on:
release:
types: [published]
push: push:
branches: branches:
- main - main
@ -19,22 +17,8 @@ jobs:
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ghcr.io/${{ github.repository_owner }}/xray-core images: ghcr.io/${{ github.repository_owner }}/xray-core
flavor: latest=auto flavor: latest=true
tags: | tags: |
type=sha
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
- name: Docker metadata Loyalsoldier flavor
id: loyalsoldier
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/xray-core
flavor: |
latest=auto
suffix=-ls,onlatest=true
tags: |
type=sha
type=ref,event=branch type=ref,event=branch
type=ref,event=pr type=ref,event=pr
type=semver,pattern={{version}} type=semver,pattern={{version}}
@ -44,33 +28,18 @@ jobs:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- # Add support for more platforms with QEMU (optional)
# https://github.com/docker/setup-qemu-action
name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Build and push - name: Build and push
uses: docker/build-push-action@v6 uses: docker/build-push-action@v5
with: with:
context: . context: .
platforms: | platforms: linux/amd64,linux/arm64
linux/amd64
linux/arm64
linux/loong64
linux/riscv64
provenance: false
file: .github/docker/Dockerfile file: .github/docker/Dockerfile
push: true push: true
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
- name: Build and push Loyalsoldier flavor labels: ${{ steps.meta.outputs.labels }}
uses: docker/build-push-action@v6
with:
context: .
platforms: |
linux/amd64
linux/arm64
linux/loong64
linux/riscv64
provenance: false
file: .github/docker/Dockerfile
build-args: flavor=loyalsoldier
push: true
tags: |
${{ steps.loyalsoldier.outputs.tags }}

View File

@ -1,11 +1,5 @@
name: Build and Release name: Build and Release
# NOTE: This Github Actions file depends on the Makefile.
# Building the correct package requires the correct binaries generated by the Makefile. To
# ensure the correct output, the Makefile must accept the appropriate input and compile the
# correct file with the correct name. If you need to modify this file, please ensure it won't
# disrupt the Makefile.
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
@ -17,27 +11,27 @@ on:
- "**/*.go" - "**/*.go"
- "go.mod" - "go.mod"
- "go.sum" - "go.sum"
- ".github/workflows/release.yml" - ".github/workflows/*.yml"
pull_request: pull_request:
types: [opened, synchronize, reopened] types: [opened, synchronize, reopened]
paths: paths:
- "**/*.go" - "**/*.go"
- "go.mod" - "go.mod"
- "go.sum" - "go.sum"
- ".github/workflows/release.yml" - ".github/workflows/*.yml"
jobs: jobs:
prepare: prepare:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Restore Cache - name: Restore Cache
uses: actions/cache/restore@v4 uses: actions/cache/restore@v3
with: with:
path: resources path: resources
key: xray-geodat- key: xray-geodat-
- name: Update Geodat - name: Update Geodat
id: update id: update
uses: nick-fields/retry@v3 uses: nick-fields/retry@v2
with: with:
timeout_minutes: 60 timeout_minutes: 60
retry_wait_seconds: 60 retry_wait_seconds: 60
@ -63,7 +57,7 @@ jobs:
done done
- name: Save Cache - name: Save Cache
uses: actions/cache/save@v4 uses: actions/cache/save@v3
if: ${{ steps.update.outputs.unhit }} if: ${{ steps.update.outputs.unhit }}
with: with:
path: resources path: resources
@ -78,15 +72,12 @@ jobs:
# Include amd64 on all platforms. # Include amd64 on all platforms.
goos: [windows, freebsd, openbsd, linux, darwin] goos: [windows, freebsd, openbsd, linux, darwin]
goarch: [amd64, 386] goarch: [amd64, 386]
gotoolchain: [""]
patch-assetname: [""]
exclude: exclude:
# Exclude i386 on darwin # Exclude i386 on darwin
- goarch: 386 - goarch: 386
goos: darwin goos: darwin
include: include:
# BEGIN MacOS ARM64 # BEIGIN MacOS ARM64
- goos: darwin - goos: darwin
goarch: arm64 goarch: arm64
# END MacOS ARM64 # END MacOS ARM64
@ -155,16 +146,6 @@ jobs:
goarch: arm goarch: arm
goarm: 7 goarm: 7
# END OPENBSD ARM # END OPENBSD ARM
# BEGIN Windows 7
- goos: windows
goarch: amd64
gotoolchain: 1.21.4
patch-assetname: win7-64
- goos: windows
goarch: 386
gotoolchain: 1.21.4
patch-assetname: win7-32
# END Windows 7
fail-fast: false fail-fast: false
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -179,15 +160,14 @@ jobs:
- name: Show workflow information - name: Show workflow information
run: | run: |
_NAME=${{ matrix.patch-assetname }} export _NAME=$(jq ".[\"$GOOS-$GOARCH$GOARM$GOMIPS\"].friendlyName" -r < .github/build/friendly-filenames.json)
[ -n "$_NAME" ] || _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 "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, GOMIPS: $GOMIPS, RELEASE_NAME: $_NAME"
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: ${{ matrix.gotoolchain || '1.23' }} go-version: '1.21'
check-latest: true check-latest: true
- name: Get project dependencies - name: Get project dependencies
@ -197,10 +177,10 @@ jobs:
run: | run: |
mkdir -p build_assets mkdir -p build_assets
make make
find . -maxdepth 1 -type f -regex './\(wxray\|xray\|xray_softfloat\)\(\|.exe\)' -exec mv {} ./build_assets/ \; find . -maxdepth 1 -type f -regex '.*\(wxray\|xray\|xray_softfloat\)\(\|.exe\)' -exec mv {} ./build_assets/ \;
- name: Restore Cache - name: Restore Cache
uses: actions/cache/restore@v4 uses: actions/cache/restore@v3
with: with:
path: resources path: resources
key: xray-geodat- key: xray-geodat-
@ -212,7 +192,6 @@ jobs:
cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE cp ${GITHUB_WORKSPACE}/LICENSE ./build_assets/LICENSE
- name: Create ZIP archive - name: Create ZIP archive
if: github.event_name == 'release'
shell: bash shell: bash
run: | run: |
pushd build_assets || exit 1 pushd build_assets || exit 1

View File

@ -27,15 +27,15 @@ jobs:
matrix: matrix:
os: [windows-latest, ubuntu-latest, macos-latest] os: [windows-latest, ubuntu-latest, macos-latest]
steps: steps:
- name: Checkout codebase
uses: actions/checkout@v4
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.23' go-version: '1.21'
check-latest: true check-latest: true
- name: Checkout codebase
uses: actions/checkout@v4
- name: Restore Cache - name: Restore Cache
uses: actions/cache/restore@v4 uses: actions/cache/restore@v3
with: with:
path: resources path: resources
key: xray-geodat- key: xray-geodat-

3
.gitignore vendored
View File

@ -28,6 +28,3 @@ errorgen
*.dat *.dat
.vscode .vscode
/build_assets /build_assets
# Output from dlv test
**/debug.*

View File

@ -2,17 +2,6 @@ NAME = xray
VERSION=$(shell git describe --always --dirty) VERSION=$(shell git describe --always --dirty)
# NOTE: This MAKEFILE can be used to build Xray-core locally and in Automatic workflows. It is \
provided for convenience in automatic building and functions as a part of it.
# NOTE: If you need to modify this file, please be aware that:\
- This file is not the main Makefile; it only accepts environment variables and builds the \
binary.\
- Automatic building expects the correct binaries to be built by this Makefile. If you \
intend to propose a change to this Makefile, carefully review the file below and ensure \
that the change will not accidentally break the automatic building:\
.github/workflows/release.yml \
Otherwise it is recommended to contact the project maintainers.
LDFLAGS = -X github.com/xtls/xray-core/core.build=$(VERSION) -s -w -buildid= LDFLAGS = -X github.com/xtls/xray-core/core.build=$(VERSION) -s -w -buildid=
PARAMS = -trimpath -ldflags "$(LDFLAGS)" -v PARAMS = -trimpath -ldflags "$(LDFLAGS)" -v
MAIN = ./main MAIN = ./main
@ -23,15 +12,18 @@ ADDITION = go build -o w$(NAME).exe -trimpath -ldflags "-H windowsgui $(LDFLAGS)
else else
OUTPUT = $(NAME) OUTPUT = $(NAME)
endif endif
ifeq ($(shell echo "$(GOARCH)" | grep -Eq "(mips|mipsle)" && echo true),true) # ifeq ($(shell echo "$(GOARCH)" | grep -Pq "(mips|mipsle)" && echo true),true) #
ADDITION = GOMIPS=softfloat go build -o $(NAME)_softfloat -trimpath -ldflags "$(LDFLAGS)" -v $(MAIN) ADDITION = GOMIPS=softfloat go build -o $(NAME)_softfloat -trimpath -ldflags "$(LDFLAGS)" -v $(MAIN)
endif endif
.PHONY: clean build .PHONY: clean
build: build:
go build -o $(OUTPUT) $(PARAMS) $(MAIN) go build -o $(OUTPUT) $(PARAMS) $(MAIN)
$(ADDITION) $(ADDITION)
install:
go build -o $(PREFIX)/bin/$(OUTPUT) $(PARAMS) $(MAIN)
clean: clean:
go clean -v -i $(PWD) go clean -v -i $(PWD)
rm -f xray xray.exe wxray.exe xray_softfloat rm -f xray xray.exe wxray.exe xray_softfloat

View File

@ -4,10 +4,6 @@
[README](https://github.com/XTLS/Xray-core#readme) is open, so feel free to submit your project [here](https://github.com/XTLS/Xray-core/pulls). [README](https://github.com/XTLS/Xray-core#readme) is open, so feel free to submit your project [here](https://github.com/XTLS/Xray-core/pulls).
## Donation & NFTs
[Announcement of NFTs by Project X](https://github.com/XTLS/Xray-core/discussions/3633)
## License ## License
[Mozilla Public License Version 2.0](https://github.com/XTLS/Xray-core/blob/main/LICENSE) [Mozilla Public License Version 2.0](https://github.com/XTLS/Xray-core/blob/main/LICENSE)
@ -22,24 +18,23 @@
[Project X Channel](https://t.me/projectXtls) [Project X Channel](https://t.me/projectXtls)
[Project VLESS](https://t.me/projectVless) (non-Chinese)
## Installation ## Installation
- Linux Script - Linux Script
- [XTLS/Xray-install](https://github.com/XTLS/Xray-install) (**Official**) - [XTLS/Xray-install](https://github.com/XTLS/Xray-install)
- [tempest](https://github.com/team-cloudchaser/tempest) (supports [`systemd`](https://systemd.io) and [OpenRC](https://github.com/OpenRC/openrc); Linux-only)
- Docker - Docker
- [ghcr.io/xtls/xray-core](https://ghcr.io/xtls/xray-core) (**Official**) - Official: [ghcr.io/xtls/xray-core](https://ghcr.io/xtls/xray-core)
- [iamybj/docker-xray](https://hub.docker.com/r/iamybj/docker-xray)
- [teddysun/xray](https://hub.docker.com/r/teddysun/xray) - [teddysun/xray](https://hub.docker.com/r/teddysun/xray)
- [wulabing/xray_docker](https://github.com/wulabing/xray_docker) - Web Panel
- Web Panel - **WARNING: Please DO NOT USE plain HTTP panels like 3X-UI**, as they are believed to be bribed by Iran GFW for supporting plain HTTP by default and refused to change (https://github.com/XTLS/Xray-core/pull/3884#issuecomment-2439595331), which has already put many users' data security in danger in the past few years. **If you are already using 3X-UI, please switch to the following panels, which are verified to support HTTPS and SSH port forwarding only:** - [X-UI-English](https://github.com/NidukaAkalanka/x-ui-english), [3X-UI](https://github.com/MHSanaei/3x-ui), [X-UI](https://github.com/alireza0/x-ui), [X-UI](https://github.com/diditra/x-ui)
- [Xray-UI](https://github.com/qist/xray-ui), [X-UI](https://github.com/sing-web/x-ui)
- [Hiddify](https://github.com/hiddify/hiddify-config)
- [Marzban](https://github.com/Gozargah/Marzban) - [Marzban](https://github.com/Gozargah/Marzban)
- [Xray-UI](https://github.com/qist/xray-ui) - [Libertea](https://github.com/VZiChoushaDui/Libertea)
- [Hiddify](https://github.com/hiddify/Hiddify-Manager)
- One Click - One Click
- [Xray-REALITY](https://github.com/zxcvos/Xray-script), [xray-reality](https://github.com/sajjaddg/xray-reality), [reality-ezpz](https://github.com/aleskxyz/reality-ezpz) - [Xray-REALITY](https://github.com/zxcvos/Xray-script), [xray-reality](https://github.com/sajjaddg/xray-reality), [reality-ezpz](https://github.com/aleskxyz/reality-ezpz)
- [Xray_bash_onekey](https://github.com/hello-yunshu/Xray_bash_onekey), [XTool](https://github.com/LordPenguin666/XTool) - [Xray-script](https://github.com/kirin10000/Xray-script), [Xray_bash_onekey](https://github.com/hello-yunshu/Xray_bash_onekey), [XTool](https://github.com/LordPenguin666/XTool)
- [v2ray-agent](https://github.com/mack-a/v2ray-agent), [Xray_onekey](https://github.com/wulabing/Xray_onekey), [ProxySU](https://github.com/proxysu/ProxySU) - [v2ray-agent](https://github.com/mack-a/v2ray-agent), [Xray_onekey](https://github.com/wulabing/Xray_onekey), [ProxySU](https://github.com/proxysu/ProxySU)
- Magisk - Magisk
- [Xray4Magisk](https://github.com/Asterisk4Magisk/Xray4Magisk) - [Xray4Magisk](https://github.com/Asterisk4Magisk/Xray4Magisk)
@ -72,13 +67,16 @@
- [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray)) - [luci-app-xray](https://github.com/yichya/luci-app-xray) ([openwrt-xray](https://github.com/yichya/openwrt-xray))
- Windows - Windows
- [v2rayN](https://github.com/2dust/v2rayN) - [v2rayN](https://github.com/2dust/v2rayN)
- [NekoRay](https://github.com/Matsuridayo/nekoray)
- [Furious](https://github.com/LorenEteval/Furious) - [Furious](https://github.com/LorenEteval/Furious)
- [HiddifyN](https://github.com/hiddify/HiddifyN)
- [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient) - [Invisible Man - Xray](https://github.com/InvisibleManVPN/InvisibleMan-XRayClient)
- Android - Android
- [v2rayNG](https://github.com/2dust/v2rayNG) - [v2rayNG](https://github.com/2dust/v2rayNG)
- [HiddifyNG](https://github.com/hiddify/HiddifyNG)
- [X-flutter](https://github.com/XTLS/X-flutter) - [X-flutter](https://github.com/XTLS/X-flutter)
- [SaeedDev94/Xray](https://github.com/SaeedDev94/Xray)
- iOS & macOS arm64 - iOS & macOS arm64
- [Mango](https://github.com/arror/Mango)
- [FoXray](https://apps.apple.com/app/foxray/id6448898396) - [FoXray](https://apps.apple.com/app/foxray/id6448898396)
- [Streisand](https://apps.apple.com/app/streisand/id6450534064) - [Streisand](https://apps.apple.com/app/streisand/id6450534064)
- macOS arm64 & x64 - macOS arm64 & x64
@ -88,6 +86,7 @@
- [FoXray](https://apps.apple.com/app/foxray/id6448898396) - [FoXray](https://apps.apple.com/app/foxray/id6448898396)
- Linux - Linux
- [v2rayA](https://github.com/v2rayA/v2rayA) - [v2rayA](https://github.com/v2rayA/v2rayA)
- [NekoRay](https://github.com/Matsuridayo/nekoray)
- [Furious](https://github.com/LorenEteval/Furious) - [Furious](https://github.com/LorenEteval/Furious)
## Others that support VLESS, XTLS, REALITY, XUDP, PLUX... ## Others that support VLESS, XTLS, REALITY, XUDP, PLUX...
@ -100,15 +99,20 @@
- [XTLS/libXray](https://github.com/XTLS/libXray) - [XTLS/libXray](https://github.com/XTLS/libXray)
- [xtlsapi](https://github.com/hiddify/xtlsapi) - [xtlsapi](https://github.com/hiddify/xtlsapi)
- [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite) - [AndroidLibXrayLite](https://github.com/2dust/AndroidLibXrayLite)
- [XrayKit](https://github.com/arror/XrayKit)
- [Xray-core-python](https://github.com/LorenEteval/Xray-core-python) - [Xray-core-python](https://github.com/LorenEteval/Xray-core-python)
- [xray-api](https://github.com/XVGuardian/xray-api)
- [XrayR](https://github.com/XrayR-project/XrayR) - [XrayR](https://github.com/XrayR-project/XrayR)
- [XrayR-release](https://github.com/XrayR-project/XrayR-release) - [XrayR-release](https://github.com/XrayR-project/XrayR-release)
- [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board) - [XrayR-V2Board](https://github.com/missuo/XrayR-V2Board)
- [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta) - [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
- [Clash Verge](https://github.com/zzzgydi/clash-verge)
- [clashN](https://github.com/2dust/clashN) - [clashN](https://github.com/2dust/clashN)
- [Clash Meta for Android](https://github.com/MetaCubeX/ClashMetaForAndroid) - [Clash Meta for Android](https://github.com/MetaCubeX/ClashMetaForAndroid)
- [meta_for_ios](https://t.me/meta_for_ios)
- [sing-box](https://github.com/SagerNet/sing-box) - [sing-box](https://github.com/SagerNet/sing-box)
- [installReality](https://github.com/BoxXt/installReality)
- [sbox-reality](https://github.com/Misaka-blog/sbox-reality)
- [sing-box-for-ios](https://github.com/SagerNet/sing-box-for-ios)
## Contributing ## Contributing
@ -121,21 +125,6 @@
## Compilation ## Compilation
### Windows (PowerShell)
```powershell
$env:CGO_ENABLED=0
go build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main
```
### Linux / macOS
```bash
CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
```
### Reproducible Releases
```bash ```bash
make make
``` ```

View File

@ -1,12 +1,13 @@
package commander package commander
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"net" "net"
"sync" "sync"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/common/signal/done"
core "github.com/xtls/xray-core/core" core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/outbound"
@ -20,14 +21,12 @@ type Commander struct {
services []Service services []Service
ohm outbound.Manager ohm outbound.Manager
tag string tag string
listen string
} }
// NewCommander creates a new Commander based on the given config. // NewCommander creates a new Commander based on the given config.
func NewCommander(ctx context.Context, config *Config) (*Commander, error) { func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
c := &Commander{ c := &Commander{
tag: config.Tag, tag: config.Tag,
listen: config.Listen,
} }
common.Must(core.RequireFeatures(ctx, func(om outbound.Manager) { common.Must(core.RequireFeatures(ctx, func(om outbound.Manager) {
@ -45,7 +44,7 @@ func NewCommander(ctx context.Context, config *Config) (*Commander, error) {
} }
service, ok := rawService.(Service) service, ok := rawService.(Service)
if !ok { if !ok {
return nil, errors.New("not a Service.") return nil, newError("not a Service.")
} }
c.services = append(c.services, service) c.services = append(c.services, service)
} }
@ -67,32 +66,19 @@ func (c *Commander) Start() error {
} }
c.Unlock() c.Unlock()
var listen = func(listener net.Listener) {
if err := c.server.Serve(listener); err != nil {
errors.LogErrorInner(context.Background(), err, "failed to start grpc server")
}
}
if len(c.listen) > 0 {
if l, err := net.Listen("tcp", c.listen); err != nil {
errors.LogErrorInner(context.Background(), err, "API server failed to listen on ", c.listen)
return err
} else {
errors.LogInfo(context.Background(), "API server listening on ", l.Addr())
go listen(l)
}
return nil
}
listener := &OutboundListener{ listener := &OutboundListener{
buffer: make(chan net.Conn, 4), buffer: make(chan net.Conn, 4),
done: done.New(), done: done.New(),
} }
go listen(listener) go func() {
if err := c.server.Serve(listener); err != nil {
newError("failed to start grpc server").Base(err).AtError().WriteToLog()
}
}()
if err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil { if err := c.ohm.RemoveHandler(context.Background(), c.tag); err != nil {
errors.LogInfoInner(context.Background(), err, "failed to remove existing handler") newError("failed to remove existing handler").WriteToLog()
} }
return c.ohm.AddHandler(context.Background(), &Outbound{ return c.ohm.AddHandler(context.Background(), &Outbound{

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/commander/config.proto // source: app/commander/config.proto
package commander package commander
@ -29,8 +29,6 @@ type Config struct {
// Tag of the outbound handler that handles grpc connections. // Tag of the outbound handler that handles grpc connections.
Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` Tag string `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"`
// Network address of commander grpc service.
Listen string `protobuf:"bytes,3,opt,name=listen,proto3" json:"listen,omitempty"`
// Services that supported by this server. All services must implement Service // Services that supported by this server. All services must implement Service
// interface. // interface.
Service []*serial.TypedMessage `protobuf:"bytes,2,rep,name=service,proto3" json:"service,omitempty"` Service []*serial.TypedMessage `protobuf:"bytes,2,rep,name=service,proto3" json:"service,omitempty"`
@ -38,9 +36,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_commander_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_commander_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -51,7 +51,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_commander_config_proto_msgTypes[0] mi := &file_app_commander_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -73,13 +73,6 @@ func (x *Config) GetTag() string {
return "" return ""
} }
func (x *Config) GetListen() string {
if x != nil {
return x.Listen
}
return ""
}
func (x *Config) GetService() []*serial.TypedMessage { func (x *Config) GetService() []*serial.TypedMessage {
if x != nil { if x != nil {
return x.Service return x.Service
@ -96,9 +89,11 @@ type ReflectionConfig struct {
func (x *ReflectionConfig) Reset() { func (x *ReflectionConfig) Reset() {
*x = ReflectionConfig{} *x = ReflectionConfig{}
mi := &file_app_commander_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_commander_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *ReflectionConfig) String() string { func (x *ReflectionConfig) String() string {
@ -109,7 +104,7 @@ func (*ReflectionConfig) ProtoMessage() {}
func (x *ReflectionConfig) ProtoReflect() protoreflect.Message { func (x *ReflectionConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_commander_config_proto_msgTypes[1] mi := &file_app_commander_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -132,21 +127,20 @@ var file_app_commander_config_proto_rawDesc = []byte{
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72,
0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2f, 0x1a, 0x21, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2f,
0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x74, 0x79, 0x70, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x6e, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x6f, 0x74, 0x6f, 0x22, 0x56, 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, 0x12, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12,
0x16, 0x0a, 0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x3a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x06, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x12, 0x3a, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73,
0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x67, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x52,
0x70, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42,
0x69, 0x63, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x58, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x58, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
0x72, 0x50, 0x01, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x12, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e,
0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0xaa, 0x02, 0x12, 0x58, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x65, 0x33,
0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -162,7 +156,7 @@ func file_app_commander_config_proto_rawDescGZIP() []byte {
} }
var file_app_commander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_app_commander_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_app_commander_config_proto_goTypes = []any{ var file_app_commander_config_proto_goTypes = []interface{}{
(*Config)(nil), // 0: xray.app.commander.Config (*Config)(nil), // 0: xray.app.commander.Config
(*ReflectionConfig)(nil), // 1: xray.app.commander.ReflectionConfig (*ReflectionConfig)(nil), // 1: xray.app.commander.ReflectionConfig
(*serial.TypedMessage)(nil), // 2: xray.common.serial.TypedMessage (*serial.TypedMessage)(nil), // 2: xray.common.serial.TypedMessage
@ -181,6 +175,32 @@ func file_app_commander_config_proto_init() {
if File_app_commander_config_proto != nil { if File_app_commander_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_commander_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
}
}
file_app_commander_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReflectionConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -12,10 +12,6 @@ import "common/serial/typed_message.proto";
message Config { message Config {
// Tag of the outbound handler that handles grpc connections. // Tag of the outbound handler that handles grpc connections.
string tag = 1; string tag = 1;
// Network address of commander grpc service.
string listen = 3;
// Services that supported by this server. All services must implement Service // Services that supported by this server. All services must implement Service
// interface. // interface.
repeated xray.common.serial.TypedMessage service = 2; repeated xray.common.serial.TypedMessage service = 2;

View File

@ -0,0 +1,9 @@
package commander
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

@ -5,7 +5,6 @@ import (
"sync" "sync"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/common/signal/done"
@ -32,7 +31,7 @@ func (l *OutboundListener) add(conn net.Conn) {
func (l *OutboundListener) Accept() (net.Conn, error) { func (l *OutboundListener) Accept() (net.Conn, error) {
select { select {
case <-l.done.Wait(): case <-l.done.Wait():
return nil, errors.New("listen closed") return nil, newError("listen closed")
case c := <-l.buffer: case c := <-l.buffer:
return c, nil return c, nil
} }

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/dispatcher/config.proto // source: app/dispatcher/config.proto
package dispatcher package dispatcher
@ -28,9 +28,11 @@ type SessionConfig struct {
func (x *SessionConfig) Reset() { func (x *SessionConfig) Reset() {
*x = SessionConfig{} *x = SessionConfig{}
mi := &file_app_dispatcher_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dispatcher_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *SessionConfig) String() string { func (x *SessionConfig) String() string {
@ -41,7 +43,7 @@ func (*SessionConfig) ProtoMessage() {}
func (x *SessionConfig) ProtoReflect() protoreflect.Message { func (x *SessionConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_dispatcher_config_proto_msgTypes[0] mi := &file_app_dispatcher_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -66,9 +68,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_dispatcher_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dispatcher_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -79,7 +83,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_dispatcher_config_proto_msgTypes[1] mi := &file_app_dispatcher_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -135,7 +139,7 @@ func file_app_dispatcher_config_proto_rawDescGZIP() []byte {
} }
var file_app_dispatcher_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_app_dispatcher_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_app_dispatcher_config_proto_goTypes = []any{ var file_app_dispatcher_config_proto_goTypes = []interface{}{
(*SessionConfig)(nil), // 0: xray.app.dispatcher.SessionConfig (*SessionConfig)(nil), // 0: xray.app.dispatcher.SessionConfig
(*Config)(nil), // 1: xray.app.dispatcher.Config (*Config)(nil), // 1: xray.app.dispatcher.Config
} }
@ -153,6 +157,32 @@ func file_app_dispatcher_config_proto_init() {
if File_app_dispatcher_config_proto != nil { if File_app_dispatcher_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_dispatcher_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SessionConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_dispatcher_config_proto_msgTypes[1].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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -1,15 +1,15 @@
package dispatcher package dispatcher
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"regexp"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/protocol"
@ -25,7 +25,7 @@ import (
"github.com/xtls/xray-core/transport/pipe" "github.com/xtls/xray-core/transport/pipe"
) )
var errSniffingTimeout = errors.New("timeout on sniffing") var errSniffingTimeout = newError("timeout on sniffing")
type cachedReader struct { type cachedReader struct {
sync.Mutex sync.Mutex
@ -39,14 +39,8 @@ func (r *cachedReader) Cache(b *buf.Buffer) {
if !mb.IsEmpty() { if !mb.IsEmpty() {
r.cache, _ = buf.MergeMulti(r.cache, mb) r.cache, _ = buf.MergeMulti(r.cache, mb)
} }
cacheLen := r.cache.Len() b.Clear()
if cacheLen <= b.Cap() { rawBytes := b.Extend(buf.Size)
b.Clear()
} else {
b.Release()
*b = *buf.NewWithSize(cacheLen)
}
rawBytes := b.Extend(cacheLen)
n := r.cache.Copy(rawBytes) n := r.cache.Copy(rawBytes)
b.Resize(0, int32(n)) b.Resize(0, int32(n))
r.Unlock() r.Unlock()
@ -181,18 +175,6 @@ func (d *DefaultDispatcher) getLink(ctx context.Context) (*transport.Link, *tran
} }
} }
} }
if p.Stats.UserOnline {
name := "user>>>" + user.Email + ">>>online"
if om, _ := stats.GetOrRegisterOnlineMap(d.stats, name); om != nil {
sessionInbounds := session.InboundFromContext(ctx)
userIP := sessionInbounds.Source.Address.String()
om.AddIP(userIP)
// log Online user with ips
// errors.LogDebug(ctx, "user>>>" + user.Email + ">>>online", om.Count(), om.List())
}
}
} }
return inboundLink, outboundLink return inboundLink, outboundLink
@ -204,20 +186,8 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
return false return false
} }
for _, d := range request.ExcludeForDomain { for _, d := range request.ExcludeForDomain {
if strings.HasPrefix(d, "regexp:") { if strings.ToLower(domain) == d {
pattern := d[7:] return false
re, err := regexp.Compile(pattern)
if err != nil {
errors.LogInfo(ctx, "Unable to compile regex")
continue
}
if re.MatchString(domain) {
return false
}
} else {
if strings.ToLower(domain) == d {
return false
}
} }
} }
protocolString := result.Protocol() protocolString := result.Protocol()
@ -229,8 +199,8 @@ func (d *DefaultDispatcher) shouldOverride(ctx context.Context, result SniffResu
return true return true
} }
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" && if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && protocolString != "bittorrent" && p == "fakedns" &&
fkr0.IsIPInIPPool(destination.Address) { destination.Address.Family().IsIP() && fkr0.IsIPInIPPool(destination.Address) {
errors.LogInfo(ctx, "Using sniffer ", protocolString, " since the fake DNS missed") newError("Using sniffer ", protocolString, " since the fake DNS missed").WriteToLog(session.ExportIDToError(ctx))
return true return true
} }
if resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok { if resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok {
@ -248,12 +218,11 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
if !destination.IsValid() { if !destination.IsValid() {
panic("Dispatcher: Invalid destination.") panic("Dispatcher: Invalid destination.")
} }
outbounds := session.OutboundsFromContext(ctx) ob := session.OutboundFromContext(ctx)
if len(outbounds) == 0 { if ob == nil {
outbounds = []*session.Outbound{{}} ob = &session.Outbound{}
ctx = session.ContextWithOutbounds(ctx, outbounds) ctx = session.ContextWithOutbound(ctx, ob)
} }
ob := outbounds[len(outbounds)-1]
ob.OriginalTarget = destination ob.OriginalTarget = destination
ob.Target = destination ob.Target = destination
content := session.ContentFromContext(ctx) content := session.ContentFromContext(ctx)
@ -261,7 +230,6 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
content = new(session.Content) content = new(session.Content)
ctx = session.ContextWithContent(ctx, content) ctx = session.ContextWithContent(ctx, content)
} }
sniffingRequest := content.SniffingRequest sniffingRequest := content.SniffingRequest
inbound, outbound := d.getLink(ctx) inbound, outbound := d.getLink(ctx)
if !sniffingRequest.Enabled { if !sniffingRequest.Enabled {
@ -278,14 +246,14 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
} }
if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) { if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain() domain := result.Domain()
errors.LogInfo(ctx, "sniffed domain: ", domain) newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain) destination.Address = net.ParseAddress(domain)
protocol := result.Protocol() protocol := result.Protocol()
if resComp, ok := result.(SnifferResultComposite); ok { if resComp, ok := result.(SnifferResultComposite); ok {
protocol = resComp.ProtocolForDomainResult() protocol = resComp.ProtocolForDomainResult()
} }
isFakeIP := false isFakeIP := false
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && fkr0.IsIPInIPPool(ob.Target.Address) { if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && ob.Target.Address.Family().IsIP() && fkr0.IsIPInIPPool(ob.Target.Address) {
isFakeIP = true isFakeIP = true
} }
if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP { if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP {
@ -303,14 +271,13 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
// DispatchLink implements routing.Dispatcher. // DispatchLink implements routing.Dispatcher.
func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.Destination, outbound *transport.Link) error { func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.Destination, outbound *transport.Link) error {
if !destination.IsValid() { if !destination.IsValid() {
return errors.New("Dispatcher: Invalid destination.") return newError("Dispatcher: Invalid destination.")
} }
outbounds := session.OutboundsFromContext(ctx) ob := session.OutboundFromContext(ctx)
if len(outbounds) == 0 { if ob == nil {
outbounds = []*session.Outbound{{}} ob = &session.Outbound{}
ctx = session.ContextWithOutbounds(ctx, outbounds) ctx = session.ContextWithOutbound(ctx, ob)
} }
ob := outbounds[len(outbounds)-1]
ob.OriginalTarget = destination ob.OriginalTarget = destination
ob.Target = destination ob.Target = destination
content := session.ContentFromContext(ctx) content := session.ContentFromContext(ctx)
@ -332,14 +299,14 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De
} }
if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) { if err == nil && d.shouldOverride(ctx, result, sniffingRequest, destination) {
domain := result.Domain() domain := result.Domain()
errors.LogInfo(ctx, "sniffed domain: ", domain) newError("sniffed domain: ", domain).WriteToLog(session.ExportIDToError(ctx))
destination.Address = net.ParseAddress(domain) destination.Address = net.ParseAddress(domain)
protocol := result.Protocol() protocol := result.Protocol()
if resComp, ok := result.(SnifferResultComposite); ok { if resComp, ok := result.(SnifferResultComposite); ok {
protocol = resComp.ProtocolForDomainResult() protocol = resComp.ProtocolForDomainResult()
} }
isFakeIP := false isFakeIP := false
if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && fkr0.IsIPInIPPool(ob.Target.Address) { if fkr0, ok := d.fdns.(dns.FakeDNSEngineRev0); ok && ob.Target.Address.Family().IsIP() && fkr0.IsIPInIPPool(ob.Target.Address) {
isFakeIP = true isFakeIP = true
} }
if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP { if sniffingRequest.RouteOnly && protocol != "fakedns" && protocol != "fakedns+others" && !isFakeIP {
@ -399,9 +366,9 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool, netw
} }
return contentResult, contentErr return contentResult, contentErr
} }
func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) { func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.Link, destination net.Destination) {
outbounds := session.OutboundsFromContext(ctx) ob := session.OutboundFromContext(ctx)
ob := outbounds[len(outbounds)-1]
if hosts, ok := d.dns.(dns.HostsLookup); ok && destination.Address.Family().IsDomain() { if hosts, ok := d.dns.(dns.HostsLookup); ok && destination.Address.Family().IsDomain() {
proxied := hosts.LookupHosts(ob.Target.String()) proxied := hosts.LookupHosts(ob.Target.String())
if proxied != nil { if proxied != nil {
@ -424,10 +391,10 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
ctx = session.SetForcedOutboundTagToContext(ctx, "") ctx = session.SetForcedOutboundTagToContext(ctx, "")
if h := d.ohm.GetHandler(forcedOutboundTag); h != nil { if h := d.ohm.GetHandler(forcedOutboundTag); h != nil {
isPickRoute = 1 isPickRoute = 1
errors.LogInfo(ctx, "taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]") newError("taking platform initialized detour [", forcedOutboundTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
handler = h handler = h
} else { } else {
errors.LogError(ctx, "non existing tag for platform initialized detour: ", forcedOutboundTag) newError("non existing tag for platform initialized detour: ", forcedOutboundTag).AtError().WriteToLog(session.ExportIDToError(ctx))
common.Close(link.Writer) common.Close(link.Writer)
common.Interrupt(link.Reader) common.Interrupt(link.Reader)
return return
@ -437,17 +404,13 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
outTag := route.GetOutboundTag() outTag := route.GetOutboundTag()
if h := d.ohm.GetHandler(outTag); h != nil { if h := d.ohm.GetHandler(outTag); h != nil {
isPickRoute = 2 isPickRoute = 2
if route.GetRuleTag() == "" { newError("taking detour [", outTag, "] for [", destination, "]").WriteToLog(session.ExportIDToError(ctx))
errors.LogInfo(ctx, "taking detour [", outTag, "] for [", destination, "]")
} else {
errors.LogInfo(ctx, "Hit route rule: [", route.GetRuleTag(), "] so taking detour [", outTag, "] for [", destination, "]")
}
handler = h handler = h
} else { } else {
errors.LogWarning(ctx, "non existing outTag: ", outTag) newError("non existing outTag: ", outTag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
} }
} else { } else {
errors.LogInfo(ctx, "default route for ", destination) newError("default route for ", destination).WriteToLog(session.ExportIDToError(ctx))
} }
} }
@ -456,13 +419,12 @@ func (d *DefaultDispatcher) routedDispatch(ctx context.Context, link *transport.
} }
if handler == nil { if handler == nil {
errors.LogInfo(ctx, "default outbound handler not exist") newError("default outbound handler not exist").WriteToLog(session.ExportIDToError(ctx))
common.Close(link.Writer) common.Close(link.Writer)
common.Interrupt(link.Reader) common.Interrupt(link.Reader)
return return
} }
ob.Tag = handler.Tag()
if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil { if accessMessage := log.AccessMessageFromContext(ctx); accessMessage != nil {
if tag := handler.Tag(); tag != "" { if tag := handler.Tag(); tag != "" {
if inTag == "" { if inTag == "" {

View File

@ -1 +1,3 @@
package dispatcher package dispatcher
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@ -0,0 +1,9 @@
package dispatcher
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

@ -5,7 +5,6 @@ import (
"strings" "strings"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
@ -23,16 +22,15 @@ func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error)
} }
if fakeDNSEngine == nil { if fakeDNSEngine == nil {
errNotInit := errors.New("FakeDNSEngine is not initialized, but such a sniffer is used").AtError() errNotInit := newError("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
return protocolSnifferWithMetadata{}, errNotInit return protocolSnifferWithMetadata{}, errNotInit
} }
return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) { return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
outbounds := session.OutboundsFromContext(ctx) Target := session.OutboundFromContext(ctx).Target
ob := outbounds[len(outbounds)-1] if Target.Network == net.Network_TCP || Target.Network == net.Network_UDP {
if ob.Target.Network == net.Network_TCP || ob.Target.Network == net.Network_UDP { domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(Target.Address)
domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(ob.Target.Address)
if domainFromFakeDNS != "" { if domainFromFakeDNS != "" {
errors.LogInfo(ctx, "fake dns got domain: ", domainFromFakeDNS, " for ip: ", ob.Target.Address.String()) newError("fake dns got domain: ", domainFromFakeDNS, " for ip: ", Target.Address.String()).WriteToLog(session.ExportIDToError(ctx))
return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
} }
} }
@ -40,7 +38,7 @@ func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error)
if ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil { if ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil {
ipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt) ipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt)
if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok { if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
inPool := fkr0.IsIPInIPPool(ob.Target.Address) inPool := fkr0.IsIPInIPPool(Target.Address)
ipAddressInRangeValue.addressInRange = &inPool ipAddressInRangeValue.addressInRange = &inPool
} }
} }
@ -110,10 +108,10 @@ func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWit
} }
return nil, common.ErrNoClue return nil, common.ErrNoClue
} }
errors.LogDebug(ctx, "ip address not in fake dns range, return as is") newError("ip address not in fake dns range, return as is").AtDebug().WriteToLog()
return nil, common.ErrNoClue return nil, common.ErrNoClue
} }
errors.LogWarning(ctx, "fake dns sniffer did not set address in range option, assume false.") newError("fake dns sniffer did not set address in range option, assume false.").AtWarning().WriteToLog()
return nil, common.ErrNoClue return nil, common.ErrNoClue
}, },
metadataSniffer: false, metadataSniffer: false,

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol/bittorrent" "github.com/xtls/xray-core/common/protocol/bittorrent"
"github.com/xtls/xray-core/common/protocol/http" "github.com/xtls/xray-core/common/protocol/http"
@ -35,7 +34,7 @@ type Sniffer struct {
func NewSniffer(ctx context.Context) *Sniffer { func NewSniffer(ctx context.Context) *Sniffer {
ret := &Sniffer{ ret := &Sniffer{
sniffer: []protocolSnifferWithMetadata{ sniffer: []protocolSnifferWithMetadata{
{func(c context.Context, b []byte) (SniffResult, error) { return http.SniffHTTP(b, c) }, false, net.Network_TCP}, {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 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 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 quic.SniffQUIC(b) }, false, net.Network_UDP},
@ -53,7 +52,7 @@ func NewSniffer(ctx context.Context) *Sniffer {
return ret return ret
} }
var errUnknownContent = errors.New("unknown content") 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, network net.Network) (SniffResult, error) {
var pendingSniffer []protocolSnifferWithMetadata var pendingSniffer []protocolSnifferWithMetadata

View File

@ -1,7 +1,6 @@
package dns package dns
import ( import (
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/common/strmatcher"
"github.com/xtls/xray-core/common/uuid" "github.com/xtls/xray-core/common/uuid"
@ -37,11 +36,11 @@ var localTLDsAndDotlessDomainsRule = &NameServer_OriginalRule{
func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) { func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
strMType, f := typeMap[t] strMType, f := typeMap[t]
if !f { if !f {
return nil, errors.New("unknown mapping type", t).AtWarning() return nil, newError("unknown mapping type", t).AtWarning()
} }
matcher, err := strMType.New(domain) matcher, err := strMType.New(domain)
if err != nil { if err != nil {
return nil, errors.New("failed to create str matcher").Base(err) return nil, newError("failed to create str matcher").Base(err)
} }
return matcher, nil return matcher, nil
} }
@ -52,7 +51,7 @@ func toNetIP(addrs []net.Address) ([]net.IP, error) {
if addr.Family().IsIP() { if addr.Family().IsIP() {
ips = append(ips, addr.IP()) ips = append(ips, addr.IP())
} else { } else {
return nil, errors.New("Failed to convert address", addr, "to Net IP.").AtWarning() return nil, newError("Failed to convert address", addr, "to Net IP.").AtWarning()
} }
} }
return ips, nil return ips, nil

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/dns/config.proto // source: app/dns/config.proto
package dns package dns
@ -139,9 +139,11 @@ type NameServer struct {
func (x *NameServer) Reset() { func (x *NameServer) Reset() {
*x = NameServer{} *x = NameServer{}
mi := &file_app_dns_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *NameServer) String() string { func (x *NameServer) String() string {
@ -152,7 +154,7 @@ func (*NameServer) ProtoMessage() {}
func (x *NameServer) ProtoReflect() protoreflect.Message { func (x *NameServer) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_config_proto_msgTypes[0] mi := &file_app_dns_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -221,9 +223,19 @@ type Config struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// Nameservers used by this DNS. Only traditional UDP servers are support at
// the moment. A special value 'localhost' as a domain address can be set to
// use DNS on local system.
//
// Deprecated: Marked as deprecated in app/dns/config.proto.
NameServers []*net.Endpoint `protobuf:"bytes,1,rep,name=NameServers,proto3" json:"NameServers,omitempty"`
// NameServer list used by this DNS client. // NameServer list used by this DNS client.
// A special value 'localhost' as a domain address can be set to use DNS on local system.
NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"` NameServer []*NameServer `protobuf:"bytes,5,rep,name=name_server,json=nameServer,proto3" json:"name_server,omitempty"`
// Static hosts. Domain to IP.
// Deprecated. Use static_hosts.
//
// Deprecated: Marked as deprecated in app/dns/config.proto.
Hosts map[string]*net.IPOrDomain `protobuf:"bytes,2,rep,name=Hosts,proto3" json:"Hosts,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
// (IPv6). // (IPv6).
ClientIp []byte `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"` ClientIp []byte `protobuf:"bytes,3,opt,name=client_ip,json=clientIp,proto3" json:"client_ip,omitempty"`
@ -239,9 +251,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_dns_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -252,7 +266,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_config_proto_msgTypes[1] mi := &file_app_dns_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -267,6 +281,14 @@ func (*Config) Descriptor() ([]byte, []int) {
return file_app_dns_config_proto_rawDescGZIP(), []int{1} return file_app_dns_config_proto_rawDescGZIP(), []int{1}
} }
// Deprecated: Marked as deprecated in app/dns/config.proto.
func (x *Config) GetNameServers() []*net.Endpoint {
if x != nil {
return x.NameServers
}
return nil
}
func (x *Config) GetNameServer() []*NameServer { func (x *Config) GetNameServer() []*NameServer {
if x != nil { if x != nil {
return x.NameServer return x.NameServer
@ -274,6 +296,14 @@ func (x *Config) GetNameServer() []*NameServer {
return nil return nil
} }
// Deprecated: Marked as deprecated in app/dns/config.proto.
func (x *Config) GetHosts() map[string]*net.IPOrDomain {
if x != nil {
return x.Hosts
}
return nil
}
func (x *Config) GetClientIp() []byte { func (x *Config) GetClientIp() []byte {
if x != nil { if x != nil {
return x.ClientIp return x.ClientIp
@ -334,9 +364,11 @@ type NameServer_PriorityDomain struct {
func (x *NameServer_PriorityDomain) Reset() { func (x *NameServer_PriorityDomain) Reset() {
*x = NameServer_PriorityDomain{} *x = NameServer_PriorityDomain{}
mi := &file_app_dns_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *NameServer_PriorityDomain) String() string { func (x *NameServer_PriorityDomain) String() string {
@ -347,7 +379,7 @@ func (*NameServer_PriorityDomain) ProtoMessage() {}
func (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message { func (x *NameServer_PriorityDomain) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_config_proto_msgTypes[2] mi := &file_app_dns_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -387,9 +419,11 @@ type NameServer_OriginalRule struct {
func (x *NameServer_OriginalRule) Reset() { func (x *NameServer_OriginalRule) Reset() {
*x = NameServer_OriginalRule{} *x = NameServer_OriginalRule{}
mi := &file_app_dns_config_proto_msgTypes[3] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_config_proto_msgTypes[3]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *NameServer_OriginalRule) String() string { func (x *NameServer_OriginalRule) String() string {
@ -400,7 +434,7 @@ func (*NameServer_OriginalRule) ProtoMessage() {}
func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message { func (x *NameServer_OriginalRule) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_config_proto_msgTypes[3] mi := &file_app_dns_config_proto_msgTypes[3]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -444,9 +478,11 @@ type Config_HostMapping struct {
func (x *Config_HostMapping) Reset() { func (x *Config_HostMapping) Reset() {
*x = Config_HostMapping{} *x = Config_HostMapping{}
mi := &file_app_dns_config_proto_msgTypes[4] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_config_proto_msgTypes[5]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config_HostMapping) String() string { func (x *Config_HostMapping) String() string {
@ -456,8 +492,8 @@ func (x *Config_HostMapping) String() string {
func (*Config_HostMapping) ProtoMessage() {} func (*Config_HostMapping) ProtoMessage() {}
func (x *Config_HostMapping) ProtoReflect() protoreflect.Message { func (x *Config_HostMapping) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_config_proto_msgTypes[4] mi := &file_app_dns_config_proto_msgTypes[5]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -469,7 +505,7 @@ func (x *Config_HostMapping) ProtoReflect() protoreflect.Message {
// Deprecated: Use Config_HostMapping.ProtoReflect.Descriptor instead. // Deprecated: Use Config_HostMapping.ProtoReflect.Descriptor instead.
func (*Config_HostMapping) Descriptor() ([]byte, []int) { func (*Config_HostMapping) Descriptor() ([]byte, []int) {
return file_app_dns_config_proto_rawDescGZIP(), []int{1, 0} return file_app_dns_config_proto_rawDescGZIP(), []int{1, 1}
} }
func (x *Config_HostMapping) GetType() DomainMatchingType { func (x *Config_HostMapping) GetType() DomainMatchingType {
@ -505,92 +541,107 @@ var File_app_dns_config_proto protoreflect.FileDescriptor
var file_app_dns_config_proto_rawDesc = []byte{ var file_app_dns_config_proto_rawDesc = []byte{
0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x64, 0x6e, 0x73, 0x1a, 0x1c, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2e, 0x64, 0x6e, 0x73, 0x1a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74,
0x2f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x2f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c,
0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x64, 0x65, 0x73, 0x74, 0x69,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x04, 0x0a, 0x0a, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x61, 0x70,
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x61, 0x64, 0x70, 0x2f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x04, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x72, 0x76, 0x65, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x6d,
0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69,
0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c,
0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61,
0x12, 0x56, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x73, 0x6b,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x69, 0x70, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x56, 0x0a, 0x12, 0x70, 0x72,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x2e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52,
0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x11, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61,
0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28,
0x05, 0x67, 0x65, 0x6f, 0x69, 0x70, 0x12, 0x4c, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x0b, 0x32, 0x16, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x6f, 0x75,
0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x74, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x52, 0x05, 0x67, 0x65, 0x6f, 0x69, 0x70,
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x12, 0x4c, 0x0a, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x72, 0x75, 0x6c,
0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76,
0x75, 0x6c, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x52,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x0d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x42,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72,
0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79,
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x1a, 0x5e, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f,
0x72, 0x69, 0x74, 0x79, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79,
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61,
0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67,
0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04,
0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65,
0x22, 0x9c, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0b, 0x6e,
0x61, 0x6d, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x18, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e,
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65,
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,
0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x49, 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f,
0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79,
0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e,
0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x0b, 0x73, 0x74, 0x61,
0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x42,
0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74,
0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65,
0x67, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x67, 0x79, 0x1a, 0x5e, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x44, 0x6f,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16,
0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49,
0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69,
0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d,
0x61, 0x74, 0x63, 0x68, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70,
0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e,
0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67,
0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f,
0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x6e, 0x1a, 0x36, 0x0a, 0x0c, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x52, 0x75,
0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02,
0x69, 0x65, 0x64, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xef, 0x05, 0x0a, 0x06, 0x43,
0x45, 0x0a, 0x12, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3f, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72,
0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x78, 0x72, 0x61,
0x0d, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x45, 0x6e, 0x64,
0x0a, 0x07, 0x4b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53,
0x65, 0x67, 0x65, 0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x73,
0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x78, 0x72,
0x50, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53,
0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x42, 0x46, 0x0a, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65,
0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x72, 0x12, 0x39, 0x0a, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x73, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e,
0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x70, 0x70, 0x2f, 0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x05, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09,
0x70, 0x2e, 0x44, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x70, 0x12, 0x43, 0x0a, 0x0c, 0x73, 0x74, 0x61,
0x74, 0x69, 0x63, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
0x67, 0x52, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x10,
0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67,
0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65,
0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x43,
0x61, 0x63, 0x68, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x73, 0x74,
0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x78,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x51, 0x75, 0x65, 0x72,
0x79, 0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x52, 0x0d, 0x71, 0x75, 0x65, 0x72, 0x79,
0x53, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x08, 0x52, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0b, 0x20, 0x01,
0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x49, 0x66, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x55, 0x0a, 0x0a, 0x48, 0x6f,
0x73, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 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, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x1a, 0x92, 0x01, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e,
0x67, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x20, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x2e, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70,
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x70, 0x12,
0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69,
0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x69, 0x65, 0x64,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4a, 0x04, 0x08, 0x07, 0x10, 0x08, 0x2a, 0x45, 0x0a, 0x12,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x54, 0x79,
0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x75, 0x6c, 0x6c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09,
0x53, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4b,
0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x65, 0x67, 0x65,
0x78, 0x10, 0x03, 0x2a, 0x35, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x72, 0x61,
0x74, 0x65, 0x67, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x10, 0x00,
0x12, 0x0b, 0x0a, 0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x34, 0x10, 0x01, 0x12, 0x0b, 0x0a,
0x07, 0x55, 0x53, 0x45, 0x5f, 0x49, 0x50, 0x36, 0x10, 0x02, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f,
0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x64, 0x6e, 0x73, 0x50, 0x01,
0x5a, 0x21, 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,
0x64, 0x6e, 0x73, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x44,
0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -606,34 +657,39 @@ func file_app_dns_config_proto_rawDescGZIP() []byte {
} }
var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_app_dns_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_app_dns_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_app_dns_config_proto_goTypes = []any{ var file_app_dns_config_proto_goTypes = []interface{}{
(DomainMatchingType)(0), // 0: xray.app.dns.DomainMatchingType (DomainMatchingType)(0), // 0: xray.app.dns.DomainMatchingType
(QueryStrategy)(0), // 1: xray.app.dns.QueryStrategy (QueryStrategy)(0), // 1: xray.app.dns.QueryStrategy
(*NameServer)(nil), // 2: xray.app.dns.NameServer (*NameServer)(nil), // 2: xray.app.dns.NameServer
(*Config)(nil), // 3: xray.app.dns.Config (*Config)(nil), // 3: xray.app.dns.Config
(*NameServer_PriorityDomain)(nil), // 4: xray.app.dns.NameServer.PriorityDomain (*NameServer_PriorityDomain)(nil), // 4: xray.app.dns.NameServer.PriorityDomain
(*NameServer_OriginalRule)(nil), // 5: xray.app.dns.NameServer.OriginalRule (*NameServer_OriginalRule)(nil), // 5: xray.app.dns.NameServer.OriginalRule
(*Config_HostMapping)(nil), // 6: xray.app.dns.Config.HostMapping nil, // 6: xray.app.dns.Config.HostsEntry
(*net.Endpoint)(nil), // 7: xray.common.net.Endpoint (*Config_HostMapping)(nil), // 7: xray.app.dns.Config.HostMapping
(*router.GeoIP)(nil), // 8: xray.app.router.GeoIP (*net.Endpoint)(nil), // 8: xray.common.net.Endpoint
(*router.GeoIP)(nil), // 9: xray.app.router.GeoIP
(*net.IPOrDomain)(nil), // 10: xray.common.net.IPOrDomain
} }
var file_app_dns_config_proto_depIdxs = []int32{ var file_app_dns_config_proto_depIdxs = []int32{
7, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint 8, // 0: xray.app.dns.NameServer.address:type_name -> xray.common.net.Endpoint
4, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain 4, // 1: xray.app.dns.NameServer.prioritized_domain:type_name -> xray.app.dns.NameServer.PriorityDomain
8, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP 9, // 2: xray.app.dns.NameServer.geoip:type_name -> xray.app.router.GeoIP
5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule 5, // 3: xray.app.dns.NameServer.original_rules:type_name -> xray.app.dns.NameServer.OriginalRule
1, // 4: xray.app.dns.NameServer.query_strategy:type_name -> xray.app.dns.QueryStrategy 1, // 4: xray.app.dns.NameServer.query_strategy:type_name -> xray.app.dns.QueryStrategy
2, // 5: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer 8, // 5: xray.app.dns.Config.NameServers:type_name -> xray.common.net.Endpoint
6, // 6: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping 2, // 6: xray.app.dns.Config.name_server:type_name -> xray.app.dns.NameServer
1, // 7: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy 6, // 7: xray.app.dns.Config.Hosts:type_name -> xray.app.dns.Config.HostsEntry
0, // 8: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType 7, // 8: xray.app.dns.Config.static_hosts:type_name -> xray.app.dns.Config.HostMapping
0, // 9: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType 1, // 9: xray.app.dns.Config.query_strategy:type_name -> xray.app.dns.QueryStrategy
10, // [10:10] is the sub-list for method output_type 0, // 10: xray.app.dns.NameServer.PriorityDomain.type:type_name -> xray.app.dns.DomainMatchingType
10, // [10:10] is the sub-list for method input_type 10, // 11: xray.app.dns.Config.HostsEntry.value:type_name -> xray.common.net.IPOrDomain
10, // [10:10] is the sub-list for extension type_name 0, // 12: xray.app.dns.Config.HostMapping.type:type_name -> xray.app.dns.DomainMatchingType
10, // [10:10] is the sub-list for extension extendee 13, // [13:13] is the sub-list for method output_type
0, // [0:10] is the sub-list for field type_name 13, // [13:13] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name
13, // [13:13] is the sub-list for extension extendee
0, // [0:13] is the sub-list for field type_name
} }
func init() { file_app_dns_config_proto_init() } func init() { file_app_dns_config_proto_init() }
@ -641,13 +697,75 @@ func file_app_dns_config_proto_init() {
if File_app_dns_config_proto != nil { if File_app_dns_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_dns_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NameServer); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_dns_config_proto_msgTypes[1].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
}
}
file_app_dns_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NameServer_PriorityDomain); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_dns_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*NameServer_OriginalRule); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_dns_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Config_HostMapping); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_dns_config_proto_rawDesc, RawDescriptor: file_app_dns_config_proto_rawDesc,
NumEnums: 2, NumEnums: 2,
NumMessages: 5, NumMessages: 6,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -6,6 +6,7 @@ option go_package = "github.com/xtls/xray-core/app/dns";
option java_package = "com.xray.app.dns"; option java_package = "com.xray.app.dns";
option java_multiple_files = true; option java_multiple_files = true;
import "common/net/address.proto";
import "common/net/destination.proto"; import "common/net/destination.proto";
import "app/router/config.proto"; import "app/router/config.proto";
@ -44,10 +45,18 @@ enum QueryStrategy {
} }
message Config { message Config {
// Nameservers used by this DNS. Only traditional UDP servers are support at
// the moment. A special value 'localhost' as a domain address can be set to
// use DNS on local system.
repeated xray.common.net.Endpoint NameServers = 1 [deprecated = true];
// NameServer list used by this DNS client. // NameServer list used by this DNS client.
// A special value 'localhost' as a domain address can be set to use DNS on local system.
repeated NameServer name_server = 5; repeated NameServer name_server = 5;
// Static hosts. Domain to IP.
// Deprecated. Use static_hosts.
map<string, xray.common.net.IPOrDomain> Hosts = 2 [deprecated = true];
// Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes // Client IP for EDNS client subnet. Must be 4 bytes (IPv4) or 16 bytes
// (IPv6). // (IPv6).
bytes client_ip = 3; bytes client_ip = 3;

View File

@ -1,6 +1,8 @@
// Package dns is an implementation of core.DNS feature. // Package dns is an implementation of core.DNS feature.
package dns package dns
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"fmt" "fmt"
@ -13,6 +15,7 @@ import (
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/common/strmatcher"
"github.com/xtls/xray-core/features"
"github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns"
) )
@ -51,7 +54,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
case 0, net.IPv4len, net.IPv6len: case 0, net.IPv4len, net.IPv6len:
clientIP = net.IP(config.ClientIp) clientIP = net.IP(config.ClientIp)
default: default:
return nil, errors.New("unexpected client IP length ", len(config.ClientIp)) return nil, newError("unexpected client IP length ", len(config.ClientIp))
} }
var ipOption *dns.IPOption var ipOption *dns.IPOption
@ -76,9 +79,9 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
} }
} }
hosts, err := NewStaticHosts(config.StaticHosts) hosts, err := NewStaticHosts(config.StaticHosts, config.Hosts)
if err != nil { if err != nil {
return nil, errors.New("failed to create hosts").Base(err) return nil, newError("failed to create hosts").Base(err)
} }
clients := []*Client{} clients := []*Client{}
@ -92,6 +95,15 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
domainMatcher := &strmatcher.MatcherGroup{} domainMatcher := &strmatcher.MatcherGroup{}
geoipContainer := router.GeoIPMatcherContainer{} geoipContainer := router.GeoIPMatcherContainer{}
for _, endpoint := range config.NameServers {
features.PrintDeprecatedFeatureWarning("simple DNS server")
client, err := NewSimpleClient(ctx, endpoint, clientIP)
if err != nil {
return nil, newError("failed to create client").Base(err)
}
clients = append(clients, client)
}
for _, ns := range config.NameServer { for _, ns := range config.NameServer {
clientIdx := len(clients) clientIdx := len(clients)
updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []*DomainMatcherInfo) error { updateDomain := func(domainRule strmatcher.Matcher, originalRuleIdx int, matcherInfos []*DomainMatcherInfo) error {
@ -110,7 +122,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) {
} }
client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain) client, err := NewClient(ctx, ns, myClientIP, geoipContainer, &matcherInfos, updateDomain)
if err != nil { if err != nil {
return nil, errors.New("failed to create client").Base(err) return nil, newError("failed to create client").Base(err)
} }
clients = append(clients, client) clients = append(clients, client)
} }
@ -158,7 +170,7 @@ func (s *DNS) IsOwnLink(ctx context.Context) bool {
// LookupIP implements dns.Client. // LookupIP implements dns.Client.
func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) { func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
if domain == "" { if domain == "" {
return nil, errors.New("empty domain name") return nil, newError("empty domain name")
} }
option.IPv4Enable = option.IPv4Enable && s.ipOption.IPv4Enable option.IPv4Enable = option.IPv4Enable && s.ipOption.IPv4Enable
@ -169,7 +181,9 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
} }
// Normalize the FQDN form query // Normalize the FQDN form query
domain = strings.TrimSuffix(domain, ".") if strings.HasSuffix(domain, ".") {
domain = domain[:len(domain)-1]
}
// Static host lookup // Static host lookup
switch addrs := s.hosts.Lookup(domain, option); { switch addrs := s.hosts.Lookup(domain, option); {
@ -178,10 +192,10 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
case len(addrs) == 0: // Domain recorded, but no valid IP returned (e.g. IPv4 address with only IPv6 enabled) case len(addrs) == 0: // Domain recorded, but no valid IP returned (e.g. IPv4 address with only IPv6 enabled)
return nil, dns.ErrEmptyResponse return nil, dns.ErrEmptyResponse
case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Domain replacement case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Domain replacement
errors.LogInfo(s.ctx, "domain replaced: ", domain, " -> ", addrs[0].Domain()) newError("domain replaced: ", domain, " -> ", addrs[0].Domain()).WriteToLog()
domain = addrs[0].Domain() domain = addrs[0].Domain()
default: // Successfully found ip records in static host default: // Successfully found ip records in static host
errors.LogInfo(s.ctx, "returning ", len(addrs), " IP(s) for domain ", domain, " -> ", addrs) newError("returning ", len(addrs), " IP(s) for domain ", domain, " -> ", addrs).WriteToLog()
return toNetIP(addrs) return toNetIP(addrs)
} }
@ -190,7 +204,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
ctx := session.ContextWithInbound(s.ctx, &session.Inbound{Tag: s.tag}) ctx := session.ContextWithInbound(s.ctx, &session.Inbound{Tag: s.tag})
for _, client := range s.sortClients(domain) { for _, client := range s.sortClients(domain) {
if !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS") { if !option.FakeEnable && strings.EqualFold(client.Name(), "FakeDNS") {
errors.LogDebug(s.ctx, "skip DNS resolution for domain ", domain, " at server ", client.Name()) newError("skip DNS resolution for domain ", domain, " at server ", client.Name()).AtDebug().WriteToLog()
continue continue
} }
ips, err := client.QueryIP(ctx, domain, option, s.disableCache) ips, err := client.QueryIP(ctx, domain, option, s.disableCache)
@ -198,7 +212,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
return ips, nil return ips, nil
} }
if err != nil { if err != nil {
errors.LogInfoInner(s.ctx, err, "failed to lookup ip for domain ", domain, " at server ", client.Name()) newError("failed to lookup ip for domain ", domain, " at server ", client.Name()).Base(err).WriteToLog()
errs = append(errs, err) errs = append(errs, err)
} }
// 5 for RcodeRefused in miekg/dns, hardcode to reduce binary size // 5 for RcodeRefused in miekg/dns, hardcode to reduce binary size
@ -207,7 +221,7 @@ func (s *DNS) LookupIP(domain string, option dns.IPOption) ([]net.IP, error) {
} }
} }
return nil, errors.New("returning nil for domain ", domain).Base(errors.Combine(errs...)) return nil, newError("returning nil for domain ", domain).Base(errors.Combine(errs...))
} }
// LookupHosts implements dns.HostsLookup. // LookupHosts implements dns.HostsLookup.
@ -219,7 +233,7 @@ func (s *DNS) LookupHosts(domain string) *net.Address {
// Normalize the FQDN form query // Normalize the FQDN form query
addrs := s.hosts.Lookup(domain, *s.ipOption) addrs := s.hosts.Lookup(domain, *s.ipOption)
if len(addrs) > 0 { if len(addrs) > 0 {
errors.LogInfo(s.ctx, "domain replaced: ", domain, " -> ", addrs[0].String()) newError("domain replaced: ", domain, " -> ", addrs[0].String()).AtInfo().WriteToLog()
return &addrs[0] return &addrs[0]
} }
@ -277,16 +291,16 @@ func (s *DNS) sortClients(domain string) []*Client {
} }
if len(domainRules) > 0 { if len(domainRules) > 0 {
errors.LogDebug(s.ctx, "domain ", domain, " matches following rules: ", domainRules) newError("domain ", domain, " matches following rules: ", domainRules).AtDebug().WriteToLog()
} }
if len(clientNames) > 0 { if len(clientNames) > 0 {
errors.LogDebug(s.ctx, "domain ", domain, " will use DNS in order: ", clientNames) newError("domain ", domain, " will use DNS in order: ", clientNames).AtDebug().WriteToLog()
} }
if len(clients) == 0 { if len(clients) == 0 {
clients = append(clients, s.clients[0]) clients = append(clients, s.clients[0])
clientNames = append(clientNames, s.clients[0].Name()) clientNames = append(clientNames, s.clients[0].Name())
errors.LogDebug(s.ctx, "domain ", domain, " will use the first DNS: ", clientNames) newError("domain ", domain, " will use the first DNS: ", clientNames).AtDebug().WriteToLog()
} }
return clients return clients

View File

@ -124,17 +124,15 @@ func TestUDPServerSubnet(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: uint32(port),
}, },
Port: uint32(port),
}, },
}, },
ClientIp: []byte{7, 8, 9, 10}, ClientIp: []byte{7, 8, 9, 10},
@ -185,17 +183,15 @@ func TestUDPServer(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: uint32(port),
}, },
Port: uint32(port),
}, },
}, },
}), }),
@ -307,18 +303,18 @@ func TestPrioritizedDomain(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: 9999, /* unreachable */
}, },
Port: 9999, /* unreachable */
}, },
},
NameServer: []*NameServer{
{ {
Address: &net.Endpoint{ Address: &net.Endpoint{
Network: net.Network_UDP, Network: net.Network_UDP,
@ -393,17 +389,15 @@ func TestUDPServerIPv6(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: uint32(port),
}, },
Port: uint32(port),
}, },
}, },
}), }),
@ -454,17 +448,15 @@ func TestStaticHostDomain(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: uint32(port),
}, },
Port: uint32(port),
}, },
}, },
StaticHosts: []*Config_HostMapping{ StaticHosts: []*Config_HostMapping{
@ -639,18 +631,18 @@ func TestLocalDomain(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: 9999, /* unreachable */
}, },
Port: 9999, /* unreachable */
}, },
},
NameServer: []*NameServer{
{ {
Address: &net.Endpoint{ Address: &net.Endpoint{
Network: net.Network_UDP, Network: net.Network_UDP,
@ -867,18 +859,18 @@ func TestMultiMatchPrioritizedDomain(t *testing.T) {
config := &core.Config{ config := &core.Config{
App: []*serial.TypedMessage{ App: []*serial.TypedMessage{
serial.ToTypedMessage(&Config{ serial.ToTypedMessage(&Config{
NameServer: []*NameServer{ NameServers: []*net.Endpoint{
{ {
Address: &net.Endpoint{ Network: net.Network_UDP,
Network: net.Network_UDP, Address: &net.IPOrDomain{
Address: &net.IPOrDomain{ Address: &net.IPOrDomain_Ip{
Address: &net.IPOrDomain_Ip{ Ip: []byte{127, 0, 0, 1},
Ip: []byte{127, 0, 0, 1},
},
}, },
Port: 9999, /* unreachable */
}, },
Port: 9999, /* unreachable */
}, },
},
NameServer: []*NameServer{
{ {
Address: &net.Endpoint{ Address: &net.Endpoint{
Network: net.Network_UDP, Network: net.Network_UDP,

View File

@ -171,10 +171,10 @@ func parseResponse(payload []byte) (*IPRecord, error) {
var parser dnsmessage.Parser var parser dnsmessage.Parser
h, err := parser.Start(payload) h, err := parser.Start(payload)
if err != nil { if err != nil {
return nil, errors.New("failed to parse DNS response").Base(err).AtWarning() return nil, newError("failed to parse DNS response").Base(err).AtWarning()
} }
if err := parser.SkipAllQuestions(); err != nil { if err := parser.SkipAllQuestions(); err != nil {
return nil, errors.New("failed to skip questions in DNS response").Base(err).AtWarning() return nil, newError("failed to skip questions in DNS response").Base(err).AtWarning()
} }
now := time.Now() now := time.Now()
@ -189,7 +189,7 @@ L:
ah, err := parser.AnswerHeader() ah, err := parser.AnswerHeader()
if err != nil { if err != nil {
if err != dnsmessage.ErrSectionDone { if err != dnsmessage.ErrSectionDone {
errors.LogInfoInner(context.Background(), err, "failed to parse answer section for domain: ", ah.Name.String()) newError("failed to parse answer section for domain: ", ah.Name.String()).Base(err).WriteToLog()
} }
break break
} }
@ -207,20 +207,20 @@ L:
case dnsmessage.TypeA: case dnsmessage.TypeA:
ans, err := parser.AResource() ans, err := parser.AResource()
if err != nil { if err != nil {
errors.LogInfoInner(context.Background(), err, "failed to parse A record for domain: ", ah.Name) newError("failed to parse A record for domain: ", ah.Name).Base(err).WriteToLog()
break L break L
} }
ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:])) ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.A[:]))
case dnsmessage.TypeAAAA: case dnsmessage.TypeAAAA:
ans, err := parser.AAAAResource() ans, err := parser.AAAAResource()
if err != nil { if err != nil {
errors.LogInfoInner(context.Background(), err, "failed to parse AAAA record for domain: ", ah.Name) newError("failed to parse AAAA record for domain: ", ah.Name).Base(err).WriteToLog()
break L break L
} }
ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:])) ipRecord.IP = append(ipRecord.IP, net.IPAddress(ans.AAAA[:]))
default: default:
if err := parser.SkipAnswer(); err != nil { if err := parser.SkipAnswer(); err != nil {
errors.LogInfoInner(context.Background(), err, "failed to skip answer") newError("failed to skip answer").Base(err).WriteToLog()
break L break L
} }
continue continue

View File

@ -88,7 +88,7 @@ func Test_parseResponse(t *testing.T) {
got.Expire = time.Time{} got.Expire = time.Time{}
} }
if cmp.Diff(got, tt.want) != "" { if cmp.Diff(got, tt.want) != "" {
t.Error(cmp.Diff(got, tt.want)) t.Errorf(cmp.Diff(got, tt.want))
// t.Errorf("handleResponse() = %#v, want %#v", got, tt.want) // t.Errorf("handleResponse() = %#v, want %#v", got, tt.want)
} }
}) })

View File

@ -0,0 +1,9 @@
package dns
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

@ -0,0 +1,9 @@
package fakedns
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

@ -10,7 +10,6 @@ import (
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/cache" "github.com/xtls/xray-core/common/cache"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns"
) )
@ -46,7 +45,7 @@ func (fkdns *Holder) Start() error {
if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 { if fkdns.config != nil && fkdns.config.IpPool != "" && fkdns.config.LruSize != 0 {
return fkdns.initializeFromConfig() return fkdns.initializeFromConfig()
} }
return errors.New("invalid fakeDNS setting") return newError("invalid fakeDNS setting")
} }
func (fkdns *Holder) Close() error { func (fkdns *Holder) Close() error {
@ -61,7 +60,7 @@ func NewFakeDNSHolder() (*Holder, error) {
var err error var err error
if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil { if fkdns, err = NewFakeDNSHolderConfigOnly(nil); err != nil {
return nil, errors.New("Unable to create Fake Dns Engine").Base(err).AtError() return nil, newError("Unable to create Fake Dns Engine").Base(err).AtError()
} }
err = fkdns.initialize(dns.FakeIPv4Pool, 65535) err = fkdns.initialize(dns.FakeIPv4Pool, 65535)
if err != nil { if err != nil {
@ -83,13 +82,13 @@ func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
var err error var err error
if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil { if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {
return errors.New("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError() return newError("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
} }
ones, bits := ipRange.Mask.Size() ones, bits := ipRange.Mask.Size()
rooms := bits - ones rooms := bits - ones
if math.Log2(float64(lruSize)) >= float64(rooms) { if math.Log2(float64(lruSize)) >= float64(rooms) {
return errors.New("LRU size is bigger than subnet size").AtError() return newError("LRU size is bigger than subnet size").AtError()
} }
fkdns.domainToIP = cache.NewLru(lruSize) fkdns.domainToIP = cache.NewLru(lruSize)
fkdns.ipRange = ipRange fkdns.ipRange = ipRange
@ -138,7 +137,7 @@ func (fkdns *Holder) GetDomainFromFakeDNS(ip net.Address) string {
if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok { if k, ok := fkdns.domainToIP.GetKeyFromValue(ip); ok {
return k.(string) return k.(string)
} }
errors.LogInfo(context.Background(), "A fake ip request to ", ip, ", however there is no matching domain name in fake DNS") newError("A fake ip request to ", ip, ", however there is no matching domain name in fake DNS").AtInfo().WriteToLog()
return "" return ""
} }
@ -193,10 +192,10 @@ func (h *HolderMulti) Start() error {
for _, v := range h.holders { for _, v := range h.holders {
if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 { if v.config != nil && v.config.IpPool != "" && v.config.LruSize != 0 {
if err := v.Start(); err != nil { if err := v.Start(); err != nil {
return errors.New("Cannot start all fake dns pools").Base(err) return newError("Cannot start all fake dns pools").Base(err)
} }
} else { } else {
return errors.New("invalid fakeDNS setting") return newError("invalid fakeDNS setting")
} }
} }
return nil return nil
@ -205,7 +204,7 @@ func (h *HolderMulti) Start() error {
func (h *HolderMulti) Close() error { func (h *HolderMulti) Close() error {
for _, v := range h.holders { for _, v := range h.holders {
if err := v.Close(); err != nil { if err := v.Close(); err != nil {
return errors.New("Cannot close all fake dns pools").Base(err) return newError("Cannot close all fake dns pools").Base(err)
} }
} }
return nil return nil

View File

@ -1 +1,3 @@
package fakedns package fakedns
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/dns/fakedns/fakedns.proto // source: app/dns/fakedns/fakedns.proto
package fakedns package fakedns
@ -31,9 +31,11 @@ type FakeDnsPool struct {
func (x *FakeDnsPool) Reset() { func (x *FakeDnsPool) Reset() {
*x = FakeDnsPool{} *x = FakeDnsPool{}
mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *FakeDnsPool) String() string { func (x *FakeDnsPool) String() string {
@ -44,7 +46,7 @@ func (*FakeDnsPool) ProtoMessage() {}
func (x *FakeDnsPool) ProtoReflect() protoreflect.Message { func (x *FakeDnsPool) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0] mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -83,9 +85,11 @@ type FakeDnsPoolMulti struct {
func (x *FakeDnsPoolMulti) Reset() { func (x *FakeDnsPoolMulti) Reset() {
*x = FakeDnsPoolMulti{} *x = FakeDnsPoolMulti{}
mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *FakeDnsPoolMulti) String() string { func (x *FakeDnsPoolMulti) String() string {
@ -96,7 +100,7 @@ func (*FakeDnsPoolMulti) ProtoMessage() {}
func (x *FakeDnsPoolMulti) ProtoReflect() protoreflect.Message { func (x *FakeDnsPoolMulti) ProtoReflect() protoreflect.Message {
mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1] mi := &file_app_dns_fakedns_fakedns_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -155,7 +159,7 @@ func file_app_dns_fakedns_fakedns_proto_rawDescGZIP() []byte {
} }
var file_app_dns_fakedns_fakedns_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_app_dns_fakedns_fakedns_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_app_dns_fakedns_fakedns_proto_goTypes = []any{ var file_app_dns_fakedns_fakedns_proto_goTypes = []interface{}{
(*FakeDnsPool)(nil), // 0: xray.app.dns.fakedns.FakeDnsPool (*FakeDnsPool)(nil), // 0: xray.app.dns.fakedns.FakeDnsPool
(*FakeDnsPoolMulti)(nil), // 1: xray.app.dns.fakedns.FakeDnsPoolMulti (*FakeDnsPoolMulti)(nil), // 1: xray.app.dns.fakedns.FakeDnsPoolMulti
} }
@ -173,6 +177,32 @@ func file_app_dns_fakedns_fakedns_proto_init() {
if File_app_dns_fakedns_fakedns_proto != nil { if File_app_dns_fakedns_fakedns_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_dns_fakedns_fakedns_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FakeDnsPool); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_dns_fakedns_fakedns_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FakeDnsPoolMulti); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -1,11 +1,10 @@
package dns package dns
import ( import (
"context" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/strmatcher" "github.com/xtls/xray-core/common/strmatcher"
"github.com/xtls/xray-core/features"
"github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns"
) )
@ -16,17 +15,34 @@ type StaticHosts struct {
} }
// NewStaticHosts creates a new StaticHosts instance. // NewStaticHosts creates a new StaticHosts instance.
func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) { func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {
g := new(strmatcher.MatcherGroup) g := new(strmatcher.MatcherGroup)
sh := &StaticHosts{ sh := &StaticHosts{
ips: make([][]net.Address, len(hosts)+16), ips: make([][]net.Address, len(hosts)+len(legacy)+16),
matchers: g, matchers: g,
} }
if legacy != nil {
features.PrintDeprecatedFeatureWarning("simple host mapping")
for domain, ip := range legacy {
matcher, err := strmatcher.Full.New(domain)
common.Must(err)
id := g.Add(matcher)
address := ip.AsAddress()
if address.Family().IsDomain() {
return nil, newError("invalid domain address in static hosts: ", address.Domain()).AtWarning()
}
sh.ips[id] = []net.Address{address}
}
}
for _, mapping := range hosts { for _, mapping := range hosts {
matcher, err := toStrMatcher(mapping.Type, mapping.Domain) matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
if err != nil { if err != nil {
return nil, errors.New("failed to create domain matcher").Base(err) return nil, newError("failed to create domain matcher").Base(err)
} }
id := g.Add(matcher) id := g.Add(matcher)
ips := make([]net.Address, 0, len(mapping.Ip)+1) ips := make([]net.Address, 0, len(mapping.Ip)+1)
@ -37,12 +53,12 @@ func NewStaticHosts(hosts []*Config_HostMapping) (*StaticHosts, error) {
for _, ip := range mapping.Ip { for _, ip := range mapping.Ip {
addr := net.IPAddress(ip) addr := net.IPAddress(ip)
if addr == nil { if addr == nil {
return nil, errors.New("invalid IP address in static hosts: ", ip).AtWarning() return nil, newError("invalid IP address in static hosts: ", ip).AtWarning()
} }
ips = append(ips, addr) ips = append(ips, addr)
} }
default: default:
return nil, errors.New("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning() return nil, newError("neither IP address nor proxied domain specified for domain: ", mapping.Domain).AtWarning()
} }
sh.ips[id] = ips sh.ips[id] = ips
@ -74,7 +90,7 @@ func (h *StaticHosts) lookup(domain string, option dns.IPOption, maxDepth int) [
case len(addrs) == 0: // Not recorded in static hosts, return nil case len(addrs) == 0: // Not recorded in static hosts, return nil
return nil return nil
case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Try to unwrap domain case len(addrs) == 1 && addrs[0].Family().IsDomain(): // Try to unwrap domain
errors.LogDebug(context.Background(), "found replaced domain: ", domain, " -> ", addrs[0].Domain(), ". Try to unwrap it") newError("found replaced domain: ", domain, " -> ", addrs[0].Domain(), ". Try to unwrap it").AtDebug().WriteToLog()
if maxDepth > 0 { if maxDepth > 0 {
unwrapped := h.lookup(addrs[0].Domain(), option, maxDepth-1) unwrapped := h.lookup(addrs[0].Domain(), option, maxDepth-1)
if unwrapped != nil { if unwrapped != nil {

View File

@ -50,7 +50,7 @@ func TestStaticHosts(t *testing.T) {
}, },
} }
hosts, err := NewStaticHosts(pb) hosts, err := NewStaticHosts(pb, nil)
common.Must(err) common.Must(err)
{ {

View File

@ -62,9 +62,9 @@ func NewServer(dest net.Destination, dispatcher routing.Dispatcher, queryStrateg
dest.Network = net.Network_UDP dest.Network = net.Network_UDP
} }
if dest.Network == net.Network_UDP { // UDP classic DNS mode if dest.Network == net.Network_UDP { // UDP classic DNS mode
return NewClassicNameServer(dest, dispatcher, queryStrategy), nil return NewClassicNameServer(dest, dispatcher), nil
} }
return nil, errors.New("No available name server could be created from ", dest).AtWarning() return nil, newError("No available name server could be created from ", dest).AtWarning()
} }
// NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs. // NewClient creates a DNS client managing a name server with client IP, domain rules and expected IPs.
@ -82,15 +82,15 @@ func NewClient(
// Create a new server for each client for now // Create a new server for each client for now
server, err := NewServer(ns.Address.AsDestination(), dispatcher, ns.GetQueryStrategy()) server, err := NewServer(ns.Address.AsDestination(), dispatcher, ns.GetQueryStrategy())
if err != nil { if err != nil {
return errors.New("failed to create nameserver").Base(err).AtWarning() return newError("failed to create nameserver").Base(err).AtWarning()
} }
// Prioritize local domains with specific TLDs or those without any dot for the local DNS // Priotize local domains with specific TLDs or without any dot to local DNS
if _, isLocalDNS := server.(*LocalNameServer); isLocalDNS { if _, isLocalDNS := server.(*LocalNameServer); isLocalDNS {
ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...) ns.PrioritizedDomain = append(ns.PrioritizedDomain, localTLDsAndDotlessDomains...)
ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule) ns.OriginalRules = append(ns.OriginalRules, localTLDsAndDotlessDomainsRule)
// The following lines is a solution to avoid core panicsrule index out of range when setting `localhost` DNS client in config. // The following lines is a solution to avoid core panicsrule index out of range when setting `localhost` DNS client in config.
// Because the `localhost` DNS client will append len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule. // Because the `localhost` DNS client will apend len(localTLDsAndDotlessDomains) rules into matcherInfos to match `geosite:private` default rule.
// But `matcherInfos` has no enough length to add rules, which leads to core panics (rule index out of range). // But `matcherInfos` has no enough length to add rules, which leads to core panics (rule index out of range).
// To avoid this, the length of `matcherInfos` must be equal to the expected, so manually append it with Golang default zero value first for later modification. // To avoid this, the length of `matcherInfos` must be equal to the expected, so manually append it with Golang default zero value first for later modification.
// Related issues: // Related issues:
@ -111,7 +111,7 @@ func NewClient(
for _, domain := range ns.PrioritizedDomain { for _, domain := range ns.PrioritizedDomain {
domainRule, err := toStrMatcher(domain.Type, domain.Domain) domainRule, err := toStrMatcher(domain.Type, domain.Domain)
if err != nil { if err != nil {
return errors.New("failed to create prioritized domain").Base(err).AtWarning() return newError("failed to create prioritized domain").Base(err).AtWarning()
} }
originalRuleIdx := ruleCurr originalRuleIdx := ruleCurr
if ruleCurr < len(ns.OriginalRules) { if ruleCurr < len(ns.OriginalRules) {
@ -130,7 +130,7 @@ func NewClient(
} }
err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos) err = updateDomainRule(domainRule, originalRuleIdx, *matcherInfos)
if err != nil { if err != nil {
return errors.New("failed to create prioritized domain").Base(err).AtWarning() return newError("failed to create prioritized domain").Base(err).AtWarning()
} }
} }
@ -139,7 +139,7 @@ func NewClient(
for _, geoip := range ns.Geoip { for _, geoip := range ns.Geoip {
matcher, err := container.Add(geoip) matcher, err := container.Add(geoip)
if err != nil { if err != nil {
return errors.New("failed to create ip matcher").Base(err).AtWarning() return newError("failed to create ip matcher").Base(err).AtWarning()
} }
matchers = append(matchers, matcher) matchers = append(matchers, matcher)
} }
@ -147,9 +147,9 @@ func NewClient(
if len(clientIP) > 0 { if len(clientIP) > 0 {
switch ns.Address.Address.GetAddress().(type) { switch ns.Address.Address.GetAddress().(type) {
case *net.IPOrDomain_Domain: case *net.IPOrDomain_Domain:
errors.LogInfo(ctx, "DNS: client ", ns.Address.Address.GetDomain(), " uses clientIP ", clientIP.String()) newError("DNS: client ", ns.Address.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
case *net.IPOrDomain_Ip: case *net.IPOrDomain_Ip:
errors.LogInfo(ctx, "DNS: client ", ns.Address.Address.GetIp(), " uses clientIP ", clientIP.String()) newError("DNS: client ", ns.Address.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
} }
} }
@ -163,6 +163,31 @@ func NewClient(
return client, err return client, err
} }
// NewSimpleClient creates a DNS client with a simple destination.
func NewSimpleClient(ctx context.Context, endpoint *net.Endpoint, clientIP net.IP) (*Client, error) {
client := &Client{}
err := core.RequireFeatures(ctx, func(dispatcher routing.Dispatcher) error {
server, err := NewServer(endpoint.AsDestination(), dispatcher, QueryStrategy_USE_IP)
if err != nil {
return newError("failed to create nameserver").Base(err).AtWarning()
}
client.server = server
client.clientIP = clientIP
return nil
})
if len(clientIP) > 0 {
switch endpoint.Address.GetAddress().(type) {
case *net.IPOrDomain_Domain:
newError("DNS: client ", endpoint.Address.GetDomain(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
case *net.IPOrDomain_Ip:
newError("DNS: client ", endpoint.Address.GetIp(), " uses clientIP ", clientIP.String()).AtInfo().WriteToLog()
}
}
return client, err
}
// Name returns the server name the client manages. // Name returns the server name the client manages.
func (c *Client) Name() string { func (c *Client) Name() string {
return c.server.Name() return c.server.Name()
@ -197,7 +222,7 @@ func (c *Client) MatchExpectedIPs(domain string, ips []net.IP) ([]net.IP, error)
if len(newIps) == 0 { if len(newIps) == 0 {
return nil, errExpectedIPNonMatch return nil, errExpectedIPNonMatch
} }
errors.LogDebug(context.Background(), "domain ", domain, " expectIPs ", newIps, " matched at server ", c.Name()) newError("domain ", domain, " expectIPs ", newIps, " matched at server ", c.Name()).AtDebug().WriteToLog()
return newIps, nil return newIps, nil
} }

View File

@ -12,7 +12,6 @@ import (
"time" "time"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/net/cnc"
@ -44,7 +43,7 @@ type DoHNameServer struct {
// NewDoHNameServer creates DOH server object for remote resolving. // NewDoHNameServer creates DOH server object for remote resolving.
func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) { func NewDoHNameServer(url *url.URL, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) (*DoHNameServer, error) {
errors.LogInfo(context.Background(), "DNS: created Remote DOH client for ", url.String()) newError("DNS: created Remote DOH client for ", url.String()).AtInfo().WriteToLog()
s := baseDOHNameServer(url, "DOH", queryStrategy) s := baseDOHNameServer(url, "DOH", queryStrategy)
s.dispatcher = dispatcher s.dispatcher = dispatcher
@ -120,7 +119,7 @@ func NewDoHLocalNameServer(url *url.URL, queryStrategy QueryStrategy) *DoHNameSe
Timeout: time.Second * 180, Timeout: time.Second * 180,
Transport: tr, Transport: tr,
} }
errors.LogInfo(context.Background(), "DNS: created Local DOH client for ", url.String()) newError("DNS: created Local DOH client for ", url.String()).AtInfo().WriteToLog()
return s return s
} }
@ -151,7 +150,7 @@ func (s *DoHNameServer) Cleanup() error {
defer s.Unlock() defer s.Unlock()
if len(s.ips) == 0 { if len(s.ips) == 0 {
return errors.New("nothing to do. stopping...") return newError("nothing to do. stopping...")
} }
for domain, record := range s.ips { for domain, record := range s.ips {
@ -163,7 +162,7 @@ func (s *DoHNameServer) Cleanup() error {
} }
if record.A == nil && record.AAAA == nil { if record.A == nil && record.AAAA == nil {
errors.LogDebug(context.Background(), s.name, " cleanup ", domain) newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
delete(s.ips, domain) delete(s.ips, domain)
} else { } else {
s.ips[domain] = record s.ips[domain] = record
@ -206,7 +205,7 @@ func (s *DoHNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
updated = true updated = true
} }
} }
errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed) newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
if updated { if updated {
s.ips[req.domain] = rec s.ips[req.domain] = rec
@ -226,10 +225,10 @@ func (s *DoHNameServer) newReqID() uint16 {
} }
func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) { func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
errors.LogInfo(ctx, s.name, " querying: ", domain) newError(s.name, " querying: ", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))
if s.name+"." == "DOH//"+domain { if s.name+"." == "DOH//"+domain {
errors.LogError(ctx, s.name, " tries to resolve itself! Use IP or set \"hosts\" instead.") newError(s.name, " tries to resolve itself! Use IP or set \"hosts\" instead.").AtError().WriteToLog(session.ExportIDToError(ctx))
return return
} }
@ -259,7 +258,7 @@ func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP n
}) })
// forced to use mux for DOH // forced to use mux for DOH
// dnsCtx = session.ContextWithMuxPreferred(dnsCtx, true) // dnsCtx = session.ContextWithMuxPrefered(dnsCtx, true)
var cancel context.CancelFunc var cancel context.CancelFunc
dnsCtx, cancel = context.WithDeadline(dnsCtx, deadline) dnsCtx, cancel = context.WithDeadline(dnsCtx, deadline)
@ -267,17 +266,17 @@ func (s *DoHNameServer) sendQuery(ctx context.Context, domain string, clientIP n
b, err := dns.PackMessage(r.msg) b, err := dns.PackMessage(r.msg)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to pack dns query for ", domain) newError("failed to pack dns query for ", domain).Base(err).AtError().WriteToLog()
return return
} }
resp, err := s.dohHTTPSContext(dnsCtx, b.Bytes()) resp, err := s.dohHTTPSContext(dnsCtx, b.Bytes())
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to retrieve response for ", domain) newError("failed to retrieve response for ", domain).Base(err).AtError().WriteToLog()
return return
} }
rec, err := parseResponse(resp) rec, err := parseResponse(resp)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to handle DOH response for ", domain) newError("failed to handle DOH response for ", domain).Base(err).AtError().WriteToLog()
return return
} }
s.updateIP(r, rec) s.updateIP(r, rec)
@ -362,11 +361,11 @@ func (s *DoHNameServer) QueryIP(ctx context.Context, domain string, clientIP net
} }
if disableCache { if disableCache {
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name) newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
} else { } else {
ips, err := s.findIPsForDomain(fqdn, option) ips, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse { if err != errRecordNotFound {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips) 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}) log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err return ips, err
} }

View File

@ -3,7 +3,6 @@ package dns
import ( import (
"context" "context"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns"
@ -26,7 +25,7 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) { if err := core.RequireFeatures(ctx, func(fd dns.FakeDNSEngine) {
f.fakeDNSEngine = fd f.fakeDNSEngine = fd
}); err != nil { }); err != nil {
return nil, errors.New("Unable to locate a fake DNS Engine").Base(err).AtError() return nil, newError("Unable to locate a fake DNS Engine").Base(err).AtError()
} }
} }
var ips []net.Address var ips []net.Address
@ -38,10 +37,10 @@ func (f *FakeDNSServer) QueryIP(ctx context.Context, domain string, _ net.IP, op
netIP, err := toNetIP(ips) netIP, err := toNetIP(ips)
if err != nil { if err != nil {
return nil, errors.New("Unable to convert IP to net ip").Base(err).AtError() return nil, newError("Unable to convert IP to net ip").Base(err).AtError()
} }
errors.LogInfo(ctx, f.Name(), " got answer: ", domain, " -> ", ips) newError(f.Name(), " got answer: ", domain, " -> ", ips).AtInfo().WriteToLog()
if len(netIP) > 0 { if len(netIP) > 0 {
return netIP, nil return netIP, nil

View File

@ -5,7 +5,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/features/dns" "github.com/xtls/xray-core/features/dns"
@ -20,7 +19,7 @@ type LocalNameServer struct {
const errEmptyResponse = "No address associated with hostname" const errEmptyResponse = "No address associated with hostname"
// QueryIP implements Server. // QueryIP implements Server.
func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) { func (s *LocalNameServer) QueryIP(_ context.Context, domain string, _ net.IP, option dns.IPOption, _ bool) (ips []net.IP, err error) {
start := time.Now() start := time.Now()
ips, err = s.client.LookupIP(domain, option) ips, err = s.client.LookupIP(domain, option)
@ -29,7 +28,7 @@ func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, _ net.IP,
} }
if len(ips) > 0 { if len(ips) > 0 {
errors.LogInfo(ctx, "Localhost got answer: ", domain, " -> ", ips) 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}) log.Record(&log.DNSLog{Server: s.Name(), Domain: domain, Result: ips, Status: log.DNSQueried, Elapsed: time.Since(start), Error: err})
} }
@ -43,7 +42,7 @@ func (s *LocalNameServer) Name() string {
// NewLocalNameServer creates localdns server object for directly lookup in system DNS. // NewLocalNameServer creates localdns server object for directly lookup in system DNS.
func NewLocalNameServer() *LocalNameServer { func NewLocalNameServer() *LocalNameServer {
errors.LogInfo(context.Background(), "DNS: created localhost client") newError("DNS: created localhost client").AtInfo().WriteToLog()
return &LocalNameServer{ return &LocalNameServer{
client: localdns.New(), client: localdns.New(),
} }

View File

@ -1,9 +1,7 @@
package dns package dns
import ( import (
"bytes"
"context" "context"
"encoding/binary"
"net/url" "net/url"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -12,7 +10,6 @@ import (
"github.com/quic-go/quic-go" "github.com/quic-go/quic-go"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol/dns" "github.com/xtls/xray-core/common/protocol/dns"
@ -27,7 +24,7 @@ import (
// NextProtoDQ - During connection establishment, DNS/QUIC support is indicated // NextProtoDQ - During connection establishment, DNS/QUIC support is indicated
// by selecting the ALPN token "dq" in the crypto handshake. // by selecting the ALPN token "dq" in the crypto handshake.
const NextProtoDQ = "doq" const NextProtoDQ = "doq-i00"
const handshakeTimeout = time.Second * 8 const handshakeTimeout = time.Second * 8
@ -46,10 +43,10 @@ type QUICNameServer struct {
// NewQUICNameServer creates DNS-over-QUIC client object for local resolving // NewQUICNameServer creates DNS-over-QUIC client object for local resolving
func NewQUICNameServer(url *url.URL, queryStrategy QueryStrategy) (*QUICNameServer, error) { func NewQUICNameServer(url *url.URL, queryStrategy QueryStrategy) (*QUICNameServer, error) {
errors.LogInfo(context.Background(), "DNS: created Local DNS-over-QUIC client for ", url.String()) newError("DNS: created Local DNS-over-QUIC client for ", url.String()).AtInfo().WriteToLog()
var err error var err error
port := net.Port(853) port := net.Port(784)
if url.Port() != "" { if url.Port() != "" {
port, err = net.PortFromString(url.Port()) port, err = net.PortFromString(url.Port())
if err != nil { if err != nil {
@ -85,7 +82,7 @@ func (s *QUICNameServer) Cleanup() error {
defer s.Unlock() defer s.Unlock()
if len(s.ips) == 0 { if len(s.ips) == 0 {
return errors.New("nothing to do. stopping...") return newError("nothing to do. stopping...")
} }
for domain, record := range s.ips { for domain, record := range s.ips {
@ -97,7 +94,7 @@ func (s *QUICNameServer) Cleanup() error {
} }
if record.A == nil && record.AAAA == nil { if record.A == nil && record.AAAA == nil {
errors.LogDebug(context.Background(), s.name, " cleanup ", domain) newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
delete(s.ips, domain) delete(s.ips, domain)
} else { } else {
s.ips[domain] = record s.ips[domain] = record
@ -140,7 +137,7 @@ func (s *QUICNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
updated = true updated = true
} }
} }
errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed) newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
if updated { if updated {
s.ips[req.domain] = rec s.ips[req.domain] = rec
@ -160,7 +157,7 @@ func (s *QUICNameServer) newReqID() uint16 {
} }
func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) { func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
errors.LogInfo(ctx, s.name, " querying: ", domain) newError(s.name, " querying: ", domain).AtInfo().WriteToLog(session.ExportIDToError(ctx))
reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP)) reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
@ -193,24 +190,19 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
b, err := dns.PackMessage(r.msg) b, err := dns.PackMessage(r.msg)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to pack dns query") newError("failed to pack dns query").Base(err).AtError().WriteToLog()
return return
} }
dnsReqBuf := buf.New()
binary.Write(dnsReqBuf, binary.BigEndian, uint16(b.Len()))
dnsReqBuf.Write(b.Bytes())
b.Release()
conn, err := s.openStream(dnsCtx) conn, err := s.openStream(dnsCtx)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to open quic connection") newError("failed to open quic connection").Base(err).AtError().WriteToLog()
return return
} }
_, err = conn.Write(dnsReqBuf.Bytes()) _, err = conn.Write(b.Bytes())
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to send query") newError("failed to send query").Base(err).AtError().WriteToLog()
return return
} }
@ -218,27 +210,15 @@ func (s *QUICNameServer) sendQuery(ctx context.Context, domain string, clientIP
respBuf := buf.New() respBuf := buf.New()
defer respBuf.Release() defer respBuf.Release()
n, err := respBuf.ReadFullFrom(conn, 2) n, err := respBuf.ReadFrom(conn)
if err != nil && n == 0 { if err != nil && n == 0 {
errors.LogErrorInner(ctx, err, "failed to read response length") newError("failed to read response").Base(err).AtError().WriteToLog()
return
}
var length int16
err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
if err != nil {
errors.LogErrorInner(ctx, err, "failed to parse response length")
return
}
respBuf.Clear()
n, err = respBuf.ReadFullFrom(conn, int32(length))
if err != nil && n == 0 {
errors.LogErrorInner(ctx, err, "failed to read response length")
return return
} }
rec, err := parseResponse(respBuf.Bytes()) rec, err := parseResponse(respBuf.Bytes())
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to handle response") newError("failed to handle response").Base(err).AtError().WriteToLog()
return return
} }
s.updateIP(r, rec) s.updateIP(r, rec)
@ -297,11 +277,11 @@ func (s *QUICNameServer) QueryIP(ctx context.Context, domain string, clientIP ne
} }
if disableCache { if disableCache {
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name) newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
} else { } else {
ips, err := s.findIPsForDomain(fqdn, option) ips, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse { if err != errRecordNotFound {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips) 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}) log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err return ips, err
} }

View File

@ -14,7 +14,7 @@ import (
) )
func TestQUICNameServer(t *testing.T) { func TestQUICNameServer(t *testing.T) {
url, err := url.Parse("quic://dns.adguard-dns.com") url, err := url.Parse("quic://dns.adguard.com")
common.Must(err) common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP) s, err := NewQUICNameServer(url, QueryStrategy_USE_IP)
common.Must(err) common.Must(err)
@ -42,7 +42,7 @@ func TestQUICNameServer(t *testing.T) {
} }
func TestQUICNameServerWithIPv4Override(t *testing.T) { func TestQUICNameServerWithIPv4Override(t *testing.T) {
url, err := url.Parse("quic://dns.adguard-dns.com") url, err := url.Parse("quic://dns.adguard.com")
common.Must(err) common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP4) s, err := NewQUICNameServer(url, QueryStrategy_USE_IP4)
common.Must(err) common.Must(err)
@ -65,7 +65,7 @@ func TestQUICNameServerWithIPv4Override(t *testing.T) {
} }
func TestQUICNameServerWithIPv6Override(t *testing.T) { func TestQUICNameServerWithIPv6Override(t *testing.T) {
url, err := url.Parse("quic://dns.adguard-dns.com") url, err := url.Parse("quic://dns.adguard.com")
common.Must(err) common.Must(err)
s, err := NewQUICNameServer(url, QueryStrategy_USE_IP6) s, err := NewQUICNameServer(url, QueryStrategy_USE_IP6)
common.Must(err) common.Must(err)

View File

@ -11,7 +11,6 @@ import (
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/net/cnc"
@ -115,7 +114,7 @@ func (s *TCPNameServer) Cleanup() error {
defer s.Unlock() defer s.Unlock()
if len(s.ips) == 0 { if len(s.ips) == 0 {
return errors.New("nothing to do. stopping...") return newError("nothing to do. stopping...")
} }
for domain, record := range s.ips { for domain, record := range s.ips {
@ -127,7 +126,7 @@ func (s *TCPNameServer) Cleanup() error {
} }
if record.A == nil && record.AAAA == nil { if record.A == nil && record.AAAA == nil {
errors.LogDebug(context.Background(), s.name, " cleanup ", domain) newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
delete(s.ips, domain) delete(s.ips, domain)
} else { } else {
s.ips[domain] = record s.ips[domain] = record
@ -170,7 +169,7 @@ func (s *TCPNameServer) updateIP(req *dnsRequest, ipRec *IPRecord) {
updated = true updated = true
} }
} }
errors.LogInfo(context.Background(), s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed) newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
if updated { if updated {
s.ips[req.domain] = rec s.ips[req.domain] = rec
@ -190,7 +189,7 @@ func (s *TCPNameServer) newReqID() uint16 {
} }
func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) { func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
errors.LogDebug(ctx, s.name, " querying DNS for: ", domain) newError(s.name, " querying DNS for: ", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))
reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP)) reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
@ -220,13 +219,13 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
b, err := dns.PackMessage(r.msg) b, err := dns.PackMessage(r.msg)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to pack dns query") newError("failed to pack dns query").Base(err).AtError().WriteToLog()
return return
} }
conn, err := s.dial(dnsCtx) conn, err := s.dial(dnsCtx)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to dial namesever") newError("failed to dial namesever").Base(err).AtError().WriteToLog()
return return
} }
defer conn.Close() defer conn.Close()
@ -237,7 +236,7 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
_, err = conn.Write(dnsReqBuf.Bytes()) _, err = conn.Write(dnsReqBuf.Bytes())
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to send query") newError("failed to send query").Base(err).AtError().WriteToLog()
return return
} }
dnsReqBuf.Release() dnsReqBuf.Release()
@ -246,25 +245,25 @@ func (s *TCPNameServer) sendQuery(ctx context.Context, domain string, clientIP n
defer respBuf.Release() defer respBuf.Release()
n, err := respBuf.ReadFullFrom(conn, 2) n, err := respBuf.ReadFullFrom(conn, 2)
if err != nil && n == 0 { if err != nil && n == 0 {
errors.LogErrorInner(ctx, err, "failed to read response length") newError("failed to read response length").Base(err).AtError().WriteToLog()
return return
} }
var length int16 var length int16
err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length) err = binary.Read(bytes.NewReader(respBuf.Bytes()), binary.BigEndian, &length)
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to parse response length") newError("failed to parse response length").Base(err).AtError().WriteToLog()
return return
} }
respBuf.Clear() respBuf.Clear()
n, err = respBuf.ReadFullFrom(conn, int32(length)) n, err = respBuf.ReadFullFrom(conn, int32(length))
if err != nil && n == 0 { if err != nil && n == 0 {
errors.LogErrorInner(ctx, err, "failed to read response length") newError("failed to read response length").Base(err).AtError().WriteToLog()
return return
} }
rec, err := parseResponse(respBuf.Bytes()) rec, err := parseResponse(respBuf.Bytes())
if err != nil { if err != nil {
errors.LogErrorInner(ctx, err, "failed to parse DNS over TCP response") newError("failed to parse DNS over TCP response").Base(err).AtError().WriteToLog()
return return
} }
@ -320,11 +319,11 @@ func (s *TCPNameServer) QueryIP(ctx context.Context, domain string, clientIP net
} }
if disableCache { if disableCache {
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name) newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
} else { } else {
ips, err := s.findIPsForDomain(fqdn, option) ips, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse { if err != errRecordNotFound {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips) 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}) log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err return ips, err
} }

View File

@ -8,11 +8,11 @@ import (
"time" "time"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/protocol/dns" "github.com/xtls/xray-core/common/protocol/dns"
udp_proto "github.com/xtls/xray-core/common/protocol/udp" udp_proto "github.com/xtls/xray-core/common/protocol/udp"
"github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal/pubsub" "github.com/xtls/xray-core/common/signal/pubsub"
"github.com/xtls/xray-core/common/task" "github.com/xtls/xray-core/common/task"
dns_feature "github.com/xtls/xray-core/features/dns" dns_feature "github.com/xtls/xray-core/features/dns"
@ -24,38 +24,36 @@ import (
// ClassicNameServer implemented traditional UDP DNS. // ClassicNameServer implemented traditional UDP DNS.
type ClassicNameServer struct { type ClassicNameServer struct {
sync.RWMutex sync.RWMutex
name string name string
address *net.Destination address *net.Destination
ips map[string]*record ips map[string]*record
requests map[uint16]*dnsRequest requests map[uint16]*dnsRequest
pub *pubsub.Service pub *pubsub.Service
udpServer *udp.Dispatcher udpServer *udp.Dispatcher
cleanup *task.Periodic cleanup *task.Periodic
reqID uint32 reqID uint32
queryStrategy QueryStrategy
} }
// NewClassicNameServer creates udp server object for remote resolving. // NewClassicNameServer creates udp server object for remote resolving.
func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher, queryStrategy QueryStrategy) *ClassicNameServer { func NewClassicNameServer(address net.Destination, dispatcher routing.Dispatcher) *ClassicNameServer {
// default to 53 if unspecific // default to 53 if unspecific
if address.Port == 0 { if address.Port == 0 {
address.Port = net.Port(53) address.Port = net.Port(53)
} }
s := &ClassicNameServer{ s := &ClassicNameServer{
address: &address, address: &address,
ips: make(map[string]*record), ips: make(map[string]*record),
requests: make(map[uint16]*dnsRequest), requests: make(map[uint16]*dnsRequest),
pub: pubsub.NewService(), pub: pubsub.NewService(),
name: strings.ToUpper(address.String()), name: strings.ToUpper(address.String()),
queryStrategy: queryStrategy,
} }
s.cleanup = &task.Periodic{ s.cleanup = &task.Periodic{
Interval: time.Minute, Interval: time.Minute,
Execute: s.Cleanup, Execute: s.Cleanup,
} }
s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse) s.udpServer = udp.NewDispatcher(dispatcher, s.HandleResponse)
errors.LogInfo(context.Background(), "DNS: created UDP client initialized for ", address.NetAddr()) newError("DNS: created UDP client initialized for ", address.NetAddr()).AtInfo().WriteToLog()
return s return s
} }
@ -71,7 +69,7 @@ func (s *ClassicNameServer) Cleanup() error {
defer s.Unlock() defer s.Unlock()
if len(s.ips) == 0 && len(s.requests) == 0 { if len(s.ips) == 0 && len(s.requests) == 0 {
return errors.New(s.name, " nothing to do. stopping...") return newError(s.name, " nothing to do. stopping...")
} }
for domain, record := range s.ips { for domain, record := range s.ips {
@ -83,7 +81,7 @@ func (s *ClassicNameServer) Cleanup() error {
} }
if record.A == nil && record.AAAA == nil { if record.A == nil && record.AAAA == nil {
errors.LogDebug(context.Background(), s.name, " cleanup ", domain) newError(s.name, " cleanup ", domain).AtDebug().WriteToLog()
delete(s.ips, domain) delete(s.ips, domain)
} else { } else {
s.ips[domain] = record s.ips[domain] = record
@ -111,7 +109,7 @@ func (s *ClassicNameServer) Cleanup() error {
func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) { func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_proto.Packet) {
ipRec, err := parseResponse(packet.Payload.Bytes()) ipRec, err := parseResponse(packet.Payload.Bytes())
if err != nil { if err != nil {
errors.LogError(ctx, s.name, " fail to parse responded DNS udp") newError(s.name, " fail to parse responded DNS udp").AtError().WriteToLog()
return return
} }
@ -124,7 +122,7 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot
} }
s.Unlock() s.Unlock()
if !ok { if !ok {
errors.LogError(ctx, s.name, " cannot find the pending request") newError(s.name, " cannot find the pending request").AtError().WriteToLog()
return return
} }
@ -137,7 +135,7 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot
} }
elapsed := time.Since(req.start) elapsed := time.Since(req.start)
errors.LogInfo(ctx, s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed) newError(s.name, " got answer: ", req.domain, " ", req.reqType, " -> ", ipRec.IP, " ", elapsed).AtInfo().WriteToLog()
if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) { if len(req.domain) > 0 && (rec.A != nil || rec.AAAA != nil) {
s.updateIP(req.domain, &rec) s.updateIP(req.domain, &rec)
} }
@ -162,7 +160,7 @@ func (s *ClassicNameServer) updateIP(domain string, newRec *record) {
} }
if updated { if updated {
errors.LogDebug(context.Background(), s.name, " updating IP records for domain:", domain) newError(s.name, " updating IP records for domain:", domain).AtDebug().WriteToLog()
s.ips[domain] = rec s.ips[domain] = rec
} }
if newRec.A != nil { if newRec.A != nil {
@ -189,7 +187,7 @@ func (s *ClassicNameServer) addPendingRequest(req *dnsRequest) {
} }
func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) { func (s *ClassicNameServer) sendQuery(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption) {
errors.LogDebug(ctx, s.name, " querying DNS for: ", domain) newError(s.name, " querying DNS for: ", domain).AtDebug().WriteToLog(session.ExportIDToError(ctx))
reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP)) reqs := buildReqMsgs(domain, option, s.newReqID, genEDNS0Options(clientIP))
@ -241,17 +239,13 @@ func (s *ClassicNameServer) findIPsForDomain(domain string, option dns_feature.I
// QueryIP implements Server. // QueryIP implements Server.
func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) { func (s *ClassicNameServer) QueryIP(ctx context.Context, domain string, clientIP net.IP, option dns_feature.IPOption, disableCache bool) ([]net.IP, error) {
fqdn := Fqdn(domain) fqdn := Fqdn(domain)
option = ResolveIpOptionOverride(s.queryStrategy, option)
if !option.IPv4Enable && !option.IPv6Enable {
return nil, dns_feature.ErrEmptyResponse
}
if disableCache { if disableCache {
errors.LogDebug(ctx, "DNS cache is disabled. Querying IP for ", domain, " at ", s.name) newError("DNS cache is disabled. Querying IP for ", domain, " at ", s.name).AtDebug().WriteToLog()
} else { } else {
ips, err := s.findIPsForDomain(fqdn, option) ips, err := s.findIPsForDomain(fqdn, option)
if err == nil || err == dns_feature.ErrEmptyResponse { if err != errRecordNotFound {
errors.LogDebugInner(ctx, err, s.name, " cache HIT ", domain, " -> ", ips) 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}) log.Record(&log.DNSLog{Server: s.name, Domain: domain, Result: ips, Status: log.DNSCacheHit, Elapsed: 0, Error: err})
return ips, err return ips, err
} }

View File

@ -1,11 +1,12 @@
package command package command
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"github.com/xtls/xray-core/app/log" "github.com/xtls/xray-core/app/log"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
) )
@ -18,13 +19,13 @@ type LoggerServer struct {
func (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) { func (s *LoggerServer) RestartLogger(ctx context.Context, request *RestartLoggerRequest) (*RestartLoggerResponse, error) {
logger := s.V.GetFeature((*log.Instance)(nil)) logger := s.V.GetFeature((*log.Instance)(nil))
if logger == nil { if logger == nil {
return nil, errors.New("unable to get logger instance") return nil, newError("unable to get logger instance")
} }
if err := logger.Close(); err != nil { if err := logger.Close(); err != nil {
return nil, errors.New("failed to close logger").Base(err) return nil, newError("failed to close logger").Base(err)
} }
if err := logger.Start(); err != nil { if err := logger.Start(); err != nil {
return nil, errors.New("failed to start logger").Base(err) return nil, newError("failed to start logger").Base(err)
} }
return &RestartLoggerResponse{}, nil return &RestartLoggerResponse{}, nil
} }

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/log/command/config.proto // source: app/log/command/config.proto
package command package command
@ -28,9 +28,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_log_command_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_log_command_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -41,7 +43,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_log_command_config_proto_msgTypes[0] mi := &file_app_log_command_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -64,9 +66,11 @@ type RestartLoggerRequest struct {
func (x *RestartLoggerRequest) Reset() { func (x *RestartLoggerRequest) Reset() {
*x = RestartLoggerRequest{} *x = RestartLoggerRequest{}
mi := &file_app_log_command_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_log_command_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *RestartLoggerRequest) String() string { func (x *RestartLoggerRequest) String() string {
@ -77,7 +81,7 @@ func (*RestartLoggerRequest) ProtoMessage() {}
func (x *RestartLoggerRequest) ProtoReflect() protoreflect.Message { func (x *RestartLoggerRequest) ProtoReflect() protoreflect.Message {
mi := &file_app_log_command_config_proto_msgTypes[1] mi := &file_app_log_command_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -100,9 +104,11 @@ type RestartLoggerResponse struct {
func (x *RestartLoggerResponse) Reset() { func (x *RestartLoggerResponse) Reset() {
*x = RestartLoggerResponse{} *x = RestartLoggerResponse{}
mi := &file_app_log_command_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_log_command_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *RestartLoggerResponse) String() string { func (x *RestartLoggerResponse) String() string {
@ -113,7 +119,7 @@ func (*RestartLoggerResponse) ProtoMessage() {}
func (x *RestartLoggerResponse) ProtoReflect() protoreflect.Message { func (x *RestartLoggerResponse) ProtoReflect() protoreflect.Message {
mi := &file_app_log_command_config_proto_msgTypes[2] mi := &file_app_log_command_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -168,7 +174,7 @@ func file_app_log_command_config_proto_rawDescGZIP() []byte {
} }
var file_app_log_command_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_app_log_command_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_app_log_command_config_proto_goTypes = []any{ var file_app_log_command_config_proto_goTypes = []interface{}{
(*Config)(nil), // 0: xray.app.log.command.Config (*Config)(nil), // 0: xray.app.log.command.Config
(*RestartLoggerRequest)(nil), // 1: xray.app.log.command.RestartLoggerRequest (*RestartLoggerRequest)(nil), // 1: xray.app.log.command.RestartLoggerRequest
(*RestartLoggerResponse)(nil), // 2: xray.app.log.command.RestartLoggerResponse (*RestartLoggerResponse)(nil), // 2: xray.app.log.command.RestartLoggerResponse
@ -188,6 +194,44 @@ func file_app_log_command_config_proto_init() {
if File_app_log_command_config_proto != nil { if File_app_log_command_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_log_command_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
}
}
file_app_log_command_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RestartLoggerRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_log_command_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RestartLoggerResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.3.0
// - protoc v5.28.2 // - protoc v4.23.1
// source: app/log/command/config.proto // source: app/log/command/config.proto
package command package command
@ -15,8 +15,8 @@ import (
// This is a compile-time assertion to ensure that this generated file // This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against. // is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later. // Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion9 const _ = grpc.SupportPackageIsVersion7
const ( const (
LoggerService_RestartLogger_FullMethodName = "/xray.app.log.command.LoggerService/RestartLogger" LoggerService_RestartLogger_FullMethodName = "/xray.app.log.command.LoggerService/RestartLogger"
@ -38,9 +38,8 @@ func NewLoggerServiceClient(cc grpc.ClientConnInterface) LoggerServiceClient {
} }
func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error) { func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLoggerRequest, opts ...grpc.CallOption) (*RestartLoggerResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RestartLoggerResponse) out := new(RestartLoggerResponse)
err := c.cc.Invoke(ctx, LoggerService_RestartLogger_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, LoggerService_RestartLogger_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -49,24 +48,20 @@ func (c *loggerServiceClient) RestartLogger(ctx context.Context, in *RestartLogg
// LoggerServiceServer is the server API for LoggerService service. // LoggerServiceServer is the server API for LoggerService service.
// All implementations must embed UnimplementedLoggerServiceServer // All implementations must embed UnimplementedLoggerServiceServer
// for forward compatibility. // for forward compatibility
type LoggerServiceServer interface { type LoggerServiceServer interface {
RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error) RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error)
mustEmbedUnimplementedLoggerServiceServer() mustEmbedUnimplementedLoggerServiceServer()
} }
// UnimplementedLoggerServiceServer must be embedded to have // UnimplementedLoggerServiceServer must be embedded to have forward compatible implementations.
// forward compatible implementations. type UnimplementedLoggerServiceServer struct {
// }
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedLoggerServiceServer struct{}
func (UnimplementedLoggerServiceServer) RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error) { func (UnimplementedLoggerServiceServer) RestartLogger(context.Context, *RestartLoggerRequest) (*RestartLoggerResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method RestartLogger not implemented") return nil, status.Errorf(codes.Unimplemented, "method RestartLogger not implemented")
} }
func (UnimplementedLoggerServiceServer) mustEmbedUnimplementedLoggerServiceServer() {} func (UnimplementedLoggerServiceServer) mustEmbedUnimplementedLoggerServiceServer() {}
func (UnimplementedLoggerServiceServer) testEmbeddedByValue() {}
// UnsafeLoggerServiceServer may be embedded to opt out of forward compatibility for this service. // UnsafeLoggerServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to LoggerServiceServer will // Use of this interface is not recommended, as added methods to LoggerServiceServer will
@ -76,13 +71,6 @@ type UnsafeLoggerServiceServer interface {
} }
func RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) { func RegisterLoggerServiceServer(s grpc.ServiceRegistrar, srv LoggerServiceServer) {
// If the following call pancis, it indicates UnimplementedLoggerServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&LoggerService_ServiceDesc, srv) s.RegisterService(&LoggerService_ServiceDesc, srv)
} }

View File

@ -0,0 +1,9 @@
package command
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,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/log/config.proto // source: app/log/config.proto
package log package log
@ -84,14 +84,15 @@ type Config struct {
AccessLogType LogType `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,proto3,enum=xray.app.log.LogType" json:"access_log_type,omitempty"` AccessLogType LogType `protobuf:"varint,4,opt,name=access_log_type,json=accessLogType,proto3,enum=xray.app.log.LogType" json:"access_log_type,omitempty"`
AccessLogPath string `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath,proto3" json:"access_log_path,omitempty"` AccessLogPath string `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath,proto3" json:"access_log_path,omitempty"`
EnableDnsLog bool `protobuf:"varint,6,opt,name=enable_dns_log,json=enableDnsLog,proto3" json:"enable_dns_log,omitempty"` EnableDnsLog bool `protobuf:"varint,6,opt,name=enable_dns_log,json=enableDnsLog,proto3" json:"enable_dns_log,omitempty"`
MaskAddress string `protobuf:"bytes,7,opt,name=mask_address,json=maskAddress,proto3" json:"mask_address,omitempty"`
} }
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_log_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_log_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -102,7 +103,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_log_config_proto_msgTypes[0] mi := &file_app_log_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -159,20 +160,13 @@ func (x *Config) GetEnableDnsLog() bool {
return false return false
} }
func (x *Config) GetMaskAddress() string {
if x != nil {
return x.MaskAddress
}
return ""
}
var File_app_log_config_proto protoreflect.FileDescriptor var File_app_log_config_proto protoreflect.FileDescriptor
var file_app_log_config_proto_rawDesc = []byte{ var file_app_log_config_proto_rawDesc = []byte{
0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x6c, 0x6f, 0x67, 0x1a, 0x14, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6c, 0x6f, 0x67, 0x2e, 0x6c, 0x6f, 0x67, 0x1a, 0x14, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x6c, 0x6f, 0x67,
0x2f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xde, 0x02, 0x0a, 0x06, 0x43, 0x2f, 0x6c, 0x6f, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbb, 0x02, 0x0a, 0x06, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x0e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6c,
0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6f, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x2e, 0x4c, 0x6f, 0x67,
@ -192,18 +186,15 @@ var file_app_log_config_proto_rawDesc = []byte{
0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x50, 0x61,
0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x6e, 0x73, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x6e, 0x73,
0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x5f, 0x6c, 0x6f, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62,
0x6c, 0x65, 0x44, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x61, 0x73, 0x6b, 0x6c, 0x65, 0x44, 0x6e, 0x73, 0x4c, 0x6f, 0x67, 0x2a, 0x35, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x54,
0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0b, 0x0a,
0x6d, 0x61, 0x73, 0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2a, 0x35, 0x0a, 0x07, 0x4c, 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x69,
0x6f, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0x03, 0x42,
0x12, 0x0b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x04, 0x46, 0x69, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x6f, 0x67, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x10, 0x03, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65,
0x70, 0x70, 0x2e, 0x6c, 0x6f, 0x67, 0x50, 0x01, 0x5a, 0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6c, 0x6f, 0x67, 0xaa, 0x02, 0x0c, 0x58, 0x72,
0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4c, 0x6f, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
} }
var ( var (
@ -220,7 +211,7 @@ func file_app_log_config_proto_rawDescGZIP() []byte {
var file_app_log_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_app_log_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_app_log_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_app_log_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_app_log_config_proto_goTypes = []any{ var file_app_log_config_proto_goTypes = []interface{}{
(LogType)(0), // 0: xray.app.log.LogType (LogType)(0), // 0: xray.app.log.LogType
(*Config)(nil), // 1: xray.app.log.Config (*Config)(nil), // 1: xray.app.log.Config
(log.Severity)(0), // 2: xray.common.log.Severity (log.Severity)(0), // 2: xray.common.log.Severity
@ -241,6 +232,20 @@ func file_app_log_config_proto_init() {
if File_app_log_config_proto != nil { if File_app_log_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_log_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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -23,5 +23,4 @@ message Config {
LogType access_log_type = 4; LogType access_log_type = 4;
string access_log_path = 5; string access_log_path = 5;
bool enable_dns_log = 6; bool enable_dns_log = 6;
string mask_address= 7;
} }

View File

@ -0,0 +1,9 @@
package log
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,14 +1,12 @@
package log package log
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"fmt"
"regexp"
"strings"
"sync" "sync"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
) )
@ -31,13 +29,13 @@ func New(ctx context.Context, config *Config) (*Instance, error) {
} }
log.RegisterHandler(g) log.RegisterHandler(g)
// start logger now, // start logger instantly on inited
// then other modules will be able to log during initialization // other modules would log during init
if err := g.startInternal(); err != nil { if err := g.startInternal(); err != nil {
return nil, err return nil, err
} }
errors.LogDebug(ctx, "Logger started") newError("Logger started").AtDebug().WriteToLog()
return g, nil return g, nil
} }
@ -79,10 +77,10 @@ func (g *Instance) startInternal() error {
g.active = true g.active = true
if err := g.initAccessLogger(); err != nil { if err := g.initAccessLogger(); err != nil {
return errors.New("failed to initialize access logger").Base(err).AtWarning() return newError("failed to initialize access logger").Base(err).AtWarning()
} }
if err := g.initErrorLogger(); err != nil { if err := g.initErrorLogger(); err != nil {
return errors.New("failed to initialize error logger").Base(err).AtWarning() return newError("failed to initialize error logger").Base(err).AtWarning()
} }
return nil return nil
@ -102,25 +100,18 @@ func (g *Instance) Handle(msg log.Message) {
return return
} }
var Msg log.Message
if g.config.MaskAddress != "" {
Msg = &MaskedMsgWrapper{Message: msg, config: g.config}
} else {
Msg = msg
}
switch msg := msg.(type) { switch msg := msg.(type) {
case *log.AccessMessage: case *log.AccessMessage:
if g.accessLogger != nil { if g.accessLogger != nil {
g.accessLogger.Handle(Msg) g.accessLogger.Handle(msg)
} }
case *log.DNSLog: case *log.DNSLog:
if g.dns && g.accessLogger != nil { if g.dns && g.accessLogger != nil {
g.accessLogger.Handle(Msg) g.accessLogger.Handle(msg)
} }
case *log.GeneralMessage: case *log.GeneralMessage:
if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel { if g.errorLogger != nil && msg.Severity <= g.config.ErrorLogLevel {
g.errorLogger.Handle(Msg) g.errorLogger.Handle(msg)
} }
default: default:
// Swallow // Swallow
@ -129,7 +120,7 @@ func (g *Instance) Handle(msg log.Message) {
// Close implements common.Closable.Close(). // Close implements common.Closable.Close().
func (g *Instance) Close() error { func (g *Instance) Close() error {
errors.LogDebug(context.Background(), "Logger closing") newError("Logger closing").AtDebug().WriteToLog()
g.Lock() g.Lock()
defer g.Unlock() defer g.Unlock()
@ -149,56 +140,6 @@ func (g *Instance) Close() error {
return nil return nil
} }
// MaskedMsgWrapper is to wrap the string() method to mask IP addresses in the log.
type MaskedMsgWrapper struct {
log.Message
config *Config
}
func (m *MaskedMsgWrapper) String() string {
str := m.Message.String()
ipv4Regex := regexp.MustCompile(`(\d{1,3}\.){3}\d{1,3}`)
ipv6Regex := regexp.MustCompile(`((?:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}){2,7})(?:[\/\\%](\d{1,3}))?`)
// Process ipv4
maskedMsg := ipv4Regex.ReplaceAllStringFunc(str, func(ip string) string {
parts := strings.Split(ip, ".")
switch m.config.MaskAddress {
case "half":
return fmt.Sprintf("%s.%s.*.*", parts[0], parts[1])
case "quarter":
return fmt.Sprintf("%s.*.*.*", parts[0])
case "full":
return "[Masked IPv4]"
default:
return ip
}
})
// process ipv6
maskedMsg = ipv6Regex.ReplaceAllStringFunc(maskedMsg, func(ip string) string {
parts := strings.Split(ip, ":")
switch m.config.MaskAddress {
case "half":
if len(parts) >= 2 {
return fmt.Sprintf("%s:%s::/32", parts[0], parts[1])
}
case "quarter":
if len(parts) >= 1 {
return fmt.Sprintf("%s::/16", parts[0])
}
case "full":
return "Masked IPv6" // Do not use [Masked IPv6] like ipv4, or you will get "[[Masked IPv6]]" (v6 address already has [])
default:
return ip
}
return ip
})
return maskedMsg
}
func init() { func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config)) return New(ctx, config.(*Config))

View File

@ -4,7 +4,6 @@ import (
"sync" "sync"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/log" "github.com/xtls/xray-core/common/log"
) )
@ -20,7 +19,7 @@ var handlerCreatorMapLock = &sync.RWMutex{}
func RegisterHandlerCreator(logType LogType, f HandlerCreator) error { func RegisterHandlerCreator(logType LogType, f HandlerCreator) error {
if f == nil { if f == nil {
return errors.New("nil HandlerCreator") return newError("nil HandlerCreator")
} }
handlerCreatorMapLock.Lock() handlerCreatorMapLock.Lock()
@ -36,7 +35,7 @@ func createHandler(logType LogType, options HandlerCreatorOptions) (log.Handler,
creator, found := handlerCreatorMap[logType] creator, found := handlerCreatorMap[logType]
if !found { if !found {
return nil, errors.New("unable to create log handler for ", logType) return nil, newError("unable to create log handler for ", logType)
} }
return creator(logType, options) return creator(logType, options)
} }

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/metrics/config.proto // source: app/metrics/config.proto
package metrics package metrics
@ -32,9 +32,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_metrics_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_metrics_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -45,7 +47,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_metrics_config_proto_msgTypes[0] mi := &file_app_metrics_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -96,7 +98,7 @@ func file_app_metrics_config_proto_rawDescGZIP() []byte {
} }
var file_app_metrics_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_app_metrics_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_app_metrics_config_proto_goTypes = []any{ var file_app_metrics_config_proto_goTypes = []interface{}{
(*Config)(nil), // 0: xray.app.metrics.Config (*Config)(nil), // 0: xray.app.metrics.Config
} }
var file_app_metrics_config_proto_depIdxs = []int32{ var file_app_metrics_config_proto_depIdxs = []int32{
@ -112,6 +114,20 @@ func file_app_metrics_config_proto_init() {
if File_app_metrics_config_proto != nil { if File_app_metrics_config_proto != nil {
return 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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -0,0 +1,9 @@
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

@ -10,7 +10,6 @@ import (
"github.com/xtls/xray-core/app/observatory" "github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/app/stats" "github.com/xtls/xray-core/app/stats"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/common/signal/done"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
@ -94,12 +93,12 @@ func (p *MetricsHandler) Start() error {
go func() { go func() {
if err := http.Serve(listener, http.DefaultServeMux); err != nil { if err := http.Serve(listener, http.DefaultServeMux); err != nil {
errors.LogErrorInner(context.Background(), err, "failed to start metrics server") newError("failed to start metrics server").Base(err).AtError().WriteToLog()
} }
}() }()
if err := p.ohm.RemoveHandler(context.Background(), p.tag); err != nil { if err := p.ohm.RemoveHandler(context.Background(), p.tag); err != nil {
errors.LogInfo(context.Background(), "failed to remove existing handler") newError("failed to remove existing handler").WriteToLog()
} }
return p.ohm.AddHandler(context.Background(), &Outbound{ return p.ohm.AddHandler(context.Background(), &Outbound{

View File

@ -5,7 +5,6 @@ import (
"sync" "sync"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/net/cnc"
"github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/common/signal/done"
@ -32,7 +31,7 @@ func (l *OutboundListener) add(conn net.Conn) {
func (l *OutboundListener) Accept() (net.Conn, error) { func (l *OutboundListener) Accept() (net.Conn, error) {
select { select {
case <-l.done.Wait(): case <-l.done.Wait():
return nil, errors.New("listen closed") return nil, newError("listen closed")
case c := <-l.buffer: case c := <-l.buffer:
return c, nil return c, nil
} }

View File

@ -1,12 +0,0 @@
package burst
import (
"math"
"time"
)
const (
rttFailed = time.Duration(math.MaxInt64 - iota)
rttUntested
rttUnqualified
)

View File

@ -1,110 +0,0 @@
package burst
import (
"context"
"sync"
"github.com/xtls/xray-core/app/observatory"
"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"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"
"google.golang.org/protobuf/proto"
)
type Observer struct {
config *Config
ctx context.Context
statusLock sync.Mutex
hp *HealthPing
finished *done.Instance
ohm outbound.Manager
}
func (o *Observer) GetObservation(ctx context.Context) (proto.Message, error) {
return &observatory.ObservationResult{Status: o.createResult()}, nil
}
func (o *Observer) createResult() []*observatory.OutboundStatus {
var result []*observatory.OutboundStatus
o.hp.access.Lock()
defer o.hp.access.Unlock()
for name, value := range o.hp.Results {
status := observatory.OutboundStatus{
Alive: value.getStatistics().All != value.getStatistics().Fail,
Delay: value.getStatistics().Average.Milliseconds(),
LastErrorReason: "",
OutboundTag: name,
LastSeenTime: 0,
LastTryTime: 0,
HealthPing: &observatory.HealthPingMeasurementResult{
All: int64(value.getStatistics().All),
Fail: int64(value.getStatistics().Fail),
Deviation: int64(value.getStatistics().Deviation),
Average: int64(value.getStatistics().Average),
Max: int64(value.getStatistics().Max),
Min: int64(value.getStatistics().Min),
},
}
result = append(result, &status)
}
return result
}
func (o *Observer) Type() interface{} {
return extension.ObservatoryType()
}
func (o *Observer) Start() error {
if o.config != nil && len(o.config.SubjectSelector) != 0 {
o.finished = done.New()
o.hp.StartScheduler(func() ([]string, error) {
hs, ok := o.ohm.(outbound.HandlerSelector)
if !ok {
return nil, errors.New("outbound.Manager is not a HandlerSelector")
}
outbounds := hs.Select(o.config.SubjectSelector)
return outbounds, nil
})
}
return nil
}
func (o *Observer) Close() error {
if o.finished != nil {
o.hp.StopScheduler()
return o.finished.Close()
}
return nil
}
func New(ctx context.Context, config *Config) (*Observer, error) {
var outboundManager outbound.Manager
err := core.RequireFeatures(ctx, func(om outbound.Manager) {
outboundManager = om
})
if err != nil {
return nil, errors.New("Cannot get depended features").Base(err)
}
hp := NewHealthPing(ctx, config.PingConfig)
return &Observer{
config: config,
ctx: ctx,
ohm: outboundManager,
hp: hp,
}, nil
}
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return New(ctx, config.(*Config))
}))
}

View File

@ -1,246 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.35.1
// protoc v5.28.2
// source: app/observatory/burst/config.proto
package burst
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)
)
type Config struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// @Document The selectors for outbound under observation
SubjectSelector []string `protobuf:"bytes,2,rep,name=subject_selector,json=subjectSelector,proto3" json:"subject_selector,omitempty"`
PingConfig *HealthPingConfig `protobuf:"bytes,3,opt,name=ping_config,json=pingConfig,proto3" json:"ping_config,omitempty"`
}
func (x *Config) Reset() {
*x = Config{}
mi := &file_app_observatory_burst_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_observatory_burst_config_proto_msgTypes[0]
if 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_burst_config_proto_rawDescGZIP(), []int{0}
}
func (x *Config) GetSubjectSelector() []string {
if x != nil {
return x.SubjectSelector
}
return nil
}
func (x *Config) GetPingConfig() *HealthPingConfig {
if x != nil {
return x.PingConfig
}
return nil
}
type HealthPingConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// destination url, need 204 for success return
// default https://connectivitycheck.gstatic.com/generate_204
Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"`
// connectivity check url
Connectivity string `protobuf:"bytes,2,opt,name=connectivity,proto3" json:"connectivity,omitempty"`
// health check interval, int64 values of time.Duration
Interval int64 `protobuf:"varint,3,opt,name=interval,proto3" json:"interval,omitempty"`
// sampling count is the amount of recent ping results which are kept for calculation
SamplingCount int32 `protobuf:"varint,4,opt,name=samplingCount,proto3" json:"samplingCount,omitempty"`
// ping timeout, int64 values of time.Duration
Timeout int64 `protobuf:"varint,5,opt,name=timeout,proto3" json:"timeout,omitempty"`
}
func (x *HealthPingConfig) Reset() {
*x = HealthPingConfig{}
mi := &file_app_observatory_burst_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *HealthPingConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HealthPingConfig) ProtoMessage() {}
func (x *HealthPingConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_burst_config_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HealthPingConfig.ProtoReflect.Descriptor instead.
func (*HealthPingConfig) Descriptor() ([]byte, []int) {
return file_app_observatory_burst_config_proto_rawDescGZIP(), []int{1}
}
func (x *HealthPingConfig) GetDestination() string {
if x != nil {
return x.Destination
}
return ""
}
func (x *HealthPingConfig) GetConnectivity() string {
if x != nil {
return x.Connectivity
}
return ""
}
func (x *HealthPingConfig) GetInterval() int64 {
if x != nil {
return x.Interval
}
return 0
}
func (x *HealthPingConfig) GetSamplingCount() int32 {
if x != nil {
return x.SamplingCount
}
return 0
}
func (x *HealthPingConfig) GetTimeout() int64 {
if x != nil {
return x.Timeout
}
return 0
}
var File_app_observatory_burst_config_proto protoreflect.FileDescriptor
var file_app_observatory_burst_config_proto_rawDesc = []byte{
0x0a, 0x22, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72,
0x79, 0x2f, 0x62, 0x75, 0x72, 0x73, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1f, 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,
0x62, 0x75, 0x72, 0x73, 0x74, 0x22, 0x87, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65,
0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x52, 0x0a, 0x0b, 0x70,
0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x31, 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, 0x62, 0x75, 0x72,
0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x52, 0x0a, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22,
0xb4, 0x01, 0x0a, 0x10, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x43, 0x6f,
0x6e, 0x66, 0x69, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69,
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69,
0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73,
0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07,
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74,
0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x70, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72,
0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2e, 0x62, 0x75, 0x72, 0x73, 0x74, 0x50, 0x01, 0x5a, 0x2f, 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, 0x62, 0x75, 0x72, 0x73, 0x74, 0xaa, 0x02, 0x1a, 0x58, 0x72,
0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f,
0x72, 0x79, 0x2e, 0x42, 0x75, 0x72, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_app_observatory_burst_config_proto_rawDescOnce sync.Once
file_app_observatory_burst_config_proto_rawDescData = file_app_observatory_burst_config_proto_rawDesc
)
func file_app_observatory_burst_config_proto_rawDescGZIP() []byte {
file_app_observatory_burst_config_proto_rawDescOnce.Do(func() {
file_app_observatory_burst_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_observatory_burst_config_proto_rawDescData)
})
return file_app_observatory_burst_config_proto_rawDescData
}
var file_app_observatory_burst_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_app_observatory_burst_config_proto_goTypes = []any{
(*Config)(nil), // 0: xray.core.app.observatory.burst.Config
(*HealthPingConfig)(nil), // 1: xray.core.app.observatory.burst.HealthPingConfig
}
var file_app_observatory_burst_config_proto_depIdxs = []int32{
1, // 0: xray.core.app.observatory.burst.Config.ping_config:type_name -> xray.core.app.observatory.burst.HealthPingConfig
1, // [1:1] is the sub-list for method output_type
1, // [1:1] 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_burst_config_proto_init() }
func file_app_observatory_burst_config_proto_init() {
if File_app_observatory_burst_config_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_observatory_burst_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_app_observatory_burst_config_proto_goTypes,
DependencyIndexes: file_app_observatory_burst_config_proto_depIdxs,
MessageInfos: file_app_observatory_burst_config_proto_msgTypes,
}.Build()
File_app_observatory_burst_config_proto = out.File
file_app_observatory_burst_config_proto_rawDesc = nil
file_app_observatory_burst_config_proto_goTypes = nil
file_app_observatory_burst_config_proto_depIdxs = nil
}

View File

@ -1,29 +0,0 @@
syntax = "proto3";
package xray.core.app.observatory.burst;
option csharp_namespace = "Xray.App.Observatory.Burst";
option go_package = "github.com/xtls/xray-core/app/observatory/burst";
option java_package = "com.xray.app.observatory.burst";
option java_multiple_files = true;
message Config {
/* @Document The selectors for outbound under observation
*/
repeated string subject_selector = 2;
HealthPingConfig ping_config = 3;
}
message HealthPingConfig {
// destination url, need 204 for success return
// default https://connectivitycheck.gstatic.com/generate_204
string destination = 1;
// connectivity check url
string connectivity = 2;
// health check interval, int64 values of time.Duration
int64 interval = 3;
// sampling count is the amount of recent ping results which are kept for calculation
int32 samplingCount = 4;
// ping timeout, int64 values of time.Duration
int64 timeout = 5;
}

View File

@ -1,254 +0,0 @@
package burst
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/xtls/xray-core/common/dice"
"github.com/xtls/xray-core/common/errors"
)
// HealthPingSettings holds settings for health Checker
type HealthPingSettings struct {
Destination string `json:"destination"`
Connectivity string `json:"connectivity"`
Interval time.Duration `json:"interval"`
SamplingCount int `json:"sampling"`
Timeout time.Duration `json:"timeout"`
}
// HealthPing is the health checker for balancers
type HealthPing struct {
ctx context.Context
access sync.Mutex
ticker *time.Ticker
tickerClose chan struct{}
Settings *HealthPingSettings
Results map[string]*HealthPingRTTS
}
// NewHealthPing creates a new HealthPing with settings
func NewHealthPing(ctx context.Context, config *HealthPingConfig) *HealthPing {
settings := &HealthPingSettings{}
if config != nil {
settings = &HealthPingSettings{
Connectivity: strings.TrimSpace(config.Connectivity),
Destination: strings.TrimSpace(config.Destination),
Interval: time.Duration(config.Interval),
SamplingCount: int(config.SamplingCount),
Timeout: time.Duration(config.Timeout),
}
}
if settings.Destination == "" {
// Destination URL, need 204 for success return default to chromium
// https://github.com/chromium/chromium/blob/main/components/safety_check/url_constants.cc#L10
// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/safety_check/url_constants.cc#10
settings.Destination = "https://connectivitycheck.gstatic.com/generate_204"
}
if settings.Interval == 0 {
settings.Interval = time.Duration(1) * time.Minute
} else if settings.Interval < 10 {
errors.LogWarning(ctx, "health check interval is too small, 10s is applied")
settings.Interval = time.Duration(10) * time.Second
}
if settings.SamplingCount <= 0 {
settings.SamplingCount = 10
}
if settings.Timeout <= 0 {
// results are saved after all health pings finish,
// a larger timeout could possibly makes checks run longer
settings.Timeout = time.Duration(5) * time.Second
}
return &HealthPing{
ctx: ctx,
Settings: settings,
Results: nil,
}
}
// StartScheduler implements the HealthChecker
func (h *HealthPing) StartScheduler(selector func() ([]string, error)) {
if h.ticker != nil {
return
}
interval := h.Settings.Interval * time.Duration(h.Settings.SamplingCount)
ticker := time.NewTicker(interval)
tickerClose := make(chan struct{})
h.ticker = ticker
h.tickerClose = tickerClose
go func() {
tags, err := selector()
if err != nil {
errors.LogWarning(h.ctx, "error select outbounds for initial health check: ", err)
return
}
h.Check(tags)
}()
go func() {
for {
go func() {
tags, err := selector()
if err != nil {
errors.LogWarning(h.ctx, "error select outbounds for scheduled health check: ", err)
return
}
h.doCheck(tags, interval, h.Settings.SamplingCount)
h.Cleanup(tags)
}()
select {
case <-ticker.C:
continue
case <-tickerClose:
return
}
}
}()
}
// StopScheduler implements the HealthChecker
func (h *HealthPing) StopScheduler() {
if h.ticker == nil {
return
}
h.ticker.Stop()
h.ticker = nil
close(h.tickerClose)
h.tickerClose = nil
}
// Check implements the HealthChecker
func (h *HealthPing) Check(tags []string) error {
if len(tags) == 0 {
return nil
}
errors.LogInfo(h.ctx, "perform one-time health check for tags ", tags)
h.doCheck(tags, 0, 1)
return nil
}
type rtt struct {
handler string
value time.Duration
}
// doCheck performs the 'rounds' amount checks in given 'duration'. You should make
// sure all tags are valid for current balancer
func (h *HealthPing) doCheck(tags []string, duration time.Duration, rounds int) {
count := len(tags) * rounds
if count == 0 {
return
}
ch := make(chan *rtt, count)
for _, tag := range tags {
handler := tag
client := newPingClient(
h.ctx,
h.Settings.Destination,
h.Settings.Timeout,
handler,
)
for i := 0; i < rounds; i++ {
delay := time.Duration(0)
if duration > 0 {
delay = time.Duration(dice.RollInt63n(int64(duration)))
}
time.AfterFunc(delay, func() {
errors.LogDebug(h.ctx, "checking ", handler)
delay, err := client.MeasureDelay()
if err == nil {
ch <- &rtt{
handler: handler,
value: delay,
}
return
}
if !h.checkConnectivity() {
errors.LogWarning(h.ctx, "network is down")
ch <- &rtt{
handler: handler,
value: 0,
}
return
}
errors.LogWarning(h.ctx, fmt.Sprintf(
"error ping %s with %s: %s",
h.Settings.Destination,
handler,
err,
))
ch <- &rtt{
handler: handler,
value: rttFailed,
}
})
}
}
for i := 0; i < count; i++ {
rtt := <-ch
if rtt.value > 0 {
// should not put results when network is down
h.PutResult(rtt.handler, rtt.value)
}
}
}
// PutResult put a ping rtt to results
func (h *HealthPing) PutResult(tag string, rtt time.Duration) {
h.access.Lock()
defer h.access.Unlock()
if h.Results == nil {
h.Results = make(map[string]*HealthPingRTTS)
}
r, ok := h.Results[tag]
if !ok {
// validity is 2 times to sampling period, since the check are
// distributed in the time line randomly, in extreme cases,
// Previous checks are distributed on the left, and later ones
// on the right
validity := h.Settings.Interval * time.Duration(h.Settings.SamplingCount) * 2
r = NewHealthPingResult(h.Settings.SamplingCount, validity)
h.Results[tag] = r
}
r.Put(rtt)
}
// Cleanup removes results of removed handlers,
// tags should be all valid tags of the Balancer now
func (h *HealthPing) Cleanup(tags []string) {
h.access.Lock()
defer h.access.Unlock()
for tag := range h.Results {
found := false
for _, v := range tags {
if tag == v {
found = true
break
}
}
if !found {
delete(h.Results, tag)
}
}
}
// checkConnectivity checks the network connectivity, it returns
// true if network is good or "connectivity check url" not set
func (h *HealthPing) checkConnectivity() bool {
if h.Settings.Connectivity == "" {
return true
}
tester := newDirectPingClient(
h.Settings.Connectivity,
h.Settings.Timeout,
)
if _, err := tester.MeasureDelay(); err != nil {
return false
}
return true
}

View File

@ -1,143 +0,0 @@
package burst
import (
"math"
"time"
)
// HealthPingStats is the statistics of HealthPingRTTS
type HealthPingStats struct {
All int
Fail int
Deviation time.Duration
Average time.Duration
Max time.Duration
Min time.Duration
}
// HealthPingRTTS holds ping rtts for health Checker
type HealthPingRTTS struct {
idx int
cap int
validity time.Duration
rtts []*pingRTT
lastUpdateAt time.Time
stats *HealthPingStats
}
type pingRTT struct {
time time.Time
value time.Duration
}
// NewHealthPingResult returns a *HealthPingResult with specified capacity
func NewHealthPingResult(cap int, validity time.Duration) *HealthPingRTTS {
return &HealthPingRTTS{cap: cap, validity: validity}
}
// Get gets statistics of the HealthPingRTTS
func (h *HealthPingRTTS) Get() *HealthPingStats {
return h.getStatistics()
}
// GetWithCache get statistics and write cache for next call
// Make sure use Mutex.Lock() before calling it, RWMutex.RLock()
// is not an option since it writes cache
func (h *HealthPingRTTS) GetWithCache() *HealthPingStats {
lastPutAt := h.rtts[h.idx].time
now := time.Now()
if h.stats == nil || h.lastUpdateAt.Before(lastPutAt) || h.findOutdated(now) >= 0 {
h.stats = h.getStatistics()
h.lastUpdateAt = now
}
return h.stats
}
// Put puts a new rtt to the HealthPingResult
func (h *HealthPingRTTS) Put(d time.Duration) {
if h.rtts == nil {
h.rtts = make([]*pingRTT, h.cap)
for i := 0; i < h.cap; i++ {
h.rtts[i] = &pingRTT{}
}
h.idx = -1
}
h.idx = h.calcIndex(1)
now := time.Now()
h.rtts[h.idx].time = now
h.rtts[h.idx].value = d
}
func (h *HealthPingRTTS) calcIndex(step int) int {
idx := h.idx
idx += step
if idx >= h.cap {
idx %= h.cap
}
return idx
}
func (h *HealthPingRTTS) getStatistics() *HealthPingStats {
stats := &HealthPingStats{}
stats.Fail = 0
stats.Max = 0
stats.Min = rttFailed
sum := time.Duration(0)
cnt := 0
validRTTs := make([]time.Duration, 0)
for _, rtt := range h.rtts {
switch {
case rtt.value == 0 || time.Since(rtt.time) > h.validity:
continue
case rtt.value == rttFailed:
stats.Fail++
continue
}
cnt++
sum += rtt.value
validRTTs = append(validRTTs, rtt.value)
if stats.Max < rtt.value {
stats.Max = rtt.value
}
if stats.Min > rtt.value {
stats.Min = rtt.value
}
}
stats.All = cnt + stats.Fail
if cnt == 0 {
stats.Min = 0
return stats
}
stats.Average = time.Duration(int(sum) / cnt)
var std float64
if cnt < 2 {
// no enough data for standard deviation, we assume it's half of the average rtt
// if we don't do this, standard deviation of 1 round tested nodes is 0, will always
// selected before 2 or more rounds tested nodes
std = float64(stats.Average / 2)
} else {
variance := float64(0)
for _, rtt := range validRTTs {
variance += math.Pow(float64(rtt-stats.Average), 2)
}
std = math.Sqrt(variance / float64(cnt))
}
stats.Deviation = time.Duration(std)
return stats
}
func (h *HealthPingRTTS) findOutdated(now time.Time) int {
for i := h.cap - 1; i < 2*h.cap; i++ {
// from oldest to latest
idx := h.calcIndex(i)
validity := h.rtts[idx].time.Add(h.validity)
if h.lastUpdateAt.After(validity) {
return idx
}
if validity.Before(now) {
return idx
}
}
return -1
}

View File

@ -1,106 +0,0 @@
package burst_test
import (
"math"
reflect "reflect"
"testing"
"time"
"github.com/xtls/xray-core/app/observatory/burst"
)
func TestHealthPingResults(t *testing.T) {
rtts := []int64{60, 140, 60, 140, 60, 60, 140, 60, 140}
hr := burst.NewHealthPingResult(4, time.Hour)
for _, rtt := range rtts {
hr.Put(time.Duration(rtt))
}
rttFailed := time.Duration(math.MaxInt64)
expected := &burst.HealthPingStats{
All: 4,
Fail: 0,
Deviation: 40,
Average: 100,
Max: 140,
Min: 60,
}
actual := hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected: %v, actual: %v", expected, actual)
}
hr.Put(rttFailed)
hr.Put(rttFailed)
expected.Fail = 2
actual = hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("failed half-failures test, expected: %v, actual: %v", expected, actual)
}
hr.Put(rttFailed)
hr.Put(rttFailed)
expected = &burst.HealthPingStats{
All: 4,
Fail: 4,
Deviation: 0,
Average: 0,
Max: 0,
Min: 0,
}
actual = hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("failed all-failures test, expected: %v, actual: %v", expected, actual)
}
}
func TestHealthPingResultsIgnoreOutdated(t *testing.T) {
rtts := []int64{60, 140, 60, 140}
hr := burst.NewHealthPingResult(4, time.Duration(10)*time.Millisecond)
for i, rtt := range rtts {
if i == 2 {
// wait for previous 2 outdated
time.Sleep(time.Duration(10) * time.Millisecond)
}
hr.Put(time.Duration(rtt))
}
hr.Get()
expected := &burst.HealthPingStats{
All: 2,
Fail: 0,
Deviation: 40,
Average: 100,
Max: 140,
Min: 60,
}
actual := hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("failed 'half-outdated' test, expected: %v, actual: %v", expected, actual)
}
// wait for all outdated
time.Sleep(time.Duration(10) * time.Millisecond)
expected = &burst.HealthPingStats{
All: 0,
Fail: 0,
Deviation: 0,
Average: 0,
Max: 0,
Min: 0,
}
actual = hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("failed 'outdated / not-tested' test, expected: %v, actual: %v", expected, actual)
}
hr.Put(time.Duration(60))
expected = &burst.HealthPingStats{
All: 1,
Fail: 0,
// 1 sample, std=0.5rtt
Deviation: 30,
Average: 60,
Max: 60,
Min: 60,
}
actual = hr.Get()
if !reflect.DeepEqual(expected, actual) {
t.Errorf("expected: %v, actual: %v", expected, actual)
}
}

View File

@ -1,69 +0,0 @@
package burst
import (
"context"
"net/http"
"time"
"github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/transport/internet/tagged"
)
type pingClient struct {
destination string
httpClient *http.Client
}
func newPingClient(ctx context.Context, destination string, timeout time.Duration, handler string) *pingClient {
return &pingClient{
destination: destination,
httpClient: newHTTPClient(ctx, handler, timeout),
}
}
func newDirectPingClient(destination string, timeout time.Duration) *pingClient {
return &pingClient{
destination: destination,
httpClient: &http.Client{Timeout: timeout},
}
}
func newHTTPClient(ctxv context.Context, handler string, timeout time.Duration) *http.Client {
tr := &http.Transport{
DisableKeepAlives: true,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
dest, err := net.ParseDestination(network + ":" + addr)
if err != nil {
return nil, err
}
return tagged.Dialer(ctxv, dest, handler)
},
}
return &http.Client{
Transport: tr,
Timeout: timeout,
// don't follow redirect
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
}
// MeasureDelay returns the delay time of the request to dest
func (s *pingClient) MeasureDelay() (time.Duration, error) {
if s.httpClient == nil {
panic("pingClient not initialized")
}
req, err := http.NewRequest(http.MethodHead, s.destination, nil)
if err != nil {
return rttFailed, err
}
start := time.Now()
resp, err := s.httpClient.Do(req)
if err != nil {
return rttFailed, err
}
// don't wait for body
resp.Body.Close()
return time.Since(start), nil
}

View File

@ -1,3 +1,6 @@
//go:build !confonly
// +build !confonly
package command package command
import ( import (

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/observatory/command/command.proto // source: app/observatory/command/command.proto
package command package command
@ -29,9 +29,11 @@ type GetOutboundStatusRequest struct {
func (x *GetOutboundStatusRequest) Reset() { func (x *GetOutboundStatusRequest) Reset() {
*x = GetOutboundStatusRequest{} *x = GetOutboundStatusRequest{}
mi := &file_app_observatory_command_command_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_command_command_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *GetOutboundStatusRequest) String() string { func (x *GetOutboundStatusRequest) String() string {
@ -42,7 +44,7 @@ func (*GetOutboundStatusRequest) ProtoMessage() {}
func (x *GetOutboundStatusRequest) ProtoReflect() protoreflect.Message { func (x *GetOutboundStatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[0] mi := &file_app_observatory_command_command_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -67,9 +69,11 @@ type GetOutboundStatusResponse struct {
func (x *GetOutboundStatusResponse) Reset() { func (x *GetOutboundStatusResponse) Reset() {
*x = GetOutboundStatusResponse{} *x = GetOutboundStatusResponse{}
mi := &file_app_observatory_command_command_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_command_command_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *GetOutboundStatusResponse) String() string { func (x *GetOutboundStatusResponse) String() string {
@ -80,7 +84,7 @@ func (*GetOutboundStatusResponse) ProtoMessage() {}
func (x *GetOutboundStatusResponse) ProtoReflect() protoreflect.Message { func (x *GetOutboundStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[1] mi := &file_app_observatory_command_command_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -110,9 +114,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_observatory_command_command_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_command_command_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -123,7 +129,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_command_command_proto_msgTypes[2] mi := &file_app_observatory_command_command_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -191,7 +197,7 @@ func file_app_observatory_command_command_proto_rawDescGZIP() []byte {
} }
var file_app_observatory_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_app_observatory_command_command_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_app_observatory_command_command_proto_goTypes = []any{ var file_app_observatory_command_command_proto_goTypes = []interface{}{
(*GetOutboundStatusRequest)(nil), // 0: xray.core.app.observatory.command.GetOutboundStatusRequest (*GetOutboundStatusRequest)(nil), // 0: xray.core.app.observatory.command.GetOutboundStatusRequest
(*GetOutboundStatusResponse)(nil), // 1: xray.core.app.observatory.command.GetOutboundStatusResponse (*GetOutboundStatusResponse)(nil), // 1: xray.core.app.observatory.command.GetOutboundStatusResponse
(*Config)(nil), // 2: xray.core.app.observatory.command.Config (*Config)(nil), // 2: xray.core.app.observatory.command.Config
@ -213,6 +219,44 @@ func file_app_observatory_command_command_proto_init() {
if File_app_observatory_command_command_proto != nil { if File_app_observatory_command_command_proto != nil {
return 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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.3.0
// - protoc v5.28.2 // - protoc v4.23.1
// source: app/observatory/command/command.proto // source: app/observatory/command/command.proto
package command package command
@ -15,8 +15,8 @@ import (
// This is a compile-time assertion to ensure that this generated file // This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against. // is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later. // Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion9 const _ = grpc.SupportPackageIsVersion7
const ( const (
ObservatoryService_GetOutboundStatus_FullMethodName = "/xray.core.app.observatory.command.ObservatoryService/GetOutboundStatus" ObservatoryService_GetOutboundStatus_FullMethodName = "/xray.core.app.observatory.command.ObservatoryService/GetOutboundStatus"
@ -38,9 +38,8 @@ func NewObservatoryServiceClient(cc grpc.ClientConnInterface) ObservatoryService
} }
func (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error) { func (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *GetOutboundStatusRequest, opts ...grpc.CallOption) (*GetOutboundStatusResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetOutboundStatusResponse) out := new(GetOutboundStatusResponse)
err := c.cc.Invoke(ctx, ObservatoryService_GetOutboundStatus_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, ObservatoryService_GetOutboundStatus_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -49,24 +48,20 @@ func (c *observatoryServiceClient) GetOutboundStatus(ctx context.Context, in *Ge
// ObservatoryServiceServer is the server API for ObservatoryService service. // ObservatoryServiceServer is the server API for ObservatoryService service.
// All implementations must embed UnimplementedObservatoryServiceServer // All implementations must embed UnimplementedObservatoryServiceServer
// for forward compatibility. // for forward compatibility
type ObservatoryServiceServer interface { type ObservatoryServiceServer interface {
GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error)
mustEmbedUnimplementedObservatoryServiceServer() mustEmbedUnimplementedObservatoryServiceServer()
} }
// UnimplementedObservatoryServiceServer must be embedded to have // UnimplementedObservatoryServiceServer must be embedded to have forward compatible implementations.
// forward compatible implementations. type UnimplementedObservatoryServiceServer struct {
// }
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedObservatoryServiceServer struct{}
func (UnimplementedObservatoryServiceServer) GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) { func (UnimplementedObservatoryServiceServer) GetOutboundStatus(context.Context, *GetOutboundStatusRequest) (*GetOutboundStatusResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetOutboundStatus not implemented") return nil, status.Errorf(codes.Unimplemented, "method GetOutboundStatus not implemented")
} }
func (UnimplementedObservatoryServiceServer) mustEmbedUnimplementedObservatoryServiceServer() {} func (UnimplementedObservatoryServiceServer) mustEmbedUnimplementedObservatoryServiceServer() {}
func (UnimplementedObservatoryServiceServer) testEmbeddedByValue() {}
// UnsafeObservatoryServiceServer may be embedded to opt out of forward compatibility for this service. // 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 // Use of this interface is not recommended, as added methods to ObservatoryServiceServer will
@ -76,13 +71,6 @@ type UnsafeObservatoryServiceServer interface {
} }
func RegisterObservatoryServiceServer(s grpc.ServiceRegistrar, srv ObservatoryServiceServer) { func RegisterObservatoryServiceServer(s grpc.ServiceRegistrar, srv ObservatoryServiceServer) {
// If the following call pancis, it indicates UnimplementedObservatoryServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&ObservatoryService_ServiceDesc, srv) s.RegisterService(&ObservatoryService_ServiceDesc, srv)
} }

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/observatory/config.proto // source: app/observatory/config.proto
package observatory package observatory
@ -30,9 +30,11 @@ type ObservationResult struct {
func (x *ObservationResult) Reset() { func (x *ObservationResult) Reset() {
*x = ObservationResult{} *x = ObservationResult{}
mi := &file_app_observatory_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *ObservationResult) String() string { func (x *ObservationResult) String() string {
@ -43,7 +45,7 @@ func (*ObservationResult) ProtoMessage() {}
func (x *ObservationResult) ProtoReflect() protoreflect.Message { func (x *ObservationResult) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[0] mi := &file_app_observatory_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -65,91 +67,6 @@ func (x *ObservationResult) GetStatus() []*OutboundStatus {
return nil return nil
} }
type HealthPingMeasurementResult struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
All int64 `protobuf:"varint,1,opt,name=all,proto3" json:"all,omitempty"`
Fail int64 `protobuf:"varint,2,opt,name=fail,proto3" json:"fail,omitempty"`
Deviation int64 `protobuf:"varint,3,opt,name=deviation,proto3" json:"deviation,omitempty"`
Average int64 `protobuf:"varint,4,opt,name=average,proto3" json:"average,omitempty"`
Max int64 `protobuf:"varint,5,opt,name=max,proto3" json:"max,omitempty"`
Min int64 `protobuf:"varint,6,opt,name=min,proto3" json:"min,omitempty"`
}
func (x *HealthPingMeasurementResult) Reset() {
*x = HealthPingMeasurementResult{}
mi := &file_app_observatory_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *HealthPingMeasurementResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HealthPingMeasurementResult) ProtoMessage() {}
func (x *HealthPingMeasurementResult) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HealthPingMeasurementResult.ProtoReflect.Descriptor instead.
func (*HealthPingMeasurementResult) Descriptor() ([]byte, []int) {
return file_app_observatory_config_proto_rawDescGZIP(), []int{1}
}
func (x *HealthPingMeasurementResult) GetAll() int64 {
if x != nil {
return x.All
}
return 0
}
func (x *HealthPingMeasurementResult) GetFail() int64 {
if x != nil {
return x.Fail
}
return 0
}
func (x *HealthPingMeasurementResult) GetDeviation() int64 {
if x != nil {
return x.Deviation
}
return 0
}
func (x *HealthPingMeasurementResult) GetAverage() int64 {
if x != nil {
return x.Average
}
return 0
}
func (x *HealthPingMeasurementResult) GetMax() int64 {
if x != nil {
return x.Max
}
return 0
}
func (x *HealthPingMeasurementResult) GetMin() int64 {
if x != nil {
return x.Min
}
return 0
}
type OutboundStatus struct { type OutboundStatus struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -173,15 +90,16 @@ type OutboundStatus struct {
LastSeenTime int64 `protobuf:"varint,5,opt,name=last_seen_time,json=lastSeenTime,proto3" json:"last_seen_time,omitempty"` 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 // @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"` LastTryTime int64 `protobuf:"varint,6,opt,name=last_try_time,json=lastTryTime,proto3" json:"last_try_time,omitempty"`
HealthPing *HealthPingMeasurementResult `protobuf:"bytes,7,opt,name=health_ping,json=healthPing,proto3" json:"health_ping,omitempty"`
} }
func (x *OutboundStatus) Reset() { func (x *OutboundStatus) Reset() {
*x = OutboundStatus{} *x = OutboundStatus{}
mi := &file_app_observatory_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *OutboundStatus) String() string { func (x *OutboundStatus) String() string {
@ -191,8 +109,8 @@ func (x *OutboundStatus) String() string {
func (*OutboundStatus) ProtoMessage() {} func (*OutboundStatus) ProtoMessage() {}
func (x *OutboundStatus) ProtoReflect() protoreflect.Message { func (x *OutboundStatus) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[2] mi := &file_app_observatory_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -204,7 +122,7 @@ func (x *OutboundStatus) ProtoReflect() protoreflect.Message {
// Deprecated: Use OutboundStatus.ProtoReflect.Descriptor instead. // Deprecated: Use OutboundStatus.ProtoReflect.Descriptor instead.
func (*OutboundStatus) Descriptor() ([]byte, []int) { func (*OutboundStatus) Descriptor() ([]byte, []int) {
return file_app_observatory_config_proto_rawDescGZIP(), []int{2} return file_app_observatory_config_proto_rawDescGZIP(), []int{1}
} }
func (x *OutboundStatus) GetAlive() bool { func (x *OutboundStatus) GetAlive() bool {
@ -249,13 +167,6 @@ func (x *OutboundStatus) GetLastTryTime() int64 {
return 0 return 0
} }
func (x *OutboundStatus) GetHealthPing() *HealthPingMeasurementResult {
if x != nil {
return x.HealthPing
}
return nil
}
type ProbeResult struct { type ProbeResult struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -275,9 +186,11 @@ type ProbeResult struct {
func (x *ProbeResult) Reset() { func (x *ProbeResult) Reset() {
*x = ProbeResult{} *x = ProbeResult{}
mi := &file_app_observatory_config_proto_msgTypes[3] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *ProbeResult) String() string { func (x *ProbeResult) String() string {
@ -287,8 +200,8 @@ func (x *ProbeResult) String() string {
func (*ProbeResult) ProtoMessage() {} func (*ProbeResult) ProtoMessage() {}
func (x *ProbeResult) ProtoReflect() protoreflect.Message { func (x *ProbeResult) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[3] mi := &file_app_observatory_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -300,7 +213,7 @@ func (x *ProbeResult) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProbeResult.ProtoReflect.Descriptor instead. // Deprecated: Use ProbeResult.ProtoReflect.Descriptor instead.
func (*ProbeResult) Descriptor() ([]byte, []int) { func (*ProbeResult) Descriptor() ([]byte, []int) {
return file_app_observatory_config_proto_rawDescGZIP(), []int{3} return file_app_observatory_config_proto_rawDescGZIP(), []int{2}
} }
func (x *ProbeResult) GetAlive() bool { func (x *ProbeResult) GetAlive() bool {
@ -336,9 +249,11 @@ type Intensity struct {
func (x *Intensity) Reset() { func (x *Intensity) Reset() {
*x = Intensity{} *x = Intensity{}
mi := &file_app_observatory_config_proto_msgTypes[4] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_config_proto_msgTypes[3]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Intensity) String() string { func (x *Intensity) String() string {
@ -348,8 +263,8 @@ func (x *Intensity) String() string {
func (*Intensity) ProtoMessage() {} func (*Intensity) ProtoMessage() {}
func (x *Intensity) ProtoReflect() protoreflect.Message { func (x *Intensity) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[4] mi := &file_app_observatory_config_proto_msgTypes[3]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -361,7 +276,7 @@ func (x *Intensity) ProtoReflect() protoreflect.Message {
// Deprecated: Use Intensity.ProtoReflect.Descriptor instead. // Deprecated: Use Intensity.ProtoReflect.Descriptor instead.
func (*Intensity) Descriptor() ([]byte, []int) { func (*Intensity) Descriptor() ([]byte, []int) {
return file_app_observatory_config_proto_rawDescGZIP(), []int{4} return file_app_observatory_config_proto_rawDescGZIP(), []int{3}
} }
func (x *Intensity) GetProbeInterval() uint32 { func (x *Intensity) GetProbeInterval() uint32 {
@ -385,9 +300,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_observatory_config_proto_msgTypes[5] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_observatory_config_proto_msgTypes[4]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -397,8 +314,8 @@ func (x *Config) String() string {
func (*Config) ProtoMessage() {} func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_observatory_config_proto_msgTypes[5] mi := &file_app_observatory_config_proto_msgTypes[4]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -410,7 +327,7 @@ func (x *Config) ProtoReflect() protoreflect.Message {
// Deprecated: Use Config.ProtoReflect.Descriptor instead. // Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) { func (*Config) Descriptor() ([]byte, []int) {
return file_app_observatory_config_proto_rawDescGZIP(), []int{5} return file_app_observatory_config_proto_rawDescGZIP(), []int{4}
} }
func (x *Config) GetSubjectSelector() []string { func (x *Config) GetSubjectSelector() []string {
@ -453,62 +370,47 @@ var file_app_observatory_config_proto_rawDesc = []byte{
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 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, 0x75, 0x74, 0x62, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x4f, 0x75, 0x74, 0x62, 0x6f,
0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
0x73, 0x22, 0x9f, 0x01, 0x0a, 0x1b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74,
0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20,
0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65,
0x61, 0x6c, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79,
0x03, 0x52, 0x04, 0x66, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x61, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x65, 0x76, 0x69, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x61, 0x73,
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c,
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x61, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x12, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01,
0x10, 0x0a, 0x03, 0x6d, 0x61, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6d, 0x61, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12,
0x78, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x24, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x74, 0x69, 0x6d,
0x6d, 0x69, 0x6e, 0x22, 0xae, 0x02, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x65, 0x65,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x74, 0x72,
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6c, 0x61,
0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x73, 0x74, 0x54, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x65, 0x0a, 0x0b, 0x50, 0x72, 0x6f,
0x61, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x62, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x76,
0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14,
0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64,
0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x04, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x67, 0x12, 0x24, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x65, 0x65, 0x6e, 0x5f, 0x74, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e,
0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x22, 0x32, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x12, 0x25, 0x0a,
0x65, 0x65, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18,
0x74, 0x72, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65,
0x6c, 0x61, 0x73, 0x74, 0x54, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x68, 0x72, 0x76, 0x61, 0x6c, 0x22, 0xa6, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63,
0x32, 0x36, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65,
0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x48, 0x65, 0x61, 0x63, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72,
0x6c, 0x74, 0x68, 0x50, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x6d, 0x65, 0x6f, 0x62, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0a, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x72, 0x6f, 0x62, 0x65, 0x55, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x65,
0x50, 0x69, 0x6e, 0x67, 0x22, 0x65, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x52, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
0x75, 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2d,
0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x0a, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72,
0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x6e, 0x61, 0x62,
0x2a, 0x0a, 0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x42, 0x5e, 0x0a,
0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62,
0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x32, 0x0a, 0x09, 0x49, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74,
0x6e, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61,
0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x6f, 0x62, 0x73, 0x65, 0x72,
0x52, 0x0d, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x22, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0xaa, 0x02, 0x14, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70,
0xa6, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x75, 0x70, 0x2e, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x6c,
0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x75,
0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x55,
0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x62,
0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x61,
0x62, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18,
0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6e,
0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x42, 0x5e, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61,
0x74, 0x6f, 0x72, 0x79, 0x50, 0x01, 0x5a, 0x29, 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, 0xaa, 0x02, 0x14, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x4f, 0x62, 0x73,
0x65, 0x72, 0x76, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -523,23 +425,21 @@ func file_app_observatory_config_proto_rawDescGZIP() []byte {
return file_app_observatory_config_proto_rawDescData return file_app_observatory_config_proto_rawDescData
} }
var file_app_observatory_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_app_observatory_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_app_observatory_config_proto_goTypes = []any{ var file_app_observatory_config_proto_goTypes = []interface{}{
(*ObservationResult)(nil), // 0: xray.core.app.observatory.ObservationResult (*ObservationResult)(nil), // 0: xray.core.app.observatory.ObservationResult
(*HealthPingMeasurementResult)(nil), // 1: xray.core.app.observatory.HealthPingMeasurementResult (*OutboundStatus)(nil), // 1: xray.core.app.observatory.OutboundStatus
(*OutboundStatus)(nil), // 2: xray.core.app.observatory.OutboundStatus (*ProbeResult)(nil), // 2: xray.core.app.observatory.ProbeResult
(*ProbeResult)(nil), // 3: xray.core.app.observatory.ProbeResult (*Intensity)(nil), // 3: xray.core.app.observatory.Intensity
(*Intensity)(nil), // 4: xray.core.app.observatory.Intensity (*Config)(nil), // 4: xray.core.app.observatory.Config
(*Config)(nil), // 5: xray.core.app.observatory.Config
} }
var file_app_observatory_config_proto_depIdxs = []int32{ var file_app_observatory_config_proto_depIdxs = []int32{
2, // 0: xray.core.app.observatory.ObservationResult.status:type_name -> xray.core.app.observatory.OutboundStatus 1, // 0: xray.core.app.observatory.ObservationResult.status:type_name -> xray.core.app.observatory.OutboundStatus
1, // 1: xray.core.app.observatory.OutboundStatus.health_ping:type_name -> xray.core.app.observatory.HealthPingMeasurementResult 1, // [1:1] is the sub-list for method output_type
2, // [2:2] is the sub-list for method output_type 1, // [1:1] is the sub-list for method input_type
2, // [2:2] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension type_name 1, // [1:1] is the sub-list for extension extendee
2, // [2:2] is the sub-list for extension extendee 0, // [0:1] is the sub-list for field type_name
0, // [0:2] is the sub-list for field type_name
} }
func init() { file_app_observatory_config_proto_init() } func init() { file_app_observatory_config_proto_init() }
@ -547,13 +447,75 @@ func file_app_observatory_config_proto_init() {
if File_app_observatory_config_proto != nil { if File_app_observatory_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_observatory_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ObservationResult); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OutboundStatus); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProbeResult); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Intensity); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_observatory_config_proto_msgTypes[4].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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_observatory_config_proto_rawDesc, RawDescriptor: file_app_observatory_config_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 6, NumMessages: 5,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@ -10,15 +10,6 @@ message ObservationResult {
repeated OutboundStatus status = 1; repeated OutboundStatus status = 1;
} }
message HealthPingMeasurementResult {
int64 all = 1;
int64 fail = 2;
int64 deviation = 3;
int64 average = 4;
int64 max = 5;
int64 min = 6;
}
message OutboundStatus{ message OutboundStatus{
/* @Document Whether this outbound is usable /* @Document Whether this outbound is usable
@Restriction ReadOnlyForUser @Restriction ReadOnlyForUser
@ -45,8 +36,6 @@ message OutboundStatus{
@Type id.outboundTag @Type id.outboundTag
*/ */
int64 last_try_time = 6; int64 last_try_time = 6;
HealthPingMeasurementResult health_ping = 7;
} }
message ProbeResult{ message ProbeResult{

View File

@ -0,0 +1,9 @@
package observatory
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

@ -8,10 +8,10 @@ type errorCollector struct {
func (e *errorCollector) SubmitError(err error) { func (e *errorCollector) SubmitError(err error) {
if e.errors == nil { if e.errors == nil {
e.errors = errors.New("underlying connection error").Base(err) e.errors = newError("underlying connection error").Base(err)
return return
} }
e.errors = e.errors.Base(errors.New("underlying connection error").Base(err)) e.errors = e.errors.Base(newError("underlying connection error").Base(err))
} }
func newErrorCollector() *errorCollector { func newErrorCollector() *errorCollector {
@ -20,7 +20,7 @@ func newErrorCollector() *errorCollector {
func (e *errorCollector) UnderlyingError() error { func (e *errorCollector) UnderlyingError() error {
if e.errors == nil { if e.errors == nil {
return errors.New("failed to produce report") return newError("failed to produce report")
} }
return e.errors return e.errors
} }

View File

@ -1 +1,3 @@
package observatory package observatory
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@ -10,7 +10,6 @@ import (
"time" "time"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
v2net "github.com/xtls/xray-core/common/net" v2net "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/common/signal/done" "github.com/xtls/xray-core/common/signal/done"
@ -61,7 +60,7 @@ func (o *Observer) background() {
for !o.finished.Done() { for !o.finished.Done() {
hs, ok := o.ohm.(outbound.HandlerSelector) hs, ok := o.ohm.(outbound.HandlerSelector)
if !ok { if !ok {
errors.LogInfo(o.ctx, "outbound.Manager is not a HandlerSelector") newError("outbound.Manager is not a HandlerSelector").WriteToLog()
return return
} }
@ -128,18 +127,18 @@ func (o *Observer) probe(outbound string) ProbeResult {
// MUST use Xray's built in context system // MUST use Xray's built in context system
dest, err := v2net.ParseDestination(network + ":" + addr) dest, err := v2net.ParseDestination(network + ":" + addr)
if err != nil { if err != nil {
return errors.New("cannot understand address").Base(err) return newError("cannot understand address").Base(err)
} }
trackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest) trackedCtx := session.TrackedConnectionError(o.ctx, errorCollectorForRequest)
conn, err := tagged.Dialer(trackedCtx, dest, outbound) conn, err := tagged.Dialer(trackedCtx, dest, outbound)
if err != nil { if err != nil {
return errors.New("cannot dial remote address ", dest).Base(err) return newError("cannot dial remote address ", dest).Base(err)
} }
connection = conn connection = conn
return nil return nil
}) })
if taskErr != nil { if taskErr != nil {
return nil, errors.New("cannot finish connection").Base(taskErr) return nil, newError("cannot finish connection").Base(taskErr)
} }
return connection, nil return connection, nil
}, },
@ -162,7 +161,7 @@ func (o *Observer) probe(outbound string) ProbeResult {
} }
response, err := httpClient.Get(probeURL) response, err := httpClient.Get(probeURL)
if err != nil { if err != nil {
return errors.New("outbound failed to relay connection").Base(err) return newError("outbound failed to relay connection").Base(err)
} }
if response.Body != nil { if response.Body != nil {
response.Body.Close() response.Body.Close()
@ -172,11 +171,15 @@ func (o *Observer) probe(outbound string) ProbeResult {
return nil return nil
}) })
if err != nil { if err != nil {
var errorMessage = "the outbound " + outbound + " is dead: GET request failed:" + err.Error() + "with outbound handler report underlying connection failed" fullerr := newError("underlying connection failed").Base(errorCollectorForRequest.UnderlyingError())
errors.LogInfoInner(o.ctx, errorCollectorForRequest.UnderlyingError(), errorMessage) fullerr = newError("with outbound handler report").Base(fullerr)
return ProbeResult{Alive: false, LastErrorReason: errorMessage} fullerr = newError("GET request failed:", err).Base(fullerr)
fullerr = newError("the outbound ", outbound, " is dead:").Base(fullerr)
fullerr = fullerr.AtInfo()
fullerr.WriteToLog()
return ProbeResult{Alive: false, LastErrorReason: fullerr.Error()}
} }
errors.LogInfo(o.ctx, "the outbound ", outbound, " is alive:", GETTime.Seconds()) newError("the outbound ", outbound, " is alive:", GETTime.Seconds()).AtInfo().WriteToLog()
return ProbeResult{Alive: true, Delay: GETTime.Milliseconds()} return ProbeResult{Alive: true, Delay: GETTime.Milliseconds()}
} }
@ -219,7 +222,7 @@ func New(ctx context.Context, config *Config) (*Observer, error) {
outboundManager = om outboundManager = om
}) })
if err != nil { if err != nil {
return nil, errors.New("Cannot get depended features").Base(err) return nil, newError("Cannot get depended features").Base(err)
} }
return &Observer{ return &Observer{
config: config, config: config,

View File

@ -73,7 +73,6 @@ func (p *Policy) ToCorePolicy() policy.Session {
if p.Stats != nil { if p.Stats != nil {
cp.Stats.UserUplink = p.Stats.UserUplink cp.Stats.UserUplink = p.Stats.UserUplink
cp.Stats.UserDownlink = p.Stats.UserDownlink cp.Stats.UserDownlink = p.Stats.UserDownlink
cp.Stats.UserOnline = p.Stats.UserOnline
} }
if p.Buffer != nil { if p.Buffer != nil {
cp.Buffer.PerConnection = p.Buffer.Connection cp.Buffer.PerConnection = p.Buffer.Connection

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/policy/config.proto // source: app/policy/config.proto
package policy package policy
@ -30,9 +30,11 @@ type Second struct {
func (x *Second) Reset() { func (x *Second) Reset() {
*x = Second{} *x = Second{}
mi := &file_app_policy_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Second) String() string { func (x *Second) String() string {
@ -43,7 +45,7 @@ func (*Second) ProtoMessage() {}
func (x *Second) ProtoReflect() protoreflect.Message { func (x *Second) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[0] mi := &file_app_policy_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -77,9 +79,11 @@ type Policy struct {
func (x *Policy) Reset() { func (x *Policy) Reset() {
*x = Policy{} *x = Policy{}
mi := &file_app_policy_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Policy) String() string { func (x *Policy) String() string {
@ -90,7 +94,7 @@ func (*Policy) ProtoMessage() {}
func (x *Policy) ProtoReflect() protoreflect.Message { func (x *Policy) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[1] mi := &file_app_policy_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -136,9 +140,11 @@ type SystemPolicy struct {
func (x *SystemPolicy) Reset() { func (x *SystemPolicy) Reset() {
*x = SystemPolicy{} *x = SystemPolicy{}
mi := &file_app_policy_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *SystemPolicy) String() string { func (x *SystemPolicy) String() string {
@ -149,7 +155,7 @@ func (*SystemPolicy) ProtoMessage() {}
func (x *SystemPolicy) ProtoReflect() protoreflect.Message { func (x *SystemPolicy) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[2] mi := &file_app_policy_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -182,9 +188,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_policy_config_proto_msgTypes[3] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[3]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -195,7 +203,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[3] mi := &file_app_policy_config_proto_msgTypes[3]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -238,9 +246,11 @@ type Policy_Timeout struct {
func (x *Policy_Timeout) Reset() { func (x *Policy_Timeout) Reset() {
*x = Policy_Timeout{} *x = Policy_Timeout{}
mi := &file_app_policy_config_proto_msgTypes[4] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[4]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Policy_Timeout) String() string { func (x *Policy_Timeout) String() string {
@ -251,7 +261,7 @@ func (*Policy_Timeout) ProtoMessage() {}
func (x *Policy_Timeout) ProtoReflect() protoreflect.Message { func (x *Policy_Timeout) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[4] mi := &file_app_policy_config_proto_msgTypes[4]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -301,14 +311,15 @@ type Policy_Stats struct {
UserUplink bool `protobuf:"varint,1,opt,name=user_uplink,json=userUplink,proto3" json:"user_uplink,omitempty"` UserUplink bool `protobuf:"varint,1,opt,name=user_uplink,json=userUplink,proto3" json:"user_uplink,omitempty"`
UserDownlink bool `protobuf:"varint,2,opt,name=user_downlink,json=userDownlink,proto3" json:"user_downlink,omitempty"` UserDownlink bool `protobuf:"varint,2,opt,name=user_downlink,json=userDownlink,proto3" json:"user_downlink,omitempty"`
UserOnline bool `protobuf:"varint,3,opt,name=user_online,json=userOnline,proto3" json:"user_online,omitempty"`
} }
func (x *Policy_Stats) Reset() { func (x *Policy_Stats) Reset() {
*x = Policy_Stats{} *x = Policy_Stats{}
mi := &file_app_policy_config_proto_msgTypes[5] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[5]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Policy_Stats) String() string { func (x *Policy_Stats) String() string {
@ -319,7 +330,7 @@ func (*Policy_Stats) ProtoMessage() {}
func (x *Policy_Stats) ProtoReflect() protoreflect.Message { func (x *Policy_Stats) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[5] mi := &file_app_policy_config_proto_msgTypes[5]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -348,13 +359,6 @@ func (x *Policy_Stats) GetUserDownlink() bool {
return false return false
} }
func (x *Policy_Stats) GetUserOnline() bool {
if x != nil {
return x.UserOnline
}
return false
}
type Policy_Buffer struct { type Policy_Buffer struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -366,9 +370,11 @@ type Policy_Buffer struct {
func (x *Policy_Buffer) Reset() { func (x *Policy_Buffer) Reset() {
*x = Policy_Buffer{} *x = Policy_Buffer{}
mi := &file_app_policy_config_proto_msgTypes[6] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[6]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Policy_Buffer) String() string { func (x *Policy_Buffer) String() string {
@ -379,7 +385,7 @@ func (*Policy_Buffer) ProtoMessage() {}
func (x *Policy_Buffer) ProtoReflect() protoreflect.Message { func (x *Policy_Buffer) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[6] mi := &file_app_policy_config_proto_msgTypes[6]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -414,9 +420,11 @@ type SystemPolicy_Stats struct {
func (x *SystemPolicy_Stats) Reset() { func (x *SystemPolicy_Stats) Reset() {
*x = SystemPolicy_Stats{} *x = SystemPolicy_Stats{}
mi := &file_app_policy_config_proto_msgTypes[7] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_policy_config_proto_msgTypes[7]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *SystemPolicy_Stats) String() string { func (x *SystemPolicy_Stats) String() string {
@ -427,7 +435,7 @@ func (*SystemPolicy_Stats) ProtoMessage() {}
func (x *SystemPolicy_Stats) ProtoReflect() protoreflect.Message { func (x *SystemPolicy_Stats) ProtoReflect() protoreflect.Message {
mi := &file_app_policy_config_proto_msgTypes[7] mi := &file_app_policy_config_proto_msgTypes[7]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -477,7 +485,7 @@ var file_app_policy_config_proto_rawDesc = []byte{
0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x78, 0x72, 0x61, 0x79, 0x2e,
0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x1e, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x1e, 0x0a, 0x06, 0x53, 0x65,
0x63, 0x6f, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc7, 0x04, 0x0a, 0x06, 0x50, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa6, 0x04, 0x0a, 0x06, 0x50,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
@ -504,51 +512,49 @@ var file_app_policy_config_proto_rawDesc = []byte{
0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x0c, 0x64, 0x6f, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x52, 0x0c, 0x64, 0x6f,
0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x1a, 0x6e, 0x0a, 0x05, 0x53, 0x74, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4f, 0x6e, 0x6c, 0x79, 0x1a, 0x4d, 0x0a, 0x05, 0x53, 0x74,
0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x61, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x75, 0x70, 0x6c, 0x69,
0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x55, 0x70, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x55, 0x70,
0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x6f, 0x77, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x6f, 0x77,
0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x73, 0x65,
0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x1a, 0x28, 0x0a, 0x06, 0x42, 0x75, 0x66,
0x72, 0x5f, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x66, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x75, 0x73, 0x65, 0x72, 0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x1a, 0x28, 0x0a, 0x06, 0x42, 0x75, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x66, 0x66, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x01, 0x0a, 0x0c, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70,
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, 0x69,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x63, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x1a,
0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6f, 0x6c, 0xaf, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x62,
0x69, 0x63, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28,
0x1a, 0xaf, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x62, 0x6f,
0x6b, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x6f,
0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x62, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03,
0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x27, 0x0a, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x70,
0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x55, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x6b, 0x22, 0xcc, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x05,
0x52, 0x10, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x72,
0x6e, 0x6b, 0x22, 0xcc, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x6f,
0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x78, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x43, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70,
0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50,
0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x1a, 0x51, 0x0a,
0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x0a, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x1a, 0x51, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a,
0x0a, 0x0a, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x78,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75,
0x01, 0x42, 0x4f, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d,
0x70, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x01, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xaa,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63,
0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0xaa, 0x02, 0x0f, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -564,7 +570,7 @@ func file_app_policy_config_proto_rawDescGZIP() []byte {
} }
var file_app_policy_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_app_policy_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_app_policy_config_proto_goTypes = []any{ var file_app_policy_config_proto_goTypes = []interface{}{
(*Second)(nil), // 0: xray.app.policy.Second (*Second)(nil), // 0: xray.app.policy.Second
(*Policy)(nil), // 1: xray.app.policy.Policy (*Policy)(nil), // 1: xray.app.policy.Policy
(*SystemPolicy)(nil), // 2: xray.app.policy.SystemPolicy (*SystemPolicy)(nil), // 2: xray.app.policy.SystemPolicy
@ -599,6 +605,104 @@ func file_app_policy_config_proto_init() {
if File_app_policy_config_proto != nil { if File_app_policy_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_policy_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Second); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Policy); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SystemPolicy); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[3].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
}
}
file_app_policy_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Policy_Timeout); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Policy_Stats); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Policy_Buffer); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_policy_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SystemPolicy_Stats); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

@ -22,7 +22,6 @@ message Policy {
message Stats { message Stats {
bool user_uplink = 1; bool user_uplink = 1;
bool user_downlink = 2; bool user_downlink = 2;
bool user_online = 3;
} }
message Buffer { message Buffer {

View File

@ -0,0 +1,9 @@
package policy
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,2 +1,4 @@
// Package policy is an implementation of policy.Manager feature. // Package policy is an implementation of policy.Manager feature.
package policy package policy
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@ -4,8 +4,6 @@ import (
"context" "context"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/protocol"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/inbound" "github.com/xtls/xray-core/features/inbound"
"github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/outbound"
@ -28,7 +26,7 @@ type OutboundOperation interface {
func getInbound(handler inbound.Handler) (proxy.Inbound, error) { func getInbound(handler inbound.Handler) (proxy.Inbound, error) {
gi, ok := handler.(proxy.GetInbound) gi, ok := handler.(proxy.GetInbound)
if !ok { if !ok {
return nil, errors.New("can't get inbound proxy from handler.") return nil, newError("can't get inbound proxy from handler.")
} }
return gi.GetInbound(), nil return gi.GetInbound(), nil
} }
@ -41,11 +39,11 @@ func (op *AddUserOperation) ApplyInbound(ctx context.Context, handler inbound.Ha
} }
um, ok := p.(proxy.UserManager) um, ok := p.(proxy.UserManager)
if !ok { if !ok {
return errors.New("proxy is not a UserManager") return newError("proxy is not a UserManager")
} }
mUser, err := op.User.ToMemoryUser() mUser, err := op.User.ToMemoryUser()
if err != nil { if err != nil {
return errors.New("failed to parse user").Base(err) return newError("failed to parse user").Base(err)
} }
return um.AddUser(ctx, mUser) return um.AddUser(ctx, mUser)
} }
@ -58,7 +56,7 @@ func (op *RemoveUserOperation) ApplyInbound(ctx context.Context, handler inbound
} }
um, ok := p.(proxy.UserManager) um, ok := p.(proxy.UserManager)
if !ok { if !ok {
return errors.New("proxy is not a UserManager") return newError("proxy is not a UserManager")
} }
return um.RemoveUser(ctx, op.Email) return um.RemoveUser(ctx, op.Email)
} }
@ -84,61 +82,21 @@ func (s *handlerServer) RemoveInbound(ctx context.Context, request *RemoveInboun
func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) { func (s *handlerServer) AlterInbound(ctx context.Context, request *AlterInboundRequest) (*AlterInboundResponse, error) {
rawOperation, err := request.Operation.GetInstance() rawOperation, err := request.Operation.GetInstance()
if err != nil { if err != nil {
return nil, errors.New("unknown operation").Base(err) return nil, newError("unknown operation").Base(err)
} }
operation, ok := rawOperation.(InboundOperation) operation, ok := rawOperation.(InboundOperation)
if !ok { if !ok {
return nil, errors.New("not an inbound operation") return nil, newError("not an inbound operation")
} }
handler, err := s.ihm.GetHandler(ctx, request.Tag) handler, err := s.ihm.GetHandler(ctx, request.Tag)
if err != nil { if err != nil {
return nil, errors.New("failed to get handler: ", request.Tag).Base(err) return nil, newError("failed to get handler: ", request.Tag).Base(err)
} }
return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler) return &AlterInboundResponse{}, operation.ApplyInbound(ctx, handler)
} }
func (s *handlerServer) GetInboundUsers(ctx context.Context, request *GetInboundUserRequest) (*GetInboundUserResponse, error) {
handler, err := s.ihm.GetHandler(ctx, request.Tag)
if err != nil {
return nil, errors.New("failed to get handler: ", request.Tag).Base(err)
}
p, err := getInbound(handler)
if err != nil {
return nil, err
}
um, ok := p.(proxy.UserManager)
if !ok {
return nil, errors.New("proxy is not a UserManager")
}
if len(request.Email) > 0 {
return &GetInboundUserResponse{Users: []*protocol.User{protocol.ToProtoUser(um.GetUser(ctx, request.Email))}}, nil
}
var result = make([]*protocol.User, 0, 100)
users := um.GetUsers(ctx)
for _, u := range users {
result = append(result, protocol.ToProtoUser(u))
}
return &GetInboundUserResponse{Users: result}, nil
}
func (s *handlerServer) GetInboundUsersCount(ctx context.Context, request *GetInboundUserRequest) (*GetInboundUsersCountResponse, error) {
handler, err := s.ihm.GetHandler(ctx, request.Tag)
if err != nil {
return nil, errors.New("failed to get handler: ", request.Tag).Base(err)
}
p, err := getInbound(handler)
if err != nil {
return nil, err
}
um, ok := p.(proxy.UserManager)
if !ok {
return nil, errors.New("proxy is not a UserManager")
}
return &GetInboundUsersCountResponse{Count: um.GetUsersCount(ctx)}, nil
}
func (s *handlerServer) AddOutbound(ctx context.Context, request *AddOutboundRequest) (*AddOutboundResponse, error) { func (s *handlerServer) AddOutbound(ctx context.Context, request *AddOutboundRequest) (*AddOutboundResponse, error) {
if err := core.AddOutboundHandler(s.s, request.Outbound); err != nil { if err := core.AddOutboundHandler(s.s, request.Outbound); err != nil {
return nil, err return nil, err
@ -153,11 +111,11 @@ func (s *handlerServer) RemoveOutbound(ctx context.Context, request *RemoveOutbo
func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) { func (s *handlerServer) AlterOutbound(ctx context.Context, request *AlterOutboundRequest) (*AlterOutboundResponse, error) {
rawOperation, err := request.Operation.GetInstance() rawOperation, err := request.Operation.GetInstance()
if err != nil { if err != nil {
return nil, errors.New("unknown operation").Base(err) return nil, newError("unknown operation").Base(err)
} }
operation, ok := rawOperation.(OutboundOperation) operation, ok := rawOperation.(OutboundOperation)
if !ok { if !ok {
return nil, errors.New("not an outbound operation") return nil, newError("not an outbound operation")
} }
handler := s.ohm.GetHandler(request.Tag) handler := s.ohm.GetHandler(request.Tag)

File diff suppressed because it is too large Load Diff

View File

@ -37,19 +37,6 @@ message AlterInboundRequest {
message AlterInboundResponse {} message AlterInboundResponse {}
message GetInboundUserRequest {
string tag = 1;
string email = 2;
}
message GetInboundUserResponse {
repeated xray.common.protocol.User users = 1;
}
message GetInboundUsersCountResponse {
int64 count = 1;
}
message AddOutboundRequest { message AddOutboundRequest {
core.OutboundHandlerConfig outbound = 1; core.OutboundHandlerConfig outbound = 1;
} }
@ -76,10 +63,6 @@ service HandlerService {
rpc AlterInbound(AlterInboundRequest) returns (AlterInboundResponse) {} rpc AlterInbound(AlterInboundRequest) returns (AlterInboundResponse) {}
rpc GetInboundUsers(GetInboundUserRequest) returns (GetInboundUserResponse) {}
rpc GetInboundUsersCount(GetInboundUserRequest) returns (GetInboundUsersCountResponse) {}
rpc AddOutbound(AddOutboundRequest) returns (AddOutboundResponse) {} rpc AddOutbound(AddOutboundRequest) returns (AddOutboundResponse) {}
rpc RemoveOutbound(RemoveOutboundRequest) returns (RemoveOutboundResponse) {} rpc RemoveOutbound(RemoveOutboundRequest) returns (RemoveOutboundResponse) {}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.3.0
// - protoc v5.28.2 // - protoc v4.23.1
// source: app/proxyman/command/command.proto // source: app/proxyman/command/command.proto
package command package command
@ -15,18 +15,16 @@ import (
// This is a compile-time assertion to ensure that this generated file // This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against. // is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later. // Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion9 const _ = grpc.SupportPackageIsVersion7
const ( const (
HandlerService_AddInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AddInbound" HandlerService_AddInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AddInbound"
HandlerService_RemoveInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/RemoveInbound" HandlerService_RemoveInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/RemoveInbound"
HandlerService_AlterInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AlterInbound" HandlerService_AlterInbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AlterInbound"
HandlerService_GetInboundUsers_FullMethodName = "/xray.app.proxyman.command.HandlerService/GetInboundUsers" HandlerService_AddOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AddOutbound"
HandlerService_GetInboundUsersCount_FullMethodName = "/xray.app.proxyman.command.HandlerService/GetInboundUsersCount" HandlerService_RemoveOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/RemoveOutbound"
HandlerService_AddOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AddOutbound" HandlerService_AlterOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AlterOutbound"
HandlerService_RemoveOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/RemoveOutbound"
HandlerService_AlterOutbound_FullMethodName = "/xray.app.proxyman.command.HandlerService/AlterOutbound"
) )
// HandlerServiceClient is the client API for HandlerService service. // HandlerServiceClient is the client API for HandlerService service.
@ -36,8 +34,6 @@ type HandlerServiceClient interface {
AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error) AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error)
RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error) RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error)
AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error) AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error)
GetInboundUsers(ctx context.Context, in *GetInboundUserRequest, opts ...grpc.CallOption) (*GetInboundUserResponse, error)
GetInboundUsersCount(ctx context.Context, in *GetInboundUserRequest, opts ...grpc.CallOption) (*GetInboundUsersCountResponse, error)
AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error) AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error)
RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error) RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error)
AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error) AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error)
@ -52,9 +48,8 @@ func NewHandlerServiceClient(cc grpc.ClientConnInterface) HandlerServiceClient {
} }
func (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error) { func (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundRequest, opts ...grpc.CallOption) (*AddInboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AddInboundResponse) out := new(AddInboundResponse)
err := c.cc.Invoke(ctx, HandlerService_AddInbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_AddInbound_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -62,9 +57,8 @@ func (c *handlerServiceClient) AddInbound(ctx context.Context, in *AddInboundReq
} }
func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error) { func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInboundRequest, opts ...grpc.CallOption) (*RemoveInboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RemoveInboundResponse) out := new(RemoveInboundResponse)
err := c.cc.Invoke(ctx, HandlerService_RemoveInbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_RemoveInbound_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -72,29 +66,8 @@ func (c *handlerServiceClient) RemoveInbound(ctx context.Context, in *RemoveInbo
} }
func (c *handlerServiceClient) AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error) { func (c *handlerServiceClient) AlterInbound(ctx context.Context, in *AlterInboundRequest, opts ...grpc.CallOption) (*AlterInboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AlterInboundResponse) out := new(AlterInboundResponse)
err := c.cc.Invoke(ctx, HandlerService_AlterInbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_AlterInbound_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *handlerServiceClient) GetInboundUsers(ctx context.Context, in *GetInboundUserRequest, opts ...grpc.CallOption) (*GetInboundUserResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetInboundUserResponse)
err := c.cc.Invoke(ctx, HandlerService_GetInboundUsers_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *handlerServiceClient) GetInboundUsersCount(ctx context.Context, in *GetInboundUserRequest, opts ...grpc.CallOption) (*GetInboundUsersCountResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GetInboundUsersCountResponse)
err := c.cc.Invoke(ctx, HandlerService_GetInboundUsersCount_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -102,9 +75,8 @@ func (c *handlerServiceClient) GetInboundUsersCount(ctx context.Context, in *Get
} }
func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error) { func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundRequest, opts ...grpc.CallOption) (*AddOutboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AddOutboundResponse) out := new(AddOutboundResponse)
err := c.cc.Invoke(ctx, HandlerService_AddOutbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_AddOutbound_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -112,9 +84,8 @@ func (c *handlerServiceClient) AddOutbound(ctx context.Context, in *AddOutboundR
} }
func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error) { func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOutboundRequest, opts ...grpc.CallOption) (*RemoveOutboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(RemoveOutboundResponse) out := new(RemoveOutboundResponse)
err := c.cc.Invoke(ctx, HandlerService_RemoveOutbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_RemoveOutbound_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -122,9 +93,8 @@ func (c *handlerServiceClient) RemoveOutbound(ctx context.Context, in *RemoveOut
} }
func (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error) { func (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *AlterOutboundRequest, opts ...grpc.CallOption) (*AlterOutboundResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(AlterOutboundResponse) out := new(AlterOutboundResponse)
err := c.cc.Invoke(ctx, HandlerService_AlterOutbound_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, HandlerService_AlterOutbound_FullMethodName, in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -133,25 +103,20 @@ func (c *handlerServiceClient) AlterOutbound(ctx context.Context, in *AlterOutbo
// HandlerServiceServer is the server API for HandlerService service. // HandlerServiceServer is the server API for HandlerService service.
// All implementations must embed UnimplementedHandlerServiceServer // All implementations must embed UnimplementedHandlerServiceServer
// for forward compatibility. // for forward compatibility
type HandlerServiceServer interface { type HandlerServiceServer interface {
AddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error) AddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error)
RemoveInbound(context.Context, *RemoveInboundRequest) (*RemoveInboundResponse, error) RemoveInbound(context.Context, *RemoveInboundRequest) (*RemoveInboundResponse, error)
AlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error) AlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error)
GetInboundUsers(context.Context, *GetInboundUserRequest) (*GetInboundUserResponse, error)
GetInboundUsersCount(context.Context, *GetInboundUserRequest) (*GetInboundUsersCountResponse, error)
AddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error) AddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error)
RemoveOutbound(context.Context, *RemoveOutboundRequest) (*RemoveOutboundResponse, error) RemoveOutbound(context.Context, *RemoveOutboundRequest) (*RemoveOutboundResponse, error)
AlterOutbound(context.Context, *AlterOutboundRequest) (*AlterOutboundResponse, error) AlterOutbound(context.Context, *AlterOutboundRequest) (*AlterOutboundResponse, error)
mustEmbedUnimplementedHandlerServiceServer() mustEmbedUnimplementedHandlerServiceServer()
} }
// UnimplementedHandlerServiceServer must be embedded to have // UnimplementedHandlerServiceServer must be embedded to have forward compatible implementations.
// forward compatible implementations. type UnimplementedHandlerServiceServer struct {
// }
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedHandlerServiceServer struct{}
func (UnimplementedHandlerServiceServer) AddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error) { func (UnimplementedHandlerServiceServer) AddInbound(context.Context, *AddInboundRequest) (*AddInboundResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddInbound not implemented") return nil, status.Errorf(codes.Unimplemented, "method AddInbound not implemented")
@ -162,12 +127,6 @@ func (UnimplementedHandlerServiceServer) RemoveInbound(context.Context, *RemoveI
func (UnimplementedHandlerServiceServer) AlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error) { func (UnimplementedHandlerServiceServer) AlterInbound(context.Context, *AlterInboundRequest) (*AlterInboundResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AlterInbound not implemented") return nil, status.Errorf(codes.Unimplemented, "method AlterInbound not implemented")
} }
func (UnimplementedHandlerServiceServer) GetInboundUsers(context.Context, *GetInboundUserRequest) (*GetInboundUserResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetInboundUsers not implemented")
}
func (UnimplementedHandlerServiceServer) GetInboundUsersCount(context.Context, *GetInboundUserRequest) (*GetInboundUsersCountResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetInboundUsersCount not implemented")
}
func (UnimplementedHandlerServiceServer) AddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error) { func (UnimplementedHandlerServiceServer) AddOutbound(context.Context, *AddOutboundRequest) (*AddOutboundResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method AddOutbound not implemented") return nil, status.Errorf(codes.Unimplemented, "method AddOutbound not implemented")
} }
@ -178,7 +137,6 @@ func (UnimplementedHandlerServiceServer) AlterOutbound(context.Context, *AlterOu
return nil, status.Errorf(codes.Unimplemented, "method AlterOutbound not implemented") return nil, status.Errorf(codes.Unimplemented, "method AlterOutbound not implemented")
} }
func (UnimplementedHandlerServiceServer) mustEmbedUnimplementedHandlerServiceServer() {} func (UnimplementedHandlerServiceServer) mustEmbedUnimplementedHandlerServiceServer() {}
func (UnimplementedHandlerServiceServer) testEmbeddedByValue() {}
// UnsafeHandlerServiceServer may be embedded to opt out of forward compatibility for this service. // UnsafeHandlerServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to HandlerServiceServer will // Use of this interface is not recommended, as added methods to HandlerServiceServer will
@ -188,13 +146,6 @@ type UnsafeHandlerServiceServer interface {
} }
func RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) { func RegisterHandlerServiceServer(s grpc.ServiceRegistrar, srv HandlerServiceServer) {
// If the following call pancis, it indicates UnimplementedHandlerServiceServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&HandlerService_ServiceDesc, srv) s.RegisterService(&HandlerService_ServiceDesc, srv)
} }
@ -252,42 +203,6 @@ func _HandlerService_AlterInbound_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _HandlerService_GetInboundUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetInboundUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HandlerServiceServer).GetInboundUsers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: HandlerService_GetInboundUsers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HandlerServiceServer).GetInboundUsers(ctx, req.(*GetInboundUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _HandlerService_GetInboundUsersCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetInboundUserRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(HandlerServiceServer).GetInboundUsersCount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: HandlerService_GetInboundUsersCount_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(HandlerServiceServer).GetInboundUsersCount(ctx, req.(*GetInboundUserRequest))
}
return interceptor(ctx, in, info, handler)
}
func _HandlerService_AddOutbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _HandlerService_AddOutbound_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(AddOutboundRequest) in := new(AddOutboundRequest)
if err := dec(in); err != nil { if err := dec(in); err != nil {
@ -361,14 +276,6 @@ var HandlerService_ServiceDesc = grpc.ServiceDesc{
MethodName: "AlterInbound", MethodName: "AlterInbound",
Handler: _HandlerService_AlterInbound_Handler, Handler: _HandlerService_AlterInbound_Handler,
}, },
{
MethodName: "GetInboundUsers",
Handler: _HandlerService_GetInboundUsers_Handler,
},
{
MethodName: "GetInboundUsersCount",
Handler: _HandlerService_GetInboundUsersCount_Handler,
},
{ {
MethodName: "AddOutbound", MethodName: "AddOutbound",
Handler: _HandlerService_AddOutbound_Handler, Handler: _HandlerService_AddOutbound_Handler,

View File

@ -1 +1,3 @@
package command package command
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen

View File

@ -0,0 +1,9 @@
package command
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

@ -19,5 +19,21 @@ func (c *ReceiverConfig) GetEffectiveSniffingSettings() *SniffingConfig {
return c.SniffingSettings return c.SniffingSettings
} }
if len(c.DomainOverride) > 0 {
var p []string
for _, kd := range c.DomainOverride {
switch kd {
case KnownProtocols_HTTP:
p = append(p, "http")
case KnownProtocols_TLS:
p = append(p, "tls")
}
}
return &SniffingConfig{
Enabled: true,
DestinationOverride: p,
}
}
return nil return nil
} }

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/proxyman/config.proto // source: app/proxyman/config.proto
package proxyman package proxyman
@ -23,6 +23,52 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
type KnownProtocols int32
const (
KnownProtocols_HTTP KnownProtocols = 0
KnownProtocols_TLS KnownProtocols = 1
)
// Enum value maps for KnownProtocols.
var (
KnownProtocols_name = map[int32]string{
0: "HTTP",
1: "TLS",
}
KnownProtocols_value = map[string]int32{
"HTTP": 0,
"TLS": 1,
}
)
func (x KnownProtocols) Enum() *KnownProtocols {
p := new(KnownProtocols)
*p = x
return p
}
func (x KnownProtocols) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (KnownProtocols) Descriptor() protoreflect.EnumDescriptor {
return file_app_proxyman_config_proto_enumTypes[0].Descriptor()
}
func (KnownProtocols) Type() protoreflect.EnumType {
return &file_app_proxyman_config_proto_enumTypes[0]
}
func (x KnownProtocols) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use KnownProtocols.Descriptor instead.
func (KnownProtocols) EnumDescriptor() ([]byte, []int) {
return file_app_proxyman_config_proto_rawDescGZIP(), []int{0}
}
type AllocationStrategy_Type int32 type AllocationStrategy_Type int32
const ( const (
@ -59,11 +105,11 @@ func (x AllocationStrategy_Type) String() string {
} }
func (AllocationStrategy_Type) Descriptor() protoreflect.EnumDescriptor { func (AllocationStrategy_Type) Descriptor() protoreflect.EnumDescriptor {
return file_app_proxyman_config_proto_enumTypes[0].Descriptor() return file_app_proxyman_config_proto_enumTypes[1].Descriptor()
} }
func (AllocationStrategy_Type) Type() protoreflect.EnumType { func (AllocationStrategy_Type) Type() protoreflect.EnumType {
return &file_app_proxyman_config_proto_enumTypes[0] return &file_app_proxyman_config_proto_enumTypes[1]
} }
func (x AllocationStrategy_Type) Number() protoreflect.EnumNumber { func (x AllocationStrategy_Type) Number() protoreflect.EnumNumber {
@ -83,9 +129,11 @@ type InboundConfig struct {
func (x *InboundConfig) Reset() { func (x *InboundConfig) Reset() {
*x = InboundConfig{} *x = InboundConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *InboundConfig) String() string { func (x *InboundConfig) String() string {
@ -96,7 +144,7 @@ func (*InboundConfig) ProtoMessage() {}
func (x *InboundConfig) ProtoReflect() protoreflect.Message { func (x *InboundConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[0] mi := &file_app_proxyman_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -127,9 +175,11 @@ type AllocationStrategy struct {
func (x *AllocationStrategy) Reset() { func (x *AllocationStrategy) Reset() {
*x = AllocationStrategy{} *x = AllocationStrategy{}
mi := &file_app_proxyman_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *AllocationStrategy) String() string { func (x *AllocationStrategy) String() string {
@ -140,7 +190,7 @@ func (*AllocationStrategy) ProtoMessage() {}
func (x *AllocationStrategy) ProtoReflect() protoreflect.Message { func (x *AllocationStrategy) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[1] mi := &file_app_proxyman_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -196,9 +246,11 @@ type SniffingConfig struct {
func (x *SniffingConfig) Reset() { func (x *SniffingConfig) Reset() {
*x = SniffingConfig{} *x = SniffingConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *SniffingConfig) String() string { func (x *SniffingConfig) String() string {
@ -209,7 +261,7 @@ func (*SniffingConfig) ProtoMessage() {}
func (x *SniffingConfig) ProtoReflect() protoreflect.Message { func (x *SniffingConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[2] mi := &file_app_proxyman_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -271,14 +323,21 @@ type ReceiverConfig struct {
AllocationStrategy *AllocationStrategy `protobuf:"bytes,3,opt,name=allocation_strategy,json=allocationStrategy,proto3" json:"allocation_strategy,omitempty"` AllocationStrategy *AllocationStrategy `protobuf:"bytes,3,opt,name=allocation_strategy,json=allocationStrategy,proto3" json:"allocation_strategy,omitempty"`
StreamSettings *internet.StreamConfig `protobuf:"bytes,4,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"` StreamSettings *internet.StreamConfig `protobuf:"bytes,4,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"`
ReceiveOriginalDestination bool `protobuf:"varint,5,opt,name=receive_original_destination,json=receiveOriginalDestination,proto3" json:"receive_original_destination,omitempty"` ReceiveOriginalDestination bool `protobuf:"varint,5,opt,name=receive_original_destination,json=receiveOriginalDestination,proto3" json:"receive_original_destination,omitempty"`
SniffingSettings *SniffingConfig `protobuf:"bytes,7,opt,name=sniffing_settings,json=sniffingSettings,proto3" json:"sniffing_settings,omitempty"` // Override domains for the given protocol.
// Deprecated. Use sniffing_settings.
//
// Deprecated: Marked as deprecated in app/proxyman/config.proto.
DomainOverride []KnownProtocols `protobuf:"varint,7,rep,packed,name=domain_override,json=domainOverride,proto3,enum=xray.app.proxyman.KnownProtocols" json:"domain_override,omitempty"`
SniffingSettings *SniffingConfig `protobuf:"bytes,8,opt,name=sniffing_settings,json=sniffingSettings,proto3" json:"sniffing_settings,omitempty"`
} }
func (x *ReceiverConfig) Reset() { func (x *ReceiverConfig) Reset() {
*x = ReceiverConfig{} *x = ReceiverConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[3] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[3]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *ReceiverConfig) String() string { func (x *ReceiverConfig) String() string {
@ -289,7 +348,7 @@ func (*ReceiverConfig) ProtoMessage() {}
func (x *ReceiverConfig) ProtoReflect() protoreflect.Message { func (x *ReceiverConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[3] mi := &file_app_proxyman_config_proto_msgTypes[3]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -339,6 +398,14 @@ func (x *ReceiverConfig) GetReceiveOriginalDestination() bool {
return false return false
} }
// Deprecated: Marked as deprecated in app/proxyman/config.proto.
func (x *ReceiverConfig) GetDomainOverride() []KnownProtocols {
if x != nil {
return x.DomainOverride
}
return nil
}
func (x *ReceiverConfig) GetSniffingSettings() *SniffingConfig { func (x *ReceiverConfig) GetSniffingSettings() *SniffingConfig {
if x != nil { if x != nil {
return x.SniffingSettings return x.SniffingSettings
@ -358,9 +425,11 @@ type InboundHandlerConfig struct {
func (x *InboundHandlerConfig) Reset() { func (x *InboundHandlerConfig) Reset() {
*x = InboundHandlerConfig{} *x = InboundHandlerConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[4] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[4]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *InboundHandlerConfig) String() string { func (x *InboundHandlerConfig) String() string {
@ -371,7 +440,7 @@ func (*InboundHandlerConfig) ProtoMessage() {}
func (x *InboundHandlerConfig) ProtoReflect() protoreflect.Message { func (x *InboundHandlerConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[4] mi := &file_app_proxyman_config_proto_msgTypes[4]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -415,9 +484,11 @@ type OutboundConfig struct {
func (x *OutboundConfig) Reset() { func (x *OutboundConfig) Reset() {
*x = OutboundConfig{} *x = OutboundConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[5] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[5]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *OutboundConfig) String() string { func (x *OutboundConfig) String() string {
@ -428,7 +499,7 @@ func (*OutboundConfig) ProtoMessage() {}
func (x *OutboundConfig) ProtoReflect() protoreflect.Message { func (x *OutboundConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[5] mi := &file_app_proxyman_config_proto_msgTypes[5]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -453,14 +524,15 @@ type SenderConfig struct {
StreamSettings *internet.StreamConfig `protobuf:"bytes,2,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"` 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"` 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"` MultiplexSettings *MultiplexingConfig `protobuf:"bytes,4,opt,name=multiplex_settings,json=multiplexSettings,proto3" json:"multiplex_settings,omitempty"`
ViaCidr string `protobuf:"bytes,5,opt,name=via_cidr,json=viaCidr,proto3" json:"via_cidr,omitempty"`
} }
func (x *SenderConfig) Reset() { func (x *SenderConfig) Reset() {
*x = SenderConfig{} *x = SenderConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[6] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[6]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *SenderConfig) String() string { func (x *SenderConfig) String() string {
@ -471,7 +543,7 @@ func (*SenderConfig) ProtoMessage() {}
func (x *SenderConfig) ProtoReflect() protoreflect.Message { func (x *SenderConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[6] mi := &file_app_proxyman_config_proto_msgTypes[6]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -514,13 +586,6 @@ func (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
return nil return nil
} }
func (x *SenderConfig) GetViaCidr() string {
if x != nil {
return x.ViaCidr
}
return ""
}
type MultiplexingConfig struct { type MultiplexingConfig struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -538,9 +603,11 @@ type MultiplexingConfig struct {
func (x *MultiplexingConfig) Reset() { func (x *MultiplexingConfig) Reset() {
*x = MultiplexingConfig{} *x = MultiplexingConfig{}
mi := &file_app_proxyman_config_proto_msgTypes[7] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[7]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *MultiplexingConfig) String() string { func (x *MultiplexingConfig) String() string {
@ -551,7 +618,7 @@ func (*MultiplexingConfig) ProtoMessage() {}
func (x *MultiplexingConfig) ProtoReflect() protoreflect.Message { func (x *MultiplexingConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[7] mi := &file_app_proxyman_config_proto_msgTypes[7]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -604,9 +671,11 @@ type AllocationStrategy_AllocationStrategyConcurrency struct {
func (x *AllocationStrategy_AllocationStrategyConcurrency) Reset() { func (x *AllocationStrategy_AllocationStrategyConcurrency) Reset() {
*x = AllocationStrategy_AllocationStrategyConcurrency{} *x = AllocationStrategy_AllocationStrategyConcurrency{}
mi := &file_app_proxyman_config_proto_msgTypes[8] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[8]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *AllocationStrategy_AllocationStrategyConcurrency) String() string { func (x *AllocationStrategy_AllocationStrategyConcurrency) String() string {
@ -617,7 +686,7 @@ func (*AllocationStrategy_AllocationStrategyConcurrency) ProtoMessage() {}
func (x *AllocationStrategy_AllocationStrategyConcurrency) ProtoReflect() protoreflect.Message { func (x *AllocationStrategy_AllocationStrategyConcurrency) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[8] mi := &file_app_proxyman_config_proto_msgTypes[8]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -649,9 +718,11 @@ type AllocationStrategy_AllocationStrategyRefresh struct {
func (x *AllocationStrategy_AllocationStrategyRefresh) Reset() { func (x *AllocationStrategy_AllocationStrategyRefresh) Reset() {
*x = AllocationStrategy_AllocationStrategyRefresh{} *x = AllocationStrategy_AllocationStrategyRefresh{}
mi := &file_app_proxyman_config_proto_msgTypes[9] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_proxyman_config_proto_msgTypes[9]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *AllocationStrategy_AllocationStrategyRefresh) String() string { func (x *AllocationStrategy_AllocationStrategyRefresh) String() string {
@ -662,7 +733,7 @@ func (*AllocationStrategy_AllocationStrategyRefresh) ProtoMessage() {}
func (x *AllocationStrategy_AllocationStrategyRefresh) ProtoReflect() protoreflect.Message { func (x *AllocationStrategy_AllocationStrategyRefresh) ProtoReflect() protoreflect.Message {
mi := &file_app_proxyman_config_proto_msgTypes[9] mi := &file_app_proxyman_config_proto_msgTypes[9]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -738,7 +809,7 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 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, 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, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x6f, 0x75, 0x74, 0x65,
0x4f, 0x6e, 0x6c, 0x79, 0x22, 0xbd, 0x03, 0x0a, 0x0e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 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, 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, 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, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x50, 0x6f, 0x72,
@ -761,8 +832,13 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 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, 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, 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, 0x0a, 0x11, 0x73, 0x6e, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69,
0x6e, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x78, 0x72, 0x61, 0x79, 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, 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, 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, 0x69, 0x66, 0x66, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4a, 0x04,
@ -779,7 +855,7 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65, 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, 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, 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, 0xcb, 0x02, 0x0a, 0x0c, 0x53, 0x65, 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, 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, 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, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f,
@ -798,25 +874,26 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 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, 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, 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, 0x19, 0x0a, 0x08, 0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a,
0x76, 0x69, 0x61, 0x5f, 0x63, 0x69, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
0x76, 0x69, 0x61, 0x43, 0x69, 0x64, 0x72, 0x22, 0xa4, 0x01, 0x0a, 0x12, 0x4d, 0x75, 0x6c, 0x74, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01,
0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a,
0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01,
0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12,
0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f,
0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64,
0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01,
0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x28, 0x09, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50,
0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x78, 0x34, 0x34, 0x33, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74,
0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x42, 0x55, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12,
0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e,
0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x6e, 0x50, 0x01, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61,
0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0xaa, 0x02, 0x11, 0x58, 0x72,
0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -831,46 +908,48 @@ func file_app_proxyman_config_proto_rawDescGZIP() []byte {
return file_app_proxyman_config_proto_rawDescData return file_app_proxyman_config_proto_rawDescData
} }
var file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_app_proxyman_config_proto_goTypes = []any{ var file_app_proxyman_config_proto_goTypes = []interface{}{
(AllocationStrategy_Type)(0), // 0: xray.app.proxyman.AllocationStrategy.Type (KnownProtocols)(0), // 0: xray.app.proxyman.KnownProtocols
(*InboundConfig)(nil), // 1: xray.app.proxyman.InboundConfig (AllocationStrategy_Type)(0), // 1: xray.app.proxyman.AllocationStrategy.Type
(*AllocationStrategy)(nil), // 2: xray.app.proxyman.AllocationStrategy (*InboundConfig)(nil), // 2: xray.app.proxyman.InboundConfig
(*SniffingConfig)(nil), // 3: xray.app.proxyman.SniffingConfig (*AllocationStrategy)(nil), // 3: xray.app.proxyman.AllocationStrategy
(*ReceiverConfig)(nil), // 4: xray.app.proxyman.ReceiverConfig (*SniffingConfig)(nil), // 4: xray.app.proxyman.SniffingConfig
(*InboundHandlerConfig)(nil), // 5: xray.app.proxyman.InboundHandlerConfig (*ReceiverConfig)(nil), // 5: xray.app.proxyman.ReceiverConfig
(*OutboundConfig)(nil), // 6: xray.app.proxyman.OutboundConfig (*InboundHandlerConfig)(nil), // 6: xray.app.proxyman.InboundHandlerConfig
(*SenderConfig)(nil), // 7: xray.app.proxyman.SenderConfig (*OutboundConfig)(nil), // 7: xray.app.proxyman.OutboundConfig
(*MultiplexingConfig)(nil), // 8: xray.app.proxyman.MultiplexingConfig (*SenderConfig)(nil), // 8: xray.app.proxyman.SenderConfig
(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 9: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency (*MultiplexingConfig)(nil), // 9: xray.app.proxyman.MultiplexingConfig
(*AllocationStrategy_AllocationStrategyRefresh)(nil), // 10: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh (*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 10: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
(*net.PortList)(nil), // 11: xray.common.net.PortList (*AllocationStrategy_AllocationStrategyRefresh)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
(*net.IPOrDomain)(nil), // 12: xray.common.net.IPOrDomain (*net.PortList)(nil), // 12: xray.common.net.PortList
(*internet.StreamConfig)(nil), // 13: xray.transport.internet.StreamConfig (*net.IPOrDomain)(nil), // 13: xray.common.net.IPOrDomain
(*serial.TypedMessage)(nil), // 14: xray.common.serial.TypedMessage (*internet.StreamConfig)(nil), // 14: xray.transport.internet.StreamConfig
(*internet.ProxyConfig)(nil), // 15: xray.transport.internet.ProxyConfig (*serial.TypedMessage)(nil), // 15: xray.common.serial.TypedMessage
(*internet.ProxyConfig)(nil), // 16: xray.transport.internet.ProxyConfig
} }
var file_app_proxyman_config_proto_depIdxs = []int32{ var file_app_proxyman_config_proto_depIdxs = []int32{
0, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type 1, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type
9, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency 10, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
10, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh 11, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
11, // 3: xray.app.proxyman.ReceiverConfig.port_list:type_name -> xray.common.net.PortList 12, // 3: xray.app.proxyman.ReceiverConfig.port_list:type_name -> xray.common.net.PortList
12, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain 13, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain
2, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy 3, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy
13, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig 14, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
3, // 7: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig 0, // 7: xray.app.proxyman.ReceiverConfig.domain_override:type_name -> xray.app.proxyman.KnownProtocols
14, // 8: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage 4, // 8: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig
14, // 9: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage 15, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage
12, // 10: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain 15, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage
13, // 11: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig 13, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain
15, // 12: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig 14, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
8, // 13: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig 16, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig
14, // [14:14] is the sub-list for method output_type 9, // 14: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig
14, // [14:14] is the sub-list for method input_type 15, // [15:15] is the sub-list for method output_type
14, // [14:14] is the sub-list for extension type_name 15, // [15:15] is the sub-list for method input_type
14, // [14:14] is the sub-list for extension extendee 15, // [15:15] is the sub-list for extension type_name
0, // [0:14] is the sub-list for field type_name 15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
} }
func init() { file_app_proxyman_config_proto_init() } func init() { file_app_proxyman_config_proto_init() }
@ -878,12 +957,134 @@ func file_app_proxyman_config_proto_init() {
if File_app_proxyman_config_proto != nil { if File_app_proxyman_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_proxyman_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InboundConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllocationStrategy); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SniffingConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ReceiverConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*InboundHandlerConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OutboundConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SenderConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MultiplexingConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllocationStrategy_AllocationStrategyConcurrency); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_proxyman_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AllocationStrategy_AllocationStrategyRefresh); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_app_proxyman_config_proto_rawDesc, RawDescriptor: file_app_proxyman_config_proto_rawDesc,
NumEnums: 1, NumEnums: 2,
NumMessages: 10, NumMessages: 10,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,

View File

@ -40,6 +40,11 @@ message AllocationStrategy {
AllocationStrategyRefresh refresh = 3; AllocationStrategyRefresh refresh = 3;
} }
enum KnownProtocols {
HTTP = 0;
TLS = 1;
}
message SniffingConfig { message SniffingConfig {
// Whether or not to enable content sniffing on an inbound connection. // Whether or not to enable content sniffing on an inbound connection.
bool enabled = 1; bool enabled = 1;
@ -66,7 +71,10 @@ message ReceiverConfig {
xray.transport.internet.StreamConfig stream_settings = 4; xray.transport.internet.StreamConfig stream_settings = 4;
bool receive_original_destination = 5; bool receive_original_destination = 5;
reserved 6; reserved 6;
SniffingConfig sniffing_settings = 7; // Override domains for the given protocol.
// Deprecated. Use sniffing_settings.
repeated KnownProtocols domain_override = 7 [ deprecated = true ];
SniffingConfig sniffing_settings = 8;
} }
message InboundHandlerConfig { message InboundHandlerConfig {
@ -83,7 +91,6 @@ message SenderConfig {
xray.transport.internet.StreamConfig stream_settings = 2; xray.transport.internet.StreamConfig stream_settings = 2;
xray.transport.internet.ProxyConfig proxy_settings = 3; xray.transport.internet.ProxyConfig proxy_settings = 3;
MultiplexingConfig multiplex_settings = 4; MultiplexingConfig multiplex_settings = 4;
string via_cidr = 5;
} }
message MultiplexingConfig { message MultiplexingConfig {

View File

@ -55,7 +55,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
} }
p, ok := rawProxy.(proxy.Inbound) p, ok := rawProxy.(proxy.Inbound)
if !ok { if !ok {
return nil, errors.New("not an inbound proxy.") return nil, newError("not an inbound proxy.")
} }
h := &AlwaysOnInboundHandler{ h := &AlwaysOnInboundHandler{
@ -75,7 +75,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings) mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
if err != nil { if err != nil {
return nil, errors.New("failed to parse stream config").Base(err).AtWarning() return nil, newError("failed to parse stream config").Base(err).AtWarning()
} }
if receiverConfig.ReceiveOriginalDestination { if receiverConfig.ReceiveOriginalDestination {
@ -89,7 +89,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
} }
if pl == nil { if pl == nil {
if net.HasNetwork(nl, net.Network_UNIX) { if net.HasNetwork(nl, net.Network_UNIX) {
errors.LogDebug(ctx, "creating unix domain socket worker on ", address) newError("creating unix domain socket worker on ", address).AtDebug().WriteToLog()
worker := &dsWorker{ worker := &dsWorker{
address: address, address: address,
@ -109,7 +109,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
for _, pr := range pl.Range { for _, pr := range pl.Range {
for port := pr.From; port <= pr.To; port++ { for port := pr.From; port <= pr.To; port++ {
if net.HasNetwork(nl, net.Network_TCP) { if net.HasNetwork(nl, net.Network_TCP) {
errors.LogDebug(ctx, "creating stream worker on ", address, ":", port) newError("creating stream worker on ", address, ":", port).AtDebug().WriteToLog()
worker := &tcpWorker{ worker := &tcpWorker{
address: address, address: address,
@ -167,7 +167,7 @@ func (h *AlwaysOnInboundHandler) Close() error {
} }
errs = append(errs, h.mux.Close()) errs = append(errs, h.mux.Close())
if err := errors.Combine(errs...); err != nil { if err := errors.Combine(errs...); err != nil {
return errors.New("failed to close all resources").Base(err) return newError("failed to close all resources").Base(err)
} }
return nil return nil
} }

View File

@ -7,7 +7,6 @@ import (
"github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common/dice" "github.com/xtls/xray-core/common/dice"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/mux" "github.com/xtls/xray-core/common/mux"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/task" "github.com/xtls/xray-core/common/task"
@ -47,7 +46,7 @@ func NewDynamicInboundHandler(ctx context.Context, tag string, receiverConfig *p
mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings) mss, err := internet.ToMemoryStreamConfig(receiverConfig.StreamSettings)
if err != nil { if err != nil {
return nil, errors.New("failed to parse stream settings").Base(err).AtWarning() return nil, newError("failed to parse stream settings").Base(err).AtWarning()
} }
if receiverConfig.ReceiveOriginalDestination { if receiverConfig.ReceiveOriginalDestination {
if mss.SocketSettings == nil { if mss.SocketSettings == nil {
@ -95,7 +94,7 @@ func (h *DynamicInboundHandler) closeWorkers(workers []worker) {
for idx, worker := range workers { for idx, worker := range workers {
ports2Del[idx] = worker.Port() ports2Del[idx] = worker.Port()
if err := worker.Close(); err != nil { if err := worker.Close(); err != nil {
errors.LogInfoInner(h.ctx, err, "failed to close worker") newError("failed to close worker").Base(err).WriteToLog()
} }
} }
@ -124,7 +123,7 @@ func (h *DynamicInboundHandler) refresh() error {
port := h.allocatePort() port := h.allocatePort()
rawProxy, err := core.CreateObject(h.v, h.proxyConfig) rawProxy, err := core.CreateObject(h.v, h.proxyConfig)
if err != nil { if err != nil {
errors.LogWarningInner(h.ctx, err, "failed to create proxy instance") newError("failed to create proxy instance").Base(err).AtWarning().WriteToLog()
continue continue
} }
p := rawProxy.(proxy.Inbound) p := rawProxy.(proxy.Inbound)
@ -144,7 +143,7 @@ func (h *DynamicInboundHandler) refresh() error {
ctx: h.ctx, ctx: h.ctx,
} }
if err := worker.Start(); err != nil { if err := worker.Start(); err != nil {
errors.LogWarningInner(h.ctx, err, "failed to create TCP worker") newError("failed to create TCP worker").Base(err).AtWarning().WriteToLog()
continue continue
} }
workers = append(workers, worker) workers = append(workers, worker)
@ -164,7 +163,7 @@ func (h *DynamicInboundHandler) refresh() error {
ctx: h.ctx, ctx: h.ctx,
} }
if err := worker.Start(); err != nil { if err := worker.Start(); err != nil {
errors.LogWarningInner(h.ctx, err, "failed to create UDP worker") newError("failed to create UDP worker").Base(err).AtWarning().WriteToLog()
continue continue
} }
workers = append(workers, worker) workers = append(workers, worker)

View File

@ -0,0 +1,9 @@
package inbound
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,19 +1,20 @@
package inbound package inbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"sync" "sync"
"github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
"github.com/xtls/xray-core/core" "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/inbound" "github.com/xtls/xray-core/features/inbound"
) )
// Manager manages all inbound handlers. // Manager is to manage all inbound handlers.
type Manager struct { type Manager struct {
access sync.RWMutex access sync.RWMutex
untaggedHandler []inbound.Handler untaggedHandler []inbound.Handler
@ -42,7 +43,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler inbound.Handler) error
tag := handler.Tag() tag := handler.Tag()
if len(tag) > 0 { if len(tag) > 0 {
if _, found := m.taggedHandlers[tag]; found { if _, found := m.taggedHandlers[tag]; found {
return errors.New("existing tag found: " + tag) return newError("existing tag found: " + tag)
} }
m.taggedHandlers[tag] = handler m.taggedHandlers[tag] = handler
} else { } else {
@ -63,7 +64,7 @@ func (m *Manager) GetHandler(ctx context.Context, tag string) (inbound.Handler,
handler, found := m.taggedHandlers[tag] handler, found := m.taggedHandlers[tag]
if !found { if !found {
return nil, errors.New("handler not found: ", tag) return nil, newError("handler not found: ", tag)
} }
return handler, nil return handler, nil
} }
@ -79,7 +80,7 @@ func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
if handler, found := m.taggedHandlers[tag]; found { if handler, found := m.taggedHandlers[tag]; found {
if err := handler.Close(); err != nil { if err := handler.Close(); err != nil {
errors.LogWarningInner(ctx, err, "failed to close handler ", tag) newError("failed to close handler ", tag).Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
} }
delete(m.taggedHandlers, tag) delete(m.taggedHandlers, tag)
return nil return nil
@ -116,20 +117,20 @@ func (m *Manager) Close() error {
m.running = false m.running = false
var errs []interface{} var errors []interface{}
for _, handler := range m.taggedHandlers { for _, handler := range m.taggedHandlers {
if err := handler.Close(); err != nil { if err := handler.Close(); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
for _, handler := range m.untaggedHandler { for _, handler := range m.untaggedHandler {
if err := handler.Close(); err != nil { if err := handler.Close(); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
if len(errs) > 0 { if len(errors) > 0 {
return errors.New("failed to close all handlers").Base(errors.New(serial.Concat(errs...))) return newError("failed to close all handlers").Base(newError(serial.Concat(errors...)))
} }
return nil return nil
@ -149,7 +150,7 @@ func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig) receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
if !ok { if !ok {
return nil, errors.New("not a ReceiverConfig").AtError() return nil, newError("not a ReceiverConfig").AtError()
} }
streamSettings := receiverSettings.StreamSettings streamSettings := receiverSettings.StreamSettings
@ -167,7 +168,7 @@ func NewHandler(ctx context.Context, config *core.InboundHandlerConfig) (inbound
if allocStrategy.Type == proxyman.AllocationStrategy_Random { if allocStrategy.Type == proxyman.AllocationStrategy_Random {
return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings) return NewDynamicInboundHandler(ctx, tag, receiverSettings, proxySettings)
} }
return nil, errors.New("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError() return nil, newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).AtError()
} }
func init() { func init() {

View File

@ -9,8 +9,6 @@ import (
"github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
c "github.com/xtls/xray-core/common/ctx"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
@ -60,16 +58,16 @@ func getTProxyType(s *internet.MemoryStreamConfig) internet.SocketConfig_TProxyM
func (w *tcpWorker) callback(conn stat.Connection) { func (w *tcpWorker) callback(conn stat.Connection) {
ctx, cancel := context.WithCancel(w.ctx) ctx, cancel := context.WithCancel(w.ctx)
sid := session.NewID() sid := session.NewID()
ctx = c.ContextWithID(ctx, sid) ctx = session.ContextWithID(ctx, sid)
outbounds := []*session.Outbound{{}} var outbound = &session.Outbound{}
if w.recvOrigDest { if w.recvOrigDest {
var dest net.Destination var dest net.Destination
switch getTProxyType(w.stream) { switch getTProxyType(w.stream) {
case internet.SocketConfig_Redirect: case internet.SocketConfig_Redirect:
d, err := tcp.GetOriginalDestination(conn) d, err := tcp.GetOriginalDestination(conn)
if err != nil { if err != nil {
errors.LogInfoInner(ctx, err, "failed to get original destination") newError("failed to get original destination").Base(err).WriteToLog(session.ExportIDToError(ctx))
} else { } else {
dest = d dest = d
} }
@ -77,10 +75,10 @@ func (w *tcpWorker) callback(conn stat.Connection) {
dest = net.DestinationFromAddr(conn.LocalAddr()) dest = net.DestinationFromAddr(conn.LocalAddr())
} }
if dest.IsValid() { if dest.IsValid() {
outbounds[0].Target = dest outbound.Target = dest
} }
} }
ctx = session.ContextWithOutbounds(ctx, outbounds) ctx = session.ContextWithOutbound(ctx, outbound)
if w.uplinkCounter != nil || w.downlinkCounter != nil { if w.uplinkCounter != nil || w.downlinkCounter != nil {
conn = &stat.CounterConnection{ conn = &stat.CounterConnection{
@ -107,7 +105,7 @@ func (w *tcpWorker) callback(conn stat.Connection) {
ctx = session.ContextWithContent(ctx, content) ctx = session.ContextWithContent(ctx, content)
if err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher); err != nil { if err := w.proxy.Process(ctx, net.Network_TCP, conn, w.dispatcher); err != nil {
errors.LogInfoInner(ctx, err, "connection ends") newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
cancel() cancel()
conn.Close() conn.Close()
@ -123,24 +121,24 @@ func (w *tcpWorker) Start() error {
go w.callback(conn) go w.callback(conn)
}) })
if err != nil { if err != nil {
return errors.New("failed to listen TCP on ", w.port).AtWarning().Base(err) return newError("failed to listen TCP on ", w.port).AtWarning().Base(err)
} }
w.hub = hub w.hub = hub
return nil return nil
} }
func (w *tcpWorker) Close() error { func (w *tcpWorker) Close() error {
var errs []interface{} var errors []interface{}
if w.hub != nil { if w.hub != nil {
if err := common.Close(w.hub); err != nil { if err := common.Close(w.hub); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
if err := common.Close(w.proxy); err != nil { if err := common.Close(w.proxy); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
if len(errs) > 0 { if len(errors) > 0 {
return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...))) return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
} }
return nil return nil
@ -308,13 +306,13 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
go func() { go func() {
ctx := w.ctx ctx := w.ctx
sid := session.NewID() sid := session.NewID()
ctx = c.ContextWithID(ctx, sid) ctx = session.ContextWithID(ctx, sid)
outbounds := []*session.Outbound{{}}
if originalDest.IsValid() { if originalDest.IsValid() {
outbounds[0].Target = originalDest ctx = session.ContextWithOutbound(ctx, &session.Outbound{
Target: originalDest,
})
} }
ctx = session.ContextWithOutbounds(ctx, outbounds)
ctx = session.ContextWithInbound(ctx, &session.Inbound{ ctx = session.ContextWithInbound(ctx, &session.Inbound{
Source: source, Source: source,
Gateway: net.UDPDestination(w.address, w.port), Gateway: net.UDPDestination(w.address, w.port),
@ -329,7 +327,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source net.Destination, originalDest
} }
ctx = session.ContextWithContent(ctx, content) ctx = session.ContextWithContent(ctx, content)
if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil { if err := w.proxy.Process(ctx, net.Network_UDP, conn, w.dispatcher); err != nil {
errors.LogInfoInner(ctx, err, "connection ends") newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
conn.Close() conn.Close()
// conn not removed by checker TODO may be lock worker here is better // conn not removed by checker TODO may be lock worker here is better
@ -360,7 +358,7 @@ func (w *udpWorker) clean() error {
defer w.Unlock() defer w.Unlock()
if len(w.activeConn) == 0 { if len(w.activeConn) == 0 {
return errors.New("no more connections. stopping...") return newError("no more connections. stopping...")
} }
for addr, conn := range w.activeConn { for addr, conn := range w.activeConn {
@ -404,26 +402,26 @@ func (w *udpWorker) Close() error {
w.Lock() w.Lock()
defer w.Unlock() defer w.Unlock()
var errs []interface{} var errors []interface{}
if w.hub != nil { if w.hub != nil {
if err := w.hub.Close(); err != nil { if err := w.hub.Close(); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
if w.checker != nil { if w.checker != nil {
if err := w.checker.Close(); err != nil { if err := w.checker.Close(); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
if err := common.Close(w.proxy); err != nil { if err := common.Close(w.proxy); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
if len(errs) > 0 { if len(errors) > 0 {
return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...))) return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
} }
return nil return nil
} }
@ -454,7 +452,7 @@ type dsWorker struct {
func (w *dsWorker) callback(conn stat.Connection) { func (w *dsWorker) callback(conn stat.Connection) {
ctx, cancel := context.WithCancel(w.ctx) ctx, cancel := context.WithCancel(w.ctx)
sid := session.NewID() sid := session.NewID()
ctx = c.ContextWithID(ctx, sid) ctx = session.ContextWithID(ctx, sid)
if w.uplinkCounter != nil || w.downlinkCounter != nil { if w.uplinkCounter != nil || w.downlinkCounter != nil {
conn = &stat.CounterConnection{ conn = &stat.CounterConnection{
@ -464,8 +462,7 @@ func (w *dsWorker) callback(conn stat.Connection) {
} }
} }
ctx = session.ContextWithInbound(ctx, &session.Inbound{ ctx = session.ContextWithInbound(ctx, &session.Inbound{
// Unix have no source addr, so we use gateway as source for log. Source: net.DestinationFromAddr(conn.RemoteAddr()),
Source: net.UnixDestination(w.address),
Gateway: net.UnixDestination(w.address), Gateway: net.UnixDestination(w.address),
Tag: w.tag, Tag: w.tag,
Conn: conn, Conn: conn,
@ -482,11 +479,11 @@ func (w *dsWorker) callback(conn stat.Connection) {
ctx = session.ContextWithContent(ctx, content) ctx = session.ContextWithContent(ctx, content)
if err := w.proxy.Process(ctx, net.Network_UNIX, conn, w.dispatcher); err != nil { if err := w.proxy.Process(ctx, net.Network_UNIX, conn, w.dispatcher); err != nil {
errors.LogInfoInner(ctx, err, "connection ends") newError("connection ends").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
cancel() cancel()
if err := conn.Close(); err != nil { if err := conn.Close(); err != nil {
errors.LogInfoInner(ctx, err, "failed to close connection") newError("failed to close connection").Base(err).WriteToLog(session.ExportIDToError(ctx))
} }
} }
@ -504,24 +501,24 @@ func (w *dsWorker) Start() error {
go w.callback(conn) go w.callback(conn)
}) })
if err != nil { if err != nil {
return errors.New("failed to listen Unix Domain Socket on ", w.address).AtWarning().Base(err) return newError("failed to listen Unix Domain Socket on ", w.address).AtWarning().Base(err)
} }
w.hub = hub w.hub = hub
return nil return nil
} }
func (w *dsWorker) Close() error { func (w *dsWorker) Close() error {
var errs []interface{} var errors []interface{}
if w.hub != nil { if w.hub != nil {
if err := common.Close(w.hub); err != nil { if err := common.Close(w.hub); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
if err := common.Close(w.proxy); err != nil { if err := common.Close(w.proxy); err != nil {
errs = append(errs, err) errors = append(errors, err)
} }
} }
if len(errs) > 0 { if len(errors) > 0 {
return errors.New("failed to close all resources").Base(errors.New(serial.Concat(errs...))) return newError("failed to close all resources").Base(newError(serial.Concat(errors...)))
} }
return nil return nil

View File

@ -0,0 +1,9 @@
package outbound
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

@ -2,17 +2,13 @@ package outbound
import ( import (
"context" "context"
"crypto/rand" "errors"
goerrors "errors"
"io" "io"
"math/big"
gonet "net"
"os" "os"
"github.com/xtls/xray-core/app/proxyman" "github.com/xtls/xray-core/app/proxyman"
"github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/mux" "github.com/xtls/xray-core/common/mux"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/net/cnc" "github.com/xtls/xray-core/common/net/cnc"
@ -54,7 +50,7 @@ func getStatCounter(v *core.Instance, tag string) (stats.Counter, stats.Counter)
return uplinkCounter, downlinkCounter return uplinkCounter, downlinkCounter
} }
// Handler implements outbound.Handler. // Handler is an implements of outbound.Handler.
type Handler struct { type Handler struct {
tag string tag string
senderSettings *proxyman.SenderConfig senderSettings *proxyman.SenderConfig
@ -89,11 +85,11 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
h.senderSettings = s h.senderSettings = s
mss, err := internet.ToMemoryStreamConfig(s.StreamSettings) mss, err := internet.ToMemoryStreamConfig(s.StreamSettings)
if err != nil { if err != nil {
return nil, errors.New("failed to parse stream settings").Base(err).AtWarning() return nil, newError("failed to parse stream settings").Base(err).AtWarning()
} }
h.streamSettings = mss h.streamSettings = mss
default: default:
return nil, errors.New("settings is not SenderConfig") return nil, newError("settings is not SenderConfig")
} }
} }
@ -109,7 +105,7 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
proxyHandler, ok := rawProxyHandler.(proxy.Outbound) proxyHandler, ok := rawProxyHandler.(proxy.Outbound)
if !ok { if !ok {
return nil, errors.New("not an outbound handler") return nil, newError("not an outbound handler")
} }
if h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil { if h.senderSettings != nil && h.senderSettings.MultiplexSettings != nil {
@ -171,31 +167,30 @@ func (h *Handler) Tag() string {
// Dispatch implements proxy.Outbound.Dispatch. // Dispatch implements proxy.Outbound.Dispatch.
func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) { func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
outbounds := session.OutboundsFromContext(ctx) outbound := session.OutboundFromContext(ctx)
ob := outbounds[len(outbounds)-1] if outbound.Target.Network == net.Network_UDP && outbound.OriginalTarget.Address != nil && outbound.OriginalTarget.Address != outbound.Target.Address {
if ob.Target.Network == net.Network_UDP && ob.OriginalTarget.Address != nil && ob.OriginalTarget.Address != ob.Target.Address { link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: outbound.Target.Address, OriginalDest: outbound.OriginalTarget.Address}
link.Reader = &buf.EndpointOverrideReader{Reader: link.Reader, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address} link.Writer = &buf.EndpointOverrideWriter{Writer: link.Writer, Dest: outbound.Target.Address, OriginalDest: outbound.OriginalTarget.Address}
link.Writer = &buf.EndpointOverrideWriter{Writer: link.Writer, Dest: ob.Target.Address, OriginalDest: ob.OriginalTarget.Address}
} }
if h.mux != nil { if h.mux != nil {
test := func(err error) { test := func(err error) {
if err != nil { if err != nil {
err := errors.New("failed to process mux outbound traffic").Base(err) err := newError("failed to process mux outbound traffic").Base(err)
session.SubmitOutboundErrorToOriginator(ctx, err) session.SubmitOutboundErrorToOriginator(ctx, err)
errors.LogInfo(ctx, err.Error()) err.WriteToLog(session.ExportIDToError(ctx))
common.Interrupt(link.Writer) common.Interrupt(link.Writer)
} }
} }
if ob.Target.Network == net.Network_UDP && ob.Target.Port == 443 { if outbound.Target.Network == net.Network_UDP && outbound.Target.Port == 443 {
switch h.udp443 { switch h.udp443 {
case "reject": case "reject":
test(errors.New("XUDP rejected UDP/443 traffic").AtInfo()) test(newError("XUDP rejected UDP/443 traffic").AtInfo())
return return
case "skip": case "skip":
goto out goto out
} }
} }
if h.xudp != nil && ob.Target.Network == net.Network_UDP { if h.xudp != nil && outbound.Target.Network == net.Network_UDP {
if !h.xudp.Enabled { if !h.xudp.Enabled {
goto out goto out
} }
@ -210,15 +205,15 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
out: out:
err := h.proxy.Process(ctx, link, h) err := h.proxy.Process(ctx, link, h)
if err != nil { if err != nil {
if goerrors.Is(err, io.EOF) || goerrors.Is(err, io.ErrClosedPipe) || goerrors.Is(err, context.Canceled) { if errors.Is(err, io.EOF) || errors.Is(err, io.ErrClosedPipe) || errors.Is(err, context.Canceled) {
err = nil err = nil
} }
} }
if err != nil { if err != nil {
// Ensure outbound ray is properly closed. // Ensure outbound ray is properly closed.
err := errors.New("failed to process outbound traffic").Base(err) err := newError("failed to process outbound traffic").Base(err)
session.SubmitOutboundErrorToOriginator(ctx, err) session.SubmitOutboundErrorToOriginator(ctx, err)
errors.LogInfo(ctx, err.Error()) err.WriteToLog(session.ExportIDToError(ctx))
common.Interrupt(link.Writer) common.Interrupt(link.Writer)
} else { } else {
common.Close(link.Writer) common.Close(link.Writer)
@ -245,12 +240,11 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
tag := h.senderSettings.ProxySettings.Tag tag := h.senderSettings.ProxySettings.Tag
handler := h.outboundManager.GetHandler(tag) handler := h.outboundManager.GetHandler(tag)
if handler != nil { if handler != nil {
errors.LogDebug(ctx, "proxying to ", tag, " for dest ", dest) newError("proxying to ", tag, " for dest ", dest).AtDebug().WriteToLog(session.ExportIDToError(ctx))
outbounds := session.OutboundsFromContext(ctx) ctx = session.ContextWithOutbound(ctx, &session.Outbound{
ctx = session.ContextWithOutbounds(ctx, append(outbounds, &session.Outbound{
Target: dest, Target: dest,
Tag: tag, })
})) // add another outbound in session ctx
opts := pipe.OptionsFromContext(ctx) opts := pipe.OptionsFromContext(ctx)
uplinkReader, uplinkWriter := pipe.New(opts...) uplinkReader, uplinkWriter := pipe.New(opts...)
downlinkReader, downlinkWriter := pipe.New(opts...) downlinkReader, downlinkWriter := pipe.New(opts...)
@ -266,17 +260,16 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
return h.getStatCouterConnection(conn), nil return h.getStatCouterConnection(conn), nil
} }
errors.LogWarning(ctx, "failed to get outbound handler with tag: ", tag) newError("failed to get outbound handler with tag: ", tag).AtWarning().WriteToLog(session.ExportIDToError(ctx))
} }
if h.senderSettings.Via != nil { if h.senderSettings.Via != nil {
outbounds := session.OutboundsFromContext(ctx) outbound := session.OutboundFromContext(ctx)
ob := outbounds[len(outbounds)-1] if outbound == nil {
if h.senderSettings.ViaCidr == "" { outbound = new(session.Outbound)
ob.Gateway = h.senderSettings.Via.AsAddress() ctx = session.ContextWithOutbound(ctx, outbound)
} else { //Get a random address.
ob.Gateway = ParseRandomIPv6(h.senderSettings.Via.AsAddress(), h.senderSettings.ViaCidr)
} }
outbound.Gateway = h.senderSettings.Via.AsAddress()
} }
} }
@ -286,9 +279,10 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
conn, err := internet.Dial(ctx, dest, h.streamSettings) conn, err := internet.Dial(ctx, dest, h.streamSettings)
conn = h.getStatCouterConnection(conn) conn = h.getStatCouterConnection(conn)
outbounds := session.OutboundsFromContext(ctx) outbound := session.OutboundFromContext(ctx)
ob := outbounds[len(outbounds)-1] if outbound != nil {
ob.Conn = conn outbound.Conn = conn
}
return conn, err return conn, err
} }
@ -318,21 +312,3 @@ func (h *Handler) Close() error {
common.Close(h.mux) common.Close(h.mux)
return nil return nil
} }
func ParseRandomIPv6(address net.Address, prefix string) net.Address {
_, network, _ := gonet.ParseCIDR(address.IP().String() + "/" + prefix)
maskSize, totalBits := network.Mask.Size()
subnetSize := big.NewInt(1).Lsh(big.NewInt(1), uint(totalBits-maskSize))
// random
randomBigInt, _ := rand.Int(rand.Reader, subnetSize)
startIPBigInt := big.NewInt(0).SetBytes(network.IP.To16())
randomIPBigInt := big.NewInt(0).Add(startIPBigInt, randomBigInt)
randomIPBytes := randomIPBigInt.Bytes()
randomIPBytes = append(make([]byte, 16-len(randomIPBytes)), randomIPBytes...)
return net.ParseAddress(gonet.IP(randomIPBytes).String())
}

View File

@ -2,19 +2,13 @@ package outbound_test
import ( import (
"context" "context"
"fmt"
"sync"
"sync/atomic"
"testing" "testing"
"time"
"github.com/xtls/xray-core/app/policy" "github.com/xtls/xray-core/app/policy"
"github.com/xtls/xray-core/app/proxyman"
. "github.com/xtls/xray-core/app/proxyman/outbound" . "github.com/xtls/xray-core/app/proxyman/outbound"
"github.com/xtls/xray-core/app/stats" "github.com/xtls/xray-core/app/stats"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/serial" "github.com/xtls/xray-core/common/serial"
"github.com/xtls/xray-core/common/session"
core "github.com/xtls/xray-core/core" core "github.com/xtls/xray-core/core"
"github.com/xtls/xray-core/features/outbound" "github.com/xtls/xray-core/features/outbound"
"github.com/xtls/xray-core/proxy/freedom" "github.com/xtls/xray-core/proxy/freedom"
@ -45,7 +39,6 @@ func TestOutboundWithoutStatCounter(t *testing.T) {
v, _ := core.New(config) v, _ := core.New(config)
v.AddFeature((outbound.Manager)(new(Manager))) v.AddFeature((outbound.Manager)(new(Manager)))
ctx := context.WithValue(context.Background(), xrayKey, v) ctx := context.WithValue(context.Background(), xrayKey, v)
ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}})
h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
Tag: "tag", Tag: "tag",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
@ -75,7 +68,6 @@ func TestOutboundWithStatCounter(t *testing.T) {
v, _ := core.New(config) v, _ := core.New(config)
v.AddFeature((outbound.Manager)(new(Manager))) v.AddFeature((outbound.Manager)(new(Manager)))
ctx := context.WithValue(context.Background(), xrayKey, v) ctx := context.WithValue(context.Background(), xrayKey, v)
ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}})
h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{
Tag: "tag", Tag: "tag",
ProxySettings: serial.ToTypedMessage(&freedom.Config{}), ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
@ -86,91 +78,3 @@ func TestOutboundWithStatCounter(t *testing.T) {
t.Errorf("Expected conn to be CounterConnection") t.Errorf("Expected conn to be CounterConnection")
} }
} }
func TestTagsCache(t *testing.T) {
test_duration := 10 * time.Second
threads_num := 50
delay := 10 * time.Millisecond
tags_prefix := "node"
tags := sync.Map{}
counter := atomic.Uint64{}
ohm, err := New(context.Background(), &proxyman.OutboundConfig{})
if err != nil {
t.Error("failed to create outbound handler manager")
}
config := &core.Config{
App: []*serial.TypedMessage{},
}
v, _ := core.New(config)
v.AddFeature(ohm)
ctx := context.WithValue(context.Background(), xrayKey, v)
stop_add_rm := false
wg_add_rm := sync.WaitGroup{}
addHandlers := func() {
defer wg_add_rm.Done()
for !stop_add_rm {
time.Sleep(delay)
idx := counter.Add(1)
tag := fmt.Sprintf("%s%d", tags_prefix, idx)
cfg := &core.OutboundHandlerConfig{
Tag: tag,
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
}
if h, err := NewHandler(ctx, cfg); err == nil {
if err := ohm.AddHandler(ctx, h); err == nil {
// t.Log("add handler:", tag)
tags.Store(tag, nil)
} else {
t.Error("failed to add handler:", tag)
}
} else {
t.Error("failed to create handler:", tag)
}
}
}
rmHandlers := func() {
defer wg_add_rm.Done()
for !stop_add_rm {
time.Sleep(delay)
tags.Range(func(key interface{}, value interface{}) bool {
if _, ok := tags.LoadAndDelete(key); ok {
// t.Log("remove handler:", key)
ohm.RemoveHandler(ctx, key.(string))
return false
}
return true
})
}
}
selectors := []string{tags_prefix}
wg_get := sync.WaitGroup{}
stop_get := false
getTags := func() {
defer wg_get.Done()
for !stop_get {
time.Sleep(delay)
_ = ohm.Select(selectors)
// t.Logf("get tags: %v", tag)
}
}
for i := 0; i < threads_num; i++ {
wg_add_rm.Add(2)
go rmHandlers()
go addHandlers()
wg_get.Add(1)
go getTags()
}
time.Sleep(test_duration)
stop_add_rm = true
wg_add_rm.Wait()
stop_get = true
wg_get.Wait()
}

View File

@ -1,8 +1,9 @@
package outbound package outbound
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
import ( import (
"context" "context"
"sort"
"strings" "strings"
"sync" "sync"
@ -20,14 +21,12 @@ type Manager struct {
taggedHandler map[string]outbound.Handler taggedHandler map[string]outbound.Handler
untaggedHandlers []outbound.Handler untaggedHandlers []outbound.Handler
running bool running bool
tagsCache *sync.Map
} }
// New creates a new Manager. // New creates a new Manager.
func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) { func New(ctx context.Context, config *proxyman.OutboundConfig) (*Manager, error) {
m := &Manager{ m := &Manager{
taggedHandler: make(map[string]outbound.Handler), taggedHandler: make(map[string]outbound.Handler),
tagsCache: &sync.Map{},
} }
return m, nil return m, nil
} }
@ -104,8 +103,6 @@ func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) erro
m.access.Lock() m.access.Lock()
defer m.access.Unlock() defer m.access.Unlock()
m.tagsCache = &sync.Map{}
if m.defaultHandler == nil { if m.defaultHandler == nil {
m.defaultHandler = handler m.defaultHandler = handler
} }
@ -113,7 +110,7 @@ func (m *Manager) AddHandler(ctx context.Context, handler outbound.Handler) erro
tag := handler.Tag() tag := handler.Tag()
if len(tag) > 0 { if len(tag) > 0 {
if _, found := m.taggedHandler[tag]; found { if _, found := m.taggedHandler[tag]; found {
return errors.New("existing tag found: " + tag) return newError("existing tag found: " + tag)
} }
m.taggedHandler[tag] = handler m.taggedHandler[tag] = handler
} else { } else {
@ -135,8 +132,6 @@ func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
m.access.Lock() m.access.Lock()
defer m.access.Unlock() defer m.access.Unlock()
m.tagsCache = &sync.Map{}
delete(m.taggedHandler, tag) delete(m.taggedHandler, tag)
if m.defaultHandler != nil && m.defaultHandler.Tag() == tag { if m.defaultHandler != nil && m.defaultHandler.Tag() == tag {
m.defaultHandler = nil m.defaultHandler = nil
@ -147,29 +142,24 @@ func (m *Manager) RemoveHandler(ctx context.Context, tag string) error {
// Select implements outbound.HandlerSelector. // Select implements outbound.HandlerSelector.
func (m *Manager) Select(selectors []string) []string { func (m *Manager) Select(selectors []string) []string {
key := strings.Join(selectors, ",")
if cache, ok := m.tagsCache.Load(key); ok {
return cache.([]string)
}
m.access.RLock() m.access.RLock()
defer m.access.RUnlock() defer m.access.RUnlock()
tags := make([]string, 0, len(selectors)) tags := make([]string, 0, len(selectors))
for tag := range m.taggedHandler { for tag := range m.taggedHandler {
match := false
for _, selector := range selectors { for _, selector := range selectors {
if strings.HasPrefix(tag, selector) { if strings.HasPrefix(tag, selector) {
tags = append(tags, tag) match = true
break break
} }
} }
if match {
tags = append(tags, tag)
}
} }
sort.Strings(tags)
m.tagsCache.Store(key, tags)
return tags return tags
} }

View File

@ -5,7 +5,6 @@ import (
"os" "os"
"github.com/sagernet/sing/common/uot" "github.com/sagernet/sing/common/uot"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet"
"github.com/xtls/xray-core/transport/internet/stat" "github.com/xtls/xray-core/transport/internet/stat"
@ -13,7 +12,7 @@ import (
func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) { func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (stat.Connection, error) {
if dest.Address == nil { if dest.Address == nil {
return nil, errors.New("nil destination address") return nil, newError("nil destination address")
} }
if !dest.Address.Family().IsDomain() { if !dest.Address.Family().IsDomain() {
return nil, os.ErrInvalid return nil, os.ErrInvalid
@ -28,7 +27,7 @@ func (h *Handler) getUoTConnection(ctx context.Context, dest net.Destination) (s
} }
packetConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings) packetConn, err := internet.ListenSystemPacket(ctx, &net.UDPAddr{IP: net.AnyIP.IP(), Port: 0}, h.streamSettings.SocketSettings)
if err != nil { if err != nil {
return nil, errors.New("unable to listen socket").Base(err) return nil, newError("unable to listen socket").Base(err)
} }
conn := uot.NewServerConn(packetConn, uotVersion) conn := uot.NewServerConn(packetConn, uotVersion)
return h.getStatCouterConnection(conn), nil return h.getStatCouterConnection(conn), nil

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"time" "time"
"github.com/xtls/xray-core/common/errors"
"github.com/xtls/xray-core/common/mux" "github.com/xtls/xray-core/common/mux"
"github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/net"
"github.com/xtls/xray-core/common/session" "github.com/xtls/xray-core/common/session"
@ -27,10 +26,10 @@ type Bridge struct {
// NewBridge creates a new Bridge instance. // NewBridge creates a new Bridge instance.
func NewBridge(config *BridgeConfig, dispatcher routing.Dispatcher) (*Bridge, error) { func NewBridge(config *BridgeConfig, dispatcher routing.Dispatcher) (*Bridge, error) {
if config.Tag == "" { if config.Tag == "" {
return nil, errors.New("bridge tag is empty") return nil, newError("bridge tag is empty")
} }
if config.Domain == "" { if config.Domain == "" {
return nil, errors.New("bridge domain is empty") return nil, newError("bridge domain is empty")
} }
b := &Bridge{ b := &Bridge{
@ -75,7 +74,7 @@ func (b *Bridge) monitor() error {
if numWorker == 0 || numConnections/numWorker > 16 { if numWorker == 0 || numConnections/numWorker > 16 {
worker, err := NewBridgeWorker(b.domain, b.tag, b.dispatcher) worker, err := NewBridgeWorker(b.domain, b.tag, b.dispatcher)
if err != nil { if err != nil {
errors.LogWarningInner(context.Background(), err, "failed to create bridge worker") newError("failed to create bridge worker").Base(err).AtWarning().WriteToLog()
return nil return nil
} }
b.workers = append(b.workers, worker) b.workers = append(b.workers, worker)
@ -158,7 +157,7 @@ func (w *BridgeWorker) handleInternalConn(link *transport.Link) {
for _, b := range mb { for _, b := range mb {
var ctl Control var ctl Control
if err := proto.Unmarshal(b.Bytes(), &ctl); err != nil { if err := proto.Unmarshal(b.Bytes(), &ctl); err != nil {
errors.LogInfoInner(context.Background(), err, "failed to parse proto message") newError("failed to parse proto message").Base(err).WriteToLog()
break break
} }
if ctl.State != w.state { if ctl.State != w.state {

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.35.1 // protoc-gen-go v1.31.0
// protoc v5.28.2 // protoc v4.23.1
// source: app/reverse/config.proto // source: app/reverse/config.proto
package reverse package reverse
@ -77,9 +77,11 @@ type Control struct {
func (x *Control) Reset() { func (x *Control) Reset() {
*x = Control{} *x = Control{}
mi := &file_app_reverse_config_proto_msgTypes[0] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_reverse_config_proto_msgTypes[0]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Control) String() string { func (x *Control) String() string {
@ -90,7 +92,7 @@ func (*Control) ProtoMessage() {}
func (x *Control) ProtoReflect() protoreflect.Message { func (x *Control) ProtoReflect() protoreflect.Message {
mi := &file_app_reverse_config_proto_msgTypes[0] mi := &file_app_reverse_config_proto_msgTypes[0]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -130,9 +132,11 @@ type BridgeConfig struct {
func (x *BridgeConfig) Reset() { func (x *BridgeConfig) Reset() {
*x = BridgeConfig{} *x = BridgeConfig{}
mi := &file_app_reverse_config_proto_msgTypes[1] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_reverse_config_proto_msgTypes[1]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *BridgeConfig) String() string { func (x *BridgeConfig) String() string {
@ -143,7 +147,7 @@ func (*BridgeConfig) ProtoMessage() {}
func (x *BridgeConfig) ProtoReflect() protoreflect.Message { func (x *BridgeConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_reverse_config_proto_msgTypes[1] mi := &file_app_reverse_config_proto_msgTypes[1]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -183,9 +187,11 @@ type PortalConfig struct {
func (x *PortalConfig) Reset() { func (x *PortalConfig) Reset() {
*x = PortalConfig{} *x = PortalConfig{}
mi := &file_app_reverse_config_proto_msgTypes[2] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_reverse_config_proto_msgTypes[2]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *PortalConfig) String() string { func (x *PortalConfig) String() string {
@ -196,7 +202,7 @@ func (*PortalConfig) ProtoMessage() {}
func (x *PortalConfig) ProtoReflect() protoreflect.Message { func (x *PortalConfig) ProtoReflect() protoreflect.Message {
mi := &file_app_reverse_config_proto_msgTypes[2] mi := &file_app_reverse_config_proto_msgTypes[2]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -236,9 +242,11 @@ type Config struct {
func (x *Config) Reset() { func (x *Config) Reset() {
*x = Config{} *x = Config{}
mi := &file_app_reverse_config_proto_msgTypes[3] if protoimpl.UnsafeEnabled {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) mi := &file_app_reverse_config_proto_msgTypes[3]
ms.StoreMessageInfo(mi) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
} }
func (x *Config) String() string { func (x *Config) String() string {
@ -249,7 +257,7 @@ func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message { func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_app_reverse_config_proto_msgTypes[3] mi := &file_app_reverse_config_proto_msgTypes[3]
if x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
@ -330,7 +338,7 @@ func file_app_reverse_config_proto_rawDescGZIP() []byte {
var file_app_reverse_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_app_reverse_config_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_app_reverse_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_app_reverse_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_app_reverse_config_proto_goTypes = []any{ var file_app_reverse_config_proto_goTypes = []interface{}{
(Control_State)(0), // 0: xray.app.reverse.Control.State (Control_State)(0), // 0: xray.app.reverse.Control.State
(*Control)(nil), // 1: xray.app.reverse.Control (*Control)(nil), // 1: xray.app.reverse.Control
(*BridgeConfig)(nil), // 2: xray.app.reverse.BridgeConfig (*BridgeConfig)(nil), // 2: xray.app.reverse.BridgeConfig
@ -353,6 +361,56 @@ func file_app_reverse_config_proto_init() {
if File_app_reverse_config_proto != nil { if File_app_reverse_config_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled {
file_app_reverse_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Control); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_reverse_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BridgeConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_reverse_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PortalConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_app_reverse_config_proto_msgTypes[3].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{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{

View File

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

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