diff --git a/.github/CRONET_GO_VERSION b/.github/CRONET_GO_VERSION
index a2d9d6ca1d..53d53768ca 100644
--- a/.github/CRONET_GO_VERSION
+++ b/.github/CRONET_GO_VERSION
@@ -1 +1 @@
-2faf34666c2cc8234f10f2ab6d4c4d6104d34ae2
+b3eec8134aec1387d850e0671dd8531e2e6140b0
diff --git a/.github/setup_go_for_macos1013.sh b/.github/setup_go_for_macos1013.sh
index 9889d2364d..9e501ca949 100755
--- a/.github/setup_go_for_macos1013.sh
+++ b/.github/setup_go_for_macos1013.sh
@@ -2,7 +2,7 @@
set -euo pipefail
-VERSION="1.25.9"
+VERSION="1.25.10"
PATCH_COMMITS=(
"afe69d3cec1c6dcf0f1797b20546795730850070"
"1ed289b0cf87dc5aae9c6fe1aa5f200a83412938"
diff --git a/.github/setup_go_for_windows7.sh b/.github/setup_go_for_windows7.sh
index e8c36596b2..01588bca0f 100755
--- a/.github/setup_go_for_windows7.sh
+++ b/.github/setup_go_for_windows7.sh
@@ -2,7 +2,7 @@
set -euo pipefail
-VERSION="1.25.9"
+VERSION="1.25.10"
PATCH_COMMITS=(
"466f6c7a29bc098b0d4c987b803c779222894a11"
"1bdabae205052afe1dadb2ad6f1ba612cdbc532a"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9d1445369c..42dde88591 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -11,7 +11,7 @@ on:
description: "Build type"
required: true
type: choice
- default: "All"
+ default: "Binary"
options:
- All
- Binary
@@ -22,12 +22,12 @@ on:
- macOS
- tvOS
- macOS-standalone
- - publish-android
+ # - publish-android
push:
branches:
- - stable
- - testing
- - unstable
+ - main-next
+ - dev-next
+ - extended
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
@@ -44,10 +44,11 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
+ submodules: 'recursive'
- name: Setup Go
uses: actions/setup-go@v5
with:
- go-version: ~1.25.9
+ go-version: ^1.25.6
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
@@ -68,63 +69,62 @@ jobs:
needs:
- calculate_version
strategy:
+ fail-fast: false
matrix:
include:
- { os: linux, arch: amd64, variant: purego, naive: true }
- - { os: linux, arch: amd64, variant: glibc, naive: true }
- - { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, alpine: x86_64, openwrt: "x86_64" }
-
- - { os: linux, arch: arm64, variant: purego, naive: true }
- - { os: linux, arch: arm64, variant: glibc, naive: true }
- - { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, alpine: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }
+ # - { os: linux, arch: amd64, variant: glibc, naive: true }
+ # # - { os: linux, arch: amd64, variant: musl, naive: true, debian: amd64, rpm: x86_64, pacman: x86_64, openwrt: "x86_64" }
- - { os: linux, arch: "386", go386: sse2 }
- - { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 }
- - { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, alpine: x86, openwrt: "i386_pentium4" }
+ # - { os: linux, arch: arm64, variant: purego, naive: true }
+ # - { os: linux, arch: arm64, variant: glibc, naive: true }
+ # # - { os: linux, arch: arm64, variant: musl, naive: true, debian: arm64, rpm: aarch64, pacman: aarch64, openwrt: "aarch64_cortex-a53 aarch64_cortex-a72 aarch64_cortex-a76 aarch64_generic" }
- - { os: linux, arch: arm, goarm: "7" }
- - { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" }
- - { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, alpine: armv7, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }
+ # # - { os: linux, arch: "386", go386: sse2 }
+ # # - { os: linux, arch: "386", variant: glibc, naive: true, go386: sse2 }
+ # # - { os: linux, arch: "386", variant: musl, naive: true, go386: sse2, debian: i386, rpm: i386, openwrt: "i386_pentium4" }
- - { os: linux, arch: mipsle, gomips: hardfloat, naive: true, variant: glibc }
- - { os: linux, arch: mipsle, gomips: softfloat, naive: true, variant: musl, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
- - { os: linux, arch: mips64le, gomips: hardfloat, naive: true, variant: glibc, debian: mips64el, rpm: mips64el }
- - { os: linux, arch: riscv64, naive: true, variant: glibc }
- - { os: linux, arch: riscv64, naive: true, variant: musl, debian: riscv64, rpm: riscv64, alpine: riscv64, openwrt: "riscv64_generic" }
- - { os: linux, arch: loong64, naive: true, variant: glibc }
- - { os: linux, arch: loong64, naive: true, variant: musl, debian: loongarch64, rpm: loongarch64, alpine: loongarch64, openwrt: "loongarch64_generic" }
+ # # - { os: linux, arch: arm, goarm: "7" }
+ # # - { os: linux, arch: arm, variant: glibc, naive: true, goarm: "7" }
+ # # - { os: linux, arch: arm, variant: musl, naive: true, goarm: "7", debian: armhf, rpm: armv7hl, pacman: armv7hl, openwrt: "arm_cortex-a5_vfpv4 arm_cortex-a7_neon-vfpv4 arm_cortex-a7_vfpv4 arm_cortex-a8_vfpv3 arm_cortex-a9_neon arm_cortex-a9_vfpv3-d16 arm_cortex-a15_neon-vfpv4" }
- - { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
- - { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
- - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
- - { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
- - { os: linux, arch: mipsle, gomips: hardfloat, openwrt: "mipsel_24kc_24kf" }
- - { os: linux, arch: mipsle, gomips: softfloat }
- - { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" }
- - { os: linux, arch: mips64le, gomips: hardfloat }
- - { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" }
- - { os: linux, arch: s390x, debian: s390x, rpm: s390x }
- - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
- - { os: linux, arch: riscv64 }
- - { os: linux, arch: loong64 }
+ # # - { os: linux, arch: "386", go386: softfloat, openwrt: "i386_pentium-mmx" }
+ # # - { os: linux, arch: arm, goarm: "5", openwrt: "arm_arm926ej-s arm_cortex-a7 arm_cortex-a9 arm_fa526 arm_xscale" }
+ # # - { os: linux, arch: arm, goarm: "6", debian: armel, rpm: armv6hl, openwrt: "arm_arm1176jzf-s_vfp" }
+ # # - { os: linux, arch: mips, gomips: softfloat, openwrt: "mips_24kc mips_4kec mips_mips32" }
+ # # - { os: linux, arch: mipsle, gomips: hardfloat, debian: mipsel, rpm: mipsel, openwrt: "mipsel_24kc_24kf" }
+ # # - { os: linux, arch: mipsle, gomips: softfloat, openwrt: "mipsel_24kc mipsel_74kc mipsel_mips32" }
+ # # - { os: linux, arch: mips64, gomips: softfloat, openwrt: "mips64_mips64r2 mips64_octeonplus" }
+ # # - { os: linux, arch: mips64le, gomips: hardfloat, debian: mips64el, rpm: mips64el }
+ # # - { os: linux, arch: mips64le, gomips: softfloat, openwrt: "mips64el_mips64r2" }
+ # # - { os: linux, arch: s390x, debian: s390x, rpm: s390x }
+ # # - { os: linux, arch: ppc64le, debian: ppc64el, rpm: ppc64le }
+ # # - { os: linux, arch: riscv64, debian: riscv64, rpm: riscv64, openwrt: "riscv64_generic" }
+ # # - { os: linux, arch: loong64, debian: loongarch64, rpm: loongarch64, openwrt: "loongarch64_generic" }
- - { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
- - { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }
+ # - { os: windows, arch: amd64, legacy_win7: true, legacy_name: "windows-7" }
+ # - { os: windows, arch: "386", legacy_win7: true, legacy_name: "windows-7" }
- - { os: android, arch: arm64, ndk: "aarch64-linux-android23" }
- - { os: android, arch: arm, ndk: "armv7a-linux-androideabi23" }
- - { os: android, arch: amd64, ndk: "x86_64-linux-android23" }
- - { os: android, arch: "386", ndk: "i686-linux-android23" }
+ # # - { os: android, arch: arm64, ndk: "aarch64-linux-android23" }
+ # # - { os: android, arch: arm, ndk: "armv7a-linux-androideabi23" }
+ # # - { os: android, arch: amd64, ndk: "x86_64-linux-android23" }
+ # # - { os: android, arch: "386", ndk: "i686-linux-android23" }
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
with:
fetch-depth: 0
+ submodules: 'recursive'
- name: Setup Go
- if: ${{ ! matrix.legacy_win7 }}
+ if: ${{ ! (matrix.legacy_win7 || matrix.legacy_go124) }}
+ uses: actions/setup-go@v5
+ with:
+ go-version: ^1.25.6
+ - name: Setup Go 1.24
+ if: matrix.legacy_go124
uses: actions/setup-go@v5
with:
- go-version: ~1.25.9
+ go-version: ~1.24.10
- name: Cache Go for Windows 7
if: matrix.legacy_win7
id: cache-go-for-windows7
@@ -132,11 +132,9 @@ jobs:
with:
path: |
~/go/go_win7
- key: go_win7_1258
+ key: go_win7_1255
- name: Setup Go for Windows 7
if: matrix.legacy_win7 && steps.cache-go-for-windows7.outputs.cache-hit != 'true'
- env:
- GITHUB_TOKEN: ${{ github.token }}
run: |-
.github/setup_go_for_windows7.sh
- name: Setup Go for Windows 7
@@ -160,23 +158,14 @@ jobs:
git -C ~/cronet-go fetch --depth=1 origin "$CRONET_GO_VERSION"
git -C ~/cronet-go checkout FETCH_HEAD
git -C ~/cronet-go submodule update --init --recursive --depth=1
- - name: Regenerate Debian keyring
- if: matrix.naive
- run: |
- set -xeuo pipefail
- rm -f ~/cronet-go/naiveproxy/src/build/linux/sysroot_scripts/keyring.gpg
- cd ~/cronet-go
- GPG_TTY=/dev/null ./naiveproxy/src/build/linux/sysroot_scripts/generate_keyring.sh
- name: Cache Chromium toolchain
if: matrix.naive
id: cache-chromium-toolchain
uses: actions/cache@v4
with:
path: |
- ~/cronet-go/naiveproxy/src/third_party/llvm-build/
- ~/cronet-go/naiveproxy/src/gn/out/
- ~/cronet-go/naiveproxy/src/chrome/build/pgo_profiles/
- ~/cronet-go/naiveproxy/src/out/sysroot-build/
+ ~/cronet-go/naiveproxy/src/third_party/llvm-build/Release+Asserts
+ ~/cronet-go/naiveproxy/src/out/sysroot-build
key: chromium-toolchain-${{ matrix.arch }}-${{ matrix.variant }}-${{ hashFiles('.github/CRONET_GO_VERSION') }}
- name: Download Chromium toolchain
if: matrix.naive
@@ -205,10 +194,9 @@ jobs:
- name: Set build tags
run: |
set -xeuo pipefail
+ TAGS='with_v2ray_api,with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0'
if [[ "${{ matrix.naive }}" == "true" ]]; then
- TAGS=$(cat release/DEFAULT_BUILD_TAGS)
- else
- TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
+ TAGS="${TAGS},with_naive_outbound"
fi
if [[ "${{ matrix.variant }}" == "purego" ]]; then
TAGS="${TAGS},with_purego"
@@ -216,16 +204,13 @@ jobs:
TAGS="${TAGS},with_musl"
fi
echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- - name: Set shared ldflags
- run: |
- echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- name: Build (purego)
if: matrix.variant == 'purego'
run: |
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
+ -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "0"
@@ -247,7 +232,7 @@ jobs:
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
+ -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "1"
@@ -255,8 +240,6 @@ jobs:
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
- GOMIPS: ${{ matrix.gomips }}
- GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (musl)
if: matrix.variant == 'musl'
@@ -264,7 +247,7 @@ jobs:
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
+ -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "1"
@@ -272,8 +255,6 @@ jobs:
GOARCH: ${{ matrix.arch }}
GO386: ${{ matrix.go386 }}
GOARM: ${{ matrix.goarm }}
- GOMIPS: ${{ matrix.gomips }}
- GOMIPS64: ${{ matrix.gomips }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build (non-variant)
if: matrix.os != 'android' && matrix.variant == ''
@@ -281,7 +262,7 @@ jobs:
set -xeuo pipefail
mkdir -p dist
go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
+ -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "0"
@@ -301,7 +282,7 @@ jobs:
export CXX="${CC}++"
mkdir -p dist
GOOS=$BUILD_GOOS GOARCH=$BUILD_GOARCH build go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
+ -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
./cmd/sing-box
env:
CGO_ENABLED: "1"
@@ -375,7 +356,7 @@ jobs:
sudo gem install fpm
sudo apt-get update
sudo apt-get install -y libarchive-tools
- cp .fpm_pacman .fpm
+ cp .fpm_systemd .fpm
fpm -t pacman \
-v "$PKG_VERSION" \
-p "dist/sing-box_${{ needs.calculate_version.outputs.version }}_${{ matrix.os }}_${{ matrix.pacman }}.pkg.tar.zst" \
@@ -396,30 +377,6 @@ jobs:
.github/deb2ipk.sh "$architecture" "dist/openwrt.deb" "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.ipk"
done
rm "dist/openwrt.deb"
- - name: Install apk-tools
- if: matrix.openwrt != '' || matrix.alpine != ''
- run: |-
- docker run --rm -v /usr/local/bin:/mnt alpine:edge sh -c "apk add --no-cache apk-tools-static && cp /sbin/apk.static /mnt/apk && chmod +x /mnt/apk"
- - name: Package OpenWrt APK
- if: matrix.openwrt != ''
- run: |-
- set -xeuo pipefail
- for architecture in ${{ matrix.openwrt }}; do
- .github/build_openwrt_apk.sh \
- "$architecture" \
- "${{ needs.calculate_version.outputs.version }}" \
- "dist/sing-box" \
- "dist/sing-box_${{ needs.calculate_version.outputs.version }}_openwrt_${architecture}.apk"
- done
- - name: Package Alpine APK
- if: matrix.alpine != ''
- run: |-
- set -xeuo pipefail
- .github/build_alpine_apk.sh \
- "${{ matrix.alpine }}" \
- "${{ needs.calculate_version.outputs.version }}" \
- "dist/sing-box" \
- "dist/sing-box_${{ needs.calculate_version.outputs.version }}_linux_${{ matrix.alpine }}.apk"
- name: Archive
run: |
set -xeuo pipefail
@@ -444,576 +401,564 @@ jobs:
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.go386 && format('_{0}', matrix.go386) }}${{ matrix.gomips && format('_{0}', matrix.gomips) }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}${{ matrix.variant && format('-{0}', matrix.variant) }}
path: "dist"
- build_darwin:
- name: Build Darwin binaries
- if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
- runs-on: macos-latest
- needs:
- - calculate_version
- strategy:
- matrix:
- include:
- - { arch: amd64 }
- - { arch: arm64 }
- - { arch: amd64, legacy_osx: true, legacy_name: "macos-10.13" }
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- - name: Setup Go
- if: ${{ ! matrix.legacy_osx }}
- uses: actions/setup-go@v5
- with:
- go-version: ^1.25.3
- - name: Cache Go for macOS 10.13
- if: matrix.legacy_osx
- id: cache-go-for-macos1013
- uses: actions/cache@v4
- with:
- path: |
- ~/go/go_osx
- key: go_osx_1258
- - name: Setup Go for macOS 10.13
- if: matrix.legacy_osx && steps.cache-go-for-macos1013.outputs.cache-hit != 'true'
- env:
- GITHUB_TOKEN: ${{ github.token }}
- run: |-
- .github/setup_go_for_macos1013.sh
- - name: Setup Go for macOS 10.13
- if: matrix.legacy_osx
- run: |-
- echo "PATH=$HOME/go/go_osx/bin:$PATH" >> $GITHUB_ENV
- echo "GOROOT=$HOME/go/go_osx" >> $GITHUB_ENV
- - name: Set tag
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- - name: Set build tags
- run: |
- set -xeuo pipefail
- if [[ "${{ matrix.legacy_osx }}" != "true" ]]; then
- TAGS=$(cat release/DEFAULT_BUILD_TAGS)
- else
- TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)
- fi
- echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
- - name: Set shared ldflags
- run: |
- echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "${GITHUB_ENV}"
- - name: Build
- run: |
- set -xeuo pipefail
- mkdir -p dist
- go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' ${LDFLAGS_SHARED} -s -w -buildid=" \
- ./cmd/sing-box
- env:
- CGO_ENABLED: "1"
- GOOS: darwin
- GOARCH: ${{ matrix.arch }}
- MACOSX_DEPLOYMENT_TARGET: ${{ matrix.legacy_osx && '10.13' || '' }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Set name
- run: |-
- DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-darwin-${{ matrix.arch }}"
- if [[ -n "${{ matrix.legacy_name }}" ]]; then
- DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
- fi
- echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
- - name: Archive
- run: |
- set -xeuo pipefail
- cd dist
- mkdir -p "${DIR_NAME}"
- cp ../LICENSE "${DIR_NAME}"
- cp sing-box "${DIR_NAME}"
- tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
- rm -r "${DIR_NAME}"
- - name: Cleanup
- run: rm dist/sing-box
- - name: Upload artifact
- uses: actions/upload-artifact@v4
- with:
- name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
- path: "dist"
- build_windows:
- name: Build Windows binaries
- if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
- runs-on: windows-latest
- needs:
- - calculate_version
- strategy:
- matrix:
- include:
- - { arch: amd64, naive: true }
- - { arch: "386" }
- - { arch: arm64, naive: true }
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version: ^1.25.4
- - name: Set tag
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- - name: Build
- if: matrix.naive
- run: |
- $TAGS = Get-Content release/DEFAULT_BUILD_TAGS_WINDOWS
- $LDFLAGS_SHARED = Get-Content release/LDFLAGS
- mkdir -p dist
- go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
- ./cmd/sing-box
- env:
- CGO_ENABLED: "0"
- GOOS: windows
- GOARCH: ${{ matrix.arch }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Build
- if: ${{ !matrix.naive }}
- run: |
- $TAGS = Get-Content release/DEFAULT_BUILD_TAGS_OTHERS
- $LDFLAGS_SHARED = Get-Content release/LDFLAGS
- mkdir -p dist
- go build -v -trimpath -o dist/sing-box.exe -tags "$TAGS" `
- -ldflags "-X 'github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }}' $LDFLAGS_SHARED -s -w -buildid=" `
- ./cmd/sing-box
- env:
- CGO_ENABLED: "0"
- GOOS: windows
- GOARCH: ${{ matrix.arch }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Extract libcronet.dll
- if: matrix.naive
- run: |
- $CRONET_GO_VERSION = Get-Content .github/CRONET_GO_VERSION
- $env:CGO_ENABLED = "0"
- go run -v "github.com/sagernet/cronet-go/cmd/build-naive@$CRONET_GO_VERSION" extract-lib --target windows/${{ matrix.arch }} -o dist
- - name: Archive
- if: matrix.naive
- run: |
- $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
- mkdir "dist/$DIR_NAME"
- Copy-Item LICENSE "dist/$DIR_NAME"
- Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
- Copy-Item "dist/libcronet.dll" "dist/$DIR_NAME"
- Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
- Remove-Item -Recurse "dist/$DIR_NAME"
- - name: Archive
- if: ${{ !matrix.naive }}
- run: |
- $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
- mkdir "dist/$DIR_NAME"
- Copy-Item LICENSE "dist/$DIR_NAME"
- Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
- Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
- Remove-Item -Recurse "dist/$DIR_NAME"
- - name: Cleanup
- if: matrix.naive
- run: Remove-Item dist/sing-box.exe, dist/libcronet.dll
- - name: Cleanup
- if: ${{ !matrix.naive }}
- run: Remove-Item dist/sing-box.exe
- - name: Upload artifact
- uses: actions/upload-artifact@v4
- with:
- name: binary-windows_${{ matrix.arch }}
- path: "dist"
- build_android:
- name: Build Android
- if: (github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android') && github.ref != 'refs/heads/oldstable'
- runs-on: ubuntu-latest
- needs:
- - calculate_version
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- submodules: 'recursive'
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version: ~1.25.9
- - name: Setup Android NDK
- id: setup-ndk
- uses: nttld/setup-ndk@v1
- with:
- ndk-version: r28
- - name: Setup OpenJDK
- run: |-
- sudo apt update && sudo apt install -y openjdk-17-jdk-headless
- /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- - name: Set tag
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- - name: Build library
- run: |-
- make lib_install
- export PATH="$PATH:$(go env GOPATH)/bin"
- make lib_android
- env:
- JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
- ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- - name: Checkout main branch
- if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
- run: |-
- cd clients/android
- git checkout main
- - name: Checkout dev branch
- if: github.ref == 'refs/heads/testing'
- run: |-
- cd clients/android
- git checkout dev
- - name: Gradle cache
- uses: actions/cache@v4
- with:
- path: ~/.gradle
- key: gradle-${{ hashFiles('**/*.gradle') }}
- - name: Update version
- if: github.event_name == 'workflow_dispatch'
- run: |-
- go run -v ./cmd/internal/update_android_version --ci
- - name: Update nightly version
- if: github.event_name != 'workflow_dispatch'
- run: |-
- go run -v ./cmd/internal/update_android_version --ci --nightly
- - name: Build
- run: |-
- mkdir clients/android/app/libs
- cp *.aar clients/android/app/libs
- cd clients/android
- ./gradlew :app:assembleOtherRelease :app:assembleOtherLegacyRelease
- env:
- JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
- ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
- - name: Prepare upload
- run: |-
- mkdir -p dist
- #cp clients/android/app/build/outputs/apk/play/release/*.apk dist
- cp clients/android/app/build/outputs/apk/other/release/*.apk dist
- cp clients/android/app/build/outputs/apk/otherLegacy/release/*.apk dist
- VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
- VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
- cat > dist/SFA-version-metadata.json << EOF
- {
- "version_code": ${VERSION_CODE},
- "version_name": "${VERSION_NAME}"
- }
- EOF
- cat dist/SFA-version-metadata.json
- - name: Upload artifact
- uses: actions/upload-artifact@v4
- with:
- name: binary-android-apks
- path: 'dist'
- publish_android:
- name: Publish Android
- if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android' && github.ref != 'refs/heads/oldstable'
- runs-on: ubuntu-latest
- needs:
- - calculate_version
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- submodules: 'recursive'
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version: ~1.25.9
- - name: Setup Android NDK
- id: setup-ndk
- uses: nttld/setup-ndk@v1
- with:
- ndk-version: r28
- - name: Setup OpenJDK
- run: |-
- sudo apt update && sudo apt install -y openjdk-17-jdk-headless
- /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
- - name: Set tag
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- - name: Build library
- run: |-
- make lib_install
- export PATH="$PATH:$(go env GOPATH)/bin"
- make lib_android
- env:
- JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
- ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- - name: Checkout main branch
- if: github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
- run: |-
- cd clients/android
- git checkout main
- - name: Checkout dev branch
- if: github.ref == 'refs/heads/testing'
- run: |-
- cd clients/android
- git checkout dev
- - name: Gradle cache
- uses: actions/cache@v4
- with:
- path: ~/.gradle
- key: gradle-${{ hashFiles('**/*.gradle') }}
- - name: Build
- run: |-
- go run -v ./cmd/internal/update_android_version --ci
- mkdir clients/android/app/libs
- cp *.aar clients/android/app/libs
- cd clients/android
- echo -n "$SERVICE_ACCOUNT_CREDENTIALS" | base64 --decode > service-account-credentials.json
- ./gradlew :app:publishPlayReleaseBundle
- env:
- JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
- ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
- LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
- SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
- build_apple:
- name: Build Apple clients
- runs-on: macos-26
- if: false # github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
- needs:
- - calculate_version
- strategy:
- matrix:
- include:
- - name: iOS
- if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
- platform: ios
- scheme: SFI
- destination: 'generic/platform=iOS'
- archive: build/SFI.xcarchive
- upload: SFI/Upload.plist
- - name: macOS
- if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
- platform: macos
- scheme: SFM
- destination: 'generic/platform=macOS'
- archive: build/SFM.xcarchive
- upload: SFI/Upload.plist
- - name: tvOS
- if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
- platform: tvos
- scheme: SFT
- destination: 'generic/platform=tvOS'
- archive: build/SFT.xcarchive
- upload: SFI/Upload.plist
- - name: macOS-standalone
- if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
- platform: macos
- scheme: SFM.System
- destination: 'generic/platform=macOS'
- archive: build/SFM.System.xcarchive
- export: SFM.System/Export.plist
- export_path: build/SFM.System
- steps:
- - name: Checkout
- if: matrix.if
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- submodules: 'recursive'
- - name: Setup Go
- if: matrix.if
- uses: actions/setup-go@v5
- with:
- go-version: ~1.25.9
- - name: Set tag
- if: matrix.if
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- - name: Checkout main branch
- if: matrix.if && github.ref == 'refs/heads/stable' && github.event_name != 'workflow_dispatch'
- run: |-
- cd clients/apple
- git checkout main
- - name: Checkout dev branch
- if: matrix.if && github.ref == 'refs/heads/testing'
- run: |-
- cd clients/apple
- git checkout dev
- - name: Setup certificates
- if: matrix.if
- run: |-
- CERTIFICATE_PATH=$RUNNER_TEMP/Certificates.p12
- KEYCHAIN_PATH=$RUNNER_TEMP/certificates.keychain-db
- echo -n "$CERTIFICATES_P12" | base64 --decode -o $CERTIFICATE_PATH
- security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
- security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
- security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
- security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
- security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
- security list-keychain -d user -s $KEYCHAIN_PATH
+ retention-days: 1
+ # build_darwin:
+ # name: Build Darwin binaries
+ # if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
+ # runs-on: macos-latest
+ # needs:
+ # - calculate_version
+ # strategy:
+ # matrix:
+ # include:
+ # - { arch: amd64 }
+ # - { arch: arm64 }
+ # - { arch: amd64, legacy_go124: true, legacy_name: "macos-11" }
+ # steps:
+ # - name: Checkout
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Setup Go
+ # if: ${{ ! matrix.legacy_go124 }}
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ^1.25.3
+ # - name: Setup Go 1.24
+ # if: matrix.legacy_go124
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ~1.24.6
+ # - name: Set tag
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # - name: Set build tags
+ # run: |
+ # set -xeuo pipefail
+ # TAGS='with_v2ray_api,with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0'
+ # if [[ "${{ matrix.legacy_go124 }}" != "true" ]]; then
+ # TAGS="${TAGS},with_naive_outbound"
+ # fi
+ # echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}"
+ # - name: Build
+ # run: |
+ # set -xeuo pipefail
+ # mkdir -p dist
+ # go build -v -trimpath -o dist/sing-box -tags "${BUILD_TAGS}" \
+ # -ldflags '-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0' \
+ # ./cmd/sing-box
+ # env:
+ # CGO_ENABLED: "1"
+ # GOOS: darwin
+ # GOARCH: ${{ matrix.arch }}
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # - name: Set name
+ # run: |-
+ # DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-darwin-${{ matrix.arch }}"
+ # if [[ -n "${{ matrix.legacy_name }}" ]]; then
+ # DIR_NAME="${DIR_NAME}-legacy-${{ matrix.legacy_name }}"
+ # fi
+ # echo "DIR_NAME=${DIR_NAME}" >> "${GITHUB_ENV}"
+ # - name: Archive
+ # run: |
+ # set -xeuo pipefail
+ # cd dist
+ # mkdir -p "${DIR_NAME}"
+ # cp ../LICENSE "${DIR_NAME}"
+ # cp sing-box "${DIR_NAME}"
+ # tar -czvf "${DIR_NAME}.tar.gz" "${DIR_NAME}"
+ # rm -r "${DIR_NAME}"
+ # - name: Cleanup
+ # run: rm dist/sing-box
+ # - name: Upload artifact
+ # uses: actions/upload-artifact@v4
+ # with:
+ # name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }}
+ # path: "dist"
+ # retention-days: 1
+ # build_windows:
+ # name: Build Windows binaries
+ # if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary'
+ # runs-on: windows-latest
+ # needs:
+ # - calculate_version
+ # strategy:
+ # matrix:
+ # include:
+ # - { arch: amd64, naive: true }
+ # - { arch: "386" }
+ # - { arch: arm64, naive: true }
+ # steps:
+ # - name: Checkout
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Setup Go
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ^1.25.4
+ # - name: Set tag
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$env:GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # - name: Build
+ # if: matrix.naive
+ # run: |
+ # mkdir -p dist
+ # go build -v -trimpath -o dist/sing-box.exe -tags "with_v2ray_api,with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0" `
+ # -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0" `
+ # ./cmd/sing-box
+ # env:
+ # CGO_ENABLED: "0"
+ # GOOS: windows
+ # GOARCH: ${{ matrix.arch }}
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # - name: Build
+ # if: ${{ !matrix.naive }}
+ # run: |
+ # mkdir -p dist
+ # go build -v -trimpath -o dist/sing-box.exe -tags "with_v2ray_api,with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0" `
+ # -ldflags "-s -buildid= -X github.com/sagernet/sing-box/constant.Version=${{ needs.calculate_version.outputs.version }} -X internal/godebug.defaultGODEBUG=multipathtcp=0 -checklinkname=0" `
+ # ./cmd/sing-box
+ # env:
+ # CGO_ENABLED: "0"
+ # GOOS: windows
+ # GOARCH: ${{ matrix.arch }}
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # - name: Extract libcronet.dll
+ # if: matrix.naive
+ # run: |
+ # $CRONET_GO_VERSION = Get-Content .github/CRONET_GO_VERSION
+ # $env:CGO_ENABLED = "0"
+ # go run -v "github.com/sagernet/cronet-go/cmd/build-naive@$CRONET_GO_VERSION" extract-lib --target windows/${{ matrix.arch }} -o dist
+ # - name: Archive
+ # if: matrix.naive
+ # run: |
+ # $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
+ # mkdir "dist/$DIR_NAME"
+ # Copy-Item LICENSE "dist/$DIR_NAME"
+ # Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
+ # Copy-Item "dist/libcronet.dll" "dist/$DIR_NAME"
+ # Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
+ # Remove-Item -Recurse "dist/$DIR_NAME"
+ # - name: Archive
+ # if: ${{ !matrix.naive }}
+ # run: |
+ # $DIR_NAME = "sing-box-${{ needs.calculate_version.outputs.version }}-windows-${{ matrix.arch }}"
+ # mkdir "dist/$DIR_NAME"
+ # Copy-Item LICENSE "dist/$DIR_NAME"
+ # Copy-Item "dist/sing-box.exe" "dist/$DIR_NAME"
+ # Compress-Archive -Path "dist/$DIR_NAME" -DestinationPath "dist/$DIR_NAME.zip"
+ # Remove-Item -Recurse "dist/$DIR_NAME"
+ # - name: Cleanup
+ # if: matrix.naive
+ # run: Remove-Item dist/sing-box.exe, dist/libcronet.dll
+ # - name: Cleanup
+ # if: ${{ !matrix.naive }}
+ # run: Remove-Item dist/sing-box.exe
+ # - name: Upload artifact
+ # uses: actions/upload-artifact@v4
+ # with:
+ # name: binary-windows_${{ matrix.arch }}
+ # path: "dist"
+ # retention-days: 1
+ # build_android:
+ # name: Build Android
+ # # if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android'
+ # if: false
+ # runs-on: ubuntu-latest
+ # needs:
+ # - calculate_version
+ # steps:
+ # - name: Checkout
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Setup Go
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ^1.25.6
+ # - name: Setup Android NDK
+ # id: setup-ndk
+ # uses: nttld/setup-ndk@v1
+ # with:
+ # ndk-version: r28
+ # - name: Setup OpenJDK
+ # run: |-
+ # sudo apt update && sudo apt install -y openjdk-17-jdk-headless
+ # /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
+ # - name: Set tag
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # - name: Build library
+ # run: |-
+ # make lib_install
+ # export PATH="$PATH:$(go env GOPATH)/bin"
+ # make lib_android
+ # env:
+ # JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
+ # ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+ # - name: Checkout main branch
+ # if: github.ref == 'refs/heads/main-next' && github.event_name != 'workflow_dispatch'
+ # run: |-
+ # cd clients/android
+ # git checkout main
+ # - name: Checkout dev branch
+ # if: github.ref == 'refs/heads/dev-next'
+ # run: |-
+ # cd clients/android
+ # git checkout dev
+ # - name: Gradle cache
+ # uses: actions/cache@v4
+ # with:
+ # path: ~/.gradle
+ # key: gradle-${{ hashFiles('**/*.gradle') }}
+ # - name: Update version
+ # if: github.event_name == 'workflow_dispatch'
+ # run: |-
+ # go run -v ./cmd/internal/update_android_version --ci
+ # - name: Update nightly version
+ # if: github.event_name != 'workflow_dispatch'
+ # run: |-
+ # go run -v ./cmd/internal/update_android_version --ci --nightly
+ # - name: Build
+ # run: |-
+ # mkdir clients/android/app/libs
+ # cp *.aar clients/android/app/libs
+ # cd clients/android
+ # ./gradlew :app:assembleOtherRelease :app:assembleOtherLegacyRelease
+ # env:
+ # JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
+ # ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+ # LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
+ # - name: Prepare upload
+ # run: |-
+ # mkdir -p dist
+ # #cp clients/android/app/build/outputs/apk/play/release/*.apk dist
+ # cp clients/android/app/build/outputs/apk/other/release/*.apk dist
+ # cp clients/android/app/build/outputs/apk/otherLegacy/release/*.apk dist
+ # VERSION_CODE=$(grep VERSION_CODE clients/android/version.properties | cut -d= -f2)
+ # VERSION_NAME=$(grep VERSION_NAME clients/android/version.properties | cut -d= -f2)
+ # cat > dist/SFA-version-metadata.json << EOF
+ # {
+ # "version_code": ${VERSION_CODE},
+ # "version_name": "${VERSION_NAME}"
+ # }
+ # EOF
+ # cat dist/SFA-version-metadata.json
+ # - name: Upload artifact
+ # uses: actions/upload-artifact@v4
+ # with:
+ # name: binary-android-apks
+ # path: 'dist'
+ # retention-days: 1
+ # publish_android:
- PROFILES_ZIP_PATH=$RUNNER_TEMP/Profiles.zip
- echo -n "$PROVISIONING_PROFILES" | base64 --decode -o $PROFILES_ZIP_PATH
+ # name: Publish Android
+ # # if: github.event_name == 'workflow_dispatch' && inputs.build == 'publish-android'
+ # if: false
+ # runs-on: ubuntu-latest
+ # needs:
+ # - calculate_version
+ # steps:
+ # - name: Checkout
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Setup Go
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ^1.25.6
+ # - name: Setup Android NDK
+ # id: setup-ndk
+ # uses: nttld/setup-ndk@v1
+ # with:
+ # ndk-version: r28
+ # - name: Setup OpenJDK
+ # run: |-
+ # sudo apt update && sudo apt install -y openjdk-17-jdk-headless
+ # /usr/lib/jvm/java-17-openjdk-amd64/bin/java --version
+ # - name: Set tag
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # - name: Build library
+ # run: |-
+ # make lib_install
+ # export PATH="$PATH:$(go env GOPATH)/bin"
+ # make lib_android
+ # env:
+ # JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
+ # ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+ # - name: Checkout main branch
+ # if: github.ref == 'refs/heads/main-next' && github.event_name != 'workflow_dispatch'
+ # run: |-
+ # cd clients/android
+ # git checkout main
+ # - name: Checkout dev branch
+ # if: github.ref == 'refs/heads/dev-next'
+ # run: |-
+ # cd clients/android
+ # git checkout dev
+ # - name: Gradle cache
+ # uses: actions/cache@v4
+ # with:
+ # path: ~/.gradle
+ # key: gradle-${{ hashFiles('**/*.gradle') }}
+ # - name: Build
+ # run: |-
+ # go run -v ./cmd/internal/update_android_version --ci
+ # mkdir clients/android/app/libs
+ # cp *.aar clients/android/app/libs
+ # cd clients/android
+ # echo -n "$SERVICE_ACCOUNT_CREDENTIALS" | base64 --decode > service-account-credentials.json
+ # ./gradlew :app:publishPlayReleaseBundle
+ # env:
+ # JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
+ # ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+ # LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
+ # SERVICE_ACCOUNT_CREDENTIALS: ${{ secrets.SERVICE_ACCOUNT_CREDENTIALS }}
+ # build_apple:
+ # name: Build Apple clients
+ # runs-on: macos-26
+ # if: false # github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store' || inputs.build == 'iOS' || inputs.build == 'macOS' || inputs.build == 'tvOS' || inputs.build == 'macOS-standalone'
+ # needs:
+ # - calculate_version
+ # strategy:
+ # matrix:
+ # include:
+ # - name: iOS
+ # if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'iOS' }}
+ # platform: ios
+ # scheme: SFI
+ # destination: 'generic/platform=iOS'
+ # archive: build/SFI.xcarchive
+ # upload: SFI/Upload.plist
+ # - name: macOS
+ # if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'macOS' }}
+ # platform: macos
+ # scheme: SFM
+ # destination: 'generic/platform=macOS'
+ # archive: build/SFM.xcarchive
+ # upload: SFI/Upload.plist
+ # - name: tvOS
+ # if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'app-store'|| inputs.build == 'tvOS' }}
+ # platform: tvos
+ # scheme: SFT
+ # destination: 'generic/platform=tvOS'
+ # archive: build/SFT.xcarchive
+ # upload: SFI/Upload.plist
+ # - name: macOS-standalone
+ # if: ${{ github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone' }}
+ # platform: macos
+ # scheme: SFM.System
+ # destination: 'generic/platform=macOS'
+ # archive: build/SFM.System.xcarchive
+ # export: SFM.System/Export.plist
+ # export_path: build/SFM.System
+ # steps:
+ # - name: Checkout
+ # if: matrix.if
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Setup Go
+ # if: matrix.if
+ # uses: actions/setup-go@v5
+ # with:
+ # go-version: ^1.25.6
+ # - name: Set tag
+ # if: matrix.if
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
+ # - name: Checkout main branch
+ # if: matrix.if && github.ref == 'refs/heads/main-next' && github.event_name != 'workflow_dispatch'
+ # run: |-
+ # cd clients/apple
+ # git checkout main
+ # - name: Checkout dev branch
+ # if: matrix.if && github.ref == 'refs/heads/dev-next'
+ # run: |-
+ # cd clients/apple
+ # git checkout dev
+ # - name: Setup certificates
+ # if: matrix.if
+ # run: |-
+ # CERTIFICATE_PATH=$RUNNER_TEMP/Certificates.p12
+ # KEYCHAIN_PATH=$RUNNER_TEMP/certificates.keychain-db
+ # echo -n "$CERTIFICATES_P12" | base64 --decode -o $CERTIFICATE_PATH
+ # security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
+ # security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
+ # security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
+ # security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
+ # security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
+ # security list-keychain -d user -s $KEYCHAIN_PATH
- PROFILES_PATH="$HOME/Library/MobileDevice/Provisioning Profiles"
- mkdir -p "$PROFILES_PATH"
- unzip $PROFILES_ZIP_PATH -d "$PROFILES_PATH"
+ # PROFILES_ZIP_PATH=$RUNNER_TEMP/Profiles.zip
+ # echo -n "$PROVISIONING_PROFILES" | base64 --decode -o $PROFILES_ZIP_PATH
- ASC_KEY_PATH=$RUNNER_TEMP/Key.p12
- echo -n "$ASC_KEY" | base64 --decode -o $ASC_KEY_PATH
+ # PROFILES_PATH="$HOME/Library/MobileDevice/Provisioning Profiles"
+ # mkdir -p "$PROFILES_PATH"
+ # unzip $PROFILES_ZIP_PATH -d "$PROFILES_PATH"
- xcrun notarytool store-credentials "notarytool-password" \
- --key $ASC_KEY_PATH \
- --key-id $ASC_KEY_ID \
- --issuer $ASC_KEY_ISSUER_ID
+ # ASC_KEY_PATH=$RUNNER_TEMP/Key.p12
+ # echo -n "$ASC_KEY" | base64 --decode -o $ASC_KEY_PATH
- echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
- echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
- echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
- env:
- CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
- P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
- KEYCHAIN_PASSWORD: ${{ secrets.P12_PASSWORD }}
- PROVISIONING_PROFILES: ${{ secrets.PROVISIONING_PROFILES }}
- ASC_KEY: ${{ secrets.ASC_KEY }}
- ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
- ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
- - name: Build library
- if: matrix.if
- run: |-
- make lib_install
- export PATH="$PATH:$(go env GOPATH)/bin"
- go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
- mv Libbox.xcframework clients/apple
- - name: Update macOS version
- if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
- run: |-
- MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
- echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
- echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
- - name: Update version
- if: matrix.if && matrix.name != 'iOS'
- run: |-
- go run -v ./cmd/internal/update_apple_version --ci
- - name: Build
- if: matrix.if
- run: |-
- cd clients/apple
- xcodebuild archive \
- -scheme "${{ matrix.scheme }}" \
- -configuration Release \
- -destination "${{ matrix.destination }}" \
- -archivePath "${{ matrix.archive }}" \
- -allowProvisioningUpdates \
- -authenticationKeyPath $ASC_KEY_PATH \
- -authenticationKeyID $ASC_KEY_ID \
- -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- - name: Upload to App Store Connect
- if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
- run: |-
- go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
- cd clients/apple
- xcodebuild -exportArchive \
- -archivePath "${{ matrix.archive }}" \
- -exportOptionsPlist ${{ matrix.upload }} \
- -allowProvisioningUpdates \
- -authenticationKeyPath $ASC_KEY_PATH \
- -authenticationKeyID $ASC_KEY_ID \
- -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
- - name: Publish to TestFlight
- if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/testing'
- run: |-
- go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
- - name: Build image
- if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
- run: |-
- pushd clients/apple
- xcodebuild -exportArchive \
- -archivePath "${{ matrix.archive }}" \
- -exportOptionsPlist ${{ matrix.export }} \
- -exportPath "${{ matrix.export_path }}"
- brew install create-dmg
- create-dmg \
- --volname "sing-box" \
- --volicon "${{ matrix.export_path }}/SFM.app/Contents/Resources/AppIcon.icns" \
- --icon "SFM.app" 0 0 \
- --hide-extension "SFM.app" \
- --app-drop-link 0 0 \
- --skip-jenkins \
- SFM.dmg "${{ matrix.export_path }}/SFM.app"
- xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
- cd "${{ matrix.archive }}"
- zip -r SFM.dSYMs.zip dSYMs
- popd
+ # xcrun notarytool store-credentials "notarytool-password" \
+ # --key $ASC_KEY_PATH \
+ # --key-id $ASC_KEY_ID \
+ # --issuer $ASC_KEY_ISSUER_ID
- mkdir -p dist
- cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
- cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
- - name: Upload image
- if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
- uses: actions/upload-artifact@v4
- with:
- name: binary-macos-dmg
- path: 'dist'
- upload:
- name: Upload builds
- if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
- runs-on: ubuntu-latest
- needs:
- - calculate_version
- - build
- - build_darwin
- - build_windows
- - build_android
- - build_apple
- steps:
- - name: Checkout
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- with:
- fetch-depth: 0
- - name: Cache ghr
- uses: actions/cache@v4
- id: cache-ghr
- with:
- path: |
- ~/go/bin/ghr
- key: ghr
- - name: Setup ghr
- if: steps.cache-ghr.outputs.cache-hit != 'true'
- run: |-
- cd $HOME
- git clone https://github.com/nekohasekai/ghr ghr
- cd ghr
- go install -v .
- - name: Set tag
- run: |-
- git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
- git tag v${{ needs.calculate_version.outputs.version }} -f
- echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
- - name: Download builds
- uses: actions/download-artifact@v5
- with:
- path: dist
- merge-multiple: true
- - name: Upload builds
- if: ${{ env.PUBLISHED == 'false' }}
- run: |-
- export PATH="$PATH:$HOME/go/bin"
- ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Replace builds
- if: ${{ env.PUBLISHED != 'false' }}
- run: |-
- export PATH="$PATH:$HOME/go/bin"
- ghr --replace -p 5 "v${VERSION}" dist
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # echo "ASC_KEY_PATH=$ASC_KEY_PATH" >> "$GITHUB_ENV"
+ # echo "ASC_KEY_ID=$ASC_KEY_ID" >> "$GITHUB_ENV"
+ # echo "ASC_KEY_ISSUER_ID=$ASC_KEY_ISSUER_ID" >> "$GITHUB_ENV"
+ # env:
+ # CERTIFICATES_P12: ${{ secrets.CERTIFICATES_P12 }}
+ # P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
+ # KEYCHAIN_PASSWORD: ${{ secrets.P12_PASSWORD }}
+ # PROVISIONING_PROFILES: ${{ secrets.PROVISIONING_PROFILES }}
+ # ASC_KEY: ${{ secrets.ASC_KEY }}
+ # ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
+ # ASC_KEY_ISSUER_ID: ${{ secrets.ASC_KEY_ISSUER_ID }}
+ # - name: Build library
+ # if: matrix.if
+ # run: |-
+ # make lib_install
+ # export PATH="$PATH:$(go env GOPATH)/bin"
+ # go run ./cmd/internal/build_libbox -target apple -platform ${{ matrix.platform }}
+ # mv Libbox.xcframework clients/apple
+ # - name: Update macOS version
+ # if: matrix.if && matrix.name == 'macOS' && github.event_name == 'workflow_dispatch'
+ # run: |-
+ # MACOS_PROJECT_VERSION=$(go run -v ./cmd/internal/app_store_connect next_macos_project_version)
+ # echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION"
+ # echo "MACOS_PROJECT_VERSION=$MACOS_PROJECT_VERSION" >> "$GITHUB_ENV"
+ # - name: Update version
+ # if: matrix.if && matrix.name != 'iOS'
+ # run: |-
+ # go run -v ./cmd/internal/update_apple_version --ci
+ # - name: Build
+ # if: matrix.if
+ # run: |-
+ # cd clients/apple
+ # xcodebuild archive \
+ # -scheme "${{ matrix.scheme }}" \
+ # -configuration Release \
+ # -destination "${{ matrix.destination }}" \
+ # -archivePath "${{ matrix.archive }}" \
+ # -allowProvisioningUpdates \
+ # -authenticationKeyPath $ASC_KEY_PATH \
+ # -authenticationKeyID $ASC_KEY_ID \
+ # -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
+ # - name: Upload to App Store Connect
+ # if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch'
+ # run: |-
+ # go run -v ./cmd/internal/app_store_connect cancel_app_store ${{ matrix.platform }}
+ # cd clients/apple
+ # xcodebuild -exportArchive \
+ # -archivePath "${{ matrix.archive }}" \
+ # -exportOptionsPlist ${{ matrix.upload }} \
+ # -allowProvisioningUpdates \
+ # -authenticationKeyPath $ASC_KEY_PATH \
+ # -authenticationKeyID $ASC_KEY_ID \
+ # -authenticationKeyIssuerID $ASC_KEY_ISSUER_ID
+ # - name: Publish to TestFlight
+ # if: matrix.if && matrix.name != 'macOS-standalone' && github.event_name == 'workflow_dispatch' && github.ref =='refs/heads/dev-next'
+ # run: |-
+ # go run -v ./cmd/internal/app_store_connect publish_testflight ${{ matrix.platform }}
+ # - name: Build image
+ # if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
+ # run: |-
+ # pushd clients/apple
+ # xcodebuild -exportArchive \
+ # -archivePath "${{ matrix.archive }}" \
+ # -exportOptionsPlist ${{ matrix.export }} \
+ # -exportPath "${{ matrix.export_path }}"
+ # brew install create-dmg
+ # create-dmg \
+ # --volname "sing-box" \
+ # --volicon "${{ matrix.export_path }}/SFM.app/Contents/Resources/AppIcon.icns" \
+ # --icon "SFM.app" 0 0 \
+ # --hide-extension "SFM.app" \
+ # --app-drop-link 0 0 \
+ # --skip-jenkins \
+ # SFM.dmg "${{ matrix.export_path }}/SFM.app"
+ # xcrun notarytool submit "SFM.dmg" --wait --keychain-profile "notarytool-password"
+ # cd "${{ matrix.archive }}"
+ # zip -r SFM.dSYMs.zip dSYMs
+ # popd
+
+ # mkdir -p dist
+ # cp clients/apple/SFM.dmg "dist/SFM-${VERSION}-universal.dmg"
+ # cp "clients/apple/${{ matrix.archive }}/SFM.dSYMs.zip" "dist/SFM-${VERSION}-universal.dSYMs.zip"
+ # - name: Upload image
+ # if: matrix.if && matrix.name == 'macOS-standalone' && github.event_name == 'workflow_dispatch'
+ # uses: actions/upload-artifact@v4
+ # with:
+ # name: binary-macos-dmg
+ # path: 'dist'
+ # retention-days: 1
+ # upload:
+ # name: Upload builds
+ # if: "!failure() && github.event_name == 'workflow_dispatch' && (inputs.build == 'All' || inputs.build == 'Binary' || inputs.build == 'Android' || inputs.build == 'Apple' || inputs.build == 'macOS-standalone')"
+ # runs-on: ubuntu-latest
+ # needs:
+ # - calculate_version
+ # - build
+ # - build_darwin
+ # - build_windows
+ # # - build_android
+ # # - build_apple
+ # steps:
+ # - name: Checkout
+ # uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ # with:
+ # fetch-depth: 0
+ # submodules: 'recursive'
+ # - name: Cache ghr
+ # uses: actions/cache@v4
+ # id: cache-ghr
+ # with:
+ # path: |
+ # ~/go/bin/ghr
+ # key: ghr
+ # - name: Setup ghr
+ # if: steps.cache-ghr.outputs.cache-hit != 'true'
+ # run: |-
+ # cd $HOME
+ # git clone https://github.com/nekohasekai/ghr ghr
+ # cd ghr
+ # go install -v .
+ # - name: Set tag
+ # run: |-
+ # git ls-remote --exit-code --tags origin v${{ needs.calculate_version.outputs.version }} || echo "PUBLISHED=false" >> "$GITHUB_ENV"
+ # git tag v${{ needs.calculate_version.outputs.version }} -f
+ # echo "VERSION=${{ needs.calculate_version.outputs.version }}" >> "$GITHUB_ENV"
+ # - name: Download builds
+ # uses: actions/download-artifact@v5
+ # with:
+ # path: dist
+ # merge-multiple: true
+ # - name: Upload builds
+ # if: ${{ env.PUBLISHED == 'false' }}
+ # run: |-
+ # export PATH="$PATH:$HOME/go/bin"
+ # ghr --replace --draft --prerelease -p 5 "v${VERSION}" dist
+ # env:
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # - name: Replace builds
+ # if: ${{ env.PUBLISHED != 'false' }}
+ # run: |-
+ # export PATH="$PATH:$HOME/go/bin"
+ # ghr --replace -p 5 "v${VERSION}" dist
+ # env:
+ # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 2ec65bdaf5..0ef3fe969f 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -55,7 +55,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
- go-version: ~1.25.9
+ go-version: ~1.25.10
- name: Clone cronet-go
if: matrix.naive
run: |
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 88c1a5fd5c..768ea56800 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -29,7 +29,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
- go-version: ~1.25.9
+ go-version: ~1.25.10
- name: Check input version
if: github.event_name == 'workflow_dispatch'
run: |-
@@ -72,7 +72,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v5
with:
- go-version: ~1.25.9
+ go-version: ~1.25.10
- name: Clone cronet-go
if: matrix.naive
run: |
@@ -216,6 +216,7 @@ jobs:
with:
name: binary-${{ matrix.os }}_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.legacy_go && '-legacy' || '' }}
path: "dist"
+ retention-days: 1
upload:
name: Upload builds
runs-on: ubuntu-latest
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000000..cc9ee0ad80
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,55 @@
+name: Test
+
+on:
+ push:
+ branches:
+ - stable
+ - testing
+ - unstable
+ paths-ignore:
+ - '**.md'
+ - '.github/**'
+ - '!.github/workflows/test.yml'
+ pull_request:
+ branches:
+ - stable
+ - testing
+ - unstable
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}-${{ inputs.build }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ name: Test
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - ubuntu-latest
+ - windows-latest
+ - macos-latest
+ go:
+ - ~1.24
+ - ~1.25
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+ - name: Setup Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: ${{ matrix.go }}
+ - name: Set build tags and ldflags
+ shell: bash
+ run: |
+ echo "BUILD_TAGS=$(cat release/DEFAULT_BUILD_TAGS_OTHERS)" >> "$GITHUB_ENV"
+ echo "LDFLAGS_SHARED=$(cat release/LDFLAGS)" >> "$GITHUB_ENV"
+ - name: Test (unix)
+ if: matrix.os != 'windows-latest'
+ run: go test -v -exec sudo -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
+ - name: Test (windows)
+ if: matrix.os == 'windows-latest'
+ shell: bash
+ run: go test -v -tags "$BUILD_TAGS" -ldflags "$LDFLAGS_SHARED" ./...
diff --git a/.gitignore b/.gitignore
index d2b74d08cd..e8ffb49298 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
+_htest/
+/data/*
+*.log
+*.db
/.idea/
/vendor/
/*.json
diff --git a/.gitmodules b/.gitmodules
index 45ffb5639b..0dadb791ea 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,12 @@
-[submodule "clients/apple"]
- path = clients/apple
- url = https://github.com/SagerNet/sing-box-for-apple.git
-[submodule "clients/android"]
- path = clients/android
- url = https://github.com/SagerNet/sing-box-for-android.git
+[submodule "replace/tailscale"]
+ path = replace/tailscale
+ url = git@github.com:hiddify/tailscale
+[submodule "replace/psiphon-quic-go"]
+ path = replace/psiphon-quic-go
+ url = git@github.com:hiddify/psiphon-quic-go
+[submodule "replace/psiphon-tls"]
+ path = replace/psiphon-tls
+ url = git@github.com:hiddify/psiphon-tls
+[submodule "replace/wireguard-go"]
+ path = replace/wireguard-go
+ url = git@github.com:hiddify/wireguard-go
diff --git a/.golangci.yml b/.golangci.yml
index 3f7fd94fb0..4991891518 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -18,7 +18,6 @@ linters:
default: none
enable:
- ineffassign
- - paralleltest
- staticcheck
- unused
- modernize
diff --git a/Makefile b/Makefile
index f78f39ede7..4234ddb178 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
NAME = sing-box
COMMIT = $(shell git rev-parse --short HEAD)
-TAGS ?= $(shell cat release/DEFAULT_BUILD_TAGS_OTHERS)
+TAGS ?= with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0,with_grpc,with_awg
GOHOSTOS = $(shell go env GOHOSTOS)
GOHOSTARCH = $(shell go env GOHOSTARCH)
@@ -36,17 +36,23 @@ install:
go build -o $(PREFIX)/bin/$(NAME) $(MAIN_PARAMS) $(MAIN)
fmt:
- @golangci-lint fmt
+ @gofumpt -l -w .
+ @gofmt -s -w .
+ @gci write --custom-order -s standard -s "prefix(github.com/sagernet/)" -s "default" .
fmt_docs:
go run ./cmd/internal/format_docs
+fmt_install:
+ go install -v mvdan.cc/gofumpt@latest
+ go install -v github.com/daixiang0/gci@latest
+
lint:
GOOS=linux golangci-lint run ./...
GOOS=android golangci-lint run ./...
GOOS=windows golangci-lint run ./...
GOOS=darwin golangci-lint run ./...
-# GOOS=freebsd golangci-lint run ./...
+ # GOOS=freebsd golangci-lint run ./...
lint_install:
go install -v github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
@@ -168,31 +174,14 @@ upload_macos_pkg:
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"
-replace_macos_pkg:
- mkdir -p dist/SFM
- cp ../sing-box-for-apple/build/SFM-Apple.pkg "dist/SFM/SFM-${VERSION}-Apple.pkg"
- cp ../sing-box-for-apple/build/SFM-Intel.pkg "dist/SFM/SFM-${VERSION}-Intel.pkg"
- cp ../sing-box-for-apple/build/SFM-Universal.pkg "dist/SFM/SFM-${VERSION}-Universal.pkg"
- ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Apple.pkg"
- ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Intel.pkg"
- ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}-Universal.pkg"
-
upload_macos_dsyms:
mkdir -p dist/SFM
cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
ghr --replace --draft --prerelease "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"
-replace_macos_dsyms:
- mkdir -p dist/SFM
- cd ../sing-box-for-apple/build/SFM.System-universal.xcarchive && zip -r SFM.dSYMs.zip dSYMs
- cp ../sing-box-for-apple/build/SFM.System-universal.xcarchive/SFM.dSYMs.zip "dist/SFM/SFM-${VERSION}.dSYMs.zip"
- ghr --replace "v${VERSION}" "dist/SFM/SFM-${VERSION}.dSYMs.zip"
-
release_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms
-replace_macos_standalone: build_macos_pkg notarize_macos_pkg upload_macos_pkg upload_macos_dsyms
-
build_tvos:
cd ../sing-box-for-apple && \
rm -rf build/SFT.xcarchive && \
diff --git a/README.md b/README.md
index 7b1c833a42..04ed0abb55 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,21 @@
-# sing-box
+# sing-box-extended
-The universal proxy platform.
+Sing-box with extended features.
-[](https://repology.org/project/sing-box/versions)
+## Features
-## Documentation
+* Amnezia 1.5
+* WARP
+* Tunneling
+* Mieru
+* XHTTP
+* SDNS (DNSCrypt)
+* Extended Wireguard options
+* Unified delay
-https://sing-box.sagernet.org
+## Examples
+
+https://github.com/shtorm-7/sing-box-extended/tree/extended/examples
## License
@@ -28,4 +37,4 @@ along with this program. If not, see .
In addition, no derivative work may use the name or imply association
with this application without prior consent.
-```
\ No newline at end of file
+```
diff --git a/adapter/certificate.go b/adapter/certificate.go
index 0998e1302a..dfed642dfd 100644
--- a/adapter/certificate.go
+++ b/adapter/certificate.go
@@ -10,6 +10,7 @@ import (
type CertificateStore interface {
LifecycleService
Pool() *x509.CertPool
+ ExclusiveAnchors() bool
}
func RootPoolFromContext(ctx context.Context) *x509.CertPool {
diff --git a/adapter/certificate/adapter.go b/adapter/certificate/adapter.go
new file mode 100644
index 0000000000..802020c1e4
--- /dev/null
+++ b/adapter/certificate/adapter.go
@@ -0,0 +1,21 @@
+package certificate
+
+type Adapter struct {
+ providerType string
+ providerTag string
+}
+
+func NewAdapter(providerType string, providerTag string) Adapter {
+ return Adapter{
+ providerType: providerType,
+ providerTag: providerTag,
+ }
+}
+
+func (a *Adapter) Type() string {
+ return a.providerType
+}
+
+func (a *Adapter) Tag() string {
+ return a.providerTag
+}
diff --git a/adapter/certificate/manager.go b/adapter/certificate/manager.go
new file mode 100644
index 0000000000..e4b9b535bb
--- /dev/null
+++ b/adapter/certificate/manager.go
@@ -0,0 +1,158 @@
+package certificate
+
+import (
+ "context"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/taskmonitor"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ F "github.com/sagernet/sing/common/format"
+)
+
+var _ adapter.CertificateProviderManager = (*Manager)(nil)
+
+type Manager struct {
+ logger log.ContextLogger
+ registry adapter.CertificateProviderRegistry
+ access sync.Mutex
+ started bool
+ stage adapter.StartStage
+ providers []adapter.CertificateProviderService
+ providerByTag map[string]adapter.CertificateProviderService
+}
+
+func NewManager(logger log.ContextLogger, registry adapter.CertificateProviderRegistry) *Manager {
+ return &Manager{
+ logger: logger,
+ registry: registry,
+ providerByTag: make(map[string]adapter.CertificateProviderService),
+ }
+}
+
+func (m *Manager) Start(stage adapter.StartStage) error {
+ m.access.Lock()
+ if m.started && m.stage >= stage {
+ panic("already started")
+ }
+ m.started = true
+ m.stage = stage
+ providers := m.providers
+ m.access.Unlock()
+ for _, provider := range providers {
+ name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
+ m.logger.Trace(stage, " ", name)
+ startTime := time.Now()
+ err := adapter.LegacyStart(provider, stage)
+ if err != nil {
+ return E.Cause(err, stage, " ", name)
+ }
+ m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
+ }
+ return nil
+}
+
+func (m *Manager) Close() error {
+ m.access.Lock()
+ defer m.access.Unlock()
+ if !m.started {
+ return nil
+ }
+ m.started = false
+ providers := m.providers
+ m.providers = nil
+ monitor := taskmonitor.New(m.logger, C.StopTimeout)
+ var err error
+ for _, provider := range providers {
+ name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
+ m.logger.Trace("close ", name)
+ startTime := time.Now()
+ monitor.Start("close ", name)
+ err = E.Append(err, provider.Close(), func(err error) error {
+ return E.Cause(err, "close ", name)
+ })
+ monitor.Finish()
+ m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
+ }
+ return err
+}
+
+func (m *Manager) CertificateProviders() []adapter.CertificateProviderService {
+ m.access.Lock()
+ defer m.access.Unlock()
+ return m.providers
+}
+
+func (m *Manager) Get(tag string) (adapter.CertificateProviderService, bool) {
+ m.access.Lock()
+ provider, found := m.providerByTag[tag]
+ m.access.Unlock()
+ return provider, found
+}
+
+func (m *Manager) Remove(tag string) error {
+ m.access.Lock()
+ provider, found := m.providerByTag[tag]
+ if !found {
+ m.access.Unlock()
+ return os.ErrInvalid
+ }
+ delete(m.providerByTag, tag)
+ index := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
+ return it == provider
+ })
+ if index == -1 {
+ panic("invalid certificate provider index")
+ }
+ m.providers = append(m.providers[:index], m.providers[index+1:]...)
+ started := m.started
+ m.access.Unlock()
+ if started {
+ return provider.Close()
+ }
+ return nil
+}
+
+func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error {
+ provider, err := m.registry.Create(ctx, logger, tag, providerType, options)
+ if err != nil {
+ return err
+ }
+ m.access.Lock()
+ defer m.access.Unlock()
+ if m.started {
+ name := "certificate-provider/" + provider.Type() + "[" + provider.Tag() + "]"
+ for _, stage := range adapter.ListStartStages {
+ m.logger.Trace(stage, " ", name)
+ startTime := time.Now()
+ err = adapter.LegacyStart(provider, stage)
+ if err != nil {
+ return E.Cause(err, stage, " ", name)
+ }
+ m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
+ }
+ }
+ if existsProvider, loaded := m.providerByTag[tag]; loaded {
+ if m.started {
+ err = existsProvider.Close()
+ if err != nil {
+ return E.Cause(err, "close certificate-provider/", existsProvider.Type(), "[", existsProvider.Tag(), "]")
+ }
+ }
+ existsIndex := common.Index(m.providers, func(it adapter.CertificateProviderService) bool {
+ return it == existsProvider
+ })
+ if existsIndex == -1 {
+ panic("invalid certificate provider index")
+ }
+ m.providers = append(m.providers[:existsIndex], m.providers[existsIndex+1:]...)
+ }
+ m.providers = append(m.providers, provider)
+ m.providerByTag[tag] = provider
+ return nil
+}
diff --git a/adapter/certificate/registry.go b/adapter/certificate/registry.go
new file mode 100644
index 0000000000..5a080f2ccc
--- /dev/null
+++ b/adapter/certificate/registry.go
@@ -0,0 +1,72 @@
+package certificate
+
+import (
+ "context"
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type ConstructorFunc[T any] func(ctx context.Context, logger log.ContextLogger, tag string, options T) (adapter.CertificateProviderService, error)
+
+func Register[Options any](registry *Registry, providerType string, constructor ConstructorFunc[Options]) {
+ registry.register(providerType, func() any {
+ return new(Options)
+ }, func(ctx context.Context, logger log.ContextLogger, tag string, rawOptions any) (adapter.CertificateProviderService, error) {
+ var options *Options
+ if rawOptions != nil {
+ options = rawOptions.(*Options)
+ }
+ return constructor(ctx, logger, tag, common.PtrValueOrDefault(options))
+ })
+}
+
+var _ adapter.CertificateProviderRegistry = (*Registry)(nil)
+
+type (
+ optionsConstructorFunc func() any
+ constructorFunc func(ctx context.Context, logger log.ContextLogger, tag string, options any) (adapter.CertificateProviderService, error)
+)
+
+type Registry struct {
+ access sync.Mutex
+ optionsType map[string]optionsConstructorFunc
+ constructor map[string]constructorFunc
+}
+
+func NewRegistry() *Registry {
+ return &Registry{
+ optionsType: make(map[string]optionsConstructorFunc),
+ constructor: make(map[string]constructorFunc),
+ }
+}
+
+func (m *Registry) CreateOptions(providerType string) (any, bool) {
+ m.access.Lock()
+ defer m.access.Unlock()
+ optionsConstructor, loaded := m.optionsType[providerType]
+ if !loaded {
+ return nil, false
+ }
+ return optionsConstructor(), true
+}
+
+func (m *Registry) Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) (adapter.CertificateProviderService, error) {
+ m.access.Lock()
+ defer m.access.Unlock()
+ constructor, loaded := m.constructor[providerType]
+ if !loaded {
+ return nil, E.New("certificate provider type not found: " + providerType)
+ }
+ return constructor(ctx, logger, tag, options)
+}
+
+func (m *Registry) register(providerType string, optionsConstructor optionsConstructorFunc, constructor constructorFunc) {
+ m.access.Lock()
+ defer m.access.Unlock()
+ m.optionsType[providerType] = optionsConstructor
+ m.constructor[providerType] = constructor
+}
diff --git a/adapter/certificate_darwin.go b/adapter/certificate_darwin.go
new file mode 100644
index 0000000000..ddcdb55f77
--- /dev/null
+++ b/adapter/certificate_darwin.go
@@ -0,0 +1,17 @@
+//go:build darwin && cgo
+
+package adapter
+
+import "unsafe"
+
+type AppleAnchors interface {
+ Retain() AppleAnchors
+ Release()
+ // Ref returns the underlying CFArrayRef, or nil if the anchor set is empty.
+ Ref() unsafe.Pointer
+}
+
+type AppleCertificateStore interface {
+ CertificateStore
+ AppleAnchors() AppleAnchors
+}
diff --git a/adapter/certificate_provider.go b/adapter/certificate_provider.go
new file mode 100644
index 0000000000..70bdeb8838
--- /dev/null
+++ b/adapter/certificate_provider.go
@@ -0,0 +1,38 @@
+package adapter
+
+import (
+ "context"
+ "crypto/tls"
+
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+)
+
+type CertificateProvider interface {
+ GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error)
+}
+
+type ACMECertificateProvider interface {
+ CertificateProvider
+ GetACMENextProtos() []string
+}
+
+type CertificateProviderService interface {
+ Lifecycle
+ Type() string
+ Tag() string
+ CertificateProvider
+}
+
+type CertificateProviderRegistry interface {
+ option.CertificateProviderOptionsRegistry
+ Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) (CertificateProviderService, error)
+}
+
+type CertificateProviderManager interface {
+ Lifecycle
+ CertificateProviders() []CertificateProviderService
+ Get(tag string) (CertificateProviderService, bool)
+ Remove(tag string) error
+ Create(ctx context.Context, logger log.ContextLogger, tag string, providerType string, options any) error
+}
diff --git a/adapter/dns.go b/adapter/dns.go
index 23fbc9def4..a613de0c44 100644
--- a/adapter/dns.go
+++ b/adapter/dns.go
@@ -3,6 +3,7 @@ package adapter
import (
"context"
"net/netip"
+ "time"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
@@ -25,35 +26,39 @@ type DNSRouter interface {
type DNSClient interface {
Start()
- Exchange(ctx context.Context, transport DNSTransport, message *dns.Msg, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) (*dns.Msg, error)
- Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) ([]netip.Addr, error)
+ Exchange(ctx context.Context, transport DNSTransport, message *dns.Msg, options DNSQueryOptions, responseChecker func(response *dns.Msg) bool) (*dns.Msg, error)
+ Lookup(ctx context.Context, transport DNSTransport, domain string, options DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error)
ClearCache()
}
type DNSQueryOptions struct {
- Transport DNSTransport
- Strategy C.DomainStrategy
- LookupStrategy C.DomainStrategy
- DisableCache bool
- RewriteTTL *uint32
- ClientSubnet netip.Prefix
+ Transport DNSTransport
+ Strategy C.DomainStrategy
+ LookupStrategy C.DomainStrategy
+ DisableCache bool
+ DisableOptimisticCache bool
+ RewriteTTL *uint32
+ Timeout time.Duration
+ ClientSubnet netip.Prefix
}
-func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (*DNSQueryOptions, error) {
- if options == nil {
- return &DNSQueryOptions{}, nil
+func DNSQueryOptionsFrom(ctx context.Context, options *option.DomainResolveOptions) (DNSQueryOptions, error) {
+ if options == nil || options.Server == "" {
+ return DNSQueryOptions{}, nil
}
transportManager := service.FromContext[DNSTransportManager](ctx)
transport, loaded := transportManager.Transport(options.Server)
if !loaded {
- return nil, E.New("domain resolver not found: " + options.Server)
+ return DNSQueryOptions{}, E.New("domain resolver not found: " + options.Server)
}
- return &DNSQueryOptions{
- Transport: transport,
- Strategy: C.DomainStrategy(options.Strategy),
- DisableCache: options.DisableCache,
- RewriteTTL: options.RewriteTTL,
- ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
+ return DNSQueryOptions{
+ Transport: transport,
+ Strategy: C.DomainStrategy(options.Strategy),
+ DisableCache: options.DisableCache,
+ DisableOptimisticCache: options.DisableOptimisticCache,
+ RewriteTTL: options.RewriteTTL,
+ Timeout: time.Duration(options.Timeout),
+ ClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
}, nil
}
@@ -63,6 +68,13 @@ type RDRCStore interface {
SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger)
}
+type DNSCacheStore interface {
+ LoadDNSCache(transportName string, qName string, qType uint16) (rawMessage []byte, expireAt time.Time, loaded bool)
+ SaveDNSCache(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time) error
+ SaveDNSCacheAsync(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time, logger logger.Logger)
+ ClearDNSCache() error
+}
+
type DNSTransport interface {
Lifecycle
Type() string
@@ -74,9 +86,9 @@ type DNSTransport interface {
Exchange(ctx context.Context, message *dns.Msg) (*dns.Msg, error)
}
-type LegacyDNSTransport interface {
- LegacyStrategy() C.DomainStrategy
- LegacyClientSubnet() netip.Prefix
+type DNSTransportWithPreferredDomain interface {
+ DNSTransport
+ PreferredDomain(domain string) bool
}
type DNSTransportRegistry interface {
diff --git a/adapter/endpoint/adapter.go b/adapter/endpoint/adapter.go
index c75e4d839c..dafe4dca01 100644
--- a/adapter/endpoint/adapter.go
+++ b/adapter/endpoint/adapter.go
@@ -1,6 +1,9 @@
package endpoint
-import "github.com/sagernet/sing-box/option"
+import (
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+)
type Adapter struct {
endpointType string
@@ -41,3 +44,11 @@ func (a *Adapter) Network() []string {
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
+
+func (a *Adapter) DisplayType() string {
+ return C.ProxyDisplayName(a.Type())
+}
+
+func (a *Adapter) IsReady() bool {
+ return true
+}
diff --git a/adapter/experimental.go b/adapter/experimental.go
index 1bd8d2d928..1fb51fac46 100644
--- a/adapter/experimental.go
+++ b/adapter/experimental.go
@@ -4,9 +4,9 @@ import (
"bytes"
"context"
"encoding/binary"
- "io"
"time"
+ "github.com/sagernet/sing-box/hiddify/ipinfo"
"github.com/sagernet/sing/common/observable"
"github.com/sagernet/sing/common/varbin"
)
@@ -21,15 +21,18 @@ type ClashServer interface {
}
type URLTestHistory struct {
- Time time.Time `json:"time"`
- Delay uint16 `json:"delay"`
+ Time time.Time `json:"time"`
+ Delay uint16 `json:"delay"`
+ IpInfo *ipinfo.IpInfo `json:"ipinfo"`
+ IsFromCache bool `json:"from_cache"`
}
type URLTestHistoryStorage interface {
SetHook(hook *observable.Subscriber[struct{}])
LoadURLTestHistory(tag string) *URLTestHistory
DeleteURLTestHistory(tag string)
- StoreURLTestHistory(tag string, history *URLTestHistory)
+ StoreURLTestHistory(tag string, history *URLTestHistory) *URLTestHistory
+ AddOnlyIpToHistory(tag string, history *URLTestHistory)
Close() error
}
@@ -47,6 +50,15 @@ type CacheFile interface {
StoreRDRC() bool
RDRCStore
+ StoreWARPConfig() bool
+ StoreMASQUEConfig() bool
+
+ StoreDNS() bool
+ DNSCacheStore
+
+ SetDisableExpire(disableExpire bool)
+ SetOptimisticTimeout(timeout time.Duration)
+
LoadMode() string
StoreMode(mode string) error
LoadSelected(group string) string
@@ -55,6 +67,8 @@ type CacheFile interface {
StoreGroupExpand(group string, expand bool) error
LoadRuleSet(tag string) *SavedBinary
SaveRuleSet(tag string, set *SavedBinary) error
+ LoadBinary(tag string) *SavedBinary
+ SaveBinary(tag string, set *SavedBinary) error
}
type SavedBinary struct {
@@ -69,11 +83,7 @@ func (s *SavedBinary) MarshalBinary() ([]byte, error) {
if err != nil {
return nil, err
}
- _, err = varbin.WriteUvarint(&buffer, uint64(len(s.Content)))
- if err != nil {
- return nil, err
- }
- _, err = buffer.Write(s.Content)
+ err = varbin.Write(&buffer, binary.BigEndian, s.Content)
if err != nil {
return nil, err
}
@@ -81,11 +91,7 @@ func (s *SavedBinary) MarshalBinary() ([]byte, error) {
if err != nil {
return nil, err
}
- _, err = varbin.WriteUvarint(&buffer, uint64(len(s.LastEtag)))
- if err != nil {
- return nil, err
- }
- _, err = buffer.WriteString(s.LastEtag)
+ err = varbin.Write(&buffer, binary.BigEndian, s.LastEtag)
if err != nil {
return nil, err
}
@@ -99,12 +105,7 @@ func (s *SavedBinary) UnmarshalBinary(data []byte) error {
if err != nil {
return err
}
- contentLength, err := binary.ReadUvarint(reader)
- if err != nil {
- return err
- }
- s.Content = make([]byte, contentLength)
- _, err = io.ReadFull(reader, s.Content)
+ err = varbin.Read(reader, binary.BigEndian, &s.Content)
if err != nil {
return err
}
@@ -114,16 +115,10 @@ func (s *SavedBinary) UnmarshalBinary(data []byte) error {
return err
}
s.LastUpdated = time.Unix(lastUpdated, 0)
- etagLength, err := binary.ReadUvarint(reader)
- if err != nil {
- return err
- }
- etagBytes := make([]byte, etagLength)
- _, err = io.ReadFull(reader, etagBytes)
+ err = varbin.Read(reader, binary.BigEndian, &s.LastEtag)
if err != nil {
return err
}
- s.LastEtag = string(etagBytes)
return nil
}
diff --git a/adapter/handler.go b/adapter/handler.go
index f8912110f9..4f54d18666 100644
--- a/adapter/handler.go
+++ b/adapter/handler.go
@@ -5,57 +5,31 @@ import (
"net"
"github.com/sagernet/sing/common/buf"
- E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
)
-// Deprecated
type ConnectionHandler interface {
- NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
+ NewConnection(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
-type ConnectionHandlerEx interface {
- NewConnectionEx(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
-}
-
-// Deprecated: use PacketHandlerEx instead
type PacketHandler interface {
- NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata InboundContext) error
+ NewPacket(buffer *buf.Buffer, source M.Socksaddr)
}
-type PacketHandlerEx interface {
- NewPacketEx(buffer *buf.Buffer, source M.Socksaddr)
+type PacketBatchHandler interface {
+ NewPacketBatch(buffers []*buf.Buffer, sources []M.Socksaddr)
}
-// Deprecated: use OOBPacketHandlerEx instead
type OOBPacketHandler interface {
- NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, oob []byte, metadata InboundContext) error
-}
-
-type OOBPacketHandlerEx interface {
- NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
+ NewPacket(buffer *buf.Buffer, oob []byte, source M.Socksaddr)
}
-// Deprecated
type PacketConnectionHandler interface {
- NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
+ NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
}
-type PacketConnectionHandlerEx interface {
- NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
-}
-
-// Deprecated: use TCPConnectionHandlerEx instead
-//
-//nolint:staticcheck
type UpstreamHandlerAdapter interface {
- N.TCPConnectionHandler
- N.UDPConnectionHandler
- E.Handler
-}
-
-type UpstreamHandlerAdapterEx interface {
N.TCPConnectionHandlerEx
N.UDPConnectionHandlerEx
}
diff --git a/adapter/http.go b/adapter/http.go
new file mode 100644
index 0000000000..3de4f1ce33
--- /dev/null
+++ b/adapter/http.go
@@ -0,0 +1,43 @@
+package adapter
+
+import (
+ "context"
+ "net/http"
+ "sync"
+
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/logger"
+)
+
+type HTTPTransport interface {
+ http.RoundTripper
+ CloseIdleConnections()
+ Reset()
+}
+
+type HTTPClientManager interface {
+ ResolveTransport(ctx context.Context, logger logger.ContextLogger, options option.HTTPClientOptions) (HTTPTransport, error)
+ DefaultTransport() HTTPTransport
+ ResetNetwork()
+}
+
+type HTTPStartContext struct {
+ access sync.Mutex
+ transports []HTTPTransport
+}
+
+func NewHTTPStartContext() *HTTPStartContext {
+ return &HTTPStartContext{}
+}
+
+func (c *HTTPStartContext) Register(transport HTTPTransport) {
+ c.access.Lock()
+ defer c.access.Unlock()
+ c.transports = append(c.transports, transport)
+}
+
+func (c *HTTPStartContext) Close() {
+ for _, transport := range c.transports {
+ transport.CloseIdleConnections()
+ }
+}
diff --git a/adapter/inbound.go b/adapter/inbound.go
index f047199e43..cfdf3d698c 100644
--- a/adapter/inbound.go
+++ b/adapter/inbound.go
@@ -2,13 +2,17 @@ package adapter
import (
"context"
+ "net"
"net/netip"
"time"
+ "github.com/sagernet/sing-box/common/tlsspoof"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
M "github.com/sagernet/sing/common/metadata"
+
+ "github.com/miekg/dns"
)
type Inbound interface {
@@ -19,12 +23,12 @@ type Inbound interface {
type TCPInjectableInbound interface {
Inbound
- ConnectionHandlerEx
+ ConnectionHandler
}
type UDPInjectableInbound interface {
Inbound
- PacketConnectionHandlerEx
+ PacketConnectionHandler
}
type InboundRegistry interface {
@@ -41,14 +45,16 @@ type InboundManager interface {
}
type InboundContext struct {
- Inbound string
- InboundType string
- IPVersion uint8
- Network string
- Source M.Socksaddr
- Destination M.Socksaddr
- User string
- Outbound string
+ Inbound string
+ InboundType string
+ IPVersion uint8
+ Network string
+ Source M.Socksaddr
+ Destination M.Socksaddr
+ TunnelSource string
+ TunnelDestination string
+ User string
+ Outbound string
// sniffer
@@ -65,25 +71,34 @@ type InboundContext struct {
InboundDetour string
LastInbound string
OriginDestination M.Socksaddr
- RouteOriginalDestination M.Socksaddr
+ RouteOriginalDestination M.Socksaddr
+ // Deprecated: to be removed
+ //nolint:staticcheck
+ InboundOptions option.InboundOptions
UDPDisableDomainUnmapping bool
UDPConnect bool
UDPTimeout time.Duration
TLSFragment bool
TLSFragmentFallbackDelay time.Duration
TLSRecordFragment bool
+ TLSSpoof string
+ TLSSpoofMethod tlsspoof.Method
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
FallbackDelay time.Duration
- DestinationAddresses []netip.Addr
- SourceGeoIPCode string
- GeoIPCode string
- ProcessInfo *ConnectionOwner
- QueryType uint16
- FakeIP bool
+ DestinationAddresses []netip.Addr
+ DNSResponse *dns.Msg
+ DestinationAddressMatchFromResponse bool
+ SourceGeoIPCode string
+ GeoIPCode string
+ ProcessInfo *ConnectionOwner
+ SourceMACAddress net.HardwareAddr
+ SourceHostname string
+ QueryType uint16
+ FakeIP bool
// rule cache
@@ -96,8 +111,16 @@ type InboundContext struct {
DestinationPortMatch bool
DidMatch bool
IgnoreDestinationIPCIDRMatch bool
+
+ RealOutbound string //H
}
+func (c *InboundContext) SetRealOutbound(tag string) {
+ c.RealOutbound = tag
+}
+func (c *InboundContext) GetRealOutbound() string {
+ return c.RealOutbound
+}
func (c *InboundContext) ResetRuleCache() {
c.IPCIDRMatchSource = false
c.IPCIDRAcceptEmpty = false
@@ -112,6 +135,51 @@ func (c *InboundContext) ResetRuleMatchCache() {
c.DidMatch = false
}
+func (c *InboundContext) DNSResponseAddressesForMatch() []netip.Addr {
+ return DNSResponseAddresses(c.DNSResponse)
+}
+
+func DNSResponseAddresses(response *dns.Msg) []netip.Addr {
+ if response == nil || response.Rcode != dns.RcodeSuccess {
+ return nil
+ }
+ addresses := make([]netip.Addr, 0, len(response.Answer))
+ for _, rawRecord := range response.Answer {
+ switch record := rawRecord.(type) {
+ case *dns.A:
+ addr := M.AddrFromIP(record.A)
+ if addr.IsValid() {
+ addresses = append(addresses, addr)
+ }
+ case *dns.AAAA:
+ addr := M.AddrFromIP(record.AAAA)
+ if addr.IsValid() {
+ addresses = append(addresses, addr)
+ }
+ case *dns.HTTPS:
+ for _, value := range record.SVCB.Value {
+ switch hint := value.(type) {
+ case *dns.SVCBIPv4Hint:
+ for _, ip := range hint.Hint {
+ addr := M.AddrFromIP(ip).Unmap()
+ if addr.IsValid() {
+ addresses = append(addresses, addr)
+ }
+ }
+ case *dns.SVCBIPv6Hint:
+ for _, ip := range hint.Hint {
+ addr := M.AddrFromIP(ip)
+ if addr.IsValid() {
+ addresses = append(addresses, addr)
+ }
+ }
+ }
+ }
+ }
+ }
+ return addresses
+}
+
type inboundContextKey struct{}
func WithContext(ctx context.Context, inboundContext *InboundContext) context.Context {
diff --git a/adapter/inbound_test.go b/adapter/inbound_test.go
new file mode 100644
index 0000000000..ec8c31289c
--- /dev/null
+++ b/adapter/inbound_test.go
@@ -0,0 +1,45 @@
+package adapter
+
+import (
+ "net"
+ "net/netip"
+ "testing"
+
+ "github.com/miekg/dns"
+ "github.com/stretchr/testify/require"
+)
+
+func TestDNSResponseAddressesUnmapsHTTPSIPv4Hints(t *testing.T) {
+ t.Parallel()
+
+ ipv4Hint := net.ParseIP("1.1.1.1")
+ require.NotNil(t, ipv4Hint)
+
+ response := &dns.Msg{
+ MsgHdr: dns.MsgHdr{
+ Response: true,
+ Rcode: dns.RcodeSuccess,
+ },
+ Answer: []dns.RR{
+ &dns.HTTPS{
+ SVCB: dns.SVCB{
+ Hdr: dns.RR_Header{
+ Name: dns.Fqdn("example.com"),
+ Rrtype: dns.TypeHTTPS,
+ Class: dns.ClassINET,
+ Ttl: 60,
+ },
+ Priority: 1,
+ Target: ".",
+ Value: []dns.SVCBKeyValue{
+ &dns.SVCBIPv4Hint{Hint: []net.IP{ipv4Hint}},
+ },
+ },
+ },
+ },
+ }
+
+ addresses := DNSResponseAddresses(response)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, addresses)
+ require.True(t, addresses[0].Is4())
+}
diff --git a/adapter/neighbor.go b/adapter/neighbor.go
new file mode 100644
index 0000000000..3115b2935d
--- /dev/null
+++ b/adapter/neighbor.go
@@ -0,0 +1,24 @@
+package adapter
+
+import (
+ "net"
+ "net/netip"
+)
+
+type NeighborEntry struct {
+ Address netip.Addr
+ MACAddress net.HardwareAddr
+ Hostname string
+}
+
+type NeighborResolver interface {
+ LookupMAC(address netip.Addr) (net.HardwareAddr, bool)
+ LookupHostname(address netip.Addr) (string, bool)
+ LookupAddresses(hostname string) []netip.Addr
+ Start() error
+ Close() error
+}
+
+type NeighborUpdateListener interface {
+ UpdateNeighborTable(entries []NeighborEntry)
+}
diff --git a/adapter/outbound.go b/adapter/outbound.go
index 91fb9c6505..b0933d59c6 100644
--- a/adapter/outbound.go
+++ b/adapter/outbound.go
@@ -7,7 +7,7 @@ import (
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing-tun"
+ tun "github.com/sagernet/sing-tun"
N "github.com/sagernet/sing/common/network"
)
@@ -18,6 +18,9 @@ type Outbound interface {
Tag() string
Network() []string
Dependencies() []string
+ DisplayType() string
+ IsReady() bool
+
N.Dialer
}
diff --git a/adapter/outbound/adapter.go b/adapter/outbound/adapter.go
index cd71527af5..c1d1ec33b6 100644
--- a/adapter/outbound/adapter.go
+++ b/adapter/outbound/adapter.go
@@ -1,6 +1,7 @@
package outbound
import (
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
)
@@ -43,3 +44,11 @@ func (a *Adapter) Network() []string {
func (a *Adapter) Dependencies() []string {
return a.dependencies
}
+
+func (a *Adapter) DisplayType() string {
+ return C.ProxyDisplayName(a.Type())
+}
+
+func (a *Adapter) IsReady() bool {
+ return true
+}
diff --git a/adapter/platform.go b/adapter/platform.go
index df1f447149..e574b885a8 100644
--- a/adapter/platform.go
+++ b/adapter/platform.go
@@ -40,6 +40,10 @@ type PlatformInterface interface {
SendNotification(notification *Notification) error
MyInterfaceAddress() []netip.Addr
+
+ UsePlatformNeighborResolver() bool
+ StartNeighborMonitor(listener NeighborUpdateListener) error
+ CloseNeighborMonitor(listener NeighborUpdateListener) error
}
type FindConnectionOwnerRequest struct {
diff --git a/adapter/router.go b/adapter/router.go
index 3d5310c4ee..24d45af006 100644
--- a/adapter/router.go
+++ b/adapter/router.go
@@ -2,17 +2,11 @@ package adapter
import (
"context"
- "crypto/tls"
"net"
- "net/http"
- "sync"
"time"
- C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-tun"
- M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/common/ntp"
"github.com/sagernet/sing/common/x/list"
"go4.org/netipx"
@@ -26,6 +20,8 @@ type Router interface {
RuleSet(tag string) (RuleSet, bool)
Rules() []Rule
NeedFindProcess() bool
+ NeedFindNeighbor() bool
+ NeighborResolver() NeighborResolver
AppendTracker(tracker ConnectionTracker)
ResetNetwork()
}
@@ -64,51 +60,20 @@ type RuleSet interface {
type RuleSetUpdateCallback func(it RuleSet)
-type RuleSetMetadata struct {
- ContainsProcessRule bool
- ContainsWIFIRule bool
- ContainsIPCIDRRule bool
-}
-type HTTPStartContext struct {
- ctx context.Context
- access sync.Mutex
- httpClientCache map[string]*http.Client
-}
-
-func NewHTTPStartContext(ctx context.Context) *HTTPStartContext {
- return &HTTPStartContext{
- ctx: ctx,
- httpClientCache: make(map[string]*http.Client),
- }
+type DNSRuleSetUpdateValidator interface {
+ ValidateRuleSetMetadataUpdate(tag string, metadata RuleSetMetadata) error
}
-func (c *HTTPStartContext) HTTPClient(detour string, dialer N.Dialer) *http.Client {
- c.access.Lock()
- defer c.access.Unlock()
- if httpClient, loaded := c.httpClientCache[detour]; loaded {
- return httpClient
- }
- httpClient := &http.Client{
- Transport: &http.Transport{
- ForceAttemptHTTP2: true,
- TLSHandshakeTimeout: C.TCPTimeout,
- DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
- return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
- },
- TLSClientConfig: &tls.Config{
- Time: ntp.TimeFuncFromContext(c.ctx),
- RootCAs: RootPoolFromContext(c.ctx),
- },
- },
- }
- c.httpClientCache[detour] = httpClient
- return httpClient
-}
-
-func (c *HTTPStartContext) Close() {
- c.access.Lock()
- defer c.access.Unlock()
- for _, client := range c.httpClientCache {
- client.CloseIdleConnections()
- }
+// ip_version is not a headless-rule item, so ContainsIPVersionRule is intentionally absent.
+type RuleSetMetadata struct {
+ ContainsProcessRule bool
+ ContainsWIFIRule bool
+ ContainsIPCIDRRule bool
+ ContainsDNSQueryTypeRule bool
+ // ContainsNonIPCIDRRule signals that the rule-set carries at least one sub-rule
+ // with a predicate other than destination ip_cidr / ip_set, so it can contribute
+ // to DNS pre-response matching. A rule-set where this is false and
+ // ContainsIPCIDRRule is true is "pure-IP" and matches nothing before a DNS
+ // response is available.
+ ContainsNonIPCIDRRule bool
}
diff --git a/adapter/rule.go b/adapter/rule.go
index f8ee797d44..d5612006ea 100644
--- a/adapter/rule.go
+++ b/adapter/rule.go
@@ -2,6 +2,8 @@ package adapter
import (
C "github.com/sagernet/sing-box/constant"
+
+ "github.com/miekg/dns"
)
type HeadlessRule interface {
@@ -18,8 +20,10 @@ type Rule interface {
type DNSRule interface {
Rule
+ LegacyPreMatch(metadata *InboundContext) bool
WithAddressLimit() bool
- MatchAddressLimit(metadata *InboundContext) bool
+ MatchAddressLimit(metadata *InboundContext, response *dns.Msg) bool
+ BypassIfFailed() bool
}
type RuleAction interface {
@@ -29,7 +33,7 @@ type RuleAction interface {
func IsFinalAction(action RuleAction) bool {
switch action.Type() {
- case C.RuleActionTypeSniff, C.RuleActionTypeResolve:
+ case C.RuleActionTypeSniff, C.RuleActionTypeResolve, C.RuleActionTypeEvaluate:
return false
default:
return true
diff --git a/adapter/tailscale.go b/adapter/tailscale.go
new file mode 100644
index 0000000000..e0ccb8ecda
--- /dev/null
+++ b/adapter/tailscale.go
@@ -0,0 +1,56 @@
+package adapter
+
+import "context"
+
+type TailscaleEndpoint interface {
+ SubscribeTailscaleStatus(ctx context.Context, fn func(*TailscaleEndpointStatus)) error
+ StartTailscalePing(ctx context.Context, peerIP string, fn func(*TailscalePingResult)) error
+ SetTailscaleExitNode(ctx context.Context, stableID string) error
+}
+
+type TailscalePingResult struct {
+ LatencyMs float64
+ IsDirect bool
+ Endpoint string
+ DERPRegionID int32
+ DERPRegionCode string
+ Error string
+}
+
+type TailscaleEndpointStatus struct {
+ BackendState string
+ AuthURL string
+ NetworkName string
+ MagicDNSSuffix string
+ Self *TailscalePeer
+ ExitNode *TailscalePeer
+ UserGroups []*TailscaleUserGroup
+}
+
+type TailscaleUserGroup struct {
+ UserID int64
+ LoginName string
+ DisplayName string
+ ProfilePicURL string
+ Peers []*TailscalePeer
+}
+
+type TailscalePeer struct {
+ StableID string
+ HostName string
+ DNSName string
+ OS string
+ TailscaleIPs []string
+ SSHHostKeys []string
+ Online bool
+ ExitNode bool
+ ExitNodeOption bool
+ ShareeNode bool
+ Expired bool
+ Active bool
+ RxBytes int64
+ TxBytes int64
+ UserID int64
+ KeyExpiry int64
+ LastSeen int64
+}
diff --git a/adapter/upstream.go b/adapter/upstream.go
index 59c8f75f6d..348e0ca8dc 100644
--- a/adapter/upstream.go
+++ b/adapter/upstream.go
@@ -9,31 +9,31 @@ import (
)
type (
- ConnectionHandlerFuncEx = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
- PacketConnectionHandlerFuncEx = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
+ ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext, onClose N.CloseHandlerFunc)
+ PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext, onClose N.CloseHandlerFunc)
)
-func NewUpstreamHandlerEx(
+func NewUpstreamHandler(
metadata InboundContext,
- connectionHandler ConnectionHandlerFuncEx,
- packetHandler PacketConnectionHandlerFuncEx,
-) UpstreamHandlerAdapterEx {
- return &myUpstreamHandlerWrapperEx{
+ connectionHandler ConnectionHandlerFunc,
+ packetHandler PacketConnectionHandlerFunc,
+) UpstreamHandlerAdapter {
+ return &myUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
-var _ UpstreamHandlerAdapterEx = (*myUpstreamHandlerWrapperEx)(nil)
+var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
-type myUpstreamHandlerWrapperEx struct {
+type myUpstreamHandlerWrapper struct {
metadata InboundContext
- connectionHandler ConnectionHandlerFuncEx
- packetHandler PacketConnectionHandlerFuncEx
+ connectionHandler ConnectionHandlerFunc
+ packetHandler PacketConnectionHandlerFunc
}
-func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (w *myUpstreamHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
@@ -44,7 +44,7 @@ func (w *myUpstreamHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn n
w.connectionHandler(ctx, conn, myMetadata, onClose)
}
-func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (w *myUpstreamHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
myMetadata := w.metadata
if source.IsValid() {
myMetadata.Source = source
@@ -55,24 +55,24 @@ func (w *myUpstreamHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context,
w.packetHandler(ctx, conn, myMetadata, onClose)
}
-var _ UpstreamHandlerAdapterEx = (*myUpstreamContextHandlerWrapperEx)(nil)
+var _ UpstreamHandlerAdapter = (*myUpstreamContextHandlerWrapper)(nil)
-type myUpstreamContextHandlerWrapperEx struct {
- connectionHandler ConnectionHandlerFuncEx
- packetHandler PacketConnectionHandlerFuncEx
+type myUpstreamContextHandlerWrapper struct {
+ connectionHandler ConnectionHandlerFunc
+ packetHandler PacketConnectionHandlerFunc
}
-func NewUpstreamContextHandlerEx(
- connectionHandler ConnectionHandlerFuncEx,
- packetHandler PacketConnectionHandlerFuncEx,
-) UpstreamHandlerAdapterEx {
- return &myUpstreamContextHandlerWrapperEx{
+func NewUpstreamContextHandler(
+ connectionHandler ConnectionHandlerFunc,
+ packetHandler PacketConnectionHandlerFunc,
+) UpstreamHandlerAdapter {
+ return &myUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
}
}
-func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (w *myUpstreamContextHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
@@ -83,7 +83,7 @@ func (w *myUpstreamContextHandlerWrapperEx) NewConnectionEx(ctx context.Context,
w.connectionHandler(ctx, conn, *myMetadata, onClose)
}
-func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (w *myUpstreamContextHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, myMetadata := ExtendContext(ctx)
if source.IsValid() {
myMetadata.Source = source
@@ -94,24 +94,24 @@ func (w *myUpstreamContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Co
w.packetHandler(ctx, conn, *myMetadata, onClose)
}
-func NewRouteHandlerEx(
+func NewRouteHandler(
metadata InboundContext,
router ConnectionRouterEx,
-) UpstreamHandlerAdapterEx {
- return &routeHandlerWrapperEx{
+) UpstreamHandlerAdapter {
+ return &routeHandlerWrapper{
metadata: metadata,
router: router,
}
}
-var _ UpstreamHandlerAdapterEx = (*routeHandlerWrapperEx)(nil)
+var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
-type routeHandlerWrapperEx struct {
+type routeHandlerWrapper struct {
metadata InboundContext
router ConnectionRouterEx
}
-func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (r *routeHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
@@ -121,7 +121,7 @@ func (r *routeHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Co
r.router.RouteConnectionEx(ctx, conn, r.metadata, onClose)
}
-func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (r *routeHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
if source.IsValid() {
r.metadata.Source = source
}
@@ -131,21 +131,21 @@ func (r *routeHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn
r.router.RoutePacketConnectionEx(ctx, conn, r.metadata, onClose)
}
-func NewRouteContextHandlerEx(
+func NewRouteContextHandler(
router ConnectionRouterEx,
-) UpstreamHandlerAdapterEx {
- return &routeContextHandlerWrapperEx{
+) UpstreamHandlerAdapter {
+ return &routeContextHandlerWrapper{
router: router,
}
}
-var _ UpstreamHandlerAdapterEx = (*routeContextHandlerWrapperEx)(nil)
+var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
-type routeContextHandlerWrapperEx struct {
+type routeContextHandlerWrapper struct {
router ConnectionRouterEx
}
-func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (r *routeContextHandlerWrapper) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
@@ -156,7 +156,7 @@ func (r *routeContextHandlerWrapperEx) NewConnectionEx(ctx context.Context, conn
r.router.RouteConnectionEx(ctx, conn, *metadata, onClose)
}
-func (r *routeContextHandlerWrapperEx) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+func (r *routeContextHandlerWrapper) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
_, metadata := ExtendContext(ctx)
if source.IsValid() {
metadata.Source = source
diff --git a/adapter/upstream_legacy.go b/adapter/upstream_legacy.go
index 65402563a4..c9320ddb80 100644
--- a/adapter/upstream_legacy.go
+++ b/adapter/upstream_legacy.go
@@ -12,21 +12,30 @@ import (
type (
// Deprecated
- ConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
+ LegacyConnectionHandlerFunc = func(ctx context.Context, conn net.Conn, metadata InboundContext) error
// Deprecated
- PacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
+ LegacyPacketConnectionHandlerFunc = func(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
)
// Deprecated
//
//nolint:staticcheck
-func NewUpstreamHandler(
+type LegacyUpstreamHandlerAdapter interface {
+ N.TCPConnectionHandler
+ N.UDPConnectionHandler
+ E.Handler
+}
+
+// Deprecated
+//
+//nolint:staticcheck
+func NewLegacyUpstreamHandler(
metadata InboundContext,
- connectionHandler ConnectionHandlerFunc,
- packetHandler PacketConnectionHandlerFunc,
+ connectionHandler LegacyConnectionHandlerFunc,
+ packetHandler LegacyPacketConnectionHandlerFunc,
errorHandler E.Handler,
-) UpstreamHandlerAdapter {
- return &myUpstreamHandlerWrapper{
+) LegacyUpstreamHandlerAdapter {
+ return &legacyUpstreamHandlerWrapper{
metadata: metadata,
connectionHandler: connectionHandler,
packetHandler: packetHandler,
@@ -34,20 +43,20 @@ func NewUpstreamHandler(
}
}
-var _ UpstreamHandlerAdapter = (*myUpstreamHandlerWrapper)(nil)
+var _ LegacyUpstreamHandlerAdapter = (*legacyUpstreamHandlerWrapper)(nil)
-// Deprecated: use myUpstreamHandlerWrapperEx instead.
+// Deprecated: use NewUpstreamHandler instead.
//
//nolint:staticcheck
-type myUpstreamHandlerWrapper struct {
+type legacyUpstreamHandlerWrapper struct {
metadata InboundContext
- connectionHandler ConnectionHandlerFunc
- packetHandler PacketConnectionHandlerFunc
+ connectionHandler LegacyConnectionHandlerFunc
+ packetHandler LegacyPacketConnectionHandlerFunc
errorHandler E.Handler
}
-// Deprecated: use myUpstreamHandlerWrapperEx instead.
-func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
+// Deprecated: use NewUpstreamHandler instead.
+func (w *legacyUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -58,8 +67,8 @@ func (w *myUpstreamHandlerWrapper) NewConnection(ctx context.Context, conn net.C
return w.connectionHandler(ctx, conn, myMetadata)
}
-// Deprecated: use myUpstreamHandlerWrapperEx instead.
-func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
+// Deprecated: use NewUpstreamHandler instead.
+func (w *legacyUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -70,8 +79,8 @@ func (w *myUpstreamHandlerWrapper) NewPacketConnection(ctx context.Context, conn
return w.packetHandler(ctx, conn, myMetadata)
}
-// Deprecated: use myUpstreamHandlerWrapperEx instead.
-func (w *myUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
+// Deprecated: use NewUpstreamHandler instead.
+func (w *legacyUpstreamHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
@@ -83,28 +92,28 @@ func UpstreamMetadata(metadata InboundContext) M.Metadata {
}
}
-// Deprecated: Use NewUpstreamContextHandlerEx instead.
-type myUpstreamContextHandlerWrapper struct {
- connectionHandler ConnectionHandlerFunc
- packetHandler PacketConnectionHandlerFunc
+// Deprecated: Use NewUpstreamContextHandler instead.
+type legacyUpstreamContextHandlerWrapper struct {
+ connectionHandler LegacyConnectionHandlerFunc
+ packetHandler LegacyPacketConnectionHandlerFunc
errorHandler E.Handler
}
-// Deprecated: Use NewUpstreamContextHandlerEx instead.
-func NewUpstreamContextHandler(
- connectionHandler ConnectionHandlerFunc,
- packetHandler PacketConnectionHandlerFunc,
+// Deprecated: Use NewUpstreamContextHandler instead.
+func NewLegacyUpstreamContextHandler(
+ connectionHandler LegacyConnectionHandlerFunc,
+ packetHandler LegacyPacketConnectionHandlerFunc,
errorHandler E.Handler,
-) UpstreamHandlerAdapter {
- return &myUpstreamContextHandlerWrapper{
+) LegacyUpstreamHandlerAdapter {
+ return &legacyUpstreamContextHandlerWrapper{
connectionHandler: connectionHandler,
packetHandler: packetHandler,
errorHandler: errorHandler,
}
}
-// Deprecated: Use NewUpstreamContextHandlerEx instead.
-func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
+// Deprecated: Use NewUpstreamContextHandler instead.
+func (w *legacyUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -115,8 +124,8 @@ func (w *myUpstreamContextHandlerWrapper) NewConnection(ctx context.Context, con
return w.connectionHandler(ctx, conn, *myMetadata)
}
-// Deprecated: Use NewUpstreamContextHandlerEx instead.
-func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
+// Deprecated: Use NewUpstreamContextHandler instead.
+func (w *legacyUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -127,18 +136,18 @@ func (w *myUpstreamContextHandlerWrapper) NewPacketConnection(ctx context.Contex
return w.packetHandler(ctx, conn, *myMetadata)
}
-// Deprecated: Use NewUpstreamContextHandlerEx instead.
-func (w *myUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
+// Deprecated: Use NewUpstreamContextHandler instead.
+func (w *legacyUpstreamContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.errorHandler.NewError(ctx, err)
}
// Deprecated: Use ConnectionRouterEx instead.
-func NewRouteHandler(
+func NewLegacyRouteHandler(
metadata InboundContext,
router ConnectionRouter,
logger logger.ContextLogger,
-) UpstreamHandlerAdapter {
- return &routeHandlerWrapper{
+) LegacyUpstreamHandlerAdapter {
+ return &legacyRouteHandlerWrapper{
metadata: metadata,
router: router,
logger: logger,
@@ -146,29 +155,29 @@ func NewRouteHandler(
}
// Deprecated: Use ConnectionRouterEx instead.
-func NewRouteContextHandler(
+func NewLegacyRouteContextHandler(
router ConnectionRouter,
logger logger.ContextLogger,
-) UpstreamHandlerAdapter {
- return &routeContextHandlerWrapper{
+) LegacyUpstreamHandlerAdapter {
+ return &legacyRouteContextHandlerWrapper{
router: router,
logger: logger,
}
}
-var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil)
+var _ LegacyUpstreamHandlerAdapter = (*legacyRouteHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
//
//nolint:staticcheck
-type routeHandlerWrapper struct {
+type legacyRouteHandlerWrapper struct {
metadata InboundContext
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
+func (w *legacyRouteHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -180,7 +189,7 @@ func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn,
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
+func (w *legacyRouteHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := w.metadata
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -192,20 +201,20 @@ func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.Pa
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) {
+func (w *legacyRouteHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
-var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil)
+var _ LegacyUpstreamHandlerAdapter = (*legacyRouteContextHandlerWrapper)(nil)
// Deprecated: Use ConnectionRouterEx instead.
-type routeContextHandlerWrapper struct {
+type legacyRouteContextHandlerWrapper struct {
router ConnectionRouter
logger logger.ContextLogger
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
+func (w *legacyRouteContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -217,7 +226,7 @@ func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
+func (w *legacyRouteContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
myMetadata := ContextFrom(ctx)
if metadata.Source.IsValid() {
myMetadata.Source = metadata.Source
@@ -229,6 +238,6 @@ func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, co
}
// Deprecated: Use ConnectionRouterEx instead.
-func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) {
+func (w *legacyRouteContextHandlerWrapper) NewError(ctx context.Context, err error) {
w.logger.ErrorContext(ctx, err)
}
diff --git a/box.go b/box.go
index c88a9bc9a8..cde22600d9 100644
--- a/box.go
+++ b/box.go
@@ -9,21 +9,27 @@ import (
"time"
"github.com/sagernet/sing-box/adapter"
+ boxCertificate "github.com/sagernet/sing-box/adapter/certificate"
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/adapter/inbound"
"github.com/sagernet/sing-box/adapter/outbound"
boxService "github.com/sagernet/sing-box/adapter/service"
"github.com/sagernet/sing-box/common/certificate"
"github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/httpclient"
+ "github.com/sagernet/sing-box/common/monitoring"
"github.com/sagernet/sing-box/common/taskmonitor"
"github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/common/urltest"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/experimental"
"github.com/sagernet/sing-box/experimental/cachefile"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/direct"
+ "github.com/sagernet/sing-box/protocol/hiddify/hinvalid"
"github.com/sagernet/sing-box/route"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
@@ -36,20 +42,22 @@ import (
var _ adapter.SimpleLifecycle = (*Box)(nil)
type Box struct {
- createdAt time.Time
- logFactory log.Factory
- logger log.ContextLogger
- network *route.NetworkManager
- endpoint *endpoint.Manager
- inbound *inbound.Manager
- outbound *outbound.Manager
- service *boxService.Manager
- dnsTransport *dns.TransportManager
- dnsRouter *dns.Router
- connection *route.ConnectionManager
- router *route.Router
- internalService []adapter.LifecycleService
- done chan struct{}
+ createdAt time.Time
+ logFactory log.Factory
+ logger log.ContextLogger
+ network *route.NetworkManager
+ endpoint *endpoint.Manager
+ inbound *inbound.Manager
+ outbound *outbound.Manager
+ service *boxService.Manager
+ certificateProvider *boxCertificate.Manager
+ dnsTransport *dns.TransportManager
+ dnsRouter *dns.Router
+ connection *route.ConnectionManager
+ router *route.Router
+ httpClientService adapter.LifecycleService
+ internalService []adapter.LifecycleService
+ done chan struct{}
}
type Options struct {
@@ -65,6 +73,7 @@ func Context(
endpointRegistry adapter.EndpointRegistry,
dnsTransportRegistry adapter.DNSTransportRegistry,
serviceRegistry adapter.ServiceRegistry,
+ certificateProviderRegistry adapter.CertificateProviderRegistry,
) context.Context {
if service.FromContext[option.InboundOptionsRegistry](ctx) == nil ||
service.FromContext[adapter.InboundRegistry](ctx) == nil {
@@ -89,6 +98,10 @@ func Context(
ctx = service.ContextWith[option.ServiceOptionsRegistry](ctx, serviceRegistry)
ctx = service.ContextWith[adapter.ServiceRegistry](ctx, serviceRegistry)
}
+ if service.FromContext[adapter.CertificateProviderRegistry](ctx) == nil {
+ ctx = service.ContextWith[option.CertificateProviderOptionsRegistry](ctx, certificateProviderRegistry)
+ ctx = service.ContextWith[adapter.CertificateProviderRegistry](ctx, certificateProviderRegistry)
+ }
return ctx
}
@@ -105,6 +118,7 @@ func New(options Options) (*Box, error) {
outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
dnsTransportRegistry := service.FromContext[adapter.DNSTransportRegistry](ctx)
serviceRegistry := service.FromContext[adapter.ServiceRegistry](ctx)
+ certificateProviderRegistry := service.FromContext[adapter.CertificateProviderRegistry](ctx)
if endpointRegistry == nil {
return nil, E.New("missing endpoint registry in context")
@@ -121,6 +135,9 @@ func New(options Options) (*Box, error) {
if serviceRegistry == nil {
return nil, E.New("missing service registry in context")
}
+ if certificateProviderRegistry == nil {
+ return nil, E.New("missing certificate provider registry in context")
+ }
ctx = pause.WithDefaultManager(ctx)
experimentalOptions := common.PtrValueOrDefault(options.Experimental)
@@ -140,6 +157,9 @@ func New(options Options) (*Box, error) {
if experimentalOptions.V2RayAPI != nil && experimentalOptions.V2RayAPI.Listen != "" {
needV2RayAPI = true
}
+ if experimentalOptions.UnifiedDelay != nil && experimentalOptions.UnifiedDelay.Enabled {
+ ctx = urltest.ContextWithIsUnifiedDelay(ctx)
+ }
platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
var defaultLogWriter io.Writer
if platformInterface != nil {
@@ -158,6 +178,7 @@ func New(options Options) (*Box, error) {
}
var internalServices []adapter.LifecycleService
+ routeOptions := common.PtrValueOrDefault(options.Route)
certificateOptions := common.PtrValueOrDefault(options.Certificate)
if C.IsAndroid || certificateOptions.Store != "" && certificateOptions.Store != C.CertificateStoreSystem ||
len(certificateOptions.Certificate) > 0 ||
@@ -170,21 +191,25 @@ func New(options Options) (*Box, error) {
service.MustRegister[adapter.CertificateStore](ctx, certificateStore)
internalServices = append(internalServices, certificateStore)
}
-
- routeOptions := common.PtrValueOrDefault(options.Route)
dnsOptions := common.PtrValueOrDefault(options.DNS)
endpointManager := endpoint.NewManager(logFactory.NewLogger("endpoint"), endpointRegistry)
inboundManager := inbound.NewManager(logFactory.NewLogger("inbound"), inboundRegistry, endpointManager)
outboundManager := outbound.NewManager(logFactory.NewLogger("outbound"), outboundRegistry, endpointManager, routeOptions.Final)
dnsTransportManager := dns.NewTransportManager(logFactory.NewLogger("dns/transport"), dnsTransportRegistry, outboundManager, dnsOptions.Final)
serviceManager := boxService.NewManager(logFactory.NewLogger("service"), serviceRegistry)
+ certificateProviderManager := boxCertificate.NewManager(logFactory.NewLogger("certificate-provider"), certificateProviderRegistry)
service.MustRegister[adapter.EndpointManager](ctx, endpointManager)
service.MustRegister[adapter.InboundManager](ctx, inboundManager)
service.MustRegister[adapter.OutboundManager](ctx, outboundManager)
service.MustRegister[adapter.DNSTransportManager](ctx, dnsTransportManager)
service.MustRegister[adapter.ServiceManager](ctx, serviceManager)
- dnsRouter := dns.NewRouter(ctx, logFactory, dnsOptions)
+ service.MustRegister[adapter.CertificateProviderManager](ctx, certificateProviderManager)
+ dnsRouter, err := dns.NewRouter(ctx, logFactory, dnsOptions)
+ if err != nil {
+ return nil, E.Cause(err, "initialize DNS router")
+ }
service.MustRegister[adapter.DNSRouter](ctx, dnsRouter)
+ service.MustRegister[adapter.DNSRuleSetUpdateValidator](ctx, dnsRouter)
networkManager, err := route.NewNetworkManager(ctx, logFactory.NewLogger("network"), routeOptions, dnsOptions)
if err != nil {
return nil, E.Cause(err, "initialize network manager")
@@ -192,6 +217,10 @@ func New(options Options) (*Box, error) {
service.MustRegister[adapter.NetworkManager](ctx, networkManager)
connectionManager := route.NewConnectionManager(logFactory.NewLogger("connection"))
service.MustRegister[adapter.ConnectionManager](ctx, connectionManager)
+ // Must register after ConnectionManager: the Apple HTTP engine's proxy bridge reads it from the context when Manager.Start resolves the default client.
+ httpClientManager := httpclient.NewManager(ctx, logFactory.NewLogger("httpclient"), options.HTTPClients, routeOptions.DefaultHTTPClient)
+ service.MustRegister[adapter.HTTPClientManager](ctx, httpClientManager)
+ httpClientService := adapter.LifecycleService(httpClientManager)
router := route.NewRouter(ctx, logFactory, routeOptions, dnsOptions)
service.MustRegister[adapter.Router](ctx, router)
err = router.Initialize(routeOptions.Rules, routeOptions.RuleSet)
@@ -271,6 +300,24 @@ func New(options Options) (*Box, error) {
return nil, E.Cause(err, "initialize inbound[", i, "]")
}
}
+ for i, serviceOptions := range options.Services {
+ var tag string
+ if serviceOptions.Tag != "" {
+ tag = serviceOptions.Tag
+ } else {
+ tag = F.ToString(i)
+ }
+ err = serviceManager.Create(
+ ctx,
+ logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
+ tag,
+ serviceOptions.Type,
+ serviceOptions.Options,
+ )
+ if err != nil {
+ return nil, E.Cause(err, "initialize service[", i, "]")
+ }
+ }
for i, outboundOptions := range options.Outbounds {
var tag string
if outboundOptions.Tag != "" {
@@ -297,22 +344,38 @@ func New(options Options) (*Box, error) {
return nil, E.Cause(err, "initialize outbound[", i, "]")
}
}
- for i, serviceOptions := range options.Services {
+ var invalidOutbound *hinvalid.Outbound
+ for _, outbound := range outboundManager.Outbounds() {
+ if outbound.Type() == C.TypeURLTest || outbound.Type() == C.TypeSelector || outbound.Type() == C.TypeDirect {
+ continue
+ }
+ if outbound.Type() == C.TypeHInvalidConfig {
+ invalidOutbound = outbound.(*hinvalid.Outbound)
+ continue
+ }
+ invalidOutbound = nil
+ break
+ }
+ if invalidOutbound != nil && invalidOutbound.InvalidOptions.Err != nil {
+ return nil, E.Cause(invalidOutbound.InvalidOptions.Err)
+ }
+
+ for i, certificateProviderOptions := range options.CertificateProviders {
var tag string
- if serviceOptions.Tag != "" {
- tag = serviceOptions.Tag
+ if certificateProviderOptions.Tag != "" {
+ tag = certificateProviderOptions.Tag
} else {
tag = F.ToString(i)
}
- err = serviceManager.Create(
+ err = certificateProviderManager.Create(
ctx,
- logFactory.NewLogger(F.ToString("service/", serviceOptions.Type, "[", tag, "]")),
+ logFactory.NewLogger(F.ToString("certificate-provider/", certificateProviderOptions.Type, "[", tag, "]")),
tag,
- serviceOptions.Type,
- serviceOptions.Options,
+ certificateProviderOptions.Type,
+ certificateProviderOptions.Options,
)
if err != nil {
- return nil, E.Cause(err, "initialize service[", i, "]")
+ return nil, E.Cause(err, "initialize certificate provider[", i, "]")
}
}
outboundManager.Initialize(func() (adapter.Outbound, error) {
@@ -333,6 +396,12 @@ func New(options Options) (*Box, error) {
&option.LocalDNSServerOptions{},
)
})
+ httpClientManager.Initialize(func() (*httpclient.ManagedTransport, error) {
+ deprecated.Report(ctx, deprecated.OptionImplicitDefaultHTTPClient)
+ var httpClientOptions option.HTTPClientOptions
+ httpClientOptions.DefaultOutbound = true
+ return httpclient.NewTransport(ctx, logFactory.NewLogger("httpclient"), "", httpClientOptions)
+ })
if platformInterface != nil {
err = platformInterface.Initialize(networkManager)
if err != nil {
@@ -340,7 +409,7 @@ func New(options Options) (*Box, error) {
}
}
if needCacheFile {
- cacheFile := cachefile.New(ctx, common.PtrValueOrDefault(experimentalOptions.CacheFile))
+ cacheFile := cachefile.New(ctx, logFactory.NewLogger("cache-file"), common.PtrValueOrDefault(experimentalOptions.CacheFile))
service.MustRegister[adapter.CacheFile](ctx, cacheFile)
internalServices = append(internalServices, cacheFile)
}
@@ -366,6 +435,15 @@ func New(options Options) (*Box, error) {
service.MustRegister[adapter.V2RayServer](ctx, v2rayServer)
}
}
+ monitor, err := monitoring.NewOutboundMonitoring(ctx, logFactory.NewLogger("monitoring"), common.PtrValueOrDefault(experimentalOptions.Monitoring))
+ if err != nil {
+ return nil, E.Cause(err, "create outbound monitoring")
+ }
+ internalServices = append(internalServices, monitor)
+ service.MustRegisterPtr[monitoring.OutboundMonitoring](ctx, monitor)
+
+ router.AppendTracker(monitor)
+
if ntpOptions.Enabled {
ntpDialer, err := dialer.New(ctx, ntpOptions.DialerOptions, ntpOptions.ServerIsDomain())
if err != nil {
@@ -383,20 +461,22 @@ func New(options Options) (*Box, error) {
internalServices = append(internalServices, adapter.NewLifecycleService(ntpService, "ntp service"))
}
return &Box{
- network: networkManager,
- endpoint: endpointManager,
- inbound: inboundManager,
- outbound: outboundManager,
- dnsTransport: dnsTransportManager,
- service: serviceManager,
- dnsRouter: dnsRouter,
- connection: connectionManager,
- router: router,
- createdAt: createdAt,
- logFactory: logFactory,
- logger: logFactory.Logger(),
- internalService: internalServices,
- done: make(chan struct{}),
+ network: networkManager,
+ endpoint: endpointManager,
+ inbound: inboundManager,
+ outbound: outboundManager,
+ dnsTransport: dnsTransportManager,
+ service: serviceManager,
+ certificateProvider: certificateProviderManager,
+ dnsRouter: dnsRouter,
+ connection: connectionManager,
+ router: router,
+ httpClientService: httpClientService,
+ createdAt: createdAt,
+ logFactory: logFactory,
+ logger: logFactory.Logger(),
+ internalService: internalServices,
+ done: make(chan struct{}),
}, nil
}
@@ -450,11 +530,19 @@ func (s *Box) preStart() error {
if err != nil {
return err
}
- err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service)
+ err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service, s.certificateProvider)
+ if err != nil {
+ return err
+ }
+ err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.network, s.connection)
if err != nil {
return err
}
- err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router)
+ err = adapter.StartNamed(s.logger, adapter.StartStateStart, []adapter.LifecycleService{s.httpClientService})
+ if err != nil {
+ return err
+ }
+ err = adapter.Start(s.logger, adapter.StartStateStart, s.router, s.dnsRouter)
if err != nil {
return err
}
@@ -470,11 +558,19 @@ func (s *Box) start() error {
if err != nil {
return err
}
- err = adapter.Start(s.logger, adapter.StartStateStart, s.inbound, s.endpoint, s.service)
+ err = adapter.Start(s.logger, adapter.StartStateStart, s.endpoint)
+ if err != nil {
+ return err
+ }
+ err = adapter.Start(s.logger, adapter.StartStateStart, s.certificateProvider)
+ if err != nil {
+ return err
+ }
+ err = adapter.Start(s.logger, adapter.StartStateStart, s.inbound, s.service)
if err != nil {
return err
}
- err = adapter.Start(s.logger, adapter.StartStatePostStart, s.outbound, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.inbound, s.endpoint, s.service)
+ err = adapter.Start(s.logger, adapter.StartStatePostStart, s.outbound, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.endpoint, s.certificateProvider, s.inbound, s.service)
if err != nil {
return err
}
@@ -482,7 +578,7 @@ func (s *Box) start() error {
if err != nil {
return err
}
- err = adapter.Start(s.logger, adapter.StartStateStarted, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service)
+ err = adapter.Start(s.logger, adapter.StartStateStarted, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.endpoint, s.certificateProvider, s.inbound, s.service)
if err != nil {
return err
}
@@ -500,14 +596,16 @@ func (s *Box) Close() error {
default:
close(s.done)
}
+ closeTimeout := time.Second * 10
var err error
for _, closeItem := range []struct {
name string
service adapter.Lifecycle
}{
{"service", s.service},
- {"endpoint", s.endpoint},
{"inbound", s.inbound},
+ {"certificate-provider", s.certificateProvider},
+ {"endpoint", s.endpoint},
{"outbound", s.outbound},
{"router", s.router},
{"connection", s.connection},
@@ -515,27 +613,55 @@ func (s *Box) Close() error {
{"dns-transport", s.dnsTransport},
{"network", s.network},
} {
- done := adapter.LogElapsed(s.logger, "close ", closeItem.name)
- err = E.Append(err, closeItem.service.Close(), func(err error) error {
+ cerr := s.closeWithTimeout(closeItem.name, closeTimeout, closeItem.service.Close)
+ err = E.Append(err, cerr, func(err error) error {
return E.Cause(err, "close ", closeItem.name)
})
- done()
+ }
+ if s.httpClientService != nil {
+ s.logger.Trace("close ", s.httpClientService.Name())
+ startTime := time.Now()
+ err = E.Append(err, s.httpClientService.Close(), func(err error) error {
+ return E.Cause(err, "close ", s.httpClientService.Name())
+ })
+ s.logger.Trace("close ", s.httpClientService.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
}
for _, lifecycleService := range s.internalService {
- done := adapter.LogElapsed(s.logger, "close ", lifecycleService.Name())
- err = E.Append(err, lifecycleService.Close(), func(err error) error {
+ cerr := s.closeWithTimeout(lifecycleService.Name(), closeTimeout, lifecycleService.Close)
+ err = E.Append(err, cerr, func(err error) error {
return E.Cause(err, "close ", lifecycleService.Name())
})
- done()
}
- done := adapter.LogElapsed(s.logger, "close logger")
- err = E.Append(err, s.logFactory.Close(), func(err error) error {
+ cerr := s.closeWithTimeout("logger", closeTimeout, s.logFactory.Close)
+ err = E.Append(err, cerr, func(err error) error {
return E.Cause(err, "close logger")
})
- done()
return err
}
+func (s *Box) closeWithTimeout(name string, timeout time.Duration, closeFn func() error) (err error) {
+ s.logger.Trace("closeing ", name)
+ startTime := time.Now()
+ defer func() {
+ if err != nil {
+ s.logger.Error("close ", name, " error (", F.Seconds(time.Since(startTime).Seconds()), "s)"+": "+err.Error())
+ } else {
+ s.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)")
+ }
+ }()
+ done := make(chan error, 1)
+
+ go func() {
+ done <- closeFn()
+ }()
+
+ select {
+ case err = <-done:
+ return err
+ case <-time.After(timeout):
+ return fmt.Errorf("close %s timed out after %s", name, timeout)
+ }
+}
func (s *Box) Network() adapter.NetworkManager {
return s.network
}
@@ -551,7 +677,6 @@ func (s *Box) Inbound() adapter.InboundManager {
func (s *Box) Outbound() adapter.OutboundManager {
return s.outbound
}
-
func (s *Box) Endpoint() adapter.EndpointManager {
return s.endpoint
}
@@ -559,3 +684,11 @@ func (s *Box) Endpoint() adapter.EndpointManager {
func (s *Box) LogFactory() log.Factory {
return s.logFactory
}
+
+func (s *Box) AddService(service adapter.LifecycleService) {
+ s.internalService = append(s.internalService, service)
+}
+
+func (s *Box) Logger() log.ContextLogger {
+ return s.logger
+}
diff --git a/clients/android b/clients/android
deleted file mode 160000
index 772879ce9c..0000000000
--- a/clients/android
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 772879ce9cd37c29e377d4d44d0efee12662948d
diff --git a/clients/apple b/clients/apple
deleted file mode 160000
index 3c3350ef9a..0000000000
--- a/clients/apple
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 3c3350ef9a94576cf78983fe115d603625b19651
diff --git a/cmd/hiddify/resolver/main.go b/cmd/hiddify/resolver/main.go
new file mode 100644
index 0000000000..4a6d90a8a4
--- /dev/null
+++ b/cmd/hiddify/resolver/main.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "net"
+ "os"
+ "strings"
+
+ _ "embed"
+
+ "github.com/oschwald/geoip2-golang"
+)
+
+//go:embed resolvers.txt
+var resolvers string
+
+func main() {
+ db, err := geoip2.Open("GeoLite2-Country.mmdb")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer db.Close()
+ added := map[string]struct{}{}
+ result := map[string][]string{}
+ for _, line := range strings.Split(resolvers, "\n") {
+ line = strings.TrimSpace(line)
+ if line == "" || line[0] == '#' {
+ continue
+ }
+
+ ip := net.ParseIP(line)
+ record, err := db.Country(ip)
+ if err != nil {
+ continue
+ }
+ country := record.Country.IsoCode
+ if _, ok := added[line]; !ok {
+ result[country] = append(result[country], line)
+ added[line] = struct{}{}
+ }
+ }
+
+ j, _ := json.MarshalIndent(result, "", " ")
+ fmt.Println(string(j))
+
+ os.WriteFile("ips_by_country.json", j, 0644)
+
+}
diff --git a/cmd/hiddify/resolver/resolvers.txt b/cmd/hiddify/resolver/resolvers.txt
new file mode 100644
index 0000000000..bfbdfd07f7
--- /dev/null
+++ b/cmd/hiddify/resolver/resolvers.txt
@@ -0,0 +1,58847 @@
+# Famous Public DNS Servers
+8.8.8.8
+8.8.4.4
+1.1.1.1
+1.0.0.1
+208.67.222.222
+208.67.220.220
+4.2.2.1
+4.2.2.2
+4.4.4.4
+156.154.70.1
+156.154.71.1
+80.80.80.80
+80.80.81.81
+9.9.9.9
+149.112.112.112
+9.9.9.10
+149.112.112.10
+9.9.9.11
+149.112.112.11
+94.140.14.14
+94.140.15.15
+94.140.14.15
+94.140.15.16
+94.140.14.140
+94.140.14.141
+194.242.2.2
+194.242.2.3
+1.1.1.2
+1.0.0.2
+1.1.1.3
+1.0.0.3
+76.76.2.0
+76.76.10.0
+76.76.19.19
+76.223.122.150
+76.76.26.0
+76.76.20.0
+8.26.56.26
+8.20.247.20
+185.228.168.9
+185.228.169.9
+185.228.168.168
+185.228.169.168
+185.228.168.10
+185.228.169.11
+77.88.8.8
+77.88.8.1
+223.5.5.5
+223.6.6.6
+180.76.76.76
+119.29.29.29
+101.101.101.101
+101.102.103.104
+64.6.64.6
+64.6.65.6
+84.200.69.80
+84.200.70.40
+109.69.8.51
+194.255.152.10
+194.255.62.80
+195.46.39.39
+195.46.39.40
+# SHUFFLE_BELOW
+185.181.182.209
+178.22.122.100
+185.51.200.2
+10.202.10.202
+10.202.10.102
+10.202.10.10
+10.202.10.11
+78.157.42.100
+78.157.42.101
+217.218.26.77
+217.218.26.78
+94.103.125.157
+94.103.125.158
+185.55.226.26
+185.55.225.25
+163.172.141.219
+2.144.4.108
+2.144.6.246
+2.144.6.65
+2.144.4.118
+2.144.7.149
+2.144.20.74
+2.144.20.109
+2.144.20.202
+2.184.239.88
+2.184.239.156
+5.160.12.250
+45.81.18.141
+46.245.90.90
+82.99.213.58
+82.99.213.59
+82.99.213.60
+82.99.213.61
+82.99.214.108
+91.92.208.152
+94.183.52.42
+102.22.81.183
+102.22.81.133
+185.49.84.2
+185.164.74.183
+2.144.4.190
+2.144.5.46
+2.144.5.118
+2.144.20.86
+2.144.22.69
+2.144.23.51
+2.144.23.148
+2.144.235.30
+207.246.121.77
+176.65.231.61
+185.129.118.121
+193.228.136.129
+5.202.255.21
+5.198.178.125
+91.106.67.82
+37.202.225.169
+45.156.185.200
+45.159.150.51
+37.202.225.166
+37.235.17.243
+45.90.74.47
+45.92.95.140
+45.138.132.115
+46.34.165.142
+37.235.17.247
+37.255.138.19
+45.9.255.21
+45.9.255.22
+45.92.93.203
+45.149.77.242
+45.159.150.210
+37.202.225.236
+45.149.79.172
+37.202.225.168
+37.202.237.245
+37.235.17.245
+37.255.219.35
+45.89.139.14
+45.129.38.78
+45.139.11.210
+45.149.77.44
+45.149.79.226
+45.156.185.106
+45.159.150.50
+46.34.162.68
+46.34.163.38
+46.34.165.238
+37.202.186.74
+45.142.191.135
+45.142.191.136
+46.167.142.120
+37.202.155.171
+45.129.39.7
+45.129.39.4
+45.129.39.3
+45.9.145.10
+45.129.39.2
+46.38.138.173
+46.100.12.186
+37.255.231.201
+45.94.214.12
+46.100.13.158
+46.100.5.135
+46.148.41.105
+46.100.94.168
+46.100.95.195
+46.100.11.49
+37.202.156.90
+45.142.191.5
+46.100.62.206
+37.202.237.244
+46.100.52.106
+37.202.180.163
+31.214.251.4
+31.214.251.31
+37.152.181.98
+37.191.85.6
+31.7.133.3
+31.7.133.2
+31.14.117.209
+31.214.174.104
+31.214.174.105
+31.214.251.33
+31.214.251.36
+31.214.251.34
+31.214.251.47
+31.214.251.50
+31.14.117.201
+31.14.117.208
+31.25.91.67
+31.214.168.234
+31.214.170.66
+31.214.170.254
+31.214.174.102
+31.214.174.103
+31.214.174.113
+31.214.251.29
+31.214.251.39
+31.214.251.44
+31.214.251.45
+31.214.251.53
+31.214.251.55
+31.214.251.59
+31.214.251.58
+37.32.13.229
+37.114.204.82
+37.156.144.92
+31.47.33.58
+31.214.168.82
+37.191.95.34
+31.214.174.106
+37.191.95.45
+31.47.46.77
+31.47.46.78
+37.156.31.94
+31.7.70.68
+37.148.82.26
+37.63.247.9
+31.130.181.233
+37.148.85.9
+37.148.57.40
+37.156.144.69
+37.148.51.30
+193.228.90.34
+185.140.58.2
+89.45.89.250
+185.165.30.119
+5.233.205.183
+2.144.3.168
+2.144.3.169
+2.144.3.170
+2.144.3.171
+2.144.3.172
+2.144.3.173
+2.144.4.8
+2.144.4.62
+2.144.4.217
+2.144.5.81
+2.144.5.181
+2.144.5.198
+2.144.6.46
+2.144.7.26
+2.144.7.218
+2.144.7.238
+2.144.20.5
+2.144.20.45
+2.144.20.224
+2.144.21.68
+2.144.21.92
+2.144.21.255
+2.144.22.135
+2.144.198.225
+2.144.231.18
+2.144.233.119
+2.144.245.252
+2.144.247.168
+2.176.71.248
+2.176.144.65
+2.176.160.155
+2.176.161.158
+2.176.163.232
+2.176.195.20
+2.176.195.71
+2.176.196.108
+2.176.203.68
+2.176.205.191
+2.176.207.244
+2.176.209.116
+2.176.211.93
+2.176.219.184
+2.176.219.209
+2.176.220.2
+2.176.231.32
+2.176.232.109
+2.176.235.135
+2.176.240.121
+2.176.246.138
+2.176.247.23
+2.176.250.23
+2.176.254.199
+2.176.255.78
+2.177.7.74
+2.177.11.130
+2.177.14.161
+2.177.24.181
+2.177.40.63
+2.177.42.167
+2.177.42.212
+2.177.43.58
+2.177.48.90
+2.177.50.76
+2.177.54.179
+2.177.58.132
+2.177.58.155
+2.177.69.242
+2.177.73.160
+2.177.73.244
+2.177.78.104
+2.177.80.237
+2.177.85.200
+2.177.96.175
+2.177.99.77
+2.177.109.173
+2.177.113.28
+2.177.117.230
+2.177.118.189
+2.177.120.14
+2.177.121.187
+2.177.126.254
+2.177.129.176
+2.177.133.217
+2.177.135.111
+2.177.139.223
+2.177.140.35
+2.177.152.158
+2.177.153.109
+2.177.155.185
+2.177.155.224
+2.177.156.192
+2.177.158.73
+2.177.158.225
+2.177.160.55
+2.177.164.229
+2.177.167.83
+2.177.167.170
+2.177.173.66
+2.177.173.87
+2.177.173.176
+2.177.175.244
+2.177.178.196
+2.177.183.65
+2.177.184.11
+2.177.187.16
+2.177.188.230
+2.177.189.84
+2.177.190.2
+2.177.192.190
+2.177.192.231
+2.177.195.151
+2.177.196.211
+2.177.197.243
+2.177.198.2
+2.177.198.159
+2.177.204.158
+2.177.204.186
+2.177.207.115
+2.177.213.224
+2.177.218.47
+2.177.220.95
+2.177.224.244
+2.177.228.67
+2.177.230.80
+2.177.237.182
+2.177.238.79
+2.177.239.150
+2.177.240.88
+2.177.242.177
+2.177.244.70
+2.177.245.77
+2.177.253.11
+2.177.254.249
+2.177.255.131
+2.178.0.24
+2.178.3.70
+2.178.4.229
+2.178.11.34
+2.178.11.72
+2.178.11.159
+2.178.11.241
+2.178.15.78
+2.178.15.130
+2.178.22.53
+2.178.22.146
+2.178.26.116
+2.178.26.206
+2.178.33.222
+2.178.36.242
+2.178.46.42
+2.178.49.12
+2.178.53.205
+2.178.61.247
+2.178.63.103
+2.178.66.121
+2.178.66.138
+2.178.68.58
+2.178.85.219
+2.178.98.210
+2.178.99.108
+2.178.104.149
+2.178.105.198
+2.178.106.212
+2.178.107.246
+2.178.111.223
+2.178.111.228
+2.178.114.218
+2.178.126.27
+2.178.139.88
+2.178.160.42
+2.178.173.175
+2.178.206.242
+2.178.212.180
+2.178.218.239
+2.178.225.41
+2.178.225.46
+2.178.240.181
+2.178.244.156
+2.178.245.219
+2.179.17.46
+2.179.73.249
+2.179.73.252
+2.179.164.1
+2.179.164.17
+2.179.164.92
+2.179.164.245
+2.179.165.2
+2.179.165.108
+2.179.166.51
+2.179.166.119
+2.179.186.165
+2.179.186.244
+2.179.194.7
+2.179.223.63
+2.179.245.7
+2.180.0.27
+2.180.1.139
+2.180.1.157
+2.180.2.5
+2.180.2.12
+2.180.2.71
+2.180.2.175
+2.180.2.188
+2.180.3.42
+2.180.7.125
+2.180.7.222
+2.180.7.223
+2.180.8.148
+2.180.10.251
+2.180.17.150
+2.180.17.221
+2.180.18.173
+2.180.18.229
+2.180.19.225
+2.180.25.216
+2.180.26.219
+2.180.29.30
+2.180.30.57
+2.180.30.220
+2.180.34.26
+2.180.34.44
+2.180.35.82
+2.180.35.201
+2.180.36.215
+2.180.39.20
+2.180.39.22
+2.180.39.66
+2.180.39.68
+2.180.40.1
+2.180.40.107
+2.180.42.106
+2.180.47.240
+2.180.140.252
+2.180.142.22
+2.180.145.231
+2.180.189.202
+2.180.201.34
+2.180.215.30
+2.181.30.33
+2.181.30.174
+2.181.30.231
+2.181.34.93
+2.181.80.30
+2.181.87.86
+2.181.105.236
+2.181.129.197
+2.181.195.225
+2.181.222.226
+2.181.234.50
+2.181.235.121
+2.181.247.240
+2.182.99.67
+2.182.109.129
+2.182.113.73
+2.182.128.170
+2.182.152.99
+2.182.154.64
+2.182.177.35
+2.182.189.113
+2.182.190.52
+2.182.194.1
+2.182.195.57
+2.182.213.73
+2.182.214.11
+2.182.214.126
+2.182.240.134
+2.182.242.139
+2.182.250.30
+2.182.250.161
+2.182.253.245
+2.182.253.246
+2.182.253.247
+2.183.8.180
+2.183.9.108
+2.183.9.110
+2.183.32.15
+2.183.32.109
+2.183.32.232
+2.183.95.185
+2.183.230.24
+2.184.30.252
+2.184.48.1
+2.184.49.134
+2.184.50.11
+2.184.70.68
+2.184.90.186
+2.184.112.150
+2.184.155.75
+2.184.236.106
+2.184.236.142
+2.144.2.8
+2.144.2.44
+2.144.2.154
+2.144.2.247
+2.144.4.30
+2.144.4.154
+2.144.4.254
+2.144.5.135
+2.144.5.186
+2.144.5.213
+2.144.5.245
+2.144.6.10
+2.144.6.48
+2.144.6.59
+2.144.6.112
+2.144.6.117
+2.144.6.207
+2.144.7.9
+2.144.7.68
+2.144.7.173
+2.144.13.3
+2.144.13.6
+2.144.14.3
+2.144.20.143
+2.144.20.147
+2.144.20.183
+2.144.20.212
+2.144.21.62
+2.144.21.115
+2.144.21.158
+2.144.21.219
+2.144.22.71
+2.144.22.101
+2.144.22.157
+2.144.22.188
+2.144.22.255
+2.144.23.53
+2.144.23.191
+2.144.23.215
+2.144.23.228
+2.144.24.5
+2.144.129.104
+2.144.129.133
+2.144.129.158
+2.144.129.253
+2.144.198.195
+2.144.198.207
+2.144.198.234
+2.144.198.236
+2.144.198.241
+2.144.198.242
+2.144.198.247
+2.144.230.61
+2.144.230.211
+2.144.231.46
+2.144.231.53
+2.144.231.66
+2.144.231.70
+2.144.231.71
+2.144.231.102
+2.144.231.135
+2.144.231.136
+2.144.231.137
+2.144.231.142
+2.144.231.144
+2.144.231.145
+2.144.231.155
+2.144.231.160
+2.144.231.161
+2.144.231.162
+2.144.231.169
+2.144.231.170
+2.144.231.171
+2.144.231.173
+2.144.231.175
+2.144.231.180
+2.144.231.182
+2.144.231.189
+2.144.231.192
+2.144.231.193
+2.144.231.195
+2.144.231.201
+2.144.231.202
+2.144.231.209
+2.144.231.214
+2.144.231.215
+2.144.231.218
+2.144.231.223
+2.144.231.225
+2.144.231.228
+2.144.231.233
+2.144.231.235
+2.144.231.239
+2.144.231.243
+2.144.231.245
+2.144.231.247
+2.144.231.248
+2.144.231.252
+2.144.232.8
+2.144.232.15
+2.144.232.24
+2.144.232.29
+2.144.232.33
+2.144.232.35
+2.144.232.36
+2.144.232.38
+2.144.232.49
+2.144.232.50
+2.144.232.51
+2.144.232.56
+2.144.232.59
+2.144.232.66
+2.144.232.68
+2.144.232.69
+2.144.232.78
+2.144.232.80
+2.144.232.83
+2.144.232.89
+2.144.232.90
+2.144.232.99
+2.144.232.100
+2.144.232.104
+2.144.232.108
+2.144.232.111
+2.144.232.112
+2.144.232.115
+2.144.232.120
+2.144.232.123
+2.144.232.125
+2.144.232.126
+2.144.232.127
+2.144.232.129
+2.144.232.130
+2.144.232.131
+2.144.232.134
+2.144.232.136
+2.144.232.141
+2.144.232.147
+2.144.232.148
+2.144.232.154
+2.144.232.156
+2.144.232.161
+2.144.232.162
+2.144.232.163
+2.144.232.164
+2.144.232.165
+2.144.232.169
+2.144.232.171
+2.144.232.173
+2.144.232.177
+2.144.232.180
+2.144.232.181
+2.144.232.184
+2.144.232.189
+2.144.232.191
+2.144.232.192
+2.144.232.196
+2.144.232.203
+2.144.232.205
+2.144.232.207
+2.144.232.210
+2.144.232.211
+2.144.232.214
+2.144.232.217
+2.144.232.219
+2.144.232.224
+2.144.233.26
+2.144.233.30
+2.144.233.40
+2.144.233.86
+2.144.233.148
+2.144.233.171
+2.144.233.235
+2.144.234.42
+2.144.234.53
+2.144.234.66
+2.144.234.75
+2.144.234.92
+2.144.234.97
+2.144.234.100
+2.144.234.101
+2.144.234.102
+2.144.234.104
+2.144.234.117
+2.144.234.123
+2.144.234.129
+2.144.234.130
+2.144.234.133
+2.144.234.136
+2.144.234.144
+2.144.234.145
+2.144.234.146
+2.144.234.151
+2.144.234.152
+2.144.234.155
+2.144.234.157
+2.144.234.209
+2.144.234.211
+2.144.234.213
+2.144.234.214
+2.144.234.219
+2.144.234.222
+2.144.234.225
+2.144.234.226
+2.144.234.228
+2.144.234.231
+2.144.234.235
+2.144.234.237
+2.144.234.241
+2.144.234.245
+2.144.234.247
+2.144.234.248
+2.144.234.252
+2.144.235.16
+2.144.235.25
+2.144.235.35
+2.144.235.39
+2.144.235.161
+2.144.235.197
+2.144.235.217
+2.144.235.219
+2.144.236.205
+2.144.236.245
+2.144.242.34
+2.144.242.62
+2.144.242.77
+2.144.242.84
+2.144.242.95
+2.144.242.123
+2.144.242.130
+2.144.242.148
+2.144.242.199
+2.144.242.225
+2.144.243.33
+2.144.243.35
+2.144.243.66
+2.144.243.76
+2.144.243.86
+2.144.243.92
+2.144.243.108
+2.144.243.109
+2.144.243.120
+2.144.243.160
+2.144.243.161
+2.144.243.162
+2.144.243.167
+2.144.243.191
+2.144.243.192
+2.144.243.200
+2.144.244.18
+2.144.244.27
+2.144.244.29
+2.144.244.30
+2.144.244.31
+2.144.244.32
+2.144.244.34
+2.144.244.35
+2.144.244.56
+2.144.244.60
+2.144.244.66
+2.144.244.68
+2.144.244.70
+2.144.244.72
+2.144.244.73
+2.144.244.78
+2.144.244.80
+2.144.244.81
+2.144.244.99
+2.144.244.121
+2.144.244.144
+2.144.244.148
+2.144.244.150
+2.144.244.151
+2.144.244.152
+2.144.244.153
+2.144.244.159
+2.144.244.223
+2.144.244.233
+2.144.245.0
+2.144.245.3
+2.144.245.15
+2.144.245.38
+2.144.245.42
+2.144.245.60
+2.144.245.61
+2.144.245.62
+2.144.245.66
+2.144.245.115
+2.144.245.119
+2.144.245.120
+2.144.245.123
+2.144.245.127
+2.144.245.130
+2.144.245.132
+2.144.245.148
+2.144.245.149
+2.144.245.154
+2.144.245.166
+2.144.245.167
+2.144.245.198
+2.144.245.213
+2.144.245.222
+2.144.245.230
+2.144.246.1
+2.144.246.22
+2.144.246.50
+2.144.246.86
+2.144.246.103
+2.144.246.106
+2.144.246.119
+2.144.246.147
+2.144.246.185
+2.144.246.187
+2.144.246.191
+2.144.246.202
+2.144.246.215
+2.144.246.226
+2.144.246.243
+2.144.247.14
+2.144.247.21
+2.144.247.29
+2.144.247.30
+2.144.247.34
+2.144.247.35
+2.144.247.42
+2.144.247.45
+2.144.247.47
+2.144.247.63
+2.144.247.66
+2.144.247.87
+2.144.247.93
+2.144.247.97
+2.144.247.118
+2.144.247.119
+2.144.247.121
+2.144.247.123
+2.144.247.137
+2.144.247.139
+2.144.247.140
+2.144.247.150
+2.144.247.155
+2.144.247.159
+2.144.247.161
+2.144.247.165
+2.144.247.169
+2.144.247.172
+2.144.247.176
+2.144.247.182
+2.144.247.185
+2.144.247.186
+2.144.247.190
+2.144.247.203
+2.144.247.211
+2.144.247.212
+2.144.247.216
+2.144.247.220
+2.144.247.224
+2.144.247.230
+2.144.247.232
+2.144.247.249
+2.144.248.188
+2.144.248.199
+2.144.248.200
+2.144.248.203
+2.144.248.206
+2.144.248.213
+2.144.248.214
+2.144.248.219
+2.144.248.220
+2.144.248.225
+2.144.248.231
+2.144.248.240
+2.144.248.245
+2.144.248.247
+2.144.248.249
+2.144.248.250
+2.144.248.252
+2.144.251.3
+2.144.251.13
+2.144.251.16
+2.144.251.24
+2.144.251.27
+2.144.251.28
+2.176.21.37
+2.176.42.197
+2.176.116.115
+2.176.128.221
+2.176.164.158
+2.176.165.86
+2.176.179.96
+2.176.186.208
+2.176.187.204
+2.176.193.184
+2.176.194.24
+2.176.195.168
+2.176.199.217
+2.176.199.235
+2.176.201.99
+2.176.201.140
+2.176.201.253
+2.176.203.2
+2.176.205.132
+2.176.207.56
+2.176.208.46
+2.176.208.115
+2.176.209.124
+2.176.210.22
+2.176.210.236
+2.176.210.237
+2.176.215.134
+2.176.216.158
+2.176.216.171
+2.176.217.52
+2.176.217.132
+2.176.218.194
+2.176.218.207
+2.176.219.211
+2.176.223.64
+2.176.227.61
+2.176.227.118
+2.176.229.49
+2.176.231.99
+2.176.233.44
+2.176.234.103
+2.176.236.16
+2.176.237.172
+2.176.238.81
+2.176.238.83
+2.176.240.89
+2.176.240.209
+2.176.240.211
+2.176.244.253
+2.176.245.66
+2.176.245.244
+2.176.247.16
+2.176.247.47
+2.176.247.227
+2.176.247.255
+2.176.248.53
+2.176.248.234
+2.176.249.176
+2.176.251.27
+2.176.253.225
+2.176.254.139
+2.177.2.85
+2.177.7.84
+2.177.7.167
+2.177.8.203
+2.177.10.196
+2.177.18.29
+2.177.18.92
+2.177.19.1
+2.177.19.79
+2.177.21.69
+2.177.22.188
+2.177.22.195
+2.177.23.80
+2.177.24.139
+2.177.25.36
+2.177.25.129
+2.177.26.95
+2.177.26.178
+2.177.27.105
+2.177.30.145
+2.177.31.65
+2.177.31.242
+2.177.33.173
+2.177.33.254
+2.177.36.221
+2.177.38.76
+2.177.38.200
+2.177.39.71
+2.177.40.221
+2.177.42.135
+2.177.45.39
+2.177.46.233
+2.177.47.128
+2.177.47.205
+2.177.48.53
+2.177.48.70
+2.177.48.192
+2.177.51.59
+2.177.51.245
+2.177.52.43
+2.177.55.195
+2.177.55.198
+2.177.56.85
+2.177.58.211
+2.177.62.61
+2.177.62.221
+2.177.64.71
+2.177.64.82
+2.177.65.14
+2.177.65.66
+2.177.65.254
+2.177.67.231
+2.177.68.185
+2.177.70.244
+2.177.71.230
+2.177.72.52
+2.177.72.131
+2.177.73.76
+2.177.75.187
+2.177.75.194
+2.177.76.190
+2.177.77.190
+2.177.78.6
+2.177.78.148
+2.177.81.249
+2.177.82.206
+2.177.84.66
+2.177.87.45
+2.177.88.165
+2.177.90.31
+2.177.92.10
+2.177.95.83
+2.177.97.83
+2.177.98.42
+2.177.98.52
+2.177.98.214
+2.177.99.87
+2.177.100.151
+2.177.101.8
+2.177.102.12
+2.177.102.121
+2.177.102.148
+2.177.103.111
+2.177.107.148
+2.177.108.101
+2.177.108.169
+2.177.109.68
+2.177.109.178
+2.177.112.192
+2.177.113.92
+2.177.113.104
+2.177.113.173
+2.177.114.42
+2.177.114.204
+2.177.120.54
+2.177.121.153
+2.177.122.60
+2.177.123.165
+2.177.123.175
+2.177.123.252
+2.177.124.28
+2.177.130.168
+2.177.130.178
+2.177.134.5
+2.177.134.191
+2.177.135.165
+2.177.136.126
+2.177.137.84
+2.177.137.129
+2.177.140.135
+2.177.142.153
+2.177.143.48
+2.177.147.178
+2.177.150.223
+2.177.151.90
+2.177.154.37
+2.177.154.43
+2.177.154.63
+2.177.155.21
+2.177.155.108
+2.177.156.85
+2.177.156.95
+2.177.158.139
+2.177.160.149
+2.177.161.136
+2.177.161.194
+2.177.162.138
+2.177.163.42
+2.177.165.215
+2.177.167.30
+2.177.167.187
+2.177.170.148
+2.177.174.202
+2.177.179.197
+2.177.179.238
+2.177.181.250
+2.177.183.104
+2.177.184.244
+2.177.186.48
+2.177.188.213
+2.177.189.81
+2.177.193.94
+2.177.193.107
+2.177.193.205
+2.177.194.248
+2.177.195.2
+2.177.195.160
+2.177.196.150
+2.177.200.2
+2.177.200.150
+2.177.201.168
+2.177.202.103
+2.177.203.198
+2.177.205.238
+2.177.205.254
+2.177.209.120
+2.177.210.254
+2.177.212.105
+2.177.213.171
+2.177.214.20
+2.177.217.23
+2.177.218.172
+2.177.219.102
+2.177.220.44
+2.177.221.239
+2.177.222.246
+2.177.223.37
+2.177.223.74
+2.177.223.126
+2.177.225.121
+2.177.230.85
+2.177.230.124
+2.177.236.183
+2.177.238.11
+2.177.240.0
+2.177.240.113
+2.177.241.158
+2.177.242.81
+2.177.245.73
+2.177.250.182
+2.177.250.254
+2.177.253.111
+2.177.254.11
+2.178.1.137
+2.178.1.221
+2.178.2.232
+2.178.6.39
+2.178.8.123
+2.178.10.182
+2.178.11.80
+2.178.19.80
+2.178.20.196
+2.178.23.207
+2.178.27.216
+2.178.29.125
+2.178.36.176
+2.178.39.162
+2.178.40.0
+2.178.42.135
+2.178.43.167
+2.178.43.177
+2.178.50.89
+2.178.52.212
+2.178.54.116
+2.178.56.133
+2.178.56.180
+2.178.57.65
+2.178.57.197
+2.178.58.161
+2.178.60.178
+2.178.61.124
+2.178.64.134
+2.178.67.184
+2.178.71.229
+2.178.74.58
+2.178.75.120
+2.178.77.245
+2.178.78.82
+2.178.79.27
+2.178.83.179
+2.178.83.239
+2.178.84.153
+2.178.85.165
+2.178.85.191
+2.178.86.146
+2.178.88.122
+2.178.88.151
+2.178.88.219
+2.178.91.16
+2.178.93.55
+2.178.94.143
+2.178.97.123
+2.178.98.188
+2.178.98.249
+2.178.99.41
+2.178.100.217
+2.178.102.112
+2.178.105.194
+2.178.107.38
+2.178.114.76
+2.178.115.196
+2.178.118.67
+2.178.118.154
+2.178.120.208
+2.178.123.127
+2.178.124.114
+2.178.124.191
+2.178.125.58
+2.178.127.45
+2.178.128.156
+2.178.128.208
+2.178.129.67
+2.178.129.134
+2.178.129.248
+2.178.133.61
+2.178.133.89
+2.178.133.230
+2.178.134.72
+2.178.134.128
+2.178.135.43
+2.178.135.46
+2.178.135.80
+2.178.135.231
+2.178.137.200
+2.178.138.95
+2.178.138.140
+2.178.139.21
+2.178.140.86
+2.178.141.40
+2.178.141.97
+2.178.142.75
+2.178.142.175
+2.178.142.191
+2.178.142.222
+2.178.143.8
+2.178.143.50
+2.178.143.150
+2.178.143.156
+2.178.144.235
+2.178.145.153
+2.178.146.150
+2.178.146.217
+2.178.147.40
+2.178.148.180
+2.178.149.81
+2.178.149.116
+2.178.149.214
+2.178.150.61
+2.178.150.148
+2.178.150.213
+2.178.151.104
+2.178.153.98
+2.178.153.123
+2.178.154.100
+2.178.155.46
+2.178.155.61
+2.178.155.244
+2.178.156.98
+2.178.156.131
+2.178.157.73
+2.178.157.199
+2.178.157.252
+2.178.158.3
+2.178.158.22
+2.178.159.106
+2.178.160.20
+2.178.160.151
+2.178.161.18
+2.178.162.119
+2.178.163.197
+2.178.165.65
+2.178.165.89
+2.178.165.104
+2.178.165.248
+2.178.166.36
+2.178.167.34
+2.178.167.128
+2.178.168.229
+2.178.169.84
+2.178.169.108
+2.178.170.11
+2.178.170.64
+2.178.170.156
+2.178.171.32
+2.178.171.118
+2.178.172.168
+2.178.176.141
+2.178.177.7
+2.178.178.85
+2.178.179.51
+2.178.179.82
+2.178.179.238
+2.178.180.124
+2.178.181.78
+2.178.183.12
+2.178.183.91
+2.178.185.82
+2.178.186.143
+2.178.186.167
+2.178.188.86
+2.178.189.245
+2.178.190.217
+2.178.192.138
+2.178.193.233
+2.178.194.16
+2.178.196.53
+2.178.198.161
+2.178.198.179
+2.178.199.33
+2.178.199.252
+2.178.200.98
+2.178.200.141
+2.178.200.181
+2.178.202.80
+2.178.202.167
+2.178.203.61
+2.178.203.80
+2.178.205.233
+2.178.206.148
+2.178.207.46
+2.178.207.157
+2.178.208.131
+2.178.209.140
+2.178.212.135
+2.178.212.192
+2.178.212.233
+2.178.213.105
+2.178.213.159
+2.178.214.118
+2.178.215.152
+2.178.216.16
+2.178.216.38
+2.178.217.48
+2.178.217.189
+2.178.217.239
+2.178.218.242
+2.178.219.107
+2.178.219.155
+2.178.221.5
+2.178.222.124
+2.178.223.189
+2.178.224.90
+2.178.225.229
+2.178.227.158
+2.178.228.40
+2.178.228.151
+2.178.228.180
+2.178.229.11
+2.178.229.163
+2.178.230.231
+2.178.230.236
+2.178.231.100
+2.178.231.105
+2.178.233.18
+2.178.233.48
+2.178.235.155
+2.178.235.186
+2.178.236.33
+2.178.237.75
+2.178.237.225
+2.178.238.36
+2.178.240.189
+2.178.241.66
+2.178.241.67
+2.178.241.112
+2.178.242.140
+2.178.243.42
+2.178.243.90
+2.178.244.9
+2.178.244.60
+2.178.245.80
+2.178.246.23
+2.178.247.0
+2.178.247.52
+2.178.248.71
+2.178.250.16
+2.178.250.220
+2.178.251.234
+2.178.253.22
+2.178.253.98
+2.178.253.156
+2.178.255.244
+2.179.12.162
+2.179.14.81
+2.179.15.62
+2.179.15.121
+2.179.25.28
+2.179.25.190
+2.179.26.186
+2.179.26.196
+2.179.27.169
+2.179.27.182
+2.179.27.201
+2.179.28.221
+2.179.40.201
+2.179.41.31
+2.179.41.78
+2.179.41.207
+2.179.42.76
+2.179.42.172
+2.179.42.237
+2.179.43.57
+2.179.44.136
+2.179.45.126
+2.179.46.67
+2.179.46.124
+2.179.46.191
+2.179.47.35
+2.179.47.160
+2.179.60.25
+2.179.60.59
+2.179.60.71
+2.179.60.164
+2.179.60.168
+2.179.60.198
+2.179.60.221
+2.179.64.18
+2.179.64.30
+2.179.64.63
+2.179.64.96
+2.179.64.108
+2.179.66.33
+2.179.67.52
+2.179.67.104
+2.179.70.18
+2.179.70.48
+2.179.72.74
+2.179.72.78
+2.179.72.80
+2.179.73.171
+2.179.76.79
+2.179.78.50
+2.179.80.40
+2.179.86.249
+2.179.87.38
+2.179.87.48
+2.179.87.243
+2.179.91.5
+2.179.93.32
+2.179.93.72
+2.179.93.76
+2.179.93.79
+2.179.93.104
+2.179.95.129
+2.179.95.226
+2.179.100.135
+2.179.108.1
+2.179.109.5
+2.179.109.135
+2.179.111.167
+2.179.113.188
+2.179.114.132
+2.179.114.231
+2.179.117.246
+2.179.118.31
+2.179.118.97
+2.179.118.204
+2.179.125.52
+2.179.125.209
+2.179.127.48
+2.179.162.88
+2.179.162.194
+2.179.163.131
+2.179.164.6
+2.179.164.32
+2.179.164.69
+2.179.164.79
+2.179.164.90
+2.179.164.130
+2.179.164.157
+2.179.164.243
+2.179.165.56
+2.179.165.80
+2.179.165.87
+2.179.165.152
+2.179.165.203
+2.179.165.229
+2.179.166.17
+2.179.166.57
+2.179.166.58
+2.179.166.121
+2.179.166.159
+2.179.166.211
+2.179.167.14
+2.179.167.53
+2.179.167.60
+2.179.167.73
+2.179.167.75
+2.179.167.92
+2.179.167.110
+2.179.167.133
+2.179.167.134
+2.179.167.168
+2.179.167.221
+2.179.167.249
+2.179.176.209
+2.179.176.248
+2.179.176.249
+2.179.176.250
+2.179.176.251
+2.179.176.253
+2.179.178.33
+2.179.178.113
+2.179.179.118
+2.179.179.158
+2.179.179.234
+2.179.179.242
+2.179.179.250
+2.179.184.38
+2.179.186.44
+2.179.186.101
+2.179.186.171
+2.179.186.184
+2.179.186.202
+2.179.186.213
+2.179.187.23
+2.179.187.34
+2.179.189.112
+2.179.189.124
+2.179.189.141
+2.179.193.59
+2.179.194.89
+2.179.194.186
+2.179.194.203
+2.179.194.208
+2.179.194.244
+2.179.194.251
+2.179.209.128
+2.179.209.207
+2.179.210.133
+2.179.210.171
+2.179.210.254
+2.179.211.199
+2.179.212.157
+2.179.213.183
+2.179.215.93
+2.179.216.109
+2.179.216.197
+2.179.219.18
+2.179.220.45
+2.179.223.163
+2.179.223.218
+2.179.235.134
+2.180.0.49
+2.180.0.52
+2.180.0.55
+2.180.0.64
+2.180.0.65
+2.180.0.83
+2.180.0.116
+2.180.0.150
+2.180.0.173
+2.180.0.210
+2.180.1.43
+2.180.1.73
+2.180.1.88
+2.180.1.94
+2.180.1.159
+2.180.1.168
+2.180.1.243
+2.180.2.36
+2.180.2.72
+2.180.2.107
+2.180.2.116
+2.180.2.154
+2.180.3.38
+2.180.3.197
+2.180.3.252
+2.180.4.19
+2.180.4.44
+2.180.4.54
+2.180.4.236
+2.180.4.250
+2.180.5.28
+2.180.5.88
+2.180.5.140
+2.180.5.161
+2.180.5.243
+2.180.6.34
+2.180.6.105
+2.180.6.140
+2.180.6.144
+2.180.6.146
+2.180.7.39
+2.180.7.67
+2.180.7.153
+2.180.7.157
+2.180.7.199
+2.180.7.200
+2.180.7.227
+2.180.8.37
+2.180.8.78
+2.180.8.149
+2.180.8.174
+2.180.8.186
+2.180.8.193
+2.180.8.207
+2.180.9.92
+2.180.9.135
+2.180.9.152
+2.180.10.158
+2.180.10.204
+2.180.10.205
+2.180.10.218
+2.180.10.225
+2.180.11.45
+2.180.11.59
+2.180.11.94
+2.180.11.100
+2.180.11.102
+2.180.11.130
+2.180.11.158
+2.180.11.162
+2.180.12.11
+2.180.12.28
+2.180.12.41
+2.180.12.45
+2.180.12.68
+2.180.12.106
+2.180.12.114
+2.180.12.146
+2.180.12.178
+2.180.12.210
+2.180.13.32
+2.180.13.98
+2.180.13.108
+2.180.13.110
+2.180.13.127
+2.180.15.18
+2.180.15.31
+2.180.15.108
+2.180.15.134
+2.180.15.175
+2.180.16.1
+2.180.16.19
+2.180.16.42
+2.180.16.135
+2.180.16.196
+2.180.16.219
+2.180.17.32
+2.180.17.123
+2.180.17.136
+2.180.17.198
+2.180.17.219
+2.180.18.2
+2.180.18.84
+2.180.18.89
+2.180.18.91
+2.180.18.116
+2.180.18.126
+2.180.18.131
+2.180.18.226
+2.180.18.231
+2.180.18.241
+2.180.19.18
+2.180.19.47
+2.180.19.60
+2.180.19.172
+2.180.19.214
+2.180.19.221
+2.180.19.228
+2.180.19.231
+2.180.20.27
+2.180.20.63
+2.180.21.17
+2.180.21.69
+2.180.21.90
+2.180.21.144
+2.180.21.185
+2.180.21.234
+2.180.21.241
+2.180.22.26
+2.180.22.70
+2.180.22.81
+2.180.22.119
+2.180.23.91
+2.180.23.128
+2.180.23.143
+2.180.23.188
+2.180.23.221
+2.180.24.58
+2.180.24.69
+2.180.24.254
+2.180.25.17
+2.180.25.47
+2.180.25.52
+2.180.25.73
+2.180.25.195
+2.180.25.242
+2.180.26.40
+2.180.26.157
+2.180.27.80
+2.180.27.143
+2.180.28.104
+2.180.28.125
+2.180.28.153
+2.180.28.163
+2.180.28.173
+2.180.28.192
+2.180.28.193
+2.180.29.48
+2.180.29.70
+2.180.29.133
+2.180.29.185
+2.180.29.204
+2.180.29.213
+2.180.29.238
+2.180.30.56
+2.180.30.209
+2.180.30.218
+2.180.31.61
+2.180.31.62
+2.180.31.110
+2.180.31.224
+2.180.32.26
+2.180.32.61
+2.180.32.72
+2.180.32.166
+2.180.32.198
+2.180.33.61
+2.180.33.119
+2.180.33.127
+2.180.33.128
+2.180.33.132
+2.180.33.168
+2.180.35.13
+2.180.35.16
+2.180.35.35
+2.180.35.116
+2.180.35.169
+2.180.35.250
+2.180.36.105
+2.180.36.147
+2.180.36.173
+2.180.36.174
+2.180.36.191
+2.180.36.228
+2.180.37.29
+2.180.37.54
+2.180.37.67
+2.180.37.143
+2.180.37.151
+2.180.37.161
+2.180.37.248
+2.180.39.32
+2.180.39.33
+2.180.39.34
+2.180.39.35
+2.180.39.36
+2.180.39.37
+2.180.39.38
+2.180.39.82
+2.180.39.83
+2.180.40.78
+2.180.40.85
+2.180.40.96
+2.180.41.6
+2.180.41.18
+2.180.41.249
+2.180.42.1
+2.180.42.50
+2.180.42.54
+2.180.42.78
+2.180.42.95
+2.180.42.109
+2.180.42.137
+2.180.42.170
+2.180.42.218
+2.180.42.228
+2.180.43.13
+2.180.43.84
+2.180.43.147
+2.180.43.186
+2.180.43.189
+2.180.43.198
+2.180.44.1
+2.180.44.2
+2.180.44.39
+2.180.44.86
+2.180.44.137
+2.180.44.151
+2.180.44.173
+2.180.44.180
+2.180.44.200
+2.180.44.203
+2.180.47.142
+2.180.47.164
+2.180.47.254
+2.180.130.61
+2.180.131.14
+2.180.132.126
+2.180.133.193
+2.180.135.8
+2.180.135.143
+2.180.138.56
+2.180.138.237
+2.180.139.63
+2.180.141.92
+2.180.146.226
+2.180.147.108
+2.180.148.113
+2.180.150.154
+2.180.151.218
+2.180.151.249
+2.180.154.235
+2.180.155.106
+2.180.155.252
+2.180.156.36
+2.180.159.21
+2.180.161.42
+2.180.162.97
+2.180.163.157
+2.180.166.27
+2.180.167.58
+2.180.167.63
+2.180.167.137
+2.180.169.124
+2.180.170.132
+2.180.171.158
+2.180.172.39
+2.180.172.198
+2.180.174.226
+2.180.175.1
+2.180.175.255
+2.180.177.79
+2.180.178.149
+2.180.178.154
+2.180.180.221
+2.180.186.98
+2.180.188.123
+2.180.197.167
+2.180.198.23
+2.180.198.235
+2.180.199.134
+2.180.199.177
+2.180.208.78
+2.180.210.6
+2.180.211.96
+2.180.215.214
+2.180.216.77
+2.180.216.116
+2.180.219.96
+2.180.223.7
+2.180.228.75
+2.180.230.225
+2.180.236.114
+2.180.238.232
+2.180.242.52
+2.180.243.51
+2.180.243.243
+2.180.248.212
+2.180.249.74
+2.180.251.146
+2.180.252.125
+2.181.0.37
+2.181.0.51
+2.181.0.54
+2.181.0.73
+2.181.0.234
+2.181.1.100
+2.181.1.245
+2.181.30.24
+2.181.30.85
+2.181.30.88
+2.181.30.198
+2.181.30.234
+2.181.31.25
+2.181.31.55
+2.181.31.69
+2.181.31.104
+2.181.31.150
+2.181.31.221
+2.181.34.28
+2.181.34.34
+2.181.34.55
+2.181.34.74
+2.181.34.255
+2.181.35.31
+2.181.35.51
+2.181.35.65
+2.181.35.210
+2.181.56.31
+2.181.58.89
+2.181.61.201
+2.181.61.208
+2.181.62.159
+2.181.78.26
+2.181.78.32
+2.181.78.219
+2.181.80.96
+2.181.81.4
+2.181.81.34
+2.181.81.155
+2.181.82.22
+2.181.82.53
+2.181.82.105
+2.181.82.191
+2.181.83.13
+2.181.84.235
+2.181.85.80
+2.181.85.206
+2.181.86.11
+2.181.86.241
+2.181.87.182
+2.181.87.219
+2.181.88.14
+2.181.89.144
+2.181.91.16
+2.181.92.32
+2.181.92.82
+2.181.92.254
+2.181.93.125
+2.181.93.146
+2.181.93.233
+2.181.94.124
+2.181.96.98
+2.181.96.159
+2.181.98.32
+2.181.98.176
+2.181.99.194
+2.181.100.35
+2.181.100.163
+2.181.101.98
+2.181.101.172
+2.181.102.30
+2.181.102.75
+2.181.102.98
+2.181.102.196
+2.181.102.208
+2.181.103.72
+2.181.104.177
+2.181.104.254
+2.181.105.60
+2.181.106.197
+2.181.107.74
+2.181.108.16
+2.181.108.190
+2.181.109.58
+2.181.109.106
+2.181.110.156
+2.181.110.241
+2.181.129.23
+2.181.195.99
+2.181.195.113
+2.181.198.66
+2.181.201.158
+2.181.202.229
+2.181.204.140
+2.181.206.33
+2.181.206.133
+2.181.208.45
+2.181.210.150
+2.181.211.7
+2.181.213.41
+2.181.213.83
+2.181.215.172
+2.181.216.44
+2.181.216.54
+2.181.216.225
+2.181.217.76
+2.181.217.170
+2.181.221.50
+2.181.222.216
+2.181.222.253
+2.181.224.62
+2.181.225.138
+2.181.225.203
+2.181.225.237
+2.181.226.194
+2.181.227.140
+2.181.227.172
+2.181.227.213
+2.181.228.24
+2.181.228.113
+2.181.228.194
+2.181.229.49
+2.181.229.236
+2.181.230.167
+2.181.231.150
+2.181.232.216
+2.181.234.74
+2.181.234.129
+2.181.234.135
+2.181.234.140
+2.181.234.194
+2.181.234.213
+2.181.234.222
+2.181.235.126
+2.181.236.18
+2.181.236.228
+2.181.237.88
+2.181.237.120
+2.181.238.72
+2.181.239.75
+2.181.239.206
+2.181.239.207
+2.181.240.16
+2.181.240.143
+2.181.240.226
+2.181.241.99
+2.181.241.197
+2.181.242.59
+2.181.243.143
+2.181.244.40
+2.181.245.241
+2.181.246.95
+2.181.249.188
+2.181.251.145
+2.181.254.53
+2.181.254.87
+2.181.254.127
+2.181.255.171
+2.181.255.222
+2.182.40.14
+2.182.40.59
+2.182.40.76
+2.182.43.6
+2.182.43.187
+2.182.44.240
+2.182.46.202
+2.182.47.140
+2.182.48.163
+2.182.48.247
+2.182.51.1
+2.182.51.29
+2.182.51.63
+2.182.51.99
+2.182.52.72
+2.182.53.247
+2.182.54.149
+2.182.66.165
+2.182.79.37
+2.182.89.108
+2.182.90.205
+2.182.112.11
+2.182.112.125
+2.182.114.75
+2.182.115.46
+2.182.115.83
+2.182.115.91
+2.182.116.22
+2.182.116.70
+2.182.116.103
+2.182.117.118
+2.182.124.100
+2.182.125.223
+2.182.152.15
+2.182.152.37
+2.182.152.103
+2.182.152.115
+2.182.152.136
+2.182.152.138
+2.182.152.155
+2.182.152.206
+2.182.152.240
+2.182.152.254
+2.182.153.95
+2.182.153.106
+2.182.153.125
+2.182.153.131
+2.182.153.145
+2.182.153.163
+2.182.153.196
+2.182.154.27
+2.182.154.57
+2.182.154.65
+2.182.154.77
+2.182.154.85
+2.182.154.110
+2.182.154.130
+2.182.154.158
+2.182.154.160
+2.182.154.185
+2.182.154.207
+2.182.155.160
+2.182.163.78
+2.182.176.193
+2.182.179.32
+2.182.179.130
+2.182.179.236
+2.182.180.119
+2.182.180.194
+2.182.181.130
+2.182.184.83
+2.182.186.225
+2.182.187.13
+2.182.188.73
+2.182.188.156
+2.182.189.30
+2.182.189.33
+2.182.189.147
+2.182.189.169
+2.182.190.37
+2.182.191.173
+2.182.192.46
+2.182.196.9
+2.182.196.65
+2.182.196.133
+2.182.196.234
+2.182.198.213
+2.182.201.3
+2.182.201.5
+2.182.201.71
+2.182.201.220
+2.182.201.221
+2.182.201.222
+2.182.204.29
+2.182.204.78
+2.182.204.250
+2.182.205.252
+2.182.206.42
+2.182.206.58
+2.182.206.121
+2.182.207.14
+2.182.207.191
+2.182.209.24
+2.182.210.235
+2.182.212.252
+2.182.214.246
+2.182.215.122
+2.182.216.144
+2.182.223.204
+2.182.228.247
+2.182.231.42
+2.182.232.85
+2.182.233.138
+2.182.236.135
+2.182.236.141
+2.182.236.154
+2.182.236.237
+2.182.237.186
+2.182.237.251
+2.182.239.170
+2.182.241.197
+2.182.243.110
+2.182.243.151
+2.182.243.209
+2.182.243.244
+2.182.244.151
+2.182.245.101
+2.182.245.200
+2.182.245.231
+2.182.246.102
+2.182.246.134
+2.182.249.84
+2.182.249.130
+2.182.250.85
+2.182.250.160
+2.182.253.241
+2.183.8.13
+2.183.8.19
+2.183.8.90
+2.183.8.118
+2.183.8.173
+2.183.8.186
+2.183.9.86
+2.183.9.165
+2.183.9.236
+2.183.32.12
+2.183.32.52
+2.183.32.62
+2.183.32.84
+2.183.32.112
+2.183.80.7
+2.183.80.8
+2.183.82.5
+2.183.82.51
+2.183.83.147
+2.183.83.235
+2.183.84.4
+2.183.86.138
+2.183.86.218
+2.183.87.231
+2.183.87.239
+2.183.97.178
+2.183.98.176
+2.183.100.95
+2.183.100.145
+2.183.102.201
+2.183.105.124
+2.183.105.142
+2.183.106.13
+2.183.107.214
+2.183.110.163
+2.183.112.69
+2.183.112.159
+2.183.112.219
+2.183.112.252
+2.183.113.112
+2.183.114.9
+2.183.114.107
+2.183.114.243
+2.183.115.91
+2.183.117.133
+2.183.117.167
+2.183.119.25
+2.183.120.146
+2.183.121.29
+2.183.123.172
+2.183.135.24
+2.183.135.52
+2.183.203.74
+2.183.203.131
+2.183.203.135
+2.183.203.142
+2.183.203.146
+2.183.231.18
+2.183.237.8
+2.184.38.118
+2.184.41.171
+2.184.48.4
+2.184.48.42
+2.184.48.46
+2.184.49.21
+2.184.49.22
+2.184.49.145
+2.184.50.27
+2.184.50.34
+2.184.50.144
+2.184.50.145
+2.184.50.165
+2.184.50.172
+2.184.51.69
+2.184.51.140
+2.184.51.143
+2.184.52.22
+2.184.52.194
+2.184.52.249
+2.184.52.250
+2.184.53.168
+2.184.53.237
+2.184.54.17
+2.184.54.38
+2.184.54.105
+2.184.54.113
+2.184.54.128
+2.184.54.157
+2.184.54.208
+2.184.55.14
+2.184.55.22
+2.184.55.37
+2.184.55.83
+2.184.55.105
+2.184.55.128
+2.184.55.156
+2.184.55.183
+2.184.57.117
+2.184.57.166
+2.184.58.19
+2.184.58.25
+2.184.58.188
+2.184.59.29
+2.184.59.52
+2.184.59.82
+2.184.59.137
+2.184.60.6
+2.184.61.36
+2.184.61.61
+2.184.61.204
+2.184.70.91
+2.184.70.104
+2.184.71.2
+2.184.71.3
+2.184.71.4
+2.184.71.6
+2.184.74.2
+2.184.74.62
+2.184.89.24
+2.184.90.99
+2.184.90.104
+2.184.90.129
+2.184.90.198
+2.184.92.31
+2.184.118.38
+2.184.155.46
+2.184.155.72
+2.184.155.83
+2.184.155.92
+2.184.155.117
+2.184.156.9
+2.184.156.38
+2.184.156.79
+2.184.156.155
+2.184.156.188
+2.184.156.189
+2.184.156.233
+2.184.157.5
+2.184.157.15
+2.184.157.18
+2.184.157.129
+2.184.157.134
+2.184.157.146
+2.184.157.150
+2.184.157.226
+2.184.157.237
+2.184.158.14
+2.184.158.38
+2.184.158.117
+2.184.158.221
+2.184.158.253
+2.184.159.66
+2.184.159.68
+2.184.159.111
+2.184.159.119
+2.184.159.126
+2.184.159.167
+2.184.159.227
+2.184.169.181
+2.184.171.87
+2.184.182.68
+2.184.182.76
+2.184.182.87
+2.184.182.136
+2.184.182.152
+2.184.217.25
+2.184.217.127
+2.184.217.167
+2.184.217.176
+2.184.217.193
+2.184.217.197
+2.184.217.224
+2.184.236.9
+2.184.236.34
+2.184.236.119
+2.184.236.159
+2.184.236.164
+2.184.236.166
+2.184.236.197
+2.184.236.217
+2.184.236.233
+2.184.236.240
+2.184.237.70
+2.184.237.208
+2.184.238.17
+2.184.238.19
+2.184.238.113
+2.184.238.123
+2.184.238.214
+2.184.239.89
+2.184.239.236
+2.185.17.15
+2.185.17.144
+2.185.17.206
+2.185.17.242
+2.185.18.223
+2.185.96.234
+2.185.97.7
+2.185.97.61
+2.185.97.73
+2.185.98.143
+2.185.98.165
+2.185.100.127
+2.185.100.154
+2.185.100.238
+2.185.105.18
+2.185.109.245
+2.185.112.36
+2.185.112.226
+2.185.114.134
+2.185.116.58
+2.185.116.139
+2.185.122.55
+2.185.123.194
+2.185.126.25
+2.185.126.221
+2.185.126.230
+2.185.127.96
+2.185.127.128
+2.185.128.41
+2.185.128.69
+2.185.128.113
+2.185.128.121
+2.185.128.161
+2.185.128.211
+2.185.128.218
+2.185.128.221
+2.185.128.225
+2.185.128.230
+2.185.141.25
+2.185.141.55
+2.185.143.33
+2.185.143.103
+2.185.144.22
+2.185.147.55
+2.185.147.166
+2.185.147.174
+2.185.147.198
+2.185.147.202
+2.185.148.21
+2.185.148.118
+2.185.148.128
+2.185.148.154
+2.185.148.217
+2.185.149.163
+2.185.150.166
+2.185.151.209
+2.185.152.1
+2.185.152.21
+2.185.153.51
+2.185.153.188
+2.185.175.55
+2.185.191.203
+2.185.192.9
+2.185.203.219
+2.185.214.7
+2.185.214.202
+2.185.224.33
+2.185.224.152
+2.185.224.167
+2.185.224.187
+2.185.225.195
+2.185.226.211
+2.185.227.51
+2.185.227.56
+2.185.227.124
+2.185.227.138
+2.185.229.38
+2.185.229.115
+2.185.231.20
+2.185.232.50
+2.185.232.170
+2.185.232.210
+2.185.232.242
+2.185.233.83
+2.185.233.166
+2.185.234.55
+2.185.235.73
+2.185.237.4
+2.185.238.45
+2.185.238.145
+2.185.239.130
+2.185.239.131
+2.185.239.132
+2.185.239.133
+2.185.239.134
+2.185.239.136
+2.185.239.137
+2.185.239.138
+2.185.239.139
+2.185.239.140
+2.185.239.230
+2.185.241.0
+2.185.241.150
+2.185.242.112
+2.185.242.141
+2.185.242.180
+2.185.244.68
+2.185.244.78
+2.185.247.168
+2.185.247.176
+2.185.247.197
+2.185.248.2
+2.185.248.141
+2.185.249.54
+2.185.250.155
+2.185.250.165
+2.185.250.215
+2.185.251.95
+2.185.252.124
+2.185.252.253
+2.185.253.215
+2.186.12.75
+2.186.12.113
+2.186.12.137
+2.186.12.138
+2.186.12.156
+2.186.12.180
+2.186.13.21
+2.186.13.26
+2.186.13.94
+2.186.14.27
+2.186.14.60
+2.186.14.92
+2.186.14.94
+2.186.14.102
+2.186.14.167
+2.186.14.234
+2.186.14.239
+2.186.15.17
+2.186.15.39
+2.186.15.74
+2.186.15.79
+2.186.15.170
+2.186.15.194
+2.186.15.196
+2.186.15.199
+2.186.112.22
+2.186.112.24
+2.186.112.85
+2.186.112.132
+2.186.112.178
+2.186.112.186
+2.186.114.125
+2.186.114.179
+2.186.114.196
+2.186.114.236
+2.186.115.35
+2.186.115.86
+2.186.115.162
+2.186.115.184
+2.186.115.252
+2.186.116.38
+2.186.116.121
+2.186.116.210
+2.186.117.2
+2.186.117.79
+2.186.117.93
+2.186.117.107
+2.186.117.140
+2.186.117.164
+2.186.118.17
+2.186.118.44
+2.186.118.49
+2.186.118.81
+2.186.118.165
+2.186.118.211
+2.186.118.255
+2.186.119.27
+2.186.119.32
+2.186.119.48
+2.186.119.65
+2.186.119.169
+2.186.119.217
+2.186.119.253
+2.186.120.41
+2.186.120.64
+2.186.120.70
+2.186.120.133
+2.186.120.175
+2.186.120.181
+2.186.120.202
+2.186.120.215
+2.186.121.39
+2.186.121.100
+2.186.121.170
+2.186.122.15
+2.186.122.50
+2.186.122.51
+2.186.122.60
+2.186.122.125
+2.186.122.184
+2.186.122.199
+2.186.122.214
+2.186.123.35
+2.186.123.64
+2.186.123.108
+2.186.123.152
+2.186.123.183
+2.186.123.213
+2.186.127.1
+2.186.127.68
+2.186.127.90
+2.186.127.158
+2.186.127.164
+2.186.127.212
+2.186.127.236
+2.186.127.247
+2.186.229.46
+2.186.229.60
+2.186.229.110
+2.186.229.192
+2.186.229.230
+2.186.231.68
+2.186.231.129
+2.186.231.130
+2.186.231.155
+2.186.231.241
+2.186.231.242
+2.186.231.243
+2.186.231.244
+2.186.231.245
+2.186.231.246
+2.187.1.167
+2.187.2.23
+2.187.2.30
+2.187.2.96
+2.187.2.101
+2.187.2.123
+2.187.2.184
+2.187.2.185
+2.187.4.172
+2.187.5.66
+2.187.6.17
+2.187.6.112
+2.187.6.182
+2.187.6.243
+2.187.7.232
+2.187.8.176
+2.187.9.2
+2.187.10.227
+2.187.11.1
+2.187.16.10
+2.187.16.17
+2.187.16.25
+2.187.16.63
+2.187.16.90
+2.187.16.147
+2.187.16.179
+2.187.16.223
+2.187.16.243
+2.187.16.252
+2.187.18.17
+2.187.18.248
+2.187.19.18
+2.187.19.151
+2.187.19.241
+2.187.19.242
+2.187.24.39
+2.187.24.235
+2.187.26.17
+2.187.26.75
+2.187.26.145
+2.187.27.146
+2.187.28.228
+2.187.30.84
+2.187.32.13
+2.187.32.72
+2.187.32.210
+2.187.32.228
+2.187.33.42
+2.187.33.50
+2.187.33.107
+2.187.33.174
+2.187.33.187
+2.187.34.87
+2.187.34.126
+2.187.34.161
+2.187.35.15
+2.187.35.19
+2.187.35.21
+2.187.35.61
+2.187.35.84
+2.187.35.140
+2.187.36.11
+2.187.37.180
+2.187.37.242
+2.187.38.26
+2.187.38.201
+2.187.39.91
+2.187.39.157
+2.187.39.172
+2.187.39.190
+2.187.39.234
+2.187.56.225
+2.187.57.8
+2.187.57.17
+2.187.57.23
+2.187.62.102
+2.187.96.30
+2.187.96.85
+2.187.96.116
+2.187.96.252
+2.187.97.4
+2.187.97.111
+2.187.97.121
+2.187.97.141
+2.187.98.41
+2.187.98.118
+2.187.98.181
+2.187.99.27
+2.187.99.71
+2.187.99.150
+2.187.100.13
+2.187.100.51
+2.187.100.137
+2.187.101.33
+2.187.101.46
+2.187.117.47
+2.187.117.140
+2.187.118.1
+2.187.119.3
+2.187.119.6
+2.187.119.113
+2.187.128.43
+2.187.128.159
+2.187.128.166
+2.187.128.170
+2.187.140.131
+2.187.142.95
+2.187.143.145
+2.187.150.9
+2.187.150.48
+2.187.150.108
+2.187.186.17
+2.187.186.65
+2.187.186.66
+2.187.186.67
+2.187.186.68
+2.187.186.69
+2.187.188.98
+2.187.188.123
+2.187.188.130
+2.187.188.137
+2.187.188.143
+2.187.188.174
+2.187.188.190
+2.187.188.239
+2.187.188.253
+2.187.189.60
+2.187.189.121
+2.187.189.193
+2.187.189.208
+2.187.189.226
+2.187.189.227
+2.187.212.11
+2.187.212.125
+2.187.213.78
+2.187.213.158
+2.187.221.33
+2.187.249.121
+2.187.249.148
+2.187.249.177
+2.187.249.178
+2.187.250.11
+2.187.250.50
+2.187.250.80
+2.187.250.110
+2.187.250.169
+2.187.250.218
+2.187.250.223
+2.187.251.88
+2.187.251.245
+2.188.43.76
+2.188.72.11
+2.188.72.48
+2.188.72.54
+2.188.72.56
+2.188.72.150
+2.188.72.174
+2.188.72.209
+2.188.72.220
+2.188.72.230
+2.188.72.238
+2.188.73.129
+2.188.73.137
+2.188.73.145
+2.188.73.153
+2.188.73.157
+2.188.73.161
+2.188.73.165
+2.188.75.14
+2.188.75.178
+2.188.160.236
+2.188.161.170
+2.188.162.74
+2.188.162.75
+2.188.162.78
+2.188.164.54
+2.188.164.91
+2.188.164.117
+2.188.164.140
+2.188.165.114
+2.188.165.170
+2.188.166.50
+2.188.166.74
+2.188.166.75
+2.188.166.78
+2.188.167.14
+2.188.167.34
+2.188.167.54
+2.188.167.114
+2.188.167.156
+2.188.168.41
+2.188.168.87
+2.188.168.88
+2.188.168.135
+2.188.168.222
+2.188.174.151
+2.188.174.173
+2.188.174.194
+2.188.174.230
+2.188.175.4
+2.188.175.21
+2.188.175.94
+2.188.175.105
+2.188.175.215
+2.188.175.228
+2.188.208.110
+2.188.208.142
+2.188.208.242
+2.188.208.254
+2.188.210.2
+2.188.210.3
+2.188.210.5
+2.188.210.6
+2.188.210.8
+2.188.210.10
+2.188.210.12
+2.188.210.13
+2.188.210.14
+2.188.210.16
+2.188.210.20
+2.188.210.21
+2.188.210.50
+2.188.210.111
+2.188.210.112
+2.188.210.125
+2.188.211.7
+2.188.211.234
+2.188.214.250
+2.188.214.252
+2.188.214.253
+2.188.214.254
+2.188.215.34
+2.188.215.67
+2.188.215.103
+2.188.217.54
+2.188.220.132
+2.188.221.14
+2.188.222.1
+2.188.222.2
+2.188.222.11
+2.188.222.14
+2.188.222.65
+2.188.222.81
+2.188.225.66
+2.188.225.67
+2.188.225.136
+2.188.225.147
+2.188.226.187
+2.188.226.188
+2.188.226.189
+2.188.226.190
+2.188.226.243
+2.188.226.245
+2.188.226.246
+2.188.226.247
+2.188.226.248
+2.188.226.250
+2.188.226.251
+2.188.226.252
+2.188.228.36
+2.188.228.37
+2.188.228.38
+2.188.228.98
+2.188.228.130
+2.188.230.210
+2.188.230.212
+2.188.231.2
+2.188.231.106
+2.188.231.110
+2.188.231.114
+2.188.231.115
+2.188.231.116
+2.188.231.117
+2.188.231.118
+2.188.231.120
+2.188.231.122
+2.188.231.123
+2.188.231.125
+2.188.231.194
+2.188.231.195
+2.188.231.196
+2.188.231.197
+2.188.231.198
+2.188.231.199
+2.188.235.128
+2.188.236.50
+2.188.236.70
+2.188.237.22
+2.188.237.146
+2.189.1.1
+2.189.1.2
+2.189.1.11
+2.189.1.12
+2.189.1.14
+2.189.1.40
+2.189.1.104
+2.189.1.251
+2.189.8.168
+2.189.9.77
+2.189.9.163
+2.189.10.247
+2.189.11.76
+2.189.11.239
+2.189.16.113
+2.189.20.156
+2.189.20.158
+2.189.21.139
+2.189.23.66
+2.189.28.38
+2.189.28.134
+2.189.28.166
+2.189.29.111
+2.189.29.229
+2.189.29.231
+2.189.30.37
+2.189.31.217
+2.189.32.52
+2.189.32.199
+2.189.33.61
+2.189.33.90
+2.189.33.114
+2.189.34.164
+2.189.34.221
+2.189.34.244
+2.189.59.81
+2.189.67.42
+2.189.86.10
+2.189.86.11
+2.189.86.12
+2.189.86.13
+2.189.86.14
+2.189.86.15
+2.189.86.16
+2.189.86.19
+2.189.86.30
+2.189.86.31
+2.189.86.32
+2.189.86.34
+2.189.86.35
+2.189.86.36
+2.189.86.41
+2.189.86.42
+2.189.86.43
+2.189.86.44
+2.189.86.45
+2.189.86.46
+2.189.86.84
+2.189.86.85
+2.189.86.86
+2.189.86.87
+2.189.86.88
+2.189.86.89
+2.189.86.90
+2.189.86.91
+2.189.86.92
+2.189.86.93
+2.189.86.94
+2.189.86.98
+2.189.86.103
+2.189.86.104
+2.189.86.105
+2.189.86.107
+2.189.86.108
+2.189.86.109
+2.189.86.110
+2.189.86.111
+2.189.86.112
+2.189.86.113
+2.189.87.172
+2.189.87.228
+2.189.89.18
+2.189.89.110
+2.189.89.166
+2.189.89.214
+2.189.90.84
+2.189.90.147
+2.189.90.206
+2.189.91.37
+2.189.91.141
+2.189.91.226
+2.189.91.229
+2.189.91.230
+2.189.91.231
+2.189.91.232
+2.189.92.31
+2.189.92.217
+2.189.93.162
+2.189.93.224
+2.189.96.121
+2.189.96.136
+2.189.98.67
+2.189.98.113
+2.189.98.135
+2.189.98.137
+2.189.101.0
+2.189.101.6
+2.189.101.12
+2.189.101.13
+2.189.101.14
+2.189.101.15
+2.189.101.85
+2.189.101.100
+2.189.101.101
+2.189.101.139
+2.189.101.146
+2.189.101.165
+2.189.101.224
+2.189.101.231
+2.189.102.15
+2.189.104.1
+2.189.104.3
+2.189.114.61
+2.189.115.49
+2.189.115.76
+2.189.115.150
+2.189.115.162
+2.189.115.174
+2.189.115.183
+2.189.120.2
+2.189.120.4
+2.189.120.14
+2.189.120.16
+2.189.120.23
+2.189.120.35
+2.189.120.39
+2.189.120.40
+2.189.120.43
+2.189.120.69
+2.189.120.74
+2.189.120.77
+2.189.120.78
+2.189.120.99
+2.189.120.109
+2.189.120.114
+2.189.120.116
+2.189.120.117
+2.189.120.144
+2.189.120.149
+2.189.120.164
+2.189.120.180
+2.189.120.183
+2.189.120.201
+2.189.120.213
+2.189.120.214
+2.189.120.220
+2.189.120.226
+2.189.120.231
+2.189.120.232
+2.189.120.233
+2.189.121.4
+2.189.121.10
+2.189.121.15
+2.189.121.16
+2.189.121.21
+2.189.121.47
+2.189.121.49
+2.189.121.53
+2.189.121.54
+2.189.121.56
+2.189.121.58
+2.189.121.62
+2.189.121.66
+2.189.121.78
+2.189.121.79
+2.189.121.88
+2.189.121.90
+2.189.121.91
+2.189.121.99
+2.189.121.104
+2.189.121.121
+2.189.121.131
+2.189.121.136
+2.189.121.146
+2.189.121.152
+2.189.121.155
+2.189.121.163
+2.189.121.176
+2.189.121.178
+2.189.121.191
+2.189.121.202
+2.189.121.210
+2.189.121.218
+2.189.121.231
+2.189.121.232
+2.189.121.240
+2.189.121.244
+2.189.122.20
+2.189.122.22
+2.189.122.103
+2.189.122.119
+2.189.122.240
+2.189.128.11
+2.189.128.12
+2.189.128.13
+2.189.128.180
+2.189.128.181
+2.189.128.182
+2.189.130.3
+2.189.130.4
+2.189.130.8
+2.189.130.10
+2.189.130.18
+2.189.130.33
+2.189.136.3
+2.189.136.6
+2.189.136.25
+2.189.136.67
+2.189.136.69
+2.189.136.78
+2.189.136.95
+2.189.136.112
+2.189.136.132
+2.189.136.153
+2.189.136.178
+2.189.137.0
+2.189.137.20
+2.189.137.27
+2.189.137.29
+2.189.137.43
+2.189.137.61
+2.189.137.98
+2.189.137.99
+2.189.137.221
+2.189.137.222
+2.189.137.223
+2.189.137.224
+2.189.137.240
+2.189.139.0
+2.189.139.5
+2.189.139.7
+2.189.139.10
+2.189.139.14
+2.189.139.16
+2.189.139.18
+2.189.139.21
+2.189.139.25
+2.189.139.35
+2.189.139.41
+2.189.139.55
+2.189.139.56
+2.189.139.63
+2.189.139.65
+2.189.139.76
+2.189.139.85
+2.189.139.89
+2.189.139.95
+2.189.139.101
+2.189.139.108
+2.189.139.109
+2.189.139.114
+2.189.139.120
+2.189.139.125
+2.189.139.128
+2.189.139.129
+2.189.139.130
+2.189.139.131
+2.189.139.135
+2.189.139.145
+2.189.139.150
+2.189.139.157
+2.189.139.161
+2.189.139.171
+2.189.139.180
+2.189.139.185
+2.189.139.193
+2.189.139.206
+2.189.139.214
+2.189.139.218
+2.189.139.221
+2.189.139.222
+2.189.139.230
+2.189.139.233
+2.189.139.240
+2.189.139.241
+2.189.139.242
+2.189.139.246
+2.189.139.247
+2.189.139.250
+2.189.140.5
+2.189.140.6
+2.189.140.7
+2.189.141.32
+2.189.142.20
+2.189.142.33
+2.189.142.38
+2.189.142.48
+2.189.142.55
+2.189.142.57
+2.189.142.63
+2.189.142.98
+2.189.142.112
+2.189.143.4
+2.189.143.5
+2.189.143.8
+2.189.143.11
+2.189.143.24
+2.189.143.49
+2.189.143.58
+2.189.143.61
+2.189.143.78
+2.189.143.145
+2.189.143.181
+2.189.143.191
+2.189.143.222
+2.189.143.253
+2.189.144.9
+2.189.144.11
+2.189.144.19
+2.189.144.28
+2.189.144.40
+2.189.144.55
+2.189.144.65
+2.189.144.73
+2.189.144.83
+2.189.144.86
+2.189.144.104
+2.189.144.109
+2.189.144.121
+2.189.144.126
+2.189.144.129
+2.189.144.140
+2.189.144.143
+2.189.144.147
+2.189.144.151
+2.189.144.159
+2.189.144.163
+2.189.144.173
+2.189.144.181
+2.189.144.184
+2.189.144.186
+2.189.144.207
+2.189.144.215
+2.189.144.218
+2.189.144.221
+2.189.144.222
+2.189.144.224
+2.189.144.227
+2.189.144.229
+2.189.144.233
+2.189.144.235
+2.189.144.247
+2.189.145.4
+2.189.145.11
+2.189.145.34
+2.189.145.46
+2.189.145.48
+2.189.145.70
+2.189.145.71
+2.189.145.75
+2.189.145.104
+2.189.145.108
+2.189.145.109
+2.189.145.122
+2.189.145.149
+2.189.145.154
+2.189.145.160
+2.189.145.164
+2.189.145.167
+2.189.145.168
+2.189.145.174
+2.189.145.177
+2.189.145.183
+2.189.145.193
+2.189.145.195
+2.189.145.197
+2.189.145.211
+2.189.145.213
+2.189.145.224
+2.189.145.244
+2.189.145.246
+2.189.145.249
+2.189.145.252
+2.189.146.113
+2.189.147.44
+2.189.147.188
+2.189.147.241
+2.189.148.2
+2.189.148.8
+2.189.148.12
+2.189.148.16
+2.189.148.17
+2.189.148.23
+2.189.148.28
+2.189.148.29
+2.189.148.32
+2.189.148.33
+2.189.148.34
+2.189.148.36
+2.189.148.38
+2.189.148.39
+2.189.148.43
+2.189.148.44
+2.189.148.49
+2.189.148.54
+2.189.148.63
+2.189.148.64
+2.189.148.67
+2.189.148.69
+2.189.148.71
+2.189.148.82
+2.189.148.87
+2.189.148.88
+2.189.148.94
+2.189.148.98
+2.189.148.104
+2.189.148.109
+2.189.148.126
+2.189.148.131
+2.189.148.133
+2.189.148.136
+2.189.148.137
+2.189.148.139
+2.189.148.146
+2.189.148.156
+2.189.148.166
+2.189.148.167
+2.189.148.169
+2.189.148.171
+2.189.148.176
+2.189.148.181
+2.189.148.182
+2.189.148.183
+2.189.148.192
+2.189.148.204
+2.189.148.205
+2.189.148.214
+2.189.148.215
+2.189.148.231
+2.189.148.235
+2.189.148.248
+2.189.148.251
+2.189.148.253
+2.189.151.5
+2.189.151.68
+2.189.151.109
+2.189.151.116
+2.189.151.126
+2.189.151.130
+2.189.151.146
+2.189.151.165
+2.189.151.171
+2.189.151.174
+2.189.151.180
+2.189.153.96
+2.189.153.162
+2.189.156.30
+2.189.156.42
+2.189.158.176
+2.189.162.18
+2.189.162.250
+2.189.163.4
+2.189.163.63
+2.189.163.112
+2.189.164.26
+2.189.164.27
+2.189.164.28
+2.189.164.29
+2.189.167.131
+2.189.167.203
+2.189.167.210
+2.189.167.211
+2.189.167.212
+2.189.167.254
+2.189.172.30
+2.189.172.49
+2.189.218.246
+2.189.220.93
+2.189.236.154
+2.189.236.246
+2.189.237.61
+2.189.237.180
+2.189.237.190
+2.189.237.236
+2.189.237.254
+2.189.238.236
+2.189.239.123
+2.189.243.1
+2.189.243.22
+2.189.254.109
+2.190.1.39
+2.190.2.98
+2.190.6.96
+2.190.6.165
+2.190.8.47
+2.190.11.209
+2.190.17.151
+2.190.19.236
+2.190.20.16
+2.190.20.231
+2.190.23.71
+2.190.25.71
+2.190.30.229
+2.190.30.232
+2.190.31.210
+2.190.32.109
+2.190.34.61
+2.190.35.228
+2.190.36.45
+2.190.36.76
+2.190.39.192
+2.190.41.13
+2.190.41.22
+2.190.43.66
+2.190.44.173
+2.190.48.7
+2.190.48.125
+2.190.48.237
+2.190.49.82
+2.190.50.185
+2.190.50.196
+2.190.52.208
+2.190.52.213
+2.190.55.11
+2.190.55.244
+2.190.61.97
+2.190.62.119
+2.190.62.191
+2.190.65.167
+2.190.67.113
+2.190.69.243
+2.190.70.196
+2.190.71.71
+2.190.73.192
+2.190.74.207
+2.190.76.5
+2.190.76.85
+2.190.76.193
+2.190.77.23
+2.190.78.61
+2.190.79.242
+2.190.83.111
+2.190.83.208
+2.190.84.71
+2.190.86.236
+2.190.89.139
+2.190.92.35
+2.190.94.144
+2.190.99.230
+2.190.107.69
+2.190.109.210
+2.190.118.22
+2.190.120.59
+2.190.122.198
+2.190.123.73
+2.190.124.254
+2.190.125.199
+2.190.126.81
+2.190.127.182
+2.190.128.34
+2.190.128.144
+2.190.129.63
+2.190.131.45
+2.190.131.59
+2.190.131.77
+2.190.132.76
+2.190.132.127
+2.190.134.82
+2.190.134.83
+2.190.135.61
+2.190.136.197
+2.190.138.238
+2.190.139.113
+2.190.139.227
+2.190.140.0
+2.190.141.236
+2.190.144.221
+2.190.145.33
+2.190.145.162
+2.190.146.22
+2.190.149.231
+2.190.150.187
+2.190.152.194
+2.190.154.18
+2.190.154.112
+2.190.155.29
+2.190.156.203
+2.190.159.247
+2.190.159.252
+2.190.161.41
+2.190.161.135
+2.190.161.184
+2.190.163.101
+2.190.165.30
+2.190.165.60
+2.190.165.211
+2.190.166.161
+2.190.167.23
+2.190.167.212
+2.190.168.142
+2.190.168.170
+2.190.168.222
+2.190.169.17
+2.190.169.52
+2.190.169.66
+2.190.170.46
+2.190.170.99
+2.190.170.190
+2.190.170.226
+2.190.171.67
+2.190.171.109
+2.190.171.169
+2.190.172.25
+2.190.174.227
+2.190.175.249
+2.190.175.253
+2.190.178.124
+2.190.179.0
+2.190.179.147
+2.190.180.43
+2.190.180.189
+2.190.184.132
+2.190.185.87
+2.190.186.3
+2.190.186.158
+2.190.186.203
+2.190.187.159
+2.190.187.241
+2.190.188.66
+2.190.188.249
+2.190.191.189
+2.190.191.200
+2.190.192.226
+2.190.192.228
+2.190.193.203
+2.190.194.46
+2.190.195.166
+2.190.195.204
+2.190.195.218
+2.190.199.157
+2.190.200.150
+2.190.200.250
+2.190.201.12
+2.190.201.171
+2.190.202.65
+2.190.202.158
+2.190.202.198
+2.190.202.216
+2.190.203.54
+2.190.203.131
+2.190.203.251
+2.190.204.64
+2.190.205.188
+2.190.206.99
+2.190.206.170
+2.190.206.210
+2.190.206.216
+2.190.207.248
+2.190.209.183
+2.190.209.211
+2.190.209.250
+2.190.210.10
+2.190.210.75
+2.190.212.167
+2.190.212.231
+2.190.213.22
+2.190.216.62
+2.190.216.174
+2.190.217.24
+2.190.217.92
+2.190.217.165
+2.190.219.214
+2.190.220.78
+2.190.220.211
+2.190.220.241
+2.190.221.12
+2.190.221.194
+2.190.222.89
+2.190.223.87
+2.190.224.7
+2.190.224.132
+2.190.224.239
+2.190.230.119
+2.190.231.82
+2.190.231.157
+2.190.232.123
+2.190.232.132
+2.190.234.135
+2.190.235.146
+2.190.238.243
+2.190.239.223
+2.190.240.72
+2.190.240.176
+2.190.243.87
+2.190.246.193
+2.190.247.151
+2.190.249.82
+2.190.249.112
+2.190.250.112
+2.190.250.122
+2.190.251.161
+2.190.252.84
+2.190.252.208
+2.190.252.246
+2.190.253.55
+2.190.254.174
+2.190.254.245
+2.190.255.24
+2.190.255.185
+2.191.0.118
+2.191.1.47
+2.191.2.50
+2.191.2.235
+2.191.6.10
+2.191.6.87
+2.191.6.132
+2.191.7.0
+2.191.8.125
+2.191.8.147
+2.191.9.10
+2.191.9.194
+2.191.12.12
+2.191.12.134
+2.191.13.14
+2.191.14.38
+2.191.14.110
+2.191.14.148
+2.191.15.52
+2.191.15.163
+2.191.17.129
+2.191.18.196
+2.191.19.66
+2.191.19.120
+2.191.19.124
+2.191.19.208
+2.191.22.243
+2.191.23.201
+2.191.24.52
+2.191.24.62
+2.191.28.157
+2.191.28.241
+2.191.29.45
+2.191.29.48
+2.191.31.85
+2.191.32.24
+2.191.34.80
+2.191.35.207
+2.191.36.246
+2.191.37.33
+2.191.37.183
+2.191.38.68
+2.191.38.70
+2.191.38.186
+2.191.38.227
+2.191.40.77
+2.191.40.149
+2.191.40.224
+2.191.41.211
+2.191.42.150
+2.191.43.136
+2.191.43.178
+2.191.44.34
+2.191.44.39
+2.191.44.211
+2.191.45.40
+2.191.45.171
+2.191.45.181
+2.191.46.25
+2.191.46.73
+2.191.46.113
+2.191.46.114
+2.191.47.158
+2.191.47.201
+2.191.48.18
+2.191.48.179
+2.191.50.99
+2.191.51.173
+2.191.52.46
+2.191.53.61
+2.191.53.242
+2.191.55.165
+2.191.56.28
+2.191.57.66
+2.191.57.179
+2.191.58.176
+2.191.58.178
+2.191.59.170
+2.191.60.102
+2.191.60.186
+2.191.60.205
+2.191.61.246
+2.191.62.3
+2.191.63.31
+2.191.63.189
+2.191.64.56
+2.191.64.61
+2.191.64.186
+2.191.64.242
+2.191.65.4
+2.191.67.29
+2.191.68.135
+2.191.69.94
+2.191.69.185
+2.191.70.110
+2.191.70.132
+2.191.71.57
+2.191.71.77
+2.191.71.219
+2.191.73.219
+2.191.74.137
+2.191.75.50
+2.191.75.144
+2.191.75.157
+2.191.76.121
+2.191.80.4
+2.191.80.253
+2.191.81.64
+2.191.82.127
+2.191.83.137
+2.191.84.65
+2.191.85.54
+2.191.85.82
+2.191.86.107
+2.191.86.180
+2.191.86.219
+2.191.86.255
+2.191.87.132
+2.191.87.206
+2.191.89.32
+2.191.90.27
+2.191.90.185
+2.191.90.186
+2.191.91.32
+2.191.91.101
+2.191.92.107
+2.191.92.185
+2.191.93.14
+2.191.94.26
+2.191.94.236
+2.191.95.249
+2.191.96.234
+2.191.97.65
+2.191.97.146
+2.191.98.243
+2.191.99.83
+2.191.99.158
+2.191.101.155
+2.191.103.93
+2.191.103.121
+2.191.103.168
+2.191.104.41
+2.191.104.51
+2.191.105.150
+2.191.108.244
+2.191.109.116
+2.191.110.5
+2.191.110.185
+2.191.111.42
+2.191.111.204
+2.191.112.254
+2.191.113.74
+2.191.113.106
+2.191.113.197
+2.191.113.215
+2.191.115.150
+2.191.115.245
+2.191.116.96
+2.191.116.114
+2.191.117.57
+2.191.117.147
+2.191.118.61
+2.191.120.25
+2.191.120.243
+2.191.124.210
+2.191.126.20
+2.191.127.29
+2.191.127.41
+2.191.131.119
+2.191.142.150
+2.191.197.194
+2.191.202.171
+2.191.208.248
+5.10.248.43
+5.10.248.53
+5.10.248.150
+5.10.248.181
+5.10.249.153
+5.10.249.156
+5.10.249.164
+5.10.249.179
+5.10.249.217
+5.10.249.245
+5.22.193.5
+5.22.193.6
+5.22.196.29
+5.22.196.102
+5.22.196.154
+5.22.197.172
+5.22.198.138
+5.22.198.190
+5.22.199.193
+5.22.200.232
+5.22.200.233
+5.22.200.234
+5.22.200.235
+5.22.201.17
+5.22.201.162
+5.22.203.98
+5.22.203.100
+5.22.203.101
+5.22.203.102
+5.42.217.140
+5.42.217.182
+5.42.223.221
+5.56.132.51
+5.56.132.142
+5.56.135.7
+5.57.32.131
+5.57.32.166
+5.57.32.180
+5.57.32.235
+5.57.33.97
+5.57.33.251
+5.57.34.199
+5.57.35.225
+5.57.37.76
+5.57.37.228
+5.57.39.58
+5.61.24.42
+5.61.28.101
+5.61.28.235
+5.61.30.35
+5.61.30.226
+5.61.31.99
+5.62.164.171
+5.63.8.227
+5.63.9.37
+5.63.9.218
+5.63.13.51
+5.63.13.52
+5.63.13.54
+5.63.13.130
+5.74.1.217
+5.74.5.10
+5.74.10.236
+5.74.13.6
+5.74.22.215
+5.74.25.251
+5.74.28.146
+5.74.35.80
+5.74.38.17
+5.74.38.158
+5.74.40.120
+5.74.40.141
+5.74.42.203
+5.74.44.199
+5.74.44.204
+5.74.56.99
+5.74.56.162
+5.74.58.120
+5.74.66.14
+5.74.66.233
+5.74.68.20
+5.74.71.139
+5.74.75.152
+5.74.80.36
+5.74.80.101
+5.74.83.157
+5.74.87.197
+5.74.89.177
+5.74.94.17
+5.74.97.165
+5.74.98.28
+5.74.100.96
+5.74.101.87
+5.74.105.229
+5.74.106.250
+5.74.111.74
+5.74.112.154
+5.74.113.149
+5.74.121.103
+5.74.126.100
+5.74.128.161
+5.74.128.210
+5.74.128.236
+5.74.129.74
+5.74.129.92
+5.74.130.60
+5.74.130.226
+5.74.131.34
+5.74.131.194
+5.74.131.198
+5.74.132.140
+5.74.132.164
+5.74.133.175
+5.74.134.201
+5.74.137.11
+5.74.139.47
+5.74.139.130
+5.74.145.22
+5.74.145.67
+5.74.146.141
+5.74.146.179
+5.74.147.228
+5.74.151.195
+5.74.154.129
+5.74.155.111
+5.74.156.49
+5.74.156.251
+5.74.157.139
+5.74.157.195
+5.74.157.228
+5.74.159.121
+5.74.159.123
+5.74.159.129
+5.74.160.71
+5.74.160.147
+5.74.160.212
+5.74.161.128
+5.74.163.73
+5.74.163.130
+5.74.164.17
+5.74.165.51
+5.74.165.234
+5.74.168.18
+5.74.168.54
+5.74.168.95
+5.74.169.91
+5.74.170.174
+5.74.170.233
+5.74.173.188
+5.74.174.30
+5.74.175.141
+5.74.176.18
+5.74.177.22
+5.74.178.191
+5.74.179.16
+5.74.180.250
+5.74.181.153
+5.74.183.117
+5.74.183.146
+5.74.184.240
+5.74.188.93
+5.74.188.151
+5.74.189.1
+5.74.193.164
+5.74.195.235
+5.74.197.49
+5.74.199.35
+5.74.199.81
+5.74.199.252
+5.74.205.78
+5.74.205.212
+5.74.206.36
+5.74.207.79
+5.74.207.114
+5.74.208.64
+5.74.211.96
+5.74.211.172
+5.74.212.1
+5.74.212.5
+5.74.212.11
+5.74.212.234
+5.74.215.107
+5.74.218.2
+5.74.219.171
+5.74.220.57
+5.74.221.24
+5.74.221.80
+5.74.221.102
+5.74.221.140
+5.74.222.115
+5.74.224.18
+5.74.225.117
+5.74.225.239
+5.74.227.193
+5.74.229.131
+5.74.231.56
+5.74.233.92
+5.74.233.254
+5.74.234.101
+5.74.234.181
+5.74.234.223
+5.74.236.142
+5.74.236.167
+5.74.237.240
+5.74.237.247
+5.74.239.195
+5.74.240.11
+5.74.242.17
+5.74.242.107
+5.74.245.153
+5.74.246.116
+5.74.246.192
+5.74.249.45
+5.74.249.231
+5.74.252.166
+5.74.255.153
+5.75.41.226
+5.106.4.130
+5.106.5.129
+5.106.5.130
+5.106.16.59
+5.106.16.163
+5.106.16.248
+5.106.17.59
+5.106.17.60
+5.106.17.61
+5.106.17.62
+5.106.17.64
+5.106.17.65
+5.106.17.66
+5.106.17.67
+5.106.17.77
+5.106.17.128
+5.106.17.129
+5.106.17.134
+5.106.17.135
+5.106.17.147
+5.106.17.161
+5.106.17.163
+5.106.17.172
+5.106.18.59
+5.106.18.62
+5.106.18.63
+5.106.18.90
+5.106.18.170
+5.106.18.176
+5.106.18.192
+5.106.18.218
+5.106.18.221
+5.106.18.235
+5.106.18.241
+5.106.18.252
+5.106.19.13
+5.106.19.45
+5.106.19.47
+5.106.19.48
+5.106.19.49
+5.106.19.50
+5.106.19.51
+5.106.19.53
+5.106.19.54
+5.106.19.56
+5.106.19.58
+5.106.19.60
+5.106.19.79
+5.106.19.89
+5.106.19.93
+5.106.19.95
+5.106.19.116
+5.106.19.126
+5.106.19.179
+5.106.19.188
+5.106.19.193
+5.106.19.195
+5.106.19.205
+5.106.21.62
+5.106.21.84
+5.106.21.103
+5.106.21.126
+5.106.21.154
+5.106.28.32
+5.106.28.115
+5.106.28.172
+5.106.28.198
+5.106.28.203
+5.106.29.212
+5.134.195.80
+5.134.195.162
+5.134.195.197
+5.134.196.195
+5.144.129.83
+5.144.129.177
+5.144.129.236
+5.144.130.94
+5.144.132.7
+5.144.132.98
+5.145.112.53
+5.145.112.57
+5.145.112.225
+5.145.113.1
+5.145.113.58
+5.145.113.60
+5.145.114.73
+5.145.114.83
+5.145.114.85
+5.145.114.98
+5.145.114.99
+5.145.114.112
+5.145.114.113
+5.145.114.115
+5.145.114.211
+5.145.114.222
+5.145.114.225
+5.145.114.234
+5.145.114.236
+5.145.114.239
+5.145.114.243
+5.145.114.249
+5.145.115.17
+5.145.115.170
+5.145.115.213
+5.145.115.217
+5.145.115.225
+5.145.115.232
+5.159.49.107
+5.159.49.207
+5.159.50.49
+5.159.50.50
+5.159.50.53
+5.159.50.55
+5.159.50.57
+5.159.50.58
+5.159.50.61
+5.159.50.194
+5.159.50.197
+5.159.50.198
+5.159.50.200
+5.159.50.201
+5.159.51.5
+5.159.52.25
+5.159.52.26
+5.159.52.27
+5.159.52.28
+5.159.52.29
+5.159.52.73
+5.159.52.76
+5.159.53.56
+5.159.53.81
+5.159.55.50
+5.159.55.53
+5.159.55.62
+5.159.55.105
+5.159.55.113
+5.159.55.121
+5.159.55.129
+5.159.55.150
+5.159.55.153
+5.159.55.181
+5.159.55.182
+5.159.55.249
+5.160.0.125
+5.160.0.127
+5.160.0.195
+5.160.0.222
+5.160.1.26
+5.160.1.42
+5.160.1.43
+5.160.1.44
+5.160.1.90
+5.160.2.38
+5.160.2.226
+5.160.2.227
+5.160.2.228
+5.160.2.229
+5.160.3.34
+5.160.3.104
+5.160.3.116
+5.160.3.174
+5.160.3.226
+5.160.4.147
+5.160.5.99
+5.160.5.100
+5.160.5.101
+5.160.5.102
+5.160.5.162
+5.160.7.214
+5.160.12.244
+5.160.12.247
+5.160.12.251
+5.160.14.203
+5.160.14.204
+5.160.14.205
+5.160.14.206
+5.160.15.10
+5.160.20.130
+5.160.23.98
+5.160.23.102
+5.160.25.180
+5.160.25.206
+5.160.26.30
+5.160.26.74
+5.160.26.75
+5.160.26.77
+5.160.27.150
+5.160.28.236
+5.160.28.238
+5.160.29.4
+5.160.29.44
+5.160.32.190
+5.160.33.2
+5.160.33.254
+5.160.36.48
+5.160.36.60
+5.160.37.8
+5.160.37.46
+5.160.37.147
+5.160.37.192
+5.160.37.201
+5.160.38.46
+5.160.38.78
+5.160.38.189
+5.160.39.98
+5.160.39.250
+5.160.40.4
+5.160.40.39
+5.160.40.44
+5.160.40.56
+5.160.40.62
+5.160.40.71
+5.160.40.154
+5.160.40.173
+5.160.40.250
+5.160.42.34
+5.160.42.46
+5.160.42.202
+5.160.43.18
+5.160.43.62
+5.160.43.82
+5.160.43.110
+5.160.45.138
+5.160.45.220
+5.160.47.67
+5.160.47.82
+5.160.47.119
+5.160.48.53
+5.160.49.14
+5.160.49.26
+5.160.49.74
+5.160.49.75
+5.160.49.76
+5.160.49.77
+5.160.49.78
+5.160.49.98
+5.160.49.100
+5.160.49.101
+5.160.49.104
+5.160.49.108
+5.160.49.109
+5.160.49.226
+5.160.50.6
+5.160.50.130
+5.160.51.241
+5.160.52.90
+5.160.52.91
+5.160.52.92
+5.160.52.93
+5.160.52.94
+5.160.52.234
+5.160.53.94
+5.160.54.26
+5.160.54.27
+5.160.54.28
+5.160.54.29
+5.160.54.30
+5.160.54.118
+5.160.56.2
+5.160.56.30
+5.160.56.50
+5.160.56.118
+5.160.56.174
+5.160.56.228
+5.160.56.249
+5.160.57.34
+5.160.57.35
+5.160.58.129
+5.160.59.18
+5.160.59.19
+5.160.59.20
+5.160.59.29
+5.160.60.6
+5.160.60.43
+5.160.60.166
+5.160.61.2
+5.160.61.161
+5.160.61.162
+5.160.61.163
+5.160.61.164
+5.160.61.166
+5.160.61.169
+5.160.61.170
+5.160.61.171
+5.160.61.172
+5.160.61.173
+5.160.61.174
+5.160.61.251
+5.160.61.254
+5.160.62.88
+5.160.62.89
+5.160.62.91
+5.160.62.160
+5.160.62.164
+5.160.63.34
+5.160.63.38
+5.160.63.126
+5.160.65.18
+5.160.65.19
+5.160.65.20
+5.160.65.21
+5.160.65.22
+5.160.65.25
+5.160.65.26
+5.160.65.27
+5.160.65.28
+5.160.65.29
+5.160.65.30
+5.160.65.190
+5.160.67.98
+5.160.67.102
+5.160.68.1
+5.160.68.50
+5.160.68.226
+5.160.68.229
+5.160.68.230
+5.160.68.231
+5.160.68.232
+5.160.68.233
+5.160.68.234
+5.160.68.235
+5.160.68.236
+5.160.68.238
+5.160.72.22
+5.160.72.53
+5.160.72.134
+5.160.72.222
+5.160.73.88
+5.160.74.147
+5.160.74.226
+5.160.74.227
+5.160.74.228
+5.160.74.229
+5.160.74.230
+5.160.74.232
+5.160.74.233
+5.160.74.254
+5.160.75.10
+5.160.75.90
+5.160.75.207
+5.160.76.106
+5.160.76.170
+5.160.76.171
+5.160.76.198
+5.160.76.226
+5.160.78.18
+5.160.78.86
+5.160.78.104
+5.160.78.134
+5.160.78.154
+5.160.78.238
+5.160.80.33
+5.160.80.98
+5.160.80.193
+5.160.80.194
+5.160.80.210
+5.160.80.211
+5.160.80.214
+5.160.81.177
+5.160.81.187
+5.160.81.251
+5.160.82.110
+5.160.83.18
+5.160.83.66
+5.160.83.117
+5.160.83.122
+5.160.84.34
+5.160.85.195
+5.160.85.234
+5.160.86.34
+5.160.87.51
+5.160.87.106
+5.160.88.34
+5.160.88.35
+5.160.88.36
+5.160.88.37
+5.160.88.38
+5.160.88.39
+5.160.88.40
+5.160.88.41
+5.160.88.42
+5.160.88.43
+5.160.88.44
+5.160.88.45
+5.160.88.46
+5.160.89.99
+5.160.89.194
+5.160.90.61
+5.160.90.86
+5.160.90.218
+5.160.91.180
+5.160.91.190
+5.160.93.210
+5.160.93.246
+5.160.95.194
+5.160.98.131
+5.160.99.4
+5.160.99.5
+5.160.99.6
+5.160.99.8
+5.160.99.9
+5.160.99.10
+5.160.99.11
+5.160.99.12
+5.160.99.13
+5.160.99.14
+5.160.99.15
+5.160.99.19
+5.160.99.20
+5.160.99.227
+5.160.99.229
+5.160.99.230
+5.160.99.231
+5.160.99.232
+5.160.99.235
+5.160.99.237
+5.160.100.8
+5.160.100.114
+5.160.100.118
+5.160.101.2
+5.160.101.244
+5.160.101.245
+5.160.101.246
+5.160.101.247
+5.160.101.249
+5.160.101.250
+5.160.101.251
+5.160.101.252
+5.160.101.253
+5.160.102.201
+5.160.103.42
+5.160.103.43
+5.160.103.46
+5.160.103.67
+5.160.103.114
+5.160.103.162
+5.160.103.185
+5.160.108.74
+5.160.108.210
+5.160.108.222
+5.160.109.186
+5.160.112.46
+5.160.112.145
+5.160.114.126
+5.160.114.132
+5.160.114.134
+5.160.115.42
+5.160.115.50
+5.160.115.51
+5.160.115.52
+5.160.115.53
+5.160.115.54
+5.160.115.130
+5.160.115.134
+5.160.115.138
+5.160.115.190
+5.160.115.210
+5.160.115.238
+5.160.118.86
+5.160.118.93
+5.160.118.110
+5.160.118.178
+5.160.118.186
+5.160.119.130
+5.160.119.210
+5.160.119.225
+5.160.119.228
+5.160.119.242
+5.160.119.250
+5.160.120.14
+5.160.121.6
+5.160.122.150
+5.160.122.226
+5.160.123.138
+5.160.124.155
+5.160.125.38
+5.160.125.46
+5.160.125.138
+5.160.125.186
+5.160.125.234
+5.160.126.139
+5.160.127.67
+5.160.127.68
+5.160.127.69
+5.160.127.70
+5.160.127.90
+5.160.129.118
+5.160.134.82
+5.160.134.83
+5.160.134.84
+5.160.134.85
+5.160.134.86
+5.160.135.46
+5.160.136.122
+5.160.136.162
+5.160.137.54
+5.160.138.227
+5.160.143.225
+5.160.144.9
+5.160.144.15
+5.160.144.19
+5.160.146.199
+5.160.146.233
+5.160.147.18
+5.160.147.226
+5.160.148.49
+5.160.150.138
+5.160.150.139
+5.160.150.140
+5.160.151.204
+5.160.151.206
+5.160.152.166
+5.160.157.75
+5.160.157.100
+5.160.159.84
+5.160.159.178
+5.160.159.181
+5.160.159.189
+5.160.160.42
+5.160.161.5
+5.160.161.18
+5.160.161.19
+5.160.161.33
+5.160.161.41
+5.160.161.45
+5.160.161.62
+5.160.161.66
+5.160.161.73
+5.160.161.84
+5.160.161.98
+5.160.161.99
+5.160.161.101
+5.160.161.117
+5.160.161.121
+5.160.161.122
+5.160.161.123
+5.160.161.127
+5.160.161.129
+5.160.161.142
+5.160.161.148
+5.160.161.152
+5.160.161.168
+5.160.161.176
+5.160.161.179
+5.160.161.180
+5.160.161.187
+5.160.161.197
+5.160.161.200
+5.160.161.219
+5.160.162.43
+5.160.162.44
+5.160.164.86
+5.160.164.93
+5.160.164.211
+5.160.166.20
+5.160.167.14
+5.160.167.60
+5.160.168.10
+5.160.168.85
+5.160.168.130
+5.160.170.2
+5.160.171.36
+5.160.171.47
+5.160.173.151
+5.160.173.190
+5.160.175.250
+5.160.176.27
+5.160.176.165
+5.160.176.208
+5.160.176.222
+5.160.176.242
+5.160.176.243
+5.160.176.245
+5.160.177.6
+5.160.178.50
+5.160.178.155
+5.160.178.157
+5.160.182.45
+5.160.182.65
+5.160.182.73
+5.160.182.77
+5.160.182.85
+5.160.182.88
+5.160.182.90
+5.160.182.101
+5.160.182.111
+5.160.182.119
+5.160.182.127
+5.160.182.130
+5.160.182.146
+5.160.182.155
+5.160.182.168
+5.160.182.180
+5.160.182.184
+5.160.182.197
+5.160.182.201
+5.160.182.208
+5.160.182.211
+5.160.182.219
+5.160.182.228
+5.160.182.229
+5.160.182.236
+5.160.182.245
+5.160.183.150
+5.160.184.90
+5.160.184.202
+5.160.185.86
+5.160.185.122
+5.160.185.222
+5.160.186.14
+5.160.186.42
+5.160.186.43
+5.160.186.44
+5.160.186.45
+5.160.187.44
+5.160.187.78
+5.160.187.98
+5.160.187.122
+5.160.187.126
+5.160.187.247
+5.160.187.254
+5.160.190.34
+5.160.190.38
+5.160.191.197
+5.160.191.242
+5.160.191.243
+5.160.196.126
+5.160.196.210
+5.160.197.207
+5.160.200.182
+5.160.211.170
+5.160.211.218
+5.160.211.219
+5.160.211.220
+5.160.214.110
+5.160.215.230
+5.160.217.254
+5.160.218.167
+5.160.219.72
+5.160.223.254
+5.160.224.225
+5.160.224.226
+5.160.224.227
+5.160.224.228
+5.160.224.229
+5.160.225.66
+5.160.225.116
+5.160.225.163
+5.160.225.174
+5.160.227.238
+5.160.228.190
+5.160.229.187
+5.160.229.234
+5.160.230.130
+5.160.230.250
+5.160.231.10
+5.160.231.130
+5.160.231.214
+5.160.233.16
+5.160.233.150
+5.160.233.226
+5.160.234.189
+5.160.235.130
+5.160.236.155
+5.160.236.158
+5.160.236.216
+5.160.237.118
+5.160.237.208
+5.160.239.98
+5.160.239.226
+5.160.239.250
+5.160.239.251
+5.160.242.48
+5.160.243.107
+5.160.243.238
+5.160.243.254
+5.160.246.29
+5.160.247.50
+5.160.247.230
+5.182.44.18
+5.182.44.124
+5.182.44.132
+5.182.44.134
+5.182.44.161
+5.182.44.184
+5.182.44.190
+5.182.46.185
+5.190.0.68
+5.190.0.178
+5.190.1.71
+5.190.1.79
+5.190.1.145
+5.190.1.161
+5.190.3.109
+5.190.3.110
+5.190.3.113
+5.190.4.17
+5.190.4.249
+5.190.6.41
+5.190.6.73
+5.190.6.241
+5.190.7.113
+5.190.20.1
+5.190.29.161
+5.190.45.70
+5.190.52.225
+5.190.53.6
+5.190.60.161
+5.190.69.68
+5.190.69.70
+5.190.69.73
+5.190.69.74
+5.190.69.75
+5.190.69.80
+5.190.69.89
+5.190.72.113
+5.190.83.70
+5.190.83.77
+5.190.84.112
+5.190.89.101
+5.190.93.133
+5.190.103.130
+5.190.106.210
+5.190.131.1
+5.190.131.230
+5.190.135.173
+5.190.138.125
+5.190.143.81
+5.190.147.1
+5.190.147.3
+5.190.154.164
+5.190.156.3
+5.190.156.4
+5.190.212.241
+5.190.212.242
+5.190.212.243
+5.190.212.245
+5.190.212.246
+5.190.212.247
+5.190.212.251
+5.190.212.252
+5.190.224.15
+5.190.224.23
+5.190.224.27
+5.190.224.37
+5.190.224.39
+5.190.235.10
+5.190.235.35
+5.190.235.74
+5.190.235.81
+5.190.235.117
+5.190.235.131
+5.190.235.160
+5.190.235.163
+5.190.235.168
+5.190.235.171
+5.190.235.183
+5.190.235.196
+5.190.235.209
+5.190.235.214
+5.190.235.247
+5.190.235.249
+5.190.235.254
+5.198.161.12
+5.198.178.64
+5.198.178.80
+5.198.178.160
+5.198.178.180
+5.198.178.237
+5.198.179.20
+5.198.179.50
+5.198.179.130
+5.198.179.190
+5.200.64.193
+5.200.67.24
+5.200.69.30
+5.200.73.82
+5.200.73.83
+5.200.73.84
+5.200.73.162
+5.200.74.66
+5.200.74.90
+5.200.74.91
+5.200.74.92
+5.200.79.14
+5.200.84.129
+5.200.94.45
+5.200.151.10
+5.200.160.21
+5.200.161.223
+5.200.165.21
+5.200.177.233
+5.200.194.25
+5.200.200.26
+5.200.217.213
+5.200.240.10
+5.200.246.248
+5.201.128.76
+5.201.129.44
+5.201.130.70
+5.201.130.106
+5.201.131.60
+5.201.132.27
+5.201.132.139
+5.201.132.143
+5.201.132.201
+5.201.132.246
+5.201.133.78
+5.201.133.162
+5.201.134.23
+5.201.134.222
+5.201.135.104
+5.201.135.127
+5.201.135.162
+5.201.136.54
+5.201.137.187
+5.201.138.9
+5.201.139.194
+5.201.141.202
+5.201.141.246
+5.201.142.74
+5.201.142.205
+5.201.142.220
+5.201.143.155
+5.201.144.80
+5.201.148.92
+5.201.150.103
+5.201.151.139
+5.201.152.225
+5.201.154.29
+5.201.154.149
+5.201.156.81
+5.201.159.173
+5.201.161.182
+5.201.161.210
+5.201.161.211
+5.201.161.212
+5.201.161.213
+5.201.162.150
+5.201.164.167
+5.201.166.105
+5.201.166.132
+5.201.166.143
+5.201.166.182
+5.201.167.42
+5.201.167.223
+5.201.168.123
+5.201.169.48
+5.201.169.124
+5.201.169.191
+5.201.170.24
+5.201.171.57
+5.201.175.251
+5.201.176.244
+5.201.177.48
+5.201.177.68
+5.201.177.93
+5.201.178.6
+5.201.178.10
+5.201.180.250
+5.201.181.247
+5.201.183.202
+5.201.184.237
+5.201.185.40
+5.201.185.163
+5.201.187.150
+5.201.187.226
+5.201.190.57
+5.201.190.239
+5.201.191.11
+5.201.191.114
+5.201.191.255
+5.202.5.114
+5.202.6.77
+5.202.6.129
+5.202.6.194
+5.202.6.196
+5.202.6.197
+5.202.6.204
+5.202.6.206
+5.202.7.19
+5.202.7.226
+5.202.7.230
+5.202.7.232
+5.202.7.234
+5.202.7.238
+5.202.8.43
+5.202.8.186
+5.202.8.187
+5.202.10.40
+5.202.15.213
+5.202.15.218
+5.202.15.219
+5.202.15.222
+5.202.18.113
+5.202.18.134
+5.202.18.169
+5.202.18.208
+5.202.18.210
+5.202.18.211
+5.202.18.212
+5.202.18.213
+5.202.18.216
+5.202.18.217
+5.202.18.218
+5.202.18.219
+5.202.18.220
+5.202.18.221
+5.202.18.222
+5.202.18.223
+5.202.20.11
+5.202.20.17
+5.202.20.44
+5.202.20.53
+5.202.20.54
+5.202.20.60
+5.202.20.79
+5.202.20.81
+5.202.20.149
+5.202.20.157
+5.202.20.161
+5.202.20.173
+5.202.20.178
+5.202.20.184
+5.202.20.196
+5.202.20.197
+5.202.20.207
+5.202.20.242
+5.202.21.11
+5.202.21.45
+5.202.21.57
+5.202.21.91
+5.202.21.136
+5.202.21.137
+5.202.21.245
+5.202.27.14
+5.202.27.142
+5.202.29.35
+5.202.29.196
+5.202.31.64
+5.202.31.65
+5.202.33.2
+5.202.33.9
+5.202.33.11
+5.202.33.32
+5.202.33.50
+5.202.33.68
+5.202.33.86
+5.202.33.123
+5.202.33.126
+5.202.33.151
+5.202.33.165
+5.202.33.179
+5.202.33.216
+5.202.33.237
+5.202.39.129
+5.202.44.20
+5.202.44.103
+5.202.44.106
+5.202.44.112
+5.202.44.162
+5.202.44.181
+5.202.44.189
+5.202.44.192
+5.202.44.196
+5.202.44.208
+5.202.44.222
+5.202.44.229
+5.202.45.20
+5.202.45.41
+5.202.45.53
+5.202.45.67
+5.202.45.92
+5.202.45.110
+5.202.45.130
+5.202.45.185
+5.202.45.201
+5.202.45.233
+5.202.46.0
+5.202.46.13
+5.202.46.38
+5.202.46.69
+5.202.46.74
+5.202.46.98
+5.202.46.109
+5.202.46.124
+5.202.46.162
+5.202.46.182
+5.202.46.191
+5.202.46.210
+5.202.46.221
+5.202.47.0
+5.202.47.5
+5.202.47.29
+5.202.47.64
+5.202.47.71
+5.202.47.107
+5.202.47.108
+5.202.47.141
+5.202.47.215
+5.202.47.253
+5.202.47.255
+5.202.50.73
+5.202.50.113
+5.202.50.114
+5.202.50.115
+5.202.50.116
+5.202.50.118
+5.202.51.81
+5.202.51.82
+5.202.51.83
+5.202.51.84
+5.202.52.6
+5.202.52.81
+5.202.52.138
+5.202.52.155
+5.202.53.100
+5.202.53.158
+5.202.53.161
+5.202.53.174
+5.202.53.186
+5.202.60.14
+5.202.60.202
+5.202.60.242
+5.202.61.160
+5.202.61.192
+5.202.63.40
+5.202.63.58
+5.202.63.60
+5.202.63.62
+5.202.63.125
+5.202.63.210
+5.202.66.2
+5.202.66.9
+5.202.67.1
+5.202.67.134
+5.202.68.10
+5.202.68.13
+5.202.68.14
+5.202.68.18
+5.202.68.21
+5.202.68.23
+5.202.68.34
+5.202.68.38
+5.202.68.65
+5.202.68.90
+5.202.68.116
+5.202.68.150
+5.202.73.50
+5.202.73.134
+5.202.77.46
+5.202.77.53
+5.202.78.8
+5.202.78.18
+5.202.78.23
+5.202.78.35
+5.202.79.163
+5.202.79.164
+5.202.79.194
+5.202.79.203
+5.202.79.210
+5.202.79.213
+5.202.79.214
+5.202.79.215
+5.202.79.217
+5.202.79.220
+5.202.79.222
+5.202.79.225
+5.202.79.227
+5.202.79.228
+5.202.79.229
+5.202.82.102
+5.202.82.118
+5.202.82.146
+5.202.82.190
+5.202.83.5
+5.202.83.59
+5.202.83.102
+5.202.83.118
+5.202.84.9
+5.202.84.21
+5.202.84.47
+5.202.84.63
+5.202.84.68
+5.202.84.85
+5.202.84.101
+5.202.84.150
+5.202.84.152
+5.202.84.161
+5.202.84.178
+5.202.84.207
+5.202.84.219
+5.202.84.247
+5.202.85.43
+5.202.85.66
+5.202.85.154
+5.202.85.186
+5.202.85.255
+5.202.86.26
+5.202.89.41
+5.202.89.89
+5.202.89.90
+5.202.90.40
+5.202.90.51
+5.202.90.56
+5.202.90.79
+5.202.90.93
+5.202.90.99
+5.202.90.103
+5.202.90.157
+5.202.90.170
+5.202.90.195
+5.202.90.196
+5.202.90.204
+5.202.90.214
+5.202.90.221
+5.202.93.144
+5.202.93.207
+5.202.96.3
+5.202.96.9
+5.202.96.10
+5.202.96.11
+5.202.96.31
+5.202.96.32
+5.202.96.37
+5.202.96.38
+5.202.96.49
+5.202.96.50
+5.202.96.51
+5.202.96.57
+5.202.96.66
+5.202.96.78
+5.202.96.83
+5.202.96.87
+5.202.96.92
+5.202.96.101
+5.202.96.109
+5.202.96.111
+5.202.96.118
+5.202.96.121
+5.202.96.126
+5.202.96.131
+5.202.96.134
+5.202.96.140
+5.202.96.146
+5.202.96.147
+5.202.96.160
+5.202.96.164
+5.202.96.171
+5.202.96.175
+5.202.96.177
+5.202.97.19
+5.202.97.20
+5.202.97.23
+5.202.97.24
+5.202.97.46
+5.202.97.49
+5.202.97.51
+5.202.97.59
+5.202.97.74
+5.202.97.79
+5.202.97.81
+5.202.97.93
+5.202.97.94
+5.202.97.100
+5.202.97.103
+5.202.97.107
+5.202.97.124
+5.202.97.126
+5.202.97.128
+5.202.101.89
+5.202.104.12
+5.202.104.14
+5.202.104.34
+5.202.104.62
+5.202.104.158
+5.202.104.166
+5.202.104.220
+5.202.105.9
+5.202.105.24
+5.202.105.31
+5.202.105.104
+5.202.105.111
+5.202.105.119
+5.202.105.120
+5.202.105.154
+5.202.105.208
+5.202.105.229
+5.202.105.240
+5.202.105.253
+5.202.112.10
+5.202.112.118
+5.202.112.154
+5.202.112.191
+5.202.112.197
+5.202.114.92
+5.202.120.35
+5.202.120.43
+5.202.120.82
+5.202.120.96
+5.202.120.97
+5.202.120.114
+5.202.120.123
+5.202.120.126
+5.202.120.163
+5.202.120.164
+5.202.120.169
+5.202.121.5
+5.202.121.6
+5.202.121.26
+5.202.121.154
+5.202.121.164
+5.202.121.222
+5.202.128.225
+5.202.130.2
+5.202.130.7
+5.202.130.41
+5.202.130.89
+5.202.130.110
+5.202.130.112
+5.202.130.179
+5.202.130.188
+5.202.130.195
+5.202.130.208
+5.202.130.213
+5.202.130.223
+5.202.130.224
+5.202.130.237
+5.202.130.239
+5.202.130.244
+5.202.130.249
+5.202.131.12
+5.202.131.21
+5.202.131.37
+5.202.131.38
+5.202.131.59
+5.202.131.68
+5.202.131.95
+5.202.131.151
+5.202.131.152
+5.202.131.160
+5.202.131.161
+5.202.131.162
+5.202.131.170
+5.202.131.190
+5.202.131.199
+5.202.131.203
+5.202.131.209
+5.202.131.212
+5.202.131.224
+5.202.132.5
+5.202.132.9
+5.202.132.36
+5.202.132.43
+5.202.132.55
+5.202.132.77
+5.202.132.83
+5.202.132.97
+5.202.132.119
+5.202.132.123
+5.202.132.124
+5.202.132.128
+5.202.132.133
+5.202.132.150
+5.202.132.189
+5.202.132.193
+5.202.132.197
+5.202.132.200
+5.202.132.204
+5.202.132.217
+5.202.132.228
+5.202.132.231
+5.202.132.232
+5.202.132.233
+5.202.132.252
+5.202.132.254
+5.202.133.0
+5.202.133.3
+5.202.133.40
+5.202.133.50
+5.202.133.56
+5.202.133.60
+5.202.133.69
+5.202.133.84
+5.202.133.110
+5.202.133.135
+5.202.133.139
+5.202.133.144
+5.202.133.146
+5.202.133.160
+5.202.133.163
+5.202.133.166
+5.202.133.168
+5.202.133.231
+5.202.133.244
+5.202.134.9
+5.202.134.38
+5.202.134.74
+5.202.134.99
+5.202.134.117
+5.202.134.131
+5.202.134.133
+5.202.134.166
+5.202.134.180
+5.202.134.196
+5.202.134.252
+5.202.135.8
+5.202.135.14
+5.202.135.17
+5.202.135.23
+5.202.135.65
+5.202.135.93
+5.202.135.96
+5.202.135.119
+5.202.135.132
+5.202.135.134
+5.202.135.140
+5.202.135.155
+5.202.135.162
+5.202.135.165
+5.202.135.201
+5.202.135.221
+5.202.135.226
+5.202.135.236
+5.202.135.243
+5.202.135.254
+5.202.136.0
+5.202.136.3
+5.202.140.48
+5.202.140.49
+5.202.140.50
+5.202.140.51
+5.202.140.52
+5.202.140.53
+5.202.140.54
+5.202.140.55
+5.202.140.65
+5.202.140.66
+5.202.140.67
+5.202.140.68
+5.202.140.69
+5.202.140.70
+5.202.140.80
+5.202.140.82
+5.202.140.83
+5.202.140.84
+5.202.140.85
+5.202.140.86
+5.202.140.87
+5.202.140.88
+5.202.140.89
+5.202.140.90
+5.202.140.91
+5.202.140.93
+5.202.140.94
+5.202.162.67
+5.202.162.75
+5.202.162.76
+5.202.163.9
+5.202.163.13
+5.202.163.80
+5.202.163.158
+5.202.163.183
+5.202.164.118
+5.202.165.112
+5.202.166.250
+5.202.166.254
+5.202.167.1
+5.202.167.30
+5.202.167.108
+5.202.167.222
+5.202.167.252
+5.202.168.0
+5.202.168.18
+5.202.168.53
+5.202.168.71
+5.202.168.93
+5.202.168.117
+5.202.168.133
+5.202.168.140
+5.202.168.149
+5.202.168.166
+5.202.168.173
+5.202.168.178
+5.202.168.180
+5.202.168.196
+5.202.168.207
+5.202.168.211
+5.202.169.2
+5.202.169.29
+5.202.169.33
+5.202.169.38
+5.202.169.80
+5.202.169.119
+5.202.169.142
+5.202.169.145
+5.202.169.155
+5.202.169.161
+5.202.169.162
+5.202.169.191
+5.202.169.192
+5.202.169.198
+5.202.170.33
+5.202.170.63
+5.202.170.100
+5.202.170.110
+5.202.170.111
+5.202.170.145
+5.202.170.153
+5.202.170.163
+5.202.170.178
+5.202.170.181
+5.202.170.187
+5.202.170.214
+5.202.170.219
+5.202.170.242
+5.202.171.35
+5.202.171.45
+5.202.171.62
+5.202.171.68
+5.202.171.82
+5.202.171.102
+5.202.171.105
+5.202.171.108
+5.202.171.120
+5.202.171.124
+5.202.171.128
+5.202.171.229
+5.202.172.3
+5.202.172.14
+5.202.172.27
+5.202.172.36
+5.202.172.56
+5.202.172.65
+5.202.172.67
+5.202.172.70
+5.202.172.134
+5.202.172.157
+5.202.172.176
+5.202.172.189
+5.202.172.200
+5.202.172.225
+5.202.172.233
+5.202.172.237
+5.202.172.239
+5.202.172.254
+5.202.174.27
+5.202.174.28
+5.202.174.33
+5.202.174.56
+5.202.174.73
+5.202.174.90
+5.202.174.170
+5.202.174.183
+5.202.174.225
+5.202.174.229
+5.202.174.233
+5.202.174.245
+5.202.175.1
+5.202.175.46
+5.202.175.52
+5.202.175.121
+5.202.175.143
+5.202.175.148
+5.202.175.165
+5.202.175.169
+5.202.175.179
+5.202.175.193
+5.202.175.207
+5.202.175.227
+5.202.175.242
+5.202.176.154
+5.202.176.166
+5.202.176.170
+5.202.177.45
+5.202.177.50
+5.202.177.51
+5.202.177.52
+5.202.177.53
+5.202.177.54
+5.202.177.114
+5.202.177.115
+5.202.177.116
+5.202.177.118
+5.202.177.122
+5.202.177.166
+5.202.177.194
+5.202.177.195
+5.202.177.196
+5.202.177.197
+5.202.177.198
+5.202.177.254
+5.202.178.67
+5.202.178.86
+5.202.179.2
+5.202.179.3
+5.202.179.4
+5.202.179.5
+5.202.179.6
+5.202.179.7
+5.202.179.8
+5.202.179.9
+5.202.179.10
+5.202.179.12
+5.202.179.13
+5.202.179.14
+5.202.179.50
+5.202.179.138
+5.202.179.170
+5.202.179.171
+5.202.179.172
+5.202.179.173
+5.202.179.174
+5.202.180.46
+5.202.182.2
+5.202.182.102
+5.202.182.210
+5.202.182.222
+5.202.184.90
+5.202.184.242
+5.202.185.38
+5.202.185.206
+5.202.186.70
+5.202.186.229
+5.202.188.2
+5.202.188.211
+5.202.188.212
+5.202.188.213
+5.202.189.18
+5.202.189.242
+5.202.190.14
+5.202.190.18
+5.202.190.19
+5.202.190.20
+5.202.190.217
+5.202.191.42
+5.202.191.78
+5.202.191.126
+5.202.191.186
+5.202.191.225
+5.202.191.245
+5.202.193.14
+5.202.193.29
+5.202.193.61
+5.202.193.62
+5.202.193.77
+5.202.193.85
+5.202.193.102
+5.202.193.115
+5.202.193.134
+5.202.193.147
+5.202.193.152
+5.202.193.210
+5.202.193.225
+5.202.193.229
+5.202.194.249
+5.202.195.4
+5.202.195.14
+5.202.195.16
+5.202.195.83
+5.202.195.97
+5.202.195.133
+5.202.195.143
+5.202.195.147
+5.202.195.162
+5.202.195.165
+5.202.195.205
+5.202.195.217
+5.202.196.7
+5.202.196.14
+5.202.196.16
+5.202.196.35
+5.202.196.54
+5.202.196.62
+5.202.196.75
+5.202.196.76
+5.202.196.81
+5.202.196.103
+5.202.196.105
+5.202.196.184
+5.202.196.198
+5.202.196.206
+5.202.196.246
+5.202.196.253
+5.202.197.2
+5.202.197.3
+5.202.197.9
+5.202.197.27
+5.202.197.60
+5.202.197.61
+5.202.197.102
+5.202.197.103
+5.202.197.111
+5.202.197.201
+5.202.197.217
+5.202.197.224
+5.202.197.227
+5.202.197.241
+5.202.198.11
+5.202.198.23
+5.202.198.27
+5.202.198.69
+5.202.198.79
+5.202.198.85
+5.202.198.102
+5.202.198.107
+5.202.198.116
+5.202.198.124
+5.202.198.136
+5.202.206.115
+5.202.236.68
+5.202.239.59
+5.202.240.32
+5.202.240.34
+5.202.240.35
+5.202.240.38
+5.202.240.39
+5.202.240.42
+5.202.240.45
+5.202.241.54
+5.202.243.0
+5.202.243.4
+5.202.243.5
+5.202.243.106
+5.202.243.134
+5.202.243.142
+5.202.243.147
+5.202.243.157
+5.202.243.165
+5.202.243.191
+5.202.243.226
+5.202.244.4
+5.202.244.38
+5.202.244.44
+5.202.244.98
+5.202.244.127
+5.202.244.129
+5.202.244.134
+5.202.244.181
+5.202.244.184
+5.202.244.211
+5.202.245.11
+5.202.245.38
+5.202.245.42
+5.202.248.20
+5.202.248.36
+5.202.248.47
+5.202.248.48
+5.202.248.58
+5.202.248.68
+5.202.248.70
+5.202.248.74
+5.202.248.78
+5.202.248.93
+5.202.248.106
+5.202.248.107
+5.202.248.111
+5.202.248.148
+5.202.248.190
+5.202.248.194
+5.202.248.196
+5.202.248.200
+5.202.248.219
+5.202.249.21
+5.202.249.169
+5.202.249.170
+5.202.249.178
+5.202.250.10
+5.202.250.81
+5.202.250.153
+5.202.250.155
+5.202.250.156
+5.202.250.157
+5.202.251.32
+5.202.251.46
+5.202.251.57
+5.202.251.80
+5.202.251.94
+5.202.251.116
+5.202.251.152
+5.202.251.162
+5.202.251.212
+5.202.251.235
+5.202.251.237
+5.202.251.243
+5.202.251.254
+5.202.252.27
+5.202.252.28
+5.202.252.29
+5.202.252.126
+5.202.252.250
+5.202.252.252
+5.202.252.253
+5.202.253.3
+5.202.253.6
+5.202.253.10
+5.202.253.11
+5.202.253.13
+5.202.253.14
+5.202.253.46
+5.202.253.52
+5.202.253.53
+5.202.253.54
+5.202.253.122
+5.202.253.146
+5.202.254.10
+5.202.254.18
+5.202.254.29
+5.202.254.154
+5.202.254.174
+5.202.254.242
+5.202.255.107
+5.202.255.108
+5.219.64.1
+5.219.128.1
+5.232.97.110
+5.232.103.33
+5.232.104.21
+5.232.116.189
+5.232.119.40
+5.232.119.66
+5.232.124.227
+5.232.126.173
+5.232.128.72
+5.232.128.198
+5.232.132.201
+5.232.140.84
+5.232.140.119
+5.232.141.89
+5.232.144.160
+5.232.149.174
+5.232.155.22
+5.232.157.90
+5.232.176.234
+5.232.177.130
+5.232.177.148
+5.232.178.50
+5.232.178.196
+5.232.179.44
+5.232.179.185
+5.232.181.38
+5.232.181.208
+5.232.182.146
+5.232.183.4
+5.232.184.206
+5.232.185.3
+5.232.185.61
+5.232.185.215
+5.232.186.151
+5.232.186.218
+5.232.186.219
+5.232.187.186
+5.232.188.152
+5.232.188.188
+5.232.189.68
+5.232.189.145
+5.232.190.238
+5.232.191.43
+5.232.191.97
+5.232.192.52
+5.232.192.99
+5.232.192.180
+5.232.193.62
+5.232.193.180
+5.232.193.202
+5.232.193.222
+5.232.194.139
+5.232.194.165
+5.232.195.238
+5.232.196.102
+5.232.197.1
+5.232.197.13
+5.232.197.158
+5.232.197.168
+5.232.197.200
+5.232.198.17
+5.232.199.18
+5.232.199.107
+5.232.199.148
+5.232.200.85
+5.232.201.113
+5.232.201.169
+5.232.201.232
+5.232.201.250
+5.232.202.205
+5.232.202.216
+5.232.204.169
+5.232.205.170
+5.232.207.56
+5.232.208.249
+5.232.209.119
+5.232.211.28
+5.232.213.42
+5.232.213.59
+5.232.213.136
+5.232.214.164
+5.232.215.34
+5.232.215.220
+5.232.215.226
+5.232.238.245
+5.233.44.59
+5.233.44.61
+5.233.94.81
+5.233.94.140
+5.233.94.174
+5.233.205.157
+5.233.205.182
+5.233.248.224
+5.233.249.52
+5.233.254.88
+5.233.254.232
+5.233.255.221
+5.234.0.57
+5.234.0.96
+5.234.0.203
+5.234.2.29
+5.234.2.132
+5.234.3.51
+5.234.3.194
+5.234.5.251
+5.234.10.9
+5.234.11.43
+5.234.12.47
+5.234.13.112
+5.234.14.122
+5.234.14.219
+5.234.15.194
+5.234.19.84
+5.234.20.156
+5.234.20.211
+5.234.21.169
+5.234.21.250
+5.234.22.63
+5.234.24.218
+5.234.25.103
+5.234.26.54
+5.234.26.138
+5.234.26.148
+5.234.28.73
+5.234.28.126
+5.234.28.147
+5.234.29.197
+5.234.32.10
+5.234.32.62
+5.234.32.75
+5.234.32.129
+5.234.33.230
+5.234.34.89
+5.234.35.195
+5.234.44.68
+5.234.44.226
+5.234.46.178
+5.234.68.222
+5.234.91.74
+5.234.166.182
+5.234.179.43
+5.234.215.102
+5.235.152.156
+5.235.152.182
+5.235.153.120
+5.235.155.61
+5.235.155.221
+5.235.156.42
+5.235.156.147
+5.235.156.149
+5.235.157.238
+5.235.158.235
+5.235.159.31
+5.235.160.173
+5.235.161.106
+5.235.162.106
+5.235.163.30
+5.235.163.180
+5.235.164.199
+5.235.164.236
+5.235.166.121
+5.235.170.173
+5.235.171.180
+5.235.171.231
+5.235.173.118
+5.235.174.61
+5.235.175.27
+5.235.176.46
+5.235.176.192
+5.235.176.234
+5.235.177.148
+5.235.179.135
+5.235.180.142
+5.235.181.200
+5.235.182.66
+5.235.182.193
+5.235.182.229
+5.235.183.189
+5.235.185.142
+5.235.185.176
+5.235.186.75
+5.235.186.161
+5.235.186.211
+5.235.186.226
+5.235.186.227
+5.235.187.111
+5.235.187.127
+5.235.189.58
+5.235.195.238
+5.235.196.83
+5.235.196.136
+5.235.197.225
+5.235.198.83
+5.235.199.92
+5.235.201.252
+5.235.202.22
+5.235.204.30
+5.235.204.191
+5.235.205.157
+5.235.219.169
+5.235.220.184
+5.235.220.187
+5.235.222.138
+5.235.223.201
+5.235.224.154
+5.235.225.248
+5.235.226.101
+5.235.226.173
+5.235.226.211
+5.235.227.158
+5.235.227.195
+5.235.228.165
+5.235.229.169
+5.235.230.173
+5.235.230.195
+5.235.231.205
+5.235.232.161
+5.235.233.39
+5.235.234.58
+5.235.234.154
+5.235.234.176
+5.235.235.10
+5.235.238.60
+5.235.239.32
+5.235.241.41
+5.235.241.121
+5.235.243.12
+5.235.245.242
+5.235.247.164
+5.235.250.43
+5.235.252.190
+5.235.253.14
+5.235.253.137
+5.235.254.8
+5.235.255.101
+5.236.25.31
+5.236.26.247
+5.236.28.53
+5.236.29.178
+5.236.30.168
+5.236.31.208
+5.236.36.45
+5.236.36.47
+5.236.36.66
+5.236.36.85
+5.236.36.100
+5.236.36.113
+5.236.36.145
+5.236.67.229
+5.236.68.165
+5.236.69.213
+5.236.71.98
+5.236.87.208
+5.236.93.14
+5.236.93.48
+5.236.93.174
+5.236.93.234
+5.236.96.19
+5.236.96.23
+5.236.96.40
+5.236.96.60
+5.236.108.235
+5.236.109.224
+5.236.113.178
+5.236.114.159
+5.236.114.235
+5.236.115.128
+5.236.115.251
+5.236.117.60
+5.236.119.154
+5.236.124.194
+5.236.192.40
+5.236.193.100
+5.236.194.126
+5.236.195.79
+5.236.195.96
+5.236.195.201
+5.236.209.244
+5.236.212.244
+5.236.213.53
+5.236.213.78
+5.236.213.179
+5.236.219.109
+5.236.220.70
+5.236.225.244
+5.236.226.78
+5.236.226.188
+5.236.229.139
+5.236.235.2
+5.236.242.203
+5.236.245.102
+5.236.246.11
+5.236.246.159
+5.236.251.75
+5.237.55.14
+5.237.142.130
+5.237.176.90
+5.237.192.208
+5.237.193.127
+5.237.194.226
+5.237.195.188
+5.237.196.7
+5.237.197.52
+5.237.200.253
+5.237.201.159
+5.237.202.87
+5.237.204.168
+5.237.208.237
+5.237.209.121
+5.237.211.73
+5.237.211.98
+5.237.211.231
+5.237.217.54
+5.237.217.64
+5.237.223.84
+5.237.223.146
+5.237.226.189
+5.237.229.54
+5.237.229.226
+5.237.230.76
+5.237.231.170
+5.237.232.125
+5.237.232.243
+5.237.233.144
+5.237.233.191
+5.237.234.34
+5.237.236.43
+5.237.238.207
+5.237.240.53
+5.237.240.103
+5.237.241.179
+5.237.241.183
+5.237.242.60
+5.237.243.14
+5.237.243.198
+5.237.247.15
+5.237.247.195
+5.237.248.197
+5.237.249.142
+5.237.249.242
+5.237.253.187
+5.237.255.14
+5.237.255.166
+5.238.3.90
+5.238.17.31
+5.238.52.159
+5.238.52.186
+5.238.52.195
+5.238.52.234
+5.238.52.236
+5.238.52.241
+5.238.74.210
+5.238.94.243
+5.238.110.7
+5.238.110.8
+5.238.110.29
+5.238.110.64
+5.238.110.210
+5.238.111.39
+5.238.111.134
+5.238.128.92
+5.238.131.6
+5.238.131.21
+5.238.131.179
+5.238.131.223
+5.238.132.182
+5.238.132.208
+5.238.132.228
+5.238.134.53
+5.238.134.155
+5.238.134.212
+5.238.135.45
+5.238.135.73
+5.238.136.160
+5.238.137.1
+5.238.137.175
+5.238.139.45
+5.238.139.62
+5.238.139.231
+5.238.140.227
+5.238.140.248
+5.238.143.149
+5.238.143.243
+5.238.144.25
+5.238.146.116
+5.238.147.99
+5.238.153.65
+5.238.153.70
+5.238.153.102
+5.238.153.107
+5.238.153.138
+5.238.156.6
+5.238.157.206
+5.238.158.183
+5.238.159.102
+5.238.159.184
+5.238.160.134
+5.238.161.24
+5.238.162.17
+5.238.162.31
+5.238.162.90
+5.238.163.60
+5.238.163.142
+5.238.164.40
+5.238.164.44
+5.238.165.168
+5.238.166.7
+5.238.166.55
+5.238.167.171
+5.238.168.83
+5.238.169.99
+5.238.169.101
+5.238.169.107
+5.238.171.30
+5.238.171.107
+5.238.171.143
+5.238.172.214
+5.238.174.56
+5.238.174.129
+5.238.174.245
+5.238.176.1
+5.238.176.59
+5.238.176.95
+5.238.177.5
+5.238.177.236
+5.238.177.239
+5.238.181.65
+5.238.184.197
+5.238.185.39
+5.238.185.123
+5.238.186.41
+5.238.187.168
+5.238.189.167
+5.238.190.228
+5.238.191.5
+5.238.195.78
+5.238.195.138
+5.238.196.51
+5.238.196.107
+5.238.196.129
+5.238.196.169
+5.238.197.118
+5.238.199.24
+5.238.202.108
+5.238.203.16
+5.238.203.28
+5.238.203.154
+5.238.204.82
+5.238.204.224
+5.238.205.112
+5.238.206.175
+5.238.207.60
+5.238.208.233
+5.238.210.11
+5.238.210.66
+5.238.210.236
+5.238.211.85
+5.238.211.121
+5.238.211.148
+5.238.212.191
+5.238.213.86
+5.238.214.195
+5.238.217.57
+5.238.217.219
+5.238.218.144
+5.238.218.227
+5.238.223.38
+5.238.227.11
+5.238.227.85
+5.238.227.104
+5.238.227.171
+5.238.227.173
+5.238.228.116
+5.238.229.131
+5.238.229.246
+5.238.230.79
+5.238.232.178
+5.238.232.190
+5.238.234.48
+5.238.235.95
+5.238.237.166
+5.238.239.165
+5.238.240.235
+5.238.241.45
+5.238.241.116
+5.238.242.137
+5.238.242.204
+5.238.245.225
+5.238.246.114
+5.238.246.145
+5.238.247.72
+5.238.247.89
+5.238.248.90
+5.238.249.80
+5.238.250.153
+5.238.251.77
+5.238.251.170
+5.238.252.216
+5.238.254.51
+5.238.255.98
+5.239.0.243
+5.239.1.191
+5.239.2.25
+5.239.2.223
+5.239.3.128
+5.239.3.164
+5.239.7.14
+5.239.7.49
+5.239.7.104
+5.239.8.209
+5.239.9.11
+5.239.9.56
+5.239.9.183
+5.239.9.228
+5.239.10.48
+5.239.11.58
+5.239.11.197
+5.239.12.67
+5.239.13.160
+5.239.14.202
+5.239.15.7
+5.239.15.157
+5.239.17.149
+5.239.17.177
+5.239.18.248
+5.239.21.24
+5.239.21.85
+5.239.22.32
+5.239.22.107
+5.239.22.173
+5.239.23.71
+5.239.23.138
+5.239.24.181
+5.239.25.176
+5.239.26.131
+5.239.26.170
+5.239.26.174
+5.239.28.44
+5.239.30.38
+5.239.30.171
+5.239.31.129
+5.239.31.205
+5.239.32.77
+5.239.33.6
+5.239.34.56
+5.239.35.31
+5.239.35.252
+5.239.36.41
+5.239.37.171
+5.239.38.117
+5.239.42.232
+5.239.43.35
+5.239.44.129
+5.239.44.132
+5.239.45.109
+5.239.45.164
+5.239.45.178
+5.239.45.211
+5.239.46.185
+5.239.46.239
+5.239.49.138
+5.239.50.156
+5.239.51.83
+5.239.53.5
+5.239.53.127
+5.239.55.249
+5.239.56.81
+5.239.56.218
+5.239.58.175
+5.239.58.192
+5.239.59.106
+5.239.59.250
+5.239.60.38
+5.239.60.45
+5.239.62.32
+5.239.63.47
+5.239.63.100
+5.239.63.159
+5.239.63.216
+5.239.64.246
+5.239.66.72
+5.239.66.141
+5.239.66.143
+5.239.66.212
+5.239.69.80
+5.239.70.40
+5.239.70.212
+5.239.71.72
+5.239.71.251
+5.239.73.218
+5.239.73.230
+5.239.75.6
+5.239.75.79
+5.239.75.145
+5.239.76.59
+5.239.76.241
+5.239.78.125
+5.239.79.2
+5.239.80.135
+5.239.81.222
+5.239.82.151
+5.239.83.12
+5.239.84.66
+5.239.84.170
+5.239.85.99
+5.239.86.243
+5.239.86.253
+5.239.88.48
+5.239.88.163
+5.239.89.252
+5.239.89.254
+5.239.91.70
+5.239.91.80
+5.239.91.161
+5.239.92.104
+5.239.96.85
+5.239.99.99
+5.239.102.203
+5.239.103.229
+5.239.104.116
+5.239.104.243
+5.239.107.132
+5.239.108.58
+5.239.108.81
+5.239.108.221
+5.239.109.52
+5.239.110.66
+5.239.110.108
+5.239.112.30
+5.239.112.157
+5.239.114.208
+5.239.115.216
+5.239.117.1
+5.239.117.174
+5.239.117.179
+5.239.118.56
+5.239.118.198
+5.239.118.217
+5.239.119.100
+5.239.119.178
+5.239.119.183
+5.239.119.207
+5.239.121.137
+5.239.121.216
+5.239.124.95
+5.239.125.35
+5.239.127.128
+5.239.127.172
+5.239.149.170
+5.239.157.217
+5.239.158.188
+5.239.160.15
+5.239.160.75
+5.239.160.105
+5.239.160.125
+5.239.160.143
+5.239.161.33
+5.239.161.49
+5.239.161.87
+5.239.161.109
+5.239.161.147
+5.239.161.178
+5.239.161.194
+5.239.176.2
+5.239.177.48
+5.239.177.69
+5.239.177.163
+5.239.177.237
+5.239.197.37
+5.239.199.8
+5.239.202.231
+5.239.230.12
+5.239.231.88
+5.239.237.119
+5.239.239.25
+5.239.240.88
+5.239.240.91
+5.239.240.193
+5.239.240.197
+5.239.240.200
+5.239.240.238
+5.239.241.12
+5.239.241.28
+5.239.241.71
+5.239.241.195
+5.239.245.137
+5.239.245.192
+5.239.245.240
+5.239.245.245
+5.239.245.249
+5.239.245.250
+5.252.216.3
+5.252.216.4
+31.7.64.4
+31.7.64.6
+31.7.64.81
+31.7.65.18
+31.7.65.22
+31.7.65.55
+31.7.65.57
+31.7.65.82
+31.7.65.83
+31.7.66.75
+31.7.66.146
+31.7.66.147
+31.7.68.249
+31.7.69.220
+31.7.71.9
+31.7.72.60
+31.7.72.146
+31.7.73.38
+31.7.73.67
+31.7.73.77
+31.7.73.85
+31.7.73.132
+31.7.74.49
+31.7.78.16
+31.7.78.26
+31.7.78.46
+31.7.78.47
+31.7.78.109
+31.7.91.159
+31.7.91.166
+31.7.110.218
+31.14.112.210
+31.14.113.237
+31.14.114.83
+31.14.114.84
+31.14.114.85
+31.14.114.86
+31.14.114.87
+31.14.114.88
+31.14.114.89
+31.14.114.90
+31.14.114.91
+31.14.114.92
+31.14.114.94
+31.14.114.165
+31.14.117.116
+31.14.117.178
+31.14.117.180
+31.14.117.226
+31.14.117.227
+31.14.118.123
+31.14.118.125
+31.14.118.126
+31.14.119.162
+31.14.119.166
+31.14.120.54
+31.14.124.45
+31.14.124.195
+31.14.126.31
+31.14.126.40
+31.14.126.85
+31.14.126.88
+31.14.126.120
+31.14.127.139
+31.14.127.183
+31.24.201.108
+31.25.90.14
+31.25.90.43
+31.25.91.7
+31.25.92.13
+31.25.92.15
+31.25.92.24
+31.25.92.31
+31.25.92.44
+31.25.92.63
+31.25.92.64
+31.25.92.71
+31.25.92.73
+31.25.92.74
+31.25.92.97
+31.25.92.138
+31.25.92.153
+31.25.92.173
+31.25.92.194
+31.25.92.198
+31.25.92.205
+31.25.92.214
+31.25.92.243
+31.25.93.8
+31.25.93.18
+31.25.93.45
+31.25.93.163
+31.25.94.1
+31.25.94.106
+31.25.95.2
+31.25.95.32
+31.25.95.184
+31.25.95.216
+31.25.128.105
+31.25.128.132
+31.25.129.39
+31.25.129.163
+31.25.129.247
+31.25.130.8
+31.25.130.228
+31.25.130.239
+31.25.131.164
+31.25.132.30
+31.25.132.49
+31.25.132.85
+31.25.132.253
+31.25.134.99
+31.25.134.148
+31.25.134.150
+31.25.134.233
+31.25.134.240
+31.25.135.50
+31.25.135.80
+31.25.135.81
+31.25.135.93
+31.25.135.173
+31.25.135.236
+31.47.32.34
+31.47.33.10
+31.47.33.11
+31.47.33.12
+31.47.33.194
+31.47.34.42
+31.47.34.74
+31.47.35.34
+31.47.39.194
+31.47.45.227
+31.47.48.3
+31.47.48.4
+31.47.48.5
+31.47.48.6
+31.47.48.7
+31.47.48.8
+31.47.48.10
+31.47.48.11
+31.47.48.13
+31.47.48.15
+31.47.48.19
+31.47.48.22
+31.47.51.55
+31.47.52.27
+31.47.52.110
+31.47.54.90
+31.47.58.98
+31.47.61.190
+31.47.61.234
+31.130.181.241
+31.130.181.254
+31.130.182.12
+31.130.182.13
+31.170.49.245
+31.170.50.59
+31.170.52.61
+31.170.52.106
+31.170.52.132
+31.170.52.191
+31.170.52.197
+31.170.52.248
+31.170.53.0
+31.170.53.86
+31.170.57.21
+31.170.57.71
+31.170.58.30
+31.170.59.26
+31.170.59.98
+31.170.59.133
+31.170.59.225
+31.170.60.16
+31.170.60.20
+31.170.60.90
+31.170.60.99
+31.170.60.111
+31.170.60.146
+31.170.60.182
+31.170.60.210
+31.170.60.230
+31.170.61.161
+31.170.61.165
+31.170.61.173
+31.170.61.237
+31.184.129.77
+31.184.129.106
+31.184.144.34
+31.184.147.78
+31.184.147.88
+31.184.147.149
+31.184.147.161
+31.184.147.170
+31.184.166.2
+31.184.167.2
+31.184.170.80
+31.184.170.98
+31.184.170.100
+31.184.170.150
+31.184.170.169
+31.184.170.178
+31.184.170.234
+31.184.171.110
+31.184.171.216
+31.184.175.2
+31.184.176.176
+31.184.177.136
+31.184.178.11
+31.184.178.224
+31.184.178.228
+31.184.179.218
+31.184.179.219
+31.184.188.1
+31.184.188.8
+31.184.188.10
+31.184.188.14
+31.184.188.18
+31.184.188.26
+31.184.188.27
+31.184.188.28
+31.184.188.42
+31.184.188.45
+31.184.188.62
+31.184.188.64
+31.184.188.70
+31.184.188.74
+31.184.188.81
+31.184.188.91
+31.184.188.99
+31.184.188.105
+31.184.188.119
+31.184.188.120
+31.184.188.131
+31.184.188.135
+31.184.188.136
+31.184.188.137
+31.184.188.143
+31.184.188.161
+31.184.188.163
+31.184.188.166
+31.184.188.170
+31.184.188.174
+31.184.188.179
+31.184.188.184
+31.184.188.191
+31.184.188.201
+31.184.188.205
+31.184.188.216
+31.184.188.221
+31.184.188.224
+31.184.188.226
+31.184.188.227
+31.184.188.230
+31.184.188.231
+31.184.188.232
+31.184.188.239
+31.184.189.10
+31.184.189.22
+31.184.189.27
+31.184.189.29
+31.184.189.35
+31.184.189.41
+31.184.189.46
+31.184.189.48
+31.184.189.50
+31.184.189.57
+31.184.189.67
+31.184.189.68
+31.184.189.88
+31.184.189.97
+31.184.189.98
+31.184.189.109
+31.184.189.120
+31.184.189.127
+31.184.189.146
+31.184.189.151
+31.184.189.152
+31.184.189.153
+31.184.189.157
+31.184.189.179
+31.184.189.184
+31.184.189.187
+31.184.189.199
+31.184.189.208
+31.184.189.213
+31.184.189.233
+31.184.189.234
+31.184.189.236
+31.184.189.237
+31.184.189.246
+31.184.190.2
+31.184.190.10
+31.184.190.51
+31.184.190.56
+31.184.190.64
+31.184.190.77
+31.184.190.84
+31.184.190.100
+31.184.190.101
+31.184.190.104
+31.184.190.111
+31.184.190.114
+31.184.190.136
+31.184.190.145
+31.184.190.158
+31.184.190.180
+31.184.190.182
+31.184.190.185
+31.184.190.194
+31.184.190.202
+31.184.190.208
+31.184.190.219
+31.184.190.228
+31.184.190.231
+31.184.190.241
+31.184.190.245
+31.184.190.254
+31.184.191.2
+31.184.191.6
+31.184.191.7
+31.184.191.12
+31.184.191.20
+31.184.191.22
+31.184.191.23
+31.184.191.28
+31.184.191.34
+31.184.191.47
+31.184.191.48
+31.184.191.54
+31.184.191.62
+31.184.191.74
+31.184.191.94
+31.184.191.100
+31.184.191.112
+31.184.191.116
+31.184.191.125
+31.184.191.126
+31.184.191.127
+31.184.191.132
+31.184.191.138
+31.184.191.146
+31.184.191.159
+31.184.191.160
+31.184.191.166
+31.184.191.184
+31.184.191.199
+31.184.191.201
+31.184.191.213
+31.184.191.215
+31.184.191.220
+31.184.191.226
+31.184.191.228
+31.184.191.235
+31.184.191.242
+31.184.191.253
+31.214.147.255
+31.214.168.66
+31.214.168.104
+31.214.168.178
+31.214.171.136
+31.214.171.226
+31.214.172.4
+31.214.172.58
+31.214.173.75
+31.214.173.77
+31.214.174.130
+31.214.175.241
+31.214.231.120
+31.214.248.242
+31.214.250.18
+31.214.250.115
+31.214.251.237
+31.214.255.52
+31.214.255.164
+31.214.255.173
+31.216.62.242
+37.10.67.11
+37.10.109.148
+37.32.4.222
+37.32.5.5
+37.32.5.25
+37.32.5.59
+37.32.5.119
+37.32.5.215
+37.32.6.67
+37.32.6.194
+37.32.9.83
+37.32.10.126
+37.32.11.191
+37.32.11.204
+37.32.12.30
+37.32.12.84
+37.32.12.231
+37.32.13.25
+37.32.13.30
+37.32.14.62
+37.32.14.81
+37.32.14.200
+37.32.15.39
+37.32.21.0
+37.32.21.21
+37.32.21.148
+37.32.24.21
+37.32.24.49
+37.32.25.86
+37.32.25.134
+37.32.25.227
+37.32.26.37
+37.32.27.56
+37.32.27.68
+37.32.40.38
+37.32.43.74
+37.32.43.75
+37.32.43.77
+37.32.43.78
+37.32.43.80
+37.32.43.81
+37.32.43.82
+37.32.43.83
+37.32.43.84
+37.32.43.85
+37.32.43.86
+37.32.43.87
+37.32.43.88
+37.32.43.89
+37.32.43.90
+37.32.43.91
+37.32.43.92
+37.32.43.93
+37.32.43.197
+37.32.45.96
+37.32.46.140
+37.32.47.181
+37.32.47.199
+37.32.112.2
+37.32.117.5
+37.32.120.100
+37.32.120.137
+37.32.121.48
+37.32.121.53
+37.32.121.76
+37.32.124.16
+37.32.125.131
+37.32.125.192
+37.32.125.193
+37.32.125.195
+37.32.127.132
+37.32.127.163
+37.75.240.1
+37.75.240.2
+37.75.240.20
+37.75.240.21
+37.75.240.30
+37.75.240.65
+37.75.242.89
+37.75.242.179
+37.75.242.188
+37.75.243.61
+37.75.243.62
+37.75.243.82
+37.75.243.146
+37.75.243.154
+37.75.243.195
+37.75.243.254
+37.75.244.22
+37.75.244.26
+37.75.244.50
+37.75.244.52
+37.75.244.53
+37.75.244.122
+37.75.245.77
+37.75.245.80
+37.75.245.131
+37.75.246.54
+37.75.246.138
+37.75.246.241
+37.75.246.242
+37.75.246.243
+37.75.246.244
+37.75.246.246
+37.75.247.176
+37.75.247.177
+37.75.247.178
+37.75.247.182
+37.98.112.30
+37.98.112.210
+37.98.118.100
+37.114.204.42
+37.114.204.114
+37.114.204.230
+37.114.205.66
+37.114.205.67
+37.114.205.68
+37.114.205.69
+37.114.205.70
+37.114.205.74
+37.114.225.82
+37.114.225.84
+37.114.225.85
+37.114.225.138
+37.114.246.46
+37.114.246.196
+37.114.247.50
+37.114.247.202
+37.130.200.3
+37.130.200.29
+37.130.202.36
+37.130.205.2
+37.130.207.2
+37.143.144.8
+37.143.146.240
+37.143.147.34
+37.143.147.58
+37.143.147.78
+37.143.147.123
+37.143.147.133
+37.143.147.147
+37.143.147.150
+37.143.148.3
+37.143.148.9
+37.143.148.20
+37.143.148.31
+37.143.148.36
+37.143.148.72
+37.143.148.75
+37.143.148.83
+37.143.148.99
+37.143.148.100
+37.143.148.114
+37.143.148.120
+37.143.148.153
+37.143.148.164
+37.143.148.184
+37.143.148.188
+37.143.148.192
+37.143.148.208
+37.143.148.252
+37.143.148.253
+37.143.149.0
+37.143.149.1
+37.143.149.2
+37.143.149.3
+37.143.149.4
+37.143.149.5
+37.143.149.7
+37.143.149.8
+37.143.149.9
+37.143.149.10
+37.143.149.11
+37.143.149.12
+37.143.149.13
+37.143.149.14
+37.143.149.15
+37.143.149.16
+37.143.149.18
+37.143.149.20
+37.143.149.21
+37.143.149.22
+37.143.149.23
+37.143.149.24
+37.143.149.25
+37.143.149.26
+37.143.149.27
+37.143.149.28
+37.143.149.29
+37.143.149.30
+37.143.149.31
+37.143.149.32
+37.143.149.33
+37.143.149.34
+37.143.149.35
+37.143.149.36
+37.143.149.37
+37.143.149.38
+37.143.149.39
+37.143.149.40
+37.143.149.41
+37.143.149.42
+37.143.149.43
+37.143.149.44
+37.143.149.45
+37.143.149.46
+37.143.149.47
+37.143.149.48
+37.143.149.49
+37.143.149.50
+37.143.149.51
+37.143.149.52
+37.143.149.53
+37.143.149.54
+37.143.149.55
+37.143.149.57
+37.143.149.58
+37.143.149.59
+37.143.149.64
+37.143.149.65
+37.143.149.67
+37.143.149.68
+37.143.149.69
+37.143.149.70
+37.143.149.71
+37.143.149.72
+37.143.149.73
+37.143.149.74
+37.143.149.75
+37.143.149.76
+37.143.149.77
+37.143.149.78
+37.143.149.79
+37.143.149.80
+37.143.149.82
+37.143.149.83
+37.143.149.84
+37.143.149.85
+37.143.149.86
+37.143.149.87
+37.143.149.88
+37.143.149.89
+37.143.149.90
+37.143.149.92
+37.143.149.93
+37.143.149.94
+37.143.149.95
+37.143.149.96
+37.143.149.97
+37.143.149.98
+37.143.149.99
+37.143.149.100
+37.143.149.101
+37.143.149.102
+37.143.149.103
+37.143.149.104
+37.143.149.105
+37.143.149.106
+37.143.149.107
+37.143.149.108
+37.143.149.109
+37.143.149.110
+37.143.149.111
+37.143.149.112
+37.143.149.113
+37.143.149.114
+37.143.149.116
+37.143.149.117
+37.143.149.118
+37.143.149.119
+37.143.149.120
+37.143.149.121
+37.143.149.122
+37.143.149.123
+37.143.149.124
+37.143.149.125
+37.143.149.126
+37.143.149.127
+37.143.151.40
+37.143.151.78
+37.143.151.82
+37.143.151.89
+37.143.151.108
+37.143.151.157
+37.143.151.162
+37.143.151.192
+37.143.151.210
+37.143.151.219
+37.148.0.4
+37.148.0.8
+37.148.0.22
+37.148.0.32
+37.148.0.55
+37.148.0.60
+37.148.0.73
+37.148.0.77
+37.148.0.80
+37.148.0.82
+37.148.0.88
+37.148.0.99
+37.148.0.103
+37.148.0.200
+37.148.0.215
+37.148.0.220
+37.148.0.225
+37.148.0.238
+37.148.0.246
+37.148.1.27
+37.148.1.28
+37.148.1.30
+37.148.1.33
+37.148.1.56
+37.148.1.60
+37.148.1.66
+37.148.1.87
+37.148.1.115
+37.148.1.116
+37.148.1.128
+37.148.1.134
+37.148.1.150
+37.148.1.154
+37.148.1.161
+37.148.1.173
+37.148.1.186
+37.148.1.223
+37.148.1.226
+37.148.1.228
+37.148.1.239
+37.148.2.13
+37.148.2.14
+37.148.2.15
+37.148.2.52
+37.148.2.54
+37.148.2.63
+37.148.2.96
+37.148.2.98
+37.148.2.107
+37.148.2.108
+37.148.2.114
+37.148.2.116
+37.148.2.125
+37.148.2.127
+37.148.2.147
+37.148.2.185
+37.148.2.189
+37.148.2.198
+37.148.2.200
+37.148.2.205
+37.148.2.218
+37.148.2.228
+37.148.2.232
+37.148.2.233
+37.148.2.240
+37.148.2.243
+37.148.3.3
+37.148.3.7
+37.148.3.16
+37.148.3.36
+37.148.3.42
+37.148.3.60
+37.148.3.64
+37.148.3.83
+37.148.3.88
+37.148.3.91
+37.148.3.94
+37.148.3.100
+37.148.3.103
+37.148.3.108
+37.148.3.120
+37.148.3.125
+37.148.3.127
+37.148.3.133
+37.148.3.134
+37.148.3.136
+37.148.3.141
+37.148.3.148
+37.148.3.150
+37.148.3.157
+37.148.3.160
+37.148.3.179
+37.148.3.237
+37.148.3.246
+37.148.4.53
+37.148.4.74
+37.148.4.75
+37.148.4.96
+37.148.4.106
+37.148.4.132
+37.148.4.168
+37.148.4.179
+37.148.4.192
+37.148.5.43
+37.148.5.79
+37.148.5.88
+37.148.5.94
+37.148.5.97
+37.148.5.109
+37.148.5.115
+37.148.5.132
+37.148.5.136
+37.148.5.143
+37.148.5.147
+37.148.5.165
+37.148.5.199
+37.148.5.222
+37.148.5.223
+37.148.5.228
+37.148.5.248
+37.148.6.1
+37.148.6.17
+37.148.6.32
+37.148.6.48
+37.148.6.65
+37.148.6.76
+37.148.6.82
+37.148.6.84
+37.148.6.89
+37.148.6.92
+37.148.6.97
+37.148.6.101
+37.148.6.109
+37.148.6.111
+37.148.6.119
+37.148.6.134
+37.148.6.136
+37.148.6.138
+37.148.6.145
+37.148.6.156
+37.148.6.161
+37.148.6.162
+37.148.6.166
+37.148.6.179
+37.148.6.188
+37.148.6.198
+37.148.6.216
+37.148.6.225
+37.148.6.228
+37.148.6.231
+37.148.6.255
+37.148.7.0
+37.148.7.4
+37.148.7.22
+37.148.7.23
+37.148.7.50
+37.148.7.65
+37.148.7.74
+37.148.7.78
+37.148.7.85
+37.148.7.105
+37.148.7.127
+37.148.7.130
+37.148.7.132
+37.148.7.181
+37.148.7.185
+37.148.7.196
+37.148.7.234
+37.148.8.4
+37.148.8.8
+37.148.8.10
+37.148.8.12
+37.148.8.16
+37.148.8.40
+37.148.8.51
+37.148.8.53
+37.148.8.63
+37.148.8.68
+37.148.8.73
+37.148.8.87
+37.148.8.95
+37.148.8.99
+37.148.8.111
+37.148.8.118
+37.148.8.158
+37.148.8.188
+37.148.8.196
+37.148.8.201
+37.148.8.210
+37.148.8.217
+37.148.8.218
+37.148.8.231
+37.148.8.240
+37.148.8.253
+37.148.9.32
+37.148.9.36
+37.148.9.56
+37.148.9.96
+37.148.9.102
+37.148.9.146
+37.148.9.149
+37.148.9.155
+37.148.9.174
+37.148.9.188
+37.148.9.228
+37.148.9.246
+37.148.10.65
+37.148.10.79
+37.148.10.83
+37.148.10.113
+37.148.10.121
+37.148.10.141
+37.148.10.155
+37.148.10.166
+37.148.10.192
+37.148.10.195
+37.148.10.217
+37.148.10.230
+37.148.11.9
+37.148.11.23
+37.148.11.39
+37.148.11.50
+37.148.11.64
+37.148.11.66
+37.148.11.75
+37.148.11.85
+37.148.11.108
+37.148.11.141
+37.148.11.168
+37.148.11.171
+37.148.11.191
+37.148.11.212
+37.148.11.229
+37.148.11.231
+37.148.11.252
+37.148.12.25
+37.148.12.27
+37.148.12.28
+37.148.12.35
+37.148.12.46
+37.148.12.68
+37.148.12.76
+37.148.12.89
+37.148.12.129
+37.148.12.145
+37.148.12.152
+37.148.12.158
+37.148.12.160
+37.148.12.162
+37.148.12.169
+37.148.12.200
+37.148.12.203
+37.148.12.212
+37.148.12.218
+37.148.12.239
+37.148.12.240
+37.148.12.241
+37.148.13.0
+37.148.13.3
+37.148.13.55
+37.148.13.78
+37.148.13.80
+37.148.13.93
+37.148.13.111
+37.148.13.119
+37.148.13.123
+37.148.13.128
+37.148.13.130
+37.148.13.131
+37.148.13.142
+37.148.13.156
+37.148.13.160
+37.148.13.166
+37.148.13.174
+37.148.13.202
+37.148.13.206
+37.148.13.213
+37.148.13.224
+37.148.13.228
+37.148.13.232
+37.148.13.239
+37.148.13.246
+37.148.14.19
+37.148.14.38
+37.148.14.41
+37.148.14.57
+37.148.14.60
+37.148.14.69
+37.148.14.94
+37.148.14.116
+37.148.14.151
+37.148.14.173
+37.148.14.179
+37.148.14.193
+37.148.14.197
+37.148.14.204
+37.148.14.246
+37.148.15.3
+37.148.15.7
+37.148.15.11
+37.148.15.26
+37.148.15.65
+37.148.15.115
+37.148.15.117
+37.148.15.142
+37.148.15.149
+37.148.15.153
+37.148.15.155
+37.148.15.177
+37.148.15.195
+37.148.15.198
+37.148.15.222
+37.148.15.234
+37.148.15.237
+37.148.16.6
+37.148.16.15
+37.148.16.17
+37.148.16.26
+37.148.16.31
+37.148.16.32
+37.148.16.45
+37.148.16.47
+37.148.16.54
+37.148.16.61
+37.148.16.66
+37.148.16.67
+37.148.16.76
+37.148.16.79
+37.148.16.100
+37.148.16.130
+37.148.16.176
+37.148.16.196
+37.148.16.214
+37.148.16.215
+37.148.16.231
+37.148.16.254
+37.148.16.255
+37.148.17.22
+37.148.17.29
+37.148.17.38
+37.148.17.43
+37.148.17.61
+37.148.17.63
+37.148.17.67
+37.148.17.83
+37.148.17.87
+37.148.17.100
+37.148.17.105
+37.148.17.111
+37.148.17.135
+37.148.17.144
+37.148.17.161
+37.148.17.170
+37.148.17.188
+37.148.17.215
+37.148.17.229
+37.148.17.255
+37.148.18.40
+37.148.18.45
+37.148.18.46
+37.148.18.71
+37.148.18.79
+37.148.18.84
+37.148.18.92
+37.148.18.124
+37.148.18.128
+37.148.18.132
+37.148.18.135
+37.148.18.137
+37.148.18.143
+37.148.18.144
+37.148.18.146
+37.148.18.155
+37.148.18.166
+37.148.18.173
+37.148.18.185
+37.148.18.199
+37.148.18.215
+37.148.18.218
+37.148.18.226
+37.148.18.237
+37.148.18.246
+37.148.18.247
+37.148.19.13
+37.148.19.15
+37.148.19.28
+37.148.19.43
+37.148.19.61
+37.148.19.72
+37.148.19.77
+37.148.19.78
+37.148.19.92
+37.148.19.93
+37.148.19.107
+37.148.19.145
+37.148.19.147
+37.148.19.195
+37.148.19.200
+37.148.19.210
+37.148.19.218
+37.148.20.12
+37.148.20.62
+37.148.20.69
+37.148.20.72
+37.148.20.94
+37.148.20.119
+37.148.20.120
+37.148.20.148
+37.148.20.159
+37.148.20.172
+37.148.20.175
+37.148.20.188
+37.148.20.190
+37.148.20.198
+37.148.20.200
+37.148.20.232
+37.148.20.235
+37.148.20.236
+37.148.20.252
+37.148.21.55
+37.148.21.70
+37.148.21.130
+37.148.21.133
+37.148.21.150
+37.148.21.157
+37.148.21.165
+37.148.21.167
+37.148.21.199
+37.148.21.210
+37.148.21.213
+37.148.21.253
+37.148.22.12
+37.148.22.32
+37.148.22.35
+37.148.22.56
+37.148.22.83
+37.148.22.114
+37.148.22.138
+37.148.22.170
+37.148.22.173
+37.148.22.176
+37.148.22.185
+37.148.22.196
+37.148.22.204
+37.148.22.218
+37.148.22.241
+37.148.22.244
+37.148.23.1
+37.148.23.4
+37.148.23.6
+37.148.23.18
+37.148.23.26
+37.148.23.32
+37.148.23.33
+37.148.23.47
+37.148.23.53
+37.148.23.76
+37.148.23.93
+37.148.23.104
+37.148.23.109
+37.148.23.115
+37.148.23.128
+37.148.23.138
+37.148.23.141
+37.148.23.142
+37.148.23.144
+37.148.23.147
+37.148.23.169
+37.148.23.178
+37.148.23.182
+37.148.23.184
+37.148.23.225
+37.148.24.7
+37.148.24.8
+37.148.24.17
+37.148.24.54
+37.148.24.61
+37.148.24.64
+37.148.24.68
+37.148.24.70
+37.148.24.80
+37.148.24.95
+37.148.24.108
+37.148.24.111
+37.148.24.116
+37.148.24.138
+37.148.24.139
+37.148.24.142
+37.148.24.147
+37.148.24.175
+37.148.24.179
+37.148.24.188
+37.148.24.205
+37.148.24.210
+37.148.24.211
+37.148.24.216
+37.148.24.240
+37.148.24.243
+37.148.24.245
+37.148.25.3
+37.148.25.13
+37.148.25.14
+37.148.25.21
+37.148.25.23
+37.148.25.30
+37.148.25.32
+37.148.25.56
+37.148.25.105
+37.148.25.134
+37.148.25.138
+37.148.25.146
+37.148.25.151
+37.148.25.165
+37.148.25.168
+37.148.25.185
+37.148.25.210
+37.148.25.214
+37.148.25.253
+37.148.26.23
+37.148.26.36
+37.148.26.67
+37.148.26.79
+37.148.26.81
+37.148.26.103
+37.148.26.107
+37.148.26.161
+37.148.26.171
+37.148.26.186
+37.148.26.195
+37.148.26.210
+37.148.26.213
+37.148.26.214
+37.148.26.233
+37.148.26.235
+37.148.26.250
+37.148.27.13
+37.148.27.24
+37.148.27.30
+37.148.27.46
+37.148.27.56
+37.148.27.57
+37.148.27.58
+37.148.27.74
+37.148.27.100
+37.148.27.107
+37.148.27.110
+37.148.27.123
+37.148.27.124
+37.148.27.138
+37.148.27.147
+37.148.27.156
+37.148.27.157
+37.148.27.172
+37.148.27.176
+37.148.27.182
+37.148.27.189
+37.148.27.194
+37.148.27.208
+37.148.27.244
+37.148.27.250
+37.148.27.254
+37.148.28.39
+37.148.28.44
+37.148.28.46
+37.148.28.66
+37.148.28.81
+37.148.28.91
+37.148.28.119
+37.148.28.131
+37.148.28.142
+37.148.28.166
+37.148.28.170
+37.148.28.202
+37.148.28.204
+37.148.28.214
+37.148.28.215
+37.148.28.247
+37.148.28.248
+37.148.29.3
+37.148.29.17
+37.148.29.25
+37.148.29.27
+37.148.29.34
+37.148.29.39
+37.148.29.46
+37.148.29.71
+37.148.29.77
+37.148.29.81
+37.148.29.82
+37.148.29.83
+37.148.29.92
+37.148.29.97
+37.148.29.98
+37.148.29.99
+37.148.29.107
+37.148.29.123
+37.148.29.135
+37.148.29.166
+37.148.29.183
+37.148.29.184
+37.148.29.189
+37.148.29.193
+37.148.29.196
+37.148.29.224
+37.148.29.235
+37.148.29.248
+37.148.30.1
+37.148.30.4
+37.148.30.8
+37.148.30.13
+37.148.30.20
+37.148.30.47
+37.148.30.52
+37.148.30.54
+37.148.30.66
+37.148.30.69
+37.148.30.71
+37.148.30.79
+37.148.30.89
+37.148.30.92
+37.148.30.99
+37.148.30.101
+37.148.30.104
+37.148.30.111
+37.148.30.119
+37.148.30.130
+37.148.30.139
+37.148.30.143
+37.148.30.146
+37.148.30.147
+37.148.30.176
+37.148.30.182
+37.148.30.185
+37.148.30.195
+37.148.30.202
+37.148.30.204
+37.148.30.209
+37.148.30.219
+37.148.30.235
+37.148.30.248
+37.148.30.252
+37.148.31.1
+37.148.31.9
+37.148.31.15
+37.148.31.16
+37.148.31.21
+37.148.31.49
+37.148.31.50
+37.148.31.53
+37.148.31.56
+37.148.31.71
+37.148.31.87
+37.148.31.97
+37.148.31.103
+37.148.31.104
+37.148.31.117
+37.148.31.131
+37.148.31.141
+37.148.31.157
+37.148.31.159
+37.148.31.163
+37.148.31.173
+37.148.31.180
+37.148.31.181
+37.148.31.185
+37.148.31.192
+37.148.31.201
+37.148.31.225
+37.148.31.240
+37.148.31.241
+37.148.31.242
+37.148.31.243
+37.148.31.249
+37.148.31.250
+37.148.40.3
+37.148.40.9
+37.148.40.11
+37.148.40.20
+37.148.40.44
+37.148.40.60
+37.148.40.69
+37.148.40.70
+37.148.40.73
+37.148.40.80
+37.148.40.83
+37.148.40.85
+37.148.40.95
+37.148.40.103
+37.148.40.120
+37.148.40.136
+37.148.40.153
+37.148.40.179
+37.148.40.180
+37.148.40.184
+37.148.40.189
+37.148.40.192
+37.148.40.197
+37.148.40.205
+37.148.40.209
+37.148.40.211
+37.148.40.213
+37.148.40.219
+37.148.40.236
+37.148.40.237
+37.148.40.240
+37.148.40.252
+37.148.41.31
+37.148.41.36
+37.148.41.40
+37.148.41.56
+37.148.41.57
+37.148.41.66
+37.148.41.71
+37.148.41.78
+37.148.41.89
+37.148.41.90
+37.148.41.111
+37.148.41.127
+37.148.41.141
+37.148.41.151
+37.148.41.164
+37.148.41.181
+37.148.41.182
+37.148.41.183
+37.148.41.186
+37.148.41.188
+37.148.41.195
+37.148.41.205
+37.148.41.207
+37.148.41.208
+37.148.41.213
+37.148.41.215
+37.148.41.219
+37.148.41.224
+37.148.42.15
+37.148.42.19
+37.148.42.22
+37.148.42.26
+37.148.42.30
+37.148.42.31
+37.148.42.40
+37.148.42.53
+37.148.42.62
+37.148.42.68
+37.148.42.74
+37.148.42.76
+37.148.42.86
+37.148.42.92
+37.148.42.101
+37.148.42.108
+37.148.42.133
+37.148.42.150
+37.148.42.151
+37.148.42.156
+37.148.42.162
+37.148.42.164
+37.148.42.172
+37.148.42.174
+37.148.42.180
+37.148.42.182
+37.148.42.185
+37.148.42.189
+37.148.42.194
+37.148.42.196
+37.148.42.198
+37.148.42.205
+37.148.42.211
+37.148.42.212
+37.148.42.235
+37.148.42.251
+37.148.43.2
+37.148.43.4
+37.148.43.6
+37.148.43.7
+37.148.43.8
+37.148.43.11
+37.148.43.35
+37.148.43.42
+37.148.43.62
+37.148.43.65
+37.148.43.67
+37.148.43.80
+37.148.43.85
+37.148.43.98
+37.148.43.107
+37.148.43.119
+37.148.43.122
+37.148.43.125
+37.148.43.128
+37.148.43.130
+37.148.43.164
+37.148.43.166
+37.148.43.169
+37.148.43.171
+37.148.43.189
+37.148.43.190
+37.148.43.195
+37.148.43.196
+37.148.43.202
+37.148.43.205
+37.148.43.207
+37.148.43.219
+37.148.43.222
+37.148.43.229
+37.148.43.233
+37.148.43.250
+37.148.44.0
+37.148.44.14
+37.148.44.24
+37.148.44.30
+37.148.44.39
+37.148.44.43
+37.148.44.60
+37.148.44.65
+37.148.44.70
+37.148.44.72
+37.148.44.73
+37.148.44.80
+37.148.44.84
+37.148.44.85
+37.148.44.92
+37.148.44.95
+37.148.44.98
+37.148.44.106
+37.148.44.113
+37.148.44.118
+37.148.44.129
+37.148.44.133
+37.148.44.134
+37.148.44.135
+37.148.44.142
+37.148.44.143
+37.148.44.152
+37.148.44.159
+37.148.44.161
+37.148.44.169
+37.148.44.181
+37.148.44.185
+37.148.44.188
+37.148.44.189
+37.148.44.191
+37.148.44.198
+37.148.44.201
+37.148.44.213
+37.148.44.215
+37.148.44.216
+37.148.44.238
+37.148.44.244
+37.148.44.254
+37.148.45.21
+37.148.45.30
+37.148.45.31
+37.148.45.35
+37.148.45.37
+37.148.45.43
+37.148.45.52
+37.148.45.53
+37.148.45.54
+37.148.45.64
+37.148.45.65
+37.148.45.72
+37.148.45.77
+37.148.45.89
+37.148.45.96
+37.148.45.97
+37.148.45.100
+37.148.45.108
+37.148.45.116
+37.148.45.120
+37.148.45.125
+37.148.45.129
+37.148.45.134
+37.148.45.142
+37.148.45.151
+37.148.45.162
+37.148.45.164
+37.148.45.183
+37.148.45.194
+37.148.45.202
+37.148.45.206
+37.148.45.217
+37.148.46.31
+37.148.46.35
+37.148.46.47
+37.148.46.53
+37.148.46.59
+37.148.46.67
+37.148.46.113
+37.148.46.142
+37.148.46.174
+37.148.46.191
+37.148.46.237
+37.148.47.7
+37.148.47.19
+37.148.47.25
+37.148.47.33
+37.148.47.45
+37.148.47.70
+37.148.47.75
+37.148.47.92
+37.148.47.99
+37.148.47.100
+37.148.47.131
+37.148.47.132
+37.148.47.139
+37.148.47.146
+37.148.47.165
+37.148.48.15
+37.148.48.17
+37.148.48.19
+37.148.48.25
+37.148.48.31
+37.148.48.43
+37.148.48.52
+37.148.48.53
+37.148.48.56
+37.148.48.68
+37.148.48.70
+37.148.48.82
+37.148.48.86
+37.148.48.87
+37.148.48.99
+37.148.48.102
+37.148.48.103
+37.148.48.104
+37.148.48.116
+37.148.48.123
+37.148.48.124
+37.148.48.180
+37.148.48.202
+37.148.48.203
+37.148.48.207
+37.148.48.210
+37.148.48.217
+37.148.48.234
+37.148.48.239
+37.148.48.241
+37.148.48.242
+37.148.48.244
+37.148.48.252
+37.148.49.17
+37.148.49.19
+37.148.49.26
+37.148.49.40
+37.148.49.41
+37.148.49.43
+37.148.49.44
+37.148.49.45
+37.148.49.70
+37.148.49.71
+37.148.49.74
+37.148.49.80
+37.148.49.93
+37.148.49.120
+37.148.49.130
+37.148.49.133
+37.148.49.134
+37.148.49.137
+37.148.49.141
+37.148.49.142
+37.148.49.143
+37.148.49.153
+37.148.49.155
+37.148.49.162
+37.148.49.163
+37.148.49.165
+37.148.49.169
+37.148.49.171
+37.148.49.173
+37.148.49.175
+37.148.49.177
+37.148.49.178
+37.148.49.182
+37.148.49.183
+37.148.49.184
+37.148.49.193
+37.148.49.236
+37.148.50.9
+37.148.50.11
+37.148.50.18
+37.148.50.29
+37.148.50.30
+37.148.50.39
+37.148.50.41
+37.148.50.58
+37.148.50.67
+37.148.50.71
+37.148.50.82
+37.148.50.91
+37.148.50.108
+37.148.50.116
+37.148.50.124
+37.148.50.128
+37.148.50.134
+37.148.50.152
+37.148.50.157
+37.148.50.158
+37.148.50.160
+37.148.50.163
+37.148.50.170
+37.148.50.174
+37.148.50.175
+37.148.50.220
+37.148.50.223
+37.148.50.230
+37.148.50.241
+37.148.50.248
+37.148.51.6
+37.148.51.15
+37.148.51.28
+37.148.51.41
+37.148.51.51
+37.148.51.58
+37.148.51.59
+37.148.51.61
+37.148.51.79
+37.148.51.114
+37.148.51.118
+37.148.51.131
+37.148.51.134
+37.148.51.135
+37.148.51.137
+37.148.51.142
+37.148.51.144
+37.148.51.147
+37.148.51.167
+37.148.51.168
+37.148.51.200
+37.148.51.201
+37.148.51.222
+37.148.51.226
+37.148.56.4
+37.148.56.10
+37.148.56.26
+37.148.56.29
+37.148.56.48
+37.148.56.81
+37.148.56.84
+37.148.56.110
+37.148.56.125
+37.148.56.155
+37.148.56.157
+37.148.56.160
+37.148.56.163
+37.148.56.165
+37.148.56.172
+37.148.56.173
+37.148.56.179
+37.148.56.191
+37.148.56.206
+37.148.56.211
+37.148.56.232
+37.148.57.4
+37.148.57.5
+37.148.57.8
+37.148.57.15
+37.148.57.18
+37.148.57.21
+37.148.57.27
+37.148.57.35
+37.148.57.36
+37.148.57.37
+37.148.57.39
+37.148.57.67
+37.148.57.71
+37.148.57.74
+37.148.57.82
+37.148.57.88
+37.148.57.98
+37.148.57.102
+37.148.57.108
+37.148.57.117
+37.148.57.119
+37.148.57.122
+37.148.57.137
+37.148.57.144
+37.148.57.171
+37.148.57.186
+37.148.57.187
+37.148.57.194
+37.148.57.198
+37.148.57.208
+37.148.57.216
+37.148.57.222
+37.148.57.236
+37.148.57.250
+37.148.58.53
+37.148.58.63
+37.148.58.89
+37.148.58.102
+37.148.58.107
+37.148.58.121
+37.148.58.138
+37.148.58.157
+37.148.58.159
+37.148.58.177
+37.148.58.190
+37.148.58.191
+37.148.58.231
+37.148.58.233
+37.148.58.235
+37.148.58.237
+37.148.59.1
+37.148.59.5
+37.148.59.10
+37.148.59.29
+37.148.59.31
+37.148.59.32
+37.148.59.53
+37.148.59.57
+37.148.59.101
+37.148.59.109
+37.148.59.169
+37.148.59.174
+37.148.59.180
+37.148.59.188
+37.148.59.189
+37.148.59.195
+37.148.59.229
+37.148.59.231
+37.148.59.235
+37.148.59.252
+37.148.60.12
+37.148.60.22
+37.148.60.55
+37.148.60.64
+37.148.60.69
+37.148.60.78
+37.148.60.81
+37.148.60.89
+37.148.60.98
+37.148.60.100
+37.148.60.101
+37.148.60.109
+37.148.60.114
+37.148.60.126
+37.148.60.132
+37.148.60.140
+37.148.60.143
+37.148.60.155
+37.148.60.178
+37.148.60.190
+37.148.60.193
+37.148.60.197
+37.148.60.198
+37.148.60.249
+37.148.61.29
+37.148.61.30
+37.148.61.37
+37.148.61.60
+37.148.61.85
+37.148.61.89
+37.148.61.97
+37.148.61.109
+37.148.61.149
+37.148.61.151
+37.148.61.168
+37.148.61.173
+37.148.61.201
+37.148.61.204
+37.148.61.213
+37.148.61.215
+37.148.61.217
+37.148.61.218
+37.148.61.234
+37.148.61.251
+37.148.62.23
+37.148.62.37
+37.148.62.100
+37.148.62.105
+37.148.62.118
+37.148.62.119
+37.148.62.141
+37.148.62.144
+37.148.62.153
+37.148.62.188
+37.148.62.195
+37.148.62.216
+37.148.62.240
+37.148.62.252
+37.148.63.45
+37.148.63.55
+37.148.63.60
+37.148.63.66
+37.148.63.79
+37.148.63.93
+37.148.63.95
+37.148.63.96
+37.148.63.97
+37.148.63.109
+37.148.63.117
+37.148.63.129
+37.148.63.137
+37.148.63.140
+37.148.63.161
+37.148.63.171
+37.148.63.178
+37.148.63.186
+37.148.63.193
+37.148.63.195
+37.148.63.197
+37.148.63.199
+37.148.63.217
+37.148.63.218
+37.148.63.250
+37.148.80.18
+37.148.80.35
+37.148.80.56
+37.148.80.78
+37.148.80.82
+37.148.80.88
+37.148.80.90
+37.148.80.95
+37.148.80.109
+37.148.80.116
+37.148.80.123
+37.148.80.146
+37.148.80.152
+37.148.80.157
+37.148.80.160
+37.148.80.161
+37.148.80.166
+37.148.80.172
+37.148.80.183
+37.148.80.188
+37.148.80.213
+37.148.80.221
+37.148.80.244
+37.148.81.0
+37.148.81.15
+37.148.81.47
+37.148.81.70
+37.148.81.80
+37.148.81.90
+37.148.81.92
+37.148.81.102
+37.148.81.118
+37.148.81.151
+37.148.81.153
+37.148.81.170
+37.148.81.173
+37.148.81.180
+37.148.81.194
+37.148.81.220
+37.148.81.224
+37.148.81.233
+37.148.81.234
+37.148.81.245
+37.148.82.9
+37.148.82.13
+37.148.82.28
+37.148.82.36
+37.148.82.48
+37.148.82.49
+37.148.82.56
+37.148.82.63
+37.148.82.69
+37.148.82.75
+37.148.82.88
+37.148.82.112
+37.148.82.113
+37.148.82.124
+37.148.82.134
+37.148.82.139
+37.148.82.152
+37.148.82.159
+37.148.82.161
+37.148.82.166
+37.148.82.170
+37.148.82.174
+37.148.82.184
+37.148.82.193
+37.148.82.212
+37.148.82.213
+37.148.82.223
+37.148.82.226
+37.148.82.245
+37.148.83.2
+37.148.83.5
+37.148.83.9
+37.148.83.25
+37.148.83.28
+37.148.83.36
+37.148.83.37
+37.148.83.46
+37.148.83.62
+37.148.83.68
+37.148.83.76
+37.148.83.141
+37.148.83.169
+37.148.83.179
+37.148.83.194
+37.148.83.221
+37.148.83.223
+37.148.83.230
+37.148.83.252
+37.148.83.255
+37.148.84.4
+37.148.84.10
+37.148.84.19
+37.148.84.44
+37.148.84.46
+37.148.84.48
+37.148.84.60
+37.148.84.62
+37.148.84.64
+37.148.84.66
+37.148.84.80
+37.148.84.115
+37.148.84.155
+37.148.84.161
+37.148.84.162
+37.148.84.163
+37.148.84.165
+37.148.84.188
+37.148.84.195
+37.148.84.227
+37.148.84.238
+37.148.84.240
+37.148.84.242
+37.148.84.243
+37.148.84.247
+37.148.85.19
+37.148.85.21
+37.148.85.24
+37.148.85.57
+37.148.85.62
+37.148.85.78
+37.148.85.83
+37.148.85.90
+37.148.85.94
+37.148.85.95
+37.148.85.102
+37.148.85.105
+37.148.85.115
+37.148.85.125
+37.148.85.131
+37.148.85.132
+37.148.85.141
+37.148.85.159
+37.148.85.175
+37.148.85.209
+37.148.85.211
+37.148.85.212
+37.148.85.218
+37.148.85.223
+37.148.85.243
+37.148.86.26
+37.148.86.42
+37.148.86.48
+37.148.86.55
+37.148.86.57
+37.148.86.85
+37.148.86.88
+37.148.86.94
+37.148.86.102
+37.148.86.110
+37.148.86.129
+37.148.86.139
+37.148.86.144
+37.148.86.149
+37.148.86.170
+37.148.86.209
+37.148.86.213
+37.148.86.243
+37.148.86.249
+37.148.87.2
+37.148.87.19
+37.148.87.25
+37.148.87.26
+37.148.87.29
+37.148.87.42
+37.148.87.44
+37.148.87.49
+37.148.87.65
+37.148.87.74
+37.148.87.76
+37.148.87.78
+37.148.87.83
+37.148.87.88
+37.148.87.90
+37.148.87.91
+37.148.87.92
+37.148.87.100
+37.148.87.110
+37.148.87.117
+37.148.87.118
+37.148.87.140
+37.148.87.144
+37.148.87.150
+37.148.87.161
+37.148.87.169
+37.148.87.173
+37.148.87.181
+37.148.87.182
+37.148.87.184
+37.148.87.192
+37.148.87.198
+37.148.87.214
+37.148.87.219
+37.148.87.223
+37.148.87.229
+37.148.87.230
+37.148.87.236
+37.148.87.248
+37.148.87.250
+37.148.87.251
+37.148.87.253
+37.148.90.12
+37.148.90.13
+37.148.90.18
+37.148.90.22
+37.148.90.34
+37.148.90.47
+37.148.90.51
+37.148.90.56
+37.148.90.66
+37.148.90.84
+37.148.90.93
+37.148.90.102
+37.148.90.118
+37.148.90.119
+37.148.90.124
+37.148.90.132
+37.148.90.176
+37.148.90.223
+37.148.90.240
+37.152.160.42
+37.152.161.45
+37.152.163.14
+37.152.163.69
+37.152.163.132
+37.152.163.145
+37.152.163.148
+37.152.163.160
+37.152.163.211
+37.152.163.216
+37.152.163.226
+37.152.163.227
+37.152.163.253
+37.152.164.17
+37.152.165.37
+37.152.165.136
+37.152.165.139
+37.152.165.151
+37.152.165.156
+37.152.165.197
+37.152.165.200
+37.152.166.10
+37.152.166.18
+37.152.166.36
+37.152.166.58
+37.152.166.68
+37.152.166.84
+37.152.166.88
+37.152.166.98
+37.152.166.102
+37.152.166.121
+37.152.166.139
+37.152.166.142
+37.152.166.144
+37.152.166.148
+37.152.166.151
+37.152.166.156
+37.152.166.158
+37.152.167.92
+37.152.167.142
+37.152.171.115
+37.152.172.104
+37.152.173.126
+37.152.177.179
+37.152.177.200
+37.152.178.112
+37.152.178.130
+37.152.179.40
+37.152.179.135
+37.152.181.83
+37.152.182.77
+37.152.188.155
+37.152.189.124
+37.152.190.29
+37.152.190.69
+37.152.190.238
+37.156.8.43
+37.156.8.147
+37.156.8.165
+37.156.8.197
+37.156.8.240
+37.156.9.26
+37.156.9.42
+37.156.9.67
+37.156.9.99
+37.156.9.152
+37.156.9.184
+37.156.9.192
+37.156.10.32
+37.156.10.49
+37.156.10.60
+37.156.10.71
+37.156.11.6
+37.156.11.10
+37.156.11.24
+37.156.11.31
+37.156.11.74
+37.156.11.80
+37.156.11.138
+37.156.11.142
+37.156.11.167
+37.156.11.175
+37.156.11.179
+37.156.11.196
+37.156.11.229
+37.156.11.248
+37.156.12.3
+37.156.12.4
+37.156.12.65
+37.156.12.94
+37.156.12.147
+37.156.12.166
+37.156.12.169
+37.156.12.209
+37.156.12.231
+37.156.12.233
+37.156.12.241
+37.156.12.251
+37.156.13.11
+37.156.13.23
+37.156.13.151
+37.156.13.152
+37.156.13.163
+37.156.13.237
+37.156.14.64
+37.156.14.97
+37.156.14.206
+37.156.14.209
+37.156.14.215
+37.156.14.226
+37.156.14.248
+37.156.15.20
+37.156.15.131
+37.156.15.149
+37.156.15.174
+37.156.15.198
+37.156.15.254
+37.156.16.202
+37.156.16.241
+37.156.17.102
+37.156.17.179
+37.156.17.246
+37.156.18.149
+37.156.19.32
+37.156.19.54
+37.156.19.84
+37.156.20.60
+37.156.20.92
+37.156.20.185
+37.156.20.235
+37.156.20.241
+37.156.21.15
+37.156.21.216
+37.156.21.225
+37.156.22.51
+37.156.23.23
+37.156.23.35
+37.156.23.39
+37.156.23.80
+37.156.23.105
+37.156.24.204
+37.156.25.28
+37.156.26.223
+37.156.27.77
+37.156.115.84
+37.156.144.66
+37.156.144.172
+37.156.144.174
+37.156.145.85
+37.156.145.195
+37.156.145.234
+37.156.146.2
+37.156.146.3
+37.156.146.4
+37.156.146.5
+37.156.146.46
+37.156.146.115
+37.156.146.180
+37.156.147.34
+37.156.147.36
+37.156.147.38
+37.156.147.213
+37.156.165.69
+37.156.165.198
+37.156.248.43
+37.156.248.193
+37.156.249.213
+37.156.249.237
+37.191.76.48
+37.191.76.49
+37.191.76.50
+37.191.76.51
+37.191.76.52
+37.191.76.53
+37.191.76.54
+37.191.76.64
+37.191.76.177
+37.191.77.102
+37.191.77.106
+37.191.77.202
+37.191.78.210
+37.191.78.211
+37.191.78.212
+37.191.78.215
+37.191.79.18
+37.191.79.55
+37.191.79.252
+37.191.84.46
+37.191.84.170
+37.191.84.222
+37.191.85.58
+37.191.92.225
+37.191.93.67
+37.191.93.126
+37.191.93.151
+37.191.94.66
+37.191.95.88
+37.191.95.181
+37.202.148.10
+37.202.148.28
+37.202.148.41
+37.202.148.69
+37.202.148.78
+37.202.148.89
+37.202.148.96
+37.202.148.101
+37.202.148.124
+37.202.148.126
+37.202.148.141
+37.202.148.165
+37.202.148.185
+37.202.148.190
+37.202.148.219
+37.202.148.231
+37.202.148.234
+37.202.148.235
+37.202.149.215
+37.202.149.224
+37.202.149.227
+37.202.149.234
+37.202.149.244
+37.202.149.252
+37.202.152.4
+37.202.152.33
+37.202.152.43
+37.202.152.46
+37.202.152.50
+37.202.152.84
+37.202.152.109
+37.202.152.112
+37.202.152.126
+37.202.152.133
+37.202.152.139
+37.202.152.149
+37.202.152.160
+37.202.152.165
+37.202.152.178
+37.202.152.182
+37.202.152.187
+37.202.152.189
+37.202.152.194
+37.202.152.203
+37.202.152.207
+37.202.152.213
+37.202.152.224
+37.202.152.226
+37.202.152.231
+37.202.152.250
+37.202.153.21
+37.202.153.22
+37.202.153.30
+37.202.153.61
+37.202.153.80
+37.202.153.83
+37.202.153.89
+37.202.153.94
+37.202.153.97
+37.202.153.103
+37.202.153.105
+37.202.153.123
+37.202.153.127
+37.202.153.138
+37.202.153.140
+37.202.153.145
+37.202.153.148
+37.202.153.197
+37.202.153.202
+37.202.153.204
+37.202.153.212
+37.202.153.219
+37.202.153.221
+37.202.153.232
+37.202.153.235
+37.202.153.242
+37.202.153.255
+37.202.154.5
+37.202.154.8
+37.202.154.26
+37.202.154.34
+37.202.154.51
+37.202.154.76
+37.202.154.83
+37.202.154.90
+37.202.154.132
+37.202.154.134
+37.202.154.158
+37.202.154.163
+37.202.154.181
+37.202.154.184
+37.202.154.195
+37.202.154.218
+37.202.154.219
+37.202.154.228
+37.202.154.230
+37.202.154.234
+37.202.154.246
+37.202.154.252
+37.202.154.253
+37.202.155.6
+37.202.155.19
+37.202.155.36
+37.202.155.40
+37.202.155.45
+37.202.155.50
+37.202.155.51
+37.202.155.69
+37.202.155.75
+37.202.155.82
+37.202.155.86
+37.202.155.88
+37.202.155.97
+37.202.155.108
+37.202.155.131
+37.202.155.132
+37.202.155.174
+37.202.155.188
+37.202.155.192
+37.202.155.218
+37.202.155.225
+37.202.155.231
+37.202.155.232
+37.202.155.242
+37.202.155.246
+37.202.156.0
+37.202.156.5
+37.202.156.10
+37.202.156.20
+37.202.156.26
+37.202.156.34
+37.202.156.53
+37.202.156.61
+37.202.156.72
+37.202.156.79
+37.202.156.82
+37.202.156.87
+37.202.156.88
+37.202.156.115
+37.202.156.132
+37.202.156.134
+37.202.156.135
+37.202.156.143
+37.202.156.204
+37.202.156.218
+37.202.156.240
+37.202.156.243
+37.202.156.246
+37.202.156.251
+37.202.157.3
+37.202.157.12
+37.202.157.40
+37.202.157.42
+37.202.157.86
+37.202.157.91
+37.202.157.96
+37.202.157.110
+37.202.157.119
+37.202.157.121
+37.202.157.126
+37.202.157.145
+37.202.157.175
+37.202.157.189
+37.202.157.197
+37.202.157.207
+37.202.157.209
+37.202.157.234
+37.202.157.237
+37.202.158.15
+37.202.158.31
+37.202.158.42
+37.202.158.59
+37.202.158.71
+37.202.158.79
+37.202.158.110
+37.202.158.154
+37.202.158.186
+37.202.158.198
+37.202.158.205
+37.202.158.238
+37.202.158.240
+37.202.158.249
+37.202.158.254
+37.202.159.1
+37.202.159.20
+37.202.159.58
+37.202.159.72
+37.202.159.78
+37.202.159.90
+37.202.159.101
+37.202.159.126
+37.202.159.135
+37.202.159.136
+37.202.159.147
+37.202.159.171
+37.202.159.184
+37.202.159.206
+37.202.159.210
+37.202.159.224
+37.202.159.243
+37.202.159.246
+37.202.159.253
+37.202.168.10
+37.202.168.28
+37.202.168.55
+37.202.168.61
+37.202.168.64
+37.202.168.80
+37.202.168.96
+37.202.168.101
+37.202.168.112
+37.202.168.119
+37.202.168.120
+37.202.168.121
+37.202.168.122
+37.202.168.135
+37.202.168.137
+37.202.168.176
+37.202.168.177
+37.202.168.228
+37.202.169.3
+37.202.169.8
+37.202.169.59
+37.202.169.65
+37.202.169.67
+37.202.169.89
+37.202.169.104
+37.202.169.145
+37.202.169.146
+37.202.169.168
+37.202.169.179
+37.202.169.189
+37.202.169.197
+37.202.169.222
+37.202.169.224
+37.202.169.242
+37.202.170.3
+37.202.170.7
+37.202.170.49
+37.202.170.60
+37.202.170.80
+37.202.170.88
+37.202.170.96
+37.202.170.115
+37.202.170.145
+37.202.170.209
+37.202.170.252
+37.202.171.4
+37.202.171.21
+37.202.171.22
+37.202.171.37
+37.202.171.49
+37.202.171.82
+37.202.171.100
+37.202.171.106
+37.202.171.131
+37.202.171.145
+37.202.171.146
+37.202.171.152
+37.202.171.157
+37.202.171.158
+37.202.171.171
+37.202.171.180
+37.202.171.188
+37.202.171.198
+37.202.171.203
+37.202.171.208
+37.202.171.230
+37.202.171.251
+37.202.171.253
+37.202.171.254
+37.202.171.255
+37.202.172.2
+37.202.172.6
+37.202.172.10
+37.202.172.11
+37.202.172.15
+37.202.172.16
+37.202.172.18
+37.202.172.36
+37.202.172.55
+37.202.172.70
+37.202.172.76
+37.202.172.81
+37.202.172.103
+37.202.172.115
+37.202.172.132
+37.202.172.138
+37.202.172.171
+37.202.172.187
+37.202.172.202
+37.202.172.222
+37.202.172.246
+37.202.173.4
+37.202.173.14
+37.202.173.23
+37.202.173.44
+37.202.173.57
+37.202.173.64
+37.202.173.72
+37.202.173.88
+37.202.173.91
+37.202.173.93
+37.202.173.112
+37.202.173.148
+37.202.173.155
+37.202.173.179
+37.202.173.183
+37.202.173.188
+37.202.173.205
+37.202.173.228
+37.202.173.240
+37.202.173.243
+37.202.173.244
+37.202.174.3
+37.202.174.10
+37.202.174.17
+37.202.174.23
+37.202.174.33
+37.202.174.50
+37.202.174.53
+37.202.174.62
+37.202.174.71
+37.202.174.91
+37.202.174.101
+37.202.174.104
+37.202.174.105
+37.202.174.115
+37.202.174.121
+37.202.174.128
+37.202.174.161
+37.202.174.181
+37.202.174.184
+37.202.174.212
+37.202.174.231
+37.202.174.232
+37.202.175.34
+37.202.175.35
+37.202.175.37
+37.202.175.39
+37.202.175.52
+37.202.175.59
+37.202.175.68
+37.202.175.69
+37.202.175.87
+37.202.175.88
+37.202.175.93
+37.202.175.94
+37.202.175.98
+37.202.175.115
+37.202.175.116
+37.202.175.120
+37.202.175.129
+37.202.175.173
+37.202.175.175
+37.202.175.185
+37.202.175.205
+37.202.175.207
+37.202.175.208
+37.202.175.224
+37.202.175.232
+37.202.175.242
+37.202.176.4
+37.202.176.10
+37.202.176.13
+37.202.176.26
+37.202.176.34
+37.202.176.49
+37.202.176.51
+37.202.176.59
+37.202.176.64
+37.202.176.66
+37.202.176.70
+37.202.176.76
+37.202.176.87
+37.202.176.95
+37.202.176.97
+37.202.176.104
+37.202.176.111
+37.202.176.119
+37.202.176.132
+37.202.176.143
+37.202.176.154
+37.202.176.168
+37.202.176.171
+37.202.176.179
+37.202.176.186
+37.202.176.189
+37.202.176.199
+37.202.176.200
+37.202.176.201
+37.202.176.205
+37.202.176.226
+37.202.176.230
+37.202.177.6
+37.202.177.10
+37.202.177.11
+37.202.177.26
+37.202.177.29
+37.202.177.30
+37.202.177.44
+37.202.177.46
+37.202.177.51
+37.202.177.58
+37.202.177.96
+37.202.177.107
+37.202.177.112
+37.202.177.117
+37.202.177.119
+37.202.177.137
+37.202.177.152
+37.202.177.174
+37.202.177.192
+37.202.177.193
+37.202.177.211
+37.202.177.217
+37.202.177.219
+37.202.177.224
+37.202.177.242
+37.202.178.4
+37.202.178.8
+37.202.178.12
+37.202.178.13
+37.202.178.24
+37.202.178.60
+37.202.178.76
+37.202.178.82
+37.202.178.106
+37.202.178.109
+37.202.178.123
+37.202.178.128
+37.202.178.136
+37.202.178.143
+37.202.178.178
+37.202.178.182
+37.202.178.198
+37.202.178.240
+37.202.178.242
+37.202.178.244
+37.202.178.245
+37.202.179.2
+37.202.179.19
+37.202.179.20
+37.202.179.21
+37.202.179.28
+37.202.179.32
+37.202.179.47
+37.202.179.53
+37.202.179.64
+37.202.179.67
+37.202.179.71
+37.202.179.80
+37.202.179.92
+37.202.179.96
+37.202.179.110
+37.202.179.188
+37.202.179.191
+37.202.179.193
+37.202.179.197
+37.202.179.203
+37.202.179.206
+37.202.179.224
+37.202.179.229
+37.202.179.230
+37.202.179.238
+37.202.179.239
+37.202.180.2
+37.202.180.43
+37.202.180.51
+37.202.180.72
+37.202.180.79
+37.202.180.83
+37.202.180.94
+37.202.180.112
+37.202.180.121
+37.202.180.133
+37.202.180.135
+37.202.180.136
+37.202.180.149
+37.202.180.176
+37.202.180.189
+37.202.180.196
+37.202.180.210
+37.202.180.219
+37.202.180.225
+37.202.180.228
+37.202.180.238
+37.202.181.5
+37.202.181.7
+37.202.181.20
+37.202.181.22
+37.202.181.26
+37.202.181.37
+37.202.181.42
+37.202.181.54
+37.202.181.62
+37.202.181.67
+37.202.181.77
+37.202.181.111
+37.202.181.112
+37.202.181.120
+37.202.181.125
+37.202.181.165
+37.202.181.192
+37.202.181.212
+37.202.181.219
+37.202.181.223
+37.202.181.231
+37.202.181.233
+37.202.181.243
+37.202.181.253
+37.202.182.41
+37.202.182.46
+37.202.182.48
+37.202.182.59
+37.202.182.66
+37.202.182.72
+37.202.182.83
+37.202.182.87
+37.202.182.90
+37.202.182.130
+37.202.182.153
+37.202.182.167
+37.202.182.189
+37.202.182.203
+37.202.184.36
+37.202.184.39
+37.202.184.42
+37.202.184.50
+37.202.184.82
+37.202.184.98
+37.202.184.130
+37.202.184.131
+37.202.184.146
+37.202.184.147
+37.202.184.154
+37.202.184.162
+37.202.184.189
+37.202.184.218
+37.202.184.251
+37.202.184.252
+37.202.184.253
+37.202.184.254
+37.202.185.1
+37.202.185.22
+37.202.185.26
+37.202.185.31
+37.202.185.35
+37.202.185.36
+37.202.185.51
+37.202.185.80
+37.202.185.91
+37.202.185.125
+37.202.185.142
+37.202.185.156
+37.202.185.170
+37.202.185.196
+37.202.185.241
+37.202.185.253
+37.202.186.0
+37.202.186.2
+37.202.186.5
+37.202.186.17
+37.202.186.29
+37.202.186.33
+37.202.186.40
+37.202.186.51
+37.202.186.52
+37.202.186.53
+37.202.186.58
+37.202.186.64
+37.202.186.67
+37.202.186.78
+37.202.186.114
+37.202.186.117
+37.202.186.120
+37.202.186.140
+37.202.186.151
+37.202.186.155
+37.202.186.181
+37.202.186.190
+37.202.186.201
+37.202.186.209
+37.202.186.211
+37.202.186.223
+37.202.186.247
+37.202.186.252
+37.202.187.43
+37.202.187.48
+37.202.187.67
+37.202.187.69
+37.202.187.72
+37.202.187.79
+37.202.187.80
+37.202.187.82
+37.202.187.120
+37.202.187.132
+37.202.187.135
+37.202.187.137
+37.202.187.140
+37.202.187.160
+37.202.187.181
+37.202.187.182
+37.202.187.185
+37.202.187.204
+37.202.187.210
+37.202.187.211
+37.202.187.220
+37.202.187.227
+37.202.188.10
+37.202.188.13
+37.202.188.15
+37.202.188.27
+37.202.188.40
+37.202.188.43
+37.202.188.50
+37.202.188.54
+37.202.188.59
+37.202.188.90
+37.202.188.91
+37.202.188.110
+37.202.188.144
+37.202.188.149
+37.202.188.158
+37.202.188.165
+37.202.188.177
+37.202.188.179
+37.202.188.185
+37.202.188.195
+37.202.188.198
+37.202.188.235
+37.202.188.238
+37.202.188.240
+37.202.188.255
+37.202.189.9
+37.202.189.25
+37.202.189.39
+37.202.189.44
+37.202.189.47
+37.202.189.76
+37.202.189.94
+37.202.189.99
+37.202.189.100
+37.202.189.103
+37.202.189.112
+37.202.189.134
+37.202.189.138
+37.202.189.147
+37.202.189.149
+37.202.189.158
+37.202.189.159
+37.202.189.189
+37.202.189.200
+37.202.189.214
+37.202.189.235
+37.202.189.239
+37.202.190.6
+37.202.190.8
+37.202.190.16
+37.202.190.61
+37.202.190.80
+37.202.190.82
+37.202.190.85
+37.202.190.88
+37.202.190.92
+37.202.190.103
+37.202.190.118
+37.202.190.137
+37.202.190.147
+37.202.190.153
+37.202.190.162
+37.202.190.166
+37.202.190.172
+37.202.190.182
+37.202.190.190
+37.202.190.194
+37.202.190.200
+37.202.190.217
+37.202.190.219
+37.202.190.222
+37.202.190.226
+37.202.190.240
+37.202.190.241
+37.202.190.242
+37.202.190.244
+37.202.191.2
+37.202.191.4
+37.202.191.12
+37.202.191.17
+37.202.191.21
+37.202.191.58
+37.202.191.63
+37.202.191.78
+37.202.191.90
+37.202.191.106
+37.202.191.128
+37.202.191.155
+37.202.191.175
+37.202.191.185
+37.202.191.212
+37.202.191.228
+37.202.191.230
+37.202.191.232
+37.202.191.238
+37.202.191.240
+37.202.225.185
+37.202.228.171
+37.202.228.254
+37.202.229.103
+37.202.231.16
+37.202.231.59
+37.202.231.242
+37.202.237.194
+37.202.239.132
+37.228.136.214
+37.228.137.85
+37.228.137.88
+37.228.137.107
+37.228.137.108
+37.228.137.156
+37.228.137.157
+37.228.137.158
+37.228.137.254
+37.228.138.66
+37.228.139.27
+37.228.139.51
+37.228.139.61
+37.228.139.226
+37.254.0.1
+37.254.96.1
+37.255.64.1
+37.255.128.41
+37.255.133.26
+37.255.133.27
+37.255.133.28
+37.255.133.29
+37.255.134.66
+37.255.134.160
+37.255.134.194
+37.255.135.34
+37.255.135.35
+37.255.135.50
+37.255.135.66
+37.255.135.203
+37.255.149.136
+37.255.149.222
+37.255.173.83
+37.255.173.134
+37.255.177.65
+37.255.177.243
+37.255.186.150
+37.255.187.147
+37.255.192.12
+37.255.192.24
+37.255.192.96
+37.255.192.191
+37.255.192.227
+37.255.193.110
+37.255.193.115
+37.255.193.151
+37.255.193.159
+37.255.193.229
+37.255.193.241
+37.255.194.14
+37.255.194.19
+37.255.194.51
+37.255.194.85
+37.255.194.100
+37.255.194.108
+37.255.194.121
+37.255.194.139
+37.255.194.171
+37.255.194.198
+37.255.194.199
+37.255.194.213
+37.255.194.231
+37.255.195.7
+37.255.195.10
+37.255.195.96
+37.255.195.170
+37.255.195.194
+37.255.196.26
+37.255.196.90
+37.255.196.95
+37.255.196.125
+37.255.196.150
+37.255.196.199
+37.255.197.63
+37.255.197.190
+37.255.198.41
+37.255.198.110
+37.255.198.220
+37.255.198.231
+37.255.199.204
+37.255.199.248
+37.255.200.103
+37.255.200.127
+37.255.200.161
+37.255.200.204
+37.255.200.254
+37.255.201.105
+37.255.201.171
+37.255.201.250
+37.255.202.94
+37.255.202.123
+37.255.202.124
+37.255.202.160
+37.255.202.219
+37.255.202.244
+37.255.202.251
+37.255.203.94
+37.255.203.130
+37.255.203.155
+37.255.203.235
+37.255.203.250
+37.255.204.1
+37.255.204.238
+37.255.204.239
+37.255.205.22
+37.255.205.232
+37.255.206.150
+37.255.206.159
+37.255.206.180
+37.255.207.114
+37.255.207.164
+37.255.207.236
+37.255.208.10
+37.255.208.12
+37.255.208.43
+37.255.208.53
+37.255.209.0
+37.255.209.44
+37.255.209.123
+37.255.209.136
+37.255.209.149
+37.255.209.161
+37.255.209.212
+37.255.210.51
+37.255.210.55
+37.255.210.70
+37.255.210.92
+37.255.210.168
+37.255.211.26
+37.255.211.56
+37.255.211.106
+37.255.211.221
+37.255.211.245
+37.255.211.252
+37.255.212.30
+37.255.212.46
+37.255.213.36
+37.255.213.38
+37.255.213.51
+37.255.213.88
+37.255.213.150
+37.255.213.235
+37.255.214.119
+37.255.215.21
+37.255.215.185
+37.255.216.19
+37.255.216.22
+37.255.216.113
+37.255.216.160
+37.255.217.22
+37.255.217.41
+37.255.217.115
+37.255.217.164
+37.255.217.196
+37.255.218.116
+37.255.218.143
+37.255.218.170
+37.255.218.191
+37.255.219.17
+37.255.219.190
+37.255.220.48
+37.255.220.51
+37.255.220.59
+37.255.220.121
+37.255.220.162
+37.255.220.172
+37.255.220.208
+37.255.221.6
+37.255.221.16
+37.255.221.40
+37.255.221.62
+37.255.221.147
+37.255.221.163
+37.255.222.36
+37.255.222.39
+37.255.222.42
+37.255.222.124
+37.255.222.223
+37.255.222.232
+37.255.223.34
+37.255.223.38
+37.255.223.40
+37.255.223.51
+37.255.223.201
+37.255.223.235
+37.255.223.239
+37.255.224.3
+37.255.224.143
+37.255.225.38
+37.255.225.108
+37.255.228.106
+37.255.228.122
+37.255.228.165
+37.255.228.219
+37.255.229.35
+37.255.229.88
+37.255.229.99
+37.255.229.163
+37.255.229.168
+37.255.229.238
+37.255.230.64
+37.255.230.169
+37.255.230.246
+37.255.231.32
+37.255.231.128
+37.255.231.132
+37.255.231.172
+37.255.231.184
+37.255.231.207
+37.255.231.221
+37.255.232.10
+37.255.232.130
+37.255.232.194
+37.255.232.233
+37.255.232.255
+37.255.233.12
+37.255.233.128
+37.255.233.143
+37.255.233.226
+37.255.233.253
+37.255.234.15
+37.255.234.75
+37.255.234.132
+37.255.234.134
+37.255.234.180
+37.255.234.188
+37.255.235.111
+37.255.235.138
+37.255.236.5
+37.255.236.64
+37.255.236.97
+37.255.236.134
+37.255.236.149
+37.255.236.193
+37.255.236.209
+37.255.237.68
+37.255.237.69
+37.255.237.70
+37.255.237.116
+37.255.237.117
+37.255.237.118
+37.255.237.119
+37.255.237.132
+37.255.238.4
+37.255.238.12
+37.255.238.23
+37.255.238.142
+37.255.238.188
+37.255.238.253
+37.255.239.81
+37.255.239.99
+37.255.239.104
+37.255.239.171
+37.255.240.0
+37.255.240.23
+37.255.240.124
+37.255.240.217
+37.255.241.27
+37.255.241.102
+37.255.241.122
+37.255.241.129
+37.255.241.137
+37.255.241.140
+37.255.241.213
+37.255.242.91
+37.255.242.182
+37.255.242.186
+37.255.242.212
+37.255.243.44
+37.255.243.69
+37.255.243.169
+37.255.243.205
+37.255.243.218
+37.255.244.53
+37.255.244.254
+37.255.245.67
+37.255.246.156
+37.255.248.156
+37.255.248.202
+37.255.248.241
+37.255.254.18
+37.255.254.20
+37.255.254.254
+37.255.255.18
+45.8.160.13
+45.8.160.79
+45.8.160.82
+45.8.160.84
+45.8.160.94
+45.8.160.211
+45.8.160.232
+45.8.160.237
+45.8.160.253
+45.9.252.86
+45.9.253.10
+45.9.253.46
+45.9.253.53
+45.9.253.122
+45.9.253.169
+45.9.254.90
+45.11.185.253
+45.11.187.165
+45.11.187.173
+45.15.200.30
+45.65.59.201
+45.81.16.103
+45.81.17.18
+45.81.17.19
+45.81.17.20
+45.81.17.23
+45.81.17.24
+45.81.17.27
+45.81.17.28
+45.81.17.29
+45.81.17.30
+45.81.17.133
+45.81.17.135
+45.81.17.190
+45.81.18.107
+45.81.18.123
+45.81.19.10
+45.81.19.11
+45.81.19.13
+45.81.19.14
+45.81.19.15
+45.81.19.16
+45.81.19.19
+45.81.19.59
+45.81.19.132
+45.81.19.150
+45.81.19.235
+45.82.137.234
+45.82.138.48
+45.84.157.43
+45.84.157.200
+45.84.157.202
+45.84.157.203
+45.84.157.204
+45.84.157.209
+45.84.157.210
+45.84.157.211
+45.84.157.212
+45.84.157.213
+45.84.157.217
+45.84.157.218
+45.84.157.220
+45.86.4.11
+45.86.4.66
+45.86.4.67
+45.86.4.82
+45.86.4.100
+45.86.5.211
+45.86.6.25
+45.86.6.113
+45.86.87.148
+45.86.87.186
+45.86.87.227
+45.87.4.116
+45.87.4.151
+45.87.5.66
+45.87.5.148
+45.87.5.178
+45.87.6.9
+45.87.6.38
+45.87.6.45
+45.89.236.37
+45.89.236.181
+45.89.237.66
+45.89.239.214
+45.89.239.227
+45.90.72.166
+45.90.73.207
+45.90.74.109
+45.90.74.225
+45.92.93.236
+45.92.94.4
+45.92.94.20
+45.92.94.122
+45.92.95.59
+45.94.214.3
+45.94.214.163
+45.94.214.219
+45.94.214.240
+45.94.215.32
+45.94.255.186
+45.129.36.45
+45.129.36.181
+45.129.36.220
+45.129.36.221
+45.129.36.222
+45.129.37.123
+45.129.37.124
+45.129.37.145
+45.129.37.148
+45.129.37.153
+45.129.37.156
+45.129.37.157
+45.129.37.158
+45.129.37.185
+45.129.37.198
+45.129.37.199
+45.129.38.35
+45.129.38.51
+45.129.38.53
+45.129.38.56
+45.129.38.60
+45.129.39.5
+45.129.39.6
+45.129.39.9
+45.129.39.12
+45.129.39.13
+45.129.39.168
+45.132.172.9
+45.132.172.56
+45.132.172.84
+45.132.172.93
+45.132.172.100
+45.132.172.144
+45.132.172.161
+45.132.173.200
+45.132.174.138
+45.132.174.191
+45.132.175.4
+45.134.99.4
+45.135.241.79
+45.135.243.61
+45.135.243.70
+45.138.132.27
+45.138.133.205
+45.138.135.32
+45.138.135.39
+45.138.135.57
+45.138.135.224
+45.139.10.61
+45.139.10.81
+45.139.10.200
+45.139.11.250
+45.140.225.4
+45.140.225.6
+45.140.225.60
+45.140.225.62
+45.140.225.218
+45.140.226.9
+45.140.226.10
+45.140.226.11
+45.140.226.12
+45.140.226.25
+45.140.226.73
+45.140.226.226
+45.142.190.13
+45.142.190.24
+45.142.190.46
+45.142.190.139
+45.142.190.142
+45.142.191.3
+45.142.191.9
+45.142.191.11
+45.142.191.17
+45.142.191.19
+45.142.191.24
+45.142.191.33
+45.142.191.35
+45.142.191.38
+45.142.191.39
+45.144.18.7
+45.144.18.52
+45.144.19.70
+45.144.19.75
+45.144.19.76
+45.144.19.77
+45.144.19.78
+45.144.19.85
+45.147.76.252
+45.147.77.59
+45.147.77.88
+45.147.77.169
+45.147.77.170
+45.147.77.171
+45.147.77.195
+45.147.79.36
+45.147.79.37
+45.147.79.38
+45.147.79.39
+45.148.248.8
+45.148.249.62
+45.148.250.68
+45.149.76.12
+45.149.76.138
+45.149.76.183
+45.149.76.195
+45.149.77.114
+45.149.77.135
+45.149.77.186
+45.149.78.156
+45.149.78.226
+45.149.79.53
+45.156.184.16
+45.156.184.26
+45.156.184.32
+45.156.184.36
+45.156.184.125
+45.156.185.30
+45.156.185.59
+45.156.185.80
+45.156.185.121
+45.156.185.129
+45.156.185.130
+45.156.185.164
+45.156.185.187
+45.156.185.192
+45.156.185.201
+45.156.185.240
+45.156.185.254
+45.156.186.108
+45.156.186.230
+45.156.186.240
+45.156.187.106
+45.158.120.7
+45.159.112.10
+45.159.112.43
+45.159.112.87
+45.159.112.107
+45.159.112.143
+45.159.112.144
+45.159.112.196
+45.159.113.144
+45.159.113.161
+45.159.113.165
+45.159.113.172
+45.159.113.242
+45.159.113.244
+45.159.114.200
+45.159.114.201
+45.159.114.202
+45.159.114.236
+45.159.115.117
+45.159.115.119
+45.159.115.127
+45.159.115.129
+45.159.115.151
+45.159.149.40
+45.159.149.108
+45.159.149.158
+45.159.150.94
+45.159.150.117
+45.159.150.157
+45.159.150.165
+45.159.151.16
+45.159.151.32
+45.159.151.39
+45.159.151.128
+45.159.151.169
+45.159.197.86
+45.159.197.114
+45.159.198.246
+46.28.72.18
+46.28.72.19
+46.28.72.20
+46.28.72.21
+46.28.72.133
+46.28.74.130
+46.28.75.66
+46.28.75.67
+46.28.75.106
+46.28.75.107
+46.28.75.108
+46.28.75.109
+46.28.75.130
+46.28.76.101
+46.28.77.26
+46.28.77.38
+46.28.77.54
+46.28.77.194
+46.32.1.13
+46.32.1.75
+46.32.1.118
+46.32.1.145
+46.32.1.165
+46.32.1.171
+46.32.1.202
+46.32.1.250
+46.32.2.13
+46.32.4.82
+46.32.4.83
+46.32.4.85
+46.32.4.86
+46.32.4.90
+46.32.4.164
+46.32.21.14
+46.32.25.75
+46.32.25.76
+46.32.25.77
+46.32.25.78
+46.32.25.178
+46.32.28.17
+46.32.28.29
+46.32.28.40
+46.32.28.52
+46.32.28.68
+46.32.28.128
+46.32.28.141
+46.32.28.144
+46.32.28.209
+46.32.28.220
+46.32.28.238
+46.32.31.50
+46.34.96.20
+46.34.161.9
+46.34.161.41
+46.34.161.67
+46.34.161.68
+46.34.161.104
+46.34.161.110
+46.34.161.183
+46.34.161.186
+46.34.161.226
+46.34.161.227
+46.34.162.18
+46.34.162.19
+46.34.162.20
+46.34.162.22
+46.34.163.161
+46.34.164.10
+46.34.164.18
+46.34.164.94
+46.34.164.105
+46.34.164.110
+46.34.164.218
+46.34.164.238
+46.34.165.50
+46.34.165.134
+46.34.165.138
+46.34.165.186
+46.34.166.18
+46.34.166.91
+46.34.166.106
+46.34.166.114
+46.34.166.115
+46.34.166.186
+46.34.166.187
+46.34.166.235
+46.34.166.237
+46.34.167.14
+46.34.167.52
+46.34.167.162
+46.34.178.130
+46.36.96.30
+46.36.103.93
+46.36.107.56
+46.38.138.50
+46.38.138.72
+46.38.138.139
+46.38.138.151
+46.38.138.165
+46.38.143.163
+46.38.143.189
+46.38.147.88
+46.38.147.219
+46.38.147.220
+46.38.147.222
+46.38.149.4
+46.38.149.200
+46.38.149.201
+46.38.151.110
+46.51.37.37
+46.51.37.38
+46.51.37.70
+46.51.37.159
+46.51.37.181
+46.51.37.233
+46.51.37.246
+46.100.5.15
+46.100.5.59
+46.100.5.122
+46.100.5.134
+46.100.5.139
+46.100.5.143
+46.100.5.186
+46.100.5.221
+46.100.5.225
+46.100.6.13
+46.100.6.82
+46.100.6.132
+46.100.6.184
+46.100.6.198
+46.100.7.0
+46.100.7.18
+46.100.7.32
+46.100.7.60
+46.100.7.143
+46.100.7.190
+46.100.7.198
+46.100.7.234
+46.100.8.3
+46.100.8.84
+46.100.8.134
+46.100.8.180
+46.100.9.8
+46.100.9.100
+46.100.9.191
+46.100.9.199
+46.100.10.34
+46.100.10.77
+46.100.11.42
+46.100.11.70
+46.100.11.131
+46.100.11.138
+46.100.11.139
+46.100.11.171
+46.100.11.212
+46.100.11.242
+46.100.11.250
+46.100.12.23
+46.100.12.81
+46.100.12.99
+46.100.12.102
+46.100.12.112
+46.100.12.130
+46.100.12.141
+46.100.12.145
+46.100.12.175
+46.100.12.176
+46.100.12.208
+46.100.12.214
+46.100.13.12
+46.100.13.14
+46.100.13.16
+46.100.13.93
+46.100.13.145
+46.100.13.147
+46.100.13.148
+46.100.14.1
+46.100.14.69
+46.100.34.124
+46.100.40.59
+46.100.40.72
+46.100.40.93
+46.100.40.132
+46.100.40.175
+46.100.40.185
+46.100.40.187
+46.100.40.210
+46.100.40.230
+46.100.41.100
+46.100.41.120
+46.100.41.217
+46.100.41.254
+46.100.42.40
+46.100.42.49
+46.100.42.51
+46.100.42.103
+46.100.42.132
+46.100.42.160
+46.100.42.163
+46.100.42.188
+46.100.42.245
+46.100.43.11
+46.100.43.41
+46.100.43.154
+46.100.45.39
+46.100.45.52
+46.100.45.72
+46.100.45.195
+46.100.45.252
+46.100.46.8
+46.100.46.56
+46.100.46.107
+46.100.46.111
+46.100.46.113
+46.100.46.122
+46.100.46.126
+46.100.46.135
+46.100.46.167
+46.100.47.51
+46.100.47.95
+46.100.47.112
+46.100.47.122
+46.100.47.137
+46.100.47.202
+46.100.47.249
+46.100.47.250
+46.100.48.37
+46.100.48.63
+46.100.48.66
+46.100.48.120
+46.100.48.178
+46.100.48.181
+46.100.48.199
+46.100.48.235
+46.100.50.8
+46.100.50.33
+46.100.50.63
+46.100.50.106
+46.100.50.115
+46.100.50.118
+46.100.50.122
+46.100.50.155
+46.100.52.16
+46.100.52.40
+46.100.52.52
+46.100.52.112
+46.100.52.170
+46.100.52.192
+46.100.52.239
+46.100.52.247
+46.100.52.251
+46.100.53.35
+46.100.53.36
+46.100.53.85
+46.100.53.106
+46.100.53.115
+46.100.53.176
+46.100.53.185
+46.100.53.187
+46.100.53.212
+46.100.53.232
+46.100.54.1
+46.100.54.4
+46.100.54.23
+46.100.54.48
+46.100.54.53
+46.100.54.167
+46.100.54.191
+46.100.55.16
+46.100.55.18
+46.100.55.37
+46.100.55.54
+46.100.55.67
+46.100.55.72
+46.100.55.158
+46.100.55.172
+46.100.55.190
+46.100.55.193
+46.100.55.207
+46.100.55.232
+46.100.56.237
+46.100.57.62
+46.100.57.115
+46.100.57.124
+46.100.57.237
+46.100.58.16
+46.100.58.87
+46.100.58.141
+46.100.58.142
+46.100.59.119
+46.100.59.146
+46.100.59.148
+46.100.59.168
+46.100.60.24
+46.100.60.26
+46.100.60.28
+46.100.60.67
+46.100.60.73
+46.100.60.80
+46.100.60.122
+46.100.60.144
+46.100.60.177
+46.100.61.16
+46.100.61.17
+46.100.61.32
+46.100.61.33
+46.100.61.196
+46.100.62.21
+46.100.62.44
+46.100.62.56
+46.100.62.80
+46.100.62.110
+46.100.62.129
+46.100.62.169
+46.100.62.235
+46.100.63.28
+46.100.63.43
+46.100.63.112
+46.100.63.124
+46.100.63.220
+46.100.63.221
+46.100.63.244
+46.100.74.110
+46.100.84.9
+46.100.84.20
+46.100.84.47
+46.100.84.171
+46.100.84.197
+46.100.84.205
+46.100.84.227
+46.100.85.171
+46.100.85.218
+46.100.85.234
+46.100.90.82
+46.100.90.105
+46.100.90.116
+46.100.90.135
+46.100.90.138
+46.100.90.168
+46.100.91.17
+46.100.91.22
+46.100.91.27
+46.100.91.109
+46.100.91.134
+46.100.91.218
+46.100.92.15
+46.100.92.50
+46.100.92.84
+46.100.92.92
+46.100.92.113
+46.100.92.128
+46.100.92.130
+46.100.92.227
+46.100.93.214
+46.100.94.2
+46.100.94.7
+46.100.94.132
+46.100.94.147
+46.100.94.190
+46.100.95.29
+46.100.95.119
+46.100.95.162
+46.100.95.193
+46.100.97.51
+46.100.97.188
+46.100.99.31
+46.100.101.194
+46.100.101.226
+46.100.101.227
+46.100.104.22
+46.100.104.48
+46.100.104.162
+46.100.104.182
+46.100.104.183
+46.100.107.90
+46.100.107.213
+46.100.116.145
+46.100.132.34
+46.100.134.39
+46.100.164.15
+46.100.164.22
+46.100.164.27
+46.100.164.39
+46.100.164.48
+46.100.164.88
+46.100.164.112
+46.100.164.157
+46.100.164.165
+46.100.164.195
+46.100.164.205
+46.100.164.212
+46.100.164.216
+46.100.164.242
+46.100.165.4
+46.100.165.56
+46.100.165.140
+46.100.165.150
+46.100.165.151
+46.100.165.196
+46.100.165.249
+46.100.166.10
+46.100.166.18
+46.100.166.32
+46.100.166.43
+46.100.166.55
+46.100.166.153
+46.100.166.194
+46.100.166.204
+46.100.167.86
+46.100.167.99
+46.100.167.117
+46.100.167.185
+46.100.167.189
+46.100.168.101
+46.100.171.4
+46.100.177.18
+46.100.177.41
+46.100.177.184
+46.100.178.45
+46.100.179.39
+46.100.180.71
+46.100.181.18
+46.100.182.46
+46.100.182.95
+46.100.183.82
+46.100.183.91
+46.100.248.135
+46.100.248.199
+46.100.249.82
+46.100.249.89
+46.100.249.117
+46.100.249.190
+46.100.249.207
+46.100.250.5
+46.100.251.5
+46.100.251.156
+46.102.132.2
+46.102.132.3
+46.102.132.4
+46.102.132.31
+46.102.137.20
+46.102.137.22
+46.102.137.32
+46.102.139.18
+46.102.139.21
+46.102.139.85
+46.102.140.35
+46.102.143.141
+46.102.143.143
+46.102.184.135
+46.102.184.175
+46.102.187.30
+46.102.187.139
+46.148.32.5
+46.148.32.16
+46.148.32.17
+46.148.32.26
+46.148.32.70
+46.148.32.98
+46.148.32.112
+46.148.32.121
+46.148.32.125
+46.148.32.135
+46.148.32.158
+46.148.32.167
+46.148.32.176
+46.148.32.209
+46.148.32.235
+46.148.32.238
+46.148.32.239
+46.148.34.74
+46.148.34.226
+46.148.35.43
+46.148.35.57
+46.148.35.59
+46.148.35.210
+46.148.35.217
+46.148.36.10
+46.148.36.40
+46.148.36.55
+46.148.36.93
+46.148.36.100
+46.148.36.105
+46.148.36.106
+46.148.36.147
+46.148.36.150
+46.148.36.219
+46.148.36.241
+46.148.36.244
+46.148.38.154
+46.148.38.167
+46.148.39.25
+46.148.39.75
+46.148.39.104
+46.148.40.0
+46.148.40.2
+46.148.40.32
+46.148.40.40
+46.148.40.47
+46.148.41.5
+46.148.41.9
+46.148.42.210
+46.148.43.33
+46.148.43.206
+46.148.43.212
+46.148.44.48
+46.148.44.54
+46.148.44.106
+46.148.44.167
+46.148.44.221
+46.148.44.227
+46.148.45.5
+46.148.45.26
+46.148.45.28
+46.148.45.33
+46.148.45.42
+46.148.45.45
+46.148.45.80
+46.148.45.89
+46.148.45.114
+46.148.45.133
+46.148.45.145
+46.148.45.154
+46.148.45.155
+46.148.45.202
+46.148.45.208
+46.148.45.223
+46.148.45.233
+46.148.45.235
+46.148.45.242
+46.167.128.168
+46.167.131.114
+46.167.132.199
+46.167.133.40
+46.167.133.248
+46.167.134.160
+46.167.135.178
+46.167.136.14
+46.167.136.26
+46.167.136.112
+46.167.138.65
+46.167.138.205
+46.167.139.228
+46.167.140.98
+46.167.141.0
+46.167.141.21
+46.167.141.22
+46.167.141.138
+46.167.143.104
+46.167.146.138
+46.167.148.146
+46.167.149.72
+46.167.149.76
+46.167.150.29
+46.167.150.227
+46.167.152.192
+46.167.152.245
+46.167.154.99
+46.167.154.209
+46.167.155.0
+46.167.155.69
+46.167.156.137
+46.167.156.199
+46.167.157.162
+46.167.157.169
+46.167.157.205
+46.167.158.135
+46.167.159.0
+46.182.32.129
+46.209.5.114
+46.209.12.25
+46.209.15.187
+46.209.20.85
+46.209.20.207
+46.209.22.226
+46.209.22.227
+46.209.22.228
+46.209.22.229
+46.209.27.3
+46.209.28.27
+46.209.30.11
+46.209.30.12
+46.209.30.107
+46.209.30.108
+46.209.45.246
+46.209.48.5
+46.209.48.82
+46.209.48.114
+46.209.48.115
+46.209.48.116
+46.209.48.118
+46.209.48.194
+46.209.48.213
+46.209.49.254
+46.209.58.194
+46.209.58.195
+46.209.61.98
+46.209.61.99
+46.209.63.218
+46.209.70.226
+46.209.73.54
+46.209.74.198
+46.209.79.58
+46.209.79.59
+46.209.79.60
+46.209.79.61
+46.209.79.62
+46.209.92.162
+46.209.92.163
+46.209.92.164
+46.209.93.85
+46.209.94.14
+46.209.95.102
+46.209.100.114
+46.209.103.118
+46.209.115.30
+46.209.115.74
+46.209.118.178
+46.209.118.180
+46.209.118.181
+46.209.118.182
+46.209.122.194
+46.209.122.196
+46.209.122.226
+46.209.140.170
+46.209.140.172
+46.209.142.2
+46.209.142.4
+46.209.142.51
+46.209.142.53
+46.209.142.82
+46.209.142.83
+46.209.142.84
+46.209.142.85
+46.209.148.202
+46.209.148.203
+46.209.148.204
+46.209.148.205
+46.209.153.225
+46.209.153.226
+46.209.153.228
+46.209.153.229
+46.209.153.230
+46.209.153.233
+46.209.153.234
+46.209.153.236
+46.209.153.238
+46.209.153.240
+46.209.153.243
+46.209.153.246
+46.209.153.247
+46.209.153.248
+46.209.153.249
+46.209.153.250
+46.209.156.131
+46.209.157.18
+46.209.157.22
+46.209.181.202
+46.209.195.18
+46.209.195.19
+46.209.195.20
+46.209.195.21
+46.209.199.86
+46.209.201.58
+46.209.203.141
+46.209.203.143
+46.209.204.142
+46.209.206.62
+46.209.206.178
+46.209.207.97
+46.209.207.98
+46.209.207.146
+46.209.207.147
+46.209.207.148
+46.209.207.149
+46.209.207.150
+46.209.207.151
+46.209.207.152
+46.209.207.155
+46.209.207.156
+46.209.207.158
+46.209.211.50
+46.209.221.66
+46.209.221.68
+46.209.221.69
+46.209.221.70
+46.209.221.71
+46.209.221.72
+46.209.221.73
+46.209.221.75
+46.209.221.76
+46.209.221.77
+46.209.221.78
+46.209.221.82
+46.209.221.84
+46.209.221.85
+46.209.221.86
+46.209.221.87
+46.209.221.88
+46.209.221.89
+46.209.221.90
+46.209.221.91
+46.209.221.93
+46.209.222.123
+46.209.232.146
+46.209.239.30
+46.209.240.90
+46.209.240.226
+46.209.240.227
+46.209.240.228
+46.209.241.67
+46.209.241.81
+46.209.241.82
+46.209.241.155
+46.209.241.226
+46.209.241.227
+46.209.241.229
+46.209.241.250
+46.209.247.155
+46.209.251.94
+46.235.76.81
+46.235.76.225
+46.235.77.15
+46.235.77.80
+46.235.77.110
+46.235.77.118
+46.235.77.131
+46.235.77.153
+46.235.77.185
+46.235.77.251
+46.245.0.109
+46.245.0.128
+46.245.0.138
+46.245.0.167
+46.245.1.65
+46.245.1.104
+46.245.2.47
+46.245.2.161
+46.245.2.253
+46.245.3.30
+46.245.4.85
+46.245.5.63
+46.245.5.75
+46.245.5.202
+46.245.5.236
+46.245.6.215
+46.245.7.102
+46.245.7.223
+46.245.8.66
+46.245.10.13
+46.245.12.183
+46.245.12.187
+46.245.12.222
+46.245.12.241
+46.245.17.101
+46.245.19.79
+46.245.25.72
+46.245.30.51
+46.245.32.26
+46.245.32.29
+46.245.32.40
+46.245.37.66
+46.245.38.42
+46.245.38.99
+46.245.38.107
+46.245.38.119
+46.245.38.206
+46.245.38.234
+46.245.39.63
+46.245.39.101
+46.245.39.102
+46.245.39.184
+46.245.39.185
+46.245.39.186
+46.245.39.210
+46.245.41.104
+46.245.42.44
+46.245.43.249
+46.245.44.1
+46.245.44.9
+46.245.46.128
+46.245.47.207
+46.245.65.2
+46.245.65.3
+46.245.66.4
+46.245.66.201
+46.245.66.202
+46.245.66.203
+46.245.66.204
+46.245.66.205
+46.245.66.251
+46.245.66.253
+46.245.67.142
+46.245.67.143
+46.245.67.144
+46.245.67.146
+46.245.67.147
+46.245.67.148
+46.245.67.151
+46.245.67.161
+46.245.69.214
+46.245.72.218
+46.245.72.219
+46.245.72.220
+46.245.76.203
+46.245.77.98
+46.245.77.99
+46.245.77.100
+46.245.77.101
+46.245.77.102
+46.245.77.103
+46.245.77.106
+46.245.77.107
+46.245.77.108
+46.245.77.109
+46.245.77.110
+46.245.78.154
+46.245.80.172
+46.245.81.34
+46.245.81.115
+46.245.81.116
+46.245.81.117
+46.245.81.118
+46.245.83.142
+46.245.84.81
+46.245.84.82
+46.245.84.83
+46.245.84.84
+46.245.84.86
+46.245.86.185
+46.245.87.218
+46.245.87.219
+46.245.87.221
+46.245.89.99
+46.245.89.101
+46.245.90.73
+46.245.90.103
+46.245.91.68
+46.245.91.71
+46.245.91.76
+46.245.91.82
+46.245.91.83
+46.245.91.84
+46.245.91.85
+46.245.91.86
+46.245.91.87
+46.245.91.88
+46.245.91.89
+46.245.91.90
+46.245.91.91
+46.245.91.92
+46.245.91.93
+46.245.91.94
+46.245.92.159
+46.245.94.106
+46.245.94.149
+46.245.94.150
+46.245.94.151
+46.245.94.177
+46.245.94.178
+46.245.95.30
+46.245.95.65
+46.245.95.188
+46.245.98.77
+46.245.98.133
+46.245.107.197
+46.245.112.16
+46.245.112.17
+46.245.112.18
+46.245.114.226
+46.245.114.227
+46.245.115.36
+46.245.115.39
+46.245.115.40
+46.245.115.43
+46.245.115.202
+46.245.117.51
+46.245.118.147
+46.245.122.19
+46.245.122.29
+46.245.123.9
+46.245.123.10
+46.245.123.82
+46.245.123.84
+46.245.123.86
+46.245.124.224
+46.249.120.25
+46.249.120.43
+46.249.120.104
+46.249.121.88
+46.249.121.89
+46.249.121.91
+46.249.121.97
+46.249.121.190
+46.249.122.3
+46.249.122.10
+46.249.122.12
+46.249.122.13
+46.249.122.15
+46.249.122.18
+46.249.122.21
+46.249.122.26
+46.249.122.29
+46.249.122.32
+46.249.122.34
+46.249.122.35
+46.249.122.39
+46.249.122.41
+46.249.122.48
+46.249.122.57
+46.249.123.7
+46.249.123.23
+46.249.124.14
+46.249.124.34
+46.249.124.244
+46.249.124.245
+46.249.125.9
+46.249.125.129
+46.249.125.200
+46.249.125.205
+46.249.125.215
+46.249.125.225
+46.249.125.244
+46.249.126.93
+46.249.127.121
+46.249.127.199
+58.147.146.146
+62.3.14.8
+62.3.14.136
+62.3.41.30
+62.3.41.88
+62.3.41.112
+62.3.41.131
+62.3.41.165
+62.3.42.2
+62.3.42.3
+62.3.42.50
+62.3.42.133
+62.3.42.136
+62.3.42.221
+62.3.42.241
+62.60.128.143
+62.60.128.166
+62.60.141.98
+62.60.141.99
+62.60.141.100
+62.60.141.102
+62.60.141.106
+62.60.141.107
+62.60.141.108
+62.60.141.109
+62.60.141.254
+62.60.143.146
+62.60.143.151
+62.60.143.163
+62.60.143.240
+62.60.143.243
+62.60.144.150
+62.60.144.151
+62.60.144.154
+62.60.144.167
+62.60.144.177
+62.60.144.184
+62.60.144.187
+62.60.144.195
+62.60.144.196
+62.60.144.197
+62.60.144.198
+62.60.144.199
+62.60.144.200
+62.60.160.29
+62.60.160.81
+62.60.160.123
+62.60.161.203
+62.60.161.217
+62.60.162.97
+62.60.162.148
+62.60.162.213
+62.60.163.202
+62.60.163.227
+62.60.163.233
+62.60.163.251
+62.60.164.128
+62.60.164.146
+62.60.167.26
+62.60.167.29
+62.60.190.190
+62.60.190.200
+62.60.200.18
+62.60.200.19
+62.60.200.20
+62.60.200.170
+62.60.200.243
+62.60.200.244
+62.60.200.245
+62.60.200.246
+62.60.204.141
+62.60.205.24
+62.60.206.6
+62.60.206.17
+62.60.207.160
+62.60.207.177
+62.60.210.60
+62.60.210.179
+62.60.212.164
+62.60.214.47
+62.60.214.71
+62.60.214.128
+62.60.214.134
+62.60.214.189
+62.60.218.224
+62.106.95.53
+62.106.95.132
+62.204.61.3
+62.204.61.16
+62.204.61.20
+62.204.61.40
+62.204.61.165
+62.204.61.188
+62.220.100.170
+62.220.100.172
+62.220.100.183
+62.220.112.63
+62.220.113.122
+62.220.113.160
+62.220.114.193
+62.220.114.197
+62.220.114.241
+62.220.115.99
+62.220.117.202
+62.220.124.52
+62.220.124.54
+62.220.126.3
+62.220.126.4
+62.220.126.5
+62.220.126.6
+62.220.126.8
+62.220.126.9
+62.220.126.15
+62.220.126.16
+62.220.126.23
+62.220.126.26
+62.220.126.28
+62.220.126.29
+62.220.126.30
+62.220.126.31
+62.220.126.33
+62.220.126.34
+62.220.126.35
+62.220.126.36
+62.220.126.37
+62.220.126.42
+62.220.126.48
+62.220.126.50
+62.220.126.52
+62.220.126.57
+62.220.126.73
+62.220.126.74
+62.220.126.75
+62.220.126.78
+62.220.126.79
+62.220.126.109
+62.220.126.111
+62.220.126.119
+62.220.126.153
+62.220.126.154
+62.220.126.155
+62.220.126.157
+62.220.126.159
+62.220.126.171
+62.220.126.172
+62.220.126.173
+62.220.126.180
+62.220.126.209
+62.220.126.210
+62.220.126.211
+62.220.126.213
+62.220.126.214
+62.220.126.215
+62.220.126.221
+62.220.126.222
+62.220.126.226
+62.220.126.236
+62.220.126.237
+62.220.126.238
+62.220.126.239
+62.220.126.244
+62.220.126.245
+62.220.126.246
+62.220.127.82
+62.220.127.116
+62.220.127.117
+62.220.127.118
+62.220.127.186
+66.79.96.123
+66.79.97.38
+66.79.98.201
+66.79.98.210
+66.79.99.182
+66.79.100.21
+66.79.100.86
+66.79.100.90
+66.79.101.14
+66.79.101.45
+66.79.102.175
+66.79.103.222
+66.79.105.22
+66.79.105.60
+77.36.237.37
+77.36.243.129
+77.81.34.250
+77.81.76.9
+77.81.76.16
+77.81.76.73
+77.81.78.16
+77.81.78.31
+77.81.78.39
+77.81.78.61
+77.81.78.63
+77.81.78.82
+77.81.78.93
+77.81.78.98
+77.81.78.108
+77.81.78.111
+77.81.78.117
+77.81.78.123
+77.81.78.125
+77.81.78.128
+77.81.78.141
+77.81.78.157
+77.81.78.186
+77.81.82.1
+77.81.82.21
+77.81.82.194
+77.81.83.3
+77.81.83.10
+77.81.144.14
+77.81.146.44
+77.81.147.224
+77.81.147.254
+77.81.148.63
+77.81.148.122
+77.81.148.155
+77.81.148.182
+77.81.149.7
+77.81.149.100
+77.81.149.196
+77.81.149.231
+77.81.151.101
+77.81.151.131
+77.81.152.62
+77.81.152.97
+77.81.152.229
+77.81.154.30
+77.81.156.28
+77.81.157.124
+77.81.158.53
+77.81.159.164
+77.95.219.74
+77.95.219.126
+77.95.219.155
+77.95.219.182
+77.104.66.74
+77.104.66.134
+77.104.67.146
+77.104.67.147
+77.104.67.148
+77.104.67.149
+77.104.67.150
+77.104.67.151
+77.104.67.152
+77.104.67.153
+77.104.67.154
+77.104.68.129
+77.104.68.153
+77.104.68.212
+77.104.72.22
+77.104.72.146
+77.104.73.66
+77.104.73.67
+77.104.73.68
+77.104.73.69
+77.104.73.70
+77.104.73.71
+77.104.73.72
+77.104.73.74
+77.104.73.75
+77.104.73.76
+77.104.73.77
+77.104.73.78
+77.104.73.130
+77.104.73.131
+77.104.73.132
+77.104.73.133
+77.104.73.135
+77.104.73.136
+77.104.73.137
+77.104.73.138
+77.104.73.139
+77.104.75.114
+77.104.75.227
+77.104.76.6
+77.104.76.44
+77.104.76.50
+77.104.76.230
+77.104.77.114
+77.104.77.197
+77.104.79.243
+77.104.79.244
+77.104.81.67
+77.104.82.66
+77.104.82.67
+77.104.82.68
+77.104.82.69
+77.104.82.70
+77.104.82.110
+77.104.82.196
+77.104.84.130
+77.104.84.136
+77.104.84.146
+77.104.84.150
+77.104.85.14
+77.104.85.50
+77.104.85.51
+77.104.85.74
+77.104.85.90
+77.104.92.3
+77.104.93.85
+77.104.99.150
+77.104.100.186
+77.104.102.162
+77.104.103.130
+77.104.103.250
+77.104.110.6
+77.104.110.10
+77.104.110.11
+77.104.110.13
+77.104.110.18
+77.104.110.137
+77.104.110.166
+77.104.114.229
+77.104.114.233
+77.104.114.237
+77.104.114.241
+77.104.114.245
+77.104.114.249
+77.104.115.183
+77.104.115.190
+77.104.115.217
+77.104.115.239
+77.104.126.28
+77.104.126.43
+77.104.126.152
+77.104.126.156
+77.104.126.181
+77.104.126.183
+77.104.126.189
+77.104.126.211
+77.104.127.6
+77.237.66.72
+77.237.67.19
+77.237.69.136
+77.237.69.192
+77.237.69.193
+77.237.70.222
+77.237.76.74
+77.237.76.223
+77.237.77.42
+77.237.77.106
+77.237.77.109
+77.237.78.1
+77.237.78.7
+77.237.78.8
+77.237.78.186
+77.237.82.49
+77.237.82.56
+77.237.82.112
+77.237.82.169
+77.237.82.221
+77.237.82.247
+77.237.83.186
+77.237.85.193
+77.237.85.197
+77.237.85.201
+77.237.85.205
+77.237.85.209
+77.237.85.213
+77.237.85.217
+77.237.85.229
+77.237.85.230
+77.237.85.233
+77.237.85.241
+77.237.85.245
+77.237.85.249
+77.237.87.190
+77.237.88.146
+77.237.88.178
+77.237.89.18
+77.237.89.194
+77.237.89.196
+77.237.89.197
+77.237.89.198
+77.237.91.146
+77.237.92.1
+77.237.92.82
+77.237.92.90
+77.237.92.106
+77.237.92.118
+77.237.92.220
+77.237.93.34
+77.237.93.35
+77.237.93.36
+77.237.93.37
+77.237.94.10
+77.237.94.202
+77.237.94.203
+77.237.95.186
+77.238.104.0
+77.238.104.47
+77.238.104.102
+77.238.104.107
+77.238.104.135
+77.238.104.150
+77.238.104.208
+77.238.104.238
+77.238.105.125
+77.238.105.147
+77.238.105.242
+77.238.106.19
+77.238.106.41
+77.238.106.58
+77.238.106.96
+77.238.106.103
+77.238.106.119
+77.238.106.138
+77.238.106.198
+77.238.106.225
+77.238.107.24
+77.238.107.32
+77.238.107.174
+77.238.107.198
+77.238.108.92
+77.238.109.91
+77.238.110.40
+77.238.110.44
+77.238.110.142
+77.238.110.163
+77.238.110.177
+77.238.110.231
+77.238.111.235
+77.238.114.64
+77.238.115.44
+77.238.117.255
+77.238.118.166
+77.238.119.32
+77.238.119.96
+77.238.120.23
+77.238.121.92
+77.238.121.128
+77.238.121.138
+77.238.121.200
+77.238.121.206
+77.238.122.146
+77.238.122.163
+77.238.122.242
+77.238.123.238
+78.31.235.1
+78.31.235.2
+78.38.0.73
+78.38.0.82
+78.38.0.92
+78.38.0.93
+78.38.16.210
+78.38.17.48
+78.38.17.67
+78.38.17.118
+78.38.17.155
+78.38.17.159
+78.38.18.137
+78.38.19.151
+78.38.20.2
+78.38.20.33
+78.38.20.98
+78.38.20.99
+78.38.20.105
+78.38.24.122
+78.38.24.199
+78.38.26.79
+78.38.26.103
+78.38.26.107
+78.38.26.124
+78.38.26.129
+78.38.26.130
+78.38.26.131
+78.38.26.133
+78.38.26.136
+78.38.26.137
+78.38.26.138
+78.38.26.140
+78.38.26.141
+78.38.26.142
+78.38.26.145
+78.38.26.146
+78.38.26.147
+78.38.26.148
+78.38.26.156
+78.38.26.157
+78.38.26.158
+78.38.26.160
+78.38.26.161
+78.38.26.162
+78.38.26.163
+78.38.26.165
+78.38.26.167
+78.38.26.168
+78.38.26.169
+78.38.26.170
+78.38.26.171
+78.38.26.173
+78.38.26.174
+78.38.26.175
+78.38.26.176
+78.38.26.177
+78.38.26.178
+78.38.26.179
+78.38.26.180
+78.38.26.182
+78.38.26.184
+78.38.26.185
+78.38.26.186
+78.38.26.187
+78.38.26.227
+78.38.29.9
+78.38.29.147
+78.38.30.35
+78.38.30.69
+78.38.30.179
+78.38.30.200
+78.38.31.45
+78.38.31.107
+78.38.31.117
+78.38.31.161
+78.38.32.56
+78.38.32.159
+78.38.36.61
+78.38.38.48
+78.38.41.17
+78.38.41.37
+78.38.46.154
+78.38.46.200
+78.38.46.209
+78.38.46.220
+78.38.48.107
+78.38.48.178
+78.38.48.210
+78.38.49.109
+78.38.49.110
+78.38.49.240
+78.38.49.255
+78.38.50.39
+78.38.50.44
+78.38.50.61
+78.38.50.125
+78.38.50.154
+78.38.50.207
+78.38.52.74
+78.38.52.82
+78.38.60.218
+78.38.64.65
+78.38.64.73
+78.38.64.129
+78.38.65.65
+78.38.65.108
+78.38.65.109
+78.38.67.24
+78.38.67.26
+78.38.67.93
+78.38.67.95
+78.38.69.87
+78.38.69.89
+78.38.71.13
+78.38.71.164
+78.38.77.47
+78.38.78.49
+78.38.80.241
+78.38.80.242
+78.38.84.12
+78.38.90.251
+78.38.92.106
+78.38.92.218
+78.38.93.34
+78.38.93.58
+78.38.93.86
+78.38.93.90
+78.38.94.74
+78.38.94.122
+78.38.94.123
+78.38.94.130
+78.38.94.131
+78.38.94.132
+78.38.94.133
+78.38.94.134
+78.38.95.57
+78.38.99.46
+78.38.99.50
+78.38.99.82
+78.38.99.118
+78.38.99.186
+78.38.99.194
+78.38.99.195
+78.38.99.196
+78.38.99.238
+78.38.100.54
+78.38.100.71
+78.38.100.121
+78.38.101.66
+78.38.105.9
+78.38.105.74
+78.38.106.232
+78.38.106.243
+78.38.107.53
+78.38.107.72
+78.38.107.88
+78.38.107.172
+78.38.108.194
+78.38.108.196
+78.38.108.198
+78.38.108.199
+78.38.108.202
+78.38.108.203
+78.38.108.204
+78.38.108.205
+78.38.109.100
+78.38.110.110
+78.38.110.138
+78.38.110.171
+78.38.110.174
+78.38.112.130
+78.38.114.86
+78.38.114.210
+78.38.114.212
+78.38.114.213
+78.38.114.221
+78.38.120.80
+78.38.120.120
+78.38.121.218
+78.38.123.210
+78.38.124.28
+78.38.124.35
+78.38.124.163
+78.38.126.2
+78.38.126.101
+78.38.126.141
+78.38.126.247
+78.38.127.149
+78.38.127.238
+78.38.140.50
+78.38.144.243
+78.38.145.228
+78.38.149.32
+78.38.152.102
+78.38.153.37
+78.38.153.81
+78.38.153.177
+78.38.153.181
+78.38.156.22
+78.38.156.129
+78.38.156.205
+78.38.156.229
+78.38.156.246
+78.38.157.65
+78.38.157.66
+78.38.157.112
+78.38.157.124
+78.38.157.167
+78.38.158.22
+78.38.161.80
+78.38.166.121
+78.38.166.122
+78.38.166.123
+78.38.166.145
+78.38.166.249
+78.38.174.78
+78.38.179.236
+78.38.182.61
+78.38.189.221
+78.38.209.57
+78.38.221.170
+78.38.221.172
+78.38.221.173
+78.38.221.174
+78.38.224.98
+78.38.239.220
+78.38.239.221
+78.38.239.222
+78.38.239.223
+78.38.239.224
+78.38.243.6
+78.38.243.234
+78.38.243.237
+78.38.246.174
+78.38.246.183
+78.38.248.46
+78.38.248.117
+78.38.248.154
+78.38.248.242
+78.38.248.250
+78.38.250.6
+78.38.250.82
+78.38.250.84
+78.38.250.85
+78.38.250.86
+78.38.250.150
+78.38.251.250
+78.38.251.251
+78.38.251.252
+78.38.251.253
+78.38.254.14
+78.38.254.66
+78.39.10.54
+78.39.10.234
+78.39.11.2
+78.39.11.14
+78.39.11.62
+78.39.11.122
+78.39.37.170
+78.39.40.114
+78.39.40.115
+78.39.40.142
+78.39.40.147
+78.39.40.155
+78.39.43.242
+78.39.46.121
+78.39.46.122
+78.39.46.123
+78.39.46.124
+78.39.46.125
+78.39.46.126
+78.39.46.127
+78.39.48.28
+78.39.48.140
+78.39.48.150
+78.39.48.202
+78.39.49.90
+78.39.50.6
+78.39.50.42
+78.39.50.76
+78.39.50.134
+78.39.50.170
+78.39.50.234
+78.39.53.120
+78.39.53.162
+78.39.53.194
+78.39.53.254
+78.39.56.183
+78.39.57.178
+78.39.57.179
+78.39.59.14
+78.39.59.38
+78.39.59.142
+78.39.62.37
+78.39.62.147
+78.39.62.148
+78.39.67.138
+78.39.80.59
+78.39.80.169
+78.39.81.17
+78.39.81.26
+78.39.81.57
+78.39.81.166
+78.39.82.26
+78.39.83.13
+78.39.83.20
+78.39.83.27
+78.39.83.30
+78.39.83.55
+78.39.83.103
+78.39.83.111
+78.39.83.118
+78.39.83.128
+78.39.88.175
+78.39.99.17
+78.39.99.25
+78.39.99.98
+78.39.102.99
+78.39.102.103
+78.39.102.108
+78.39.103.3
+78.39.103.4
+78.39.103.9
+78.39.103.10
+78.39.103.15
+78.39.103.16
+78.39.103.24
+78.39.108.18
+78.39.108.24
+78.39.108.121
+78.39.108.196
+78.39.109.10
+78.39.109.54
+78.39.117.48
+78.39.124.225
+78.39.125.69
+78.39.125.70
+78.39.125.71
+78.39.125.72
+78.39.125.73
+78.39.125.74
+78.39.125.75
+78.39.125.77
+78.39.125.78
+78.39.125.80
+78.39.125.81
+78.39.136.50
+78.39.138.94
+78.39.138.115
+78.39.140.23
+78.39.141.84
+78.39.141.204
+78.39.144.157
+78.39.145.101
+78.39.145.216
+78.39.147.202
+78.39.150.26
+78.39.159.153
+78.39.175.161
+78.39.176.89
+78.39.180.157
+78.39.180.174
+78.39.181.87
+78.39.181.97
+78.39.192.15
+78.39.193.34
+78.39.193.74
+78.39.193.75
+78.39.193.78
+78.39.194.9
+78.39.195.234
+78.39.195.238
+78.39.198.4
+78.39.204.9
+78.39.204.17
+78.39.204.33
+78.39.209.115
+78.39.209.202
+78.39.217.45
+78.39.217.53
+78.39.217.161
+78.39.217.236
+78.39.218.2
+78.39.218.3
+78.39.218.4
+78.39.218.6
+78.39.218.7
+78.39.218.8
+78.39.218.10
+78.39.218.12
+78.39.220.114
+78.39.220.122
+78.39.220.123
+78.39.220.124
+78.39.220.125
+78.39.220.126
+78.39.220.163
+78.39.225.143
+78.39.226.16
+78.39.226.113
+78.39.227.26
+78.39.228.234
+78.39.229.24
+78.39.230.239
+78.39.233.108
+78.39.233.143
+78.39.233.156
+78.39.233.159
+78.39.234.54
+78.39.234.221
+78.39.234.231
+78.39.235.108
+78.39.235.148
+78.39.244.140
+78.39.245.159
+78.39.249.51
+78.39.249.136
+78.39.250.143
+78.39.251.53
+78.39.251.221
+78.39.252.62
+78.39.253.225
+78.39.255.246
+78.109.194.122
+78.109.195.58
+78.109.196.139
+78.109.198.2
+78.109.199.57
+78.109.201.52
+78.109.201.55
+78.110.120.195
+78.110.120.200
+78.110.120.227
+78.110.122.96
+78.110.123.67
+78.110.124.19
+78.110.124.90
+78.110.124.162
+78.110.124.203
+78.110.124.206
+78.110.125.58
+78.110.125.83
+78.110.125.85
+78.110.125.250
+78.110.126.170
+78.110.127.91
+78.111.0.30
+78.111.0.68
+78.111.1.22
+78.111.3.17
+78.111.3.94
+78.111.3.177
+78.111.5.2
+78.111.5.246
+78.111.7.1
+78.111.7.2
+78.111.7.3
+78.111.7.4
+78.111.7.5
+78.111.7.6
+78.111.7.7
+78.111.7.8
+78.111.7.9
+78.111.7.10
+78.111.7.12
+78.111.7.14
+78.111.7.15
+78.111.7.16
+78.111.7.18
+78.111.7.19
+78.111.7.20
+78.111.7.22
+78.111.7.23
+78.111.7.24
+78.111.7.25
+78.111.7.26
+78.111.7.27
+78.111.7.28
+78.111.7.29
+78.111.7.30
+78.111.7.31
+78.111.7.32
+78.111.7.33
+78.111.7.34
+78.111.7.35
+78.111.7.36
+78.111.7.37
+78.111.7.38
+78.111.7.39
+78.111.7.40
+78.111.7.42
+78.111.7.43
+78.111.7.44
+78.111.7.45
+78.111.7.46
+78.111.7.47
+78.111.7.48
+78.111.7.49
+78.111.7.50
+78.111.7.52
+78.111.7.53
+78.111.7.54
+78.111.7.55
+78.111.7.56
+78.111.7.57
+78.111.7.58
+78.111.7.59
+78.111.7.60
+78.111.7.61
+78.111.7.62
+78.111.7.63
+78.111.7.64
+78.111.7.66
+78.111.7.67
+78.111.7.68
+78.111.7.69
+78.111.7.70
+78.111.7.71
+78.111.7.72
+78.111.7.74
+78.111.7.75
+78.111.7.76
+78.111.7.77
+78.111.7.78
+78.111.7.79
+78.111.7.80
+78.111.7.81
+78.111.7.82
+78.111.7.84
+78.111.7.85
+78.111.7.86
+78.111.7.87
+78.111.7.88
+78.111.7.89
+78.111.7.90
+78.111.7.91
+78.111.7.92
+78.111.7.93
+78.111.7.94
+78.111.7.95
+78.111.7.96
+78.111.7.97
+78.111.7.98
+78.111.7.99
+78.111.7.100
+78.111.7.101
+78.111.7.102
+78.111.7.103
+78.111.7.104
+78.111.7.105
+78.111.7.106
+78.111.7.108
+78.111.7.109
+78.111.7.110
+78.111.7.112
+78.111.7.113
+78.111.7.114
+78.111.7.115
+78.111.7.116
+78.111.7.117
+78.111.7.118
+78.111.7.119
+78.111.7.121
+78.111.7.122
+78.111.7.123
+78.111.7.124
+78.111.7.125
+78.111.7.126
+78.111.7.127
+78.111.7.128
+78.111.7.129
+78.111.7.130
+78.111.7.131
+78.111.7.132
+78.111.7.133
+78.111.7.134
+78.111.7.135
+78.111.7.136
+78.111.7.138
+78.111.7.139
+78.111.7.140
+78.111.7.141
+78.111.7.142
+78.111.7.143
+78.111.7.144
+78.111.7.145
+78.111.7.146
+78.111.7.147
+78.111.7.149
+78.111.7.150
+78.111.7.151
+78.111.7.152
+78.111.7.153
+78.111.7.154
+78.111.7.156
+78.111.7.157
+78.111.7.158
+78.111.7.159
+78.111.7.161
+78.111.7.162
+78.111.7.163
+78.111.7.164
+78.111.7.165
+78.111.7.166
+78.111.7.167
+78.111.7.168
+78.111.7.169
+78.111.7.170
+78.111.7.171
+78.111.7.173
+78.111.7.174
+78.111.7.175
+78.111.7.176
+78.111.7.177
+78.111.7.178
+78.111.7.179
+78.111.7.180
+78.111.7.182
+78.111.7.183
+78.111.7.185
+78.111.7.186
+78.111.7.187
+78.111.7.188
+78.111.7.189
+78.111.7.190
+78.111.7.191
+78.111.7.192
+78.111.7.194
+78.111.7.195
+78.111.7.196
+78.111.7.197
+78.111.7.198
+78.111.7.200
+78.111.7.201
+78.111.7.202
+78.111.7.203
+78.111.7.204
+78.111.7.205
+78.111.7.206
+78.111.7.207
+78.111.7.208
+78.111.7.209
+78.111.7.210
+78.111.7.211
+78.111.7.212
+78.111.7.213
+78.111.7.214
+78.111.7.215
+78.111.7.216
+78.111.7.217
+78.111.7.218
+78.111.7.219
+78.111.7.220
+78.111.7.221
+78.111.7.222
+78.111.7.223
+78.111.7.224
+78.111.7.225
+78.111.7.228
+78.111.7.229
+78.111.7.230
+78.111.7.231
+78.111.7.232
+78.111.7.234
+78.111.7.235
+78.111.7.236
+78.111.7.237
+78.111.7.238
+78.111.7.239
+78.111.7.240
+78.111.7.241
+78.111.7.243
+78.111.7.244
+78.111.7.245
+78.111.7.246
+78.111.7.247
+78.111.7.248
+78.111.7.249
+78.111.7.251
+78.111.7.252
+78.111.7.253
+78.111.7.254
+78.157.34.172
+78.157.34.173
+78.157.35.53
+78.157.35.71
+78.157.35.225
+78.157.36.94
+78.157.36.116
+78.157.36.117
+78.157.36.118
+78.157.36.119
+78.157.36.120
+78.157.36.121
+78.157.36.122
+78.157.36.123
+78.157.36.124
+78.157.36.125
+78.157.36.126
+78.157.38.110
+78.157.38.115
+78.157.38.210
+78.157.39.71
+78.157.39.167
+78.157.39.180
+78.157.40.67
+78.157.40.75
+78.157.40.144
+78.157.41.50
+78.157.41.242
+78.157.41.243
+78.157.42.199
+78.157.42.207
+78.157.44.181
+78.157.44.221
+78.157.45.197
+78.157.48.187
+78.157.48.189
+78.157.48.190
+78.157.48.230
+78.157.49.38
+78.157.49.44
+78.157.50.35
+78.157.50.36
+78.157.50.206
+78.157.50.208
+78.157.50.218
+78.157.50.226
+78.157.51.212
+78.157.51.249
+78.157.51.253
+78.157.53.183
+78.157.56.22
+78.157.56.98
+78.157.56.99
+78.157.56.101
+78.157.57.62
+78.157.57.69
+78.157.57.71
+78.157.57.85
+78.157.57.204
+78.157.57.222
+78.157.57.251
+78.157.60.1
+78.157.60.2
+78.157.60.3
+78.157.60.215
+78.157.61.24
+78.157.61.109
+78.157.62.33
+78.157.62.148
+78.157.63.106
+78.158.165.138
+78.158.165.139
+78.158.166.131
+78.158.166.132
+78.158.168.143
+78.158.168.189
+78.158.168.190
+78.158.179.8
+78.158.179.10
+78.158.179.43
+78.158.179.87
+78.158.179.112
+78.158.179.120
+78.158.179.124
+78.158.179.146
+78.158.179.155
+78.158.179.203
+78.158.182.126
+78.158.191.77
+78.158.191.115
+78.158.191.130
+78.158.191.156
+78.158.191.158
+78.158.191.224
+78.158.191.225
+78.158.191.231
+78.158.191.236
+78.158.191.237
+78.158.191.241
+78.158.191.252
+79.127.0.18
+79.127.0.63
+79.127.0.85
+79.127.0.140
+79.127.0.184
+79.127.0.200
+79.127.0.224
+79.127.1.32
+79.127.1.77
+79.127.1.85
+79.127.1.104
+79.127.1.187
+79.127.1.205
+79.127.1.211
+79.127.1.248
+79.127.2.25
+79.127.2.120
+79.127.2.128
+79.127.2.141
+79.127.2.142
+79.127.2.149
+79.127.2.164
+79.127.2.175
+79.127.2.236
+79.127.3.10
+79.127.3.28
+79.127.3.42
+79.127.3.50
+79.127.3.53
+79.127.3.164
+79.127.3.173
+79.127.3.182
+79.127.3.196
+79.127.3.208
+79.127.3.210
+79.127.4.49
+79.127.4.59
+79.127.4.81
+79.127.4.134
+79.127.4.135
+79.127.4.197
+79.127.4.200
+79.127.4.245
+79.127.5.11
+79.127.5.13
+79.127.5.17
+79.127.5.53
+79.127.5.79
+79.127.5.93
+79.127.5.94
+79.127.5.109
+79.127.5.127
+79.127.5.161
+79.127.5.164
+79.127.6.2
+79.127.6.65
+79.127.6.91
+79.127.6.105
+79.127.6.141
+79.127.6.142
+79.127.6.191
+79.127.6.218
+79.127.6.227
+79.127.7.18
+79.127.7.34
+79.127.7.50
+79.127.7.59
+79.127.7.83
+79.127.7.114
+79.127.7.127
+79.127.7.226
+79.127.11.80
+79.127.11.106
+79.127.11.154
+79.127.11.226
+79.127.12.1
+79.127.12.112
+79.127.12.147
+79.127.12.148
+79.127.12.162
+79.127.13.0
+79.127.13.30
+79.127.13.38
+79.127.13.134
+79.127.13.167
+79.127.13.171
+79.127.13.200
+79.127.13.236
+79.127.14.49
+79.127.14.70
+79.127.14.81
+79.127.14.108
+79.127.14.116
+79.127.14.140
+79.127.14.145
+79.127.15.17
+79.127.15.28
+79.127.15.41
+79.127.15.91
+79.127.15.117
+79.127.15.135
+79.127.15.148
+79.127.15.156
+79.127.15.159
+79.127.15.165
+79.127.15.206
+79.127.15.223
+79.127.15.239
+79.127.16.37
+79.127.24.251
+79.127.29.99
+79.127.29.164
+79.127.30.178
+79.127.30.179
+79.127.30.180
+79.127.30.186
+79.127.31.209
+79.127.32.2
+79.127.32.18
+79.127.32.26
+79.127.32.43
+79.127.32.122
+79.127.32.123
+79.127.32.125
+79.127.32.126
+79.127.32.250
+79.127.33.10
+79.127.33.81
+79.127.33.106
+79.127.33.186
+79.127.33.188
+79.127.33.198
+79.127.34.58
+79.127.34.62
+79.127.34.130
+79.127.34.226
+79.127.34.229
+79.127.35.50
+79.127.35.242
+79.127.35.243
+79.127.36.98
+79.127.37.4
+79.127.37.5
+79.127.37.6
+79.127.37.90
+79.127.37.226
+79.127.37.234
+79.127.37.235
+79.127.40.66
+79.127.40.135
+79.127.40.202
+79.127.41.42
+79.127.42.226
+79.127.45.49
+79.127.47.18
+79.127.47.19
+79.127.47.26
+79.127.47.27
+79.127.47.28
+79.127.47.29
+79.127.47.30
+79.127.47.68
+79.127.47.82
+79.127.47.83
+79.127.47.146
+79.127.47.186
+79.127.47.251
+79.127.49.27
+79.127.49.130
+79.127.49.178
+79.127.49.179
+79.127.50.178
+79.127.50.180
+79.127.50.250
+79.127.51.90
+79.127.51.170
+79.127.51.226
+79.127.52.162
+79.127.52.163
+79.127.52.164
+79.127.52.165
+79.127.52.178
+79.127.52.194
+79.127.52.234
+79.127.53.26
+79.127.53.122
+79.127.53.131
+79.127.53.170
+79.127.54.163
+79.127.54.186
+79.127.54.205
+79.127.54.242
+79.127.54.250
+79.127.55.178
+79.127.55.234
+79.127.56.58
+79.127.56.61
+79.127.56.139
+79.127.56.140
+79.127.56.178
+79.127.59.101
+79.127.60.18
+79.127.63.90
+79.127.63.210
+79.127.65.34
+79.127.65.155
+79.127.66.90
+79.127.66.101
+79.127.66.194
+79.127.66.195
+79.127.66.250
+79.127.68.34
+79.127.68.35
+79.127.68.37
+79.127.68.38
+79.127.69.116
+79.127.69.117
+79.127.69.118
+79.127.69.122
+79.127.69.123
+79.127.69.124
+79.127.69.126
+79.127.69.163
+79.127.70.130
+79.127.70.131
+79.127.70.132
+79.127.70.133
+79.127.70.134
+79.127.70.135
+79.127.70.136
+79.127.70.137
+79.127.70.139
+79.127.70.141
+79.127.70.142
+79.127.70.146
+79.127.70.162
+79.127.71.10
+79.127.71.11
+79.127.71.12
+79.127.71.14
+79.127.71.34
+79.127.71.114
+79.127.71.219
+79.127.71.243
+79.127.72.26
+79.127.72.187
+79.127.72.189
+79.127.72.191
+79.127.72.218
+79.127.73.201
+79.127.74.34
+79.127.74.66
+79.127.74.114
+79.127.74.115
+79.127.74.116
+79.127.74.117
+79.127.74.234
+79.127.74.243
+79.127.75.10
+79.127.76.18
+79.127.76.122
+79.127.76.138
+79.127.76.147
+79.127.76.186
+79.127.76.210
+79.127.76.211
+79.127.76.214
+79.127.76.226
+79.127.77.106
+79.127.77.142
+79.127.77.161
+79.127.78.26
+79.127.78.66
+79.127.79.10
+79.127.79.162
+79.127.79.165
+79.127.80.114
+79.127.80.115
+79.127.81.2
+79.127.81.10
+79.127.82.26
+79.127.83.26
+79.127.83.94
+79.127.83.114
+79.127.83.202
+79.127.84.122
+79.127.84.124
+79.127.84.125
+79.127.84.126
+79.127.85.170
+79.127.85.171
+79.127.85.178
+79.127.86.11
+79.127.86.252
+79.127.87.179
+79.127.87.226
+79.127.92.1
+79.127.92.8
+79.127.92.9
+79.127.92.16
+79.127.92.17
+79.127.92.20
+79.127.92.79
+79.127.92.83
+79.127.92.106
+79.127.92.166
+79.127.92.180
+79.127.92.186
+79.127.92.215
+79.127.92.217
+79.127.92.221
+79.127.92.238
+79.127.94.21
+79.127.94.22
+79.127.94.30
+79.127.94.36
+79.127.94.55
+79.127.94.57
+79.127.94.59
+79.127.94.83
+79.127.94.91
+79.127.94.108
+79.127.94.116
+79.127.94.135
+79.127.94.141
+79.127.94.142
+79.127.94.157
+79.127.94.163
+79.127.94.170
+79.127.94.184
+79.127.94.187
+79.127.94.213
+79.127.94.228
+79.127.94.255
+79.127.95.6
+79.127.95.14
+79.127.95.63
+79.127.95.74
+79.127.95.96
+79.127.95.102
+79.127.95.107
+79.127.95.110
+79.127.95.117
+79.127.95.119
+79.127.95.130
+79.127.95.133
+79.127.95.139
+79.127.95.143
+79.127.95.164
+79.127.95.184
+79.127.95.193
+79.127.95.195
+79.127.95.205
+79.127.95.230
+79.127.95.234
+79.127.95.236
+79.127.95.241
+79.127.95.248
+79.127.96.6
+79.127.96.40
+79.127.101.21
+79.127.101.194
+79.127.102.143
+79.127.103.225
+79.127.107.233
+79.127.108.80
+79.127.110.91
+79.127.113.91
+79.127.116.1
+79.127.116.9
+79.127.116.17
+79.127.116.56
+79.127.116.186
+79.127.117.60
+79.127.117.66
+79.127.117.199
+79.127.119.146
+79.127.120.51
+79.127.120.82
+79.127.120.218
+79.127.120.222
+79.127.121.10
+79.127.121.184
+79.127.121.185
+79.127.121.187
+79.127.121.188
+79.127.121.189
+79.127.121.226
+79.127.122.10
+79.127.122.98
+79.127.123.34
+79.127.124.106
+79.127.125.74
+79.127.125.75
+79.127.125.76
+79.127.125.77
+79.127.125.78
+79.127.125.212
+79.127.126.67
+79.127.126.93
+79.127.126.114
+79.127.126.243
+79.127.127.71
+79.127.127.73
+79.127.127.122
+79.127.127.214
+79.127.127.216
+79.132.193.34
+79.132.193.58
+79.132.193.73
+79.132.193.196
+79.132.193.198
+79.132.193.212
+79.132.193.235
+79.132.205.29
+79.132.205.33
+79.132.206.198
+79.132.206.209
+79.132.206.217
+79.132.208.49
+79.132.208.50
+79.132.208.53
+79.132.214.254
+79.143.84.70
+79.143.86.3
+79.143.86.11
+79.143.86.12
+79.143.86.40
+79.143.86.50
+79.143.86.66
+79.143.86.129
+79.143.86.158
+79.143.86.161
+79.143.86.193
+79.143.86.201
+79.143.86.209
+79.174.160.210
+79.174.160.222
+79.175.131.190
+79.175.131.196
+79.175.131.253
+79.175.133.54
+79.175.134.37
+79.175.139.185
+79.175.149.66
+79.175.149.68
+79.175.149.69
+79.175.149.70
+79.175.149.217
+79.175.151.43
+79.175.151.142
+79.175.152.194
+79.175.152.195
+79.175.153.210
+79.175.153.211
+79.175.153.212
+79.175.153.213
+79.175.153.214
+79.175.153.215
+79.175.153.217
+79.175.153.218
+79.175.153.219
+79.175.153.221
+79.175.153.222
+79.175.162.226
+79.175.163.215
+79.175.165.171
+79.175.167.96
+79.175.168.78
+79.175.168.220
+79.175.168.222
+79.175.169.50
+79.175.169.61
+79.175.169.213
+79.175.169.221
+79.175.170.133
+79.175.173.154
+79.175.173.155
+79.175.173.156
+79.175.173.157
+79.175.173.158
+79.175.176.2
+79.175.176.90
+79.175.177.8
+79.175.177.10
+79.175.177.125
+79.175.187.189
+79.175.189.3
+79.175.189.4
+79.175.189.231
+80.66.177.23
+80.71.112.51
+80.71.112.98
+80.71.112.115
+80.71.114.16
+80.71.114.19
+80.71.114.23
+80.71.114.38
+80.71.114.148
+80.71.114.153
+80.71.114.164
+80.71.114.175
+80.71.114.197
+80.71.114.203
+80.71.118.2
+80.71.149.32
+80.71.149.62
+80.75.0.201
+80.75.1.66
+80.75.1.230
+80.75.4.24
+80.75.4.50
+80.75.4.66
+80.75.4.67
+80.75.4.68
+80.75.4.69
+80.75.4.76
+80.75.4.77
+80.75.7.22
+80.75.7.58
+80.75.7.66
+80.75.7.94
+80.75.7.170
+80.75.7.171
+80.75.7.172
+80.75.7.173
+80.75.7.174
+80.75.8.194
+80.75.9.182
+80.75.9.197
+80.75.9.222
+80.75.11.58
+80.75.12.100
+80.75.13.30
+80.75.13.34
+80.75.13.107
+80.75.13.178
+80.75.14.34
+80.75.14.110
+80.75.14.111
+80.75.14.130
+80.75.14.219
+80.75.14.250
+80.75.213.163
+80.75.213.247
+80.91.208.26
+80.91.208.27
+80.91.208.28
+80.91.208.29
+80.91.208.30
+80.91.208.75
+80.91.208.76
+80.191.2.7
+80.191.2.224
+80.191.11.45
+80.191.11.217
+80.191.16.15
+80.191.16.68
+80.191.16.126
+80.191.16.194
+80.191.17.100
+80.191.18.190
+80.191.18.211
+80.191.23.134
+80.191.27.33
+80.191.27.34
+80.191.40.130
+80.191.40.131
+80.191.40.132
+80.191.40.133
+80.191.40.134
+80.191.40.135
+80.191.40.138
+80.191.40.139
+80.191.40.140
+80.191.40.141
+80.191.40.142
+80.191.40.143
+80.191.40.144
+80.191.40.145
+80.191.40.146
+80.191.40.147
+80.191.40.148
+80.191.40.149
+80.191.40.150
+80.191.40.151
+80.191.40.153
+80.191.40.154
+80.191.40.155
+80.191.40.156
+80.191.40.157
+80.191.40.158
+80.191.42.10
+80.191.44.80
+80.191.44.91
+80.191.46.150
+80.191.50.28
+80.191.50.253
+80.191.51.53
+80.191.52.37
+80.191.52.216
+80.191.52.254
+80.191.60.35
+80.191.60.36
+80.191.75.159
+80.191.77.139
+80.191.84.18
+80.191.85.46
+80.191.89.66
+80.191.91.57
+80.191.91.84
+80.191.91.109
+80.191.92.74
+80.191.100.9
+80.191.100.67
+80.191.100.106
+80.191.100.124
+80.191.100.182
+80.191.100.199
+80.191.102.39
+80.191.102.46
+80.191.102.93
+80.191.102.154
+80.191.102.167
+80.191.102.225
+80.191.102.241
+80.191.106.141
+80.191.106.144
+80.191.106.237
+80.191.107.16
+80.191.107.90
+80.191.108.51
+80.191.108.70
+80.191.108.107
+80.191.108.164
+80.191.108.192
+80.191.108.228
+80.191.110.90
+80.191.110.161
+80.191.110.178
+80.191.115.120
+80.191.115.122
+80.191.116.30
+80.191.128.1
+80.191.131.64
+80.191.143.18
+80.191.144.1
+80.191.152.66
+80.191.153.1
+80.191.153.4
+80.191.153.107
+80.191.155.242
+80.191.160.149
+80.191.164.98
+80.191.164.105
+80.191.168.212
+80.191.169.162
+80.191.171.224
+80.191.172.9
+80.191.172.23
+80.191.172.33
+80.191.172.35
+80.191.172.50
+80.191.172.81
+80.191.185.180
+80.191.186.118
+80.191.189.125
+80.191.190.179
+80.191.191.11
+80.191.191.12
+80.191.191.14
+80.191.191.18
+80.191.192.209
+80.191.197.194
+80.191.198.122
+80.191.198.226
+80.191.200.3
+80.191.200.5
+80.191.206.50
+80.191.206.66
+80.191.206.98
+80.191.206.135
+80.191.207.2
+80.191.207.3
+80.191.207.4
+80.191.207.5
+80.191.207.7
+80.191.207.9
+80.191.207.10
+80.191.207.11
+80.191.207.21
+80.191.207.33
+80.191.207.34
+80.191.207.35
+80.191.207.37
+80.191.207.38
+80.191.207.40
+80.191.209.94
+80.191.209.105
+80.191.212.141
+80.191.221.26
+80.191.221.27
+80.191.221.33
+80.191.227.147
+80.191.227.148
+80.191.235.90
+80.191.235.91
+80.191.235.92
+80.191.235.93
+80.191.235.94
+80.191.235.145
+80.191.235.194
+80.191.236.19
+80.191.238.82
+80.191.238.83
+80.191.240.66
+80.191.240.128
+80.191.240.138
+80.191.240.185
+80.191.240.191
+80.191.241.194
+80.191.241.195
+80.191.241.196
+80.191.241.197
+80.191.241.198
+80.191.241.199
+80.191.241.200
+80.191.241.201
+80.191.241.202
+80.191.241.203
+80.191.241.205
+80.191.241.208
+80.191.241.209
+80.191.241.210
+80.191.241.212
+80.191.241.214
+80.191.241.217
+80.191.241.218
+80.191.241.220
+80.191.241.221
+80.191.242.2
+80.191.242.110
+80.191.243.226
+80.191.243.234
+80.191.245.235
+80.191.252.152
+80.191.253.205
+80.191.255.18
+80.191.255.22
+80.210.17.128
+80.210.17.137
+80.210.17.163
+80.210.17.197
+80.210.17.229
+80.210.17.240
+80.210.17.249
+80.210.18.45
+80.210.18.93
+80.210.18.121
+80.210.18.147
+80.210.18.219
+80.210.18.220
+80.210.18.235
+80.210.18.243
+80.210.19.31
+80.210.19.69
+80.210.19.124
+80.210.19.172
+80.210.19.179
+80.210.19.186
+80.210.19.215
+80.210.19.220
+80.210.20.31
+80.210.20.88
+80.210.21.16
+80.210.21.70
+80.210.21.84
+80.210.21.91
+80.210.21.179
+80.210.21.211
+80.210.21.224
+80.210.22.14
+80.210.22.47
+80.210.22.77
+80.210.22.79
+80.210.22.113
+80.210.22.140
+80.210.22.142
+80.210.22.153
+80.210.22.217
+80.210.22.229
+80.210.22.243
+80.210.24.7
+80.210.24.89
+80.210.24.110
+80.210.24.158
+80.210.24.185
+80.210.24.246
+80.210.25.33
+80.210.25.237
+80.210.26.72
+80.210.26.90
+80.210.26.101
+80.210.26.104
+80.210.26.110
+80.210.26.120
+80.210.26.126
+80.210.26.179
+80.210.26.219
+80.210.26.228
+80.210.26.240
+80.210.26.251
+80.210.27.111
+80.210.27.140
+80.210.27.148
+80.210.27.153
+80.210.27.187
+80.210.27.213
+80.210.27.221
+80.210.28.38
+80.210.28.52
+80.210.28.88
+80.210.28.161
+80.210.29.27
+80.210.29.50
+80.210.29.57
+80.210.29.105
+80.210.29.132
+80.210.29.155
+80.210.29.168
+80.210.29.175
+80.210.29.180
+80.210.29.184
+80.210.29.224
+80.210.30.2
+80.210.30.57
+80.210.30.129
+80.210.30.152
+80.210.30.155
+80.210.30.170
+80.210.30.202
+80.210.30.251
+80.210.31.23
+80.210.31.60
+80.210.31.74
+80.210.31.112
+80.210.31.133
+80.210.31.151
+80.210.31.184
+80.210.31.218
+80.210.31.223
+80.210.31.229
+80.210.32.40
+80.210.32.63
+80.210.32.103
+80.210.32.104
+80.210.32.116
+80.210.32.131
+80.210.32.143
+80.210.32.146
+80.210.32.176
+80.210.32.201
+80.210.32.235
+80.210.33.52
+80.210.33.166
+80.210.33.227
+80.210.33.238
+80.210.34.40
+80.210.34.71
+80.210.34.89
+80.210.34.137
+80.210.34.150
+80.210.34.172
+80.210.34.230
+80.210.35.144
+80.210.35.159
+80.210.35.171
+80.210.35.175
+80.210.36.17
+80.210.36.37
+80.210.36.68
+80.210.36.111
+80.210.36.121
+80.210.36.169
+80.210.36.196
+80.210.36.201
+80.210.36.203
+80.210.37.14
+80.210.37.100
+80.210.37.115
+80.210.37.209
+80.210.38.53
+80.210.38.67
+80.210.38.101
+80.210.38.127
+80.210.38.130
+80.210.38.178
+80.210.38.187
+80.210.38.205
+80.210.38.222
+80.210.38.251
+80.210.39.57
+80.210.39.81
+80.210.39.98
+80.210.39.153
+80.210.39.167
+80.210.39.205
+80.210.39.221
+80.210.39.230
+80.210.40.34
+80.210.40.72
+80.210.40.98
+80.210.40.109
+80.210.40.147
+80.210.40.192
+80.210.40.195
+80.210.40.213
+80.210.40.233
+80.210.41.13
+80.210.41.22
+80.210.41.34
+80.210.41.113
+80.210.41.116
+80.210.41.236
+80.210.42.3
+80.210.42.11
+80.210.42.18
+80.210.42.49
+80.210.42.69
+80.210.42.149
+80.210.42.161
+80.210.42.169
+80.210.43.101
+80.210.43.108
+80.210.43.131
+80.210.43.141
+80.210.43.169
+80.210.43.184
+80.210.43.217
+80.210.44.21
+80.210.44.59
+80.210.44.71
+80.210.44.105
+80.210.44.147
+80.210.44.184
+80.210.44.187
+80.210.44.245
+80.210.45.59
+80.210.45.107
+80.210.45.234
+80.210.46.105
+80.210.46.171
+80.210.46.202
+80.210.46.246
+80.210.47.68
+80.210.47.93
+80.210.47.94
+80.210.47.149
+80.210.48.24
+80.210.48.26
+80.210.48.48
+80.210.48.57
+80.210.48.84
+80.210.48.98
+80.210.48.147
+80.210.48.177
+80.210.49.41
+80.210.49.70
+80.210.49.79
+80.210.49.83
+80.210.49.173
+80.210.49.196
+80.210.49.232
+80.210.50.30
+80.210.50.35
+80.210.50.40
+80.210.50.173
+80.210.51.50
+80.210.51.82
+80.210.51.202
+80.210.52.240
+80.210.53.34
+80.210.53.35
+80.210.53.70
+80.210.53.97
+80.210.53.209
+80.210.53.213
+80.210.54.38
+80.210.54.40
+80.210.54.49
+80.210.54.52
+80.210.54.60
+80.210.54.68
+80.210.54.95
+80.210.54.118
+80.210.54.185
+80.210.54.199
+80.210.54.217
+80.210.54.221
+80.210.54.243
+80.210.55.19
+80.210.55.56
+80.210.55.87
+80.210.55.118
+80.210.55.120
+80.210.55.131
+80.210.55.146
+80.210.55.161
+80.210.56.0
+80.210.56.83
+80.210.56.102
+80.210.56.141
+80.210.56.143
+80.210.56.169
+80.210.56.186
+80.210.56.199
+80.210.56.205
+80.210.56.225
+80.210.56.233
+80.210.56.253
+80.210.57.117
+80.210.58.1
+80.210.58.7
+80.210.58.29
+80.210.58.59
+80.210.58.73
+80.210.58.86
+80.210.58.89
+80.210.58.111
+80.210.58.117
+80.210.58.133
+80.210.58.142
+80.210.58.146
+80.210.58.163
+80.210.58.229
+80.210.58.243
+80.210.59.100
+80.210.60.109
+80.210.60.150
+80.210.60.155
+80.210.60.211
+80.210.61.20
+80.210.61.51
+80.210.61.123
+80.210.61.124
+80.210.61.128
+80.210.61.141
+80.210.61.159
+80.210.61.174
+80.210.61.178
+80.210.62.57
+80.210.62.109
+80.210.62.128
+80.210.62.146
+80.210.62.155
+80.210.62.173
+80.210.62.195
+80.210.62.203
+80.210.62.206
+80.210.62.210
+80.210.62.237
+80.210.63.3
+80.210.63.13
+80.210.63.21
+80.210.63.26
+80.210.63.63
+80.210.63.107
+80.210.63.142
+80.210.63.153
+80.210.63.185
+80.210.63.194
+80.210.63.233
+80.210.63.243
+80.210.63.251
+80.210.128.198
+80.210.131.213
+80.210.132.9
+80.210.132.50
+80.210.132.100
+80.210.132.101
+80.210.132.191
+80.210.133.249
+80.210.134.163
+80.210.135.10
+80.210.135.125
+80.210.137.2
+80.210.139.10
+80.210.139.68
+80.210.141.214
+80.210.141.239
+80.210.142.6
+80.210.142.54
+80.210.143.142
+80.210.160.23
+80.210.164.73
+80.210.164.78
+80.210.165.60
+80.210.165.199
+80.210.168.207
+80.210.170.150
+80.210.171.56
+80.210.171.115
+80.210.172.44
+80.210.172.76
+80.210.172.118
+80.210.174.109
+80.210.176.194
+80.210.177.164
+80.250.200.1
+80.253.133.144
+80.253.133.145
+80.253.152.222
+81.12.1.27
+81.12.5.22
+81.12.5.152
+81.12.5.229
+81.12.5.247
+81.12.5.250
+81.12.6.34
+81.12.6.58
+81.12.7.57
+81.12.7.219
+81.12.7.220
+81.12.7.221
+81.12.12.233
+81.12.24.167
+81.12.24.170
+81.12.24.198
+81.12.24.203
+81.12.24.205
+81.12.24.224
+81.12.24.250
+81.12.25.25
+81.12.26.27
+81.12.26.28
+81.12.26.29
+81.12.26.31
+81.12.26.32
+81.12.26.112
+81.12.26.113
+81.12.26.114
+81.12.26.115
+81.12.26.116
+81.12.26.117
+81.12.26.118
+81.12.26.119
+81.12.26.127
+81.12.26.128
+81.12.26.129
+81.12.27.123
+81.12.27.252
+81.12.32.164
+81.12.33.99
+81.12.36.37
+81.12.36.58
+81.12.36.94
+81.12.36.155
+81.12.36.178
+81.12.36.190
+81.12.36.217
+81.12.39.30
+81.12.39.136
+81.12.39.142
+81.12.39.145
+81.12.39.192
+81.12.39.217
+81.12.39.232
+81.12.39.234
+81.12.39.245
+81.12.40.14
+81.12.40.86
+81.12.40.165
+81.12.41.54
+81.12.41.178
+81.12.41.251
+81.12.41.252
+81.12.41.253
+81.12.41.254
+81.12.43.66
+81.12.43.238
+81.12.43.242
+81.12.44.26
+81.12.47.94
+81.12.47.234
+81.12.47.235
+81.12.47.236
+81.12.47.237
+81.12.47.238
+81.12.52.94
+81.12.53.132
+81.12.53.163
+81.12.53.235
+81.12.53.236
+81.12.64.10
+81.12.64.11
+81.12.64.13
+81.12.64.14
+81.12.64.66
+81.12.64.67
+81.12.64.68
+81.12.64.69
+81.12.64.71
+81.12.64.72
+81.12.64.73
+81.12.64.77
+81.12.65.42
+81.12.65.135
+81.12.69.174
+81.12.70.98
+81.12.70.178
+81.12.71.10
+81.12.71.98
+81.12.72.108
+81.12.72.162
+81.12.72.238
+81.12.72.251
+81.12.73.150
+81.12.74.16
+81.12.75.30
+81.12.75.58
+81.12.75.243
+81.12.76.250
+81.12.78.130
+81.12.79.82
+81.12.85.237
+81.12.85.241
+81.12.85.245
+81.12.87.2
+81.12.87.136
+81.12.87.138
+81.12.87.139
+81.12.87.141
+81.12.87.142
+81.12.87.226
+81.12.88.51
+81.12.89.74
+81.12.89.86
+81.12.89.243
+81.12.90.74
+81.12.90.246
+81.12.93.106
+81.12.94.74
+81.12.94.106
+81.12.95.18
+81.12.98.2
+81.12.98.125
+81.12.99.22
+81.12.99.98
+81.12.99.99
+81.12.99.100
+81.12.99.101
+81.12.99.102
+81.12.99.103
+81.12.99.105
+81.12.99.138
+81.12.99.227
+81.12.100.174
+81.12.100.216
+81.12.100.222
+81.12.102.145
+81.12.102.149
+81.12.102.153
+81.12.104.34
+81.12.104.36
+81.12.104.37
+81.12.104.38
+81.12.104.39
+81.12.104.40
+81.12.104.42
+81.12.104.43
+81.12.104.44
+81.12.104.45
+81.12.104.46
+81.12.104.66
+81.12.104.67
+81.12.104.68
+81.12.104.69
+81.12.104.70
+81.12.104.71
+81.12.104.73
+81.12.104.74
+81.12.105.50
+81.12.105.56
+81.12.105.57
+81.12.105.58
+81.12.105.62
+81.12.106.27
+81.12.106.130
+81.12.107.26
+81.12.108.90
+81.12.108.92
+81.12.108.93
+81.12.108.94
+81.12.108.98
+81.12.108.115
+81.12.108.116
+81.12.108.118
+81.12.109.19
+81.12.109.22
+81.12.109.134
+81.12.109.170
+81.12.109.174
+81.12.110.130
+81.12.111.166
+81.12.112.10
+81.12.113.18
+81.12.113.101
+81.12.113.118
+81.12.113.196
+81.12.113.198
+81.12.113.212
+81.12.114.62
+81.12.116.10
+81.12.116.174
+81.12.117.114
+81.12.117.119
+81.12.117.120
+81.12.118.34
+81.12.118.35
+81.12.118.36
+81.12.118.37
+81.12.118.38
+81.12.118.39
+81.12.118.41
+81.12.118.42
+81.12.118.43
+81.12.118.44
+81.12.118.45
+81.12.118.47
+81.12.118.48
+81.12.118.49
+81.12.118.50
+81.12.118.51
+81.12.118.52
+81.12.118.53
+81.12.118.57
+81.12.118.58
+81.12.118.59
+81.12.118.60
+81.12.118.61
+81.12.118.62
+81.12.118.210
+81.12.118.211
+81.12.118.212
+81.12.118.213
+81.12.119.114
+81.12.119.138
+81.12.119.214
+81.12.120.26
+81.12.120.62
+81.12.120.132
+81.12.120.220
+81.12.120.222
+81.12.120.234
+81.12.120.235
+81.12.120.236
+81.12.121.19
+81.12.122.118
+81.12.123.66
+81.12.124.33
+81.12.124.105
+81.12.124.114
+81.12.125.130
+81.12.125.146
+81.12.125.148
+81.12.125.152
+81.12.125.153
+81.12.125.156
+81.12.127.54
+81.16.112.6
+81.16.112.154
+81.16.112.213
+81.16.112.215
+81.16.113.82
+81.16.113.85
+81.16.113.88
+81.16.113.110
+81.16.113.118
+81.16.113.122
+81.16.113.165
+81.16.114.84
+81.16.114.86
+81.16.114.127
+81.16.114.134
+81.16.114.155
+81.16.116.18
+81.16.116.89
+81.16.116.92
+81.16.116.97
+81.16.116.211
+81.16.116.220
+81.16.116.228
+81.16.116.233
+81.16.117.127
+81.16.117.129
+81.16.117.205
+81.16.118.109
+81.16.118.156
+81.16.119.27
+81.16.119.55
+81.16.119.78
+81.16.119.196
+81.16.119.229
+81.16.120.60
+81.16.120.93
+81.16.120.119
+81.16.120.122
+81.16.120.236
+81.16.121.93
+81.16.121.114
+81.16.121.115
+81.16.121.178
+81.16.121.221
+81.16.121.226
+81.16.122.194
+81.16.122.212
+81.16.123.3
+81.16.123.248
+81.16.124.33
+81.16.124.54
+81.16.124.67
+81.16.124.71
+81.16.124.72
+81.16.124.80
+81.16.124.147
+81.16.124.148
+81.16.124.184
+81.16.124.243
+81.16.125.8
+81.16.125.9
+81.16.125.21
+81.16.125.46
+81.16.125.181
+81.16.125.190
+81.16.125.194
+81.16.125.213
+81.16.125.221
+81.16.126.44
+81.16.126.67
+81.16.126.81
+81.16.126.92
+81.16.126.137
+81.16.126.144
+81.16.126.196
+81.16.127.47
+81.16.127.72
+81.16.127.94
+81.16.127.112
+81.16.127.155
+81.16.127.160
+81.16.127.186
+81.16.127.189
+81.16.127.192
+81.16.127.199
+81.16.127.204
+81.16.127.205
+81.16.127.254
+81.28.36.146
+81.28.43.30
+81.28.43.162
+81.28.47.2
+81.28.50.2
+81.28.57.2
+81.28.60.102
+81.28.252.58
+81.28.252.59
+81.28.252.136
+81.28.252.171
+81.28.252.243
+81.28.253.103
+81.28.253.144
+81.28.253.157
+81.28.253.175
+81.29.248.22
+81.29.248.38
+81.29.248.109
+81.29.248.202
+81.29.249.86
+81.29.249.190
+81.29.249.242
+81.29.249.246
+81.29.255.170
+81.29.255.218
+81.31.250.2
+81.31.250.5
+81.31.250.6
+81.31.250.11
+81.31.250.13
+81.31.250.15
+81.31.250.18
+81.31.250.21
+81.31.250.130
+81.31.250.146
+81.31.250.147
+81.31.250.232
+81.31.250.250
+81.90.145.19
+81.90.145.37
+81.90.145.76
+81.90.145.94
+81.90.145.116
+81.90.145.120
+81.90.146.66
+81.90.148.106
+81.90.149.178
+81.90.149.234
+81.90.149.254
+81.90.152.38
+81.90.152.86
+81.90.154.178
+81.90.154.179
+81.90.154.180
+81.90.154.181
+81.90.154.182
+81.90.154.183
+81.90.154.184
+81.90.154.186
+81.90.154.187
+81.90.154.188
+81.90.154.190
+81.90.157.82
+81.90.158.110
+81.90.159.158
+81.91.129.228
+81.91.132.20
+81.91.136.134
+81.91.137.34
+81.91.138.3
+81.91.138.67
+81.91.138.114
+81.91.138.182
+81.91.139.18
+81.91.144.116
+81.91.145.2
+81.91.145.7
+81.91.145.66
+81.91.145.78
+81.91.145.192
+81.91.145.193
+81.91.145.194
+81.91.145.195
+81.91.146.30
+81.91.146.138
+81.91.146.202
+81.91.146.203
+81.91.146.214
+81.91.147.30
+81.91.150.66
+81.91.150.190
+81.91.152.6
+81.91.152.70
+81.91.152.86
+81.91.153.2
+81.91.153.10
+81.91.153.26
+81.91.153.210
+81.91.153.211
+81.91.153.234
+81.91.154.69
+81.91.154.82
+81.91.154.230
+81.91.155.2
+81.91.155.22
+81.91.156.67
+81.91.156.134
+81.91.156.150
+81.91.157.6
+81.91.157.50
+81.91.157.51
+81.91.157.134
+81.91.158.126
+81.91.158.130
+81.91.158.132
+81.91.158.133
+81.91.158.218
+81.91.159.34
+81.91.159.82
+81.91.159.106
+81.91.159.170
+81.91.159.234
+81.163.0.33
+81.163.0.79
+81.163.0.96
+81.163.0.97
+81.163.0.110
+81.163.0.117
+81.163.0.138
+81.163.1.66
+81.163.1.105
+81.163.1.106
+81.163.1.107
+81.163.1.108
+81.163.1.109
+81.163.1.180
+81.163.3.1
+81.163.3.2
+81.163.4.85
+81.163.6.30
+81.163.6.107
+81.163.7.49
+81.163.7.57
+81.163.7.71
+82.99.194.34
+82.99.194.106
+82.99.194.197
+82.99.195.82
+82.99.195.110
+82.99.195.114
+82.99.201.162
+82.99.201.163
+82.99.201.164
+82.99.201.166
+82.99.201.180
+82.99.201.182
+82.99.202.157
+82.99.202.209
+82.99.202.210
+82.99.202.218
+82.99.202.225
+82.99.202.227
+82.99.204.1
+82.99.204.18
+82.99.204.21
+82.99.204.249
+82.99.206.98
+82.99.206.99
+82.99.206.191
+82.99.213.62
+82.99.213.206
+82.99.214.106
+82.99.214.107
+82.99.214.109
+82.99.214.110
+82.99.230.170
+82.99.247.45
+82.99.248.106
+82.99.248.114
+82.99.248.214
+82.99.249.230
+82.99.250.178
+82.99.250.228
+82.99.252.247
+82.99.253.81
+82.99.254.250
+82.102.14.39
+82.102.14.248
+83.97.72.1
+83.97.72.50
+83.97.72.254
+83.147.193.5
+83.150.193.79
+84.47.225.198
+84.47.226.106
+84.47.226.108
+84.47.226.111
+84.47.226.242
+84.47.227.194
+84.47.236.57
+84.47.236.59
+84.47.236.74
+84.47.236.112
+84.47.236.113
+84.47.236.200
+84.47.239.21
+84.241.0.3
+84.241.0.62
+84.241.0.119
+84.241.0.123
+84.241.0.156
+84.241.0.223
+84.241.0.226
+84.241.0.232
+84.241.1.36
+84.241.1.71
+84.241.1.76
+84.241.1.99
+84.241.1.119
+84.241.1.203
+84.241.1.248
+84.241.1.254
+84.241.2.85
+84.241.2.90
+84.241.2.198
+84.241.2.206
+84.241.2.235
+84.241.3.50
+84.241.3.98
+84.241.3.105
+84.241.3.137
+84.241.3.149
+84.241.3.199
+84.241.3.235
+84.241.4.8
+84.241.4.33
+84.241.4.68
+84.241.4.86
+84.241.4.140
+84.241.4.192
+84.241.5.18
+84.241.5.20
+84.241.5.45
+84.241.5.52
+84.241.5.79
+84.241.5.94
+84.241.5.140
+84.241.5.176
+84.241.5.253
+84.241.6.19
+84.241.6.72
+84.241.6.105
+84.241.6.150
+84.241.6.165
+84.241.6.197
+84.241.6.236
+84.241.6.248
+84.241.7.8
+84.241.7.46
+84.241.7.48
+84.241.7.61
+84.241.7.136
+84.241.7.233
+84.241.8.39
+84.241.8.50
+84.241.8.225
+84.241.8.238
+84.241.9.7
+84.241.9.51
+84.241.9.69
+84.241.9.79
+84.241.9.96
+84.241.9.105
+84.241.9.108
+84.241.9.115
+84.241.9.171
+84.241.9.191
+84.241.9.200
+84.241.9.223
+84.241.9.233
+84.241.9.234
+84.241.9.236
+84.241.10.57
+84.241.10.70
+84.241.10.99
+84.241.10.131
+84.241.10.164
+84.241.10.193
+84.241.10.212
+84.241.10.216
+84.241.11.10
+84.241.11.26
+84.241.11.61
+84.241.11.66
+84.241.11.73
+84.241.11.138
+84.241.11.144
+84.241.11.145
+84.241.11.172
+84.241.11.190
+84.241.11.211
+84.241.12.24
+84.241.12.49
+84.241.12.69
+84.241.12.104
+84.241.12.112
+84.241.12.138
+84.241.12.153
+84.241.12.165
+84.241.12.197
+84.241.13.93
+84.241.13.133
+84.241.13.136
+84.241.13.171
+84.241.13.210
+84.241.13.235
+84.241.13.241
+84.241.14.30
+84.241.14.50
+84.241.14.126
+84.241.14.157
+84.241.14.198
+84.241.14.239
+84.241.15.2
+84.241.15.6
+84.241.15.56
+84.241.15.75
+84.241.15.127
+84.241.15.147
+84.241.15.161
+84.241.15.189
+84.241.15.203
+84.241.15.208
+84.241.15.220
+84.241.15.230
+84.241.15.253
+84.241.15.254
+84.241.16.13
+84.241.16.17
+84.241.16.44
+84.241.16.54
+84.241.16.66
+84.241.16.126
+84.241.16.165
+84.241.16.195
+84.241.16.219
+84.241.16.222
+84.241.16.232
+84.241.18.90
+84.241.18.108
+84.241.18.161
+84.241.18.185
+84.241.18.195
+84.241.18.197
+84.241.18.246
+84.241.19.9
+84.241.19.22
+84.241.19.52
+84.241.19.111
+84.241.19.115
+84.241.19.134
+84.241.19.172
+84.241.19.186
+84.241.19.229
+84.241.20.91
+84.241.21.48
+84.241.21.127
+84.241.21.213
+84.241.21.216
+84.241.21.245
+84.241.22.38
+84.241.22.52
+84.241.22.61
+84.241.22.94
+84.241.22.157
+84.241.22.245
+84.241.23.238
+84.241.24.10
+84.241.24.55
+84.241.24.58
+84.241.24.59
+84.241.24.132
+84.241.24.204
+84.241.24.207
+84.241.24.233
+84.241.24.249
+84.241.24.254
+84.241.25.4
+84.241.25.30
+84.241.25.79
+84.241.25.124
+84.241.25.131
+84.241.25.178
+84.241.25.187
+84.241.25.200
+84.241.25.205
+84.241.25.239
+84.241.25.244
+84.241.26.9
+84.241.26.29
+84.241.26.34
+84.241.26.40
+84.241.26.58
+84.241.26.65
+84.241.26.98
+84.241.26.100
+84.241.26.149
+84.241.26.240
+84.241.27.13
+84.241.27.86
+84.241.27.124
+84.241.27.145
+84.241.27.180
+84.241.27.189
+84.241.28.10
+84.241.28.27
+84.241.28.36
+84.241.28.49
+84.241.28.80
+84.241.28.85
+84.241.28.101
+84.241.29.26
+84.241.29.70
+84.241.29.119
+84.241.29.129
+84.241.29.194
+84.241.29.206
+84.241.29.228
+84.241.30.13
+84.241.30.33
+84.241.30.57
+84.241.30.96
+84.241.30.103
+84.241.30.111
+84.241.30.190
+84.241.30.224
+84.241.31.0
+84.241.31.7
+84.241.31.53
+84.241.31.90
+84.241.31.100
+84.241.32.19
+84.241.32.78
+84.241.32.89
+84.241.32.203
+84.241.32.254
+84.241.33.19
+84.241.33.183
+84.241.34.132
+84.241.35.0
+84.241.35.155
+84.241.36.15
+84.241.36.86
+84.241.36.104
+84.241.36.116
+84.241.36.138
+84.241.36.150
+84.241.37.79
+84.241.37.202
+84.241.37.211
+84.241.37.234
+84.241.38.130
+84.241.38.131
+84.241.38.177
+84.241.40.188
+84.241.41.21
+84.241.41.131
+84.241.41.197
+84.241.41.225
+84.241.42.178
+84.241.43.18
+84.241.43.118
+84.241.43.119
+84.241.44.96
+84.241.44.106
+84.241.44.211
+84.241.44.245
+84.241.45.14
+84.241.45.183
+84.241.45.194
+84.241.46.127
+84.241.46.177
+84.241.47.6
+84.241.47.109
+84.241.47.190
+84.241.47.244
+84.241.51.38
+84.241.51.93
+84.241.53.153
+84.241.53.175
+84.241.53.190
+84.241.53.243
+84.241.54.101
+84.241.55.13
+84.241.55.14
+84.241.55.30
+84.241.55.57
+84.241.55.234
+84.241.55.250
+84.241.56.80
+84.241.59.241
+84.241.59.249
+84.241.59.251
+84.241.59.252
+84.241.59.253
+84.241.59.254
+84.241.60.21
+84.241.60.253
+84.241.61.1
+84.241.61.193
+84.241.63.25
+85.9.65.241
+85.9.65.242
+85.9.71.126
+85.9.71.233
+85.9.79.217
+85.9.85.111
+85.9.85.113
+85.9.86.54
+85.9.86.239
+85.9.86.254
+85.9.86.255
+85.9.87.53
+85.9.87.54
+85.9.87.62
+85.9.87.102
+85.9.87.121
+85.9.91.25
+85.9.91.211
+85.9.92.36
+85.9.94.166
+85.9.94.182
+85.9.94.208
+85.9.94.238
+85.9.95.234
+85.9.97.10
+85.9.97.179
+85.9.97.209
+85.9.105.36
+85.9.105.39
+85.9.105.40
+85.9.105.42
+85.9.105.43
+85.9.105.44
+85.9.105.45
+85.9.105.202
+85.9.105.204
+85.9.105.205
+85.9.107.178
+85.9.107.179
+85.9.107.180
+85.9.107.187
+85.9.107.226
+85.9.108.169
+85.9.109.55
+85.9.111.9
+85.9.111.11
+85.9.111.12
+85.9.111.15
+85.9.111.17
+85.9.111.18
+85.9.111.22
+85.9.111.124
+85.9.113.235
+85.9.113.237
+85.9.113.238
+85.9.113.239
+85.9.113.240
+85.9.113.242
+85.9.113.244
+85.9.114.84
+85.9.119.237
+85.9.119.255
+85.9.121.33
+85.9.123.72
+85.9.123.252
+85.9.124.89
+85.9.124.111
+85.9.124.233
+85.9.124.245
+85.9.125.68
+85.15.1.115
+85.15.1.120
+85.15.1.188
+85.15.3.5
+85.15.45.187
+85.15.47.176
+85.15.47.236
+85.133.130.99
+85.133.130.114
+85.133.130.132
+85.133.133.102
+85.133.133.104
+85.133.133.109
+85.133.133.111
+85.133.133.138
+85.133.133.148
+85.133.133.161
+85.133.133.162
+85.133.133.165
+85.133.133.173
+85.133.133.192
+85.133.133.199
+85.133.133.201
+85.133.133.214
+85.133.133.225
+85.133.133.235
+85.133.133.239
+85.133.134.5
+85.133.134.28
+85.133.134.30
+85.133.134.40
+85.133.134.53
+85.133.134.63
+85.133.134.71
+85.133.134.72
+85.133.134.78
+85.133.134.87
+85.133.134.112
+85.133.134.118
+85.133.134.122
+85.133.134.129
+85.133.134.138
+85.133.134.142
+85.133.134.152
+85.133.134.173
+85.133.134.175
+85.133.134.184
+85.133.134.186
+85.133.134.189
+85.133.134.195
+85.133.134.204
+85.133.134.211
+85.133.134.242
+85.133.135.146
+85.133.135.190
+85.133.136.242
+85.133.137.190
+85.133.138.10
+85.133.138.53
+85.133.138.99
+85.133.138.101
+85.133.138.130
+85.133.138.154
+85.133.138.168
+85.133.138.178
+85.133.138.187
+85.133.138.188
+85.133.138.209
+85.133.139.34
+85.133.139.45
+85.133.139.79
+85.133.139.81
+85.133.139.83
+85.133.139.88
+85.133.139.104
+85.133.139.114
+85.133.139.120
+85.133.139.121
+85.133.139.130
+85.133.139.132
+85.133.139.183
+85.133.139.187
+85.133.139.198
+85.133.139.199
+85.133.139.207
+85.133.139.210
+85.133.139.215
+85.133.139.219
+85.133.139.237
+85.133.139.240
+85.133.145.37
+85.133.145.159
+85.133.149.42
+85.133.152.3
+85.133.152.25
+85.133.152.27
+85.133.152.34
+85.133.152.49
+85.133.152.57
+85.133.152.80
+85.133.152.87
+85.133.152.90
+85.133.152.103
+85.133.152.123
+85.133.152.136
+85.133.152.137
+85.133.152.146
+85.133.152.152
+85.133.152.155
+85.133.152.172
+85.133.152.184
+85.133.152.185
+85.133.152.198
+85.133.152.217
+85.133.152.221
+85.133.152.222
+85.133.152.227
+85.133.152.232
+85.133.152.236
+85.133.152.238
+85.133.152.244
+85.133.152.252
+85.133.153.171
+85.133.154.130
+85.133.154.154
+85.133.154.155
+85.133.154.190
+85.133.155.130
+85.133.155.131
+85.133.155.132
+85.133.155.133
+85.133.155.134
+85.133.155.162
+85.133.156.179
+85.133.157.4
+85.133.157.26
+85.133.157.47
+85.133.157.72
+85.133.157.79
+85.133.157.86
+85.133.157.90
+85.133.157.93
+85.133.157.103
+85.133.157.106
+85.133.157.112
+85.133.157.113
+85.133.157.128
+85.133.157.129
+85.133.157.152
+85.133.157.153
+85.133.157.157
+85.133.157.174
+85.133.157.175
+85.133.157.180
+85.133.157.197
+85.133.157.217
+85.133.157.240
+85.133.158.122
+85.133.158.195
+85.133.158.196
+85.133.158.198
+85.133.158.201
+85.133.160.180
+85.133.160.226
+85.133.161.24
+85.133.161.56
+85.133.161.87
+85.133.161.202
+85.133.162.16
+85.133.162.17
+85.133.162.19
+85.133.162.44
+85.133.162.95
+85.133.162.140
+85.133.162.151
+85.133.162.172
+85.133.162.182
+85.133.163.2
+85.133.163.31
+85.133.163.85
+85.133.163.94
+85.133.163.114
+85.133.163.158
+85.133.167.62
+85.133.167.107
+85.133.167.108
+85.133.167.246
+85.133.168.130
+85.133.168.202
+85.133.171.34
+85.133.171.35
+85.133.171.36
+85.133.171.37
+85.133.171.38
+85.133.171.178
+85.133.172.3
+85.133.172.68
+85.133.172.84
+85.133.172.102
+85.133.172.118
+85.133.172.129
+85.133.172.144
+85.133.172.158
+85.133.172.162
+85.133.172.164
+85.133.172.172
+85.133.172.180
+85.133.172.206
+85.133.172.211
+85.133.172.213
+85.133.172.217
+85.133.172.218
+85.133.172.228
+85.133.172.244
+85.133.173.66
+85.133.173.90
+85.133.173.98
+85.133.175.18
+85.133.175.110
+85.133.175.199
+85.133.176.13
+85.133.176.127
+85.133.178.30
+85.133.179.46
+85.133.179.189
+85.133.180.170
+85.133.181.26
+85.133.181.102
+85.133.181.118
+85.133.181.190
+85.133.182.12
+85.133.182.17
+85.133.182.23
+85.133.182.27
+85.133.182.36
+85.133.182.40
+85.133.182.42
+85.133.182.52
+85.133.182.75
+85.133.182.86
+85.133.182.88
+85.133.182.98
+85.133.182.106
+85.133.182.110
+85.133.182.116
+85.133.182.121
+85.133.182.125
+85.133.182.134
+85.133.182.141
+85.133.182.158
+85.133.182.193
+85.133.182.205
+85.133.182.217
+85.133.182.222
+85.133.182.236
+85.133.182.240
+85.133.182.241
+85.133.182.246
+85.133.183.62
+85.133.183.106
+85.133.183.110
+85.133.183.182
+85.133.183.186
+85.133.184.51
+85.133.184.158
+85.133.185.26
+85.133.185.102
+85.133.185.106
+85.133.185.110
+85.133.185.130
+85.133.185.150
+85.133.186.26
+85.133.186.149
+85.133.186.178
+85.133.186.179
+85.133.186.180
+85.133.186.181
+85.133.186.182
+85.133.186.190
+85.133.187.59
+85.133.187.178
+85.133.188.218
+85.133.189.147
+85.133.189.222
+85.133.190.40
+85.133.190.171
+85.133.190.172
+85.133.190.173
+85.133.190.174
+85.133.191.198
+85.133.193.36
+85.133.193.41
+85.133.193.54
+85.133.193.72
+85.133.193.74
+85.133.193.114
+85.133.193.136
+85.133.197.203
+85.133.202.86
+85.133.205.212
+85.133.212.234
+85.133.212.251
+85.133.216.14
+85.133.216.41
+85.133.217.68
+85.133.225.160
+85.133.225.162
+85.133.225.172
+85.133.225.187
+85.133.229.115
+85.133.229.120
+85.133.229.129
+85.133.229.210
+85.133.237.26
+85.133.237.93
+85.133.240.33
+85.133.240.35
+85.133.240.38
+85.133.240.41
+85.133.240.44
+85.133.240.48
+85.133.240.59
+85.133.240.60
+85.133.240.61
+85.133.240.62
+85.133.240.151
+85.133.240.155
+85.133.240.156
+85.133.240.157
+85.133.240.159
+85.133.240.161
+85.133.240.165
+85.133.240.166
+85.133.240.167
+85.133.240.171
+85.133.240.173
+85.133.240.174
+85.133.240.175
+85.133.240.176
+85.133.240.178
+85.133.240.179
+85.133.240.180
+85.133.240.181
+85.133.240.183
+85.133.240.184
+85.133.240.185
+85.133.240.186
+85.133.240.188
+85.133.240.189
+85.133.240.197
+85.133.240.199
+85.133.240.203
+85.133.240.204
+85.133.240.205
+85.133.240.206
+85.133.240.207
+85.133.240.208
+85.133.240.210
+85.133.240.212
+85.133.241.116
+85.133.241.138
+85.133.241.188
+85.133.253.101
+85.133.253.118
+85.133.253.119
+85.133.254.71
+85.185.4.19
+85.185.4.20
+85.185.4.62
+85.185.4.146
+85.185.4.218
+85.185.4.219
+85.185.6.1
+85.185.6.2
+85.185.6.3
+85.185.6.4
+85.185.6.5
+85.185.6.6
+85.185.6.8
+85.185.6.9
+85.185.6.10
+85.185.6.11
+85.185.6.12
+85.185.6.13
+85.185.6.209
+85.185.8.75
+85.185.13.35
+85.185.13.41
+85.185.13.161
+85.185.14.41
+85.185.17.124
+85.185.20.185
+85.185.20.226
+85.185.21.78
+85.185.22.114
+85.185.28.141
+85.185.29.6
+85.185.29.30
+85.185.29.90
+85.185.29.178
+85.185.41.85
+85.185.41.87
+85.185.41.104
+85.185.41.123
+85.185.42.106
+85.185.52.176
+85.185.54.229
+85.185.55.245
+85.185.55.252
+85.185.56.80
+85.185.57.27
+85.185.58.20
+85.185.60.200
+85.185.62.57
+85.185.62.72
+85.185.62.196
+85.185.64.8
+85.185.64.61
+85.185.64.89
+85.185.64.90
+85.185.64.91
+85.185.64.92
+85.185.64.93
+85.185.64.205
+85.185.64.219
+85.185.66.81
+85.185.66.179
+85.185.66.193
+85.185.66.216
+85.185.66.225
+85.185.67.38
+85.185.67.43
+85.185.67.165
+85.185.67.177
+85.185.67.178
+85.185.75.11
+85.185.75.38
+85.185.75.187
+85.185.75.210
+85.185.75.211
+85.185.75.212
+85.185.76.130
+85.185.76.131
+85.185.76.132
+85.185.76.133
+85.185.76.134
+85.185.76.138
+85.185.76.142
+85.185.76.194
+85.185.81.82
+85.185.81.99
+85.185.84.194
+85.185.84.226
+85.185.86.211
+85.185.88.133
+85.185.88.137
+85.185.88.139
+85.185.93.114
+85.185.95.185
+85.185.104.17
+85.185.105.101
+85.185.105.104
+85.185.105.217
+85.185.106.20
+85.185.110.226
+85.185.110.252
+85.185.123.6
+85.185.128.1
+85.185.130.136
+85.185.138.2
+85.185.138.5
+85.185.138.6
+85.185.138.18
+85.185.138.28
+85.185.138.29
+85.185.138.30
+85.185.138.58
+85.185.138.122
+85.185.138.154
+85.185.138.158
+85.185.138.178
+85.185.138.182
+85.185.138.186
+85.185.138.218
+85.185.138.226
+85.185.139.46
+85.185.140.67
+85.185.149.18
+85.185.149.24
+85.185.149.30
+85.185.158.146
+85.185.159.74
+85.185.159.76
+85.185.159.77
+85.185.161.214
+85.185.161.227
+85.185.161.240
+85.185.164.111
+85.185.165.124
+85.185.165.125
+85.185.165.126
+85.185.165.127
+85.185.166.138
+85.185.169.42
+85.185.170.2
+85.185.185.10
+85.185.190.141
+85.185.198.135
+85.185.201.16
+85.185.201.19
+85.185.202.98
+85.185.202.178
+85.185.202.242
+85.185.206.193
+85.185.206.222
+85.185.207.178
+85.185.216.106
+85.185.218.11
+85.185.218.15
+85.185.218.102
+85.185.218.127
+85.185.222.240
+85.185.229.9
+85.185.229.84
+85.185.229.90
+85.185.229.163
+85.185.232.42
+85.185.235.43
+85.185.235.59
+85.185.235.188
+85.185.235.190
+85.185.235.235
+85.185.236.131
+85.185.236.154
+85.185.237.58
+85.185.237.82
+85.185.237.83
+85.185.237.84
+85.185.237.85
+85.185.239.26
+85.185.239.178
+85.185.239.179
+85.185.239.180
+85.185.239.181
+85.185.239.182
+85.185.239.202
+85.185.241.106
+85.185.241.107
+85.185.241.170
+85.185.241.171
+85.185.241.172
+85.185.241.173
+85.185.241.236
+85.185.244.115
+85.185.244.178
+85.185.244.194
+85.185.244.242
+85.185.246.18
+85.185.246.218
+85.185.247.68
+85.185.247.138
+85.185.249.66
+85.185.249.67
+85.185.251.1
+85.185.251.57
+85.185.251.89
+85.185.251.177
+85.185.251.178
+85.185.251.193
+85.185.251.218
+85.185.252.10
+85.185.253.160
+85.185.254.15
+85.185.255.8
+85.185.255.20
+85.185.255.36
+85.185.255.133
+85.198.0.113
+85.198.2.5
+85.198.24.54
+85.198.24.166
+85.198.25.50
+85.198.25.66
+85.198.25.93
+85.198.25.98
+85.198.25.99
+85.198.25.100
+85.198.25.101
+85.198.25.102
+85.198.25.146
+85.198.25.147
+85.198.25.234
+85.198.26.82
+85.198.26.177
+85.198.26.250
+85.198.27.86
+85.198.28.10
+85.198.28.27
+85.198.28.38
+85.198.28.112
+85.198.28.123
+85.198.28.125
+85.198.28.197
+85.198.28.198
+85.198.29.33
+85.198.29.55
+85.198.29.56
+85.198.29.127
+85.198.29.161
+85.198.30.3
+85.198.30.4
+85.198.30.15
+85.198.30.31
+85.198.30.52
+85.198.30.60
+85.198.30.70
+85.198.30.84
+85.198.30.123
+85.198.30.213
+85.198.30.224
+85.198.30.244
+85.198.30.254
+85.198.31.18
+85.198.31.35
+85.198.31.40
+85.198.31.146
+85.198.31.169
+85.198.31.183
+85.198.31.192
+85.198.31.232
+85.204.30.148
+85.204.30.192
+85.204.76.71
+85.204.76.222
+85.204.77.105
+85.204.77.153
+85.204.77.217
+85.204.80.224
+85.204.83.87
+85.204.83.145
+85.204.84.122
+85.204.85.173
+85.204.87.34
+85.204.87.94
+85.204.88.117
+85.204.88.234
+85.204.90.40
+85.204.91.128
+85.204.91.149
+85.204.92.246
+85.204.93.198
+85.204.104.181
+85.204.104.218
+85.204.104.238
+85.204.105.43
+85.204.105.122
+85.204.105.169
+85.204.105.215
+85.204.105.253
+85.204.128.134
+85.204.128.252
+85.204.129.59
+85.204.130.34
+85.204.211.136
+85.204.211.220
+85.204.213.50
+85.204.213.86
+85.204.213.169
+85.204.215.106
+85.204.215.153
+85.204.217.165
+85.204.218.216
+85.204.219.79
+85.204.219.135
+85.204.220.90
+85.204.223.114
+85.208.253.12
+85.208.253.25
+85.208.253.43
+85.208.253.62
+85.208.253.119
+85.208.253.144
+85.208.253.152
+85.208.253.232
+85.208.253.243
+85.208.254.61
+85.208.254.63
+85.208.254.152
+85.208.254.209
+85.208.254.213
+86.104.32.106
+86.104.81.59
+86.104.96.213
+86.104.96.253
+86.104.104.116
+86.104.104.176
+86.104.107.7
+86.104.110.81
+86.104.243.225
+86.104.244.130
+86.104.244.136
+86.104.244.176
+86.104.244.225
+86.104.244.241
+86.105.44.36
+86.105.47.48
+86.105.47.82
+86.105.47.235
+86.106.142.1
+86.106.142.44
+86.106.142.117
+86.107.1.133
+86.107.8.2
+86.107.8.18
+86.107.8.75
+86.107.14.14
+86.107.14.21
+86.107.14.45
+86.107.14.48
+86.107.14.54
+86.107.14.62
+86.107.14.69
+86.107.14.77
+86.107.14.87
+86.107.14.102
+86.107.14.103
+86.107.14.122
+86.107.14.152
+86.107.14.156
+86.107.14.160
+86.107.14.165
+86.107.14.170
+86.107.14.181
+86.107.14.189
+86.107.14.191
+86.107.14.204
+86.107.14.219
+86.107.14.234
+86.107.14.236
+86.107.14.243
+86.107.14.244
+86.107.14.251
+86.107.15.4
+86.107.15.14
+86.107.15.16
+86.107.15.22
+86.107.15.32
+86.107.15.35
+86.107.15.56
+86.107.15.62
+86.107.15.90
+86.107.15.91
+86.107.15.123
+86.107.15.127
+86.107.15.198
+86.107.15.201
+86.107.15.212
+86.107.15.215
+86.107.15.221
+86.107.15.228
+86.107.15.236
+86.107.15.249
+86.107.15.254
+86.107.144.227
+86.107.146.168
+86.107.147.238
+86.107.150.6
+86.107.150.35
+86.107.151.171
+86.107.151.172
+86.107.152.190
+86.107.152.194
+86.107.152.248
+86.107.153.163
+86.107.153.179
+86.107.157.155
+86.107.157.232
+86.107.158.161
+86.107.158.181
+86.107.159.246
+86.109.45.154
+86.109.45.186
+86.109.45.187
+86.109.45.188
+86.109.54.134
+87.107.6.17
+87.107.6.23
+87.107.6.36
+87.107.6.59
+87.107.6.60
+87.107.6.84
+87.107.6.97
+87.107.6.202
+87.107.8.85
+87.107.8.87
+87.107.8.88
+87.107.8.89
+87.107.8.166
+87.107.9.170
+87.107.9.171
+87.107.9.173
+87.107.10.74
+87.107.10.241
+87.107.11.91
+87.107.11.93
+87.107.12.221
+87.107.16.30
+87.107.16.214
+87.107.16.222
+87.107.17.222
+87.107.18.2
+87.107.18.14
+87.107.18.22
+87.107.18.66
+87.107.18.82
+87.107.19.14
+87.107.19.68
+87.107.19.104
+87.107.19.196
+87.107.19.198
+87.107.28.90
+87.107.29.158
+87.107.30.6
+87.107.30.86
+87.107.30.166
+87.107.38.230
+87.107.44.2
+87.107.48.7
+87.107.48.26
+87.107.48.63
+87.107.48.66
+87.107.48.81
+87.107.48.124
+87.107.48.144
+87.107.48.159
+87.107.48.173
+87.107.48.184
+87.107.48.229
+87.107.48.233
+87.107.49.19
+87.107.49.88
+87.107.49.106
+87.107.49.163
+87.107.49.173
+87.107.49.195
+87.107.49.220
+87.107.52.99
+87.107.52.235
+87.107.54.69
+87.107.54.228
+87.107.54.233
+87.107.55.56
+87.107.55.134
+87.107.55.203
+87.107.68.38
+87.107.68.43
+87.107.68.49
+87.107.68.87
+87.107.73.116
+87.107.74.34
+87.107.74.36
+87.107.74.37
+87.107.75.32
+87.107.77.18
+87.107.77.94
+87.107.78.18
+87.107.78.130
+87.107.78.178
+87.107.78.242
+87.107.78.246
+87.107.79.62
+87.107.79.152
+87.107.82.201
+87.107.82.213
+87.107.83.18
+87.107.83.64
+87.107.83.77
+87.107.83.120
+87.107.83.238
+87.107.83.240
+87.107.87.5
+87.107.87.118
+87.107.94.3
+87.107.95.138
+87.107.100.160
+87.107.101.13
+87.107.101.26
+87.107.101.61
+87.107.101.63
+87.107.101.70
+87.107.101.72
+87.107.101.88
+87.107.101.97
+87.107.101.99
+87.107.101.100
+87.107.101.101
+87.107.101.251
+87.107.102.195
+87.107.102.227
+87.107.103.226
+87.107.103.250
+87.107.104.8
+87.107.104.177
+87.107.104.214
+87.107.105.27
+87.107.105.31
+87.107.108.185
+87.107.108.208
+87.107.108.221
+87.107.109.107
+87.107.110.10
+87.107.110.22
+87.107.110.138
+87.107.111.178
+87.107.111.180
+87.107.111.181
+87.107.111.182
+87.107.111.202
+87.107.111.203
+87.107.111.204
+87.107.111.206
+87.107.121.85
+87.107.124.117
+87.107.124.124
+87.107.132.35
+87.107.135.242
+87.107.136.42
+87.107.137.50
+87.107.137.82
+87.107.137.250
+87.107.137.251
+87.107.138.50
+87.107.138.52
+87.107.138.53
+87.107.138.58
+87.107.138.70
+87.107.138.151
+87.107.138.226
+87.107.139.218
+87.107.139.220
+87.107.139.222
+87.107.139.254
+87.107.141.1
+87.107.141.37
+87.107.141.79
+87.107.141.95
+87.107.141.105
+87.107.141.113
+87.107.142.18
+87.107.143.4
+87.107.143.12
+87.107.143.15
+87.107.143.19
+87.107.143.21
+87.107.143.29
+87.107.143.130
+87.107.143.131
+87.107.143.132
+87.107.143.133
+87.107.143.134
+87.107.143.135
+87.107.143.136
+87.107.143.137
+87.107.143.138
+87.107.143.139
+87.107.143.140
+87.107.143.141
+87.107.143.142
+87.107.144.54
+87.107.144.62
+87.107.144.217
+87.107.146.29
+87.107.146.39
+87.107.146.141
+87.107.146.243
+87.107.152.35
+87.107.152.211
+87.107.152.212
+87.107.152.214
+87.107.152.246
+87.107.153.116
+87.107.154.27
+87.107.154.69
+87.107.154.174
+87.107.155.82
+87.107.155.238
+87.107.164.15
+87.107.164.28
+87.107.164.29
+87.107.164.65
+87.107.164.179
+87.107.164.215
+87.107.165.65
+87.107.165.135
+87.107.166.6
+87.107.166.122
+87.107.166.150
+87.107.167.67
+87.107.167.92
+87.107.167.182
+87.107.167.183
+87.107.167.185
+87.107.167.186
+87.107.174.43
+87.107.174.114
+87.107.174.134
+87.107.174.139
+87.107.184.98
+87.107.185.204
+87.107.185.216
+87.236.38.233
+87.236.39.134
+87.236.166.3
+87.236.209.21
+87.236.209.173
+87.236.209.229
+87.236.210.54
+87.236.210.126
+87.236.211.5
+87.236.211.11
+87.236.211.70
+87.236.211.75
+87.236.211.119
+87.236.211.220
+87.236.211.222
+87.236.212.82
+87.236.212.132
+87.236.212.146
+87.236.212.178
+87.236.213.20
+87.236.213.33
+87.236.213.97
+87.236.213.129
+87.236.213.161
+87.236.213.249
+87.236.214.20
+87.236.214.47
+87.236.214.129
+87.236.214.225
+87.236.214.249
+87.236.215.169
+87.236.215.170
+87.236.215.227
+87.247.168.101
+87.247.168.190
+87.247.170.156
+87.247.171.4
+87.247.171.74
+87.247.174.146
+87.247.174.214
+87.247.176.68
+87.247.176.242
+87.247.176.252
+87.247.176.254
+87.248.130.28
+87.248.130.42
+87.248.130.91
+87.248.130.133
+87.248.130.186
+87.248.131.23
+87.248.131.45
+87.248.131.67
+87.248.131.125
+87.248.131.164
+87.248.131.207
+87.248.137.243
+87.248.138.33
+87.248.138.162
+87.248.138.163
+87.248.138.164
+87.248.138.165
+87.248.138.166
+87.248.139.186
+87.248.139.236
+87.248.139.237
+87.248.140.6
+87.248.140.65
+87.248.140.123
+87.248.140.171
+87.248.140.195
+87.248.140.197
+87.248.141.133
+87.248.141.142
+87.248.141.144
+87.248.141.152
+87.248.141.196
+87.248.141.211
+87.248.145.145
+87.248.147.154
+87.248.147.155
+87.248.150.118
+87.248.151.5
+87.248.151.38
+87.248.151.59
+87.248.151.117
+87.248.151.124
+87.248.152.44
+87.248.152.189
+87.248.153.230
+87.248.154.31
+87.248.154.89
+87.248.154.103
+87.248.154.113
+87.248.154.129
+87.248.154.194
+87.248.154.207
+87.248.155.14
+87.248.155.79
+87.248.155.81
+87.248.155.245
+87.248.156.62
+87.248.156.134
+87.248.156.195
+88.135.38.143
+88.135.38.146
+88.135.38.147
+88.135.38.148
+88.135.38.149
+88.135.38.150
+88.135.38.151
+88.135.39.29
+88.135.68.2
+88.135.68.15
+88.135.68.96
+88.135.75.148
+88.135.75.201
+88.218.16.58
+88.218.16.123
+88.218.16.124
+89.32.197.12
+89.32.197.30
+89.32.197.51
+89.32.197.52
+89.32.197.87
+89.32.197.111
+89.32.197.182
+89.32.197.214
+89.32.248.1
+89.32.248.36
+89.32.248.65
+89.32.248.73
+89.32.248.81
+89.32.248.129
+89.32.248.130
+89.32.248.134
+89.32.248.137
+89.32.248.145
+89.32.248.161
+89.32.248.162
+89.32.248.163
+89.32.248.194
+89.32.248.201
+89.32.248.203
+89.32.248.209
+89.32.248.225
+89.32.249.1
+89.32.249.65
+89.32.249.97
+89.32.249.129
+89.32.249.145
+89.32.249.153
+89.32.249.161
+89.32.249.193
+89.32.250.1
+89.32.250.6
+89.32.250.33
+89.32.250.39
+89.32.250.65
+89.32.250.77
+89.32.250.129
+89.32.250.161
+89.32.250.177
+89.32.250.193
+89.32.250.223
+89.32.251.1
+89.32.251.17
+89.32.251.33
+89.32.251.41
+89.32.251.65
+89.32.251.95
+89.32.251.107
+89.32.251.129
+89.32.251.161
+89.33.18.10
+89.33.18.18
+89.33.18.20
+89.33.18.21
+89.33.18.29
+89.33.18.42
+89.33.18.50
+89.33.18.52
+89.33.18.54
+89.33.18.55
+89.33.18.61
+89.33.18.68
+89.33.18.70
+89.33.18.84
+89.33.18.93
+89.33.18.99
+89.33.18.101
+89.33.18.104
+89.33.18.106
+89.33.18.111
+89.33.18.114
+89.33.18.142
+89.33.18.145
+89.33.18.150
+89.33.18.153
+89.33.18.157
+89.33.18.160
+89.33.18.168
+89.33.18.174
+89.33.18.186
+89.33.18.189
+89.33.18.190
+89.33.18.191
+89.33.18.192
+89.33.18.193
+89.33.18.206
+89.33.18.212
+89.33.18.225
+89.33.18.231
+89.33.18.235
+89.33.18.242
+89.33.18.246
+89.33.18.249
+89.33.18.251
+89.33.19.13
+89.33.19.14
+89.33.19.30
+89.33.19.31
+89.33.19.45
+89.33.19.49
+89.33.19.50
+89.33.19.51
+89.33.19.62
+89.33.19.65
+89.33.19.67
+89.33.19.68
+89.33.19.73
+89.33.19.94
+89.33.19.99
+89.33.19.107
+89.33.19.112
+89.33.19.117
+89.33.19.118
+89.33.19.119
+89.33.19.125
+89.33.19.126
+89.33.19.130
+89.33.19.141
+89.33.19.152
+89.33.19.156
+89.33.19.165
+89.33.19.169
+89.33.19.170
+89.33.19.173
+89.33.19.176
+89.33.19.179
+89.33.19.182
+89.33.19.190
+89.33.19.197
+89.33.19.200
+89.33.19.207
+89.33.19.209
+89.33.19.216
+89.33.19.218
+89.33.19.220
+89.33.19.227
+89.33.19.229
+89.33.19.231
+89.33.19.235
+89.33.19.236
+89.33.19.239
+89.33.19.240
+89.33.19.244
+89.33.19.246
+89.33.19.251
+89.33.129.167
+89.33.129.170
+89.33.205.167
+89.33.234.12
+89.33.240.41
+89.34.21.101
+89.34.96.30
+89.34.96.77
+89.34.96.86
+89.34.96.87
+89.34.96.88
+89.34.96.89
+89.34.96.90
+89.34.96.91
+89.34.96.92
+89.34.96.93
+89.34.96.94
+89.34.96.95
+89.34.96.100
+89.34.96.101
+89.34.96.102
+89.34.96.103
+89.34.96.104
+89.34.96.105
+89.34.96.106
+89.34.96.117
+89.34.96.146
+89.34.97.70
+89.34.169.18
+89.34.169.108
+89.34.169.116
+89.34.169.222
+89.34.176.58
+89.34.176.66
+89.34.176.105
+89.34.176.185
+89.34.177.113
+89.34.200.91
+89.34.200.94
+89.34.200.117
+89.34.201.120
+89.34.254.147
+89.35.58.51
+89.35.132.69
+89.35.132.78
+89.35.132.122
+89.35.133.153
+89.35.133.210
+89.35.133.223
+89.35.133.237
+89.36.226.24
+89.36.226.29
+89.37.1.10
+89.37.1.58
+89.37.1.59
+89.37.1.60
+89.37.1.61
+89.37.1.62
+89.37.1.115
+89.37.3.182
+89.37.4.54
+89.37.9.118
+89.37.11.210
+89.37.12.84
+89.37.13.250
+89.37.15.11
+89.37.15.12
+89.37.15.34
+89.37.15.90
+89.37.15.91
+89.37.15.92
+89.37.103.14
+89.37.103.30
+89.37.103.65
+89.37.103.81
+89.37.103.103
+89.37.146.97
+89.37.147.29
+89.37.148.152
+89.37.148.159
+89.37.148.182
+89.37.153.246
+89.37.155.233
+89.37.198.147
+89.37.199.125
+89.37.199.209
+89.37.219.29
+89.37.219.30
+89.37.219.51
+89.37.219.220
+89.37.241.17
+89.37.242.36
+89.37.242.162
+89.37.245.11
+89.37.245.55
+89.37.246.36
+89.37.247.74
+89.37.248.10
+89.37.248.120
+89.37.249.127
+89.37.250.29
+89.37.250.157
+89.37.251.210
+89.37.252.31
+89.37.253.74
+89.37.253.85
+89.37.253.125
+89.37.253.130
+89.37.253.240
+89.37.254.33
+89.37.254.83
+89.37.255.217
+89.38.81.43
+89.38.81.101
+89.38.82.199
+89.38.83.102
+89.38.84.75
+89.38.84.110
+89.38.85.197
+89.38.86.67
+89.38.87.69
+89.38.87.96
+89.38.87.192
+89.38.88.198
+89.38.89.20
+89.38.89.32
+89.38.89.171
+89.38.90.62
+89.38.90.169
+89.38.91.21
+89.38.92.26
+89.38.92.163
+89.38.93.89
+89.38.93.111
+89.38.94.189
+89.38.94.214
+89.38.95.197
+89.38.102.107
+89.38.102.227
+89.38.102.251
+89.38.103.22
+89.38.103.58
+89.38.103.81
+89.38.103.139
+89.38.103.166
+89.38.103.219
+89.38.246.58
+89.39.208.9
+89.39.208.17
+89.39.208.21
+89.39.208.25
+89.39.208.33
+89.39.208.39
+89.39.208.73
+89.39.208.77
+89.39.208.81
+89.39.208.97
+89.39.208.105
+89.39.208.113
+89.39.208.126
+89.39.208.129
+89.39.208.133
+89.39.208.145
+89.39.208.171
+89.39.208.177
+89.39.208.182
+89.40.78.162
+89.40.78.189
+89.40.78.208
+89.40.78.219
+89.40.79.27
+89.40.79.53
+89.40.79.71
+89.40.79.117
+89.40.79.123
+89.40.79.185
+89.40.79.211
+89.40.79.226
+89.40.106.17
+89.40.106.139
+89.40.107.24
+89.40.107.223
+89.40.107.244
+89.40.159.148
+89.40.246.2
+89.40.246.135
+89.40.246.212
+89.40.247.10
+89.40.247.138
+89.40.247.154
+89.41.40.56
+89.41.40.106
+89.41.40.171
+89.41.41.83
+89.41.42.52
+89.41.42.193
+89.41.42.230
+89.41.42.234
+89.41.43.48
+89.41.43.64
+89.41.43.135
+89.41.43.163
+89.42.44.211
+89.42.96.21
+89.42.96.80
+89.42.96.167
+89.42.97.57
+89.42.100.11
+89.42.100.28
+89.42.100.50
+89.42.100.56
+89.42.101.45
+89.42.101.182
+89.42.102.130
+89.42.102.184
+89.42.103.21
+89.42.103.160
+89.42.103.237
+89.42.136.30
+89.42.136.114
+89.42.136.115
+89.42.136.116
+89.42.136.218
+89.42.138.122
+89.42.139.89
+89.42.150.51
+89.42.151.230
+89.42.197.6
+89.42.197.17
+89.42.197.18
+89.42.197.21
+89.42.197.25
+89.42.197.78
+89.42.198.4
+89.42.198.12
+89.42.198.21
+89.42.198.30
+89.42.198.31
+89.42.198.43
+89.42.198.57
+89.42.198.73
+89.42.198.86
+89.42.198.110
+89.42.198.116
+89.42.198.131
+89.42.198.180
+89.42.198.216
+89.42.199.59
+89.42.199.212
+89.42.208.1
+89.42.208.65
+89.42.208.97
+89.42.208.112
+89.42.208.129
+89.42.208.145
+89.42.208.153
+89.42.208.161
+89.42.208.177
+89.42.208.193
+89.42.208.209
+89.42.208.211
+89.42.208.217
+89.42.208.225
+89.42.208.233
+89.42.208.241
+89.42.209.18
+89.42.209.32
+89.42.209.55
+89.42.209.65
+89.42.209.85
+89.42.209.90
+89.42.209.97
+89.42.209.129
+89.42.209.145
+89.42.209.149
+89.42.209.161
+89.42.209.177
+89.42.209.185
+89.42.209.193
+89.42.209.201
+89.42.209.225
+89.42.209.233
+89.42.209.249
+89.42.209.253
+89.42.210.1
+89.42.210.18
+89.42.210.56
+89.42.210.59
+89.42.210.129
+89.42.210.161
+89.42.210.193
+89.42.210.209
+89.42.210.233
+89.42.210.241
+89.42.210.242
+89.42.210.249
+89.42.211.1
+89.42.211.17
+89.42.211.33
+89.42.211.97
+89.42.211.113
+89.42.211.129
+89.42.211.161
+89.42.211.193
+89.42.211.225
+89.42.211.233
+89.43.2.90
+89.43.3.78
+89.43.3.224
+89.43.7.205
+89.43.11.226
+89.43.13.7
+89.43.36.175
+89.43.144.185
+89.43.216.15
+89.43.217.102
+89.43.222.45
+89.43.222.109
+89.43.223.216
+89.43.226.5
+89.43.227.38
+89.43.227.44
+89.43.229.90
+89.43.230.171
+89.43.230.207
+89.43.231.200
+89.44.112.4
+89.44.112.6
+89.44.112.7
+89.44.112.8
+89.44.112.9
+89.44.118.4
+89.44.118.20
+89.44.118.21
+89.44.129.129
+89.44.129.255
+89.44.130.118
+89.44.132.3
+89.44.134.62
+89.44.176.34
+89.44.176.246
+89.44.177.25
+89.44.177.66
+89.44.179.14
+89.44.179.172
+89.44.179.254
+89.44.180.39
+89.44.183.233
+89.44.240.59
+89.44.240.200
+89.44.240.220
+89.45.56.19
+89.45.56.25
+89.45.56.35
+89.45.56.52
+89.45.56.74
+89.45.56.78
+89.45.56.82
+89.45.56.86
+89.45.56.111
+89.45.56.113
+89.45.56.122
+89.45.56.125
+89.45.56.140
+89.45.56.179
+89.45.56.186
+89.45.89.1
+89.45.89.90
+89.45.89.248
+89.45.89.249
+89.45.89.251
+89.45.89.252
+89.45.89.253
+89.45.89.254
+89.45.115.201
+89.46.60.49
+89.46.61.219
+89.46.94.24
+89.46.94.71
+89.46.94.197
+89.46.94.202
+89.46.94.231
+89.46.95.220
+89.46.95.222
+89.46.216.5
+89.46.216.13
+89.46.216.14
+89.46.216.41
+89.46.216.208
+89.46.218.17
+89.46.218.41
+89.46.218.145
+89.46.219.1
+89.46.219.4
+89.46.219.33
+89.46.219.34
+89.46.219.36
+89.46.219.37
+89.46.219.38
+89.46.219.40
+89.46.219.41
+89.46.219.42
+89.46.219.44
+89.46.219.45
+89.46.219.46
+89.47.196.131
+89.47.196.137
+89.47.196.143
+89.47.199.106
+89.47.199.158
+89.47.199.230
+89.47.201.38
+89.47.202.101
+89.144.132.178
+89.144.133.130
+89.144.133.136
+89.144.133.193
+89.144.135.118
+89.144.137.200
+89.144.139.180
+89.144.139.181
+89.144.140.81
+89.144.141.129
+89.144.143.162
+89.144.143.163
+89.144.143.165
+89.144.149.93
+89.144.151.82
+89.144.151.88
+89.144.152.1
+89.144.152.2
+89.144.153.48
+89.144.155.82
+89.144.157.164
+89.144.160.25
+89.144.169.244
+89.144.172.248
+89.144.173.180
+89.144.174.181
+89.144.174.248
+89.144.175.220
+89.144.180.65
+89.144.183.65
+89.144.183.241
+89.144.184.9
+89.144.185.201
+89.144.186.10
+89.144.187.121
+89.144.188.168
+89.144.189.72
+89.165.0.138
+89.165.3.242
+89.165.7.118
+89.165.40.10
+89.165.44.194
+89.165.45.194
+89.165.56.12
+89.165.64.8
+89.219.64.56
+89.219.64.250
+89.219.66.253
+89.219.67.35
+89.219.67.204
+89.219.68.206
+89.219.68.251
+89.219.69.245
+89.219.70.146
+89.219.70.157
+89.219.71.200
+89.219.72.72
+89.219.72.195
+89.219.74.112
+89.219.75.26
+89.219.76.119
+89.219.78.58
+89.219.81.228
+89.219.84.28
+89.219.86.59
+89.219.86.83
+89.219.86.161
+89.219.88.197
+89.219.89.194
+89.219.90.152
+89.219.91.179
+89.219.91.185
+89.219.91.252
+89.219.93.59
+89.219.93.170
+89.219.94.38
+89.219.94.79
+89.219.95.230
+89.219.100.4
+89.219.100.20
+89.219.100.47
+89.219.105.68
+89.219.107.184
+89.219.108.107
+89.219.108.139
+89.219.108.250
+89.219.111.145
+89.219.112.154
+89.219.114.134
+89.219.115.186
+89.219.117.58
+89.219.118.20
+89.219.118.67
+89.219.119.157
+89.219.120.250
+89.219.122.59
+89.219.124.202
+89.219.125.162
+89.219.194.91
+89.219.194.254
+89.219.195.206
+89.219.200.100
+89.219.202.212
+89.219.203.130
+89.219.207.174
+89.219.208.238
+89.219.209.174
+89.219.218.83
+89.219.221.97
+89.219.221.160
+89.219.225.235
+89.219.226.15
+89.219.229.89
+89.219.236.121
+89.219.243.103
+89.219.245.17
+89.219.246.98
+89.219.246.103
+89.219.247.62
+89.219.252.29
+89.219.252.79
+89.219.255.238
+89.221.84.84
+89.221.84.88
+89.221.85.56
+89.221.85.110
+89.221.85.122
+89.221.85.137
+89.221.85.140
+89.221.85.142
+89.221.85.217
+89.221.86.76
+89.221.86.171
+89.221.86.173
+89.221.86.202
+89.221.86.213
+89.235.79.11
+89.235.79.12
+89.235.79.14
+89.235.79.17
+89.235.79.179
+89.235.93.201
+89.235.95.206
+89.235.96.26
+89.235.99.208
+89.235.104.1
+89.235.112.1
+89.235.116.213
+91.92.114.105
+91.92.114.198
+91.92.114.239
+91.92.121.13
+91.92.121.59
+91.92.121.77
+91.92.121.115
+91.92.121.122
+91.92.121.157
+91.92.122.4
+91.92.122.22
+91.92.122.90
+91.92.122.95
+91.92.122.138
+91.92.122.144
+91.92.122.219
+91.92.123.159
+91.92.123.214
+91.92.124.1
+91.92.124.40
+91.92.124.81
+91.92.124.90
+91.92.124.147
+91.92.124.172
+91.92.124.220
+91.92.124.248
+91.92.125.160
+91.92.125.219
+91.92.125.243
+91.92.126.4
+91.92.126.48
+91.92.126.49
+91.92.126.71
+91.92.126.85
+91.92.126.97
+91.92.126.117
+91.92.126.123
+91.92.126.238
+91.92.127.14
+91.92.127.37
+91.92.127.53
+91.92.127.75
+91.92.127.105
+91.92.127.145
+91.92.127.167
+91.92.127.191
+91.92.127.228
+91.92.129.59
+91.92.129.87
+91.92.129.162
+91.92.129.188
+91.92.129.216
+91.92.130.4
+91.92.130.49
+91.92.130.111
+91.92.130.112
+91.92.130.148
+91.92.130.157
+91.92.130.168
+91.92.130.197
+91.92.130.202
+91.92.130.231
+91.92.131.57
+91.92.131.107
+91.92.131.115
+91.92.131.135
+91.92.131.151
+91.92.131.155
+91.92.131.166
+91.92.131.168
+91.92.131.196
+91.92.131.199
+91.92.131.201
+91.92.131.204
+91.92.131.208
+91.92.131.218
+91.92.131.248
+91.92.132.17
+91.92.133.8
+91.92.133.75
+91.92.133.80
+91.92.133.83
+91.92.133.87
+91.92.133.89
+91.92.133.97
+91.92.133.121
+91.92.133.135
+91.92.133.145
+91.92.133.158
+91.92.133.195
+91.92.149.37
+91.92.151.37
+91.92.156.9
+91.92.157.82
+91.92.158.66
+91.92.158.72
+91.92.159.114
+91.92.159.131
+91.92.159.241
+91.92.164.17
+91.92.164.200
+91.92.165.41
+91.92.165.51
+91.92.166.52
+91.92.166.201
+91.92.167.216
+91.92.180.19
+91.92.180.30
+91.92.180.36
+91.92.180.72
+91.92.180.80
+91.92.180.87
+91.92.180.106
+91.92.180.109
+91.92.180.125
+91.92.180.127
+91.92.180.131
+91.92.180.139
+91.92.180.182
+91.92.180.216
+91.92.180.230
+91.92.180.253
+91.92.181.44
+91.92.181.61
+91.92.181.113
+91.92.181.138
+91.92.181.142
+91.92.181.205
+91.92.182.57
+91.92.182.77
+91.92.182.120
+91.92.182.150
+91.92.182.181
+91.92.182.200
+91.92.182.251
+91.92.183.23
+91.92.183.70
+91.92.183.106
+91.92.183.172
+91.92.185.29
+91.92.185.70
+91.92.185.92
+91.92.186.17
+91.92.186.108
+91.92.186.132
+91.92.186.154
+91.92.186.167
+91.92.186.214
+91.92.186.225
+91.92.187.10
+91.92.187.30
+91.92.188.38
+91.92.188.142
+91.92.188.218
+91.92.188.223
+91.92.189.39
+91.92.189.183
+91.92.190.18
+91.92.190.87
+91.92.190.126
+91.92.190.168
+91.92.190.190
+91.92.190.193
+91.92.190.215
+91.92.191.30
+91.92.191.36
+91.92.191.81
+91.92.191.167
+91.92.191.168
+91.92.191.177
+91.92.191.178
+91.92.191.221
+91.92.192.17
+91.92.204.27
+91.92.204.130
+91.92.204.165
+91.92.204.178
+91.92.204.194
+91.92.204.211
+91.92.205.179
+91.92.205.208
+91.92.206.34
+91.92.206.90
+91.92.207.152
+91.92.207.195
+91.92.207.221
+91.92.207.228
+91.92.207.238
+91.92.208.3
+91.92.208.10
+91.92.208.21
+91.92.208.38
+91.92.208.43
+91.92.208.51
+91.92.208.63
+91.92.208.108
+91.92.208.149
+91.92.208.173
+91.92.208.192
+91.92.208.205
+91.92.208.229
+91.92.208.245
+91.92.209.2
+91.92.209.5
+91.92.209.9
+91.92.209.27
+91.92.209.32
+91.92.209.38
+91.92.209.43
+91.92.209.45
+91.92.209.75
+91.92.209.115
+91.92.209.165
+91.92.209.167
+91.92.209.173
+91.92.209.192
+91.92.209.194
+91.92.209.247
+91.92.210.135
+91.92.211.24
+91.92.211.55
+91.92.211.66
+91.92.211.77
+91.92.211.78
+91.92.211.81
+91.92.211.108
+91.92.211.135
+91.92.211.151
+91.92.211.160
+91.92.211.174
+91.92.211.218
+91.92.211.232
+91.92.211.245
+91.92.211.250
+91.92.211.253
+91.92.212.33
+91.92.212.69
+91.92.212.157
+91.92.212.167
+91.92.212.171
+91.92.212.194
+91.92.212.240
+91.92.212.246
+91.92.213.37
+91.92.213.82
+91.92.213.148
+91.92.214.41
+91.92.214.46
+91.92.214.65
+91.92.214.85
+91.92.214.93
+91.92.214.104
+91.92.214.143
+91.92.214.188
+91.92.214.190
+91.92.214.202
+91.92.214.211
+91.92.214.218
+91.92.214.236
+91.92.214.242
+91.92.215.0
+91.92.215.10
+91.92.215.13
+91.92.215.25
+91.92.215.48
+91.92.215.74
+91.92.215.81
+91.92.215.98
+91.92.215.106
+91.92.215.129
+91.92.215.132
+91.92.215.231
+91.92.231.55
+91.92.231.92
+91.92.231.112
+91.92.231.203
+91.106.64.25
+91.106.64.49
+91.106.64.94
+91.106.66.32
+91.106.66.173
+91.106.67.85
+91.106.67.252
+91.106.68.164
+91.106.70.14
+91.106.70.206
+91.106.70.213
+91.106.72.95
+91.106.74.77
+91.106.76.129
+91.106.83.25
+91.106.83.26
+91.106.83.193
+91.106.84.20
+91.106.84.25
+91.106.85.2
+91.106.85.5
+91.106.85.6
+91.106.85.19
+91.106.85.22
+91.106.85.33
+91.106.85.34
+91.106.85.35
+91.106.85.36
+91.106.85.37
+91.106.85.38
+91.106.85.39
+91.106.85.41
+91.106.85.42
+91.106.85.44
+91.106.85.45
+91.106.85.46
+91.106.85.47
+91.106.91.55
+91.106.91.69
+91.106.91.85
+91.106.91.192
+91.106.91.232
+91.106.92.139
+91.106.94.145
+91.106.95.130
+91.108.128.114
+91.108.128.174
+91.108.129.98
+91.108.129.99
+91.108.129.100
+91.108.129.101
+91.108.129.122
+91.108.130.112
+91.108.131.9
+91.108.131.10
+91.108.138.41
+91.108.140.3
+91.108.140.4
+91.108.140.5
+91.108.145.15
+91.108.145.68
+91.108.150.2
+91.108.150.24
+91.108.150.41
+91.108.152.6
+91.108.155.44
+91.108.155.194
+91.108.155.195
+91.108.155.198
+91.108.155.210
+91.108.155.244
+91.185.148.110
+91.186.193.222
+91.199.9.18
+91.199.9.117
+91.199.9.118
+91.199.9.232
+91.199.9.234
+91.199.18.5
+91.199.18.20
+91.199.18.37
+91.199.18.39
+91.199.18.68
+91.199.18.69
+91.199.18.70
+91.199.18.71
+91.199.18.242
+91.199.18.243
+91.199.18.255
+91.199.27.177
+91.199.27.178
+91.199.27.211
+91.199.27.214
+91.199.27.240
+91.199.27.241
+91.199.30.254
+91.199.215.34
+91.199.215.238
+91.206.177.2
+91.206.177.3
+91.207.205.3
+91.207.205.7
+91.208.163.195
+91.212.174.20
+91.212.174.32
+91.212.174.78
+91.212.174.246
+91.212.252.48
+91.220.113.36
+91.220.113.121
+91.220.113.247
+91.221.241.243
+91.222.196.8
+91.222.196.9
+91.222.196.53
+91.222.197.22
+91.222.197.25
+91.222.198.42
+91.222.198.43
+91.223.116.150
+91.223.116.173
+91.223.116.176
+91.223.116.179
+91.223.116.238
+91.223.146.17
+91.224.20.253
+91.224.176.0
+91.224.176.9
+91.227.86.244
+91.227.246.49
+91.227.246.132
+91.227.246.150
+91.227.246.167
+91.227.246.168
+91.227.246.197
+91.227.246.224
+91.227.246.225
+91.228.132.5
+91.232.72.30
+91.232.72.70
+91.234.39.76
+91.234.39.98
+91.234.39.193
+91.234.39.231
+91.236.168.144
+91.236.168.168
+91.236.169.161
+91.236.169.162
+91.236.169.163
+91.236.169.164
+91.236.169.165
+91.236.169.166
+91.236.169.167
+91.236.169.168
+91.236.169.169
+91.236.169.170
+91.237.255.130
+91.237.255.224
+91.240.60.65
+91.240.60.66
+91.240.60.230
+91.240.61.17
+91.240.61.45
+91.240.61.164
+91.240.61.165
+91.240.61.166
+91.240.61.217
+91.240.61.230
+91.240.61.238
+91.240.61.240
+91.240.61.248
+91.240.61.254
+91.240.63.15
+91.240.63.25
+91.240.63.59
+91.240.63.129
+91.240.63.214
+91.241.20.98
+91.241.20.181
+91.241.20.182
+91.241.20.183
+91.241.20.193
+91.241.21.17
+91.241.21.66
+91.241.21.82
+91.241.21.116
+91.241.21.117
+91.241.21.118
+91.241.21.119
+91.241.21.137
+91.241.21.139
+91.241.21.140
+91.241.21.142
+91.241.21.237
+91.242.44.2
+91.242.44.96
+91.242.44.253
+91.242.45.14
+91.242.45.37
+91.242.45.249
+91.243.127.222
+91.243.160.13
+91.243.160.62
+91.243.160.90
+91.243.160.104
+91.243.160.123
+91.243.160.144
+91.243.160.180
+91.243.160.211
+91.243.161.6
+91.243.161.35
+91.243.161.44
+91.243.161.77
+91.243.161.124
+91.243.161.164
+91.243.161.180
+91.243.161.188
+91.243.162.90
+91.243.164.4
+91.243.164.87
+91.243.164.132
+91.243.164.183
+91.243.164.188
+91.243.164.203
+91.243.164.227
+91.243.164.241
+91.243.165.43
+91.243.165.48
+91.243.165.59
+91.243.165.143
+91.243.165.192
+91.243.165.196
+91.243.165.245
+91.243.168.44
+91.243.168.106
+91.243.168.140
+91.243.168.251
+91.243.170.15
+91.243.170.211
+91.243.170.212
+91.243.170.213
+91.243.170.214
+91.243.171.169
+91.243.171.173
+91.243.171.193
+91.243.171.198
+91.243.172.27
+91.243.172.67
+91.243.172.123
+91.243.172.165
+91.243.172.218
+91.243.172.247
+91.243.175.129
+91.243.175.145
+91.245.228.241
+91.245.229.2
+91.245.230.16
+91.245.230.17
+91.245.230.25
+91.245.231.3
+91.246.31.108
+91.247.66.10
+91.247.66.46
+91.247.66.53
+91.247.66.66
+91.247.66.68
+91.247.66.90
+91.247.66.95
+91.247.66.97
+91.247.66.113
+91.247.66.138
+91.247.66.152
+91.247.66.156
+91.247.66.157
+91.247.66.162
+91.247.66.163
+91.247.66.164
+91.247.66.178
+91.247.66.193
+91.247.66.201
+91.247.66.206
+91.247.66.218
+91.247.66.235
+91.247.66.249
+91.247.67.222
+91.247.67.237
+91.247.67.244
+91.247.67.247
+91.247.171.167
+91.247.171.183
+92.42.207.4
+92.43.162.37
+92.43.162.95
+92.43.163.134
+92.43.163.179
+92.114.19.11
+92.114.26.73
+92.114.26.125
+92.114.29.91
+92.114.29.246
+92.114.29.247
+92.114.30.127
+92.114.48.60
+92.114.48.97
+92.114.48.140
+92.114.48.157
+92.114.48.171
+92.114.48.207
+92.114.48.210
+92.114.49.78
+92.114.49.154
+92.114.49.196
+92.114.49.243
+92.114.49.246
+92.119.57.85
+92.242.192.176
+92.242.192.178
+92.242.198.74
+92.242.198.202
+92.242.198.203
+92.242.198.204
+92.242.198.206
+92.242.198.254
+92.242.202.130
+92.242.202.186
+92.242.202.187
+92.242.202.188
+92.242.202.189
+92.242.202.190
+92.242.204.66
+92.242.204.67
+92.242.204.68
+92.242.204.69
+92.242.204.70
+92.242.204.71
+92.242.204.75
+92.242.204.150
+92.242.206.224
+92.242.207.43
+92.242.207.68
+92.242.212.50
+92.242.212.51
+92.242.212.99
+92.242.217.169
+92.242.217.174
+92.242.219.202
+92.242.219.203
+92.242.219.204
+92.242.219.205
+92.242.219.213
+92.242.220.181
+92.242.220.188
+92.242.223.10
+92.242.223.178
+92.246.144.10
+92.246.144.58
+92.246.144.59
+92.246.144.130
+92.246.144.225
+92.246.145.96
+92.246.145.164
+92.246.145.165
+92.246.145.166
+92.246.146.12
+92.246.146.22
+92.246.146.46
+92.246.146.74
+92.246.146.81
+92.246.146.89
+92.246.146.110
+92.246.146.141
+92.246.146.151
+92.246.146.202
+92.246.147.96
+92.246.147.212
+92.246.147.225
+92.249.56.18
+92.249.56.28
+93.113.224.82
+93.113.227.2
+93.113.233.3
+93.113.233.4
+93.113.234.70
+93.113.234.74
+93.113.236.13
+93.113.236.14
+93.113.236.15
+93.113.236.17
+93.114.104.1
+93.114.104.45
+93.114.104.91
+93.114.104.133
+93.114.104.139
+93.114.104.154
+93.114.104.185
+93.114.104.200
+93.114.105.11
+93.114.105.57
+93.114.105.69
+93.114.105.88
+93.114.105.93
+93.114.105.145
+93.114.105.153
+93.114.105.200
+93.114.105.233
+93.114.106.51
+93.114.106.94
+93.114.106.187
+93.114.106.188
+93.114.106.203
+93.114.108.15
+93.114.108.58
+93.114.108.62
+93.114.108.138
+93.114.108.140
+93.114.108.234
+93.114.108.241
+93.114.109.56
+93.114.109.77
+93.114.109.82
+93.114.109.137
+93.114.109.140
+93.114.109.158
+93.114.109.204
+93.114.110.11
+93.114.110.92
+93.114.110.123
+93.114.110.166
+93.114.110.193
+93.114.110.196
+93.114.110.218
+93.114.110.224
+93.114.111.49
+93.114.111.125
+93.114.111.147
+93.114.111.216
+93.114.111.244
+93.115.120.4
+93.115.120.98
+93.115.120.168
+93.115.120.181
+93.115.120.231
+93.115.121.0
+93.115.121.62
+93.115.121.68
+93.115.121.79
+93.115.121.106
+93.115.121.161
+93.115.121.223
+93.115.121.229
+93.115.122.8
+93.115.122.104
+93.115.122.144
+93.115.122.171
+93.115.123.15
+93.115.123.240
+93.115.124.114
+93.115.124.131
+93.115.124.189
+93.115.124.191
+93.115.124.200
+93.115.124.230
+93.115.124.236
+93.115.125.21
+93.115.125.53
+93.115.125.106
+93.115.125.123
+93.115.125.125
+93.115.125.157
+93.115.125.158
+93.115.125.171
+93.115.125.179
+93.115.125.221
+93.115.125.252
+93.115.126.1
+93.115.126.157
+93.115.126.183
+93.115.126.223
+93.115.126.224
+93.115.126.244
+93.115.127.71
+93.115.127.75
+93.115.127.119
+93.115.127.220
+93.115.144.1
+93.115.144.4
+93.115.144.13
+93.115.144.40
+93.115.144.45
+93.115.144.50
+93.115.144.62
+93.115.144.81
+93.115.144.88
+93.115.144.121
+93.115.144.130
+93.115.144.134
+93.115.144.137
+93.115.144.159
+93.115.144.167
+93.115.144.193
+93.115.144.195
+93.115.144.210
+93.115.144.214
+93.115.144.220
+93.115.144.234
+93.115.144.246
+93.115.145.22
+93.115.145.25
+93.115.145.30
+93.115.145.71
+93.115.145.83
+93.115.145.94
+93.115.145.105
+93.115.145.125
+93.115.145.141
+93.115.145.185
+93.115.145.198
+93.115.145.229
+93.115.145.239
+93.115.146.4
+93.115.146.17
+93.115.146.52
+93.115.146.53
+93.115.146.74
+93.115.146.81
+93.115.146.178
+93.115.146.215
+93.115.146.219
+93.115.146.234
+93.115.146.237
+93.115.147.71
+93.115.147.113
+93.115.147.115
+93.115.147.122
+93.115.147.126
+93.115.147.189
+93.115.147.215
+93.115.147.218
+93.115.147.225
+93.115.147.230
+93.115.148.16
+93.115.148.27
+93.115.148.29
+93.115.148.47
+93.115.148.64
+93.115.148.66
+93.115.148.82
+93.115.148.102
+93.115.148.129
+93.115.148.136
+93.115.148.156
+93.115.148.165
+93.115.148.186
+93.115.148.189
+93.115.148.207
+93.115.148.211
+93.115.148.237
+93.115.148.248
+93.115.149.8
+93.115.149.10
+93.115.149.29
+93.115.149.49
+93.115.149.54
+93.115.149.57
+93.115.149.58
+93.115.149.75
+93.115.149.86
+93.115.149.92
+93.115.149.136
+93.115.149.166
+93.115.149.173
+93.115.149.178
+93.115.149.198
+93.115.149.207
+93.115.149.230
+93.115.150.30
+93.115.151.130
+93.115.151.131
+93.115.151.132
+93.115.151.133
+93.115.151.136
+93.115.151.137
+93.115.151.139
+93.115.151.140
+93.115.151.141
+93.115.151.143
+93.115.151.144
+93.115.151.148
+93.115.151.153
+93.115.151.155
+93.115.151.157
+93.115.151.158
+93.115.151.160
+93.115.151.161
+93.115.151.162
+93.115.151.163
+93.115.151.164
+93.115.151.166
+93.115.151.170
+93.115.151.180
+93.115.151.181
+93.115.151.182
+93.115.151.183
+93.115.151.184
+93.115.151.185
+93.115.151.186
+93.115.151.188
+93.115.151.189
+93.115.151.190
+93.117.0.57
+93.117.0.248
+93.117.4.197
+93.117.7.237
+93.117.10.108
+93.117.11.67
+93.117.13.70
+93.117.14.55
+93.117.16.212
+93.117.19.20
+93.117.20.234
+93.117.23.104
+93.117.23.251
+93.117.24.200
+93.117.28.7
+93.117.28.137
+93.117.31.137
+93.117.33.30
+93.117.33.209
+93.117.33.239
+93.117.34.68
+93.117.35.213
+93.117.36.21
+93.117.36.179
+93.117.37.169
+93.117.38.3
+93.117.39.183
+93.117.40.249
+93.117.42.5
+93.117.42.113
+93.117.42.253
+93.117.43.51
+93.117.43.72
+93.117.44.18
+93.117.44.23
+93.117.44.93
+93.117.44.135
+93.117.46.170
+93.117.46.171
+93.117.46.214
+93.117.97.109
+93.117.127.70
+93.117.127.73
+93.117.127.91
+93.117.127.107
+93.117.127.164
+93.117.127.218
+93.118.96.24
+93.118.96.35
+93.118.96.68
+93.118.96.188
+93.118.96.210
+93.118.97.33
+93.118.97.63
+93.118.97.88
+93.118.97.92
+93.118.97.121
+93.118.97.135
+93.118.97.147
+93.118.98.13
+93.118.98.90
+93.118.98.119
+93.118.98.244
+93.118.99.20
+93.118.99.31
+93.118.99.74
+93.118.99.150
+93.118.100.139
+93.118.100.158
+93.118.101.10
+93.118.101.25
+93.118.101.48
+93.118.101.94
+93.118.101.129
+93.118.101.139
+93.118.101.153
+93.118.101.154
+93.118.101.155
+93.118.101.179
+93.118.101.232
+93.118.101.243
+93.118.102.6
+93.118.103.45
+93.118.103.208
+93.118.105.62
+93.118.105.139
+93.118.105.144
+93.118.105.170
+93.118.105.178
+93.118.106.95
+93.118.106.99
+93.118.106.182
+93.118.107.84
+93.118.108.18
+93.118.108.32
+93.118.108.90
+93.118.108.146
+93.118.108.177
+93.118.108.216
+93.118.108.225
+93.118.108.232
+93.118.109.52
+93.118.109.58
+93.118.109.61
+93.118.109.82
+93.118.109.117
+93.118.109.127
+93.118.109.140
+93.118.109.167
+93.118.109.200
+93.118.110.10
+93.118.110.24
+93.118.110.43
+93.118.110.73
+93.118.110.100
+93.118.110.156
+93.118.110.190
+93.118.110.215
+93.118.110.216
+93.118.110.231
+93.118.110.235
+93.118.111.49
+93.118.111.64
+93.118.111.109
+93.118.112.17
+93.118.112.19
+93.118.112.31
+93.118.112.46
+93.118.112.62
+93.118.112.102
+93.118.112.145
+93.118.112.161
+93.118.112.191
+93.118.112.236
+93.118.113.23
+93.118.113.133
+93.118.113.152
+93.118.113.224
+93.118.114.59
+93.118.114.127
+93.118.114.138
+93.118.114.165
+93.118.114.196
+93.118.114.240
+93.118.115.13
+93.118.115.43
+93.118.115.45
+93.118.115.108
+93.118.115.112
+93.118.115.131
+93.118.115.138
+93.118.115.143
+93.118.115.171
+93.118.115.207
+93.118.115.216
+93.118.115.234
+93.118.115.236
+93.118.115.240
+93.118.116.33
+93.118.116.37
+93.118.116.66
+93.118.116.127
+93.118.116.138
+93.118.116.174
+93.118.116.239
+93.118.116.247
+93.118.117.31
+93.118.117.50
+93.118.117.97
+93.118.117.122
+93.118.117.129
+93.118.117.177
+93.118.119.87
+93.118.119.110
+93.118.119.117
+93.118.119.169
+93.118.119.223
+93.118.120.5
+93.118.120.93
+93.118.120.119
+93.118.120.133
+93.118.120.139
+93.118.120.148
+93.118.120.207
+93.118.120.214
+93.118.121.32
+93.118.122.17
+93.118.122.34
+93.118.122.126
+93.118.122.154
+93.118.123.9
+93.118.123.11
+93.118.123.70
+93.118.123.83
+93.118.123.101
+93.118.123.121
+93.118.123.155
+93.118.123.176
+93.118.123.177
+93.118.123.196
+93.118.123.211
+93.118.123.218
+93.118.123.229
+93.118.124.38
+93.118.124.182
+93.118.124.254
+93.118.125.5
+93.118.125.28
+93.118.125.34
+93.118.125.143
+93.118.125.201
+93.118.125.205
+93.118.126.23
+93.118.126.41
+93.118.126.100
+93.118.126.107
+93.118.126.170
+93.118.126.205
+93.118.126.229
+93.118.126.251
+93.118.127.10
+93.118.127.49
+93.118.127.54
+93.118.127.60
+93.118.127.182
+93.118.127.206
+93.118.127.230
+93.118.127.249
+93.118.128.27
+93.118.128.37
+93.118.128.38
+93.118.128.56
+93.118.128.66
+93.118.128.101
+93.118.128.104
+93.118.128.124
+93.118.129.28
+93.118.129.96
+93.118.129.191
+93.118.130.149
+93.118.130.183
+93.118.130.185
+93.118.130.243
+93.118.131.12
+93.118.131.106
+93.118.132.12
+93.118.132.41
+93.118.132.213
+93.118.133.12
+93.118.133.69
+93.118.133.170
+93.118.133.198
+93.118.133.212
+93.118.134.13
+93.118.135.61
+93.118.135.97
+93.118.135.103
+93.118.135.170
+93.118.135.225
+93.118.136.25
+93.118.136.36
+93.118.136.44
+93.118.136.83
+93.118.136.169
+93.118.136.203
+93.118.136.207
+93.118.136.232
+93.118.137.14
+93.118.137.38
+93.118.137.49
+93.118.137.65
+93.118.137.91
+93.118.137.98
+93.118.137.221
+93.118.138.36
+93.118.138.52
+93.118.138.73
+93.118.138.88
+93.118.138.114
+93.118.138.223
+93.118.138.246
+93.118.139.36
+93.118.139.84
+93.118.139.90
+93.118.139.97
+93.118.139.130
+93.118.139.144
+93.118.139.145
+93.118.139.151
+93.118.139.155
+93.118.139.210
+93.118.139.246
+93.118.140.18
+93.118.140.56
+93.118.140.70
+93.118.140.102
+93.118.140.148
+93.118.140.152
+93.118.140.196
+93.118.140.209
+93.118.140.211
+93.118.140.224
+93.118.140.225
+93.118.141.27
+93.118.141.188
+93.118.141.201
+93.118.141.232
+93.118.141.252
+93.118.142.209
+93.118.142.222
+93.118.143.2
+93.118.143.9
+93.118.143.64
+93.118.143.67
+93.118.143.86
+93.118.143.89
+93.118.143.95
+93.118.143.97
+93.118.143.111
+93.118.143.112
+93.118.143.143
+93.118.143.155
+93.118.143.195
+93.118.143.211
+93.118.143.226
+93.118.143.231
+93.118.144.0
+93.118.144.16
+93.118.144.41
+93.118.144.74
+93.118.144.114
+93.118.144.119
+93.118.144.124
+93.118.144.141
+93.118.144.168
+93.118.144.228
+93.118.144.242
+93.118.145.25
+93.118.145.213
+93.118.145.245
+93.118.145.248
+93.118.146.59
+93.118.146.88
+93.118.146.176
+93.118.146.253
+93.118.147.14
+93.118.147.158
+93.118.147.176
+93.118.147.180
+93.118.147.193
+93.118.148.1
+93.118.148.7
+93.118.148.26
+93.118.148.30
+93.118.148.34
+93.118.148.70
+93.118.148.118
+93.118.148.140
+93.118.148.189
+93.118.148.199
+93.118.149.228
+93.118.150.42
+93.118.151.217
+93.118.151.236
+93.118.151.249
+93.118.152.46
+93.118.152.81
+93.118.152.168
+93.118.152.177
+93.118.152.247
+93.118.152.253
+93.118.153.92
+93.118.153.104
+93.118.153.108
+93.118.153.109
+93.118.153.110
+93.118.153.119
+93.118.153.126
+93.118.153.131
+93.118.153.137
+93.118.153.157
+93.118.153.229
+93.118.153.252
+93.118.154.12
+93.118.154.56
+93.118.154.174
+93.118.154.188
+93.118.154.205
+93.118.154.225
+93.118.154.226
+93.118.155.66
+93.118.155.69
+93.118.155.100
+93.118.155.109
+93.118.156.42
+93.118.156.46
+93.118.156.78
+93.118.156.149
+93.118.156.176
+93.118.157.57
+93.118.157.146
+93.118.157.210
+93.118.157.223
+93.118.158.0
+93.118.158.20
+93.118.158.37
+93.118.158.78
+93.118.158.92
+93.118.158.166
+93.118.158.172
+93.118.158.204
+93.118.159.64
+93.118.159.114
+93.118.159.149
+93.118.159.200
+93.118.160.27
+93.118.160.109
+93.118.160.123
+93.118.160.175
+93.118.160.189
+93.118.160.213
+93.118.161.8
+93.118.161.30
+93.118.161.39
+93.118.161.69
+93.118.161.71
+93.118.161.168
+93.118.161.225
+93.118.161.228
+93.118.161.233
+93.118.162.13
+93.118.162.161
+93.118.163.9
+93.118.163.140
+93.118.163.146
+93.118.163.230
+93.118.163.252
+93.118.164.28
+93.118.164.41
+93.118.164.59
+93.118.164.183
+93.118.164.199
+93.118.165.55
+93.118.165.136
+93.118.165.182
+93.118.166.36
+93.118.166.62
+93.118.166.73
+93.118.166.131
+93.118.166.150
+93.118.166.193
+93.118.166.235
+93.118.166.245
+93.118.167.33
+93.118.167.58
+93.118.167.64
+93.118.167.147
+93.118.167.152
+93.118.167.176
+93.118.167.208
+93.118.167.219
+93.118.167.223
+93.118.167.236
+93.118.180.129
+93.118.180.245
+93.118.181.27
+93.118.181.112
+93.118.181.114
+93.118.181.149
+93.118.181.225
+93.118.181.238
+93.118.182.9
+93.118.182.21
+93.118.182.35
+93.118.182.63
+93.118.183.167
+93.118.183.188
+93.119.54.205
+93.126.2.252
+93.126.3.22
+93.126.3.98
+93.126.3.229
+93.126.4.73
+93.126.5.81
+93.126.5.94
+93.126.5.106
+93.126.5.127
+93.126.6.39
+93.126.6.61
+93.126.7.168
+93.126.8.121
+93.126.9.1
+93.126.9.2
+93.126.9.3
+93.126.9.10
+93.126.9.57
+93.126.9.86
+93.126.9.153
+93.126.9.166
+93.126.9.186
+93.126.9.233
+93.126.9.234
+93.126.9.235
+93.126.9.236
+93.126.9.237
+93.126.9.238
+93.126.10.17
+93.126.10.70
+93.126.11.234
+93.126.12.22
+93.126.12.254
+93.126.13.84
+93.126.13.132
+93.126.15.129
+93.126.17.130
+93.126.19.246
+93.126.20.107
+93.126.21.4
+93.126.21.57
+93.126.21.58
+93.126.21.117
+93.126.25.33
+93.126.29.14
+93.126.29.44
+93.126.29.53
+93.126.29.64
+93.126.29.96
+93.126.29.108
+93.126.29.109
+93.126.31.140
+93.126.31.161
+93.126.34.81
+93.126.40.7
+93.126.40.17
+93.126.40.18
+93.126.40.19
+93.126.40.22
+93.126.40.23
+93.126.40.24
+93.126.40.30
+93.126.40.67
+93.126.40.68
+93.126.40.69
+93.126.40.70
+93.126.40.71
+93.126.40.72
+93.126.40.73
+93.126.40.76
+93.126.41.0
+93.126.41.1
+93.126.41.2
+93.126.41.3
+93.126.41.4
+93.126.41.6
+93.126.41.7
+93.126.41.8
+93.126.41.9
+93.126.41.11
+93.126.41.12
+93.126.41.13
+93.126.41.14
+93.126.41.15
+93.126.41.16
+93.126.41.17
+93.126.41.18
+93.126.41.19
+93.126.41.20
+93.126.41.23
+93.126.41.24
+93.126.41.26
+93.126.41.27
+93.126.41.28
+93.126.41.29
+93.126.41.30
+93.126.41.31
+93.126.41.34
+93.126.41.35
+93.126.41.36
+93.126.41.37
+93.126.41.38
+93.126.41.39
+93.126.41.40
+93.126.41.41
+93.126.41.42
+93.126.41.44
+93.126.41.45
+93.126.41.46
+93.126.41.47
+93.126.41.48
+93.126.41.49
+93.126.41.50
+93.126.41.51
+93.126.41.52
+93.126.41.53
+93.126.41.55
+93.126.41.56
+93.126.41.57
+93.126.41.58
+93.126.41.60
+93.126.41.61
+93.126.41.62
+93.126.41.63
+93.126.41.64
+93.126.41.65
+93.126.41.66
+93.126.41.67
+93.126.41.68
+93.126.41.69
+93.126.41.70
+93.126.41.71
+93.126.41.72
+93.126.41.73
+93.126.41.74
+93.126.41.76
+93.126.41.77
+93.126.41.78
+93.126.41.80
+93.126.41.81
+93.126.41.82
+93.126.41.83
+93.126.41.84
+93.126.41.85
+93.126.41.86
+93.126.41.87
+93.126.41.88
+93.126.41.89
+93.126.41.90
+93.126.41.91
+93.126.41.92
+93.126.41.93
+93.126.41.95
+93.126.41.96
+93.126.41.97
+93.126.41.99
+93.126.41.100
+93.126.41.101
+93.126.41.102
+93.126.41.103
+93.126.41.104
+93.126.41.105
+93.126.41.106
+93.126.41.107
+93.126.41.108
+93.126.41.109
+93.126.41.110
+93.126.41.111
+93.126.41.112
+93.126.41.113
+93.126.41.114
+93.126.41.115
+93.126.41.116
+93.126.41.117
+93.126.41.118
+93.126.41.119
+93.126.41.120
+93.126.41.121
+93.126.41.122
+93.126.41.123
+93.126.41.124
+93.126.41.125
+93.126.41.126
+93.126.41.127
+93.126.41.128
+93.126.41.129
+93.126.41.130
+93.126.41.131
+93.126.41.132
+93.126.41.133
+93.126.41.134
+93.126.41.135
+93.126.41.136
+93.126.41.137
+93.126.41.138
+93.126.41.139
+93.126.41.140
+93.126.41.141
+93.126.41.142
+93.126.41.143
+93.126.41.144
+93.126.41.145
+93.126.41.147
+93.126.41.148
+93.126.41.149
+93.126.41.150
+93.126.41.151
+93.126.41.153
+93.126.41.154
+93.126.41.155
+93.126.41.156
+93.126.41.157
+93.126.41.158
+93.126.41.159
+93.126.41.160
+93.126.41.161
+93.126.41.163
+93.126.41.164
+93.126.41.165
+93.126.41.166
+93.126.41.167
+93.126.41.168
+93.126.41.169
+93.126.41.170
+93.126.41.171
+93.126.41.172
+93.126.41.173
+93.126.41.174
+93.126.41.175
+93.126.41.176
+93.126.41.177
+93.126.41.178
+93.126.41.179
+93.126.41.180
+93.126.41.181
+93.126.41.182
+93.126.41.183
+93.126.41.184
+93.126.41.185
+93.126.41.186
+93.126.41.187
+93.126.41.188
+93.126.41.189
+93.126.41.190
+93.126.41.192
+93.126.41.193
+93.126.41.194
+93.126.41.195
+93.126.41.196
+93.126.41.198
+93.126.41.200
+93.126.41.201
+93.126.41.202
+93.126.41.203
+93.126.41.204
+93.126.41.205
+93.126.41.207
+93.126.41.208
+93.126.41.210
+93.126.41.211
+93.126.41.212
+93.126.41.213
+93.126.41.214
+93.126.41.215
+93.126.41.216
+93.126.41.217
+93.126.41.218
+93.126.41.219
+93.126.41.220
+93.126.41.221
+93.126.41.222
+93.126.41.223
+93.126.41.225
+93.126.41.226
+93.126.41.227
+93.126.41.228
+93.126.41.229
+93.126.41.230
+93.126.41.231
+93.126.41.232
+93.126.41.233
+93.126.41.234
+93.126.41.235
+93.126.41.236
+93.126.41.237
+93.126.41.238
+93.126.41.239
+93.126.44.161
+93.126.44.162
+93.126.44.163
+93.126.44.164
+93.126.44.165
+93.126.44.166
+93.126.44.167
+93.126.44.169
+93.126.44.170
+93.126.49.151
+93.126.51.142
+93.126.51.144
+93.126.51.179
+93.126.57.4
+93.126.58.43
+93.126.58.69
+93.126.58.245
+94.74.128.169
+94.74.128.185
+94.74.128.251
+94.74.129.52
+94.74.130.172
+94.74.132.135
+94.74.133.174
+94.74.133.178
+94.74.135.180
+94.74.136.120
+94.74.136.145
+94.74.136.187
+94.74.136.240
+94.74.138.44
+94.74.138.54
+94.74.138.123
+94.74.138.124
+94.74.138.146
+94.74.138.174
+94.74.138.201
+94.74.138.210
+94.74.138.226
+94.74.139.44
+94.74.139.149
+94.74.139.168
+94.74.139.216
+94.74.139.252
+94.74.141.70
+94.74.141.176
+94.74.142.165
+94.74.144.14
+94.74.144.25
+94.74.144.31
+94.74.144.166
+94.74.145.2
+94.74.145.28
+94.74.145.110
+94.74.146.192
+94.74.146.200
+94.74.146.251
+94.74.149.5
+94.74.149.71
+94.74.150.75
+94.74.150.184
+94.74.151.34
+94.74.160.61
+94.74.160.86
+94.74.160.88
+94.74.161.41
+94.74.161.51
+94.74.161.101
+94.74.161.166
+94.74.161.169
+94.74.161.237
+94.74.161.251
+94.74.163.22
+94.74.163.185
+94.74.163.186
+94.74.165.190
+94.74.166.42
+94.74.166.99
+94.74.167.161
+94.74.168.200
+94.74.168.201
+94.74.168.202
+94.74.168.203
+94.74.168.206
+94.74.169.9
+94.74.169.10
+94.74.169.29
+94.74.169.30
+94.74.172.64
+94.74.172.104
+94.74.172.155
+94.74.172.173
+94.74.174.73
+94.74.174.122
+94.74.174.232
+94.74.174.235
+94.74.175.55
+94.74.177.157
+94.74.177.220
+94.74.178.235
+94.74.179.219
+94.74.180.242
+94.74.183.30
+94.74.183.32
+94.74.183.196
+94.74.186.1
+94.74.186.9
+94.74.186.53
+94.74.186.103
+94.74.186.187
+94.74.188.48
+94.74.188.53
+94.74.188.151
+94.74.188.199
+94.74.188.210
+94.74.190.92
+94.101.128.11
+94.101.128.124
+94.101.128.174
+94.101.129.174
+94.101.131.160
+94.101.131.176
+94.101.132.45
+94.101.133.28
+94.101.133.133
+94.101.133.192
+94.101.140.10
+94.101.177.11
+94.101.177.92
+94.101.178.227
+94.101.179.5
+94.101.179.22
+94.101.179.216
+94.101.180.83
+94.101.180.180
+94.101.184.113
+94.101.185.66
+94.101.185.103
+94.101.185.253
+94.101.186.9
+94.101.186.145
+94.101.187.203
+94.139.180.63
+94.139.180.84
+94.139.180.131
+94.139.182.140
+94.139.183.152
+94.139.183.153
+94.139.191.205
+94.139.191.216
+94.182.0.43
+94.182.0.131
+94.182.0.152
+94.182.0.217
+94.182.1.188
+94.182.1.195
+94.182.1.227
+94.182.2.14
+94.182.2.48
+94.182.2.99
+94.182.2.110
+94.182.2.126
+94.182.2.174
+94.182.2.193
+94.182.2.245
+94.182.10.166
+94.182.16.81
+94.182.16.82
+94.182.16.83
+94.182.16.84
+94.182.16.85
+94.182.16.86
+94.182.16.87
+94.182.16.88
+94.182.16.90
+94.182.17.163
+94.182.18.5
+94.182.18.26
+94.182.18.46
+94.182.18.118
+94.182.18.137
+94.182.18.150
+94.182.18.162
+94.182.18.191
+94.182.18.207
+94.182.18.208
+94.182.18.210
+94.182.18.225
+94.182.18.248
+94.182.18.251
+94.182.19.97
+94.182.20.8
+94.182.20.22
+94.182.22.18
+94.182.22.20
+94.182.22.24
+94.182.22.26
+94.182.22.31
+94.182.26.26
+94.182.26.28
+94.182.26.58
+94.182.26.82
+94.182.27.58
+94.182.27.101
+94.182.27.102
+94.182.27.103
+94.182.27.107
+94.182.27.142
+94.182.27.230
+94.182.31.3
+94.182.31.13
+94.182.31.25
+94.182.31.37
+94.182.31.57
+94.182.31.61
+94.182.31.68
+94.182.31.73
+94.182.31.91
+94.182.31.98
+94.182.31.106
+94.182.31.112
+94.182.31.119
+94.182.31.123
+94.182.31.126
+94.182.31.130
+94.182.31.143
+94.182.31.148
+94.182.31.165
+94.182.31.175
+94.182.31.180
+94.182.31.183
+94.182.31.187
+94.182.34.59
+94.182.35.22
+94.182.35.86
+94.182.35.150
+94.182.35.167
+94.182.35.187
+94.182.35.201
+94.182.35.210
+94.182.35.246
+94.182.35.247
+94.182.35.253
+94.182.36.26
+94.182.36.121
+94.182.36.134
+94.182.36.182
+94.182.36.192
+94.182.36.202
+94.182.36.214
+94.182.36.225
+94.182.36.231
+94.182.36.251
+94.182.37.9
+94.182.37.113
+94.182.37.163
+94.182.37.213
+94.182.37.234
+94.182.38.2
+94.182.38.74
+94.182.38.88
+94.182.38.89
+94.182.38.90
+94.182.38.91
+94.182.38.113
+94.182.39.195
+94.182.39.224
+94.182.39.225
+94.182.39.226
+94.182.39.227
+94.182.39.228
+94.182.39.229
+94.182.39.231
+94.182.39.232
+94.182.39.233
+94.182.39.234
+94.182.39.235
+94.182.39.236
+94.182.39.237
+94.182.39.238
+94.182.39.239
+94.182.42.7
+94.182.42.8
+94.182.43.2
+94.182.43.30
+94.182.43.86
+94.182.44.157
+94.182.44.174
+94.182.46.46
+94.182.46.197
+94.182.47.138
+94.182.48.4
+94.182.48.11
+94.182.48.14
+94.182.48.49
+94.182.48.50
+94.182.48.69
+94.182.48.70
+94.182.48.71
+94.182.49.6
+94.182.49.54
+94.182.49.106
+94.182.49.113
+94.182.49.227
+94.182.49.232
+94.182.49.240
+94.182.50.49
+94.182.50.50
+94.182.50.51
+94.182.50.52
+94.182.50.53
+94.182.50.54
+94.182.50.55
+94.182.50.60
+94.182.50.62
+94.182.50.66
+94.182.50.67
+94.182.50.69
+94.182.50.70
+94.182.50.73
+94.182.50.74
+94.182.50.78
+94.182.50.94
+94.182.50.129
+94.182.50.147
+94.182.52.49
+94.182.52.50
+94.182.52.68
+94.182.52.72
+94.182.52.91
+94.182.52.92
+94.182.53.66
+94.182.53.94
+94.182.53.161
+94.182.53.162
+94.182.53.178
+94.182.53.186
+94.182.53.189
+94.182.53.237
+94.182.53.246
+94.182.54.2
+94.182.54.7
+94.182.54.12
+94.182.54.38
+94.182.54.77
+94.182.54.200
+94.182.54.202
+94.182.54.204
+94.182.54.207
+94.182.54.218
+94.182.56.6
+94.182.56.20
+94.182.56.33
+94.182.56.58
+94.182.56.60
+94.182.56.254
+94.182.62.1
+94.182.83.203
+94.182.83.215
+94.182.85.86
+94.182.87.148
+94.182.87.213
+94.182.87.221
+94.182.91.212
+94.182.92.46
+94.182.92.87
+94.182.95.178
+94.182.104.157
+94.182.110.254
+94.182.129.67
+94.182.134.138
+94.182.136.21
+94.182.136.107
+94.182.136.163
+94.182.137.91
+94.182.146.6
+94.182.146.7
+94.182.146.92
+94.182.149.69
+94.182.149.80
+94.182.150.184
+94.182.155.132
+94.182.155.135
+94.182.155.200
+94.182.156.116
+94.182.156.188
+94.182.157.184
+94.182.168.168
+94.182.168.220
+94.182.169.56
+94.182.169.113
+94.182.170.150
+94.182.170.196
+94.182.170.242
+94.182.172.195
+94.182.172.201
+94.182.172.252
+94.182.175.3
+94.182.175.29
+94.182.175.30
+94.182.175.57
+94.182.176.141
+94.182.176.143
+94.182.176.144
+94.182.178.96
+94.182.178.106
+94.182.178.139
+94.182.180.141
+94.182.183.154
+94.182.186.227
+94.182.186.228
+94.182.192.4
+94.182.192.30
+94.182.192.31
+94.182.192.46
+94.182.192.50
+94.182.192.57
+94.182.192.79
+94.182.192.85
+94.182.192.107
+94.182.192.120
+94.182.192.139
+94.182.192.169
+94.182.192.170
+94.182.192.173
+94.182.192.192
+94.182.192.228
+94.182.192.231
+94.182.192.248
+94.182.192.253
+94.182.193.3
+94.182.193.12
+94.182.193.36
+94.182.193.40
+94.182.193.44
+94.182.193.52
+94.182.193.76
+94.182.193.78
+94.182.193.93
+94.182.193.98
+94.182.193.106
+94.182.193.112
+94.182.193.113
+94.182.193.140
+94.182.193.141
+94.182.193.155
+94.182.193.171
+94.182.193.175
+94.182.193.183
+94.182.193.184
+94.182.193.186
+94.182.193.189
+94.182.193.230
+94.182.193.235
+94.182.193.238
+94.182.193.243
+94.182.193.244
+94.182.194.73
+94.182.194.74
+94.182.194.83
+94.182.194.98
+94.182.194.120
+94.182.194.149
+94.182.194.151
+94.182.194.181
+94.182.194.184
+94.182.194.185
+94.182.194.195
+94.182.194.198
+94.182.194.206
+94.182.194.227
+94.182.194.231
+94.182.195.14
+94.182.195.58
+94.182.195.61
+94.182.195.160
+94.182.196.62
+94.182.196.82
+94.182.196.238
+94.182.197.62
+94.182.197.142
+94.182.197.153
+94.182.197.154
+94.182.197.174
+94.182.197.198
+94.182.198.6
+94.182.198.30
+94.182.198.34
+94.182.198.78
+94.182.198.194
+94.182.198.214
+94.182.198.238
+94.182.199.106
+94.182.199.226
+94.182.199.246
+94.182.199.250
+94.182.201.9
+94.182.201.25
+94.182.201.58
+94.182.201.59
+94.182.201.115
+94.182.202.91
+94.182.202.185
+94.182.202.216
+94.182.202.217
+94.182.203.114
+94.182.203.115
+94.182.203.116
+94.182.203.117
+94.182.203.178
+94.182.209.2
+94.182.211.62
+94.182.211.250
+94.182.211.251
+94.182.214.179
+94.182.214.180
+94.182.214.181
+94.182.214.183
+94.182.214.184
+94.182.214.186
+94.182.214.187
+94.182.214.188
+94.182.214.190
+94.182.216.1
+94.182.216.2
+94.182.219.26
+94.182.219.54
+94.182.219.129
+94.182.219.154
+94.182.219.162
+94.182.219.246
+94.182.219.247
+94.182.220.6
+94.182.225.139
+94.182.225.152
+94.182.225.164
+94.182.225.175
+94.182.225.183
+94.182.225.231
+94.182.225.233
+94.182.225.238
+94.182.225.254
+94.182.227.48
+94.182.227.93
+94.182.227.139
+94.182.227.177
+94.182.250.3
+94.182.250.4
+94.182.250.5
+94.182.250.50
+94.182.251.115
+94.182.251.125
+94.182.251.151
+94.182.253.71
+94.182.253.135
+94.182.254.5
+94.182.254.117
+94.182.254.121
+94.182.254.122
+94.182.255.139
+94.182.255.200
+94.183.0.37
+94.183.0.46
+94.183.0.54
+94.183.0.85
+94.183.0.97
+94.183.0.125
+94.183.0.167
+94.183.0.241
+94.183.1.21
+94.183.1.50
+94.183.1.98
+94.183.1.229
+94.183.1.246
+94.183.2.47
+94.183.2.151
+94.183.2.211
+94.183.3.130
+94.183.3.150
+94.183.3.196
+94.183.5.95
+94.183.6.186
+94.183.6.229
+94.183.6.245
+94.183.7.129
+94.183.7.199
+94.183.7.207
+94.183.11.9
+94.183.11.29
+94.183.11.36
+94.183.11.87
+94.183.11.100
+94.183.11.160
+94.183.13.233
+94.183.14.202
+94.183.15.43
+94.183.15.64
+94.183.15.245
+94.183.16.15
+94.183.16.45
+94.183.17.128
+94.183.17.141
+94.183.18.36
+94.183.20.50
+94.183.20.147
+94.183.21.119
+94.183.22.114
+94.183.23.1
+94.183.23.2
+94.183.23.163
+94.183.23.207
+94.183.24.57
+94.183.24.98
+94.183.26.10
+94.183.26.122
+94.183.26.130
+94.183.26.132
+94.183.27.72
+94.183.27.83
+94.183.27.96
+94.183.27.154
+94.183.27.159
+94.183.27.223
+94.183.27.235
+94.183.28.24
+94.183.28.60
+94.183.28.85
+94.183.28.92
+94.183.28.102
+94.183.28.111
+94.183.28.141
+94.183.28.159
+94.183.28.195
+94.183.28.235
+94.183.29.4
+94.183.29.100
+94.183.29.112
+94.183.29.113
+94.183.29.137
+94.183.29.167
+94.183.29.187
+94.183.30.36
+94.183.30.38
+94.183.30.42
+94.183.30.43
+94.183.30.46
+94.183.30.65
+94.183.30.78
+94.183.30.88
+94.183.30.107
+94.183.30.116
+94.183.30.117
+94.183.30.128
+94.183.30.161
+94.183.30.164
+94.183.30.167
+94.183.30.170
+94.183.30.171
+94.183.30.199
+94.183.30.202
+94.183.30.204
+94.183.30.212
+94.183.30.216
+94.183.31.23
+94.183.31.63
+94.183.31.73
+94.183.31.124
+94.183.31.156
+94.183.31.202
+94.183.31.205
+94.183.32.25
+94.183.32.86
+94.183.33.78
+94.183.33.240
+94.183.34.55
+94.183.34.98
+94.183.34.232
+94.183.35.74
+94.183.35.226
+94.183.37.2
+94.183.37.76
+94.183.38.141
+94.183.40.253
+94.183.42.107
+94.183.44.111
+94.183.46.108
+94.183.46.116
+94.183.48.10
+94.183.48.15
+94.183.49.6
+94.183.49.21
+94.183.49.41
+94.183.49.47
+94.183.49.130
+94.183.49.206
+94.183.50.97
+94.183.50.174
+94.183.50.187
+94.183.50.231
+94.183.51.95
+94.183.51.144
+94.183.51.165
+94.183.51.215
+94.183.52.51
+94.183.52.67
+94.183.52.94
+94.183.52.215
+94.183.52.227
+94.183.53.29
+94.183.53.99
+94.183.53.113
+94.183.53.133
+94.183.56.163
+94.183.56.191
+94.183.56.229
+94.183.56.251
+94.183.57.45
+94.183.57.66
+94.183.57.215
+94.183.58.29
+94.183.58.79
+94.183.58.188
+94.183.58.198
+94.183.59.32
+94.183.59.75
+94.183.59.104
+94.183.59.114
+94.183.59.197
+94.183.59.245
+94.183.60.19
+94.183.60.28
+94.183.61.126
+94.183.61.145
+94.183.61.218
+94.183.62.125
+94.183.62.141
+94.183.62.222
+94.183.63.68
+94.183.67.57
+94.183.67.84
+94.183.68.106
+94.183.70.115
+94.183.70.140
+94.183.72.99
+94.183.72.116
+94.183.72.164
+94.183.72.187
+94.183.72.243
+94.183.73.76
+94.183.73.77
+94.183.73.78
+94.183.73.111
+94.183.73.214
+94.183.73.218
+94.183.73.246
+94.183.74.15
+94.183.74.58
+94.183.74.78
+94.183.74.101
+94.183.74.184
+94.183.75.49
+94.183.78.74
+94.183.80.22
+94.183.82.7
+94.183.82.216
+94.183.83.1
+94.183.83.19
+94.183.83.115
+94.183.83.183
+94.183.83.211
+94.183.83.241
+94.183.84.144
+94.183.84.236
+94.183.85.31
+94.183.85.115
+94.183.85.139
+94.183.85.190
+94.183.85.232
+94.183.88.131
+94.183.88.134
+94.183.90.106
+94.183.90.166
+94.183.90.221
+94.183.90.227
+94.183.91.32
+94.183.91.82
+94.183.91.241
+94.183.92.64
+94.183.92.70
+94.183.92.77
+94.183.92.84
+94.183.92.92
+94.183.92.95
+94.183.92.112
+94.183.92.121
+94.183.92.227
+94.183.92.232
+94.183.93.28
+94.183.93.48
+94.183.93.51
+94.183.93.52
+94.183.93.74
+94.183.93.103
+94.183.93.106
+94.183.93.109
+94.183.93.117
+94.183.93.123
+94.183.93.200
+94.183.93.210
+94.183.93.228
+94.183.93.239
+94.183.94.29
+94.183.94.38
+94.183.94.39
+94.183.94.40
+94.183.94.54
+94.183.94.55
+94.183.95.114
+94.183.95.122
+94.183.95.146
+94.183.95.171
+94.183.95.206
+94.183.95.208
+94.183.97.22
+94.183.99.63
+94.183.99.81
+94.183.99.111
+94.183.99.176
+94.183.99.210
+94.183.99.218
+94.183.99.222
+94.183.99.226
+94.183.99.237
+94.183.99.238
+94.183.100.59
+94.183.100.202
+94.183.100.251
+94.183.102.151
+94.183.102.226
+94.183.103.139
+94.183.104.107
+94.183.106.110
+94.183.107.102
+94.183.108.65
+94.183.109.224
+94.183.110.113
+94.183.110.223
+94.183.111.6
+94.183.113.41
+94.183.113.86
+94.183.114.81
+94.183.114.92
+94.183.115.73
+94.183.115.167
+94.183.115.187
+94.183.115.188
+94.183.116.18
+94.183.116.56
+94.183.116.126
+94.183.116.220
+94.183.117.124
+94.183.117.200
+94.183.118.6
+94.183.118.14
+94.183.118.42
+94.183.118.107
+94.183.118.123
+94.183.118.127
+94.183.119.28
+94.183.119.88
+94.183.119.104
+94.183.119.202
+94.183.119.246
+94.183.120.17
+94.183.120.34
+94.183.120.86
+94.183.120.104
+94.183.120.224
+94.183.122.16
+94.183.122.17
+94.183.122.64
+94.183.122.126
+94.183.122.174
+94.183.123.128
+94.183.123.129
+94.183.123.132
+94.183.124.16
+94.183.124.21
+94.183.124.30
+94.183.124.45
+94.183.124.77
+94.183.124.130
+94.183.124.140
+94.183.124.187
+94.183.124.194
+94.183.125.56
+94.183.125.172
+94.183.125.187
+94.183.126.39
+94.183.126.41
+94.183.126.42
+94.183.126.111
+94.183.126.211
+94.183.127.13
+94.183.127.27
+94.183.127.40
+94.183.127.76
+94.183.127.100
+94.183.127.114
+94.183.127.123
+94.183.127.163
+94.183.129.209
+94.183.132.5
+94.183.132.100
+94.183.132.119
+94.183.132.126
+94.183.132.128
+94.183.132.143
+94.183.132.144
+94.183.132.174
+94.183.132.214
+94.183.133.82
+94.183.133.113
+94.183.133.132
+94.183.133.146
+94.183.133.159
+94.183.133.175
+94.183.133.223
+94.183.133.235
+94.183.133.247
+94.183.134.150
+94.183.134.153
+94.183.134.202
+94.183.134.255
+94.183.135.140
+94.183.138.109
+94.183.139.136
+94.183.140.110
+94.183.140.138
+94.183.141.68
+94.183.144.185
+94.183.145.89
+94.183.145.147
+94.183.145.155
+94.183.145.214
+94.183.146.186
+94.183.146.203
+94.183.146.221
+94.183.147.241
+94.183.148.65
+94.183.148.98
+94.183.148.129
+94.183.148.184
+94.183.148.238
+94.183.149.65
+94.183.149.85
+94.183.149.140
+94.183.149.146
+94.183.149.171
+94.183.149.204
+94.183.149.249
+94.183.149.252
+94.183.150.73
+94.183.150.75
+94.183.150.115
+94.183.150.229
+94.183.154.207
+94.183.156.128
+94.183.156.137
+94.183.162.195
+94.183.163.52
+94.183.163.60
+94.183.163.75
+94.183.164.37
+94.183.164.49
+94.183.172.174
+94.183.172.182
+94.183.173.6
+94.183.175.157
+94.183.176.45
+94.183.180.21
+94.184.3.203
+94.184.3.226
+94.184.3.227
+94.184.3.230
+94.184.10.98
+94.184.16.7
+94.184.16.178
+94.184.17.213
+94.184.18.24
+94.184.18.44
+94.184.18.189
+94.184.21.66
+94.184.22.6
+94.184.22.158
+94.184.23.65
+94.184.23.243
+94.184.29.33
+94.184.29.218
+94.184.90.225
+94.184.177.129
+94.184.208.77
+94.184.208.102
+94.199.0.1
+94.199.0.41
+94.199.0.60
+94.199.0.78
+94.199.0.212
+94.232.168.162
+94.232.171.82
+94.232.171.83
+94.232.171.84
+94.232.171.85
+94.232.171.91
+94.232.172.109
+94.232.173.8
+94.232.173.136
+94.232.173.192
+94.232.175.210
+94.232.175.211
+95.38.10.9
+95.38.10.65
+95.38.10.153
+95.38.10.195
+95.38.10.197
+95.38.10.219
+95.38.10.230
+95.38.10.253
+95.38.11.1
+95.38.11.26
+95.38.11.42
+95.38.11.46
+95.38.11.84
+95.38.11.89
+95.38.11.94
+95.38.11.95
+95.38.11.201
+95.38.11.223
+95.38.15.205
+95.38.15.247
+95.38.20.66
+95.38.20.67
+95.38.24.146
+95.38.25.0
+95.38.27.16
+95.38.27.32
+95.38.27.36
+95.38.34.30
+95.38.34.58
+95.38.34.59
+95.38.34.60
+95.38.34.242
+95.38.35.44
+95.38.38.75
+95.38.38.83
+95.38.39.173
+95.38.46.84
+95.38.46.130
+95.38.47.173
+95.38.48.253
+95.38.49.157
+95.38.50.102
+95.38.52.218
+95.38.53.118
+95.38.60.5
+95.38.60.11
+95.38.60.42
+95.38.60.252
+95.38.63.47
+95.38.63.59
+95.38.63.200
+95.38.63.234
+95.38.65.2
+95.38.65.3
+95.38.65.5
+95.38.65.234
+95.38.66.23
+95.38.72.23
+95.38.75.75
+95.38.75.79
+95.38.76.42
+95.38.76.160
+95.38.77.190
+95.38.78.69
+95.38.78.239
+95.38.86.50
+95.38.86.51
+95.38.86.52
+95.38.86.53
+95.38.86.54
+95.38.86.55
+95.38.86.56
+95.38.86.59
+95.38.86.60
+95.38.86.61
+95.38.86.62
+95.38.89.16
+95.38.89.17
+95.38.89.18
+95.38.89.19
+95.38.89.21
+95.38.89.77
+95.38.89.78
+95.38.89.80
+95.38.89.90
+95.38.89.95
+95.38.89.107
+95.38.89.112
+95.38.89.192
+95.38.89.199
+95.38.94.14
+95.38.94.21
+95.38.94.218
+95.38.96.230
+95.38.99.146
+95.38.102.89
+95.38.103.70
+95.38.103.218
+95.38.103.254
+95.38.105.66
+95.38.105.71
+95.38.105.122
+95.38.106.146
+95.38.123.254
+95.38.130.108
+95.38.131.28
+95.38.131.44
+95.38.131.59
+95.38.131.81
+95.38.131.93
+95.38.131.95
+95.38.131.110
+95.38.131.143
+95.38.131.144
+95.38.131.159
+95.38.131.163
+95.38.131.194
+95.38.131.199
+95.38.131.216
+95.38.131.243
+95.38.131.247
+95.38.131.248
+95.38.134.24
+95.38.134.26
+95.38.134.50
+95.38.134.85
+95.38.134.190
+95.38.134.202
+95.38.135.12
+95.38.135.140
+95.38.138.38
+95.38.138.154
+95.38.138.174
+95.38.138.202
+95.38.142.34
+95.38.142.62
+95.38.144.16
+95.38.144.17
+95.38.144.26
+95.38.144.41
+95.38.144.127
+95.38.144.158
+95.38.144.178
+95.38.144.203
+95.38.145.12
+95.38.145.68
+95.38.145.73
+95.38.145.74
+95.38.145.78
+95.38.145.95
+95.38.146.86
+95.38.146.202
+95.38.146.217
+95.38.147.86
+95.38.147.133
+95.38.147.134
+95.38.147.190
+95.38.148.15
+95.38.148.59
+95.38.148.163
+95.38.148.171
+95.38.148.198
+95.38.149.2
+95.38.149.176
+95.38.153.226
+95.38.155.50
+95.38.155.74
+95.38.156.45
+95.38.156.53
+95.38.156.56
+95.38.156.60
+95.38.157.90
+95.38.157.120
+95.38.159.194
+95.38.159.254
+95.38.169.118
+95.38.169.154
+95.38.169.202
+95.38.169.222
+95.38.170.16
+95.38.170.17
+95.38.174.38
+95.38.174.65
+95.38.174.81
+95.38.174.83
+95.38.174.85
+95.38.174.87
+95.38.174.106
+95.38.174.226
+95.38.192.99
+95.38.192.140
+95.38.192.167
+95.38.192.183
+95.38.196.129
+95.38.196.134
+95.38.196.190
+95.38.196.216
+95.38.197.134
+95.38.197.254
+95.38.199.0
+95.38.199.10
+95.38.199.18
+95.38.201.30
+95.38.201.114
+95.38.201.201
+95.38.201.211
+95.38.203.178
+95.38.209.226
+95.38.209.227
+95.38.209.229
+95.38.209.230
+95.38.209.231
+95.38.209.232
+95.38.209.233
+95.38.209.234
+95.38.209.235
+95.38.211.243
+95.38.211.250
+95.38.224.86
+95.38.224.151
+95.38.224.202
+95.38.224.218
+95.38.241.65
+95.38.243.46
+95.38.243.250
+95.38.244.50
+95.38.244.114
+95.38.244.115
+95.38.244.120
+95.38.244.121
+95.38.244.122
+95.38.244.124
+95.38.244.126
+95.38.245.14
+95.38.245.33
+95.38.245.58
+95.38.245.62
+95.38.245.146
+95.38.245.147
+95.38.245.148
+95.38.245.149
+95.38.245.150
+95.38.246.19
+95.38.248.184
+95.38.248.194
+95.38.248.246
+95.38.248.250
+95.38.250.184
+95.38.250.195
+95.38.250.230
+95.80.140.2
+95.80.140.26
+95.80.140.32
+95.80.140.53
+95.80.140.64
+95.80.140.80
+95.80.140.91
+95.80.140.92
+95.80.140.110
+95.80.140.126
+95.80.140.159
+95.80.140.162
+95.80.140.205
+95.80.140.210
+95.80.140.229
+95.80.140.233
+95.80.140.238
+95.80.141.2
+95.80.141.12
+95.80.141.15
+95.80.141.18
+95.80.141.37
+95.80.141.48
+95.80.141.71
+95.80.141.74
+95.80.141.81
+95.80.141.84
+95.80.141.103
+95.80.141.110
+95.80.141.112
+95.80.141.117
+95.80.141.124
+95.80.141.142
+95.80.141.150
+95.80.141.151
+95.80.141.162
+95.80.141.167
+95.80.141.176
+95.80.141.190
+95.80.141.214
+95.80.141.220
+95.80.141.238
+95.80.141.253
+95.80.142.4
+95.80.142.9
+95.80.142.29
+95.80.142.33
+95.80.142.42
+95.80.142.54
+95.80.142.57
+95.80.142.81
+95.80.142.96
+95.80.142.102
+95.80.142.106
+95.80.142.117
+95.80.142.124
+95.80.142.140
+95.80.142.150
+95.80.142.167
+95.80.142.177
+95.80.142.199
+95.80.142.217
+95.80.142.224
+95.80.142.228
+95.80.142.244
+95.80.142.248
+95.80.143.1
+95.80.143.11
+95.80.143.28
+95.80.143.31
+95.80.143.45
+95.80.143.82
+95.80.143.83
+95.80.143.119
+95.80.143.134
+95.80.143.137
+95.80.143.138
+95.80.143.151
+95.80.143.160
+95.80.143.163
+95.80.143.169
+95.80.143.183
+95.80.143.198
+95.80.143.224
+95.80.157.65
+95.80.159.242
+95.80.160.58
+95.80.160.66
+95.80.160.180
+95.80.161.130
+95.80.168.12
+95.80.168.22
+95.80.168.56
+95.80.168.63
+95.80.168.69
+95.80.168.90
+95.80.168.115
+95.80.168.151
+95.80.168.161
+95.80.168.194
+95.80.168.203
+95.80.168.221
+95.80.168.233
+95.80.169.1
+95.80.169.8
+95.80.169.14
+95.80.169.20
+95.80.169.48
+95.80.169.61
+95.80.169.62
+95.80.169.78
+95.80.169.101
+95.80.169.131
+95.80.169.138
+95.80.169.152
+95.80.169.177
+95.80.169.185
+95.80.169.190
+95.80.169.191
+95.80.169.198
+95.80.169.215
+95.80.170.4
+95.80.170.24
+95.80.170.25
+95.80.170.36
+95.80.170.42
+95.80.170.53
+95.80.170.81
+95.80.170.95
+95.80.170.104
+95.80.170.125
+95.80.170.133
+95.80.170.134
+95.80.170.142
+95.80.170.167
+95.80.170.176
+95.80.170.180
+95.80.170.225
+95.80.170.251
+95.80.171.12
+95.80.171.23
+95.80.171.32
+95.80.171.93
+95.80.171.94
+95.80.171.113
+95.80.171.122
+95.80.171.141
+95.80.171.168
+95.80.171.197
+95.80.171.216
+95.80.171.249
+95.80.172.18
+95.80.172.36
+95.80.172.55
+95.80.172.88
+95.80.172.123
+95.80.172.128
+95.80.172.138
+95.80.172.140
+95.80.172.157
+95.80.172.165
+95.80.172.191
+95.80.172.222
+95.80.172.242
+95.80.172.248
+95.80.172.250
+95.80.173.89
+95.80.173.99
+95.80.173.137
+95.80.173.141
+95.80.173.146
+95.80.173.156
+95.80.173.158
+95.80.173.168
+95.80.173.228
+95.80.173.236
+95.80.173.244
+95.80.173.253
+95.80.174.2
+95.80.174.3
+95.80.174.12
+95.80.174.19
+95.80.174.83
+95.80.174.100
+95.80.174.109
+95.80.174.152
+95.80.174.160
+95.80.174.180
+95.80.174.181
+95.80.174.187
+95.80.174.191
+95.80.174.196
+95.80.174.200
+95.80.174.214
+95.80.174.222
+95.80.174.229
+95.80.174.237
+95.80.175.21
+95.80.175.25
+95.80.175.33
+95.80.175.34
+95.80.175.57
+95.80.175.64
+95.80.175.93
+95.80.175.99
+95.80.175.127
+95.80.175.167
+95.80.175.184
+95.80.175.205
+95.80.175.228
+95.80.175.235
+95.80.190.10
+95.80.190.11
+95.130.56.214
+95.130.58.25
+95.130.58.40
+95.130.60.34
+95.130.62.46
+95.130.225.12
+95.130.225.65
+95.141.39.218
+95.142.226.13
+95.142.237.244
+95.156.236.25
+95.156.236.27
+95.156.236.58
+95.156.236.59
+95.156.236.60
+95.156.253.34
+95.156.253.51
+95.215.59.140
+95.215.160.1
+95.215.160.22
+95.215.160.62
+95.215.160.108
+95.215.160.126
+95.215.160.157
+95.215.160.195
+95.215.160.217
+95.215.160.223
+95.215.161.106
+95.215.161.125
+95.215.161.137
+95.215.161.187
+95.215.161.231
+95.215.161.233
+95.215.161.246
+102.133.234.155
+102.215.240.26
+102.215.240.45
+102.215.240.66
+102.215.240.72
+102.215.240.74
+102.215.240.81
+102.215.240.120
+102.215.240.121
+102.215.240.216
+102.215.242.125
+102.215.242.149
+102.215.242.182
+102.215.243.18
+102.215.243.98
+103.46.211.146
+103.53.18.115
+103.53.19.201
+103.53.25.216
+103.53.27.90
+103.53.27.208
+103.130.146.35
+103.130.146.36
+103.130.146.37
+103.130.146.43
+103.130.146.195
+103.130.146.198
+103.130.146.206
+103.130.146.235
+103.130.146.238
+103.213.107.241
+103.215.220.216
+103.215.223.64
+103.215.223.91
+103.216.61.171
+103.216.63.202
+103.216.63.203
+103.216.63.204
+103.231.136.0
+103.231.136.255
+103.231.137.0
+103.231.137.255
+103.231.138.0
+103.231.138.1
+103.231.139.0
+103.231.139.255
+109.70.237.25
+109.70.237.44
+109.70.237.50
+109.70.237.67
+109.70.237.94
+109.70.237.118
+109.70.237.123
+109.70.237.137
+109.70.237.177
+109.70.237.207
+109.70.237.233
+109.70.237.235
+109.70.237.245
+109.72.195.128
+109.72.195.139
+109.72.195.159
+109.72.195.161
+109.72.195.178
+109.72.195.184
+109.72.195.188
+109.72.195.192
+109.72.195.203
+109.72.195.211
+109.72.195.221
+109.72.195.223
+109.72.195.225
+109.72.195.226
+109.72.195.230
+109.72.195.234
+109.72.195.237
+109.72.195.239
+109.72.195.243
+109.72.195.251
+109.72.195.255
+109.72.201.9
+109.72.201.14
+109.72.201.17
+109.72.201.29
+109.72.201.36
+109.72.201.44
+109.72.201.47
+109.72.201.51
+109.72.201.54
+109.72.201.61
+109.72.201.65
+109.72.201.66
+109.72.201.73
+109.72.201.80
+109.72.201.81
+109.72.201.84
+109.72.201.87
+109.72.201.115
+109.72.201.125
+109.72.201.127
+109.72.201.128
+109.72.201.154
+109.72.201.155
+109.72.201.163
+109.72.201.167
+109.72.201.183
+109.72.201.187
+109.72.201.193
+109.72.201.216
+109.72.201.223
+109.72.201.231
+109.72.201.239
+109.72.201.242
+109.74.226.188
+109.74.228.195
+109.74.230.245
+109.74.238.178
+109.94.164.100
+109.94.164.170
+109.95.60.4
+109.95.60.33
+109.95.60.38
+109.95.60.56
+109.95.60.57
+109.95.60.59
+109.95.60.61
+109.95.60.77
+109.95.60.97
+109.95.60.139
+109.95.60.149
+109.95.60.242
+109.95.60.255
+109.95.61.201
+109.95.61.204
+109.95.61.245
+109.95.61.254
+109.95.62.134
+109.95.63.192
+109.95.67.100
+109.95.71.25
+109.109.42.61
+109.109.43.186
+109.109.43.199
+109.109.46.76
+109.109.52.167
+109.109.54.104
+109.109.54.150
+109.109.55.91
+109.109.63.58
+109.122.227.126
+109.122.228.6
+109.122.228.152
+109.122.230.26
+109.122.231.102
+109.122.232.193
+109.122.233.36
+109.122.236.62
+109.122.238.53
+109.122.238.121
+109.122.240.4
+109.122.240.6
+109.122.240.16
+109.122.240.17
+109.122.240.19
+109.122.240.20
+109.122.240.22
+109.122.245.53
+109.122.245.58
+109.125.128.28
+109.125.128.59
+109.125.128.166
+109.125.128.236
+109.125.129.72
+109.125.129.84
+109.125.129.170
+109.125.129.226
+109.125.130.3
+109.125.130.50
+109.125.130.111
+109.125.130.176
+109.125.131.80
+109.125.131.90
+109.125.131.101
+109.125.131.136
+109.125.131.162
+109.125.132.73
+109.125.132.147
+109.125.132.154
+109.125.133.22
+109.125.133.102
+109.125.133.206
+109.125.134.30
+109.125.134.83
+109.125.134.87
+109.125.134.254
+109.125.135.50
+109.125.135.62
+109.125.135.160
+109.125.135.213
+109.125.136.12
+109.125.136.149
+109.125.136.234
+109.125.136.239
+109.125.137.32
+109.125.137.170
+109.125.137.212
+109.125.138.89
+109.125.140.57
+109.125.140.127
+109.125.140.150
+109.125.140.211
+109.125.141.45
+109.125.141.57
+109.125.141.67
+109.125.141.78
+109.125.141.148
+109.125.141.166
+109.125.141.235
+109.125.141.246
+109.125.142.212
+109.125.143.33
+109.125.144.51
+109.125.144.96
+109.125.144.143
+109.125.145.79
+109.125.145.97
+109.125.146.166
+109.125.146.173
+109.125.148.226
+109.125.160.3
+109.125.160.7
+109.125.160.9
+109.125.160.10
+109.125.160.65
+109.125.160.144
+109.125.160.147
+109.125.160.160
+109.125.160.176
+109.125.160.191
+109.125.160.205
+109.125.160.209
+109.125.160.226
+109.125.160.252
+109.125.168.1
+109.125.168.35
+109.125.168.41
+109.125.168.53
+109.125.168.83
+109.125.168.119
+109.125.168.126
+109.125.168.141
+109.125.168.218
+109.125.168.226
+109.125.168.234
+109.125.178.101
+109.125.191.2
+109.125.191.54
+109.162.128.193
+109.162.158.62
+109.162.158.111
+109.162.196.66
+109.162.196.138
+109.162.197.28
+109.162.197.65
+109.162.198.243
+109.162.230.136
+109.162.251.14
+109.162.251.43
+109.162.251.46
+109.162.251.110
+109.162.251.158
+109.201.0.17
+109.201.0.58
+109.201.2.81
+109.201.8.84
+109.201.8.85
+109.201.8.86
+109.201.13.186
+109.201.13.187
+109.201.13.189
+109.201.13.190
+109.201.15.10
+109.201.15.38
+109.201.15.86
+109.201.15.161
+109.201.17.57
+109.201.19.177
+109.201.19.213
+109.201.19.241
+109.201.19.244
+109.201.19.246
+109.201.23.6
+109.201.23.25
+109.201.23.41
+109.201.23.43
+109.201.23.48
+109.201.23.63
+109.201.23.77
+109.201.23.96
+109.201.23.138
+109.201.23.147
+109.201.23.195
+109.201.24.138
+109.201.24.194
+109.201.24.196
+109.201.27.79
+109.201.27.146
+109.206.254.122
+109.206.254.123
+109.206.254.124
+109.206.254.125
+109.206.254.126
+109.206.254.130
+109.230.72.32
+109.230.72.53
+109.230.72.63
+109.230.72.97
+109.230.72.98
+109.230.72.99
+109.230.72.110
+109.230.72.137
+109.230.72.145
+109.230.72.162
+109.230.72.172
+109.230.72.222
+109.230.72.224
+109.230.72.226
+109.230.72.227
+109.230.72.228
+109.230.72.231
+109.230.72.236
+109.230.72.242
+109.230.72.243
+109.230.72.245
+109.230.73.109
+109.230.73.151
+109.230.74.86
+109.230.74.105
+109.230.75.51
+109.230.77.76
+109.230.77.77
+109.230.77.78
+109.230.77.79
+109.230.78.3
+109.230.78.13
+109.230.78.86
+109.230.78.113
+109.230.78.114
+109.230.78.115
+109.230.78.116
+109.230.78.117
+109.230.78.118
+109.230.78.119
+109.230.78.120
+109.230.78.121
+109.230.78.122
+109.230.78.123
+109.230.78.124
+109.230.78.125
+109.230.78.126
+109.230.78.245
+109.230.79.1
+109.230.79.2
+109.230.79.4
+109.230.79.10
+109.230.79.198
+109.230.79.208
+109.230.79.248
+109.230.79.250
+109.230.79.251
+109.230.80.126
+109.230.80.186
+109.230.80.218
+109.230.80.219
+109.230.80.220
+109.230.80.221
+109.230.80.222
+109.230.80.242
+109.230.81.50
+109.230.81.54
+109.230.81.98
+109.230.81.102
+109.230.81.201
+109.230.82.70
+109.230.83.155
+109.230.83.210
+109.230.83.212
+109.230.83.214
+109.230.83.245
+109.230.88.22
+109.230.88.42
+109.230.88.226
+109.230.88.234
+109.230.88.235
+109.230.88.236
+109.230.88.237
+109.230.89.114
+109.230.89.115
+109.230.89.116
+109.230.89.118
+109.230.89.126
+109.230.89.139
+109.230.89.140
+109.230.89.154
+109.230.89.155
+109.230.89.156
+109.230.89.158
+109.230.89.210
+109.230.90.146
+109.230.90.238
+109.230.91.226
+109.230.91.227
+109.230.91.228
+109.230.92.98
+109.230.92.158
+109.230.92.166
+109.230.92.174
+109.230.92.178
+109.230.92.182
+109.230.92.242
+109.230.93.51
+109.230.93.82
+109.230.93.138
+109.230.93.206
+109.230.94.50
+109.230.94.130
+109.230.94.182
+109.230.95.62
+109.230.95.82
+109.230.95.194
+109.230.95.196
+109.230.95.208
+109.230.95.226
+109.230.95.234
+109.230.200.83
+109.230.200.84
+109.230.200.85
+109.230.204.64
+109.230.205.174
+109.230.221.18
+109.230.221.19
+109.230.221.20
+109.230.221.66
+109.230.221.67
+109.230.221.221
+109.230.221.225
+109.230.242.53
+109.230.242.90
+109.230.242.227
+109.232.0.34
+109.232.0.36
+109.232.0.76
+109.232.0.85
+109.232.0.248
+109.232.0.250
+109.232.0.251
+109.232.1.46
+109.232.1.84
+109.232.1.105
+109.232.1.145
+109.232.1.158
+109.232.1.255
+109.232.2.7
+109.232.2.13
+109.232.2.31
+109.232.2.44
+109.232.2.73
+109.232.2.74
+109.232.2.107
+109.232.2.227
+109.232.2.253
+109.232.2.255
+109.232.3.3
+109.232.3.10
+109.232.3.11
+109.232.3.87
+109.232.3.108
+109.232.3.128
+109.232.3.205
+109.232.4.34
+109.232.4.53
+109.232.4.54
+109.232.4.83
+109.238.181.9
+109.238.187.93
+109.238.187.241
+109.238.187.246
+109.238.188.49
+109.238.188.148
+109.238.188.149
+109.238.189.70
+109.238.190.41
+109.238.190.49
+109.238.190.93
+109.238.191.34
+109.238.191.225
+116.204.242.61
+116.204.242.63
+128.65.176.41
+128.65.176.57
+128.65.176.64
+128.65.176.82
+128.65.176.139
+128.65.176.154
+128.65.177.117
+128.65.177.254
+128.65.178.130
+128.65.178.172
+128.65.178.213
+128.65.179.52
+128.65.179.62
+128.65.179.126
+128.65.179.151
+128.65.179.177
+128.65.179.229
+128.65.179.252
+128.65.181.35
+128.65.181.50
+128.65.181.122
+128.65.181.167
+128.65.181.224
+128.65.181.247
+128.65.182.14
+128.65.182.27
+128.65.182.34
+128.65.182.87
+128.65.183.18
+128.65.183.128
+128.65.183.141
+128.65.183.144
+128.65.183.194
+128.65.184.36
+128.65.184.66
+128.65.184.84
+128.65.184.195
+128.65.184.207
+128.65.185.45
+128.65.185.82
+128.65.185.167
+128.65.185.227
+128.65.185.247
+128.65.186.99
+128.65.187.46
+128.65.188.23
+128.65.188.67
+128.65.188.113
+128.65.188.209
+128.65.189.162
+128.65.190.48
+128.65.190.182
+128.65.191.19
+130.185.72.101
+130.185.72.147
+130.185.72.188
+130.185.72.220
+130.185.72.222
+130.185.72.239
+130.185.73.133
+130.185.73.173
+130.185.73.202
+130.185.73.213
+130.185.74.10
+130.185.74.55
+130.185.74.182
+130.185.74.196
+130.185.74.200
+130.185.75.48
+130.185.75.161
+130.185.75.199
+130.185.76.29
+130.185.76.93
+130.185.76.98
+130.185.76.159
+130.185.76.167
+130.185.76.186
+130.185.76.222
+130.185.76.242
+130.185.77.163
+130.185.77.211
+130.185.77.223
+130.185.77.235
+130.185.78.32
+130.185.78.97
+130.193.77.3
+130.193.77.65
+130.193.77.72
+130.193.77.135
+130.193.77.200
+134.255.200.202
+134.255.201.90
+134.255.201.198
+134.255.206.5
+146.19.212.24
+146.19.212.29
+146.19.212.90
+146.19.212.125
+146.19.212.169
+146.19.212.189
+146.70.86.142
+149.54.11.98
+149.54.64.118
+151.232.1.192
+151.232.1.193
+151.232.1.194
+151.232.1.197
+151.232.1.198
+151.232.1.199
+151.232.1.201
+151.232.2.118
+151.232.3.162
+151.232.8.14
+151.232.8.80
+151.232.8.82
+151.232.8.84
+151.232.8.85
+151.232.8.87
+151.232.8.88
+151.232.8.89
+151.232.8.94
+151.232.9.3
+151.232.9.48
+151.232.9.64
+151.232.9.222
+151.232.17.161
+151.232.18.66
+151.232.18.69
+151.232.23.53
+151.232.36.11
+151.232.36.129
+151.232.37.137
+151.232.76.21
+151.232.76.142
+151.232.80.214
+151.232.81.227
+151.232.83.174
+151.232.83.205
+151.232.84.74
+151.232.87.195
+151.232.124.57
+151.232.130.87
+151.232.143.14
+151.232.143.214
+151.232.193.44
+151.232.195.120
+151.232.201.125
+151.232.202.148
+151.232.203.139
+151.232.207.162
+151.233.48.38
+151.233.48.61
+151.233.48.113
+151.233.49.80
+151.233.49.238
+151.233.50.9
+151.233.50.51
+151.233.50.57
+151.233.50.58
+151.233.50.82
+151.233.50.91
+151.233.50.158
+151.233.50.203
+151.233.50.251
+151.233.51.43
+151.233.51.64
+151.233.51.90
+151.233.51.169
+151.233.51.187
+151.233.51.192
+151.233.51.208
+151.233.51.223
+151.233.51.239
+151.233.52.97
+151.233.52.245
+151.233.52.255
+151.233.53.29
+151.233.53.53
+151.233.53.100
+151.233.53.106
+151.233.53.170
+151.233.53.226
+151.233.54.20
+151.233.54.44
+151.233.54.60
+151.233.54.65
+151.233.54.80
+151.233.54.182
+151.233.54.240
+151.233.55.15
+151.233.55.108
+151.233.55.125
+151.233.55.133
+151.233.55.149
+151.233.56.140
+151.233.56.149
+151.233.56.164
+151.233.57.7
+151.233.57.13
+151.233.57.89
+151.233.57.129
+151.233.57.151
+151.233.57.182
+151.233.57.255
+151.233.58.3
+151.233.58.16
+151.233.58.74
+151.233.58.92
+151.233.58.93
+151.233.58.227
+151.233.59.39
+151.233.59.136
+151.233.75.0
+151.233.76.239
+151.233.81.99
+151.233.89.126
+151.233.103.231
+151.233.144.2
+151.233.170.0
+151.233.172.5
+151.234.24.238
+151.234.25.204
+151.234.26.244
+151.234.27.0
+151.234.27.197
+151.234.29.147
+151.234.30.219
+151.234.30.223
+151.234.31.188
+151.234.31.191
+151.234.31.221
+151.234.72.89
+151.234.73.63
+151.234.73.92
+151.234.73.155
+151.234.75.100
+151.234.75.105
+151.234.77.38
+151.234.77.219
+151.234.87.1
+151.234.87.40
+151.234.87.114
+151.234.87.165
+151.234.87.194
+151.234.87.210
+151.234.87.211
+151.234.87.242
+151.234.92.135
+151.234.113.106
+151.234.115.64
+151.234.150.188
+151.234.151.114
+151.234.156.241
+151.234.157.118
+151.234.158.28
+151.234.158.113
+151.234.158.197
+151.234.161.54
+151.234.161.74
+151.234.161.176
+151.234.161.204
+151.234.161.224
+151.234.161.241
+151.234.161.242
+151.234.161.244
+151.234.186.191
+151.234.189.135
+151.234.191.195
+151.234.191.217
+151.234.213.48
+151.234.219.129
+151.234.225.130
+151.234.226.164
+151.234.242.190
+151.234.245.221
+151.234.249.4
+151.234.249.182
+151.234.249.224
+151.234.250.47
+151.234.251.59
+151.234.251.135
+151.235.0.146
+151.235.0.237
+151.235.5.101
+151.235.10.118
+151.235.10.218
+151.235.11.43
+151.235.11.227
+151.235.13.114
+151.235.13.222
+151.235.13.252
+151.235.17.25
+151.235.18.33
+151.235.18.73
+151.235.28.168
+151.235.29.252
+151.235.34.200
+151.235.34.224
+151.235.36.180
+151.235.37.161
+151.235.128.57
+151.235.128.147
+151.235.128.153
+151.235.129.153
+151.235.130.71
+151.235.133.10
+151.235.134.174
+151.235.135.50
+151.235.135.181
+151.235.135.186
+151.235.136.191
+151.235.136.230
+151.235.137.37
+151.235.138.46
+151.235.138.247
+151.235.140.42
+151.235.140.80
+151.235.140.246
+151.235.141.196
+151.235.142.241
+151.235.164.118
+151.235.165.6
+151.235.167.214
+151.235.169.72
+151.235.175.211
+151.235.180.120
+151.235.183.250
+151.235.186.159
+151.235.187.218
+151.235.188.185
+151.235.190.187
+151.235.190.205
+151.235.192.69
+151.235.193.122
+151.235.196.22
+151.235.197.125
+151.235.198.102
+151.235.201.56
+151.235.201.162
+151.235.204.31
+151.235.206.184
+151.235.208.44
+151.235.210.61
+151.235.210.73
+151.235.212.131
+151.235.213.71
+151.235.214.4
+151.235.215.175
+151.235.215.224
+151.235.216.23
+151.235.216.27
+151.235.217.215
+151.235.218.134
+151.235.220.179
+151.235.220.218
+151.235.221.71
+151.235.223.17
+151.235.224.240
+151.235.225.172
+151.235.227.237
+151.235.229.66
+151.235.229.140
+151.235.229.210
+151.235.232.49
+151.235.233.108
+151.235.233.146
+151.235.234.18
+151.235.234.38
+151.235.236.56
+151.235.236.152
+151.235.237.71
+151.235.237.171
+151.235.239.155
+151.235.239.169
+151.235.239.212
+151.235.240.147
+151.235.242.23
+151.235.243.133
+151.235.249.16
+151.235.250.210
+151.235.253.108
+151.235.253.221
+151.235.254.196
+151.235.255.118
+151.235.255.131
+151.238.184.86
+151.238.184.246
+151.238.185.102
+151.238.186.13
+151.238.186.173
+151.238.187.46
+151.238.187.116
+151.238.190.155
+151.238.190.165
+151.238.193.134
+151.238.193.178
+151.238.193.182
+151.238.194.110
+151.238.195.0
+151.238.195.35
+151.238.196.29
+151.238.196.207
+151.238.196.251
+151.238.197.123
+151.238.198.106
+151.238.198.134
+151.238.204.159
+151.238.205.88
+151.238.205.150
+151.238.207.135
+151.238.207.197
+151.238.208.237
+151.238.208.239
+151.238.209.137
+151.238.210.27
+151.238.210.154
+151.238.211.61
+151.238.212.194
+151.238.212.219
+151.238.213.21
+151.238.213.62
+151.238.213.99
+151.238.216.107
+151.238.218.31
+151.238.218.114
+151.238.220.172
+151.238.220.253
+151.238.222.203
+151.238.222.237
+151.238.223.235
+151.238.224.2
+151.238.225.244
+151.238.226.19
+151.238.232.186
+151.238.233.90
+151.238.234.231
+151.238.240.186
+151.238.242.23
+151.238.243.33
+151.238.244.103
+151.238.248.152
+151.238.248.203
+151.238.250.71
+151.238.251.250
+151.238.252.32
+151.238.252.162
+151.238.253.25
+151.238.253.54
+151.238.254.63
+151.238.254.142
+151.238.254.254
+151.238.255.176
+151.239.1.37
+151.239.1.66
+151.239.11.99
+151.239.11.159
+151.239.14.27
+151.239.14.73
+151.239.15.154
+151.239.15.226
+151.239.16.160
+151.239.17.80
+151.239.18.84
+151.239.18.137
+151.239.18.224
+151.239.19.56
+151.239.19.131
+151.239.19.178
+151.239.22.1
+151.239.22.42
+151.239.22.65
+151.239.24.135
+151.239.25.75
+151.239.25.111
+151.239.38.241
+151.239.39.41
+151.239.40.194
+151.239.40.206
+151.239.40.239
+151.239.42.33
+151.239.42.90
+151.239.43.114
+151.239.44.93
+151.239.44.204
+151.239.45.80
+151.239.45.162
+151.239.49.100
+151.239.51.84
+151.239.52.50
+151.239.52.84
+151.239.55.108
+151.239.57.23
+151.239.57.138
+151.239.57.141
+151.239.57.144
+151.239.59.104
+151.239.60.8
+151.239.60.48
+151.239.62.85
+151.239.63.111
+151.239.64.86
+151.239.64.154
+151.239.64.179
+151.239.66.174
+151.239.69.194
+151.239.72.162
+151.239.76.67
+151.239.76.69
+151.239.76.126
+151.239.77.139
+151.239.79.39
+151.239.79.85
+151.239.79.146
+151.239.87.78
+151.239.88.240
+151.239.89.88
+151.239.89.147
+151.239.89.152
+151.239.89.215
+151.239.91.162
+151.239.92.206
+151.239.94.229
+151.239.95.199
+151.239.96.66
+151.239.97.53
+151.239.98.194
+151.239.100.227
+151.239.103.11
+151.239.103.119
+151.239.104.254
+151.239.105.172
+151.239.105.228
+151.239.111.149
+151.239.112.50
+151.239.113.8
+151.239.113.218
+151.239.113.242
+151.239.114.86
+151.239.115.141
+151.239.116.70
+151.239.116.152
+151.239.117.135
+157.119.188.208
+157.119.188.209
+157.119.188.218
+157.119.191.243
+157.119.191.244
+157.119.191.249
+158.58.184.98
+158.58.185.43
+158.58.185.106
+158.58.185.170
+158.58.187.5
+158.58.187.21
+158.58.187.43
+158.58.187.140
+158.58.187.188
+158.58.188.22
+158.58.190.44
+158.255.74.7
+158.255.74.18
+158.255.74.28
+158.255.74.37
+158.255.74.92
+158.255.74.139
+158.255.74.161
+158.255.74.222
+158.255.74.227
+159.20.96.100
+159.20.102.234
+159.20.109.48
+160.187.18.5
+164.138.16.46
+164.138.16.181
+164.138.16.191
+164.138.17.234
+164.138.18.73
+164.138.19.203
+164.138.19.217
+164.138.19.218
+164.138.19.219
+164.138.19.220
+164.138.19.221
+164.138.20.154
+164.138.21.3
+164.138.22.115
+164.138.22.116
+164.138.128.0
+164.138.128.1
+164.138.128.2
+164.138.128.3
+164.138.128.7
+164.138.128.8
+164.138.203.1
+164.215.59.116
+165.101.26.38
+167.234.255.2
+171.22.24.19
+171.22.24.71
+171.22.24.99
+171.22.24.173
+171.22.24.213
+171.22.25.17
+171.22.25.38
+171.22.25.67
+171.22.25.74
+171.22.25.85
+171.22.25.184
+171.22.26.61
+171.22.26.65
+171.22.26.71
+171.22.26.213
+171.22.27.22
+171.22.27.105
+171.22.27.186
+176.10.95.144
+176.10.95.176
+176.10.95.225
+176.10.95.253
+176.65.176.61
+176.65.177.21
+176.65.177.237
+176.65.178.227
+176.65.180.244
+176.65.183.179
+176.65.184.237
+176.65.187.129
+176.65.191.87
+176.65.191.237
+176.65.232.19
+176.65.233.3
+176.65.238.47
+176.65.240.82
+176.65.240.83
+176.65.240.84
+176.65.240.85
+176.65.240.86
+176.65.240.88
+176.65.240.90
+176.65.240.91
+176.65.240.92
+176.65.240.93
+176.65.240.94
+176.65.240.130
+176.65.241.110
+176.65.241.163
+176.65.241.166
+176.65.241.194
+176.65.241.236
+176.65.242.68
+176.65.242.100
+176.65.242.130
+176.65.242.132
+176.65.243.55
+176.65.243.237
+176.65.243.245
+176.65.252.2
+176.65.252.15
+176.65.252.26
+176.65.252.29
+176.65.252.53
+176.65.252.60
+176.65.252.71
+176.65.252.72
+176.65.252.96
+176.65.252.116
+176.65.252.150
+176.65.252.198
+176.65.252.214
+176.65.252.243
+176.65.253.21
+176.65.253.32
+176.65.253.44
+176.65.253.49
+176.65.253.69
+176.65.253.87
+176.65.253.132
+176.65.253.135
+176.65.253.149
+176.65.253.205
+176.65.253.240
+176.65.253.241
+176.65.253.242
+176.65.253.243
+176.65.253.244
+176.65.253.245
+176.65.253.246
+176.65.253.255
+176.65.254.50
+176.65.254.80
+176.65.254.85
+176.65.254.86
+176.65.254.120
+176.65.254.121
+176.65.254.130
+176.65.254.162
+176.65.254.202
+176.65.254.212
+176.65.254.239
+176.65.254.241
+176.97.218.20
+176.97.218.22
+176.97.218.39
+176.97.218.55
+176.97.218.184
+176.97.220.65
+176.97.220.149
+176.101.32.2
+176.101.32.62
+176.101.32.90
+176.101.32.98
+176.101.32.146
+176.101.32.200
+176.101.33.190
+176.101.33.214
+176.101.48.250
+176.102.224.50
+176.102.233.11
+176.102.233.253
+176.102.240.123
+176.102.240.200
+176.102.251.1
+176.102.253.1
+176.120.16.220
+176.120.16.242
+176.122.210.1
+176.122.210.5
+176.122.210.9
+176.122.210.13
+176.122.210.17
+176.122.210.21
+176.122.210.25
+176.122.210.29
+176.122.210.34
+176.122.210.37
+176.122.210.40
+176.122.210.41
+176.122.210.42
+176.122.210.43
+176.122.210.44
+176.122.210.45
+176.122.210.46
+176.122.210.57
+176.122.210.89
+176.122.210.97
+176.122.210.101
+176.122.210.190
+176.122.211.0
+176.122.211.48
+176.122.211.255
+176.221.66.2
+176.221.66.9
+178.21.161.14
+178.21.161.139
+178.21.163.54
+178.21.163.66
+178.21.163.83
+178.21.163.84
+178.21.163.85
+178.21.164.176
+178.21.164.177
+178.22.121.211
+178.22.121.213
+178.22.121.254
+178.22.122.102
+178.22.122.246
+178.22.122.250
+178.22.122.253
+178.22.123.6
+178.22.126.90
+178.131.9.23
+178.131.16.8
+178.131.17.162
+178.131.17.214
+178.131.18.13
+178.131.18.63
+178.131.19.140
+178.131.19.192
+178.131.20.57
+178.131.20.111
+178.131.20.156
+178.131.20.180
+178.131.23.33
+178.131.28.7
+178.131.30.3
+178.131.30.244
+178.131.40.9
+178.131.40.56
+178.131.40.83
+178.131.41.99
+178.131.41.212
+178.131.42.225
+178.131.42.254
+178.131.43.32
+178.131.43.78
+178.131.44.3
+178.131.44.142
+178.131.46.16
+178.131.47.218
+178.131.47.220
+178.131.48.19
+178.131.49.249
+178.131.50.56
+178.131.50.203
+178.131.51.39
+178.131.54.56
+178.131.55.72
+178.131.57.93
+178.131.59.45
+178.131.59.80
+178.131.61.47
+178.131.62.127
+178.131.63.36
+178.131.63.166
+178.131.63.182
+178.131.63.206
+178.131.64.50
+178.131.64.66
+178.131.65.18
+178.131.65.111
+178.131.65.232
+178.131.66.192
+178.131.67.252
+178.131.68.20
+178.131.68.123
+178.131.69.104
+178.131.69.213
+178.131.70.80
+178.131.71.200
+178.131.73.105
+178.131.73.211
+178.131.74.27
+178.131.74.97
+178.131.76.7
+178.131.77.156
+178.131.77.251
+178.131.78.185
+178.131.78.222
+178.131.78.227
+178.131.79.133
+178.131.79.169
+178.131.80.5
+178.131.80.23
+178.131.80.41
+178.131.82.47
+178.131.83.57
+178.131.84.118
+178.131.85.103
+178.131.86.77
+178.131.86.133
+178.131.86.141
+178.131.87.166
+178.131.87.170
+178.131.88.87
+178.131.88.156
+178.131.89.205
+178.131.89.249
+178.131.90.103
+178.131.93.109
+178.131.93.112
+178.131.93.188
+178.131.93.195
+178.131.93.205
+178.131.102.148
+178.131.105.110
+178.131.107.34
+178.131.108.6
+178.131.109.241
+178.131.110.99
+178.131.111.49
+178.131.114.21
+178.131.115.48
+178.131.116.190
+178.131.125.33
+178.131.126.12
+178.131.133.113
+178.131.140.116
+178.131.142.33
+178.131.142.190
+178.131.145.1
+178.131.157.34
+178.131.165.18
+178.131.172.252
+178.131.177.36
+178.131.180.73
+178.131.181.136
+178.131.181.227
+178.131.182.149
+178.131.182.155
+178.131.183.122
+178.131.183.130
+178.131.190.216
+178.131.190.237
+178.157.0.86
+178.157.0.113
+178.157.0.140
+178.157.0.144
+178.157.0.166
+178.173.128.88
+178.173.130.10
+178.173.130.36
+178.173.131.93
+178.173.131.128
+178.173.132.25
+178.173.132.37
+178.173.132.86
+178.173.132.104
+178.173.132.114
+178.173.132.117
+178.173.134.42
+178.173.134.57
+178.173.134.72
+178.173.134.183
+178.173.134.236
+178.173.134.239
+178.173.137.96
+178.173.137.140
+178.173.137.176
+178.173.137.192
+178.173.137.215
+178.173.137.231
+178.173.138.53
+178.173.138.169
+178.173.138.235
+178.173.138.252
+178.173.139.11
+178.173.139.49
+178.173.139.120
+178.173.139.149
+178.173.139.171
+178.173.139.173
+178.173.139.237
+178.173.140.148
+178.173.140.161
+178.173.140.250
+178.173.141.63
+178.173.141.83
+178.173.141.147
+178.173.141.158
+178.173.141.194
+178.173.141.244
+178.173.142.5
+178.173.142.37
+178.173.142.68
+178.173.142.134
+178.173.142.159
+178.173.142.173
+178.173.142.206
+178.173.142.210
+178.173.142.219
+178.173.143.29
+178.173.143.50
+178.173.143.112
+178.173.143.150
+178.173.143.209
+178.173.144.45
+178.173.144.59
+178.173.144.71
+178.173.144.149
+178.173.144.175
+178.173.144.240
+178.173.145.17
+178.173.145.83
+178.173.145.149
+178.173.145.217
+178.173.147.25
+178.173.147.43
+178.173.147.58
+178.173.147.132
+178.173.147.133
+178.173.147.149
+178.173.147.169
+178.173.147.238
+178.173.147.240
+178.173.147.242
+178.173.148.20
+178.173.148.128
+178.173.148.129
+178.173.148.130
+178.173.148.140
+178.173.148.142
+178.173.148.143
+178.173.148.145
+178.173.148.240
+178.173.149.21
+178.173.149.36
+178.173.149.210
+178.173.149.213
+178.173.149.247
+178.173.149.249
+178.173.151.94
+178.173.151.166
+178.173.151.211
+178.173.151.226
+178.173.160.70
+178.173.163.66
+178.173.163.67
+178.173.163.77
+178.173.163.85
+178.173.163.117
+178.173.163.166
+178.173.163.196
+178.173.163.216
+178.173.163.217
+178.173.163.233
+178.173.169.12
+178.173.169.100
+178.173.169.125
+178.173.169.150
+178.173.169.179
+178.173.169.203
+178.173.170.42
+178.173.170.68
+178.173.170.124
+178.173.170.222
+178.173.170.250
+178.173.171.58
+178.173.171.242
+178.173.171.243
+178.173.171.244
+178.173.171.245
+178.173.171.246
+178.173.171.247
+178.173.171.248
+178.173.171.250
+178.173.171.251
+178.173.172.10
+178.173.172.71
+178.173.172.74
+178.173.172.241
+178.173.172.243
+178.173.172.245
+178.173.172.247
+178.173.172.252
+178.173.174.145
+178.173.174.182
+178.173.174.240
+178.173.175.47
+178.173.175.84
+178.173.175.90
+178.173.175.91
+178.173.175.156
+178.173.175.199
+178.173.175.227
+178.173.182.27
+178.173.182.40
+178.173.182.48
+178.173.182.128
+178.173.182.186
+178.173.182.213
+178.173.182.249
+178.173.183.19
+178.173.183.81
+178.173.183.168
+178.173.183.233
+178.173.184.106
+178.173.184.232
+178.173.186.80
+178.173.186.121
+178.173.186.157
+178.173.186.186
+178.173.186.229
+178.173.186.253
+178.173.187.45
+178.173.187.47
+178.173.187.62
+178.173.187.92
+178.173.187.115
+178.173.187.122
+178.173.187.164
+178.173.187.179
+178.173.187.182
+178.173.187.223
+178.173.188.9
+178.173.188.128
+178.173.188.133
+178.173.188.191
+178.173.188.207
+178.173.188.240
+178.173.189.15
+178.173.189.35
+178.173.189.43
+178.173.189.78
+178.173.189.133
+178.173.189.141
+178.173.189.189
+178.173.189.207
+178.173.189.213
+178.173.189.247
+178.173.190.62
+178.173.190.222
+178.173.190.244
+178.173.191.3
+178.173.191.149
+178.173.192.32
+178.173.192.122
+178.173.192.139
+178.173.192.146
+178.173.192.169
+178.173.193.10
+178.173.193.45
+178.173.193.78
+178.173.193.84
+178.173.193.139
+178.173.193.144
+178.173.195.24
+178.173.195.52
+178.173.195.60
+178.173.195.70
+178.173.195.86
+178.173.195.123
+178.173.195.138
+178.173.195.163
+178.173.195.170
+178.173.195.188
+178.173.195.195
+178.173.195.243
+178.173.196.45
+178.173.196.164
+178.173.196.212
+178.173.197.82
+178.173.197.132
+178.173.198.3
+178.173.198.16
+178.173.198.25
+178.173.198.39
+178.173.198.237
+178.173.198.246
+178.173.199.48
+178.173.199.76
+178.173.199.162
+178.173.200.44
+178.173.200.72
+178.173.200.107
+178.173.200.212
+178.173.210.128
+178.173.210.212
+178.173.210.249
+178.173.211.22
+178.173.211.33
+178.173.211.80
+178.173.211.164
+178.173.211.177
+178.173.211.240
+178.173.212.39
+178.173.212.168
+178.173.212.169
+178.173.212.171
+178.173.212.203
+178.173.213.48
+178.173.213.51
+178.173.213.112
+178.173.213.217
+178.173.214.85
+178.173.214.152
+178.173.214.172
+178.173.214.250
+178.173.215.25
+178.173.215.57
+178.173.215.89
+178.173.215.92
+178.173.215.166
+178.173.215.168
+178.173.215.212
+178.173.215.236
+178.173.216.34
+178.173.216.40
+178.173.216.131
+178.173.216.159
+178.173.216.190
+178.173.217.29
+178.173.217.145
+178.173.217.253
+178.173.218.29
+178.173.218.35
+178.173.218.64
+178.173.218.107
+178.173.218.214
+178.173.218.220
+178.173.219.10
+178.173.219.128
+178.173.219.229
+178.173.219.242
+178.173.219.251
+178.173.220.55
+178.173.220.103
+178.173.220.146
+178.173.220.160
+178.173.220.161
+178.173.220.215
+178.173.221.2
+178.173.221.9
+178.173.221.46
+178.173.221.125
+178.173.221.195
+178.173.222.2
+178.173.222.3
+178.173.222.177
+178.173.222.200
+178.173.222.206
+178.216.248.235
+178.216.248.236
+178.216.248.237
+178.216.249.213
+178.216.250.190
+178.216.251.236
+178.216.251.237
+178.216.251.238
+178.236.33.129
+178.236.33.161
+178.236.100.59
+178.236.104.48
+178.236.104.118
+178.236.104.192
+178.236.104.240
+178.236.105.223
+178.236.106.91
+178.236.106.227
+178.236.107.71
+178.236.108.175
+178.236.109.34
+178.236.109.97
+178.238.192.60
+178.238.192.112
+178.238.192.166
+178.238.193.205
+178.238.194.22
+178.238.194.118
+178.238.194.139
+178.238.195.99
+178.238.195.240
+178.238.197.73
+178.238.199.3
+178.239.144.129
+178.239.147.133
+178.239.151.4
+178.239.151.49
+178.239.151.80
+178.239.151.94
+178.239.151.158
+178.239.151.229
+178.239.152.57
+178.239.152.145
+178.239.152.150
+178.239.152.160
+178.239.152.179
+178.239.152.184
+178.239.156.1
+178.239.156.5
+178.239.156.56
+178.239.156.61
+178.239.156.67
+178.239.156.126
+178.239.158.66
+178.239.158.129
+178.239.159.73
+178.239.159.160
+178.239.159.255
+178.252.129.30
+178.252.132.125
+178.252.132.217
+178.252.132.218
+178.252.132.222
+178.252.132.228
+178.252.133.85
+178.252.133.222
+178.252.134.178
+178.252.134.213
+178.252.134.229
+178.252.134.238
+178.252.135.2
+178.252.135.26
+178.252.135.53
+178.252.135.54
+178.252.135.117
+178.252.135.196
+178.252.135.202
+178.252.135.206
+178.252.136.2
+178.252.136.18
+178.252.136.130
+178.252.136.132
+178.252.136.133
+178.252.136.250
+178.252.140.98
+178.252.140.99
+178.252.140.104
+178.252.140.107
+178.252.141.50
+178.252.141.134
+178.252.141.226
+178.252.142.78
+178.252.143.22
+178.252.143.99
+178.252.143.102
+178.252.143.234
+178.252.144.18
+178.252.144.58
+178.252.144.102
+178.252.144.240
+178.252.147.35
+178.252.147.54
+178.252.147.65
+178.252.147.82
+178.252.147.83
+178.252.147.84
+178.252.147.85
+178.252.147.86
+178.252.147.122
+178.252.147.123
+178.252.147.124
+178.252.147.146
+178.252.147.148
+178.252.147.150
+178.252.147.154
+178.252.147.186
+178.252.147.187
+178.252.147.188
+178.252.147.189
+178.252.148.204
+178.252.149.202
+178.252.151.18
+178.252.151.22
+178.252.151.42
+178.252.151.43
+178.252.151.44
+178.252.151.46
+178.252.151.154
+178.252.151.162
+178.252.151.238
+178.252.151.250
+178.252.151.251
+178.252.152.56
+178.252.152.57
+178.252.152.58
+178.252.152.61
+178.252.152.62
+178.252.153.106
+178.252.153.122
+178.252.165.24
+178.252.165.82
+178.252.165.83
+178.252.165.84
+178.252.165.85
+178.252.165.102
+178.252.165.118
+178.252.165.193
+178.252.165.230
+178.252.166.10
+178.252.166.98
+178.252.166.153
+178.252.166.182
+178.252.167.51
+178.252.167.90
+178.252.170.106
+178.252.170.166
+178.252.170.222
+178.252.171.70
+178.252.171.74
+178.252.171.226
+178.252.171.228
+178.252.171.229
+178.252.171.234
+178.252.176.10
+178.252.176.68
+178.252.176.115
+178.252.176.130
+178.252.176.131
+178.252.176.146
+178.252.177.6
+178.252.177.8
+178.252.177.10
+178.252.177.12
+178.252.177.170
+178.252.178.205
+178.252.178.209
+178.252.178.210
+178.252.178.222
+178.252.183.28
+178.252.183.99
+178.252.183.250
+178.252.183.251
+178.252.183.252
+178.252.183.253
+178.252.183.254
+178.252.184.70
+178.252.184.138
+178.252.184.139
+178.252.184.141
+178.252.184.154
+178.252.189.82
+178.252.189.83
+178.252.189.84
+178.252.189.213
+178.252.189.214
+178.252.191.19
+178.252.191.163
+178.252.191.164
+178.252.191.169
+180.94.70.74
+180.94.91.170
+185.2.14.94
+185.2.14.253
+185.3.124.62
+185.3.124.83
+185.3.124.85
+185.3.124.86
+185.3.125.2
+185.3.125.3
+185.3.125.4
+185.3.125.87
+185.3.125.144
+185.3.201.197
+185.3.202.42
+185.3.202.57
+185.3.203.19
+185.3.203.77
+185.3.203.84
+185.3.203.85
+185.3.203.91
+185.3.212.76
+185.3.212.141
+185.3.213.61
+185.3.215.200
+185.3.215.226
+185.4.1.24
+185.4.1.25
+185.4.1.45
+185.4.1.96
+185.4.3.2
+185.4.3.73
+185.4.30.6
+185.4.30.46
+185.4.30.58
+185.4.30.72
+185.4.30.100
+185.7.172.1
+185.7.172.2
+185.7.172.7
+185.7.172.17
+185.7.172.33
+185.7.172.49
+185.7.172.65
+185.7.172.81
+185.7.172.97
+185.7.172.113
+185.7.172.129
+185.7.172.145
+185.7.212.35
+185.7.212.89
+185.7.212.133
+185.7.212.150
+185.8.172.49
+185.8.172.207
+185.8.173.27
+185.8.173.91
+185.8.174.13
+185.8.174.184
+185.8.174.207
+185.8.175.44
+185.8.175.153
+185.8.175.187
+185.8.175.229
+185.8.175.241
+185.8.175.249
+185.10.71.235
+185.10.72.124
+185.10.74.112
+185.10.74.234
+185.10.75.77
+185.10.75.108
+185.10.75.113
+185.10.75.119
+185.10.75.121
+185.10.75.196
+185.11.69.55
+185.11.69.56
+185.11.69.148
+185.11.69.150
+185.11.69.174
+185.11.70.18
+185.11.70.55
+185.11.70.211
+185.11.70.217
+185.11.70.230
+185.11.70.233
+185.11.71.169
+185.13.229.253
+185.13.229.254
+185.13.230.46
+185.13.230.116
+185.13.230.155
+185.13.230.158
+185.13.231.49
+185.14.81.252
+185.14.161.36
+185.14.161.67
+185.14.161.82
+185.14.161.84
+185.14.161.85
+185.14.162.5
+185.14.162.18
+185.14.163.162
+185.14.163.163
+185.14.163.164
+185.14.163.165
+185.14.163.166
+185.14.163.167
+185.14.163.168
+185.14.163.169
+185.14.163.170
+185.14.163.171
+185.14.163.172
+185.14.163.174
+185.14.163.210
+185.14.163.234
+185.14.163.235
+185.18.212.67
+185.18.213.26
+185.18.213.47
+185.18.213.67
+185.18.213.76
+185.18.213.98
+185.18.213.180
+185.18.214.4
+185.18.214.120
+185.18.214.138
+185.18.214.244
+185.18.215.26
+185.18.215.36
+185.18.215.38
+185.18.215.90
+185.18.215.208
+185.18.215.240
+185.19.201.102
+185.19.201.188
+185.19.201.193
+185.19.201.199
+185.21.68.53
+185.21.70.41
+185.21.70.233
+185.21.71.46
+185.21.71.199
+185.21.71.216
+185.21.71.246
+185.22.30.174
+185.22.31.226
+185.22.31.227
+185.23.128.147
+185.23.128.148
+185.24.252.43
+185.24.252.65
+185.24.252.76
+185.24.252.111
+185.24.252.115
+185.24.252.129
+185.24.252.242
+185.24.252.250
+185.24.253.1
+185.24.253.8
+185.24.253.48
+185.24.253.65
+185.24.253.96
+185.24.253.120
+185.24.253.129
+185.24.255.109
+185.24.255.115
+185.24.255.161
+185.24.255.169
+185.24.255.187
+185.26.33.213
+185.26.34.227
+185.26.35.47
+185.26.35.242
+185.26.235.53
+185.29.223.233
+185.33.25.86
+185.36.228.170
+185.36.231.37
+185.36.231.53
+185.36.231.140
+185.37.53.144
+185.37.53.146
+185.37.53.147
+185.37.53.148
+185.37.53.149
+185.37.53.150
+185.37.54.10
+185.37.54.186
+185.39.181.6
+185.39.181.17
+185.39.181.21
+185.39.181.23
+185.39.181.92
+185.39.181.110
+185.39.181.142
+185.39.181.179
+185.39.181.229
+185.39.181.243
+185.39.182.34
+185.39.183.157
+185.41.3.5
+185.42.224.170
+185.42.225.68
+185.42.225.74
+185.42.225.90
+185.42.225.196
+185.42.225.199
+185.42.226.26
+185.42.226.27
+185.42.226.28
+185.42.226.30
+185.42.227.93
+185.42.227.94
+185.42.227.238
+185.44.36.3
+185.44.36.30
+185.44.36.50
+185.44.36.193
+185.44.112.13
+185.44.112.170
+185.44.112.206
+185.44.114.153
+185.46.109.0
+185.46.109.2
+185.46.109.10
+185.46.109.123
+185.46.109.126
+185.46.109.127
+185.46.109.130
+185.46.109.131
+185.46.109.146
+185.46.109.149
+185.46.109.151
+185.46.109.161
+185.46.109.167
+185.46.109.172
+185.46.109.175
+185.46.109.179
+185.46.110.92
+185.46.110.122
+185.46.111.43
+185.46.111.45
+185.46.111.74
+185.46.111.106
+185.46.111.219
+185.46.111.228
+185.46.111.231
+185.46.217.105
+185.46.218.77
+185.46.218.127
+185.46.218.198
+185.46.219.18
+185.46.219.87
+185.46.219.126
+185.46.219.220
+185.47.48.6
+185.47.48.10
+185.47.48.13
+185.47.48.14
+185.47.48.131
+185.47.48.178
+185.47.48.201
+185.47.48.225
+185.47.48.253
+185.47.48.254
+185.47.49.46
+185.47.49.53
+185.47.49.89
+185.47.49.127
+185.47.49.138
+185.47.49.168
+185.47.49.172
+185.47.49.226
+185.47.49.229
+185.47.49.245
+185.47.49.252
+185.47.50.62
+185.47.50.95
+185.47.50.238
+185.47.51.2
+185.47.51.201
+185.49.84.122
+185.49.84.123
+185.49.84.124
+185.49.84.125
+185.49.84.126
+185.49.85.202
+185.49.86.35
+185.49.86.228
+185.49.86.229
+185.49.86.230
+185.49.86.241
+185.49.87.156
+185.49.96.168
+185.49.96.207
+185.49.96.209
+185.49.97.49
+185.49.97.69
+185.49.97.83
+185.49.97.108
+185.49.97.170
+185.49.97.186
+185.49.97.187
+185.49.97.228
+185.50.38.1
+185.50.38.2
+185.50.38.3
+185.51.40.10
+185.51.42.255
+185.51.43.96
+185.51.43.130
+185.51.201.68
+185.51.201.69
+185.51.201.70
+185.53.140.9
+185.53.140.14
+185.53.140.18
+185.53.140.20
+185.53.140.25
+185.53.140.37
+185.53.140.38
+185.53.140.69
+185.53.140.75
+185.53.140.85
+185.53.140.106
+185.53.140.107
+185.53.140.119
+185.53.140.122
+185.53.140.147
+185.53.140.150
+185.53.140.151
+185.53.140.155
+185.53.140.157
+185.53.140.181
+185.53.140.184
+185.53.140.186
+185.53.140.187
+185.53.140.189
+185.53.140.194
+185.53.140.195
+185.53.140.196
+185.53.140.198
+185.53.140.206
+185.53.140.238
+185.53.140.239
+185.53.140.240
+185.53.140.242
+185.53.140.243
+185.53.140.245
+185.53.140.246
+185.53.140.248
+185.53.140.249
+185.53.140.250
+185.53.140.251
+185.53.140.252
+185.53.141.101
+185.53.142.12
+185.53.142.44
+185.53.142.101
+185.53.142.248
+185.53.143.13
+185.53.143.50
+185.53.143.51
+185.53.143.52
+185.53.143.53
+185.53.143.55
+185.53.143.56
+185.53.143.57
+185.53.143.58
+185.53.143.59
+185.53.143.60
+185.53.143.78
+185.55.224.58
+185.55.224.79
+185.55.224.89
+185.55.224.92
+185.55.224.95
+185.55.224.103
+185.55.224.115
+185.55.224.131
+185.55.224.193
+185.55.225.101
+185.55.225.158
+185.55.225.176
+185.55.225.189
+185.55.226.19
+185.55.226.25
+185.55.226.40
+185.55.227.25
+185.55.227.38
+185.55.227.43
+185.55.227.52
+185.55.227.90
+185.55.227.101
+185.55.227.121
+185.55.227.143
+185.55.227.147
+185.55.227.188
+185.55.227.200
+185.56.93.29
+185.56.93.30
+185.56.93.70
+185.56.93.122
+185.56.94.1
+185.56.94.16
+185.56.94.17
+185.56.95.186
+185.57.132.27
+185.57.133.62
+185.57.133.109
+185.57.133.140
+185.57.133.235
+185.57.133.245
+185.57.135.9
+185.57.167.225
+185.58.240.145
+185.58.240.165
+185.58.241.128
+185.58.242.64
+185.58.242.113
+185.58.242.220
+185.58.243.169
+185.60.59.2
+185.60.59.3
+185.60.59.4
+185.60.59.73
+185.60.136.28
+185.60.136.65
+185.60.136.74
+185.60.136.193
+185.63.113.12
+185.63.113.164
+185.63.113.165
+185.63.113.206
+185.63.113.216
+185.63.237.10
+185.64.176.19
+185.64.176.103
+185.66.224.14
+185.66.224.110
+185.66.224.148
+185.66.226.43
+185.66.226.130
+185.66.226.235
+185.66.227.59
+185.66.227.102
+185.66.227.113
+185.66.227.115
+185.66.227.118
+185.66.227.123
+185.66.227.124
+185.66.227.224
+185.66.227.227
+185.66.228.1
+185.66.228.2
+185.66.230.18
+185.66.230.155
+185.66.230.255
+185.71.194.140
+185.71.194.141
+185.71.194.153
+185.71.194.163
+185.72.25.85
+185.72.25.86
+185.72.25.94
+185.72.25.95
+185.72.25.121
+185.72.25.122
+185.72.25.124
+185.72.25.130
+185.72.25.146
+185.72.26.62
+185.72.26.114
+185.72.26.146
+185.72.26.147
+185.72.26.148
+185.72.26.149
+185.72.26.150
+185.72.26.218
+185.72.27.50
+185.72.27.97
+185.72.27.162
+185.72.27.232
+185.73.112.114
+185.73.112.123
+185.73.112.253
+185.73.114.228
+185.73.226.235
+185.74.221.11
+185.74.221.12
+185.74.221.14
+185.75.207.100
+185.75.207.210
+185.75.207.223
+185.78.21.48
+185.79.96.35
+185.79.96.36
+185.79.96.37
+185.79.96.92
+185.79.96.93
+185.79.96.94
+185.79.96.123
+185.79.96.124
+185.79.97.2
+185.79.97.5
+185.79.97.19
+185.79.97.131
+185.79.97.132
+185.79.97.133
+185.79.97.195
+185.79.97.196
+185.79.97.197
+185.79.98.131
+185.79.98.132
+185.79.98.133
+185.79.156.39
+185.79.156.55
+185.79.156.77
+185.79.156.82
+185.79.156.109
+185.79.156.170
+185.79.156.191
+185.79.156.208
+185.79.156.209
+185.79.156.210
+185.79.156.211
+185.79.156.212
+185.79.156.213
+185.79.156.230
+185.79.156.238
+185.79.156.239
+185.79.156.251
+185.79.156.253
+185.79.157.130
+185.79.157.131
+185.79.157.133
+185.79.157.162
+185.79.157.190
+185.79.158.12
+185.79.158.14
+185.79.158.19
+185.79.158.133
+185.79.159.130
+185.81.99.52
+185.82.65.172
+185.82.65.205
+185.82.67.2
+185.82.67.35
+185.82.67.36
+185.82.67.37
+185.82.67.144
+185.82.67.146
+185.82.67.147
+185.82.67.169
+185.82.67.175
+185.82.67.178
+185.82.136.149
+185.82.136.163
+185.82.136.188
+185.82.136.207
+185.82.136.215
+185.82.136.250
+185.82.136.254
+185.82.137.14
+185.82.137.18
+185.82.137.24
+185.82.137.33
+185.82.137.47
+185.82.137.55
+185.82.137.84
+185.82.137.97
+185.82.137.100
+185.82.139.9
+185.82.139.114
+185.82.139.124
+185.82.139.140
+185.82.139.168
+185.82.139.206
+185.82.139.227
+185.82.139.237
+185.82.139.238
+185.82.165.10
+185.82.165.66
+185.82.165.110
+185.83.88.9
+185.83.88.11
+185.83.88.13
+185.83.88.15
+185.83.88.18
+185.83.88.22
+185.83.88.44
+185.83.88.66
+185.83.88.89
+185.83.88.112
+185.83.88.113
+185.83.88.118
+185.83.88.156
+185.83.88.162
+185.83.88.190
+185.83.88.193
+185.83.88.241
+185.83.89.114
+185.83.89.194
+185.83.91.236
+185.83.112.19
+185.83.113.29
+185.83.114.220
+185.83.115.121
+185.83.115.122
+185.83.115.193
+185.83.115.204
+185.83.180.41
+185.83.180.145
+185.83.180.151
+185.83.182.20
+185.83.182.90
+185.83.182.197
+185.83.182.218
+185.83.183.96
+185.83.183.126
+185.83.183.137
+185.83.183.162
+185.83.183.251
+185.83.196.13
+185.83.196.14
+185.83.196.17
+185.83.196.30
+185.83.196.90
+185.83.196.102
+185.83.196.134
+185.83.196.150
+185.83.196.249
+185.83.197.42
+185.83.197.43
+185.83.197.45
+185.83.198.154
+185.83.198.156
+185.83.198.162
+185.83.199.83
+185.83.199.96
+185.83.199.99
+185.83.199.100
+185.83.199.101
+185.83.199.102
+185.83.199.123
+185.83.199.178
+185.83.199.234
+185.83.208.134
+185.83.208.166
+185.83.208.181
+185.83.208.185
+185.84.158.17
+185.84.158.36
+185.84.158.55
+185.85.136.1
+185.85.136.3
+185.85.136.5
+185.85.136.12
+185.85.136.18
+185.85.136.21
+185.85.136.22
+185.85.136.24
+185.85.136.26
+185.85.136.39
+185.85.136.253
+185.85.138.130
+185.85.138.200
+185.85.138.201
+185.85.138.202
+185.85.138.203
+185.85.139.201
+185.85.139.203
+185.85.139.205
+185.85.139.206
+185.85.139.207
+185.85.139.208
+185.85.139.209
+185.85.139.210
+185.85.139.211
+185.85.139.212
+185.85.139.213
+185.85.139.214
+185.85.139.215
+185.85.139.217
+185.85.139.218
+185.85.139.219
+185.85.139.222
+185.85.139.223
+185.85.139.240
+185.85.139.242
+185.85.139.243
+185.85.139.245
+185.85.139.246
+185.85.139.247
+185.85.139.248
+185.85.139.249
+185.85.139.250
+185.85.139.251
+185.85.139.252
+185.85.139.253
+185.85.139.254
+185.86.36.113
+185.86.181.52
+185.86.181.55
+185.86.181.84
+185.86.181.167
+185.86.183.160
+185.88.50.38
+185.88.50.53
+185.88.50.88
+185.88.50.177
+185.88.50.186
+185.88.51.17
+185.88.51.41
+185.88.51.96
+185.88.51.97
+185.88.51.98
+185.88.51.99
+185.88.51.100
+185.88.51.101
+185.88.51.102
+185.88.51.103
+185.88.152.54
+185.88.152.90
+185.88.152.198
+185.88.152.251
+185.88.153.3
+185.88.153.12
+185.88.153.48
+185.88.153.136
+185.88.153.160
+185.88.153.202
+185.88.153.248
+185.88.154.8
+185.88.154.68
+185.88.154.244
+185.88.176.10
+185.88.176.44
+185.88.177.23
+185.88.177.39
+185.88.177.65
+185.88.177.93
+185.88.177.108
+185.88.177.137
+185.88.177.189
+185.88.177.208
+185.88.177.213
+185.88.178.8
+185.88.178.10
+185.88.178.12
+185.88.178.14
+185.88.178.19
+185.88.178.25
+185.88.178.34
+185.88.178.37
+185.88.178.54
+185.88.178.70
+185.88.178.74
+185.88.178.78
+185.88.178.120
+185.88.178.121
+185.88.178.184
+185.88.179.232
+185.88.252.71
+185.88.252.79
+185.88.252.87
+185.88.252.107
+185.88.252.117
+185.88.252.146
+185.88.253.11
+185.89.112.58
+185.89.112.68
+185.89.112.162
+185.89.112.212
+185.89.113.106
+185.89.113.126
+185.89.113.200
+185.89.115.185
+185.92.40.1
+185.92.40.40
+185.92.42.89
+185.94.96.1
+185.94.96.5
+185.94.96.9
+185.94.96.17
+185.94.96.21
+185.94.96.25
+185.94.96.37
+185.94.96.41
+185.94.96.45
+185.94.96.49
+185.94.96.65
+185.94.96.97
+185.94.96.105
+185.94.96.117
+185.94.96.121
+185.94.96.129
+185.94.96.133
+185.94.96.137
+185.94.96.141
+185.94.96.145
+185.94.96.157
+185.94.96.161
+185.94.96.165
+185.94.96.169
+185.94.96.173
+185.94.96.177
+185.94.96.181
+185.94.96.185
+185.94.96.189
+185.94.96.193
+185.94.96.225
+185.94.96.241
+185.94.96.245
+185.94.96.249
+185.94.97.1
+185.94.97.17
+185.94.97.21
+185.94.97.22
+185.94.97.25
+185.94.97.29
+185.94.97.33
+185.94.97.38
+185.94.97.41
+185.94.97.45
+185.94.97.49
+185.94.97.53
+185.94.97.57
+185.94.97.61
+185.94.97.65
+185.94.97.69
+185.94.97.73
+185.94.97.77
+185.94.97.81
+185.94.97.97
+185.94.97.105
+185.94.97.109
+185.94.97.117
+185.94.97.145
+185.94.97.149
+185.94.97.157
+185.94.97.197
+185.94.97.201
+185.94.97.205
+185.94.97.209
+185.94.97.213
+185.94.97.217
+185.94.97.225
+185.94.97.232
+185.94.97.241
+185.94.97.245
+185.94.97.249
+185.94.97.253
+185.94.98.1
+185.94.98.37
+185.94.98.41
+185.94.98.49
+185.94.98.53
+185.94.98.57
+185.94.98.61
+185.94.98.73
+185.94.98.81
+185.94.98.89
+185.94.98.97
+185.94.98.101
+185.94.98.105
+185.94.98.109
+185.94.98.113
+185.94.98.129
+185.94.98.145
+185.94.98.165
+185.94.98.193
+185.94.98.225
+185.94.98.233
+185.94.98.241
+185.94.98.249
+185.94.99.1
+185.94.99.5
+185.94.99.33
+185.94.99.65
+185.94.99.129
+185.94.99.137
+185.94.99.141
+185.94.99.145
+185.94.99.153
+185.94.99.157
+185.94.99.161
+185.94.99.165
+185.94.99.169
+185.94.99.177
+185.94.99.185
+185.94.99.193
+185.94.99.208
+185.94.99.212
+185.94.99.225
+185.95.152.33
+185.95.152.105
+185.95.152.130
+185.95.152.132
+185.95.152.148
+185.95.182.1
+185.97.117.1
+185.97.117.112
+185.97.118.189
+185.97.118.202
+185.97.119.194
+185.97.119.241
+185.99.212.43
+185.99.212.92
+185.99.213.56
+185.100.44.28
+185.100.44.106
+185.100.44.183
+185.100.44.222
+185.100.45.22
+185.100.45.102
+185.100.46.56
+185.100.46.167
+185.100.46.168
+185.100.47.161
+185.100.47.166
+185.100.47.249
+185.101.231.186
+185.101.231.188
+185.101.231.190
+185.101.231.242
+185.103.84.1
+185.103.84.16
+185.103.87.30
+185.103.129.69
+185.103.129.70
+185.103.129.110
+185.103.130.34
+185.103.130.146
+185.103.130.162
+185.103.130.170
+185.103.130.238
+185.103.131.10
+185.103.131.131
+185.103.248.13
+185.103.248.150
+185.103.250.253
+185.104.229.202
+185.104.229.203
+185.104.229.204
+185.104.229.205
+185.104.229.206
+185.104.243.80
+185.105.101.1
+185.105.184.125
+185.105.187.133
+185.105.187.148
+185.105.187.172
+185.105.237.98
+185.105.238.157
+185.106.136.153
+185.106.136.154
+185.106.137.93
+185.106.138.209
+185.106.144.29
+185.106.145.98
+185.106.146.221
+185.106.201.7
+185.107.31.90
+185.107.31.91
+185.107.32.62
+185.107.244.195
+185.107.245.100
+185.107.245.177
+185.107.245.240
+185.107.246.26
+185.107.246.129
+185.107.246.131
+185.107.246.140
+185.107.246.141
+185.107.246.142
+185.107.246.146
+185.107.246.154
+185.107.247.215
+185.109.60.43
+185.109.60.45
+185.109.61.7
+185.109.61.41
+185.109.61.228
+185.109.62.69
+185.109.62.105
+185.109.62.108
+185.109.63.106
+185.109.63.107
+185.109.63.108
+185.109.63.109
+185.109.63.158
+185.109.63.192
+185.109.74.1
+185.109.74.87
+185.109.74.119
+185.109.74.124
+185.109.74.175
+185.109.74.195
+185.109.74.199
+185.109.74.241
+185.109.75.41
+185.109.81.91
+185.109.82.73
+185.109.82.77
+185.109.83.55
+185.109.244.188
+185.109.245.114
+185.109.246.82
+185.109.246.114
+185.109.247.18
+185.109.247.19
+185.109.247.20
+185.109.247.21
+185.109.247.85
+185.109.247.99
+185.109.247.226
+185.109.248.126
+185.110.28.1
+185.110.28.8
+185.110.28.9
+185.110.28.20
+185.110.28.30
+185.110.28.54
+185.110.28.79
+185.110.28.97
+185.110.28.98
+185.110.28.99
+185.110.28.100
+185.110.28.101
+185.110.28.102
+185.110.28.103
+185.110.28.105
+185.110.28.193
+185.110.28.194
+185.110.28.245
+185.110.28.249
+185.110.28.253
+185.110.29.38
+185.110.29.113
+185.110.29.153
+185.110.29.193
+185.110.29.249
+185.110.30.14
+185.110.30.62
+185.110.30.70
+185.110.30.79
+185.110.30.145
+185.110.30.177
+185.110.30.241
+185.110.31.10
+185.110.31.17
+185.110.31.140
+185.110.31.170
+185.110.219.25
+185.110.219.57
+185.110.219.131
+185.110.236.0
+185.110.236.33
+185.110.236.36
+185.110.236.66
+185.110.237.0
+185.110.237.58
+185.110.237.197
+185.110.238.0
+185.110.239.1
+185.110.244.55
+185.110.247.23
+185.110.252.41
+185.110.252.49
+185.110.252.97
+185.110.252.145
+185.110.252.159
+185.110.252.167
+185.110.252.229
+185.110.253.208
+185.111.65.28
+185.111.81.117
+185.111.81.118
+185.111.82.139
+185.111.83.6
+185.111.83.73
+185.111.83.144
+185.111.83.163
+185.111.83.221
+185.112.32.26
+185.112.32.42
+185.112.32.186
+185.112.33.80
+185.112.33.88
+185.112.33.89
+185.112.33.108
+185.112.33.109
+185.112.33.178
+185.112.33.179
+185.112.33.253
+185.112.34.115
+185.112.35.84
+185.112.35.202
+185.112.35.205
+185.112.35.206
+185.112.36.8
+185.112.36.17
+185.112.36.51
+185.112.36.70
+185.112.36.94
+185.112.36.106
+185.112.36.134
+185.112.36.188
+185.112.36.197
+185.112.36.200
+185.112.36.201
+185.112.36.205
+185.112.36.215
+185.112.36.223
+185.112.36.253
+185.112.37.5
+185.112.37.43
+185.112.37.56
+185.112.37.57
+185.112.37.65
+185.112.37.83
+185.112.37.94
+185.112.37.110
+185.112.37.112
+185.112.37.119
+185.112.37.128
+185.112.37.155
+185.112.37.181
+185.112.37.186
+185.112.37.214
+185.112.37.218
+185.112.37.238
+185.112.38.16
+185.112.38.18
+185.112.38.44
+185.112.38.46
+185.112.38.55
+185.112.38.64
+185.112.38.71
+185.112.38.91
+185.112.38.96
+185.112.38.104
+185.112.38.112
+185.112.38.118
+185.112.38.121
+185.112.38.131
+185.112.38.137
+185.112.38.225
+185.112.38.227
+185.112.38.230
+185.112.39.7
+185.112.39.21
+185.112.39.36
+185.112.39.45
+185.112.39.60
+185.112.39.88
+185.112.39.123
+185.112.39.129
+185.112.39.151
+185.112.39.160
+185.112.150.24
+185.112.150.26
+185.112.151.4
+185.112.151.178
+185.112.151.207
+185.112.151.223
+185.112.151.246
+185.113.9.56
+185.113.9.124
+185.113.9.211
+185.113.9.246
+185.113.56.1
+185.113.56.11
+185.113.56.19
+185.113.56.30
+185.113.56.35
+185.113.56.125
+185.113.56.130
+185.113.57.17
+185.113.57.208
+185.113.58.71
+185.113.58.73
+185.113.58.92
+185.113.58.221
+185.113.58.229
+185.113.58.231
+185.113.58.235
+185.113.59.161
+185.115.149.29
+185.115.149.228
+185.115.168.1
+185.115.168.3
+185.115.168.4
+185.115.168.11
+185.115.168.24
+185.115.168.55
+185.115.168.109
+185.115.168.157
+185.115.168.181
+185.115.168.195
+185.115.169.29
+185.115.169.46
+185.115.169.90
+185.115.169.162
+185.115.169.179
+185.115.169.186
+185.115.169.223
+185.115.171.5
+185.115.171.29
+185.115.171.31
+185.115.171.42
+185.115.171.45
+185.115.171.46
+185.115.171.48
+185.115.171.81
+185.115.171.91
+185.115.171.110
+185.115.171.171
+185.115.171.174
+185.115.171.184
+185.115.171.187
+185.115.171.194
+185.115.171.219
+185.115.171.252
+185.116.20.97
+185.116.20.169
+185.116.20.173
+185.116.20.190
+185.116.21.75
+185.116.21.76
+185.116.21.77
+185.116.22.5
+185.116.22.8
+185.116.22.49
+185.116.22.50
+185.116.22.66
+185.116.22.81
+185.116.22.177
+185.116.23.2
+185.116.23.13
+185.116.23.17
+185.116.23.57
+185.116.23.129
+185.116.23.193
+185.116.160.30
+185.116.160.73
+185.116.160.125
+185.116.160.131
+185.116.161.31
+185.116.161.108
+185.116.161.114
+185.116.162.37
+185.116.162.88
+185.116.163.32
+185.116.163.71
+185.116.163.76
+185.116.163.95
+185.116.163.99
+185.116.163.105
+185.116.163.142
+185.116.163.214
+185.117.48.248
+185.117.139.83
+185.117.139.84
+185.117.139.89
+185.117.139.91
+185.117.139.132
+185.117.139.162
+185.117.139.163
+185.117.139.164
+185.117.139.166
+185.117.139.167
+185.117.139.170
+185.117.139.171
+185.117.139.172
+185.117.139.174
+185.118.13.101
+185.118.13.140
+185.118.13.185
+185.118.13.229
+185.118.14.22
+185.118.14.83
+185.118.14.99
+185.118.14.113
+185.118.14.122
+185.118.14.130
+185.118.14.142
+185.118.14.149
+185.118.14.165
+185.118.14.176
+185.118.14.191
+185.118.14.199
+185.118.14.201
+185.118.14.203
+185.118.152.13
+185.118.152.17
+185.118.152.21
+185.118.152.22
+185.118.152.30
+185.118.152.93
+185.118.152.101
+185.118.152.169
+185.118.152.182
+185.118.152.185
+185.118.152.193
+185.118.152.214
+185.118.152.248
+185.118.152.249
+185.118.153.19
+185.118.153.98
+185.118.155.25
+185.118.155.33
+185.118.155.84
+185.118.155.95
+185.118.155.114
+185.118.155.122
+185.118.155.212
+185.118.155.233
+185.118.155.237
+185.119.164.61
+185.119.164.65
+185.119.164.66
+185.119.164.67
+185.119.164.69
+185.119.164.70
+185.119.164.77
+185.119.164.166
+185.119.166.8
+185.119.166.165
+185.120.162.49
+185.120.162.60
+185.120.162.61
+185.120.162.62
+185.120.162.97
+185.120.169.150
+185.120.201.34
+185.120.201.35
+185.120.201.42
+185.120.201.56
+185.120.220.27
+185.120.220.28
+185.120.220.155
+185.120.220.193
+185.120.220.194
+185.120.221.84
+185.120.221.180
+185.120.221.249
+185.120.222.138
+185.120.222.166
+185.120.222.184
+185.120.222.198
+185.120.222.211
+185.120.222.217
+185.120.222.218
+185.120.222.232
+185.120.222.242
+185.120.249.175
+185.120.250.225
+185.121.128.102
+185.121.128.115
+185.121.128.119
+185.121.128.130
+185.121.128.162
+185.121.128.163
+185.121.128.164
+185.121.129.66
+185.121.129.67
+185.121.129.69
+185.121.129.75
+185.121.129.85
+185.121.129.86
+185.121.129.89
+185.121.129.134
+185.121.129.158
+185.121.129.170
+185.121.130.106
+185.121.130.154
+185.121.130.210
+185.121.130.230
+185.121.131.6
+185.121.131.105
+185.121.131.107
+185.121.131.109
+185.121.131.110
+185.121.131.186
+185.124.112.51
+185.124.112.59
+185.124.112.153
+185.124.113.224
+185.124.114.37
+185.124.114.40
+185.124.114.96
+185.124.114.131
+185.124.114.214
+185.124.114.220
+185.124.115.104
+185.124.115.137
+185.124.173.90
+185.124.173.100
+185.125.20.4
+185.125.20.5
+185.125.20.32
+185.125.20.102
+185.125.20.119
+185.125.20.204
+185.125.20.205
+185.125.20.229
+185.125.20.254
+185.125.23.106
+185.125.23.107
+185.125.23.108
+185.125.23.109
+185.125.23.113
+185.125.23.203
+185.125.23.218
+185.125.23.228
+185.125.23.229
+185.125.248.129
+185.125.248.154
+185.125.248.217
+185.125.248.229
+185.125.249.42
+185.125.251.90
+185.125.252.77
+185.125.252.102
+185.125.252.190
+185.125.252.226
+185.125.255.82
+185.125.255.83
+185.125.255.84
+185.125.255.85
+185.125.255.86
+185.125.255.88
+185.125.255.89
+185.125.255.90
+185.125.255.91
+185.125.255.92
+185.125.255.93
+185.125.255.113
+185.125.255.114
+185.125.255.119
+185.125.255.120
+185.125.255.241
+185.126.0.84
+185.126.1.4
+185.126.1.166
+185.126.2.44
+185.126.3.91
+185.126.3.92
+185.126.3.132
+185.126.3.133
+185.126.3.134
+185.126.3.135
+185.126.3.136
+185.126.3.137
+185.126.3.138
+185.126.3.140
+185.126.3.141
+185.126.3.142
+185.126.3.143
+185.126.3.145
+185.126.3.146
+185.126.3.147
+185.126.3.149
+185.126.3.151
+185.126.3.152
+185.126.3.153
+185.126.3.154
+185.126.3.155
+185.126.3.158
+185.126.4.62
+185.126.4.170
+185.126.5.14
+185.126.5.40
+185.126.5.41
+185.126.5.49
+185.126.5.221
+185.126.6.174
+185.126.6.241
+185.126.8.18
+185.126.8.19
+185.126.8.21
+185.126.8.22
+185.126.9.147
+185.126.9.148
+185.126.9.150
+185.126.9.186
+185.126.10.180
+185.126.10.205
+185.126.11.97
+185.126.14.109
+185.126.14.110
+185.126.14.114
+185.126.14.115
+185.126.14.116
+185.126.14.117
+185.126.14.118
+185.126.14.119
+185.126.14.120
+185.126.14.121
+185.126.14.122
+185.126.14.123
+185.126.14.124
+185.126.14.126
+185.126.14.196
+185.126.14.202
+185.126.14.204
+185.126.14.205
+185.126.14.212
+185.126.14.244
+185.126.14.245
+185.126.15.13
+185.126.15.202
+185.126.16.9
+185.126.18.9
+185.126.40.95
+185.126.40.106
+185.126.40.109
+185.126.40.125
+185.126.40.175
+185.126.40.178
+185.126.40.226
+185.126.201.3
+185.126.201.4
+185.126.201.5
+185.126.201.6
+185.126.201.7
+185.126.201.8
+185.126.201.9
+185.126.201.19
+185.126.201.22
+185.126.201.25
+185.126.201.26
+185.126.201.27
+185.126.201.235
+185.126.202.12
+185.126.202.13
+185.126.202.202
+185.126.203.26
+185.126.203.44
+185.128.40.16
+185.128.80.32
+185.128.80.68
+185.128.81.50
+185.128.81.225
+185.128.136.12
+185.128.137.200
+185.128.137.202
+185.128.138.2
+185.128.138.100
+185.128.138.102
+185.128.138.103
+185.128.138.175
+185.128.139.73
+185.128.139.133
+185.128.152.13
+185.128.152.59
+185.128.152.137
+185.128.152.201
+185.128.152.246
+185.129.116.74
+185.129.116.75
+185.129.116.76
+185.129.116.77
+185.129.117.67
+185.129.117.68
+185.129.117.69
+185.129.117.105
+185.129.117.195
+185.129.117.196
+185.129.117.197
+185.129.118.2
+185.129.118.3
+185.129.118.5
+185.129.118.6
+185.129.118.53
+185.129.118.131
+185.129.118.132
+185.129.118.237
+185.129.119.3
+185.129.119.4
+185.129.119.5
+185.129.119.131
+185.129.119.132
+185.129.119.133
+185.129.168.41
+185.129.168.166
+185.129.168.193
+185.129.169.131
+185.129.169.132
+185.129.169.137
+185.129.170.87
+185.129.197.155
+185.129.197.173
+185.129.197.215
+185.129.197.226
+185.129.197.227
+185.129.197.233
+185.129.197.235
+185.129.199.74
+185.129.199.186
+185.129.200.201
+185.129.202.131
+185.129.212.178
+185.129.213.145
+185.129.213.149
+185.129.213.170
+185.129.213.189
+185.129.213.203
+185.129.213.210
+185.129.213.221
+185.129.214.25
+185.129.214.47
+185.129.214.200
+185.129.215.29
+185.129.215.45
+185.129.215.165
+185.129.216.19
+185.129.216.30
+185.129.216.152
+185.129.217.10
+185.129.217.38
+185.129.217.59
+185.129.217.116
+185.129.217.129
+185.129.217.203
+185.129.218.0
+185.129.230.18
+185.129.230.213
+185.129.236.49
+185.129.236.194
+185.129.236.195
+185.129.237.45
+185.129.238.52
+185.129.238.178
+185.129.238.255
+185.129.239.37
+185.129.239.43
+185.129.239.48
+185.129.239.93
+185.129.239.123
+185.129.239.171
+185.129.239.232
+185.129.239.235
+185.130.50.92
+185.130.50.113
+185.130.50.130
+185.130.50.141
+185.130.50.142
+185.130.50.154
+185.130.50.248
+185.130.79.230
+185.131.30.14
+185.131.30.18
+185.131.30.21
+185.131.30.49
+185.131.30.50
+185.131.30.58
+185.131.30.83
+185.131.30.104
+185.131.30.122
+185.131.30.135
+185.131.30.168
+185.131.30.205
+185.131.30.237
+185.131.30.250
+185.131.117.125
+185.131.117.145
+185.131.119.78
+185.131.155.109
+185.132.80.3
+185.132.80.18
+185.132.80.20
+185.132.80.30
+185.132.80.65
+185.132.80.131
+185.132.80.228
+185.132.80.232
+185.132.80.244
+185.132.81.17
+185.132.81.19
+185.132.81.25
+185.132.81.53
+185.132.81.74
+185.132.81.109
+185.132.81.148
+185.132.81.172
+185.132.81.197
+185.132.81.200
+185.132.81.249
+185.132.82.7
+185.132.82.19
+185.132.82.20
+185.132.82.58
+185.132.82.84
+185.132.82.94
+185.132.82.128
+185.132.82.160
+185.132.82.168
+185.132.82.177
+185.132.82.178
+185.132.82.191
+185.134.96.114
+185.134.96.150
+185.134.96.161
+185.134.96.162
+185.134.96.230
+185.134.97.98
+185.134.97.230
+185.134.97.250
+185.134.98.10
+185.134.98.130
+185.134.98.142
+185.134.98.144
+185.134.98.166
+185.134.98.196
+185.134.98.213
+185.134.98.220
+185.134.98.250
+185.134.99.250
+185.135.47.70
+185.135.228.209
+185.135.229.72
+185.135.229.227
+185.135.230.4
+185.135.230.84
+185.135.230.246
+185.135.230.251
+185.135.231.122
+185.136.100.43
+185.136.100.78
+185.136.101.31
+185.136.101.142
+185.136.102.96
+185.136.102.124
+185.136.102.229
+185.136.103.90
+185.136.103.125
+185.136.133.36
+185.136.133.37
+185.136.133.38
+185.136.133.106
+185.136.133.107
+185.136.180.9
+185.136.180.75
+185.136.180.91
+185.136.180.102
+185.136.180.176
+185.136.180.184
+185.136.180.218
+185.136.180.221
+185.136.180.234
+185.136.180.255
+185.136.182.160
+185.136.182.185
+185.136.183.168
+185.136.183.180
+185.136.183.210
+185.136.183.220
+185.136.183.252
+185.136.192.18
+185.136.192.114
+185.136.193.22
+185.136.193.41
+185.136.193.207
+185.136.193.233
+185.136.194.33
+185.136.194.34
+185.136.194.36
+185.136.194.38
+185.136.194.39
+185.136.194.42
+185.136.194.43
+185.136.194.44
+185.136.194.45
+185.136.194.46
+185.136.195.206
+185.137.25.70
+185.137.25.98
+185.137.25.210
+185.137.26.54
+185.137.26.138
+185.137.26.155
+185.137.26.182
+185.137.60.112
+185.137.60.150
+185.137.60.202
+185.137.108.1
+185.137.108.106
+185.137.108.128
+185.137.108.137
+185.137.108.163
+185.137.108.192
+185.137.108.193
+185.137.108.197
+185.137.108.198
+185.137.108.211
+185.137.108.215
+185.137.108.230
+185.137.108.238
+185.137.109.0
+185.137.109.1
+185.137.109.2
+185.137.109.13
+185.137.109.36
+185.137.109.49
+185.137.109.131
+185.137.109.254
+185.137.109.255
+185.137.110.0
+185.137.110.18
+185.137.110.25
+185.137.110.31
+185.137.110.57
+185.137.110.64
+185.137.110.74
+185.137.110.76
+185.137.110.106
+185.137.110.109
+185.137.111.0
+185.140.4.8
+185.140.4.14
+185.140.4.24
+185.140.4.26
+185.140.4.27
+185.140.4.28
+185.140.4.29
+185.140.4.65
+185.140.4.66
+185.140.4.67
+185.140.4.72
+185.140.4.73
+185.140.4.76
+185.140.4.77
+185.140.4.78
+185.140.4.79
+185.140.5.6
+185.140.7.130
+185.140.7.131
+185.140.7.142
+185.140.56.21
+185.140.58.179
+185.140.59.3
+185.140.59.162
+185.140.59.186
+185.140.232.9
+185.140.232.28
+185.140.232.47
+185.140.232.57
+185.140.232.66
+185.140.232.242
+185.140.232.249
+185.140.232.251
+185.140.232.252
+185.140.234.1
+185.140.234.47
+185.140.234.251
+185.140.235.2
+185.140.240.1
+185.140.240.16
+185.140.240.49
+185.140.240.50
+185.140.240.54
+185.140.240.89
+185.140.240.94
+185.140.240.159
+185.140.240.161
+185.140.240.162
+185.140.240.239
+185.140.240.250
+185.140.240.252
+185.140.241.148
+185.140.242.33
+185.140.242.35
+185.140.242.41
+185.140.242.42
+185.140.242.44
+185.140.242.49
+185.140.242.50
+185.140.242.129
+185.140.242.133
+185.140.242.134
+185.140.242.146
+185.140.242.155
+185.140.243.13
+185.140.243.104
+185.140.243.121
+185.140.243.128
+185.140.243.133
+185.140.243.169
+185.140.243.175
+185.140.243.176
+185.140.243.179
+185.140.243.182
+185.140.243.254
+185.140.243.255
+185.141.36.58
+185.141.36.67
+185.141.39.3
+185.141.39.21
+185.141.39.30
+185.141.39.39
+185.141.39.114
+185.141.39.225
+185.141.49.129
+185.141.104.120
+185.141.104.209
+185.141.105.209
+185.141.105.210
+185.141.105.211
+185.141.105.212
+185.141.105.213
+185.141.105.235
+185.141.105.236
+185.141.106.51
+185.141.106.217
+185.141.106.219
+185.141.106.220
+185.141.106.221
+185.141.106.222
+185.141.106.223
+185.141.107.137
+185.141.107.220
+185.141.132.64
+185.141.132.65
+185.141.132.66
+185.141.133.164
+185.141.134.48
+185.141.134.149
+185.141.134.150
+185.141.134.219
+185.141.134.253
+185.141.168.12
+185.141.168.98
+185.141.168.118
+185.141.169.233
+185.141.171.114
+185.141.171.115
+185.141.171.116
+185.141.171.117
+185.141.213.130
+185.141.213.169
+185.141.213.246
+185.141.213.252
+185.141.214.19
+185.141.214.92
+185.141.215.61
+185.142.92.104
+185.142.92.107
+185.142.92.111
+185.142.92.117
+185.142.92.156
+185.142.92.166
+185.142.92.177
+185.142.92.184
+185.142.92.198
+185.142.92.199
+185.142.92.214
+185.142.92.220
+185.142.92.222
+185.142.93.27
+185.142.93.48
+185.142.93.64
+185.142.93.81
+185.142.93.100
+185.142.93.137
+185.142.93.138
+185.142.93.144
+185.142.93.146
+185.142.93.173
+185.142.93.200
+185.142.93.203
+185.142.93.208
+185.142.93.214
+185.142.93.230
+185.142.93.234
+185.142.93.235
+185.142.93.236
+185.142.93.243
+185.142.94.6
+185.142.94.16
+185.142.94.31
+185.142.94.38
+185.142.94.42
+185.142.94.48
+185.142.94.53
+185.142.94.66
+185.142.94.68
+185.142.94.77
+185.142.94.79
+185.142.94.82
+185.142.94.121
+185.142.94.143
+185.142.94.152
+185.142.94.158
+185.142.94.159
+185.142.94.160
+185.142.95.52
+185.142.95.53
+185.142.95.55
+185.142.95.98
+185.142.95.178
+185.142.124.18
+185.142.124.19
+185.142.124.21
+185.142.124.65
+185.142.124.66
+185.142.124.67
+185.142.124.68
+185.142.124.69
+185.142.124.70
+185.142.124.103
+185.142.124.241
+185.142.125.6
+185.142.125.8
+185.142.125.13
+185.142.125.14
+185.142.125.46
+185.142.125.60
+185.142.125.63
+185.142.125.64
+185.142.125.84
+185.142.125.110
+185.142.125.119
+185.142.125.123
+185.142.125.132
+185.142.125.133
+185.142.125.143
+185.142.125.151
+185.142.125.155
+185.142.125.160
+185.142.125.170
+185.142.125.181
+185.142.125.212
+185.142.125.216
+185.142.125.220
+185.142.126.2
+185.142.126.25
+185.142.126.27
+185.142.126.28
+185.142.126.30
+185.142.126.31
+185.142.126.50
+185.142.126.59
+185.142.126.65
+185.142.126.66
+185.142.126.76
+185.142.126.82
+185.142.126.96
+185.142.126.130
+185.142.126.134
+185.142.126.177
+185.142.126.184
+185.142.126.188
+185.142.126.198
+185.142.126.224
+185.142.126.226
+185.142.126.236
+185.142.126.243
+185.142.127.58
+185.142.127.76
+185.142.127.101
+185.142.127.109
+185.142.127.126
+185.142.127.131
+185.142.127.161
+185.142.127.166
+185.142.127.212
+185.142.127.214
+185.142.156.216
+185.142.156.226
+185.142.157.54
+185.142.157.94
+185.142.157.250
+185.142.159.66
+185.142.159.85
+185.142.159.100
+185.142.159.110
+185.142.159.170
+185.142.159.187
+185.142.159.250
+185.142.159.252
+185.143.205.13
+185.143.205.62
+185.143.205.96
+185.143.205.141
+185.143.205.146
+185.143.205.150
+185.143.205.160
+185.143.205.226
+185.143.207.3
+185.143.207.13
+185.143.207.92
+185.143.207.111
+185.143.207.114
+185.143.207.117
+185.143.207.130
+185.143.207.142
+185.143.207.148
+185.143.207.150
+185.143.207.151
+185.143.207.182
+185.143.207.253
+185.145.8.254
+185.145.9.76
+185.145.9.80
+185.145.9.161
+185.145.184.91
+185.145.184.94
+185.145.184.145
+185.145.184.147
+185.145.184.148
+185.145.184.151
+185.145.184.175
+185.145.184.183
+185.145.184.192
+185.145.184.193
+185.145.184.195
+185.145.184.235
+185.145.185.13
+185.145.185.14
+185.145.185.15
+185.145.185.87
+185.145.185.96
+185.145.185.98
+185.145.185.99
+185.145.185.111
+185.145.185.127
+185.145.185.132
+185.145.185.170
+185.145.185.176
+185.145.186.45
+185.145.186.80
+185.145.186.134
+185.145.186.141
+185.145.186.161
+185.145.186.170
+185.145.186.240
+185.145.186.241
+185.145.186.242
+185.145.186.243
+185.145.186.244
+185.145.186.245
+185.145.186.246
+185.145.186.247
+185.145.187.13
+185.145.187.161
+185.145.187.169
+185.145.187.190
+185.145.187.196
+185.145.187.221
+185.145.187.229
+185.145.187.235
+185.145.187.241
+185.145.187.243
+185.147.40.10
+185.147.40.39
+185.147.40.88
+185.147.40.210
+185.147.41.28
+185.147.41.42
+185.147.41.176
+185.147.160.66
+185.147.160.101
+185.147.161.195
+185.147.161.200
+185.147.161.205
+185.147.162.11
+185.147.163.206
+185.149.192.20
+185.149.192.27
+185.149.192.37
+185.149.192.41
+185.149.192.137
+185.149.192.138
+185.153.185.11
+185.153.185.254
+185.153.208.6
+185.155.9.102
+185.155.10.3
+185.155.10.6
+185.155.10.7
+185.155.10.60
+185.155.10.66
+185.155.10.163
+185.155.10.169
+185.155.10.212
+185.155.14.83
+185.155.14.95
+185.155.14.126
+185.155.14.174
+185.155.14.199
+185.155.14.226
+185.155.15.27
+185.155.15.56
+185.155.15.92
+185.155.15.189
+185.155.15.244
+185.158.172.26
+185.158.172.30
+185.158.172.116
+185.158.172.129
+185.158.172.245
+185.158.173.53
+185.158.173.119
+185.158.173.181
+185.158.174.73
+185.158.174.237
+185.159.153.14
+185.159.153.28
+185.159.153.41
+185.159.153.117
+185.159.153.144
+185.159.153.188
+185.159.153.195
+185.159.153.206
+185.159.153.217
+185.159.153.229
+185.159.154.12
+185.159.154.121
+185.159.154.122
+185.159.154.148
+185.159.154.156
+185.159.154.203
+185.160.205.6
+185.161.38.18
+185.161.38.117
+185.161.38.121
+185.161.38.145
+185.161.38.253
+185.161.39.72
+185.161.39.73
+185.161.39.77
+185.161.39.116
+185.161.39.170
+185.161.39.194
+185.161.39.195
+185.161.39.196
+185.161.39.197
+185.161.39.222
+185.161.112.231
+185.161.112.249
+185.161.113.130
+185.161.113.134
+185.161.113.226
+185.161.113.228
+185.161.113.242
+185.161.114.10
+185.161.114.22
+185.161.114.74
+185.161.114.138
+185.161.114.189
+185.161.115.178
+185.161.115.243
+185.162.40.27
+185.162.41.69
+185.162.41.122
+185.164.72.41
+185.164.72.54
+185.164.72.90
+185.164.72.123
+185.164.72.158
+185.164.72.234
+185.164.73.172
+185.164.73.253
+185.164.74.240
+185.164.252.27
+185.164.252.28
+185.164.252.130
+185.164.253.24
+185.165.30.80
+185.165.40.11
+185.165.41.221
+185.165.41.222
+185.165.43.11
+185.165.116.18
+185.165.116.33
+185.165.116.35
+185.165.116.138
+185.165.116.147
+185.165.116.240
+185.165.118.55
+185.165.118.65
+185.165.119.49
+185.166.104.55
+185.169.6.62
+185.169.6.120
+185.169.6.197
+185.169.6.204
+185.169.20.34
+185.169.20.74
+185.169.20.234
+185.169.21.50
+185.169.21.118
+185.169.22.102
+185.170.236.18
+185.170.236.125
+185.170.236.130
+185.170.236.145
+185.170.236.171
+185.170.236.205
+185.170.237.141
+185.170.237.161
+185.170.237.204
+185.170.237.209
+185.170.238.64
+185.170.238.70
+185.170.238.159
+185.170.238.194
+185.170.238.200
+185.170.239.5
+185.170.239.59
+185.170.239.72
+185.170.239.130
+185.170.239.150
+185.170.239.210
+185.171.53.150
+185.171.54.18
+185.171.54.20
+185.171.54.21
+185.171.54.26
+185.171.54.29
+185.171.54.30
+185.171.54.34
+185.171.54.35
+185.171.54.36
+185.171.54.42
+185.171.54.67
+185.171.54.68
+185.171.54.69
+185.171.54.84
+185.171.54.86
+185.171.54.90
+185.171.54.138
+185.171.54.139
+185.171.54.140
+185.171.54.141
+185.171.54.156
+185.171.54.170
+185.171.54.234
+185.171.54.237
+185.171.54.238
+185.171.55.138
+185.171.55.139
+185.171.55.140
+185.171.55.141
+185.171.55.162
+185.171.55.163
+185.171.55.164
+185.171.55.219
+185.171.55.220
+185.171.55.221
+185.171.55.222
+185.171.55.233
+185.172.0.42
+185.172.0.206
+185.172.0.218
+185.172.0.238
+185.172.1.70
+185.172.1.126
+185.172.1.202
+185.172.1.214
+185.172.2.194
+185.172.2.195
+185.172.2.196
+185.172.2.198
+185.172.3.162
+185.172.3.242
+185.172.68.1
+185.172.68.3
+185.172.68.4
+185.172.68.13
+185.172.68.16
+185.172.68.31
+185.172.68.32
+185.172.68.37
+185.172.68.41
+185.172.68.64
+185.172.68.71
+185.172.68.75
+185.172.68.76
+185.172.69.9
+185.172.69.37
+185.172.70.70
+185.173.104.53
+185.173.104.194
+185.173.104.200
+185.173.104.208
+185.173.105.78
+185.173.105.141
+185.173.105.142
+185.173.106.117
+185.173.107.26
+185.173.129.35
+185.173.129.91
+185.173.129.185
+185.173.129.203
+185.173.129.240
+185.173.129.243
+185.174.132.21
+185.174.132.25
+185.174.132.130
+185.174.132.217
+185.174.132.254
+185.174.134.66
+185.175.76.162
+185.175.76.164
+185.175.76.165
+185.175.76.166
+185.175.77.67
+185.175.79.89
+185.175.79.177
+185.175.79.193
+185.176.32.38
+185.176.33.38
+185.176.34.16
+185.176.34.25
+185.176.34.94
+185.176.35.130
+185.176.56.253
+185.176.57.98
+185.176.57.138
+185.176.59.48
+185.176.59.49
+185.176.59.201
+185.176.59.209
+185.176.59.246
+185.176.59.254
+185.177.158.50
+185.177.158.53
+185.177.158.54
+185.177.158.60
+185.177.159.84
+185.177.159.227
+185.177.159.247
+185.179.90.107
+185.179.168.3
+185.179.168.4
+185.179.168.13
+185.179.168.14
+185.179.168.16
+185.179.168.17
+185.179.168.18
+185.179.168.19
+185.179.168.31
+185.179.168.36
+185.179.168.47
+185.179.168.114
+185.179.168.115
+185.179.168.116
+185.179.168.117
+185.179.168.118
+185.179.168.119
+185.179.168.120
+185.179.168.121
+185.179.168.122
+185.179.168.123
+185.179.168.124
+185.179.168.125
+185.179.168.126
+185.179.168.169
+185.179.169.28
+185.179.169.82
+185.179.169.141
+185.179.169.166
+185.179.169.169
+185.179.169.180
+185.179.169.203
+185.179.169.208
+185.179.169.212
+185.179.169.221
+185.179.169.244
+185.179.170.2
+185.179.170.124
+185.179.170.127
+185.179.170.217
+185.179.170.230
+185.179.170.239
+185.179.171.0
+185.179.171.25
+185.179.171.55
+185.179.171.72
+185.179.171.110
+185.179.171.121
+185.179.171.130
+185.179.171.200
+185.179.221.3
+185.179.221.168
+185.180.128.22
+185.180.128.54
+185.180.128.64
+185.180.128.69
+185.180.128.70
+185.180.128.100
+185.180.129.2
+185.180.129.4
+185.180.129.5
+185.180.129.6
+185.180.129.7
+185.180.129.40
+185.180.129.41
+185.180.129.100
+185.180.129.138
+185.180.129.142
+185.180.129.216
+185.180.129.222
+185.180.129.228
+185.180.129.229
+185.180.129.230
+185.180.129.231
+185.180.129.234
+185.180.130.1
+185.180.130.8
+185.180.130.47
+185.180.130.133
+185.180.130.136
+185.180.130.182
+185.180.130.184
+185.180.130.231
+185.180.130.240
+185.180.130.246
+185.180.130.254
+185.181.180.138
+185.181.181.64
+185.181.181.65
+185.181.181.67
+185.181.181.68
+185.181.181.69
+185.181.181.70
+185.181.181.71
+185.181.181.72
+185.181.181.73
+185.181.181.75
+185.181.181.77
+185.181.181.79
+185.181.181.167
+185.181.182.39
+185.181.182.61
+185.181.182.141
+185.181.182.169
+185.181.182.235
+185.181.183.4
+185.181.183.12
+185.181.183.17
+185.181.183.51
+185.181.183.100
+185.181.183.105
+185.181.183.117
+185.186.50.221
+185.186.51.49
+185.186.240.9
+185.186.240.64
+185.186.240.65
+185.186.240.66
+185.186.240.67
+185.186.240.177
+185.186.240.179
+185.186.240.180
+185.186.240.182
+185.186.240.232
+185.186.242.66
+185.186.242.146
+185.186.243.23
+185.186.243.30
+185.186.243.31
+185.186.243.39
+185.186.243.48
+185.186.243.57
+185.186.243.98
+185.186.243.99
+185.186.243.112
+185.186.243.124
+185.186.243.148
+185.186.243.176
+185.186.243.240
+185.186.243.241
+185.186.243.243
+185.186.243.245
+185.186.243.246
+185.187.48.30
+185.187.48.74
+185.187.48.122
+185.187.49.12
+185.187.49.15
+185.187.49.56
+185.187.49.60
+185.187.49.70
+185.187.50.39
+185.187.50.43
+185.187.51.0
+185.187.51.32
+185.187.51.42
+185.187.51.48
+185.187.51.49
+185.187.51.94
+185.187.51.245
+185.187.51.255
+185.187.87.253
+185.188.112.149
+185.188.112.154
+185.188.112.172
+185.188.112.193
+185.188.112.207
+185.188.113.21
+185.188.113.104
+185.188.113.113
+185.188.115.5
+185.188.115.10
+185.190.39.59
+185.190.39.242
+185.191.76.26
+185.191.77.170
+185.191.77.174
+185.191.77.253
+185.191.78.86
+185.191.78.233
+185.191.78.245
+185.191.79.6
+185.191.79.154
+185.191.79.210
+185.192.112.69
+185.192.112.73
+185.192.112.143
+185.192.112.252
+185.192.113.83
+185.192.113.87
+185.192.113.108
+185.192.113.121
+185.192.113.148
+185.196.148.111
+185.196.151.7
+185.201.48.17
+185.201.48.141
+185.201.48.172
+185.201.48.184
+185.201.48.231
+185.201.49.146
+185.201.50.90
+185.201.51.41
+185.201.51.67
+185.201.51.69
+185.201.51.75
+185.201.51.76
+185.201.51.116
+185.201.51.161
+185.201.51.217
+185.201.51.221
+185.201.51.229
+185.202.56.22
+185.202.56.74
+185.202.56.86
+185.202.56.98
+185.202.56.102
+185.202.56.210
+185.202.56.214
+185.202.58.150
+185.202.58.183
+185.202.58.236
+185.202.59.114
+185.204.182.10
+185.204.197.53
+185.204.197.149
+185.204.197.226
+185.205.203.242
+185.206.92.63
+185.206.93.203
+185.206.94.42
+185.206.95.9
+185.206.229.21
+185.206.229.22
+185.206.229.23
+185.206.229.24
+185.206.229.25
+185.206.229.30
+185.206.229.31
+185.206.229.32
+185.206.229.35
+185.206.229.36
+185.206.229.50
+185.206.229.72
+185.206.229.103
+185.206.229.104
+185.206.231.31
+185.206.231.68
+185.206.231.79
+185.206.231.216
+185.206.238.178
+185.208.76.101
+185.208.76.102
+185.208.76.103
+185.208.76.104
+185.208.76.105
+185.208.76.106
+185.208.77.85
+185.208.77.178
+185.208.77.179
+185.208.78.100
+185.208.78.101
+185.208.79.95
+185.208.148.3
+185.208.148.48
+185.208.148.216
+185.208.148.241
+185.208.149.138
+185.208.174.44
+185.208.174.68
+185.208.174.153
+185.208.175.11
+185.208.175.167
+185.208.175.209
+185.208.175.235
+185.208.180.9
+185.208.180.170
+185.208.181.66
+185.208.181.67
+185.208.181.68
+185.208.181.86
+185.208.182.3
+185.208.182.77
+185.208.182.117
+185.208.183.14
+185.208.183.164
+185.208.183.188
+185.209.42.6
+185.209.42.50
+185.209.42.95
+185.211.56.126
+185.211.57.166
+185.211.58.79
+185.211.58.146
+185.211.59.115
+185.211.59.134
+185.211.59.160
+185.212.50.5
+185.212.50.10
+185.212.51.73
+185.212.51.119
+185.212.51.144
+185.212.51.160
+185.212.51.201
+185.212.51.202
+185.212.51.203
+185.212.51.204
+185.212.51.205
+185.212.51.206
+185.212.51.241
+185.212.193.4
+185.212.193.21
+185.212.193.22
+185.212.193.23
+185.212.193.97
+185.212.193.160
+185.212.193.162
+185.212.193.163
+185.212.193.165
+185.212.193.170
+185.212.195.34
+185.212.195.35
+185.212.195.36
+185.212.195.37
+185.212.195.38
+185.212.195.41
+185.212.195.58
+185.212.195.113
+185.212.195.114
+185.212.195.116
+185.212.195.154
+185.212.195.161
+185.212.195.167
+185.212.195.174
+185.212.195.177
+185.212.195.178
+185.212.195.254
+185.213.10.99
+185.213.10.101
+185.213.11.23
+185.213.11.59
+185.213.11.75
+185.213.11.77
+185.213.11.93
+185.213.164.4
+185.213.164.5
+185.213.164.25
+185.213.164.105
+185.213.164.151
+185.213.164.191
+185.213.164.242
+185.213.165.30
+185.213.165.31
+185.213.165.32
+185.213.165.62
+185.213.165.70
+185.213.165.82
+185.213.165.97
+185.213.165.104
+185.213.165.224
+185.214.39.156
+185.215.154.23
+185.215.234.253
+185.217.6.30
+185.217.6.130
+185.218.139.80
+185.218.139.100
+185.218.139.133
+185.220.226.0
+185.220.226.1
+185.220.226.2
+185.220.226.3
+185.220.226.4
+185.220.226.5
+185.220.226.6
+185.220.226.7
+185.220.226.8
+185.220.226.10
+185.220.226.11
+185.220.226.12
+185.220.226.13
+185.220.226.15
+185.220.226.17
+185.220.226.18
+185.220.226.19
+185.220.226.21
+185.220.226.24
+185.220.226.25
+185.220.226.26
+185.220.226.27
+185.220.226.29
+185.220.226.30
+185.220.226.31
+185.220.226.33
+185.220.226.34
+185.220.226.35
+185.220.226.36
+185.220.226.37
+185.220.226.38
+185.220.226.39
+185.220.226.40
+185.220.226.42
+185.220.226.43
+185.220.226.44
+185.220.226.45
+185.220.226.46
+185.220.226.47
+185.220.226.48
+185.220.226.49
+185.220.226.50
+185.220.226.51
+185.220.226.52
+185.220.226.53
+185.220.226.54
+185.220.226.55
+185.220.226.56
+185.220.226.57
+185.220.226.58
+185.220.226.59
+185.220.226.60
+185.220.226.61
+185.220.226.62
+185.220.226.63
+185.220.226.64
+185.220.226.65
+185.220.226.66
+185.220.226.68
+185.220.226.69
+185.220.226.70
+185.220.226.71
+185.220.226.72
+185.220.226.73
+185.220.226.75
+185.220.226.76
+185.220.226.77
+185.220.226.78
+185.220.226.79
+185.220.226.80
+185.220.226.81
+185.220.226.83
+185.220.226.84
+185.220.226.85
+185.220.226.86
+185.220.226.87
+185.220.226.88
+185.220.226.89
+185.220.226.90
+185.220.226.92
+185.220.226.93
+185.220.226.94
+185.220.226.95
+185.220.226.96
+185.220.226.97
+185.220.226.98
+185.220.226.99
+185.220.226.100
+185.220.226.101
+185.220.226.103
+185.220.226.104
+185.220.226.105
+185.220.226.106
+185.220.226.108
+185.220.226.110
+185.220.226.111
+185.220.226.112
+185.220.226.114
+185.220.226.115
+185.220.226.116
+185.220.226.117
+185.220.226.118
+185.220.226.121
+185.220.226.122
+185.220.226.123
+185.220.226.124
+185.220.226.125
+185.220.226.126
+185.220.226.127
+185.220.226.128
+185.220.226.130
+185.220.226.131
+185.220.226.132
+185.220.226.133
+185.220.226.134
+185.220.226.135
+185.220.226.136
+185.220.226.137
+185.220.226.138
+185.220.226.139
+185.220.226.140
+185.220.226.141
+185.220.226.142
+185.220.226.143
+185.220.226.144
+185.220.226.145
+185.220.226.146
+185.220.226.147
+185.220.226.148
+185.220.226.150
+185.220.226.151
+185.220.226.152
+185.220.226.153
+185.220.226.154
+185.220.226.155
+185.220.226.156
+185.220.226.157
+185.220.226.158
+185.220.226.159
+185.220.226.160
+185.220.226.161
+185.220.226.162
+185.220.226.163
+185.220.226.164
+185.220.226.165
+185.220.226.166
+185.220.226.167
+185.220.226.168
+185.220.226.169
+185.220.226.170
+185.220.226.171
+185.220.226.172
+185.220.226.173
+185.220.226.174
+185.220.226.175
+185.220.226.176
+185.220.226.177
+185.220.226.178
+185.220.226.179
+185.220.226.181
+185.220.226.182
+185.220.226.183
+185.220.226.184
+185.220.226.185
+185.220.226.186
+185.220.226.187
+185.220.226.188
+185.220.226.189
+185.220.226.190
+185.220.226.191
+185.220.226.192
+185.220.226.193
+185.220.226.195
+185.220.226.198
+185.220.226.199
+185.220.226.200
+185.220.226.201
+185.220.226.202
+185.220.226.203
+185.220.226.204
+185.220.226.205
+185.220.226.206
+185.220.226.207
+185.220.226.208
+185.220.226.209
+185.220.226.211
+185.220.226.212
+185.220.226.213
+185.220.226.214
+185.220.226.215
+185.220.226.216
+185.220.226.217
+185.220.226.218
+185.220.226.219
+185.220.226.220
+185.220.226.221
+185.220.226.222
+185.220.226.223
+185.220.226.224
+185.220.226.225
+185.220.226.226
+185.220.226.227
+185.220.226.228
+185.220.226.230
+185.220.226.231
+185.220.226.232
+185.220.226.233
+185.220.226.234
+185.220.226.236
+185.220.226.237
+185.220.226.239
+185.220.226.240
+185.220.226.241
+185.220.226.242
+185.220.226.244
+185.220.226.247
+185.220.226.248
+185.220.226.249
+185.220.226.250
+185.220.226.251
+185.220.226.252
+185.220.226.253
+185.220.226.255
+185.221.192.6
+185.221.192.27
+185.221.192.28
+185.221.192.101
+185.221.192.215
+185.221.194.133
+185.221.194.195
+185.221.194.228
+185.221.194.238
+185.221.194.250
+185.221.194.252
+185.221.195.94
+185.221.195.95
+185.221.195.227
+185.221.195.235
+185.221.239.51
+185.221.239.59
+185.221.239.73
+185.221.239.89
+185.221.239.92
+185.221.239.164
+185.221.239.220
+185.222.163.1
+185.222.163.2
+185.222.163.65
+185.222.163.81
+185.222.163.89
+185.222.163.93
+185.222.163.97
+185.222.163.165
+185.222.163.169
+185.222.163.177
+185.222.163.185
+185.222.163.193
+185.222.163.201
+185.222.163.209
+185.224.176.14
+185.224.176.24
+185.224.176.41
+185.224.176.82
+185.224.176.112
+185.224.176.125
+185.224.176.127
+185.224.176.159
+185.224.176.163
+185.224.176.177
+185.224.176.190
+185.224.176.215
+185.224.176.220
+185.224.177.33
+185.224.177.91
+185.224.177.112
+185.224.177.163
+185.224.177.187
+185.224.177.244
+185.224.179.16
+185.224.179.17
+185.224.179.27
+185.224.179.38
+185.224.179.45
+185.224.179.47
+185.224.179.61
+185.224.179.75
+185.224.179.81
+185.224.179.90
+185.224.179.118
+185.224.179.176
+185.224.179.186
+185.224.179.204
+185.224.179.213
+185.224.179.227
+185.225.80.25
+185.225.80.73
+185.225.80.102
+185.225.80.130
+185.225.80.233
+185.225.80.234
+185.225.82.154
+185.225.82.162
+185.225.82.195
+185.225.83.64
+185.225.183.2
+185.225.240.138
+185.225.240.150
+185.225.241.230
+185.225.241.242
+185.225.241.250
+185.225.242.162
+185.225.242.178
+185.225.242.243
+185.225.243.83
+185.225.243.84
+185.225.243.86
+185.225.243.87
+185.225.243.88
+185.225.243.89
+185.225.243.91
+185.225.243.94
+185.226.116.89
+185.226.116.243
+185.226.117.8
+185.226.117.111
+185.226.117.156
+185.226.117.161
+185.226.117.193
+185.226.117.231
+185.226.118.2
+185.226.119.93
+185.226.119.113
+185.226.119.143
+185.226.119.220
+185.228.59.189
+185.229.28.46
+185.229.31.47
+185.229.31.73
+185.229.31.171
+185.229.31.193
+185.229.133.40
+185.229.204.98
+185.229.204.99
+185.229.204.100
+185.229.204.101
+185.229.204.145
+185.231.65.2
+185.231.65.213
+185.231.112.64
+185.231.112.114
+185.231.112.169
+185.231.115.28
+185.231.115.126
+185.231.115.201
+185.231.115.248
+185.231.180.157
+185.231.181.20
+185.231.181.30
+185.231.182.164
+185.231.182.250
+185.231.183.143
+185.232.154.125
+185.233.131.19
+185.233.131.30
+185.233.131.152
+185.233.131.154
+185.233.131.156
+185.233.131.170
+185.233.131.171
+185.233.131.183
+185.233.131.186
+185.234.14.114
+185.235.136.161
+185.235.136.184
+185.235.139.9
+185.235.139.41
+185.235.139.57
+185.235.139.70
+185.235.139.151
+185.235.196.3
+185.235.196.6
+185.235.196.21
+185.235.196.41
+185.235.196.42
+185.235.196.44
+185.235.196.51
+185.235.196.54
+185.235.196.58
+185.235.196.75
+185.235.196.91
+185.235.196.105
+185.235.196.109
+185.235.196.118
+185.235.196.144
+185.235.197.39
+185.235.245.149
+185.235.245.186
+185.236.36.154
+185.236.37.101
+185.236.37.199
+185.236.38.41
+185.236.38.42
+185.236.38.43
+185.236.38.47
+185.236.38.84
+185.237.84.36
+185.237.84.49
+185.237.84.188
+185.237.84.195
+185.237.84.241
+185.237.84.243
+185.237.84.245
+185.237.85.220
+185.237.86.140
+185.237.87.6
+185.237.87.65
+185.237.87.99
+185.237.87.128
+185.237.87.141
+185.237.87.158
+185.237.87.165
+185.237.87.195
+185.237.87.214
+185.238.44.24
+185.238.44.61
+185.238.44.72
+185.238.44.121
+185.238.44.134
+185.238.44.205
+185.238.44.212
+185.238.44.215
+185.238.44.232
+185.238.44.234
+185.238.45.15
+185.238.45.17
+185.238.45.25
+185.238.45.47
+185.238.45.71
+185.238.45.76
+185.238.45.119
+185.238.45.121
+185.238.45.129
+185.238.45.156
+185.238.45.173
+185.238.45.176
+185.238.45.181
+185.238.45.211
+185.238.45.214
+185.238.45.246
+185.238.45.250
+185.238.46.8
+185.238.46.18
+185.238.46.54
+185.238.46.59
+185.238.46.62
+185.238.46.118
+185.238.46.138
+185.238.46.140
+185.238.46.146
+185.238.46.158
+185.238.46.164
+185.238.46.172
+185.238.46.181
+185.238.46.200
+185.238.46.214
+185.238.46.215
+185.238.46.232
+185.238.46.237
+185.238.46.244
+185.238.47.6
+185.238.47.11
+185.238.47.13
+185.238.47.21
+185.238.47.36
+185.238.47.62
+185.238.47.109
+185.238.47.111
+185.238.47.115
+185.238.47.124
+185.238.47.147
+185.238.47.152
+185.238.47.185
+185.238.47.199
+185.238.47.216
+185.238.47.252
+185.238.140.75
+185.239.0.72
+185.239.1.30
+185.239.1.62
+185.239.2.3
+185.239.3.51
+185.239.3.69
+185.239.3.166
+185.239.3.189
+185.239.106.121
+185.243.48.103
+185.243.48.133
+185.243.48.190
+185.243.49.158
+185.243.50.1
+185.243.50.2
+185.246.6.94
+185.246.6.102
+185.251.76.53
+185.251.76.193
+185.251.76.194
+185.251.77.130
+185.252.29.116
+185.252.29.233
+185.252.30.130
+185.252.31.36
+185.252.31.58
+185.252.31.68
+185.252.31.113
+185.252.31.130
+185.252.31.156
+185.252.31.200
+185.252.31.210
+185.252.86.16
+185.252.86.40
+185.252.86.154
+185.252.86.182
+185.255.88.108
+185.255.88.114
+185.255.88.138
+185.255.88.155
+185.255.88.166
+185.255.88.204
+185.255.88.237
+185.255.89.69
+185.255.89.80
+185.255.89.100
+185.255.89.101
+185.255.89.108
+185.255.89.130
+185.255.89.146
+185.255.89.156
+185.255.89.158
+185.255.89.164
+185.255.89.246
+185.255.90.24
+185.255.90.114
+185.255.90.130
+185.255.90.140
+185.255.90.147
+185.255.91.1
+185.255.91.2
+185.255.91.10
+185.255.91.42
+185.255.91.84
+185.255.91.207
+185.255.208.35
+185.255.208.179
+185.255.208.194
+185.255.209.132
+185.255.209.134
+185.255.209.137
+185.255.209.224
+185.255.209.227
+185.255.209.253
+185.255.210.32
+185.255.210.151
+185.255.210.152
+185.255.210.167
+185.255.210.175
+185.255.210.195
+185.255.210.198
+185.255.210.199
+185.255.210.209
+185.255.211.6
+185.255.211.30
+185.255.211.48
+185.255.211.67
+185.255.211.121
+185.255.211.150
+185.255.211.158
+185.255.211.195
+188.0.240.2
+188.0.240.3
+188.0.240.5
+188.0.240.6
+188.0.241.253
+188.0.244.246
+188.0.244.254
+188.0.245.1
+188.0.246.55
+188.0.246.94
+188.0.247.47
+188.0.247.245
+188.0.249.124
+188.0.249.204
+188.0.249.219
+188.0.251.180
+188.0.252.126
+188.0.254.153
+188.0.255.161
+188.75.65.201
+188.75.78.42
+188.75.78.131
+188.75.78.173
+188.75.78.181
+188.75.80.42
+188.75.80.73
+188.75.80.192
+188.75.80.226
+188.75.80.227
+188.75.80.228
+188.75.80.234
+188.75.81.162
+188.75.81.163
+188.75.81.165
+188.75.81.166
+188.75.87.195
+188.75.88.147
+188.75.88.148
+188.75.88.149
+188.75.88.150
+188.75.93.203
+188.75.93.227
+188.75.104.114
+188.75.104.115
+188.75.104.116
+188.75.104.117
+188.75.104.118
+188.75.126.18
+188.75.126.74
+188.94.188.1
+188.121.96.87
+188.121.100.30
+188.121.100.110
+188.121.100.111
+188.121.100.169
+188.121.100.176
+188.121.100.203
+188.121.101.25
+188.121.101.133
+188.121.101.140
+188.121.102.5
+188.121.102.200
+188.121.103.53
+188.121.103.86
+188.121.103.248
+188.121.104.17
+188.121.104.40
+188.121.105.16
+188.121.105.93
+188.121.105.118
+188.121.105.171
+188.121.106.202
+188.121.107.141
+188.121.107.164
+188.121.108.55
+188.121.108.56
+188.121.109.133
+188.121.110.36
+188.121.110.61
+188.121.110.172
+188.121.110.202
+188.121.111.40
+188.121.111.127
+188.121.112.15
+188.121.113.136
+188.121.116.47
+188.121.116.238
+188.121.117.164
+188.121.117.166
+188.121.118.101
+188.121.118.105
+188.121.118.128
+188.121.118.162
+188.121.118.197
+188.121.118.206
+188.121.118.216
+188.121.119.99
+188.121.119.145
+188.121.119.191
+188.121.119.217
+188.121.120.91
+188.121.120.194
+188.121.122.208
+188.121.123.70
+188.121.123.188
+188.121.124.67
+188.121.128.40
+188.121.129.122
+188.121.129.226
+188.121.129.227
+188.121.129.228
+188.121.129.238
+188.121.144.30
+188.121.144.162
+188.121.144.194
+188.121.144.238
+188.121.145.6
+188.121.145.22
+188.121.145.78
+188.121.145.122
+188.121.145.154
+188.121.145.182
+188.121.146.50
+188.121.146.142
+188.121.146.198
+188.121.146.226
+188.121.147.34
+188.121.147.38
+188.121.147.42
+188.121.147.46
+188.121.147.50
+188.121.147.58
+188.121.147.62
+188.121.147.66
+188.121.147.70
+188.121.147.74
+188.121.147.78
+188.121.147.90
+188.121.147.118
+188.121.147.150
+188.121.147.166
+188.121.148.46
+188.121.148.66
+188.121.148.94
+188.121.148.162
+188.121.148.174
+188.121.148.186
+188.121.148.190
+188.121.149.50
+188.121.149.62
+188.121.149.114
+188.121.149.138
+188.121.149.186
+188.121.149.242
+188.121.156.211
+188.121.157.133
+188.121.157.170
+188.121.157.181
+188.121.157.186
+188.121.157.250
+188.121.159.2
+188.121.159.34
+188.121.159.36
+188.121.159.37
+188.136.130.1
+188.136.130.160
+188.136.133.33
+188.136.133.111
+188.136.133.114
+188.136.133.123
+188.136.133.218
+188.136.133.224
+188.136.133.225
+188.136.133.243
+188.136.142.81
+188.136.142.133
+188.136.142.134
+188.136.142.166
+188.136.143.13
+188.136.143.20
+188.136.144.38
+188.136.144.131
+188.136.144.143
+188.136.154.38
+188.136.154.51
+188.136.154.137
+188.136.154.186
+188.136.154.187
+188.136.154.188
+188.136.154.189
+188.136.155.41
+188.136.162.21
+188.136.162.30
+188.136.162.104
+188.136.162.213
+188.136.162.216
+188.136.162.217
+188.136.162.218
+188.136.162.220
+188.136.162.221
+188.136.165.1
+188.136.172.33
+188.136.172.34
+188.136.172.35
+188.136.172.37
+188.136.172.38
+188.136.172.44
+188.136.172.45
+188.136.172.47
+188.136.172.53
+188.136.172.76
+188.136.172.83
+188.136.172.86
+188.136.172.97
+188.136.172.101
+188.136.172.103
+188.136.172.120
+188.136.172.121
+188.136.172.126
+188.136.172.127
+188.136.172.129
+188.136.172.132
+188.136.172.136
+188.136.172.142
+188.136.172.148
+188.136.172.152
+188.136.172.157
+188.136.172.158
+188.136.172.160
+188.136.172.161
+188.136.172.165
+188.136.172.172
+188.136.172.176
+188.136.172.183
+188.136.172.184
+188.136.172.185
+188.136.172.186
+188.136.172.187
+188.136.172.188
+188.136.172.189
+188.136.172.190
+188.136.172.193
+188.136.172.224
+188.136.172.226
+188.136.172.227
+188.136.172.229
+188.136.172.230
+188.136.172.231
+188.136.172.232
+188.136.172.234
+188.136.172.235
+188.136.172.237
+188.136.172.240
+188.136.172.241
+188.136.172.242
+188.136.172.245
+188.136.172.247
+188.136.172.250
+188.136.172.251
+188.136.172.253
+188.136.174.34
+188.136.174.35
+188.136.174.42
+188.136.174.86
+188.136.174.118
+188.136.174.130
+188.136.174.131
+188.136.174.133
+188.136.174.134
+188.136.174.214
+188.136.174.234
+188.136.174.242
+188.136.194.54
+188.136.194.238
+188.136.196.1
+188.136.196.29
+188.136.196.36
+188.136.196.125
+188.136.196.164
+188.136.196.167
+188.136.196.178
+188.136.196.180
+188.136.196.216
+188.136.196.217
+188.136.196.220
+188.136.196.221
+188.136.196.222
+188.136.196.224
+188.136.196.226
+188.136.196.228
+188.136.196.229
+188.136.208.6
+188.136.208.82
+188.136.208.83
+188.136.208.114
+188.136.208.210
+188.136.208.211
+188.136.208.212
+188.136.208.242
+188.136.208.244
+188.136.208.250
+188.136.208.251
+188.136.208.253
+188.136.208.254
+188.208.56.88
+188.208.56.94
+188.208.56.134
+188.208.56.230
+188.208.63.30
+188.208.63.66
+188.208.144.7
+188.208.144.84
+188.208.144.141
+188.208.144.191
+188.208.144.218
+188.208.145.14
+188.208.145.39
+188.208.145.67
+188.208.145.83
+188.208.145.97
+188.208.145.124
+188.208.145.184
+188.208.145.187
+188.208.146.177
+188.208.146.210
+188.208.147.201
+188.208.149.13
+188.208.149.118
+188.208.149.200
+188.208.149.213
+188.208.149.246
+188.208.150.5
+188.208.150.68
+188.208.150.73
+188.208.150.91
+188.208.150.117
+188.208.150.161
+188.208.150.165
+188.208.150.171
+188.208.150.174
+188.208.150.179
+188.208.150.229
+188.208.151.8
+188.208.151.20
+188.208.151.188
+188.208.151.194
+188.208.151.216
+188.208.151.231
+188.208.151.235
+188.208.151.239
+188.208.152.48
+188.209.5.105
+188.209.7.237
+188.209.64.130
+188.209.67.86
+188.209.68.119
+188.209.68.154
+188.209.70.75
+188.209.71.99
+188.209.73.96
+188.209.73.213
+188.209.75.111
+188.209.152.41
+188.209.152.44
+188.209.152.45
+188.210.87.44
+188.210.101.67
+188.210.102.82
+188.210.106.213
+188.210.108.144
+188.210.111.45
+188.210.119.248
+188.210.122.152
+188.210.124.2
+188.211.0.21
+188.211.36.106
+188.211.37.41
+188.211.37.66
+188.211.37.241
+188.211.38.53
+188.211.38.123
+188.211.39.239
+188.211.64.58
+188.211.67.61
+188.211.68.251
+188.211.71.224
+188.211.72.217
+188.211.73.160
+188.211.74.213
+188.211.75.219
+188.211.77.39
+188.211.81.212
+188.211.83.2
+188.211.83.111
+188.211.85.38
+188.211.86.144
+188.211.87.74
+188.211.87.109
+188.211.88.213
+188.211.94.162
+188.211.97.75
+188.211.97.191
+188.211.101.64
+188.211.102.1
+188.211.102.63
+188.211.103.103
+188.211.104.86
+188.211.106.247
+188.211.108.91
+188.211.108.225
+188.211.108.233
+188.211.109.198
+188.211.109.231
+188.211.111.1
+188.211.111.88
+188.211.112.52
+188.211.116.32
+188.211.116.106
+188.211.117.99
+188.211.119.76
+188.211.119.151
+188.211.120.127
+188.211.122.83
+188.211.122.114
+188.211.122.196
+188.211.200.215
+188.211.201.191
+188.211.202.114
+188.211.203.139
+188.211.204.58
+188.211.205.92
+188.211.205.231
+188.211.206.93
+188.211.206.213
+188.212.22.1
+188.212.22.9
+188.212.22.33
+188.212.22.65
+188.212.22.129
+188.212.22.137
+188.212.22.141
+188.212.22.145
+188.212.22.162
+188.212.22.177
+188.212.22.181
+188.212.22.193
+188.212.22.225
+188.212.22.233
+188.212.22.241
+188.212.22.245
+188.212.64.211
+188.212.65.46
+188.212.66.9
+188.212.66.23
+188.212.66.156
+188.212.68.65
+188.212.68.198
+188.212.71.143
+188.212.71.247
+188.212.73.158
+188.212.74.73
+188.212.79.110
+188.212.82.196
+188.212.85.146
+188.212.85.156
+188.212.88.208
+188.212.88.236
+188.212.89.105
+188.212.89.188
+188.212.90.171
+188.212.92.230
+188.212.92.247
+188.212.93.138
+188.212.93.197
+188.212.95.78
+188.212.148.162
+188.212.160.208
+188.212.161.115
+188.212.169.84
+188.212.171.199
+188.212.172.58
+188.212.173.54
+188.212.177.247
+188.212.178.9
+188.212.178.118
+188.212.178.182
+188.212.183.13
+188.212.183.19
+188.212.186.53
+188.212.187.42
+188.212.242.211
+188.212.244.182
+188.213.66.15
+188.213.66.20
+188.213.66.25
+188.213.66.90
+188.213.66.131
+188.213.66.132
+188.213.66.133
+188.213.67.70
+188.213.67.98
+188.213.67.108
+188.213.67.131
+188.213.68.146
+188.213.71.62
+188.213.71.207
+188.213.76.19
+188.213.76.94
+188.213.76.183
+188.213.76.240
+188.213.77.26
+188.213.78.22
+188.213.79.21
+188.213.79.116
+188.213.79.221
+188.213.79.240
+188.213.176.97
+188.213.178.0
+188.213.178.61
+188.213.178.62
+188.213.179.251
+188.213.180.79
+188.213.181.176
+188.213.189.255
+188.213.191.85
+188.213.195.243
+188.213.196.20
+188.213.196.137
+188.213.196.138
+188.213.196.185
+188.213.198.13
+188.213.198.219
+188.213.209.124
+188.213.209.146
+188.213.209.149
+188.213.209.156
+188.213.209.168
+188.213.209.178
+188.213.209.218
+188.213.211.25
+188.213.211.170
+188.214.96.65
+188.214.96.106
+188.214.96.146
+188.214.96.150
+188.214.97.41
+188.214.98.114
+188.214.98.215
+188.214.98.253
+188.214.99.182
+188.214.173.57
+188.214.216.26
+188.214.216.59
+188.214.216.154
+188.214.216.255
+188.214.217.240
+188.214.218.34
+188.214.219.48
+188.214.219.103
+188.214.219.142
+188.214.219.206
+188.214.219.248
+188.214.220.225
+188.214.221.32
+188.214.221.78
+188.214.222.47
+188.214.223.109
+188.214.223.160
+188.214.223.232
+188.215.140.46
+188.215.140.220
+188.215.160.200
+188.215.162.36
+188.215.163.71
+188.215.164.144
+188.215.166.176
+188.215.167.35
+188.215.168.146
+188.215.168.152
+188.215.174.188
+188.215.213.76
+188.215.214.66
+188.240.212.9
+188.253.2.67
+188.253.2.115
+188.253.2.147
+188.253.2.210
+188.253.2.241
+188.253.2.250
+188.253.3.136
+188.253.3.185
+193.3.255.1
+193.3.255.2
+193.3.255.3
+193.3.255.4
+193.3.255.5
+193.3.255.6
+193.3.255.7
+193.3.255.8
+193.3.255.9
+193.3.255.12
+193.3.255.15
+193.3.255.16
+193.3.255.18
+193.3.255.19
+193.3.255.21
+193.3.255.22
+193.3.255.24
+193.3.255.25
+193.3.255.28
+193.3.255.29
+193.3.255.30
+193.3.255.31
+193.3.255.32
+193.3.255.33
+193.3.255.34
+193.3.255.35
+193.3.255.36
+193.3.255.37
+193.3.255.38
+193.3.255.39
+193.3.255.40
+193.3.255.41
+193.3.255.42
+193.3.255.43
+193.3.255.44
+193.3.255.45
+193.3.255.46
+193.3.255.47
+193.3.255.48
+193.3.255.49
+193.3.255.50
+193.3.255.51
+193.3.255.52
+193.3.255.53
+193.3.255.54
+193.3.255.55
+193.3.255.56
+193.3.255.57
+193.3.255.59
+193.3.255.60
+193.3.255.61
+193.3.255.62
+193.3.255.63
+193.3.255.65
+193.3.255.66
+193.3.255.67
+193.3.255.68
+193.3.255.69
+193.3.255.70
+193.3.255.71
+193.3.255.72
+193.3.255.73
+193.3.255.74
+193.3.255.75
+193.3.255.76
+193.3.255.77
+193.3.255.79
+193.3.255.80
+193.3.255.81
+193.3.255.82
+193.3.255.83
+193.3.255.84
+193.3.255.85
+193.3.255.86
+193.3.255.87
+193.3.255.88
+193.3.255.89
+193.3.255.90
+193.3.255.91
+193.3.255.92
+193.3.255.93
+193.3.255.95
+193.3.255.96
+193.3.255.98
+193.3.255.99
+193.3.255.100
+193.3.255.102
+193.3.255.103
+193.3.255.104
+193.3.255.105
+193.3.255.106
+193.3.255.107
+193.3.255.108
+193.3.255.109
+193.3.255.110
+193.3.255.111
+193.3.255.112
+193.3.255.113
+193.3.255.114
+193.3.255.115
+193.3.255.116
+193.3.255.117
+193.3.255.118
+193.3.255.119
+193.3.255.120
+193.3.255.121
+193.3.255.122
+193.3.255.123
+193.3.255.124
+193.3.255.125
+193.3.255.126
+193.3.255.128
+193.3.255.129
+193.3.255.130
+193.3.255.131
+193.3.255.133
+193.3.255.134
+193.3.255.135
+193.3.255.137
+193.3.255.139
+193.3.255.140
+193.3.255.141
+193.3.255.142
+193.3.255.143
+193.3.255.144
+193.3.255.145
+193.3.255.146
+193.3.255.147
+193.3.255.148
+193.3.255.149
+193.3.255.150
+193.3.255.151
+193.3.255.152
+193.3.255.153
+193.3.255.154
+193.3.255.155
+193.3.255.156
+193.3.255.157
+193.3.255.158
+193.3.255.160
+193.3.255.161
+193.3.255.164
+193.3.255.165
+193.3.255.166
+193.3.255.167
+193.3.255.168
+193.3.255.169
+193.3.255.170
+193.3.255.171
+193.3.255.172
+193.3.255.174
+193.3.255.175
+193.3.255.176
+193.3.255.177
+193.3.255.178
+193.3.255.179
+193.3.255.180
+193.3.255.182
+193.3.255.184
+193.3.255.185
+193.3.255.186
+193.3.255.187
+193.3.255.188
+193.3.255.191
+193.3.255.192
+193.3.255.193
+193.3.255.197
+193.3.255.198
+193.3.255.199
+193.3.255.200
+193.3.255.201
+193.3.255.202
+193.3.255.203
+193.3.255.204
+193.3.255.205
+193.3.255.206
+193.3.255.207
+193.3.255.208
+193.3.255.209
+193.3.255.210
+193.3.255.211
+193.3.255.212
+193.3.255.213
+193.3.255.214
+193.3.255.216
+193.3.255.217
+193.3.255.218
+193.3.255.219
+193.3.255.220
+193.3.255.221
+193.3.255.222
+193.3.255.223
+193.3.255.224
+193.3.255.225
+193.3.255.226
+193.3.255.227
+193.3.255.228
+193.3.255.229
+193.3.255.230
+193.3.255.231
+193.3.255.232
+193.3.255.233
+193.3.255.234
+193.3.255.235
+193.3.255.236
+193.3.255.237
+193.3.255.238
+193.3.255.239
+193.3.255.240
+193.3.255.241
+193.3.255.242
+193.3.255.243
+193.3.255.244
+193.3.255.245
+193.3.255.246
+193.3.255.248
+193.3.255.249
+193.3.255.250
+193.3.255.251
+193.3.255.252
+193.3.255.253
+193.5.44.24
+193.5.44.96
+193.5.44.201
+193.19.144.9
+193.19.144.10
+193.22.20.2
+193.24.103.1
+193.24.103.2
+193.35.230.2
+193.35.230.9
+193.35.230.34
+193.37.37.2
+193.37.37.3
+193.37.37.248
+193.39.9.66
+193.39.9.101
+193.39.9.115
+193.56.59.10
+193.56.61.140
+193.56.61.164
+193.56.107.107
+193.56.107.180
+193.56.107.196
+193.56.107.236
+193.56.107.238
+193.56.118.24
+193.56.118.26
+193.56.118.33
+193.56.118.126
+193.56.118.199
+193.58.119.39
+193.84.255.67
+193.104.29.50
+193.105.6.203
+193.105.234.5
+193.105.234.74
+193.105.234.122
+193.105.234.141
+193.105.234.153
+193.107.44.16
+193.107.44.19
+193.107.44.25
+193.107.44.61
+193.111.234.83
+193.111.234.117
+193.111.234.145
+193.111.234.205
+193.111.234.217
+193.111.235.31
+193.111.235.42
+193.111.235.91
+193.111.235.95
+193.111.235.231
+193.111.235.232
+193.111.235.235
+193.111.235.236
+193.111.236.136
+193.111.236.139
+193.111.236.180
+193.134.100.74
+193.134.100.108
+193.134.100.243
+193.134.101.67
+193.134.101.132
+193.141.64.6
+193.141.64.75
+193.141.64.79
+193.141.64.101
+193.141.64.106
+193.141.64.113
+193.141.64.135
+193.141.64.156
+193.141.64.163
+193.141.64.188
+193.141.64.236
+193.141.65.130
+193.148.65.41
+193.148.65.69
+193.148.65.240
+193.148.65.244
+193.148.66.21
+193.148.66.165
+193.148.67.117
+193.150.66.62
+193.150.66.134
+193.151.132.30
+193.151.137.70
+193.151.145.132
+193.151.153.134
+193.151.154.156
+193.151.157.155
+193.151.157.157
+193.151.157.158
+193.151.157.175
+193.151.157.190
+193.151.157.191
+193.151.157.192
+193.151.157.193
+193.151.159.229
+193.151.159.248
+193.176.97.103
+193.176.97.128
+193.176.97.141
+193.177.242.20
+193.178.200.20
+193.186.32.83
+193.186.32.102
+193.186.32.158
+193.186.32.226
+193.186.215.9
+193.200.148.10
+193.200.148.17
+193.200.148.48
+193.200.148.55
+193.200.148.58
+193.200.148.68
+193.200.148.149
+193.200.148.151
+193.200.148.162
+193.200.148.186
+193.200.148.197
+193.200.148.205
+193.201.192.250
+193.228.90.29
+193.228.90.30
+193.228.90.96
+193.228.90.118
+193.228.90.138
+193.228.90.153
+193.228.91.26
+193.228.91.27
+193.228.91.153
+193.228.136.128
+193.228.136.133
+193.228.136.138
+193.228.136.139
+193.228.136.140
+193.228.136.144
+193.228.136.145
+193.228.136.151
+193.228.136.155
+193.228.136.158
+193.228.136.192
+193.228.136.193
+193.228.136.204
+193.228.136.209
+193.228.136.210
+193.228.136.215
+193.228.136.218
+193.228.136.219
+193.228.136.220
+193.228.136.221
+193.228.136.223
+193.228.168.52
+193.228.168.162
+193.228.168.234
+193.228.169.10
+193.228.169.21
+193.228.169.25
+193.242.125.66
+193.246.200.1
+193.246.200.33
+193.246.200.34
+193.246.200.65
+193.246.200.81
+193.246.200.82
+193.246.200.114
+193.246.200.117
+193.246.200.119
+193.246.200.120
+193.246.200.124
+193.246.200.125
+193.246.200.126
+193.246.201.46
+194.1.155.9
+194.1.155.54
+194.5.175.112
+194.5.175.159
+194.5.175.225
+194.5.176.42
+194.5.177.1
+194.5.179.1
+194.5.188.44
+194.5.188.81
+194.5.188.109
+194.5.188.160
+194.5.195.19
+194.5.195.97
+194.5.195.166
+194.5.195.189
+194.5.205.51
+194.5.205.159
+194.5.205.227
+194.5.205.241
+194.9.57.32
+194.9.57.119
+194.9.57.148
+194.9.57.160
+194.9.57.167
+194.9.57.186
+194.9.57.199
+194.9.57.217
+194.9.80.21
+194.9.80.35
+194.9.80.38
+194.9.80.56
+194.9.80.84
+194.9.80.125
+194.9.80.127
+194.26.117.37
+194.26.117.40
+194.26.117.57
+194.26.117.68
+194.31.108.22
+194.31.108.45
+194.31.108.250
+194.31.108.251
+194.31.194.184
+194.31.194.203
+194.33.105.11
+194.33.105.12
+194.33.105.53
+194.33.105.96
+194.33.105.185
+194.33.107.242
+194.34.163.55
+194.36.174.30
+194.36.174.157
+194.36.174.251
+194.39.254.54
+194.41.48.21
+194.48.198.50
+194.48.198.204
+194.53.118.3
+194.53.119.3
+194.53.122.41
+194.53.122.61
+194.53.122.70
+194.53.122.75
+194.53.122.76
+194.53.122.83
+194.53.122.101
+194.53.122.119
+194.53.122.123
+194.53.122.126
+194.53.122.141
+194.53.122.150
+194.53.122.178
+194.53.122.248
+194.56.148.5
+194.56.148.129
+194.56.148.170
+194.56.148.177
+194.56.148.225
+194.56.148.235
+194.56.148.243
+194.59.170.3
+194.59.170.235
+194.59.171.12
+194.59.171.32
+194.59.171.71
+194.59.214.78
+194.59.214.89
+194.59.214.254
+194.59.215.114
+194.60.209.10
+194.60.209.11
+194.60.209.12
+194.60.209.14
+194.60.209.26
+194.60.209.98
+194.60.211.105
+194.60.211.125
+194.60.230.60
+194.60.230.118
+194.60.231.14
+194.60.231.55
+194.60.231.73
+194.60.231.153
+194.60.231.173
+194.60.231.226
+194.60.231.229
+194.62.17.34
+194.62.17.171
+194.62.17.246
+194.62.43.52
+194.62.43.119
+194.62.43.147
+194.62.43.173
+194.107.116.115
+194.107.116.116
+194.107.116.117
+194.107.116.118
+194.107.116.254
+194.146.151.21
+194.146.239.49
+194.146.239.72
+194.146.239.73
+194.147.142.11
+194.147.142.226
+194.147.167.48
+194.147.167.85
+194.147.167.221
+194.147.222.122
+194.150.68.0
+194.150.68.98
+194.150.68.101
+194.150.68.128
+194.150.68.144
+194.150.68.145
+194.150.68.147
+194.150.68.148
+194.150.68.149
+194.150.68.150
+194.150.68.151
+194.150.68.152
+194.150.68.153
+194.150.68.156
+194.150.68.158
+194.150.68.199
+194.150.68.207
+194.150.68.248
+194.150.68.249
+194.150.68.250
+194.150.68.251
+194.150.69.148
+194.150.69.159
+194.150.69.181
+194.150.69.197
+194.150.69.198
+194.150.69.199
+194.150.70.38
+194.150.70.44
+194.150.70.45
+194.150.70.46
+194.150.70.47
+194.150.70.55
+194.150.70.91
+194.150.70.180
+194.150.71.17
+194.150.71.37
+194.150.71.45
+194.150.71.57
+194.150.71.58
+194.150.71.174
+194.150.71.234
+194.150.71.251
+194.156.140.111
+194.156.140.167
+194.180.11.149
+194.180.11.197
+194.180.11.203
+194.180.11.252
+194.180.224.21
+194.225.24.15
+194.225.24.113
+194.225.26.41
+194.225.50.88
+194.225.70.5
+194.225.70.83
+194.225.101.1
+194.225.101.2
+194.225.101.3
+194.225.101.5
+194.225.101.7
+194.225.101.9
+194.225.101.11
+194.225.101.12
+194.225.101.13
+194.225.101.14
+194.225.101.15
+194.225.101.16
+194.225.101.17
+194.225.101.18
+194.225.101.19
+194.225.101.20
+194.225.101.21
+194.225.101.22
+194.225.101.24
+194.225.101.26
+194.225.101.27
+194.225.101.32
+194.225.116.10
+194.225.136.254
+194.225.230.72
+195.2.234.254
+195.8.102.50
+195.18.10.15
+195.26.27.158
+195.28.11.12
+195.28.11.56
+195.28.11.100
+195.28.11.107
+195.28.11.126
+195.28.11.227
+195.62.4.28
+195.62.4.29
+195.88.189.5
+195.88.189.18
+195.88.189.33
+195.88.189.38
+195.88.189.56
+195.88.189.67
+195.88.189.85
+195.88.189.89
+195.88.189.103
+195.88.189.105
+195.88.189.119
+195.88.189.144
+195.88.189.153
+195.88.189.189
+195.88.189.195
+195.110.38.130
+195.110.38.233
+195.114.8.145
+195.114.8.146
+195.114.8.147
+195.114.8.148
+195.114.8.149
+195.114.8.150
+195.114.8.151
+195.177.255.7
+195.177.255.92
+195.177.255.133
+195.177.255.138
+195.177.255.149
+195.177.255.198
+195.177.255.211
+195.181.36.29
+195.181.36.41
+195.181.36.63
+195.181.36.80
+195.181.37.11
+195.181.37.49
+195.181.37.75
+195.181.37.79
+195.181.37.190
+195.181.38.44
+195.181.38.48
+195.181.38.56
+195.181.38.128
+195.181.38.211
+195.181.38.234
+195.181.39.40
+195.181.40.13
+195.181.40.70
+195.181.41.140
+195.181.42.99
+195.181.42.100
+195.181.42.101
+195.181.42.102
+195.181.42.103
+195.181.42.105
+195.181.42.106
+195.181.42.107
+195.181.42.109
+195.181.42.110
+195.181.57.219
+195.181.58.29
+195.181.58.63
+195.181.59.49
+195.181.67.97
+195.181.67.208
+195.181.68.14
+195.181.68.235
+195.181.69.11
+195.181.69.69
+195.181.69.251
+195.181.70.117
+195.181.71.73
+195.181.74.147
+195.181.75.174
+195.181.76.140
+195.181.77.166
+195.181.78.111
+195.181.78.163
+195.181.79.112
+195.181.79.121
+195.181.79.153
+195.181.80.176
+195.181.81.96
+195.181.82.25
+195.181.82.183
+195.181.83.149
+195.181.85.207
+195.181.88.31
+195.181.88.147
+195.181.88.219
+195.181.88.223
+195.181.89.140
+195.181.94.39
+195.181.110.185
+195.181.112.94
+195.181.112.252
+195.181.113.38
+195.181.113.53
+195.181.113.189
+195.181.113.219
+195.181.113.255
+195.181.114.59
+195.181.114.81
+195.181.114.107
+195.181.114.196
+195.181.114.224
+195.181.117.163
+195.181.118.41
+195.181.118.57
+195.181.119.171
+195.181.119.186
+195.191.44.6
+195.191.44.7
+195.191.44.20
+195.191.44.70
+195.191.44.98
+195.191.44.115
+195.191.44.142
+195.191.44.154
+195.191.44.161
+195.191.44.170
+195.191.44.176
+195.191.44.191
+195.191.44.207
+195.191.44.213
+195.191.44.214
+195.191.44.254
+195.191.44.255
+195.191.45.12
+195.191.45.14
+195.191.45.26
+195.191.45.44
+195.191.45.45
+195.191.45.47
+195.191.45.61
+195.191.45.75
+195.191.45.88
+195.191.45.130
+195.191.45.149
+195.191.45.151
+195.191.45.155
+195.191.45.179
+195.191.45.189
+195.191.45.241
+195.191.45.250
+195.211.44.20
+195.211.44.25
+195.211.44.164
+195.211.44.165
+195.211.44.166
+195.211.44.175
+195.211.45.150
+195.211.45.222
+195.211.45.228
+195.211.46.63
+195.211.46.208
+195.211.46.243
+195.211.46.244
+195.211.47.66
+195.211.47.135
+195.211.47.195
+195.214.235.6
+195.214.235.27
+195.214.235.115
+195.214.235.120
+195.214.235.140
+195.214.235.173
+195.214.235.174
+195.214.235.208
+195.226.223.12
+195.226.223.27
+195.226.223.28
+195.226.223.29
+195.226.223.30
+195.226.223.214
+195.230.107.93
+195.238.231.97
+195.238.240.83
+195.238.240.84
+195.238.240.89
+195.245.70.1
+195.245.70.65
+212.16.68.41
+212.16.68.124
+212.16.75.253
+212.16.77.19
+212.16.77.20
+212.16.77.21
+212.16.77.22
+212.16.84.128
+212.16.86.17
+212.16.86.86
+212.16.86.112
+212.16.86.137
+212.16.86.139
+212.18.108.187
+212.18.108.235
+212.23.201.166
+212.23.201.238
+212.23.216.12
+212.23.216.99
+212.23.216.116
+212.23.216.123
+212.23.216.149
+212.33.195.77
+212.33.195.84
+212.33.195.201
+212.33.197.9
+212.33.198.66
+212.33.198.98
+212.33.198.245
+212.33.199.2
+212.33.201.73
+212.33.201.227
+212.33.202.146
+212.33.202.180
+212.33.204.94
+212.33.205.10
+212.33.205.59
+212.33.205.72
+212.33.205.148
+212.33.206.9
+212.33.206.21
+212.33.206.22
+212.33.206.23
+212.33.206.24
+212.33.206.25
+212.33.206.27
+212.33.206.181
+212.33.206.185
+212.33.206.186
+212.33.206.188
+212.33.206.189
+212.33.206.190
+212.33.206.191
+212.33.212.180
+212.33.213.154
+212.33.215.66
+212.33.216.151
+212.33.216.213
+212.33.218.29
+212.33.218.62
+212.33.218.134
+212.33.219.209
+212.33.222.251
+212.33.223.56
+212.33.223.66
+212.80.8.8
+212.80.8.58
+212.80.8.152
+212.80.10.78
+212.80.10.91
+212.80.20.98
+212.80.20.103
+212.80.24.14
+212.86.64.2
+212.86.64.68
+212.86.64.79
+212.86.64.83
+212.86.64.101
+212.86.64.102
+212.86.64.103
+212.86.64.105
+212.86.65.25
+212.86.65.40
+212.86.65.60
+212.86.65.126
+212.86.72.0
+212.86.72.11
+212.86.72.46
+212.86.72.56
+212.86.72.72
+212.86.72.91
+212.86.72.123
+212.86.72.217
+212.86.73.4
+212.86.73.41
+212.86.73.56
+212.86.73.97
+212.86.73.173
+212.86.73.175
+212.86.73.200
+212.86.73.217
+212.86.73.220
+212.86.74.0
+212.86.74.6
+212.86.74.10
+212.86.74.49
+212.86.74.60
+212.86.74.67
+212.86.74.76
+212.86.74.79
+212.86.74.158
+212.86.74.160
+212.86.74.188
+212.86.74.194
+212.86.74.216
+212.86.74.218
+212.86.74.225
+212.86.75.0
+212.86.75.36
+212.86.75.42
+212.86.75.52
+212.86.75.71
+212.86.75.94
+212.86.75.96
+212.86.75.160
+212.86.75.205
+212.86.75.240
+212.86.75.243
+212.86.76.41
+212.86.79.177
+212.86.79.179
+212.86.79.183
+212.86.79.186
+212.86.79.187
+212.86.82.225
+212.86.87.251
+212.86.93.93
+212.86.94.20
+212.86.94.74
+212.86.94.113
+212.86.94.144
+212.86.94.207
+212.108.125.92
+212.120.192.236
+212.120.192.254
+212.120.193.20
+212.120.193.241
+212.120.194.72
+212.120.196.90
+212.120.197.31
+212.120.198.232
+212.120.201.203
+212.120.203.88
+212.120.204.95
+212.120.210.84
+212.120.218.141
+212.120.219.9
+212.120.219.153
+212.120.221.10
+212.120.221.141
+212.120.222.106
+212.120.223.163
+212.120.223.165
+213.108.240.139
+213.108.240.153
+213.108.240.206
+213.108.241.134
+213.108.242.161
+213.108.242.193
+213.108.242.225
+213.108.242.227
+213.108.242.245
+213.109.199.3
+213.109.248.105
+213.109.250.84
+213.109.252.154
+213.109.253.62
+213.109.253.187
+213.109.254.199
+213.176.4.6
+213.176.6.230
+213.176.7.117
+213.176.28.53
+213.176.28.147
+213.176.29.10
+213.176.69.211
+213.176.120.16
+213.176.120.74
+213.176.122.5
+213.176.122.28
+213.176.122.56
+213.176.124.10
+213.176.124.55
+213.176.127.130
+213.177.176.3
+213.177.176.103
+213.177.176.107
+213.177.176.112
+213.177.178.212
+213.195.22.51
+213.195.22.67
+213.195.22.109
+213.195.22.122
+213.195.56.45
+213.195.58.44
+213.195.58.177
+213.195.59.0
+213.195.59.10
+213.195.59.11
+213.195.59.179
+213.195.60.19
+213.195.61.119
+213.195.61.124
+213.195.61.254
+213.195.62.126
+213.207.195.118
+213.207.195.194
+213.207.196.30
+213.207.196.114
+213.207.196.138
+213.207.196.214
+213.207.198.22
+213.207.198.91
+213.207.198.180
+213.207.198.226
+213.207.200.114
+213.207.200.115
+213.207.200.162
+213.207.200.186
+213.207.200.226
+213.207.202.44
+213.207.202.94
+213.207.202.235
+213.207.202.242
+213.207.203.2
+213.207.203.30
+213.207.203.106
+213.207.203.122
+213.207.203.123
+213.207.203.124
+213.207.204.70
+213.207.204.104
+213.207.204.107
+213.207.204.154
+213.207.204.186
+213.207.204.226
+213.207.204.242
+213.207.250.159
+213.207.250.218
+213.232.124.210
+213.232.124.250
+213.232.127.18
+213.232.127.28
+213.232.127.30
+213.233.177.103
+213.233.178.35
+213.233.181.18
+213.233.181.26
+213.233.181.27
+213.233.181.106
+213.233.182.146
+213.233.182.229
+213.233.184.40
+217.11.18.50
+217.11.18.51
+217.11.18.52
+217.11.18.53
+217.11.18.54
+217.11.18.58
+217.11.18.59
+217.11.18.61
+217.11.18.62
+217.11.18.114
+217.11.18.178
+217.11.18.179
+217.11.18.180
+217.11.18.183
+217.11.18.189
+217.11.22.34
+217.11.24.162
+217.11.24.249
+217.11.26.6
+217.11.27.138
+217.11.27.139
+217.11.27.140
+217.11.27.211
+217.11.27.213
+217.11.28.74
+217.11.28.138
+217.11.28.237
+217.11.29.185
+217.11.29.189
+217.11.30.34
+217.11.30.182
+217.24.144.122
+217.24.145.5
+217.24.146.16
+217.24.147.76
+217.24.148.1
+217.24.151.89
+217.24.151.109
+217.24.151.141
+217.24.153.18
+217.24.155.149
+217.24.155.244
+217.24.157.131
+217.25.48.63
+217.25.56.90
+217.26.222.235
+217.60.238.99
+217.60.243.183
+217.60.255.67
+217.60.255.231
+217.60.255.233
+217.60.255.234
+217.60.255.235
+217.60.255.236
+217.60.255.237
+217.60.255.238
+217.66.195.26
+217.66.200.206
+217.66.200.219
+217.66.201.115
+217.66.201.116
+217.66.201.118
+217.66.203.166
+217.66.207.1
+217.66.212.246
+217.66.213.5
+217.66.213.105
+217.66.213.133
+217.66.213.134
+217.66.213.145
+217.66.215.86
+217.66.215.138
+217.66.221.21
+217.114.40.23
+217.114.40.244
+217.114.46.130
+217.144.104.1
+217.144.104.45
+217.144.104.104
+217.144.104.115
+217.144.104.124
+217.144.104.252
+217.144.105.1
+217.144.105.92
+217.144.106.1
+217.144.106.42
+217.144.106.65
+217.144.106.97
+217.144.106.98
+217.144.106.161
+217.144.106.213
+217.144.107.1
+217.144.107.122
+217.144.107.165
+217.144.107.206
+217.146.208.2
+217.146.209.178
+217.146.209.179
+217.146.215.100
+217.146.217.247
+217.146.218.141
+217.146.218.142
+217.171.145.233
+217.171.148.147
+217.171.148.190
+217.171.148.236
+217.171.149.81
+217.171.149.188
+217.171.149.201
+217.171.150.82
+217.171.150.242
+217.171.151.3
+217.171.151.16
+217.172.98.11
+217.172.98.73
+217.172.98.107
+217.172.98.130
+217.172.98.134
+217.172.104.161
+217.172.108.198
+217.172.112.36
+217.172.113.123
+217.172.113.235
+217.172.114.74
+217.172.114.92
+217.172.116.133
+217.172.117.38
+217.172.121.49
+217.172.121.115
+217.172.121.116
+217.172.121.210
+217.172.122.154
+217.172.122.155
+217.172.122.156
+217.172.122.157
+217.172.122.158
+217.172.126.1
+217.172.126.20
+217.172.126.209
+217.172.126.215
+217.172.126.234
+217.172.126.237
+217.172.126.253
+217.172.127.43
+217.172.127.77
+217.172.127.78
+217.172.127.81
+217.172.127.93
+217.172.127.101
+217.172.127.118
+217.172.127.136
+217.172.127.186
+217.172.127.189
+217.198.190.41
+217.198.190.96
+217.218.3.51
+217.218.3.163
+217.218.3.233
+217.218.42.1
+217.218.42.21
+217.218.42.22
+217.218.42.246
+217.218.44.189
+217.218.46.34
+217.218.46.35
+217.218.46.36
+217.218.51.78
+217.218.54.250
+217.218.56.227
+217.218.56.228
+217.218.56.235
+217.218.62.62
+217.218.74.14
+217.218.77.131
+217.218.81.137
+217.218.82.32
+217.218.82.33
+217.218.82.34
+217.218.82.102
+217.218.83.138
+217.218.85.245
+217.218.87.29
+217.218.87.51
+217.218.91.8
+217.218.100.216
+217.218.100.239
+217.218.103.120
+217.218.108.177
+217.218.113.130
+217.218.114.240
+217.218.114.241
+217.218.114.242
+217.218.114.244
+217.218.114.245
+217.218.114.247
+217.218.114.250
+217.218.114.253
+217.218.115.42
+217.218.115.43
+217.218.115.44
+217.218.115.46
+217.218.115.178
+217.218.115.179
+217.218.120.2
+217.218.120.216
+217.218.121.54
+217.218.125.21
+217.218.126.164
+217.218.134.57
+217.218.134.58
+217.218.134.59
+217.218.134.60
+217.218.134.61
+217.218.134.62
+217.218.135.87
+217.218.136.230
+217.218.139.255
+217.218.159.68
+217.218.162.62
+217.218.164.77
+217.218.180.42
+217.218.180.225
+217.218.192.210
+217.218.192.211
+217.218.195.26
+217.218.196.183
+217.218.201.16
+217.218.201.24
+217.218.201.49
+217.218.201.101
+217.218.201.113
+217.218.201.140
+217.218.201.175
+217.218.201.184
+217.218.201.198
+217.218.201.213
+217.218.204.114
+217.218.204.115
+217.218.204.117
+217.218.204.130
+217.218.204.138
+217.218.204.170
+217.218.206.34
+217.218.206.189
+217.218.212.136
+217.218.212.137
+217.218.213.13
+217.218.219.105
+217.218.219.201
+217.218.222.187
+217.218.223.154
+217.218.224.2
+217.218.224.156
+217.218.224.157
+217.218.224.158
+217.218.224.210
+217.218.224.211
+217.218.224.213
+217.218.224.230
+217.218.225.190
+217.218.226.98
+217.218.226.131
+217.218.227.2
+217.218.227.3
+217.218.227.4
+217.218.227.5
+217.218.227.6
+217.218.227.10
+217.218.227.50
+217.218.227.245
+217.218.227.246
+217.218.235.138
+217.218.236.2
+217.218.236.68
+217.218.236.70
+217.218.236.76
+217.218.236.85
+217.218.236.86
+217.218.236.88
+217.218.236.89
+217.218.236.162
+217.218.236.171
+217.218.237.26
+217.218.237.27
+217.218.237.28
+217.218.238.76
+217.218.242.24
+217.218.242.75
+217.218.243.191
+217.218.243.204
+217.218.243.207
+217.218.243.249
+217.218.245.13
+217.218.248.170
+217.218.249.17
+217.218.249.63
+217.218.249.240
+217.218.250.16
+217.218.250.145
+217.218.250.172
+217.218.252.33
+217.218.252.64
+217.218.252.66
+217.218.253.93
+217.218.253.110
+217.219.1.1
+217.219.14.162
+217.219.14.164
+217.219.16.1
+217.219.21.26
+217.219.26.145
+217.219.27.58
+217.219.27.65
+217.219.29.186
+217.219.29.202
+217.219.29.203
+217.219.29.250
+217.219.30.153
+217.219.30.156
+217.219.31.90
+217.219.33.127
+217.219.34.6
+217.219.34.15
+217.219.34.57
+217.219.34.66
+217.219.34.95
+217.219.35.3
+217.219.35.7
+217.219.35.10
+217.219.35.14
+217.219.35.32
+217.219.35.49
+217.219.35.55
+217.219.35.63
+217.219.35.69
+217.219.35.73
+217.219.35.90
+217.219.35.129
+217.219.35.134
+217.219.35.171
+217.219.35.183
+217.219.35.196
+217.219.35.201
+217.219.35.254
+217.219.37.3
+217.219.39.74
+217.219.39.75
+217.219.39.76
+217.219.39.77
+217.219.39.122
+217.219.39.234
+217.219.42.135
+217.219.45.2
+217.219.45.3
+217.219.45.5
+217.219.45.138
+217.219.45.178
+217.219.45.210
+217.219.45.222
+217.219.47.66
+217.219.47.122
+217.219.47.138
+217.219.47.139
+217.219.47.146
+217.219.47.170
+217.219.47.186
+217.219.47.194
+217.219.47.195
+217.219.64.66
+217.219.64.117
+217.219.64.196
+217.219.67.166
+217.219.67.179
+217.219.67.221
+217.219.68.169
+217.219.68.190
+217.219.68.250
+217.219.70.61
+217.219.70.122
+217.219.71.242
+217.219.72.10
+217.219.72.18
+217.219.72.19
+217.219.72.98
+217.219.72.102
+217.219.72.111
+217.219.72.115
+217.219.72.116
+217.219.72.119
+217.219.72.121
+217.219.72.123
+217.219.72.194
+217.219.72.199
+217.219.72.200
+217.219.72.203
+217.219.72.206
+217.219.73.193
+217.219.77.69
+217.219.77.114
+217.219.77.194
+217.219.77.250
+217.219.78.151
+217.219.80.154
+217.219.80.241
+217.219.81.2
+217.219.81.3
+217.219.81.18
+217.219.81.74
+217.219.81.249
+217.219.82.110
+217.219.82.218
+217.219.82.226
+217.219.83.146
+217.219.84.83
+217.219.85.6
+217.219.86.98
+217.219.86.99
+217.219.86.100
+217.219.87.2
+217.219.87.26
+217.219.87.42
+217.219.87.122
+217.219.87.154
+217.219.87.170
+217.219.90.87
+217.219.106.144
+217.219.106.146
+217.219.113.164
+217.219.113.180
+217.219.121.156
+217.219.124.78
+217.219.124.96
+217.219.124.97
+217.219.124.98
+217.219.124.99
+217.219.124.100
+217.219.124.101
+217.219.124.102
+217.219.124.103
+217.219.124.104
+217.219.124.105
+217.219.124.106
+217.219.124.107
+217.219.124.108
+217.219.124.109
+217.219.124.110
+217.219.124.111
+217.219.129.19
+217.219.129.213
+217.219.129.215
+217.219.129.247
+217.219.131.14
+217.219.131.116
+217.219.131.130
+217.219.132.14
+217.219.132.22
+217.219.132.65
+217.219.132.75
+217.219.132.88
+217.219.132.104
+217.219.133.86
+217.219.135.137
+217.219.136.77
+217.219.136.156
+217.219.138.206
+217.219.141.170
+217.219.143.83
+217.219.143.87
+217.219.146.81
+217.219.146.201
+217.219.147.89
+217.219.147.90
+217.219.148.34
+217.219.148.209
+217.219.148.217
+217.219.149.137
+217.219.149.201
+217.219.150.49
+217.219.155.36
+217.219.157.65
+217.219.157.88
+217.219.157.121
+217.219.158.50
+217.219.158.113
+217.219.161.172
+217.219.161.190
+217.219.162.178
+217.219.163.1
+217.219.163.3
+217.219.163.10
+217.219.163.11
+217.219.163.13
+217.219.163.14
+217.219.163.15
+217.219.163.16
+217.219.163.17
+217.219.163.18
+217.219.163.19
+217.219.163.21
+217.219.163.23
+217.219.163.24
+217.219.163.25
+217.219.163.26
+217.219.163.28
+217.219.163.30
+217.219.163.31
+217.219.163.32
+217.219.163.33
+217.219.163.34
+217.219.163.35
+217.219.163.36
+217.219.163.37
+217.219.163.38
+217.219.163.39
+217.219.163.40
+217.219.163.41
+217.219.163.42
+217.219.163.43
+217.219.163.44
+217.219.163.47
+217.219.163.48
+217.219.163.49
+217.219.163.50
+217.219.163.51
+217.219.163.52
+217.219.163.54
+217.219.163.55
+217.219.163.56
+217.219.163.57
+217.219.163.59
+217.219.163.60
+217.219.163.62
+217.219.163.63
+217.219.163.64
+217.219.163.65
+217.219.163.66
+217.219.163.67
+217.219.163.68
+217.219.163.69
+217.219.163.71
+217.219.163.73
+217.219.163.74
+217.219.163.75
+217.219.163.76
+217.219.163.77
+217.219.163.80
+217.219.163.81
+217.219.163.82
+217.219.163.85
+217.219.163.88
+217.219.163.90
+217.219.163.95
+217.219.163.96
+217.219.163.99
+217.219.163.100
+217.219.163.101
+217.219.163.102
+217.219.163.103
+217.219.163.104
+217.219.163.105
+217.219.163.110
+217.219.163.111
+217.219.163.121
+217.219.163.122
+217.219.163.123
+217.219.163.125
+217.219.163.126
+217.219.163.133
+217.219.163.134
+217.219.163.143
+217.219.163.150
+217.219.163.152
+217.219.163.153
+217.219.163.154
+217.219.163.155
+217.219.163.156
+217.219.163.157
+217.219.163.159
+217.219.163.160
+217.219.163.161
+217.219.163.164
+217.219.163.165
+217.219.163.166
+217.219.163.170
+217.219.163.171
+217.219.163.174
+217.219.163.180
+217.219.163.190
+217.219.163.200
+217.219.163.201
+217.219.163.210
+217.219.163.211
+217.219.163.222
+217.219.163.223
+217.219.163.252
+217.219.164.105
+217.219.164.106
+217.219.164.129
+217.219.164.194
+217.219.165.201
+217.219.166.3
+217.219.166.228
+217.219.166.229
+217.219.166.231
+217.219.166.235
+217.219.168.23
+217.219.169.161
+217.219.169.180
+217.219.172.106
+217.219.172.185
+217.219.172.238
+217.219.175.61
+217.219.175.66
+217.219.178.154
+217.219.179.5
+217.219.179.6
+217.219.179.18
+217.219.179.33
+217.219.179.61
+217.219.179.62
+217.219.181.228
+217.219.191.169
+217.219.192.117
+217.219.196.67
+217.219.196.114
+217.219.196.115
+217.219.196.116
+217.219.196.117
+217.219.196.170
+217.219.196.218
+217.219.196.226
+217.219.199.50
+217.219.202.234
+217.219.203.210
+217.219.206.144
+217.219.207.226
+217.219.209.125
+217.219.209.130
+217.219.216.123
+217.219.217.128
+217.219.217.141
+217.219.217.217
+217.219.217.249
+217.219.219.10
+217.219.219.137
+217.219.219.138
+217.219.219.145
+217.219.219.150
+217.219.222.76
+217.219.223.1
+217.219.223.2
+217.219.223.14
+217.219.223.106
+217.219.224.2
+217.219.224.162
+217.219.224.194
+217.219.225.2
+217.219.226.70
+217.219.227.34
+217.219.227.40
+217.219.228.36
+217.219.228.88
+217.219.228.130
+217.219.229.154
+217.219.229.155
+217.219.229.156
+217.219.229.157
+217.219.230.22
+217.219.230.221
+217.219.243.10
+217.219.244.6
+217.219.245.3
+217.219.245.14
+217.219.245.70
+217.219.245.95
+217.219.245.106
+217.219.245.136
+217.219.245.175
+217.219.245.191
+217.219.246.98
+217.219.247.99
+217.219.247.122
+2.144.2.111
+2.144.4.21
+2.144.5.134
+2.144.5.203
+2.144.6.52
+2.144.6.158
+2.144.20.43
+2.144.21.174
+2.144.22.179
+2.144.23.66
+2.144.247.175
+2.176.61.28
+2.176.193.50
+2.176.197.47
+2.176.199.118
+2.176.202.164
+2.176.205.179
+2.176.231.4
+2.176.232.223
+2.176.237.47
+2.176.239.230
+2.176.240.92
+2.176.243.141
+2.176.244.41
+2.176.245.72
+2.176.245.231
+2.176.246.166
+2.176.250.217
+2.176.255.77
+2.177.13.185
+2.177.14.0
+2.177.14.32
+2.177.14.43
+2.177.31.166
+2.177.36.242
+2.177.37.184
+2.177.41.202
+2.177.48.152
+2.177.51.194
+2.177.64.43
+2.177.68.25
+2.177.73.48
+2.177.73.79
+2.177.79.37
+2.177.83.219
+2.177.99.220
+2.177.100.226
+2.177.107.104
+2.177.113.124
+2.177.117.169
+2.177.118.6
+2.177.129.148
+2.177.130.105
+2.177.137.86
+2.177.142.148
+2.177.151.132
+2.177.151.156
+2.177.165.9
+2.177.166.150
+2.177.168.234
+2.177.171.89
+2.177.182.115
+2.177.185.122
+2.177.187.200
+2.177.197.115
+2.177.198.53
+2.177.199.51
+2.177.199.107
+2.177.199.245
+2.177.204.214
+2.177.211.79
+2.177.216.209
+2.177.223.128
+2.177.225.220
+2.177.226.55
+2.177.227.249
+2.177.228.177
+2.177.230.204
+2.177.231.85
+2.177.233.155
+2.177.240.13
+2.177.241.251
+2.177.242.157
+2.177.248.198
+2.177.249.33
+2.178.10.49
+2.178.26.120
+2.178.29.129
+2.178.33.172
+2.178.39.222
+2.178.47.252
+2.178.50.226
+2.178.68.197
+2.178.75.96
+2.178.82.205
+2.178.96.216
+2.178.97.192
+2.178.106.14
+2.178.165.235
+2.178.166.233
+2.178.178.132
+2.178.190.214
+2.178.196.1
+2.178.212.26
+2.178.213.139
+2.178.222.197
+2.178.224.182
+2.178.248.58
+2.178.248.241
+2.179.110.69
+2.179.111.38
+2.179.127.252
+2.179.165.153
+2.179.175.184
+2.179.232.32
+2.180.40.2
+2.180.160.254
+2.180.198.17
+2.180.203.21
+2.180.228.113
+2.181.165.5
+2.181.167.6
+2.181.194.140
+2.181.198.224
+2.181.241.244
+2.182.46.37
+2.182.56.10
+2.182.184.108
+2.182.185.9
+2.182.188.221
+2.182.197.16
+2.182.215.254
+2.182.245.1
+2.183.173.236
+2.183.203.2
+2.185.17.37
+2.185.18.125
+2.185.108.67
+2.185.109.142
+2.185.122.248
+2.185.126.202
+2.185.142.5
+2.185.228.204
+2.185.230.220
+2.185.247.106
+2.185.248.133
+2.185.249.127
+2.185.249.210
+2.185.251.86
+2.187.18.3
+2.187.140.164
+2.188.3.60
+2.188.168.129
+2.188.175.242
+2.189.1.0
+2.189.9.97
+2.189.11.159
+2.189.86.97
+2.189.145.17
+2.189.145.173
+2.189.157.249
+2.189.217.144
+2.189.219.152
+2.189.242.12
+2.190.3.235
+2.190.26.244
+2.190.28.221
+2.190.28.244
+2.190.29.197
+2.190.40.249
+2.190.49.235
+2.190.59.172
+2.190.60.13
+2.190.60.27
+2.190.61.4
+2.190.61.175
+2.190.62.132
+2.190.71.116
+2.190.72.84
+2.190.87.152
+2.190.95.36
+2.190.97.50
+2.190.103.243
+2.190.110.83
+2.190.117.30
+2.190.131.33
+2.190.140.44
+2.190.142.104
+2.190.157.58
+2.190.159.232
+2.190.168.235
+2.190.173.111
+2.190.174.81
+2.190.180.13
+2.190.180.245
+2.190.182.58
+2.190.189.139
+2.190.193.93
+2.190.205.31
+2.190.210.124
+2.190.212.127
+2.190.216.0
+2.190.222.0
+2.190.226.150
+2.190.234.39
+2.190.240.24
+2.191.5.220
+2.191.6.55
+2.191.11.21
+2.191.19.182
+2.191.21.202
+2.191.26.194
+2.191.34.72
+2.191.40.236
+2.191.42.139
+2.191.46.127
+2.191.49.238
+2.191.52.197
+2.191.54.134
+2.191.57.99
+2.191.59.64
+2.191.61.46
+2.191.69.203
+2.191.73.215
+2.191.79.184
+2.191.88.247
+2.191.99.161
+2.191.100.238
+2.191.103.229
+2.191.111.210
+2.191.115.176
+2.191.116.220
+5.10.248.174
+5.10.249.91
+5.42.223.178
+5.57.32.117
+5.57.32.181
+5.57.32.184
+5.57.39.168
+5.63.8.22
+5.74.7.121
+5.74.21.26
+5.74.26.180
+5.74.26.234
+5.74.38.29
+5.74.47.64
+5.74.52.237
+5.74.53.212
+5.74.56.152
+5.74.68.57
+5.74.69.171
+5.74.72.160
+5.74.76.182
+5.74.86.57
+5.74.90.172
+5.74.99.0
+5.74.101.93
+5.74.105.40
+5.74.109.253
+5.74.111.45
+5.74.113.74
+5.74.115.250
+5.74.133.146
+5.74.137.184
+5.74.139.166
+5.74.142.206
+5.74.160.227
+5.74.173.21
+5.74.175.47
+5.74.184.125
+5.74.188.152
+5.74.201.91
+5.74.219.145
+5.74.239.134
+5.74.239.234
+5.74.246.169
+5.144.129.5
+5.144.129.11
+5.144.129.32
+5.144.129.40
+5.144.129.63
+5.144.129.64
+5.144.129.66
+5.144.129.69
+5.144.129.110
+5.144.129.148
+5.144.129.151
+5.144.129.166
+5.144.129.216
+5.144.130.19
+5.144.130.26
+5.144.130.82
+5.144.130.96
+5.144.130.117
+5.144.130.159
+5.144.130.196
+5.144.130.214
+5.144.130.219
+5.144.130.245
+5.144.130.249
+5.144.131.245
+5.159.48.21
+5.159.48.40
+5.159.51.194
+5.159.51.207
+5.159.53.8
+5.160.40.6
+5.160.46.203
+5.160.55.3
+5.160.55.13
+5.160.79.248
+5.160.95.165
+5.160.96.210
+5.160.118.66
+5.160.186.19
+5.160.225.168
+5.160.242.53
+5.182.44.177
+5.190.86.86
+5.190.87.87
+5.198.161.51
+5.198.161.55
+5.200.134.206
+5.200.144.52
+5.200.150.169
+5.200.183.90
+5.200.186.226
+5.200.238.224
+5.201.165.192
+5.202.5.131
+5.202.50.82
+5.202.52.36
+5.202.67.5
+5.202.97.22
+5.232.125.241
+5.232.135.255
+5.233.57.47
+5.233.68.161
+5.233.183.139
+5.233.193.222
+5.234.3.0
+5.234.8.25
+5.234.9.41
+5.234.15.25
+5.234.17.120
+5.234.18.35
+5.234.18.94
+5.234.22.170
+5.234.28.171
+5.234.160.153
+5.234.198.228
+5.234.207.158
+5.234.208.42
+5.234.211.176
+5.235.163.209
+5.235.164.4
+5.235.166.97
+5.235.166.254
+5.235.168.38
+5.235.174.230
+5.235.176.185
+5.235.183.53
+5.235.198.109
+5.236.64.61
+5.236.75.164
+5.236.80.59
+5.236.117.196
+5.236.125.34
+5.236.193.186
+5.236.218.37
+5.236.224.25
+5.236.231.47
+5.236.248.172
+5.236.251.85
+5.237.171.184
+5.237.182.67
+5.237.184.184
+5.237.190.101
+5.237.200.102
+5.237.249.162
+5.238.77.204
+5.238.84.14
+5.238.128.102
+5.238.145.107
+5.238.162.247
+5.238.169.180
+5.238.171.106
+5.238.179.1
+5.238.187.194
+5.238.189.61
+5.238.192.15
+5.238.205.201
+5.238.213.205
+5.238.219.22
+5.238.225.98
+5.238.225.134
+5.238.226.108
+5.238.226.157
+5.238.229.48
+5.238.229.227
+5.238.236.60
+5.238.243.239
+5.239.10.166
+5.239.18.23
+5.239.32.209
+5.239.34.3
+5.239.43.82
+5.239.46.65
+5.239.53.249
+5.239.62.129
+5.239.77.105
+5.239.79.88
+5.239.81.68
+5.239.82.223
+5.239.84.107
+5.239.89.157
+5.239.92.43
+5.239.105.226
+5.239.106.140
+5.239.120.67
+31.7.72.178
+31.7.111.214
+31.47.40.31
+31.170.50.93
+31.171.222.195
+31.171.222.199
+31.184.140.207
+31.216.62.142
+37.32.10.23
+37.148.24.109
+37.148.46.201
+37.148.50.109
+37.148.51.63
+37.148.82.202
+37.148.82.225
+37.152.176.135
+37.152.191.247
+37.156.31.22
+37.202.155.93
+37.202.225.135
+37.202.225.137
+37.202.225.156
+37.202.225.160
+37.228.137.89
+37.255.173.82
+37.255.243.165
+45.65.59.252
+45.82.138.154
+45.89.236.235
+45.92.92.10
+45.92.92.18
+45.92.92.25
+45.92.92.41
+45.92.92.53
+45.92.92.69
+45.92.92.73
+45.92.92.76
+45.92.92.151
+45.92.92.175
+45.92.92.196
+45.92.94.92
+45.92.94.96
+45.135.243.138
+45.138.132.238
+45.138.133.43
+45.138.133.55
+45.138.133.59
+45.138.133.63
+45.138.133.146
+45.138.133.161
+45.138.134.19
+45.138.134.44
+45.138.134.81
+45.138.134.134
+45.138.134.142
+45.138.134.169
+45.138.134.176
+45.138.134.251
+45.138.135.179
+45.147.77.157
+45.149.79.40
+45.156.185.85
+45.159.113.35
+45.159.149.196
+45.159.151.14
+45.159.151.83
+45.159.151.137
+46.18.248.134
+46.100.5.51
+46.100.47.7
+46.100.59.39
+46.100.145.243
+46.100.177.40
+46.167.141.24
+46.209.67.146
+46.209.212.75
+46.245.1.100
+46.245.8.151
+46.245.10.1
+46.245.16.4
+46.245.19.220
+46.245.27.65
+46.245.34.19
+46.245.39.187
+46.245.40.151
+46.245.43.89
+46.245.45.43
+46.245.77.2
+46.245.86.27
+46.245.91.230
+46.245.115.37
+62.3.41.64
+62.3.41.95
+62.3.42.23
+62.60.133.3
+62.60.133.8
+62.60.133.28
+62.60.133.35
+62.60.133.46
+62.60.133.57
+62.60.133.60
+62.60.133.81
+62.60.133.82
+62.60.133.101
+62.60.133.129
+62.60.133.193
+62.60.133.199
+62.60.133.204
+62.60.163.226
+62.60.195.95
+62.60.201.19
+62.60.201.23
+62.60.201.91
+62.60.201.114
+62.60.201.129
+62.60.201.150
+62.60.201.181
+62.60.201.188
+62.60.201.237
+62.60.204.166
+62.60.205.96
+62.60.205.165
+62.60.205.190
+62.60.205.205
+62.60.205.206
+62.60.205.252
+62.60.206.155
+62.60.207.78
+62.60.211.198
+62.60.211.201
+62.60.214.83
+62.204.61.159
+62.220.117.130
+66.79.110.174
+77.81.144.148
+77.81.146.166
+77.81.152.206
+77.104.118.2
+77.237.67.13
+77.237.75.148
+77.237.83.30
+78.38.29.129
+78.38.182.201
+78.38.189.230
+78.39.62.36
+78.39.81.46
+78.39.122.99
+78.39.146.149
+78.39.147.33
+78.39.194.10
+78.39.224.155
+78.39.245.8
+78.39.248.252
+78.39.255.27
+78.109.202.101
+78.157.33.201
+78.157.35.39
+78.157.35.47
+78.157.35.96
+78.157.38.200
+78.157.40.143
+78.157.40.184
+78.157.40.224
+78.157.41.79
+78.157.43.64
+78.157.43.127
+78.157.45.32
+78.157.45.63
+78.157.45.143
+78.157.46.111
+78.157.50.16
+78.157.50.248
+78.157.52.8
+78.157.52.10
+78.157.57.159
+78.157.57.233
+78.157.58.47
+78.158.179.134
+79.127.125.126
+79.127.126.68
+79.127.127.55
+79.175.134.65
+79.175.167.4
+79.175.171.67
+79.175.187.131
+80.191.62.6
+80.191.65.174
+80.191.103.98
+80.191.110.242
+80.191.170.173
+80.210.27.243
+80.210.34.217
+80.210.136.8
+80.210.140.143
+80.210.142.120
+80.210.160.220
+80.210.168.80
+80.210.170.69
+80.210.171.8
+80.210.171.49
+80.210.177.84
+81.12.20.85
+81.12.54.213
+81.12.54.248
+81.12.104.84
+81.12.106.190
+81.12.108.142
+81.16.121.120
+81.16.124.109
+81.91.156.130
+82.99.206.97
+84.47.239.13
+84.241.0.112
+84.241.2.163
+84.241.7.245
+84.241.19.157
+84.241.28.59
+84.241.34.116
+84.241.36.70
+85.9.98.70
+85.9.122.167
+85.9.125.118
+85.133.182.163
+85.133.184.122
+85.133.187.22
+85.185.17.75
+85.185.17.115
+85.185.52.32
+85.185.54.129
+85.185.55.190
+85.185.75.108
+85.185.86.212
+85.185.205.28
+85.185.216.27
+85.208.253.58
+85.208.254.65
+86.104.32.35
+86.104.104.68
+86.105.41.35
+86.105.42.20
+86.105.47.95
+86.106.142.123
+86.107.148.140
+86.107.158.131
+87.107.102.4
+87.107.104.60
+87.236.211.12
+87.236.211.83
+87.248.130.22
+87.248.131.112
+87.248.131.176
+88.135.75.144
+89.32.196.33
+89.32.248.22
+89.32.251.75
+89.34.96.78
+89.37.103.20
+89.38.24.35
+89.42.199.197
+89.42.209.50
+89.42.210.237
+89.42.211.230
+89.43.216.130
+89.43.219.10
+89.43.227.128
+89.46.94.42
+89.46.94.164
+89.46.218.69
+89.46.218.109
+89.46.218.127
+89.46.219.82
+89.46.219.199
+89.144.131.138
+89.144.137.223
+89.144.137.233
+89.144.137.244
+89.144.137.247
+89.144.137.255
+89.144.138.156
+89.144.139.1
+89.144.139.7
+89.144.139.11
+89.144.139.25
+89.144.139.36
+89.144.139.60
+89.144.139.61
+89.144.139.69
+89.144.139.80
+89.144.139.81
+89.144.139.83
+89.144.139.99
+89.144.139.100
+89.144.139.107
+89.144.139.109
+89.144.139.111
+89.144.139.113
+89.144.139.120
+89.144.149.191
+89.144.154.235
+89.144.166.172
+89.144.166.191
+89.144.166.193
+89.144.166.217
+89.144.166.242
+89.144.175.238
+89.144.189.137
+89.144.189.177
+89.144.189.191
+89.144.189.232
+89.144.189.234
+89.219.64.174
+89.219.66.175
+89.219.73.15
+89.219.74.106
+89.219.77.0
+89.219.78.56
+89.219.93.252
+89.219.97.108
+89.219.99.81
+89.219.107.135
+89.219.107.220
+89.219.110.207
+89.219.115.60
+89.219.116.22
+89.219.118.105
+89.219.120.2
+89.219.123.224
+89.219.197.210
+89.219.202.225
+89.219.233.5
+89.219.252.178
+89.219.255.108
+89.235.103.95
+91.92.126.7
+91.92.150.122
+91.92.164.144
+91.92.205.110
+91.92.208.114
+91.92.231.138
+91.199.27.108
+91.220.113.242
+91.223.116.140
+91.228.132.22
+91.247.171.251
+92.42.53.30
+92.114.48.234
+93.114.105.206
+93.115.149.15
+93.115.149.237
+93.117.33.12
+93.117.34.217
+93.117.35.8
+93.117.38.185
+93.117.43.30
+93.118.114.23
+93.118.116.117
+93.118.123.32
+93.118.125.189
+93.118.145.201
+93.126.61.205
+94.74.128.171
+94.101.176.247
+94.182.39.201
+94.182.39.230
+94.182.91.237
+94.182.92.68
+94.182.106.3
+94.182.178.90
+94.182.181.250
+94.182.186.6
+94.182.192.220
+94.182.195.189
+94.182.209.62
+94.182.210.200
+94.182.216.105
+94.182.227.239
+94.182.251.1
+94.183.180.71
+95.38.24.226
+95.38.34.104
+95.38.103.219
+95.38.209.209
+109.109.32.12
+109.109.32.89
+109.109.32.97
+109.109.32.98
+109.109.32.103
+109.109.32.217
+109.109.34.76
+109.109.34.85
+109.109.34.123
+109.109.34.139
+109.109.34.183
+109.109.34.185
+109.109.34.188
+109.109.34.199
+109.109.34.213
+109.109.34.218
+109.109.34.231
+109.109.34.234
+109.109.34.237
+109.109.34.249
+109.109.35.12
+109.109.35.75
+109.109.35.125
+109.109.37.159
+109.109.40.58
+109.109.41.24
+109.109.43.141
+109.109.43.142
+109.109.43.145
+109.109.43.148
+109.109.43.194
+109.109.43.207
+109.109.43.208
+109.109.43.219
+109.109.43.228
+109.109.43.231
+109.109.43.244
+109.109.43.251
+109.109.45.21
+109.109.45.69
+109.109.45.82
+109.109.45.86
+109.109.45.97
+109.109.47.39
+109.109.47.58
+109.109.47.61
+109.109.47.68
+109.109.47.71
+109.109.47.88
+109.109.47.89
+109.109.47.110
+109.109.47.111
+109.109.47.118
+109.109.53.30
+109.109.54.39
+109.109.54.50
+109.109.54.51
+109.109.54.77
+109.109.54.89
+109.109.54.109
+109.109.54.141
+109.109.54.146
+109.109.54.166
+109.109.54.168
+109.109.54.207
+109.109.54.209
+109.109.54.212
+109.109.58.8
+109.109.58.36
+109.109.58.43
+109.109.58.76
+109.109.58.166
+109.109.59.6
+109.109.59.24
+109.109.59.25
+109.109.59.26
+109.109.59.35
+109.109.59.52
+109.109.59.53
+109.109.59.55
+109.109.59.84
+109.109.59.88
+109.109.59.99
+109.109.59.231
+109.109.60.7
+109.109.60.40
+109.109.60.43
+109.109.60.69
+109.109.60.73
+109.109.60.93
+109.109.60.98
+109.109.60.102
+109.109.60.116
+109.109.60.176
+109.109.60.204
+109.109.61.208
+109.109.61.209
+109.109.61.216
+109.109.61.218
+109.109.61.232
+109.109.62.0
+109.109.62.2
+109.109.63.130
+109.109.63.136
+109.109.63.152
+109.109.63.193
+109.109.63.196
+109.109.63.208
+109.109.63.241
+109.109.63.253
+109.122.251.188
+109.206.252.43
+128.65.181.82
+130.185.77.137
+130.193.77.37
+130.193.77.124
+151.232.80.169
+151.234.25.189
+151.234.29.56
+151.234.75.123
+151.234.186.93
+151.234.245.87
+151.235.13.16
+151.235.18.98
+151.235.123.250
+151.235.125.168
+151.235.126.91
+159.20.99.117
+171.22.24.162
+176.62.144.37
+176.62.144.44
+176.65.224.95
+178.173.140.41
+178.173.140.129
+178.173.148.167
+178.173.211.35
+178.173.216.97
+178.173.218.96
+178.173.221.167
+178.216.248.85
+178.216.251.244
+178.236.105.153
+178.236.106.202
+178.238.196.223
+178.239.147.81
+178.252.134.188
+178.252.166.146
+178.252.181.101
+185.3.202.129
+185.4.30.50
+185.8.175.98
+185.10.75.8
+185.10.75.75
+185.10.75.199
+185.18.213.84
+185.41.3.106
+185.42.225.197
+185.44.36.51
+185.53.142.229
+185.55.224.119
+185.55.225.182
+185.58.241.89
+185.59.112.25
+185.73.112.229
+185.73.226.28
+185.79.156.242
+185.79.157.196
+185.83.113.170
+185.83.183.95
+185.83.183.125
+185.84.158.30
+185.88.153.190
+185.88.154.59
+185.88.154.223
+185.88.178.43
+185.88.178.53
+185.94.97.11
+185.94.99.26
+185.94.99.37
+185.94.99.245
+185.97.116.171
+185.100.46.141
+185.103.84.39
+185.109.74.238
+185.110.219.40
+185.111.83.10
+185.112.149.97
+185.112.149.115
+185.112.149.118
+185.113.9.175
+185.113.58.197
+185.113.59.202
+185.117.50.230
+185.118.155.62
+185.119.167.5
+185.120.219.76
+185.120.221.228
+185.124.115.15
+185.129.169.78
+185.129.200.200
+185.131.88.224
+185.131.152.196
+185.137.27.47
+185.140.240.8
+185.141.104.86
+185.141.105.237
+185.141.105.238
+185.141.132.69
+185.141.134.205
+185.147.41.71
+185.149.192.24
+185.149.192.165
+185.164.72.9
+185.164.73.213
+185.165.116.184
+185.165.118.34
+185.165.118.245
+185.169.6.195
+185.190.39.68
+185.191.76.146
+185.192.10.2
+185.192.112.4
+185.192.112.37
+185.192.114.72
+185.192.114.109
+185.192.114.136
+185.192.114.152
+185.192.114.251
+185.208.174.78
+185.208.174.125
+185.208.175.79
+185.211.59.123
+185.231.112.172
+185.231.115.129
+185.231.115.167
+185.231.181.225
+185.232.154.79
+185.235.196.141
+185.235.197.79
+185.243.50.0
+185.243.50.3
+185.243.50.4
+185.243.50.5
+185.243.50.6
+185.243.50.8
+185.243.50.9
+185.243.50.10
+185.243.50.11
+185.243.50.12
+185.243.50.13
+185.243.50.14
+185.243.50.15
+185.243.50.17
+185.243.50.18
+185.243.50.19
+185.243.50.20
+185.243.50.21
+185.243.50.22
+185.243.50.23
+185.243.50.24
+185.243.50.25
+185.243.50.26
+185.243.50.27
+185.243.50.28
+185.243.50.29
+185.243.50.30
+185.243.50.31
+185.243.50.32
+185.243.50.34
+185.243.50.35
+185.243.50.36
+185.243.50.37
+185.243.50.38
+185.243.50.39
+185.243.50.40
+185.243.50.41
+185.243.50.42
+185.243.50.43
+185.243.50.44
+185.243.50.45
+185.243.50.46
+185.243.50.47
+185.243.50.48
+185.243.50.49
+185.243.50.50
+185.243.50.51
+185.243.50.52
+185.243.50.53
+185.243.50.54
+185.243.50.55
+185.243.50.56
+185.243.50.57
+185.243.50.59
+185.243.50.60
+185.243.50.61
+185.243.50.62
+185.243.50.63
+185.243.50.64
+185.243.50.65
+185.243.50.67
+185.243.50.68
+185.243.50.70
+185.243.50.71
+185.243.50.72
+185.243.50.73
+185.243.50.74
+185.243.50.75
+185.243.50.76
+185.243.50.77
+185.243.50.78
+185.243.50.79
+185.243.50.80
+185.243.50.81
+185.243.50.82
+185.243.50.84
+185.243.50.85
+185.243.50.86
+185.243.50.87
+185.243.50.88
+185.243.50.89
+185.243.50.90
+185.243.50.91
+185.243.50.92
+185.243.50.93
+185.243.50.95
+185.243.50.96
+185.243.50.97
+185.243.50.98
+185.243.50.99
+185.243.50.100
+185.243.50.101
+185.243.50.103
+185.243.50.104
+185.243.50.105
+185.243.50.106
+185.243.50.107
+185.243.50.108
+185.243.50.109
+185.243.50.110
+185.243.50.111
+185.243.50.112
+185.243.50.113
+185.243.50.115
+185.243.50.116
+185.243.50.117
+185.243.50.118
+185.243.50.119
+185.243.50.121
+185.243.50.122
+185.243.50.123
+185.243.50.124
+185.243.50.126
+185.243.50.127
+185.243.50.129
+185.243.50.130
+185.243.50.131
+185.243.50.132
+185.243.50.133
+185.243.50.134
+185.243.50.135
+185.243.50.136
+185.243.50.137
+185.243.50.138
+185.243.50.139
+185.243.50.140
+185.243.50.141
+185.243.50.142
+185.243.50.143
+185.243.50.144
+185.243.50.145
+185.243.50.146
+185.243.50.147
+185.243.50.148
+185.243.50.149
+185.243.50.150
+185.243.50.151
+185.243.50.152
+185.243.50.153
+185.243.50.154
+185.243.50.157
+185.243.50.158
+185.243.50.159
+185.243.50.161
+185.243.50.162
+185.243.50.164
+185.243.50.166
+185.243.50.168
+185.243.50.169
+185.243.50.170
+185.243.50.171
+185.243.50.172
+185.243.50.173
+185.243.50.174
+185.243.50.175
+185.243.50.176
+185.243.50.177
+185.243.50.178
+185.243.50.179
+185.243.50.180
+185.243.50.181
+185.243.50.182
+185.243.50.184
+185.243.50.185
+185.243.50.186
+185.243.50.187
+185.243.50.188
+185.243.50.189
+185.243.50.190
+185.243.50.191
+185.243.50.193
+185.243.50.194
+185.243.50.196
+185.243.50.197
+185.243.50.200
+185.243.50.201
+185.243.50.202
+185.243.50.205
+185.243.50.206
+185.243.50.207
+185.243.50.208
+185.243.50.209
+185.243.50.210
+185.243.50.211
+185.243.50.212
+185.243.50.213
+185.243.50.214
+185.243.50.217
+185.243.50.218
+185.243.50.219
+185.243.50.220
+185.243.50.221
+185.243.50.222
+185.243.50.223
+185.243.50.224
+185.243.50.225
+185.243.50.226
+185.243.50.227
+185.243.50.228
+185.243.50.231
+185.243.50.232
+185.243.50.234
+185.243.50.236
+185.243.50.237
+185.243.50.238
+185.243.50.239
+185.243.50.241
+185.243.50.242
+185.243.50.243
+185.243.50.244
+185.243.50.245
+185.243.50.246
+185.243.50.247
+185.243.50.249
+185.243.50.250
+185.243.50.251
+185.243.50.252
+185.243.50.253
+185.243.50.254
+185.255.88.55
+185.255.88.128
+188.0.240.133
+188.0.249.52
+188.121.100.132
+188.121.104.21
+188.121.117.78
+188.121.119.175
+188.121.123.128
+188.208.59.159
+188.208.151.64
+188.209.6.170
+188.209.68.61
+188.209.71.69
+188.209.76.133
+188.209.78.143
+188.210.97.80
+188.210.116.62
+188.211.68.160
+188.211.70.150
+188.211.87.38
+188.211.99.14
+188.211.99.23
+188.211.103.126
+188.211.108.135
+188.211.108.255
+188.211.113.11
+188.211.114.213
+188.211.121.143
+188.211.123.106
+188.211.126.196
+188.212.22.21
+188.212.76.158
+188.212.80.155
+188.213.66.140
+188.213.79.54
+188.213.181.202
+188.213.190.157
+188.215.165.169
+193.39.9.161
+193.58.119.108
+193.58.119.223
+193.105.234.127
+193.141.64.116
+193.141.65.182
+193.162.129.210
+193.228.90.213
+193.228.136.200
+193.242.125.194
+194.5.179.18
+194.5.195.74
+194.5.195.170
+194.41.51.39
+194.62.43.124
+194.150.70.88
+194.225.40.115
+195.26.27.173
+195.245.70.230
+212.23.201.215
+212.33.202.232
+212.80.24.24
+212.120.193.152
+212.120.194.55
+212.120.205.188
+212.120.212.25
+212.120.216.60
+212.120.221.106
+212.120.223.208
+213.176.0.14
+213.176.29.251
+213.195.60.63
+213.232.124.11
+217.11.24.233
+217.77.117.252
+217.144.106.34
+217.144.107.175
+217.170.251.3
+217.170.252.66
+217.170.252.156
+217.170.252.165
+217.171.149.19
+217.171.150.0
+217.172.98.173
+217.218.59.18
+217.218.66.24
+217.218.66.54
+217.218.72.215
+217.218.91.126
+217.218.102.173
+217.218.121.219
+217.218.126.180
+217.218.126.192
+217.218.147.109
+217.218.162.250
+217.218.171.21
+217.218.231.165
+217.219.78.210
+217.219.113.176
+217.219.146.132
+217.219.162.171
+217.219.162.179
+217.219.162.190
+217.219.219.68
+217.219.247.178
+217.219.247.179
+217.219.247.180
+217.219.247.182
+217.219.247.186
+217.219.247.208
+217.219.247.226
+217.219.250.67
+217.219.251.250
+2.184.237.250
+2.184.239.96
+2.185.60.53
+2.185.100.114
+2.185.111.42
+2.185.115.187
+2.185.118.190
+2.185.119.25
+2.185.121.161
+2.185.123.125
+2.185.144.18
+2.185.144.71
+2.185.146.147
+2.185.152.23
+2.185.228.3
+2.185.228.166
+2.185.229.141
+2.185.229.223
+2.185.232.202
+2.185.233.97
+2.185.234.29
+2.185.251.169
+2.185.254.215
+2.186.12.33
+2.186.12.72
+2.186.12.169
+2.186.14.53
+2.186.114.102
+2.186.118.65
+2.186.121.65
+2.186.122.56
+2.186.123.180
+2.186.123.193
+2.187.25.177
+2.187.32.105
+2.187.59.28
+2.187.97.193
+2.187.150.211
+2.187.188.97
+2.187.189.192
+2.188.2.253
+2.188.15.200
+2.188.15.201
+2.188.15.202
+2.188.21.20
+2.188.21.90
+2.188.21.100
+2.188.21.120
+2.188.21.130
+2.188.21.190
+2.188.21.200
+2.188.21.230
+2.188.21.240
+2.188.26.10
+2.188.43.88
+2.188.54.1
+2.188.54.2
+2.188.54.54
+2.188.54.55
+2.188.58.12
+2.188.73.81
+2.188.163.135
+2.188.163.136
+2.188.164.29
+2.188.164.30
+2.188.165.106
+2.188.168.184
+2.188.184.19
+2.188.212.158
+2.188.218.179
+2.188.218.180
+2.188.218.181
+2.188.228.114
+2.188.230.127
+2.188.235.83
+2.188.236.82
+2.189.1.10
+2.189.1.13
+2.189.1.15
+2.189.1.19
+2.189.1.253
+2.189.4.29
+2.189.4.30
+2.189.5.183
+2.189.9.56
+2.189.9.87
+2.189.44.44
+2.189.58.3
+2.189.87.170
+2.189.90.130
+2.189.92.1
+2.189.120.111
+2.189.142.70
+2.189.147.101
+2.189.147.211
+2.189.160.131
+2.189.161.45
+2.189.162.131
+2.189.162.136
+2.189.172.227
+2.189.172.229
+2.189.172.233
+2.189.173.198
+2.189.188.54
+2.189.188.56
+2.189.188.62
+2.189.188.190
+2.189.217.95
+2.189.217.251
+2.189.222.223
+2.189.242.36
+2.189.242.86
+2.189.242.100
+2.189.242.107
+2.189.242.109
+2.189.243.18
+2.189.243.19
+2.189.243.21
+2.189.243.25
+2.189.243.101
+2.189.243.103
+2.189.243.226
+2.189.243.228
+2.189.254.58
+2.189.254.67
+2.189.255.21
+2.189.255.130
+2.189.255.227
+2.190.3.49
+2.190.9.251
+2.190.12.228
+2.190.13.15
+2.190.14.71
+2.190.17.170
+2.190.18.195
+2.190.31.215
+2.190.35.50
+2.190.36.61
+2.190.37.214
+2.190.37.229
+2.190.41.98
+2.190.43.76
+2.190.44.114
+2.190.44.119
+2.190.48.163
+2.190.49.111
+2.190.53.64
+2.190.53.68
+2.190.53.92
+2.190.53.100
+2.190.55.74
+2.190.55.120
+2.190.59.91
+2.190.59.155
+2.190.73.43
+2.190.73.67
+2.190.78.115
+2.190.79.245
+2.190.86.118
+2.190.92.26
+2.190.94.100
+2.190.100.174
+2.190.108.91
+2.190.111.134
+2.190.113.182
+2.190.133.106
+2.190.137.215
+2.190.139.102
+2.190.144.183
+2.190.147.151
+2.190.152.187
+2.190.153.67
+2.190.159.244
+2.190.163.207
+2.190.169.87
+2.190.179.133
+2.190.182.32
+2.190.183.92
+2.190.185.210
+2.190.189.114
+2.190.196.38
+2.190.197.33
+2.190.197.175
+2.190.208.237
+2.190.211.50
+2.190.218.16
+2.190.218.137
+2.190.222.23
+2.190.225.89
+2.190.226.224
+2.190.230.164
+2.190.239.52
+2.190.254.192
+2.191.1.142
+2.191.3.59
+2.191.7.101
+2.191.11.236
+2.191.13.68
+2.191.14.96
+2.191.17.34
+2.191.19.25
+2.191.20.200
+2.191.30.238
+2.191.34.90
+2.191.37.81
+2.191.37.155
+2.191.38.203
+2.191.42.29
+2.191.44.179
+2.191.46.6
+2.191.50.40
+2.191.53.152
+2.191.59.4
+2.191.59.95
+2.191.65.208
+2.191.66.14
+2.191.66.48
+2.191.70.85
+2.191.78.251
+2.191.79.86
+2.191.83.25
+2.191.92.195
+2.191.95.198
+2.191.112.91
+2.191.114.44
+2.191.119.38
+2.191.120.15
+5.10.248.4
+5.10.248.7
+5.10.248.13
+5.10.248.23
+5.10.248.26
+5.10.248.31
+5.10.248.33
+5.10.248.41
+5.10.248.57
+5.10.248.65
+5.10.248.67
+5.10.248.88
+5.10.248.92
+5.10.248.95
+5.10.248.99
+5.10.248.107
+5.10.248.110
+5.10.248.117
+5.10.248.119
+5.10.248.128
+5.10.248.138
+5.10.248.155
+5.10.248.158
+5.10.248.160
+5.10.248.164
+5.10.248.169
+5.10.248.170
+5.10.248.171
+5.10.248.183
+5.10.248.215
+5.10.248.225
+5.10.248.237
+5.10.248.240
+5.10.248.241
+5.10.249.2
+5.10.249.24
+5.10.249.44
+5.10.249.79
+5.10.249.105
+5.10.249.138
+5.10.249.140
+5.10.249.175
+5.10.249.184
+5.10.249.208
+5.10.249.233
+5.10.249.242
+5.22.193.2
+5.22.193.3
+5.22.200.250
+5.22.203.46
+5.22.203.47
+5.42.217.8
+5.42.217.25
+5.42.217.76
+5.42.217.181
+5.42.217.186
+5.42.217.207
+5.42.217.208
+5.42.223.9
+5.42.223.119
+5.42.223.160
+5.42.223.179
+5.42.223.189
+5.42.223.247
+5.42.223.254
+5.56.128.128
+5.56.132.47
+5.56.132.69
+5.56.132.70
+5.56.132.76
+5.56.132.79
+5.56.132.89
+5.56.132.93
+5.56.132.97
+5.56.132.99
+5.56.132.100
+5.56.132.109
+5.56.132.120
+5.56.132.121
+5.56.132.126
+5.56.132.132
+5.56.132.145
+5.56.132.148
+5.56.132.150
+5.56.132.157
+5.56.132.169
+5.56.132.170
+5.56.132.174
+5.56.132.176
+5.56.132.177
+5.56.132.180
+5.56.132.182
+5.56.132.183
+5.56.132.185
+5.56.132.186
+5.56.132.188
+5.56.132.189
+5.56.132.203
+5.56.132.218
+5.56.132.219
+5.56.132.220
+5.56.132.235
+5.56.132.251
+5.56.132.253
+5.56.134.9
+5.56.134.51
+5.56.134.95
+5.56.134.153
+5.56.134.237
+5.56.135.5
+5.56.135.15
+5.56.135.16
+5.56.135.25
+5.56.135.131
+5.56.135.132
+5.56.135.196
+5.56.135.218
+5.56.135.244
+5.57.32.2
+5.57.32.29
+5.57.32.32
+5.57.32.103
+5.57.32.106
+5.57.32.125
+5.57.32.140
+5.57.32.163
+5.57.32.164
+5.57.32.165
+5.57.32.167
+5.57.32.168
+5.57.32.169
+5.57.32.170
+5.57.32.171
+5.57.32.172
+5.57.32.174
+5.57.32.205
+5.57.32.226
+5.57.32.228
+5.57.32.229
+5.57.32.231
+5.57.32.232
+5.57.32.236
+5.57.32.237
+5.57.32.239
+5.57.32.240
+5.57.32.242
+5.57.32.243
+5.57.32.244
+5.57.32.245
+5.57.32.246
+5.57.32.248
+5.57.32.249
+5.57.32.252
+5.57.32.253
+5.57.34.4
+5.57.34.48
+5.57.34.53
+5.57.34.121
+5.57.34.140
+5.57.34.142
+5.57.34.194
+5.57.34.195
+5.57.34.197
+5.57.34.229
+5.57.34.230
+5.57.34.231
+5.57.34.232
+5.57.34.233
+5.57.34.234
+5.57.34.235
+5.57.34.236
+5.57.34.237
+5.57.34.238
+5.57.34.242
+5.57.34.243
+5.57.34.244
+5.57.34.246
+5.57.34.249
+5.57.34.250
+5.57.34.251
+5.57.34.252
+5.57.35.57
+5.57.35.112
+5.57.35.181
+5.57.35.229
+5.57.37.20
+5.57.37.40
+5.57.37.84
+5.57.37.89
+5.57.37.144
+5.57.37.224
+5.57.39.16
+5.57.39.80
+5.57.39.101
+5.57.39.114
+5.57.39.178
+5.57.39.189
+5.57.39.197
+5.57.39.230
+5.61.24.2
+5.61.24.5
+5.61.24.15
+5.61.24.24
+5.61.24.30
+5.61.24.64
+5.61.24.78
+5.61.24.126
+5.61.24.202
+5.61.24.236
+5.61.25.2
+5.61.25.34
+5.61.25.55
+5.61.25.132
+5.61.25.226
+5.61.26.4
+5.61.26.5
+5.61.28.2
+5.61.28.12
+5.61.28.34
+5.61.28.38
+5.61.28.44
+5.61.28.48
+5.61.28.102
+5.61.28.103
+5.61.28.109
+5.61.28.113
+5.61.28.236
+5.61.28.239
+5.61.28.245
+5.61.29.43
+5.61.29.113
+5.61.29.135
+5.61.29.140
+5.61.29.165
+5.61.29.168
+5.61.29.170
+5.61.29.181
+5.61.29.183
+5.61.29.210
+5.61.29.212
+5.61.29.230
+5.61.30.20
+5.61.30.42
+5.61.30.84
+5.61.30.99
+5.61.30.100
+5.61.30.101
+5.61.30.102
+5.61.30.116
+5.61.30.132
+5.61.30.135
+5.61.30.145
+5.61.30.164
+5.61.30.195
+5.61.30.230
+5.61.30.233
+5.61.30.238
+5.61.31.35
+5.61.31.72
+5.61.31.84
+5.61.31.88
+5.61.31.101
+5.61.31.103
+5.61.31.106
+5.61.31.148
+5.61.31.170
+5.61.31.184
+5.61.31.190
+5.61.31.214
+5.61.31.236
+5.61.31.241
+5.62.190.164
+5.63.8.38
+5.63.8.43
+5.63.8.44
+5.63.8.46
+5.63.8.62
+5.63.8.70
+5.63.8.83
+5.63.8.130
+5.63.8.134
+5.63.8.138
+5.63.8.142
+5.63.8.146
+5.63.8.155
+5.63.8.186
+5.63.8.190
+5.63.8.243
+5.63.8.247
+5.63.8.248
+5.63.8.252
+5.63.8.253
+5.63.8.254
+5.63.9.35
+5.63.9.36
+5.63.9.38
+5.63.9.39
+5.63.9.40
+5.63.9.41
+5.63.9.42
+5.63.9.43
+5.63.9.44
+5.63.9.45
+5.63.9.142
+5.63.9.179
+5.63.9.180
+5.63.9.181
+5.63.9.202
+5.63.9.205
+5.63.9.206
+5.63.9.219
+5.63.9.222
+5.63.9.242
+5.63.9.251
+5.63.10.115
+5.63.10.122
+5.63.10.202
+5.63.10.227
+5.63.10.228
+5.63.13.6
+5.63.13.10
+5.63.13.14
+5.63.13.61
+5.63.13.62
+5.63.13.91
+5.63.13.92
+5.63.13.93
+5.63.13.94
+5.63.13.98
+5.63.13.125
+5.63.13.147
+5.63.13.158
+5.63.13.172
+5.63.13.174
+5.63.13.179
+5.63.13.183
+5.63.13.187
+5.63.13.188
+5.63.13.212
+5.63.13.246
+5.63.13.250
+5.63.15.2
+5.63.15.95
+5.74.13.212
+5.74.20.118
+5.74.25.40
+5.74.27.137
+5.74.30.157
+5.74.35.175
+5.74.40.57
+5.74.64.61
+5.74.70.72
+5.74.80.124
+5.74.82.62
+5.74.85.54
+5.74.87.230
+5.74.89.141
+5.74.91.84
+5.74.93.18
+5.74.94.246
+5.74.103.0
+5.74.108.253
+5.74.116.99
+5.74.157.17
+5.74.159.248
+5.74.168.73
+5.74.169.165
+5.74.173.111
+5.74.177.58
+5.74.179.196
+5.74.193.165
+5.74.201.57
+5.74.204.86
+5.74.220.174
+5.74.226.60
+5.74.229.186
+5.74.230.137
+5.74.233.4
+5.74.247.49
+5.74.249.133
+5.74.249.152
+5.74.250.193
+5.74.254.130
+5.74.255.47
+5.106.6.30
+5.106.18.134
+5.106.19.21
+5.106.28.197
+5.106.50.108
+5.106.52.108
+5.134.192.129
+5.134.194.83
+5.144.128.17
+5.144.128.20
+5.144.128.21
+5.144.129.2
+5.144.129.4
+5.144.129.6
+5.144.129.7
+5.144.129.8
+5.144.129.9
+5.144.129.10
+5.144.129.12
+5.144.129.14
+5.144.129.15
+5.144.129.16
+5.144.129.18
+5.144.129.19
+5.144.129.20
+5.144.129.21
+5.144.129.22
+5.144.129.23
+5.144.129.24
+5.144.129.26
+5.144.129.27
+5.144.129.28
+5.144.129.29
+5.144.129.30
+5.144.129.31
+5.144.129.33
+5.144.129.34
+5.144.129.35
+5.144.129.36
+5.144.129.37
+5.144.129.38
+5.144.129.39
+5.144.129.41
+5.144.129.42
+5.144.129.43
+5.144.129.44
+5.144.129.45
+5.144.129.46
+5.144.129.47
+5.144.129.48
+5.144.129.50
+5.144.129.51
+5.144.129.53
+5.144.129.54
+5.144.129.55
+5.144.129.56
+5.144.129.58
+5.144.129.59
+5.144.129.60
+5.144.129.61
+5.144.129.62
+5.144.129.65
+5.144.129.67
+5.144.129.68
+5.144.129.70
+5.144.129.71
+5.144.129.72
+5.144.129.73
+5.144.129.74
+5.144.129.75
+5.144.129.76
+5.144.129.77
+5.144.129.78
+5.144.129.79
+5.144.129.80
+5.144.129.81
+5.144.129.82
+5.144.129.84
+5.144.129.85
+5.144.129.86
+5.144.129.87
+5.144.129.88
+5.144.129.89
+5.144.129.90
+5.144.129.91
+5.144.129.92
+5.144.129.93
+5.144.129.94
+5.144.129.95
+5.144.129.96
+5.144.129.97
+5.144.129.98
+5.144.129.99
+5.144.129.102
+5.144.129.103
+5.144.129.104
+5.144.129.105
+5.144.129.106
+5.144.129.107
+5.144.129.108
+5.144.129.109
+5.144.129.112
+5.144.129.113
+5.144.129.114
+5.144.129.115
+5.144.129.116
+5.144.129.117
+5.144.129.118
+5.144.129.119
+5.144.129.120
+5.144.129.121
+5.144.129.122
+5.144.129.123
+5.144.129.124
+5.144.129.125
+5.144.129.126
+5.144.129.127
+5.144.129.128
+5.144.129.129
+5.144.129.130
+5.144.129.131
+5.144.129.132
+5.144.129.133
+5.144.129.134
+5.144.129.135
+5.144.129.136
+5.144.129.137
+5.144.129.139
+5.144.129.140
+5.144.129.141
+5.144.129.142
+5.144.129.143
+5.144.129.144
+5.144.129.145
+5.144.129.146
+5.144.129.147
+5.144.129.149
+5.144.129.150
+5.144.129.152
+5.144.129.153
+5.144.129.154
+5.144.129.155
+5.144.129.156
+5.144.129.157
+5.144.129.158
+5.144.129.159
+5.144.129.160
+5.144.129.161
+5.144.129.162
+5.144.129.163
+5.144.129.164
+5.144.129.165
+5.144.129.167
+5.144.129.168
+5.144.129.169
+5.144.129.170
+5.144.129.171
+5.144.129.172
+5.144.129.173
+5.144.129.174
+5.144.129.175
+5.144.129.176
+5.144.129.178
+5.144.129.179
+5.144.129.180
+5.144.129.181
+5.144.129.182
+5.144.129.183
+5.144.129.184
+5.144.129.185
+5.144.129.186
+5.144.129.187
+5.144.129.188
+5.144.129.190
+5.144.129.191
+5.144.129.192
+5.144.129.193
+5.144.129.194
+5.144.129.195
+5.144.129.196
+5.144.129.197
+5.144.129.198
+5.144.129.199
+5.144.129.200
+5.144.129.201
+5.144.129.202
+5.144.129.203
+5.144.129.204
+5.144.129.205
+5.144.129.206
+5.144.129.207
+5.144.129.208
+5.144.129.209
+5.144.129.210
+5.144.129.211
+5.144.129.212
+5.144.129.213
+5.144.129.214
+5.144.129.215
+5.144.129.217
+5.144.129.218
+5.144.129.219
+5.144.129.220
+5.144.129.221
+5.144.129.222
+5.144.129.223
+5.144.129.224
+5.144.129.225
+5.144.129.226
+5.144.129.227
+5.144.129.228
+5.144.129.229
+5.144.129.230
+5.144.129.231
+5.144.129.232
+5.144.129.233
+5.144.129.234
+5.144.129.235
+5.144.129.237
+5.144.129.238
+5.144.129.239
+5.144.129.240
+5.144.129.241
+5.144.129.242
+5.144.129.243
+5.144.129.244
+5.144.129.245
+5.144.129.246
+5.144.129.247
+5.144.129.248
+5.144.129.249
+5.144.129.250
+5.144.129.251
+5.144.129.252
+5.144.129.253
+5.144.129.254
+5.144.130.3
+5.144.130.5
+5.144.130.7
+5.144.130.9
+5.144.130.10
+5.144.130.11
+5.144.130.12
+5.144.130.13
+5.144.130.14
+5.144.130.15
+5.144.130.16
+5.144.130.17
+5.144.130.20
+5.144.130.21
+5.144.130.23
+5.144.130.24
+5.144.130.25
+5.144.130.27
+5.144.130.28
+5.144.130.29
+5.144.130.30
+5.144.130.31
+5.144.130.32
+5.144.130.34
+5.144.130.35
+5.144.130.36
+5.144.130.37
+5.144.130.40
+5.144.130.42
+5.144.130.43
+5.144.130.44
+5.144.130.45
+5.144.130.46
+5.144.130.47
+5.144.130.48
+5.144.130.50
+5.144.130.51
+5.144.130.53
+5.144.130.57
+5.144.130.59
+5.144.130.60
+5.144.130.61
+5.144.130.62
+5.144.130.63
+5.144.130.64
+5.144.130.65
+5.144.130.66
+5.144.130.67
+5.144.130.68
+5.144.130.69
+5.144.130.70
+5.144.130.71
+5.144.130.72
+5.144.130.73
+5.144.130.74
+5.144.130.76
+5.144.130.77
+5.144.130.78
+5.144.130.79
+5.144.130.80
+5.144.130.81
+5.144.130.83
+5.144.130.85
+5.144.130.86
+5.144.130.87
+5.144.130.88
+5.144.130.89
+5.144.130.91
+5.144.130.92
+5.144.130.93
+5.144.130.95
+5.144.130.97
+5.144.130.98
+5.144.130.99
+5.144.130.100
+5.144.130.101
+5.144.130.102
+5.144.130.103
+5.144.130.104
+5.144.130.105
+5.144.130.106
+5.144.130.107
+5.144.130.108
+5.144.130.109
+5.144.130.110
+5.144.130.111
+5.144.130.112
+5.144.130.114
+5.144.130.115
+5.144.130.116
+5.144.130.118
+5.144.130.120
+5.144.130.121
+5.144.130.123
+5.144.130.125
+5.144.130.126
+5.144.130.127
+5.144.130.128
+5.144.130.129
+5.144.130.130
+5.144.130.131
+5.144.130.132
+5.144.130.133
+5.144.130.134
+5.144.130.135
+5.144.130.136
+5.144.130.137
+5.144.130.139
+5.144.130.140
+5.144.130.141
+5.144.130.142
+5.144.130.144
+5.144.130.146
+5.144.130.148
+5.144.130.149
+5.144.130.151
+5.144.130.152
+5.144.130.153
+5.144.130.154
+5.144.130.155
+5.144.130.156
+5.144.130.157
+5.144.130.158
+5.144.130.160
+5.144.130.161
+5.144.130.162
+5.144.130.163
+5.144.130.164
+5.144.130.165
+5.144.130.166
+5.144.130.167
+5.144.130.168
+5.144.130.169
+5.144.130.170
+5.144.130.172
+5.144.130.173
+5.144.130.174
+5.144.130.175
+5.144.130.176
+5.144.130.178
+5.144.130.179
+5.144.130.180
+5.144.130.181
+5.144.130.182
+5.144.130.183
+5.144.130.184
+5.144.130.185
+5.144.130.187
+5.144.130.188
+5.144.130.189
+5.144.130.191
+5.144.130.192
+5.144.130.193
+5.144.130.194
+5.144.130.195
+5.144.130.197
+5.144.130.198
+5.144.130.199
+5.144.130.201
+5.144.130.202
+5.144.130.203
+5.144.130.204
+5.144.130.205
+5.144.130.206
+5.144.130.207
+5.144.130.208
+5.144.130.209
+5.144.130.210
+5.144.130.211
+5.144.130.212
+5.144.130.213
+5.144.130.215
+5.144.130.216
+5.144.130.217
+5.144.130.218
+5.144.130.220
+5.144.130.221
+5.144.130.222
+5.144.130.223
+5.144.130.224
+5.144.130.225
+5.144.130.226
+5.144.130.227
+5.144.130.228
+5.144.130.229
+5.144.130.230
+5.144.130.231
+5.144.130.232
+5.144.130.233
+5.144.130.234
+5.144.130.235
+5.144.130.236
+5.144.130.238
+5.144.130.239
+5.144.130.241
+5.144.130.242
+5.144.130.243
+5.144.130.244
+5.144.130.246
+5.144.130.247
+5.144.130.248
+5.144.130.250
+5.144.130.251
+5.144.130.253
+5.144.130.254
+5.144.131.168
+5.144.131.226
+5.144.131.227
+5.144.131.228
+5.144.131.229
+5.144.131.230
+5.144.131.231
+5.144.131.234
+5.144.131.236
+5.144.131.237
+5.144.131.238
+5.144.131.239
+5.144.131.244
+5.144.131.249
+5.144.131.250
+5.144.131.251
+5.144.131.252
+5.144.131.254
+5.144.132.4
+5.144.132.6
+5.144.132.23
+5.144.132.24
+5.144.132.25
+5.144.132.29
+5.144.132.33
+5.144.132.38
+5.144.132.53
+5.144.132.111
+5.144.132.123
+5.144.132.137
+5.144.132.151
+5.144.132.155
+5.144.132.158
+5.144.132.167
+5.144.132.175
+5.144.132.178
+5.144.132.199
+5.144.132.237
+5.144.132.238
+5.144.132.241
+5.144.133.55
+5.144.133.156
+5.144.133.163
+5.144.133.164
+5.144.133.171
+5.144.133.182
+5.144.133.183
+5.144.133.195
+5.144.133.198
+5.144.133.244
+5.144.134.74
+5.144.134.85
+5.144.134.126
+5.144.134.210
+5.144.134.211
+5.144.134.212
+5.144.134.213
+5.144.134.214
+5.144.135.35
+5.144.135.36
+5.144.135.37
+5.144.135.186
+5.145.112.38
+5.145.112.39
+5.145.112.50
+5.145.112.51
+5.145.112.52
+5.145.112.54
+5.145.112.55
+5.145.112.56
+5.145.112.58
+5.145.112.59
+5.145.112.70
+5.145.112.112
+5.145.113.112
+5.145.115.90
+5.145.115.115
+5.145.115.125
+5.145.119.118
+5.145.119.119
+5.159.48.16
+5.159.48.25
+5.159.48.41
+5.159.48.42
+5.159.48.43
+5.159.48.49
+5.159.49.10
+5.159.49.28
+5.159.49.40
+5.159.49.59
+5.159.49.78
+5.159.49.95
+5.159.49.100
+5.159.49.118
+5.159.49.141
+5.159.49.154
+5.159.49.162
+5.159.49.177
+5.159.49.212
+5.159.49.233
+5.159.50.144
+5.159.50.146
+5.159.50.147
+5.159.50.148
+5.159.50.149
+5.159.50.150
+5.159.51.1
+5.159.51.2
+5.159.51.16
+5.159.51.17
+5.159.51.18
+5.159.51.19
+5.159.51.20
+5.159.51.21
+5.159.51.22
+5.159.51.23
+5.159.51.192
+5.159.51.193
+5.159.51.195
+5.159.51.196
+5.159.51.197
+5.159.51.198
+5.159.51.199
+5.159.51.200
+5.159.51.201
+5.159.51.202
+5.159.51.203
+5.159.51.204
+5.159.51.205
+5.159.51.206
+5.159.52.46
+5.159.52.47
+5.159.52.48
+5.159.52.49
+5.159.52.50
+5.159.52.51
+5.159.52.52
+5.159.52.54
+5.159.52.55
+5.159.52.56
+5.159.52.57
+5.159.52.58
+5.159.52.59
+5.159.52.60
+5.159.52.61
+5.159.52.62
+5.159.52.74
+5.159.52.75
+5.159.53.9
+5.159.53.10
+5.159.53.11
+5.159.55.51
+5.159.55.55
+5.159.55.106
+5.159.55.116
+5.159.55.123
+5.159.55.154
+5.159.55.226
+5.159.55.227
+5.160.0.37
+5.160.2.51
+5.160.2.157
+5.160.2.158
+5.160.5.66
+5.160.5.67
+5.160.5.68
+5.160.5.207
+5.160.6.67
+5.160.8.243
+5.160.10.151
+5.160.10.152
+5.160.10.204
+5.160.11.95
+5.160.12.98
+5.160.13.235
+5.160.14.4
+5.160.27.80
+5.160.28.35
+5.160.28.180
+5.160.29.154
+5.160.30.27
+5.160.42.43
+5.160.42.44
+5.160.42.120
+5.160.42.138
+5.160.42.180
+5.160.43.117
+5.160.43.195
+5.160.46.2
+5.160.46.234
+5.160.47.154
+5.160.47.196
+5.160.47.199
+5.160.48.202
+5.160.48.210
+5.160.48.212
+5.160.48.214
+5.160.48.215
+5.160.48.216
+5.160.48.217
+5.160.48.218
+5.160.48.219
+5.160.48.220
+5.160.50.34
+5.160.50.174
+5.160.53.92
+5.160.56.242
+5.160.56.244
+5.160.56.254
+5.160.61.43
+5.160.61.167
+5.160.63.135
+5.160.64.69
+5.160.65.23
+5.160.66.82
+5.160.66.91
+5.160.66.171
+5.160.66.172
+5.160.66.173
+5.160.68.228
+5.160.69.36
+5.160.71.168
+5.160.72.210
+5.160.72.211
+5.160.72.212
+5.160.75.2
+5.160.79.56
+5.160.79.219
+5.160.80.180
+5.160.80.183
+5.160.80.230
+5.160.83.253
+5.160.85.243
+5.160.85.244
+5.160.86.141
+5.160.90.91
+5.160.91.141
+5.160.91.243
+5.160.92.164
+5.160.93.189
+5.160.95.50
+5.160.96.34
+5.160.98.197
+5.160.99.121
+5.160.99.226
+5.160.99.238
+5.160.103.178
+5.160.103.179
+5.160.104.2
+5.160.104.3
+5.160.108.179
+5.160.108.181
+5.160.109.165
+5.160.109.229
+5.160.115.35
+5.160.116.174
+5.160.116.180
+5.160.118.138
+5.160.119.53
+5.160.120.52
+5.160.121.70
+5.160.121.186
+5.160.122.41
+5.160.123.165
+5.160.128.142
+5.160.134.2
+5.160.135.51
+5.160.138.21
+5.160.138.43
+5.160.138.66
+5.160.138.70
+5.160.138.157
+5.160.138.220
+5.160.139.18
+5.160.139.19
+5.160.139.74
+5.160.139.86
+5.160.139.91
+5.160.140.4
+5.160.142.7
+5.160.144.16
+5.160.146.1
+5.160.146.74
+5.160.146.194
+5.160.146.196
+5.160.146.197
+5.160.146.232
+5.160.146.234
+5.160.150.30
+5.160.151.59
+5.160.151.60
+5.160.152.135
+5.160.152.163
+5.160.152.164
+5.160.152.165
+5.160.152.171
+5.160.153.4
+5.160.154.34
+5.160.154.53
+5.160.154.61
+5.160.159.98
+5.160.166.36
+5.160.167.249
+5.160.178.229
+5.160.179.179
+5.160.179.227
+5.160.179.237
+5.160.186.163
+5.160.187.35
+5.160.187.51
+5.160.189.11
+5.160.189.12
+5.160.192.5
+5.160.192.9
+5.160.195.11
+5.160.196.134
+5.160.196.141
+5.160.196.142
+5.160.196.181
+5.160.197.195
+5.160.197.196
+5.160.197.197
+5.160.197.199
+5.160.197.200
+5.160.197.210
+5.160.197.221
+5.160.198.78
+5.160.200.18
+5.160.200.163
+5.160.200.168
+5.160.200.172
+5.160.200.174
+5.160.200.178
+5.160.200.197
+5.160.200.204
+5.160.203.70
+5.160.208.6
+5.160.211.32
+5.160.211.131
+5.160.211.132
+5.160.215.166
+5.160.217.10
+5.160.217.11
+5.160.218.102
+5.160.218.121
+5.160.218.125
+5.160.218.236
+5.160.218.245
+5.160.219.133
+5.160.219.139
+5.160.219.188
+5.160.223.51
+5.160.223.52
+5.160.225.4
+5.160.225.20
+5.160.227.245
+5.160.228.181
+5.160.230.66
+5.160.231.210
+5.160.232.104
+5.160.242.54
+5.160.242.184
+5.160.243.30
+5.160.243.66
+5.160.243.137
+5.160.243.151
+5.160.243.157
+5.160.243.227
+5.160.243.231
+5.160.246.47
+5.160.246.178
+5.160.246.252
+5.160.247.71
+5.160.247.147
+5.160.247.148
+5.160.247.158
+5.160.247.196
+5.160.247.198
+5.160.247.199
+5.160.247.200
+5.160.247.201
+5.160.247.202
+5.182.44.16
+5.182.44.19
+5.182.44.20
+5.182.44.26
+5.182.44.28
+5.182.44.33
+5.182.44.34
+5.182.44.39
+5.182.44.41
+5.182.44.43
+5.182.44.48
+5.182.44.55
+5.182.44.58
+5.182.44.61
+5.182.44.63
+5.182.44.65
+5.182.44.67
+5.182.44.71
+5.182.44.72
+5.182.44.74
+5.182.44.77
+5.182.44.92
+5.182.44.98
+5.182.44.99
+5.182.44.100
+5.182.44.101
+5.182.44.102
+5.182.44.103
+5.182.44.104
+5.182.44.105
+5.182.44.106
+5.182.44.107
+5.182.44.110
+5.182.44.112
+5.182.44.113
+5.182.44.114
+5.182.44.115
+5.182.44.116
+5.182.44.117
+5.182.44.119
+5.182.44.121
+5.182.44.127
+5.182.44.129
+5.182.44.130
+5.182.44.131
+5.182.44.138
+5.182.44.139
+5.182.44.141
+5.182.44.142
+5.182.44.144
+5.182.44.146
+5.182.44.148
+5.182.44.149
+5.182.44.152
+5.182.44.154
+5.182.44.155
+5.182.44.158
+5.182.44.160
+5.182.44.162
+5.182.44.163
+5.182.44.164
+5.182.44.165
+5.182.44.167
+5.182.44.171
+5.182.44.172
+5.182.44.173
+5.182.44.178
+5.182.44.180
+5.182.44.181
+5.182.44.182
+5.182.44.185
+5.182.44.187
+5.182.44.188
+5.182.44.189
+5.182.44.192
+5.182.44.194
+5.182.44.196
+5.182.44.198
+5.182.44.202
+5.182.44.204
+5.182.44.206
+5.182.44.207
+5.182.44.210
+5.182.44.217
+5.182.44.219
+5.182.44.223
+5.182.44.224
+5.182.44.226
+5.182.44.228
+5.182.44.229
+5.182.44.241
+5.182.44.244
+5.182.44.250
+5.182.45.24
+5.182.46.1
+5.182.46.2
+5.182.46.7
+5.182.46.23
+5.182.46.31
+5.182.46.34
+5.182.46.36
+5.182.46.41
+5.182.46.48
+5.182.46.57
+5.182.46.192
+5.182.46.195
+5.190.1.5
+5.190.1.25
+5.190.1.27
+5.190.2.65
+5.190.8.113
+5.190.15.130
+5.190.29.201
+5.190.48.6
+5.190.52.102
+5.190.52.245
+5.190.69.66
+5.190.77.209
+5.190.100.67
+5.190.101.130
+5.190.116.154
+5.190.154.36
+5.190.154.37
+5.190.166.2
+5.190.190.3
+5.190.209.10
+5.190.211.50
+5.190.211.52
+5.200.65.61
+5.200.69.88
+5.200.72.229
+5.200.128.135
+5.200.149.177
+5.200.150.244
+5.200.168.221
+5.200.169.199
+5.200.176.227
+5.200.189.251
+5.200.206.162
+5.200.228.95
+5.200.229.26
+5.200.229.99
+5.201.161.214
+5.201.164.149
+5.201.165.218
+5.201.175.194
+5.201.177.244
+5.202.5.222
+5.202.6.42
+5.202.6.46
+5.202.6.67
+5.202.6.68
+5.202.6.195
+5.202.6.198
+5.202.6.199
+5.202.6.200
+5.202.6.201
+5.202.6.202
+5.202.6.203
+5.202.6.207
+5.202.6.230
+5.202.7.28
+5.202.7.70
+5.202.7.85
+5.202.7.168
+5.202.7.170
+5.202.8.253
+5.202.9.71
+5.202.9.77
+5.202.9.78
+5.202.9.99
+5.202.10.2
+5.202.10.36
+5.202.10.39
+5.202.10.42
+5.202.10.44
+5.202.10.45
+5.202.10.48
+5.202.10.49
+5.202.10.50
+5.202.10.52
+5.202.10.54
+5.202.10.55
+5.202.10.58
+5.202.10.61
+5.202.12.20
+5.202.13.85
+5.202.13.86
+5.202.13.234
+5.202.13.235
+5.202.13.236
+5.202.14.2
+5.202.14.7
+5.202.15.246
+5.202.28.142
+5.202.45.250
+5.202.50.41
+5.202.50.42
+5.202.56.58
+5.202.60.146
+5.202.74.30
+5.202.75.244
+5.202.82.59
+5.202.84.226
+5.202.84.234
+5.202.85.159
+5.202.90.128
+5.202.90.131
+5.202.90.187
+5.202.93.180
+5.202.100.100
+5.202.100.101
+5.202.104.85
+5.202.104.163
+5.202.129.29
+5.202.129.30
+5.202.129.31
+5.202.129.32
+5.202.163.204
+5.202.171.138
+5.202.174.168
+5.202.174.211
+5.202.175.80
+5.202.179.237
+5.202.181.233
+5.202.181.246
+5.202.183.10
+5.202.183.165
+5.202.192.34
+5.202.195.114
+5.202.196.63
+5.202.196.245
+5.202.197.202
+5.202.240.33
+5.202.240.36
+5.202.240.37
+5.202.240.43
+5.202.243.94
+5.202.252.30
+5.202.254.25
+5.232.142.26
+5.232.200.53
+5.232.202.36
+5.232.207.123
+5.233.44.58
+5.233.44.60
+5.233.44.130
+5.233.46.104
+5.233.49.38
+5.233.64.155
+5.233.68.117
+5.233.69.52
+5.233.74.61
+5.233.79.124
+5.233.87.166
+5.233.184.241
+5.234.1.249
+5.234.2.97
+5.234.3.203
+5.234.6.249
+5.234.7.101
+5.234.14.184
+5.234.17.49
+5.234.18.240
+5.234.21.81
+5.234.23.206
+5.234.28.29
+5.234.28.201
+5.234.45.50
+5.234.45.240
+5.234.165.195
+5.234.194.136
+5.234.196.39
+5.234.201.187
+5.234.202.60
+5.234.213.173
+5.234.215.171
+5.235.161.28
+5.235.172.1
+5.235.175.177
+5.235.177.154
+5.235.178.108
+5.235.180.3
+5.235.186.172
+5.235.232.65
+5.235.254.187
+5.236.24.76
+5.236.25.20
+5.236.37.8
+5.236.96.242
+5.236.104.163
+5.236.105.251
+5.236.193.47
+5.236.193.128
+5.236.194.247
+5.236.195.113
+5.236.195.211
+5.237.179.70
+5.237.193.239
+5.237.201.65
+5.237.243.46
+5.237.243.168
+5.238.52.10
+5.238.52.133
+5.238.65.238
+5.238.88.214
+5.238.91.216
+5.238.110.141
+5.238.110.178
+5.238.129.145
+5.238.136.226
+5.238.139.75
+5.238.142.6
+5.238.146.31
+5.238.146.126
+5.238.152.244
+5.238.157.188
+5.238.158.161
+5.238.161.202
+5.238.163.58
+5.238.165.255
+5.238.167.20
+5.238.168.18
+5.238.169.163
+5.238.169.251
+5.238.171.210
+5.238.176.158
+5.238.184.49
+5.238.192.34
+5.238.192.161
+5.238.200.214
+5.238.205.46
+5.238.206.81
+5.238.211.141
+5.238.220.93
+5.238.221.36
+5.238.227.230
+5.238.228.234
+5.238.229.0
+5.238.230.8
+5.238.236.19
+5.238.239.99
+5.238.241.190
+5.238.242.251
+5.238.243.187
+5.238.245.7
+5.238.255.152
+5.239.10.28
+5.239.19.142
+5.239.39.175
+5.239.62.113
+5.239.62.215
+5.239.76.206
+5.239.78.243
+5.239.80.95
+5.239.80.138
+5.239.85.223
+5.239.100.27
+5.239.110.134
+5.239.122.122
+5.239.147.118
+5.239.160.77
+5.239.177.85
+5.239.241.236
+5.239.244.75
+10.1.24.51
+10.2.32.113
+10.3.8.211
+10.3.53.179
+10.3.53.180
+10.3.53.181
+10.3.53.238
+10.3.98.162
+10.3.98.163
+10.9.28.202
+10.9.28.206
+10.19.179.4
+10.21.201.140
+10.30.5.167
+10.30.116.171
+10.30.116.172
+10.30.236.16
+10.48.4.11
+10.56.130.141
+10.56.143.10
+10.58.108.186
+10.69.78.50
+10.75.10.3
+10.80.78.3
+10.80.78.19
+10.80.78.36
+10.80.78.67
+10.80.78.99
+10.80.78.116
+10.80.84.243
+10.80.85.10
+10.80.85.35
+10.80.85.51
+10.86.33.3
+10.86.33.11
+10.86.34.10
+10.86.34.90
+10.86.34.99
+10.86.36.10
+10.86.106.99
+10.87.78.51
+10.88.0.210
+10.88.4.126
+10.88.163.64
+10.88.163.65
+10.88.163.66
+10.88.165.26
+10.88.180.130
+10.88.180.138
+10.88.180.146
+10.88.195.57
+10.88.198.18
+10.88.198.21
+10.92.103.55
+10.103.10.3
+10.104.4.19
+10.104.25.154
+10.104.31.239
+10.104.31.255
+10.104.33.246
+10.104.36.24
+10.104.36.207
+10.104.204.0
+10.104.204.15
+10.104.204.23
+10.104.204.31
+10.104.204.32
+10.104.204.55
+10.104.204.63
+10.104.204.79
+10.104.204.80
+10.104.204.103
+10.104.204.111
+10.104.204.119
+10.104.204.151
+10.104.204.167
+10.104.204.175
+10.104.204.183
+10.104.204.191
+10.104.204.207
+10.104.204.255
+10.104.205.23
+10.104.205.79
+10.104.205.95
+10.104.205.119
+10.104.205.135
+10.104.205.143
+10.104.205.159
+10.104.205.183
+10.104.208.85
+10.104.208.87
+10.104.208.175
+10.104.208.231
+10.104.208.239
+10.104.209.7
+10.104.209.15
+10.104.209.40
+10.104.209.71
+10.104.209.87
+10.104.209.183
+10.104.209.247
+10.104.216.232
+10.104.217.44
+10.104.217.45
+10.104.219.149
+10.104.220.159
+10.104.224.61
+10.104.227.5
+10.104.227.7
+10.104.228.239
+10.104.229.109
+10.104.229.111
+10.104.230.101
+10.106.240.117
+10.106.240.119
+10.106.241.13
+10.106.241.15
+10.114.63.66
+10.114.143.170
+10.115.14.189
+10.117.250.3
+10.121.249.38
+10.124.252.253
+10.124.255.65
+10.124.255.139
+10.126.15.114
+10.126.15.115
+10.126.15.120
+10.140.40.4
+10.140.196.194
+10.141.194.65
+10.141.194.66
+10.141.194.67
+10.141.194.68
+10.141.194.69
+10.141.194.70
+10.141.194.74
+10.170.244.154
+10.170.248.102
+10.171.13.6
+10.175.46.18
+10.175.237.132
+10.175.238.20
+10.175.239.68
+10.176.75.146
+10.187.63.83
+10.201.32.163
+10.201.48.193
+10.201.66.118
+10.201.66.120
+10.201.66.121
+10.201.66.122
+10.201.66.123
+10.201.77.82
+10.202.3.212
+10.223.252.145
+10.224.254.58
+10.233.249.52
+10.233.249.57
+10.246.35.148
+10.249.2.10
+10.249.52.27
+10.249.52.58
+10.249.52.84
+10.249.52.233
+10.249.52.234
+10.249.52.239
+10.249.52.244
+10.250.251.7
+10.250.252.97
+12.15.19.238
+12.15.19.241
+31.7.65.29
+31.7.65.45
+31.7.65.61
+31.7.65.92
+31.7.65.102
+31.7.65.132
+31.7.65.133
+31.7.65.134
+31.7.65.135
+31.7.66.78
+31.7.66.235
+31.7.68.93
+31.7.68.201
+31.7.68.202
+31.7.68.206
+31.7.68.215
+31.7.68.220
+31.7.68.246
+31.7.68.248
+31.7.68.250
+31.7.68.251
+31.7.69.57
+31.7.69.218
+31.7.70.12
+31.7.70.104
+31.7.71.8
+31.7.71.11
+31.7.71.122
+31.7.71.197
+31.7.72.37
+31.7.72.114
+31.7.72.147
+31.7.72.148
+31.7.72.179
+31.7.72.180
+31.7.72.181
+31.7.72.182
+31.7.73.5
+31.7.73.6
+31.7.73.21
+31.7.73.91
+31.7.73.95
+31.7.73.117
+31.7.73.120
+31.7.73.131
+31.7.74.4
+31.7.74.164
+31.7.76.254
+31.7.77.226
+31.7.78.15
+31.7.78.39
+31.7.78.83
+31.7.78.124
+31.7.78.133
+31.7.78.140
+31.7.78.157
+31.7.78.180
+31.7.78.191
+31.7.79.69
+31.7.79.114
+31.7.79.130
+31.7.79.137
+31.7.79.140
+31.7.79.150
+31.7.79.155
+31.7.79.156
+31.7.79.200
+31.7.89.103
+31.7.89.104
+31.14.113.35
+31.14.113.146
+31.14.113.147
+31.14.113.148
+31.14.113.149
+31.14.113.150
+31.14.114.62
+31.14.115.2
+31.14.115.12
+31.14.115.70
+31.14.115.83
+31.14.115.196
+31.14.115.198
+31.14.116.2
+31.14.117.10
+31.14.117.194
+31.14.117.202
+31.14.117.207
+31.14.117.212
+31.14.118.146
+31.14.118.147
+31.14.118.228
+31.14.118.229
+31.14.119.165
+31.14.120.2
+31.14.121.116
+31.14.121.131
+31.14.123.2
+31.14.123.24
+31.14.123.127
+31.14.123.145
+31.14.124.74
+31.24.234.34
+31.24.234.35
+31.24.234.37
+31.25.90.7
+31.25.90.10
+31.25.90.11
+31.25.90.13
+31.25.90.22
+31.25.90.29
+31.25.90.76
+31.25.90.93
+31.25.90.94
+31.25.90.100
+31.25.90.110
+31.25.90.114
+31.25.90.116
+31.25.90.130
+31.25.90.131
+31.25.90.132
+31.25.90.142
+31.25.90.143
+31.25.90.145
+31.25.90.146
+31.25.90.147
+31.25.90.148
+31.25.90.149
+31.25.90.150
+31.25.90.151
+31.25.90.152
+31.25.90.158
+31.25.90.163
+31.25.90.164
+31.25.90.165
+31.25.90.166
+31.25.90.167
+31.25.90.168
+31.25.90.169
+31.25.90.170
+31.25.90.171
+31.25.90.172
+31.25.90.176
+31.25.90.177
+31.25.90.178
+31.25.90.179
+31.25.90.180
+31.25.90.182
+31.25.90.189
+31.25.90.194
+31.25.90.229
+31.25.90.242
+31.25.91.4
+31.25.91.5
+31.25.91.6
+31.25.91.9
+31.25.91.10
+31.25.91.11
+31.25.91.12
+31.25.91.13
+31.25.91.15
+31.25.91.22
+31.25.91.40
+31.25.91.41
+31.25.91.84
+31.25.91.85
+31.25.91.87
+31.25.91.97
+31.25.91.112
+31.25.91.113
+31.25.91.115
+31.25.91.124
+31.25.91.204
+31.25.95.227
+31.47.38.137
+31.47.42.2
+31.47.43.228
+31.47.43.241
+31.47.43.246
+31.47.45.2
+31.47.46.34
+31.47.46.35
+31.47.46.36
+31.47.46.37
+31.47.46.38
+31.47.46.41
+31.47.46.42
+31.47.46.44
+31.47.46.46
+31.47.46.51
+31.47.46.53
+31.47.46.54
+31.47.46.56
+31.47.46.59
+31.47.46.60
+31.47.46.61
+31.47.46.62
+31.47.46.67
+31.47.46.69
+31.47.46.70
+31.47.46.72
+31.47.46.73
+31.47.46.75
+31.47.46.76
+31.47.46.81
+31.47.46.83
+31.47.46.84
+31.47.46.86
+31.47.46.87
+31.47.51.2
+31.47.51.32
+31.47.51.102
+31.47.53.2
+31.47.55.162
+31.47.56.131
+31.47.61.33
+31.47.61.66
+31.47.61.99
+31.47.62.193
+31.58.237.101
+31.58.237.107
+31.130.182.10
+31.170.49.43
+31.171.222.180
+31.171.223.114
+31.184.129.66
+31.184.130.2
+31.184.130.252
+31.184.131.3
+31.184.134.159
+31.184.134.161
+31.184.134.178
+31.184.136.173
+31.184.160.109
+31.184.170.203
+31.184.171.128
+31.184.191.246
+31.193.186.2
+31.193.186.3
+31.193.186.4
+31.193.186.5
+31.193.186.6
+31.193.186.7
+31.193.186.8
+31.193.186.9
+31.193.186.10
+31.193.186.11
+31.193.186.12
+31.193.186.13
+31.193.186.14
+31.214.168.26
+31.214.168.35
+31.214.168.42
+31.214.168.68
+31.214.168.100
+31.214.168.132
+31.214.168.162
+31.214.168.164
+31.214.168.166
+31.214.168.179
+31.214.168.180
+31.214.168.229
+31.214.168.246
+31.214.169.21
+31.214.169.22
+31.214.169.206
+31.214.169.244
+31.214.170.74
+31.214.170.163
+31.214.170.194
+31.214.170.213
+31.214.171.86
+31.214.171.130
+31.214.171.132
+31.214.171.133
+31.214.171.134
+31.214.171.135
+31.214.171.170
+31.214.171.171
+31.214.171.174
+31.214.172.6
+31.214.172.11
+31.214.172.78
+31.214.172.183
+31.214.172.184
+31.214.173.30
+31.214.173.76
+31.214.173.170
+31.214.173.178
+31.214.173.210
+31.214.173.244
+31.214.173.254
+31.214.174.4
+31.214.174.6
+31.214.174.27
+31.214.174.90
+31.214.174.91
+31.214.174.92
+31.214.174.93
+31.214.174.99
+31.214.174.114
+31.214.174.125
+31.214.174.163
+31.214.174.166
+31.214.174.194
+31.214.174.195
+31.214.174.196
+31.214.174.197
+31.214.174.205
+31.214.175.10
+31.214.175.11
+31.214.175.13
+31.214.175.14
+31.214.175.146
+31.214.175.185
+31.214.175.214
+31.214.175.220
+31.214.175.246
+31.214.228.242
+31.214.228.243
+31.214.229.212
+31.214.231.121
+31.214.248.27
+31.214.248.60
+31.214.248.74
+31.214.248.75
+31.214.248.76
+31.214.248.77
+31.214.248.78
+31.214.248.102
+31.214.248.146
+31.214.248.147
+31.214.248.174
+31.214.250.14
+31.214.250.28
+31.214.250.42
+31.214.250.69
+31.214.250.70
+31.214.250.72
+31.214.250.75
+31.214.250.76
+31.214.250.77
+31.214.250.83
+31.214.250.84
+31.214.250.88
+31.214.250.90
+31.214.250.91
+31.214.250.92
+31.214.250.94
+31.214.250.96
+31.214.250.98
+31.214.250.99
+31.214.250.100
+31.214.250.101
+31.214.250.102
+31.214.250.106
+31.214.250.108
+31.214.250.109
+31.214.250.112
+31.214.250.113
+31.214.250.114
+31.214.250.116
+31.214.250.118
+31.214.250.121
+31.214.250.122
+31.214.250.123
+31.214.250.125
+31.214.250.198
+31.214.250.199
+31.214.250.201
+31.214.250.203
+31.214.250.209
+31.214.250.210
+31.214.250.211
+31.214.250.213
+31.214.250.214
+31.214.250.215
+31.214.250.216
+31.214.250.217
+31.214.250.218
+31.214.250.219
+31.214.250.220
+31.214.250.221
+31.214.251.6
+31.214.251.147
+31.214.251.148
+31.214.251.149
+31.214.251.194
+31.214.251.196
+31.214.251.199
+31.214.251.200
+31.214.251.201
+31.214.251.202
+31.214.251.203
+31.214.251.204
+31.214.251.206
+31.214.251.207
+31.214.251.208
+31.214.251.209
+31.214.251.215
+31.214.251.217
+31.214.251.219
+31.214.251.220
+31.214.251.228
+31.214.251.230
+31.214.251.231
+31.214.251.232
+31.214.251.233
+31.214.251.234
+31.214.251.238
+31.214.251.239
+31.214.251.241
+31.214.251.247
+31.214.251.253
+31.214.255.50
+31.214.255.53
+31.214.255.54
+31.214.255.139
+31.214.255.140
+31.214.255.152
+31.214.255.154
+31.214.255.155
+31.214.255.156
+31.214.255.160
+31.214.255.161
+31.214.255.163
+31.214.255.165
+31.214.255.166
+31.214.255.167
+31.214.255.168
+31.214.255.169
+31.214.255.170
+31.214.255.171
+31.214.255.176
+31.214.255.177
+31.214.255.178
+31.214.255.179
+31.214.255.180
+31.214.255.181
+31.214.255.182
+31.214.255.183
+31.214.255.184
+31.214.255.185
+31.214.255.186
+31.214.255.187
+31.214.255.188
+31.214.255.189
+31.216.62.30
+31.216.62.39
+31.216.62.58
+31.216.62.60
+31.216.62.82
+31.216.62.86
+31.216.62.93
+31.216.62.102
+31.216.62.107
+31.216.62.118
+31.216.62.131
+31.216.62.136
+31.216.62.137
+31.216.62.144
+31.216.62.146
+31.216.62.147
+31.216.62.158
+31.216.62.170
+31.216.62.203
+31.216.62.212
+31.216.62.227
+31.216.62.248
+37.9.253.32
+37.9.253.33
+37.10.67.10
+37.10.67.18
+37.10.109.29
+37.32.2.2
+37.32.4.41
+37.32.4.124
+37.32.8.52
+37.32.8.55
+37.32.8.100
+37.32.8.180
+37.32.8.208
+37.32.8.253
+37.32.9.100
+37.32.9.117
+37.32.9.118
+37.32.9.248
+37.32.10.21
+37.32.10.53
+37.32.10.120
+37.32.10.151
+37.32.10.227
+37.32.10.254
+37.32.11.26
+37.32.12.41
+37.32.12.48
+37.32.12.50
+37.32.12.52
+37.32.12.146
+37.32.13.105
+37.32.13.171
+37.32.14.47
+37.32.14.114
+37.32.14.184
+37.32.14.226
+37.32.14.234
+37.32.15.0
+37.32.15.18
+37.32.15.85
+37.32.15.155
+37.32.15.205
+37.32.15.208
+37.32.15.248
+37.32.22.248
+37.32.24.35
+37.32.24.126
+37.32.24.156
+37.32.24.192
+37.32.25.162
+37.32.25.174
+37.32.25.185
+37.32.26.165
+37.32.27.138
+37.32.27.222
+37.32.28.174
+37.32.29.195
+37.32.29.247
+37.32.43.208
+37.32.43.224
+37.32.44.58
+37.32.45.18
+37.32.45.20
+37.32.46.131
+37.32.46.132
+37.32.46.133
+37.32.46.134
+37.32.46.135
+37.32.46.136
+37.32.46.137
+37.32.46.138
+37.32.46.139
+37.32.46.141
+37.32.46.142
+37.32.46.143
+37.32.46.144
+37.32.46.145
+37.32.46.146
+37.32.46.147
+37.32.46.148
+37.32.46.149
+37.32.46.162
+37.32.46.163
+37.32.46.165
+37.32.46.166
+37.32.46.168
+37.32.46.169
+37.32.46.171
+37.32.46.172
+37.32.46.174
+37.32.46.175
+37.32.47.196
+37.32.120.138
+37.32.120.139
+37.32.120.148
+37.32.121.133
+37.32.125.138
+37.32.126.130
+37.32.127.99
+37.32.127.100
+37.32.127.106
+37.75.240.5
+37.75.240.14
+37.75.240.15
+37.75.240.16
+37.75.241.200
+37.130.202.14
+37.130.202.66
+37.130.206.6
+37.130.206.7
+37.143.148.145
+37.148.0.167
+37.148.0.222
+37.148.3.35
+37.148.3.51
+37.148.4.83
+37.148.13.79
+37.148.13.187
+37.148.15.80
+37.148.15.221
+37.148.18.165
+37.148.20.117
+37.148.21.64
+37.148.23.120
+37.148.23.172
+37.148.31.13
+37.148.31.44
+37.148.40.88
+37.148.42.47
+37.148.45.196
+37.148.48.54
+37.148.49.252
+37.148.50.125
+37.148.50.202
+37.148.57.6
+37.148.58.5
+37.148.59.134
+37.148.61.147
+37.148.81.227
+37.148.82.138
+37.148.83.154
+37.148.83.210
+37.148.84.245
+37.148.85.86
+37.148.85.180
+37.148.87.111
+37.148.91.8
+37.148.248.50
+37.148.248.77
+37.152.160.27
+37.152.173.170
+37.152.173.215
+37.152.175.67
+37.152.176.118
+37.152.176.179
+37.152.176.237
+37.152.177.84
+37.152.177.138
+37.152.179.31
+37.152.179.69
+37.152.180.124
+37.152.180.157
+37.152.180.240
+37.152.181.60
+37.152.181.115
+37.152.181.142
+37.152.182.41
+37.152.182.119
+37.152.182.187
+37.152.183.92
+37.152.186.170
+37.152.186.203
+37.152.186.224
+37.152.188.11
+37.152.188.16
+37.152.188.131
+37.152.188.132
+37.152.188.220
+37.152.188.254
+37.152.189.114
+37.152.189.128
+37.152.189.156
+37.152.190.8
+37.152.190.9
+37.152.190.80
+37.152.190.239
+37.152.190.252
+37.152.191.223
+37.156.8.90
+37.156.9.203
+37.156.9.255
+37.156.11.220
+37.156.14.221
+37.156.20.91
+37.156.144.82
+37.156.144.83
+37.156.144.85
+37.156.144.91
+37.156.144.125
+37.156.144.202
+37.156.144.203
+37.156.144.204
+37.156.145.84
+37.156.145.86
+37.156.145.136
+37.156.145.137
+37.156.145.138
+37.156.145.139
+37.156.145.141
+37.156.145.144
+37.156.145.146
+37.156.145.147
+37.156.145.152
+37.156.145.153
+37.156.145.155
+37.156.145.158
+37.156.145.197
+37.156.145.251
+37.156.145.252
+37.156.146.39
+37.156.146.40
+37.156.146.45
+37.156.146.61
+37.156.146.105
+37.156.146.109
+37.156.146.125
+37.156.146.166
+37.156.146.245
+37.156.147.43
+37.156.147.110
+37.156.147.116
+37.156.147.125
+37.156.147.220
+37.156.147.221
+37.156.147.242
+37.156.147.243
+37.156.147.244
+37.156.147.245
+37.156.147.246
+37.191.76.202
+37.191.77.81
+37.191.79.136
+37.191.92.114
+37.191.92.115
+37.191.92.116
+37.191.92.117
+37.191.92.118
+37.191.92.119
+37.191.93.195
+37.191.93.196
+37.191.93.202
+37.191.93.203
+37.191.94.35
+37.191.94.44
+37.191.95.6
+37.191.95.7
+37.191.95.13
+37.191.95.14
+37.191.95.70
+37.191.95.82
+37.191.95.86
+37.191.95.99
+37.191.95.100
+37.202.148.139
+37.202.154.171
+37.202.158.11
+37.202.159.84
+37.202.159.125
+37.202.159.230
+37.202.169.144
+37.202.169.202
+37.202.169.251
+37.202.170.32
+37.202.171.239
+37.202.172.64
+37.202.172.82
+37.202.182.143
+37.202.185.61
+37.202.185.66
+37.202.185.132
+37.202.188.85
+37.202.189.203
+37.202.191.176
+37.202.225.95
+37.202.225.173
+37.202.225.206
+37.202.225.224
+37.202.229.195
+37.202.229.200
+37.202.229.205
+37.202.229.209
+37.202.229.215
+37.202.229.220
+37.202.232.222
+37.202.236.4
+37.202.236.12
+37.202.236.100
+37.202.236.126
+37.202.237.2
+37.202.237.195
+37.202.237.242
+37.202.237.246
+37.202.238.11
+37.202.246.70
+37.228.136.98
+37.228.136.157
+37.228.136.181
+37.228.137.35
+37.228.137.66
+37.228.137.76
+37.228.138.34
+37.228.138.123
+37.228.138.134
+37.228.138.138
+37.228.138.154
+37.228.138.155
+37.228.138.201
+37.228.138.203
+37.228.139.3
+37.228.139.5
+37.228.139.26
+37.228.139.40
+37.228.139.41
+37.228.139.107
+37.228.139.229
+37.255.128.78
+37.255.128.250
+37.255.132.14
+37.255.132.54
+37.255.135.36
+37.255.148.218
+37.255.148.221
+37.255.173.171
+37.255.173.172
+37.255.177.60
+37.255.177.138
+37.255.177.153
+37.255.186.102
+37.255.187.164
+37.255.193.188
+37.255.194.13
+37.255.194.69
+37.255.198.80
+37.255.201.39
+37.255.202.25
+37.255.202.70
+37.255.208.38
+37.255.212.55
+37.255.213.220
+37.255.216.121
+37.255.223.36
+37.255.223.218
+37.255.223.240
+37.255.223.243
+37.255.223.244
+37.255.230.35
+37.255.234.14
+37.255.234.34
+37.255.236.67
+37.255.239.57
+37.255.239.175
+37.255.242.68
+37.255.245.39
+37.255.249.150
+37.255.249.166
+37.255.249.172
+37.255.249.205
+37.255.249.220
+45.9.252.79
+45.11.184.151
+45.11.185.10
+45.11.185.148
+45.11.187.103
+45.15.200.31
+45.81.16.36
+45.81.16.155
+45.81.16.217
+45.81.17.109
+45.81.17.159
+45.81.17.160
+45.81.17.177
+45.81.17.182
+45.81.17.183
+45.81.17.184
+45.81.17.196
+45.81.17.197
+45.81.17.199
+45.81.18.104
+45.81.18.109
+45.81.19.49
+45.81.19.60
+45.81.19.133
+45.82.136.141
+45.82.136.148
+45.82.138.40
+45.82.138.113
+45.82.138.224
+45.82.139.150
+45.86.87.11
+45.86.87.84
+45.86.87.85
+45.86.87.150
+45.86.87.242
+45.89.139.5
+45.89.236.7
+45.89.236.11
+45.89.236.13
+45.89.236.15
+45.89.236.16
+45.89.236.17
+45.89.236.28
+45.89.236.29
+45.89.236.30
+45.89.236.40
+45.89.236.41
+45.89.236.47
+45.89.236.48
+45.89.236.51
+45.89.236.52
+45.89.236.53
+45.89.236.55
+45.89.236.59
+45.89.236.67
+45.89.236.68
+45.89.236.73
+45.89.236.74
+45.89.236.87
+45.89.236.89
+45.89.236.133
+45.89.236.153
+45.89.236.154
+45.89.236.158
+45.89.236.163
+45.89.236.173
+45.89.236.179
+45.89.236.180
+45.89.236.183
+45.89.236.185
+45.89.236.187
+45.89.236.190
+45.89.236.227
+45.89.236.228
+45.89.236.247
+45.89.236.249
+45.89.236.252
+45.89.237.18
+45.89.237.24
+45.89.237.67
+45.89.237.68
+45.89.237.70
+45.89.237.72
+45.89.237.80
+45.89.237.81
+45.89.237.82
+45.89.237.85
+45.89.237.86
+45.89.237.101
+45.89.237.109
+45.89.237.158
+45.89.238.179
+45.89.238.183
+45.89.238.185
+45.89.238.187
+45.89.238.189
+45.89.238.190
+45.89.239.33
+45.89.239.35
+45.89.239.39
+45.89.239.40
+45.89.239.41
+45.89.239.42
+45.89.239.43
+45.89.239.44
+45.89.239.45
+45.89.239.109
+45.89.239.110
+45.89.239.121
+45.89.239.130
+45.89.239.190
+45.89.239.210
+45.89.239.228
+45.89.239.234
+45.89.239.238
+45.89.239.252
+45.89.239.253
+45.90.72.14
+45.90.72.85
+45.90.72.153
+45.90.72.161
+45.90.72.172
+45.90.72.227
+45.90.72.228
+45.90.73.12
+45.90.73.14
+45.90.73.15
+45.90.73.16
+45.90.73.30
+45.90.73.31
+45.90.73.56
+45.90.73.61
+45.90.73.66
+45.90.73.68
+45.90.73.153
+45.90.73.154
+45.90.73.187
+45.90.73.205
+45.90.73.206
+45.90.73.208
+45.90.73.209
+45.90.74.14
+45.90.74.24
+45.90.74.29
+45.90.74.61
+45.90.74.104
+45.90.74.114
+45.90.74.159
+45.90.74.174
+45.90.74.175
+45.90.74.176
+45.90.74.185
+45.90.74.192
+45.90.74.202
+45.90.74.204
+45.90.74.217
+45.90.74.241
+45.90.74.253
+45.90.75.75
+45.91.152.3
+45.91.152.10
+45.91.152.11
+45.91.153.10
+45.92.92.2
+45.92.92.3
+45.92.92.4
+45.92.92.5
+45.92.92.6
+45.92.92.7
+45.92.92.8
+45.92.92.9
+45.92.92.11
+45.92.92.12
+45.92.92.13
+45.92.92.14
+45.92.92.15
+45.92.92.16
+45.92.92.17
+45.92.92.19
+45.92.92.20
+45.92.92.22
+45.92.92.23
+45.92.92.24
+45.92.92.26
+45.92.92.27
+45.92.92.28
+45.92.92.29
+45.92.92.30
+45.92.92.31
+45.92.92.32
+45.92.92.34
+45.92.92.35
+45.92.92.36
+45.92.92.38
+45.92.92.39
+45.92.92.40
+45.92.92.42
+45.92.92.43
+45.92.92.44
+45.92.92.47
+45.92.92.50
+45.92.92.51
+45.92.92.52
+45.92.92.54
+45.92.92.55
+45.92.92.56
+45.92.92.57
+45.92.92.58
+45.92.92.59
+45.92.92.60
+45.92.92.61
+45.92.92.62
+45.92.92.63
+45.92.92.64
+45.92.92.65
+45.92.92.66
+45.92.92.67
+45.92.92.68
+45.92.92.70
+45.92.92.71
+45.92.92.72
+45.92.92.74
+45.92.92.75
+45.92.92.77
+45.92.92.78
+45.92.92.79
+45.92.92.80
+45.92.92.81
+45.92.92.82
+45.92.92.83
+45.92.92.84
+45.92.92.85
+45.92.92.86
+45.92.92.87
+45.92.92.88
+45.92.92.89
+45.92.92.90
+45.92.92.91
+45.92.92.93
+45.92.92.94
+45.92.92.95
+45.92.92.96
+45.92.92.97
+45.92.92.98
+45.92.92.99
+45.92.92.100
+45.92.92.101
+45.92.92.102
+45.92.92.103
+45.92.92.104
+45.92.92.105
+45.92.92.106
+45.92.92.107
+45.92.92.108
+45.92.92.109
+45.92.92.110
+45.92.92.111
+45.92.92.112
+45.92.92.113
+45.92.92.115
+45.92.92.116
+45.92.92.117
+45.92.92.118
+45.92.92.119
+45.92.92.120
+45.92.92.121
+45.92.92.122
+45.92.92.123
+45.92.92.124
+45.92.92.125
+45.92.92.127
+45.92.92.128
+45.92.92.129
+45.92.92.130
+45.92.92.131
+45.92.92.132
+45.92.92.133
+45.92.92.134
+45.92.92.135
+45.92.92.136
+45.92.92.137
+45.92.92.139
+45.92.92.140
+45.92.92.141
+45.92.92.142
+45.92.92.143
+45.92.92.144
+45.92.92.145
+45.92.92.146
+45.92.92.147
+45.92.92.148
+45.92.92.149
+45.92.92.150
+45.92.92.152
+45.92.92.153
+45.92.92.154
+45.92.92.156
+45.92.92.157
+45.92.92.158
+45.92.92.159
+45.92.92.161
+45.92.92.163
+45.92.92.164
+45.92.92.165
+45.92.92.166
+45.92.92.168
+45.92.92.169
+45.92.92.170
+45.92.92.172
+45.92.92.174
+45.92.92.176
+45.92.92.177
+45.92.92.178
+45.92.92.179
+45.92.92.181
+45.92.92.182
+45.92.92.183
+45.92.92.185
+45.92.92.186
+45.92.92.187
+45.92.92.188
+45.92.92.190
+45.92.92.191
+45.92.92.192
+45.92.92.193
+45.92.92.194
+45.92.92.195
+45.92.92.197
+45.92.92.199
+45.92.92.201
+45.92.92.202
+45.92.92.203
+45.92.92.204
+45.92.92.205
+45.92.92.206
+45.92.92.207
+45.92.92.208
+45.92.92.209
+45.92.92.210
+45.92.92.211
+45.92.92.212
+45.92.92.213
+45.92.92.214
+45.92.92.215
+45.92.92.216
+45.92.92.217
+45.92.92.218
+45.92.92.219
+45.92.92.220
+45.92.92.221
+45.92.92.222
+45.92.92.223
+45.92.92.224
+45.92.92.225
+45.92.92.226
+45.92.92.227
+45.92.92.228
+45.92.92.229
+45.92.92.231
+45.92.92.232
+45.92.92.233
+45.92.92.234
+45.92.92.235
+45.92.92.236
+45.92.92.237
+45.92.92.238
+45.92.92.239
+45.92.92.240
+45.92.92.241
+45.92.92.242
+45.92.92.243
+45.92.92.244
+45.92.92.245
+45.92.92.246
+45.92.92.248
+45.92.92.249
+45.92.92.250
+45.92.92.251
+45.92.92.252
+45.92.92.253
+45.92.93.18
+45.92.93.48
+45.92.93.70
+45.92.93.94
+45.92.93.97
+45.92.93.98
+45.92.93.104
+45.92.93.118
+45.92.93.137
+45.92.93.138
+45.92.93.139
+45.92.93.151
+45.92.93.162
+45.92.93.164
+45.92.93.172
+45.92.93.180
+45.92.93.249
+45.92.93.250
+45.92.93.251
+45.92.94.2
+45.92.94.3
+45.92.94.5
+45.92.94.6
+45.92.94.8
+45.92.94.9
+45.92.94.10
+45.92.94.16
+45.92.94.19
+45.92.94.21
+45.92.94.22
+45.92.94.34
+45.92.94.46
+45.92.94.47
+45.92.94.48
+45.92.94.49
+45.92.94.50
+45.92.94.51
+45.92.94.52
+45.92.94.53
+45.92.94.54
+45.92.94.55
+45.92.94.56
+45.92.94.57
+45.92.94.58
+45.92.94.59
+45.92.94.60
+45.92.94.89
+45.92.94.97
+45.92.94.109
+45.92.94.151
+45.92.94.170
+45.92.94.171
+45.92.94.226
+45.92.94.244
+45.92.95.67
+45.92.95.68
+45.92.95.70
+45.92.95.254
+45.94.212.13
+45.94.214.22
+45.94.214.230
+45.94.254.34
+45.94.254.69
+45.94.254.70
+45.94.255.189
+45.94.255.222
+45.129.36.6
+45.129.36.10
+45.129.36.19
+45.129.36.28
+45.129.36.30
+45.129.36.42
+45.129.36.58
+45.129.36.59
+45.129.36.60
+45.129.36.61
+45.129.36.62
+45.129.36.114
+45.129.36.162
+45.129.36.166
+45.129.36.182
+45.129.37.10
+45.129.37.70
+45.129.37.71
+45.129.37.72
+45.129.37.76
+45.129.37.98
+45.129.37.115
+45.129.37.116
+45.129.37.117
+45.129.37.118
+45.129.37.150
+45.129.37.151
+45.129.37.178
+45.129.37.183
+45.129.37.184
+45.129.38.34
+45.129.38.37
+45.129.38.52
+45.129.38.54
+45.129.38.61
+45.129.38.66
+45.129.38.130
+45.129.38.140
+45.129.38.170
+45.129.38.173
+45.129.39.90
+45.129.39.117
+45.129.39.146
+45.129.39.195
+45.129.39.206
+45.132.32.4
+45.132.32.5
+45.132.32.222
+45.132.172.90
+45.132.172.95
+45.132.172.241
+45.135.241.12
+45.135.241.22
+45.135.241.33
+45.135.241.70
+45.135.241.74
+45.135.241.83
+45.135.241.95
+45.135.241.129
+45.135.241.144
+45.135.241.228
+45.135.241.237
+45.135.241.245
+45.135.241.253
+45.135.243.22
+45.135.243.30
+45.135.243.34
+45.135.243.56
+45.135.243.58
+45.135.243.73
+45.135.243.76
+45.135.243.78
+45.135.243.79
+45.135.243.85
+45.135.243.87
+45.135.243.88
+45.135.243.92
+45.135.243.94
+45.135.243.105
+45.135.243.206
+45.135.243.216
+45.135.243.217
+45.135.243.222
+45.135.243.226
+45.135.243.227
+45.135.243.235
+45.137.16.10
+45.137.17.120
+45.137.17.133
+45.137.17.242
+45.137.17.243
+45.137.17.244
+45.137.17.245
+45.138.132.25
+45.138.132.26
+45.138.132.28
+45.138.132.29
+45.138.132.30
+45.138.132.31
+45.138.132.38
+45.138.132.43
+45.138.132.46
+45.138.132.47
+45.138.132.48
+45.138.132.57
+45.138.132.71
+45.138.132.80
+45.138.132.117
+45.138.132.118
+45.138.132.136
+45.138.132.174
+45.138.132.193
+45.138.132.204
+45.138.132.247
+45.138.132.249
+45.138.133.3
+45.138.133.4
+45.138.133.5
+45.138.133.6
+45.138.133.7
+45.138.133.8
+45.138.133.9
+45.138.133.10
+45.138.133.11
+45.138.133.12
+45.138.133.13
+45.138.133.14
+45.138.133.15
+45.138.133.16
+45.138.133.17
+45.138.133.18
+45.138.133.20
+45.138.133.21
+45.138.133.22
+45.138.133.23
+45.138.133.24
+45.138.133.25
+45.138.133.26
+45.138.133.28
+45.138.133.29
+45.138.133.30
+45.138.133.32
+45.138.133.33
+45.138.133.34
+45.138.133.35
+45.138.133.36
+45.138.133.37
+45.138.133.38
+45.138.133.39
+45.138.133.41
+45.138.133.42
+45.138.133.44
+45.138.133.45
+45.138.133.46
+45.138.133.47
+45.138.133.49
+45.138.133.51
+45.138.133.52
+45.138.133.53
+45.138.133.56
+45.138.133.57
+45.138.133.60
+45.138.133.61
+45.138.133.62
+45.138.133.64
+45.138.133.65
+45.138.133.66
+45.138.133.67
+45.138.133.69
+45.138.133.70
+45.138.133.71
+45.138.133.72
+45.138.133.73
+45.138.133.75
+45.138.133.76
+45.138.133.77
+45.138.133.78
+45.138.133.79
+45.138.133.81
+45.138.133.85
+45.138.133.89
+45.138.133.90
+45.138.133.91
+45.138.133.92
+45.138.133.93
+45.138.133.94
+45.138.133.95
+45.138.133.96
+45.138.133.98
+45.138.133.99
+45.138.133.100
+45.138.133.101
+45.138.133.102
+45.138.133.103
+45.138.133.104
+45.138.133.105
+45.138.133.107
+45.138.133.108
+45.138.133.110
+45.138.133.111
+45.138.133.112
+45.138.133.114
+45.138.133.115
+45.138.133.117
+45.138.133.118
+45.138.133.122
+45.138.133.123
+45.138.133.124
+45.138.133.125
+45.138.133.128
+45.138.133.129
+45.138.133.130
+45.138.133.131
+45.138.133.132
+45.138.133.133
+45.138.133.134
+45.138.133.136
+45.138.133.137
+45.138.133.138
+45.138.133.140
+45.138.133.141
+45.138.133.142
+45.138.133.143
+45.138.133.144
+45.138.133.147
+45.138.133.148
+45.138.133.149
+45.138.133.150
+45.138.133.151
+45.138.133.152
+45.138.133.154
+45.138.133.155
+45.138.133.156
+45.138.133.157
+45.138.133.158
+45.138.133.159
+45.138.133.160
+45.138.133.162
+45.138.133.163
+45.138.133.164
+45.138.133.165
+45.138.133.167
+45.138.133.168
+45.138.133.169
+45.138.133.170
+45.138.133.171
+45.138.133.172
+45.138.133.173
+45.138.133.174
+45.138.133.175
+45.138.133.176
+45.138.133.177
+45.138.133.178
+45.138.133.179
+45.138.133.180
+45.138.133.181
+45.138.133.182
+45.138.133.183
+45.138.133.184
+45.138.133.185
+45.138.133.186
+45.138.133.187
+45.138.133.188
+45.138.133.189
+45.138.133.190
+45.138.133.191
+45.138.133.192
+45.138.133.193
+45.138.133.194
+45.138.133.195
+45.138.133.196
+45.138.133.197
+45.138.133.199
+45.138.133.200
+45.138.133.201
+45.138.133.202
+45.138.133.203
+45.138.133.204
+45.138.133.206
+45.138.133.207
+45.138.133.208
+45.138.133.209
+45.138.133.211
+45.138.133.212
+45.138.133.213
+45.138.133.214
+45.138.133.215
+45.138.133.217
+45.138.133.218
+45.138.133.219
+45.138.133.220
+45.138.133.221
+45.138.133.223
+45.138.133.224
+45.138.133.225
+45.138.133.226
+45.138.133.227
+45.138.133.228
+45.138.133.229
+45.138.133.230
+45.138.133.231
+45.138.133.232
+45.138.133.233
+45.138.133.234
+45.138.133.235
+45.138.133.236
+45.138.133.237
+45.138.133.238
+45.138.133.239
+45.138.133.240
+45.138.133.241
+45.138.133.242
+45.138.133.243
+45.138.133.244
+45.138.133.245
+45.138.133.247
+45.138.133.248
+45.138.133.249
+45.138.133.250
+45.138.133.251
+45.138.133.252
+45.138.133.253
+45.138.133.254
+45.138.134.2
+45.138.134.3
+45.138.134.4
+45.138.134.5
+45.138.134.6
+45.138.134.7
+45.138.134.8
+45.138.134.9
+45.138.134.10
+45.138.134.11
+45.138.134.12
+45.138.134.13
+45.138.134.14
+45.138.134.16
+45.138.134.17
+45.138.134.18
+45.138.134.20
+45.138.134.21
+45.138.134.22
+45.138.134.23
+45.138.134.24
+45.138.134.25
+45.138.134.27
+45.138.134.28
+45.138.134.29
+45.138.134.30
+45.138.134.33
+45.138.134.34
+45.138.134.35
+45.138.134.36
+45.138.134.37
+45.138.134.38
+45.138.134.39
+45.138.134.40
+45.138.134.41
+45.138.134.42
+45.138.134.43
+45.138.134.45
+45.138.134.46
+45.138.134.47
+45.138.134.48
+45.138.134.49
+45.138.134.50
+45.138.134.51
+45.138.134.52
+45.138.134.53
+45.138.134.54
+45.138.134.55
+45.138.134.56
+45.138.134.57
+45.138.134.58
+45.138.134.59
+45.138.134.60
+45.138.134.61
+45.138.134.62
+45.138.134.63
+45.138.134.64
+45.138.134.65
+45.138.134.67
+45.138.134.68
+45.138.134.69
+45.138.134.70
+45.138.134.71
+45.138.134.72
+45.138.134.73
+45.138.134.74
+45.138.134.75
+45.138.134.76
+45.138.134.77
+45.138.134.78
+45.138.134.79
+45.138.134.80
+45.138.134.82
+45.138.134.83
+45.138.134.84
+45.138.134.85
+45.138.134.86
+45.138.134.87
+45.138.134.88
+45.138.134.89
+45.138.134.90
+45.138.134.91
+45.138.134.92
+45.138.134.93
+45.138.134.94
+45.138.134.97
+45.138.134.98
+45.138.134.100
+45.138.134.101
+45.138.134.102
+45.138.134.103
+45.138.134.104
+45.138.134.106
+45.138.134.107
+45.138.134.108
+45.138.134.109
+45.138.134.110
+45.138.134.111
+45.138.134.112
+45.138.134.113
+45.138.134.114
+45.138.134.115
+45.138.134.116
+45.138.134.118
+45.138.134.119
+45.138.134.120
+45.138.134.121
+45.138.134.122
+45.138.134.123
+45.138.134.124
+45.138.134.125
+45.138.134.126
+45.138.134.127
+45.138.134.130
+45.138.134.131
+45.138.134.132
+45.138.134.133
+45.138.134.135
+45.138.134.136
+45.138.134.137
+45.138.134.138
+45.138.134.139
+45.138.134.140
+45.138.134.141
+45.138.134.143
+45.138.134.145
+45.138.134.146
+45.138.134.147
+45.138.134.149
+45.138.134.150
+45.138.134.151
+45.138.134.152
+45.138.134.153
+45.138.134.155
+45.138.134.157
+45.138.134.158
+45.138.134.159
+45.138.134.161
+45.138.134.162
+45.138.134.163
+45.138.134.164
+45.138.134.165
+45.138.134.166
+45.138.134.167
+45.138.134.168
+45.138.134.171
+45.138.134.172
+45.138.134.173
+45.138.134.175
+45.138.134.177
+45.138.134.178
+45.138.134.179
+45.138.134.180
+45.138.134.181
+45.138.134.184
+45.138.134.185
+45.138.134.187
+45.138.134.188
+45.138.134.189
+45.138.134.190
+45.138.134.191
+45.138.134.192
+45.138.134.193
+45.138.134.195
+45.138.134.196
+45.138.134.197
+45.138.134.198
+45.138.134.200
+45.138.134.203
+45.138.134.205
+45.138.134.206
+45.138.134.207
+45.138.134.209
+45.138.134.210
+45.138.134.211
+45.138.134.212
+45.138.134.213
+45.138.134.214
+45.138.134.215
+45.138.134.216
+45.138.134.217
+45.138.134.218
+45.138.134.219
+45.138.134.220
+45.138.134.221
+45.138.134.223
+45.138.134.224
+45.138.134.225
+45.138.134.226
+45.138.134.227
+45.138.134.230
+45.138.134.233
+45.138.134.234
+45.138.134.236
+45.138.134.237
+45.138.134.238
+45.138.134.239
+45.138.134.240
+45.138.134.241
+45.138.134.242
+45.138.134.243
+45.138.134.244
+45.138.134.245
+45.138.134.246
+45.138.134.247
+45.138.134.250
+45.138.134.252
+45.138.134.253
+45.138.135.4
+45.138.135.6
+45.138.135.7
+45.138.135.8
+45.138.135.9
+45.138.135.10
+45.138.135.11
+45.138.135.12
+45.138.135.13
+45.138.135.14
+45.138.135.15
+45.138.135.16
+45.138.135.17
+45.138.135.18
+45.138.135.19
+45.138.135.21
+45.138.135.22
+45.138.135.23
+45.138.135.24
+45.138.135.25
+45.138.135.26
+45.138.135.27
+45.138.135.28
+45.138.135.29
+45.138.135.30
+45.138.135.31
+45.138.135.35
+45.138.135.38
+45.138.135.42
+45.138.135.43
+45.138.135.45
+45.138.135.48
+45.138.135.51
+45.138.135.52
+45.138.135.59
+45.138.135.83
+45.138.135.97
+45.138.135.114
+45.138.135.115
+45.138.135.116
+45.138.135.120
+45.138.135.131
+45.138.135.140
+45.138.135.145
+45.138.135.153
+45.138.135.158
+45.138.135.163
+45.138.135.171
+45.138.135.176
+45.138.135.182
+45.138.135.185
+45.138.135.186
+45.138.135.190
+45.138.135.202
+45.138.135.203
+45.138.135.205
+45.138.135.209
+45.138.135.222
+45.138.135.223
+45.138.135.231
+45.138.135.233
+45.138.135.238
+45.138.135.241
+45.138.135.250
+45.138.135.251
+45.139.10.8
+45.139.10.23
+45.139.10.37
+45.139.10.42
+45.139.10.45
+45.139.10.51
+45.139.10.52
+45.139.10.53
+45.139.10.58
+45.139.10.65
+45.139.10.68
+45.139.10.70
+45.139.10.82
+45.139.10.86
+45.139.10.87
+45.139.10.92
+45.139.10.100
+45.139.10.108
+45.139.10.110
+45.139.10.113
+45.139.10.119
+45.139.10.120
+45.139.10.124
+45.139.10.126
+45.139.10.130
+45.139.10.133
+45.139.10.136
+45.139.10.139
+45.139.10.143
+45.139.10.157
+45.139.10.167
+45.139.10.181
+45.139.10.190
+45.139.10.194
+45.139.10.195
+45.139.10.198
+45.139.10.203
+45.139.10.210
+45.139.10.213
+45.139.10.215
+45.139.10.224
+45.139.10.233
+45.139.10.242
+45.139.10.243
+45.139.10.246
+45.139.10.247
+45.139.10.251
+45.139.10.252
+45.139.10.253
+45.139.11.5
+45.139.11.7
+45.139.11.29
+45.139.11.43
+45.139.11.45
+45.139.11.46
+45.139.11.47
+45.139.11.48
+45.139.11.50
+45.139.11.51
+45.139.11.60
+45.139.11.72
+45.139.11.78
+45.139.11.83
+45.139.11.89
+45.139.11.98
+45.139.11.100
+45.139.11.102
+45.139.11.107
+45.139.11.108
+45.139.11.115
+45.139.11.124
+45.139.11.125
+45.139.11.128
+45.139.11.133
+45.139.11.135
+45.139.11.137
+45.139.11.139
+45.139.11.140
+45.139.11.142
+45.139.11.145
+45.139.11.146
+45.139.11.149
+45.139.11.155
+45.139.11.157
+45.139.11.164
+45.139.11.169
+45.139.11.170
+45.139.11.174
+45.139.11.177
+45.139.11.179
+45.139.11.187
+45.139.11.194
+45.139.11.212
+45.139.11.216
+45.139.11.219
+45.139.11.222
+45.139.11.226
+45.139.11.229
+45.139.11.244
+45.142.189.25
+45.142.189.68
+45.142.189.114
+45.142.189.200
+45.142.191.152
+45.144.18.2
+45.144.18.6
+45.144.18.10
+45.144.18.12
+45.144.18.17
+45.144.18.20
+45.144.18.50
+45.144.18.51
+45.144.18.58
+45.144.18.59
+45.144.18.60
+45.144.18.66
+45.144.18.72
+45.144.18.73
+45.144.18.100
+45.144.18.102
+45.144.18.104
+45.144.18.110
+45.144.18.115
+45.144.18.118
+45.144.18.119
+45.144.18.124
+45.144.18.129
+45.144.18.130
+45.147.76.66
+45.147.76.115
+45.147.76.118
+45.147.76.119
+45.147.76.120
+45.147.76.121
+45.147.76.138
+45.147.76.171
+45.147.76.173
+45.147.76.211
+45.147.76.249
+45.147.76.250
+45.147.76.251
+45.147.76.253
+45.147.76.254
+45.147.77.50
+45.147.77.53
+45.147.77.82
+45.147.77.83
+45.147.77.91
+45.147.77.221
+45.147.78.21
+45.147.78.40
+45.147.78.99
+45.147.78.198
+45.147.78.200
+45.147.78.201
+45.147.78.204
+45.147.78.243
+45.148.250.246
+45.149.76.11
+45.149.76.13
+45.149.76.14
+45.149.76.15
+45.149.76.16
+45.149.76.17
+45.149.76.22
+45.149.76.26
+45.149.76.27
+45.149.76.28
+45.149.76.29
+45.149.76.31
+45.149.76.34
+45.149.76.36
+45.149.76.37
+45.149.76.39
+45.149.76.47
+45.149.76.49
+45.149.76.50
+45.149.76.59
+45.149.76.64
+45.149.76.69
+45.149.76.87
+45.149.76.90
+45.149.76.93
+45.149.76.94
+45.149.76.96
+45.149.76.117
+45.149.76.130
+45.149.76.131
+45.149.76.141
+45.149.76.144
+45.149.76.145
+45.149.76.148
+45.149.76.151
+45.149.76.154
+45.149.76.156
+45.149.76.157
+45.149.76.164
+45.149.76.170
+45.149.76.172
+45.149.76.173
+45.149.76.174
+45.149.76.187
+45.149.76.192
+45.149.76.204
+45.149.76.210
+45.149.76.213
+45.149.76.218
+45.149.76.226
+45.149.76.229
+45.149.76.230
+45.149.76.231
+45.149.76.234
+45.149.76.244
+45.149.76.249
+45.149.76.250
+45.149.77.5
+45.149.77.7
+45.149.77.12
+45.149.77.25
+45.149.77.30
+45.149.77.31
+45.149.77.35
+45.149.77.45
+45.149.77.51
+45.149.77.61
+45.149.77.73
+45.149.77.77
+45.149.77.80
+45.149.77.84
+45.149.77.85
+45.149.77.87
+45.149.77.92
+45.149.77.94
+45.149.77.95
+45.149.77.97
+45.149.77.100
+45.149.77.101
+45.149.77.108
+45.149.77.126
+45.149.77.131
+45.149.77.139
+45.149.77.143
+45.149.77.147
+45.149.77.154
+45.149.77.162
+45.149.77.166
+45.149.77.167
+45.149.77.175
+45.149.77.181
+45.149.77.182
+45.149.77.191
+45.149.77.196
+45.149.77.204
+45.149.77.222
+45.149.77.224
+45.149.77.232
+45.149.77.233
+45.149.77.236
+45.149.77.247
+45.149.77.248
+45.149.78.5
+45.149.78.16
+45.149.78.17
+45.149.78.20
+45.149.78.21
+45.149.78.30
+45.149.78.33
+45.149.78.44
+45.149.78.45
+45.149.78.53
+45.149.78.56
+45.149.78.59
+45.149.78.61
+45.149.78.64
+45.149.78.69
+45.149.78.75
+45.149.78.82
+45.149.78.83
+45.149.78.87
+45.149.78.89
+45.149.78.92
+45.149.78.95
+45.149.78.96
+45.149.78.101
+45.149.78.106
+45.149.78.114
+45.149.78.120
+45.149.78.121
+45.149.78.131
+45.149.78.132
+45.149.78.135
+45.149.78.142
+45.149.78.143
+45.149.78.146
+45.149.78.159
+45.149.78.169
+45.149.78.172
+45.149.78.176
+45.149.78.180
+45.149.78.197
+45.149.78.207
+45.149.78.211
+45.149.78.220
+45.149.78.224
+45.149.78.233
+45.149.78.234
+45.149.78.246
+45.149.78.248
+45.149.78.253
+45.149.79.5
+45.149.79.8
+45.149.79.9
+45.149.79.13
+45.149.79.15
+45.149.79.18
+45.149.79.25
+45.149.79.26
+45.149.79.29
+45.149.79.36
+45.149.79.50
+45.149.79.54
+45.149.79.62
+45.149.79.64
+45.149.79.67
+45.149.79.71
+45.149.79.80
+45.149.79.84
+45.149.79.88
+45.149.79.98
+45.149.79.104
+45.149.79.105
+45.149.79.111
+45.149.79.114
+45.149.79.125
+45.149.79.127
+45.149.79.132
+45.149.79.133
+45.149.79.134
+45.149.79.139
+45.149.79.142
+45.149.79.152
+45.149.79.160
+45.149.79.162
+45.149.79.164
+45.149.79.165
+45.149.79.167
+45.149.79.169
+45.149.79.171
+45.149.79.174
+45.149.79.185
+45.149.79.186
+45.149.79.189
+45.149.79.190
+45.149.79.194
+45.149.79.199
+45.149.79.204
+45.149.79.210
+45.149.79.212
+45.149.79.223
+45.149.79.243
+45.149.79.250
+45.156.184.24
+45.156.184.25
+45.156.184.27
+45.156.184.28
+45.156.184.29
+45.156.184.30
+45.156.184.31
+45.156.184.33
+45.156.184.34
+45.156.184.35
+45.156.184.37
+45.156.184.38
+45.156.184.39
+45.156.184.41
+45.156.184.42
+45.156.184.47
+45.156.184.51
+45.156.184.104
+45.156.184.243
+45.156.185.5
+45.156.185.8
+45.156.185.43
+45.156.185.45
+45.156.185.48
+45.156.185.53
+45.156.185.69
+45.156.185.77
+45.156.185.78
+45.156.185.83
+45.156.185.88
+45.156.185.91
+45.156.185.92
+45.156.185.98
+45.156.185.131
+45.156.185.151
+45.156.185.157
+45.156.185.166
+45.156.185.170
+45.156.185.171
+45.156.185.188
+45.156.185.195
+45.156.185.199
+45.156.185.222
+45.156.185.230
+45.156.185.233
+45.156.185.249
+45.156.186.17
+45.156.186.19
+45.156.186.25
+45.156.186.41
+45.156.186.42
+45.156.186.92
+45.156.186.128
+45.156.186.183
+45.156.186.200
+45.156.186.246
+45.156.187.38
+45.156.187.48
+45.156.187.62
+45.156.187.99
+45.156.187.102
+45.156.187.108
+45.156.187.110
+45.156.187.134
+45.157.244.200
+45.157.244.201
+45.159.112.5
+45.159.112.11
+45.159.112.12
+45.159.112.14
+45.159.112.16
+45.159.112.17
+45.159.112.19
+45.159.112.21
+45.159.112.25
+45.159.112.30
+45.159.112.33
+45.159.112.34
+45.159.112.35
+45.159.112.36
+45.159.112.37
+45.159.112.60
+45.159.112.63
+45.159.112.65
+45.159.112.66
+45.159.112.68
+45.159.112.70
+45.159.112.72
+45.159.112.73
+45.159.112.81
+45.159.112.82
+45.159.112.85
+45.159.112.92
+45.159.112.96
+45.159.112.115
+45.159.112.116
+45.159.112.117
+45.159.112.118
+45.159.112.124
+45.159.112.130
+45.159.112.131
+45.159.112.132
+45.159.112.135
+45.159.112.136
+45.159.112.141
+45.159.112.147
+45.159.112.149
+45.159.112.152
+45.159.112.168
+45.159.112.171
+45.159.112.186
+45.159.112.203
+45.159.112.205
+45.159.112.216
+45.159.113.16
+45.159.113.18
+45.159.113.22
+45.159.113.39
+45.159.113.41
+45.159.113.51
+45.159.113.64
+45.159.113.66
+45.159.113.67
+45.159.113.72
+45.159.113.88
+45.159.113.91
+45.159.113.98
+45.159.113.101
+45.159.113.102
+45.159.113.103
+45.159.113.106
+45.159.113.108
+45.159.113.110
+45.159.113.111
+45.159.113.116
+45.159.113.117
+45.159.113.118
+45.159.113.119
+45.159.113.121
+45.159.113.123
+45.159.113.124
+45.159.113.126
+45.159.113.128
+45.159.113.129
+45.159.113.133
+45.159.113.134
+45.159.113.135
+45.159.113.137
+45.159.113.146
+45.159.113.149
+45.159.113.154
+45.159.113.157
+45.159.113.160
+45.159.113.163
+45.159.113.171
+45.159.113.194
+45.159.113.200
+45.159.113.202
+45.159.113.203
+45.159.113.204
+45.159.113.206
+45.159.113.208
+45.159.113.211
+45.159.113.216
+45.159.113.224
+45.159.113.225
+45.159.113.228
+45.159.113.236
+45.159.113.249
+45.159.114.211
+45.159.114.213
+45.159.114.215
+45.159.114.219
+45.159.114.220
+45.159.114.227
+45.159.114.229
+45.159.114.230
+45.159.114.231
+45.159.114.232
+45.159.114.239
+45.159.114.241
+45.159.114.251
+45.159.115.7
+45.159.115.10
+45.159.115.11
+45.159.115.12
+45.159.115.14
+45.159.115.15
+45.159.115.21
+45.159.115.32
+45.159.115.38
+45.159.115.39
+45.159.115.40
+45.159.115.44
+45.159.115.51
+45.159.115.52
+45.159.115.68
+45.159.115.79
+45.159.115.81
+45.159.115.86
+45.159.115.88
+45.159.115.90
+45.159.115.91
+45.159.115.92
+45.159.115.93
+45.159.115.98
+45.159.115.100
+45.159.115.101
+45.159.115.103
+45.159.115.105
+45.159.115.107
+45.159.115.108
+45.159.115.109
+45.159.115.110
+45.159.115.112
+45.159.115.114
+45.159.115.115
+45.159.115.116
+45.159.115.118
+45.159.115.120
+45.159.115.123
+45.159.115.124
+45.159.115.126
+45.159.115.128
+45.159.115.130
+45.159.115.136
+45.159.115.137
+45.159.115.138
+45.159.115.139
+45.159.115.141
+45.159.115.142
+45.159.115.146
+45.159.115.147
+45.159.115.149
+45.159.115.154
+45.159.115.156
+45.159.115.157
+45.159.115.158
+45.159.115.159
+45.159.115.162
+45.159.115.163
+45.159.115.165
+45.159.115.170
+45.159.115.173
+45.159.115.174
+45.159.115.175
+45.159.115.179
+45.159.115.180
+45.159.115.181
+45.159.115.183
+45.159.115.185
+45.159.115.186
+45.159.115.188
+45.159.115.190
+45.159.115.197
+45.159.115.200
+45.159.115.205
+45.159.115.215
+45.159.115.218
+45.159.115.230
+45.159.115.231
+45.159.115.232
+45.159.115.234
+45.159.115.238
+45.159.149.5
+45.159.149.6
+45.159.149.7
+45.159.149.8
+45.159.149.13
+45.159.149.15
+45.159.149.17
+45.159.149.19
+45.159.149.25
+45.159.149.29
+45.159.149.31
+45.159.149.42
+45.159.149.52
+45.159.149.55
+45.159.149.63
+45.159.149.64
+45.159.149.70
+45.159.149.79
+45.159.149.83
+45.159.149.89
+45.159.149.91
+45.159.149.92
+45.159.149.95
+45.159.149.101
+45.159.149.105
+45.159.149.109
+45.159.149.125
+45.159.149.127
+45.159.149.135
+45.159.149.146
+45.159.149.147
+45.159.149.154
+45.159.149.160
+45.159.149.165
+45.159.149.172
+45.159.149.180
+45.159.149.186
+45.159.149.209
+45.159.149.211
+45.159.149.215
+45.159.149.217
+45.159.149.232
+45.159.149.252
+45.159.149.253
+45.159.150.5
+45.159.150.12
+45.159.150.14
+45.159.150.20
+45.159.150.26
+45.159.150.27
+45.159.150.41
+45.159.150.53
+45.159.150.69
+45.159.150.75
+45.159.150.78
+45.159.150.88
+45.159.150.89
+45.159.150.100
+45.159.150.107
+45.159.150.115
+45.159.150.129
+45.159.150.133
+45.159.150.136
+45.159.150.142
+45.159.150.146
+45.159.150.152
+45.159.150.166
+45.159.150.173
+45.159.150.179
+45.159.150.181
+45.159.150.184
+45.159.150.194
+45.159.150.204
+45.159.150.221
+45.159.150.222
+45.159.150.223
+45.159.150.224
+45.159.150.231
+45.159.150.242
+45.159.150.244
+45.159.150.245
+45.159.151.8
+45.159.151.25
+45.159.151.33
+45.159.151.34
+45.159.151.35
+45.159.151.42
+45.159.151.44
+45.159.151.48
+45.159.151.53
+45.159.151.55
+45.159.151.56
+45.159.151.58
+45.159.151.59
+45.159.151.61
+45.159.151.63
+45.159.151.64
+45.159.151.65
+45.159.151.66
+45.159.151.67
+45.159.151.70
+45.159.151.71
+45.159.151.73
+45.159.151.74
+45.159.151.75
+45.159.151.76
+45.159.151.77
+45.159.151.78
+45.159.151.79
+45.159.151.80
+45.159.151.81
+45.159.151.82
+45.159.151.84
+45.159.151.85
+45.159.151.86
+45.159.151.87
+45.159.151.88
+45.159.151.89
+45.159.151.90
+45.159.151.91
+45.159.151.92
+45.159.151.93
+45.159.151.94
+45.159.151.95
+45.159.151.99
+45.159.151.100
+45.159.151.101
+45.159.151.102
+45.159.151.109
+45.159.151.110
+45.159.151.111
+45.159.151.112
+45.159.151.113
+45.159.151.114
+45.159.151.115
+45.159.151.116
+45.159.151.117
+45.159.151.118
+45.159.151.119
+45.159.151.120
+45.159.151.121
+45.159.151.122
+45.159.151.123
+45.159.151.124
+45.159.151.125
+45.159.151.126
+45.159.151.129
+45.159.151.133
+45.159.151.134
+45.159.151.135
+45.159.151.136
+45.159.151.138
+45.159.151.145
+45.159.151.146
+45.159.151.147
+45.159.151.149
+45.159.151.150
+45.159.151.151
+45.159.151.152
+45.159.151.154
+45.159.151.155
+45.159.151.156
+45.159.151.158
+45.159.151.159
+45.159.151.160
+45.159.151.161
+45.159.151.162
+45.159.151.163
+45.159.151.164
+45.159.151.165
+45.159.151.166
+45.159.151.167
+45.159.151.168
+45.159.151.170
+45.159.151.171
+45.159.196.5
+45.159.197.66
+45.159.197.99
+45.159.197.139
+45.159.197.141
+45.159.198.4
+45.159.198.5
+45.159.198.9
+45.159.198.10
+45.159.198.182
+45.159.198.251
+45.159.199.130
+46.18.248.136
+46.28.74.35
+46.28.78.11
+46.28.78.12
+46.32.4.137
+46.32.4.165
+46.32.4.244
+46.32.10.50
+46.32.11.130
+46.32.11.131
+46.32.12.72
+46.32.15.196
+46.32.16.68
+46.32.17.68
+46.32.17.70
+46.32.26.18
+46.32.30.74
+46.32.30.81
+46.32.31.29
+46.32.31.30
+46.34.160.41
+46.34.160.56
+46.34.162.76
+46.34.163.85
+46.34.165.1
+46.34.166.60
+46.34.166.210
+46.34.167.120
+46.36.96.1
+46.36.96.65
+46.36.96.66
+46.36.107.98
+46.36.107.99
+46.36.111.2
+46.36.111.3
+46.38.138.47
+46.38.138.84
+46.38.138.89
+46.38.138.92
+46.38.138.156
+46.38.138.168
+46.38.142.66
+46.38.146.131
+46.38.146.163
+46.38.147.10
+46.38.150.195
+46.38.150.243
+46.38.159.21
+46.38.159.23
+46.100.5.49
+46.100.8.21
+46.100.10.64
+46.100.12.158
+46.100.12.255
+46.100.13.60
+46.100.41.110
+46.100.41.240
+46.100.45.147
+46.100.47.154
+46.100.48.239
+46.100.58.214
+46.100.63.131
+46.100.74.83
+46.100.84.60
+46.100.85.5
+46.100.90.13
+46.100.90.93
+46.100.90.166
+46.100.95.206
+46.100.166.125
+46.100.167.215
+46.100.167.222
+46.100.177.148
+46.100.218.22
+46.100.249.63
+46.100.249.195
+46.102.129.202
+46.102.129.203
+46.102.130.2
+46.102.130.31
+46.102.130.116
+46.102.130.165
+46.102.130.166
+46.102.130.215
+46.102.130.229
+46.102.132.112
+46.102.136.2
+46.102.136.33
+46.102.136.34
+46.102.136.35
+46.102.136.36
+46.102.136.75
+46.102.136.77
+46.102.136.89
+46.102.136.93
+46.102.137.18
+46.102.138.219
+46.102.138.222
+46.102.139.45
+46.102.139.66
+46.102.139.67
+46.102.139.68
+46.102.139.69
+46.102.139.70
+46.102.139.98
+46.102.139.118
+46.102.140.16
+46.102.140.45
+46.102.141.156
+46.148.34.202
+46.148.35.162
+46.148.35.163
+46.148.36.9
+46.148.41.47
+46.148.47.1
+46.148.47.27
+46.167.135.183
+46.167.139.74
+46.167.139.125
+46.167.141.33
+46.167.141.196
+46.167.144.175
+46.167.146.37
+46.167.146.174
+46.167.146.202
+46.167.146.231
+46.167.158.79
+46.167.159.116
+46.209.7.114
+46.209.7.115
+46.209.7.116
+46.209.7.136
+46.209.9.178
+46.209.11.8
+46.209.11.30
+46.209.16.181
+46.209.20.86
+46.209.20.154
+46.209.20.181
+46.209.22.219
+46.209.25.195
+46.209.30.13
+46.209.31.248
+46.209.44.74
+46.209.50.15
+46.209.50.133
+46.209.59.66
+46.209.59.67
+46.209.62.250
+46.209.67.150
+46.209.69.121
+46.209.69.123
+46.209.73.211
+46.209.89.19
+46.209.92.54
+46.209.92.147
+46.209.115.6
+46.209.128.217
+46.209.150.220
+46.209.157.179
+46.209.191.3
+46.209.191.4
+46.209.206.205
+46.209.207.153
+46.209.207.154
+46.209.207.202
+46.209.207.203
+46.209.209.209
+46.209.211.13
+46.209.213.114
+46.209.216.247
+46.209.221.92
+46.209.239.189
+46.209.239.190
+46.209.240.130
+46.209.241.66
+46.209.244.246
+46.209.251.12
+46.235.77.195
+46.245.0.105
+46.245.4.205
+46.245.5.30
+46.245.6.140
+46.245.8.140
+46.245.13.16
+46.245.16.181
+46.245.17.163
+46.245.24.138
+46.245.28.206
+46.245.34.157
+46.245.38.100
+46.245.38.101
+46.245.39.140
+46.245.39.163
+46.245.43.60
+46.245.43.87
+46.245.45.87
+46.245.45.174
+46.245.64.24
+46.245.64.36
+46.245.64.37
+46.245.64.38
+46.245.64.55
+46.245.64.132
+46.245.66.13
+46.245.66.26
+46.245.66.61
+46.245.66.72
+46.245.66.91
+46.245.66.120
+46.245.66.137
+46.245.67.36
+46.245.67.101
+46.245.67.141
+46.245.67.162
+46.245.68.169
+46.245.69.35
+46.245.69.94
+46.245.69.109
+46.245.69.110
+46.245.69.133
+46.245.69.134
+46.245.69.135
+46.245.69.215
+46.245.69.222
+46.245.69.229
+46.245.69.234
+46.245.72.183
+46.245.73.17
+46.245.73.26
+46.245.76.4
+46.245.76.5
+46.245.76.6
+46.245.76.7
+46.245.76.8
+46.245.76.9
+46.245.76.10
+46.245.76.11
+46.245.76.12
+46.245.76.13
+46.245.76.14
+46.245.76.28
+46.245.76.29
+46.245.76.50
+46.245.76.51
+46.245.76.52
+46.245.76.53
+46.245.76.54
+46.245.76.116
+46.245.76.162
+46.245.76.171
+46.245.76.172
+46.245.76.173
+46.245.76.174
+46.245.77.7
+46.245.77.8
+46.245.77.70
+46.245.77.75
+46.245.77.76
+46.245.77.77
+46.245.77.78
+46.245.78.18
+46.245.78.19
+46.245.78.227
+46.245.79.11
+46.245.79.134
+46.245.79.135
+46.245.79.136
+46.245.79.137
+46.245.79.235
+46.245.80.35
+46.245.80.75
+46.245.80.77
+46.245.80.82
+46.245.80.206
+46.245.81.54
+46.245.81.61
+46.245.81.68
+46.245.81.90
+46.245.83.130
+46.245.84.44
+46.245.85.3
+46.245.85.22
+46.245.85.27
+46.245.85.28
+46.245.85.29
+46.245.85.36
+46.245.85.37
+46.245.85.44
+46.245.85.179
+46.245.86.26
+46.245.86.28
+46.245.86.29
+46.245.86.30
+46.245.86.177
+46.245.86.186
+46.245.86.190
+46.245.86.242
+46.245.86.245
+46.245.87.68
+46.245.87.69
+46.245.87.72
+46.245.87.74
+46.245.87.75
+46.245.87.105
+46.245.87.110
+46.245.87.132
+46.245.87.222
+46.245.88.170
+46.245.88.171
+46.245.88.172
+46.245.88.173
+46.245.88.174
+46.245.89.100
+46.245.89.130
+46.245.89.131
+46.245.89.133
+46.245.89.136
+46.245.89.138
+46.245.89.141
+46.245.89.203
+46.245.91.214
+46.245.91.227
+46.245.91.228
+46.245.91.229
+46.245.91.231
+46.245.91.233
+46.245.91.237
+46.245.91.238
+46.245.91.245
+46.245.92.2
+46.245.92.58
+46.245.92.85
+46.245.92.86
+46.245.92.107
+46.245.92.108
+46.245.92.109
+46.245.92.116
+46.245.92.185
+46.245.93.42
+46.245.93.115
+46.245.93.201
+46.245.93.202
+46.245.93.209
+46.245.94.109
+46.245.94.163
+46.245.94.170
+46.245.94.171
+46.245.94.172
+46.245.95.99
+46.245.95.133
+46.245.95.136
+46.245.95.152
+46.245.95.160
+46.245.95.162
+46.245.95.165
+46.245.95.237
+46.245.96.216
+46.245.98.13
+46.245.99.40
+46.245.99.142
+46.245.100.90
+46.245.107.28
+46.245.107.29
+46.245.107.164
+46.245.107.195
+46.245.107.198
+46.245.107.199
+46.245.107.201
+46.245.107.202
+46.245.107.205
+46.245.112.61
+46.245.114.228
+46.245.115.51
+46.245.115.56
+46.245.115.201
+46.245.115.213
+46.245.120.150
+46.245.122.8
+46.245.122.24
+46.245.122.25
+46.245.123.19
+46.245.123.20
+46.245.123.21
+46.245.123.23
+46.245.123.25
+46.245.124.20
+46.245.124.48
+46.249.122.162
+46.249.125.22
+62.3.14.59
+62.3.14.68
+62.3.14.132
+62.3.14.133
+62.3.14.134
+62.3.14.135
+62.3.14.140
+62.3.14.153
+62.3.14.154
+62.3.14.162
+62.3.14.163
+62.3.14.164
+62.3.14.167
+62.3.14.168
+62.3.14.169
+62.3.14.203
+62.3.14.204
+62.3.14.205
+62.3.41.8
+62.3.41.9
+62.3.41.28
+62.3.41.32
+62.3.41.36
+62.3.41.45
+62.3.41.47
+62.3.41.50
+62.3.41.53
+62.3.41.66
+62.3.41.73
+62.3.41.77
+62.3.41.82
+62.3.41.87
+62.3.41.89
+62.3.41.92
+62.3.41.111
+62.3.41.114
+62.3.41.117
+62.3.41.122
+62.3.41.129
+62.3.41.132
+62.3.41.135
+62.3.41.149
+62.3.41.159
+62.3.41.160
+62.3.41.178
+62.3.41.179
+62.3.41.191
+62.3.41.194
+62.3.41.198
+62.3.41.199
+62.3.41.200
+62.3.41.210
+62.3.41.215
+62.3.41.226
+62.3.41.227
+62.3.41.228
+62.3.41.229
+62.3.41.233
+62.3.41.237
+62.3.41.242
+62.3.41.253
+62.3.42.17
+62.3.42.32
+62.3.42.34
+62.3.42.47
+62.3.42.59
+62.3.42.85
+62.3.42.90
+62.3.42.99
+62.3.42.105
+62.3.42.106
+62.3.42.111
+62.3.42.119
+62.3.42.126
+62.3.42.131
+62.3.42.134
+62.3.42.137
+62.3.42.139
+62.3.42.145
+62.3.42.171
+62.3.42.176
+62.3.42.187
+62.3.42.198
+62.3.42.206
+62.3.42.215
+62.3.42.237
+62.3.42.238
+62.60.128.8
+62.60.128.11
+62.60.128.42
+62.60.128.49
+62.60.128.54
+62.60.128.56
+62.60.128.58
+62.60.128.59
+62.60.128.89
+62.60.128.105
+62.60.128.119
+62.60.128.120
+62.60.128.122
+62.60.128.124
+62.60.128.125
+62.60.128.126
+62.60.128.127
+62.60.128.209
+62.60.129.186
+62.60.129.189
+62.60.132.61
+62.60.132.133
+62.60.132.174
+62.60.132.248
+62.60.133.4
+62.60.133.5
+62.60.133.6
+62.60.133.7
+62.60.133.9
+62.60.133.10
+62.60.133.11
+62.60.133.12
+62.60.133.13
+62.60.133.14
+62.60.133.15
+62.60.133.16
+62.60.133.17
+62.60.133.18
+62.60.133.19
+62.60.133.20
+62.60.133.22
+62.60.133.23
+62.60.133.24
+62.60.133.25
+62.60.133.26
+62.60.133.27
+62.60.133.29
+62.60.133.30
+62.60.133.31
+62.60.133.32
+62.60.133.33
+62.60.133.34
+62.60.133.36
+62.60.133.37
+62.60.133.38
+62.60.133.39
+62.60.133.40
+62.60.133.41
+62.60.133.42
+62.60.133.43
+62.60.133.44
+62.60.133.45
+62.60.133.47
+62.60.133.48
+62.60.133.49
+62.60.133.50
+62.60.133.51
+62.60.133.52
+62.60.133.53
+62.60.133.54
+62.60.133.55
+62.60.133.56
+62.60.133.58
+62.60.133.59
+62.60.133.61
+62.60.133.62
+62.60.133.63
+62.60.133.64
+62.60.133.65
+62.60.133.66
+62.60.133.67
+62.60.133.68
+62.60.133.69
+62.60.133.70
+62.60.133.71
+62.60.133.72
+62.60.133.73
+62.60.133.74
+62.60.133.75
+62.60.133.76
+62.60.133.77
+62.60.133.78
+62.60.133.79
+62.60.133.80
+62.60.133.83
+62.60.133.84
+62.60.133.85
+62.60.133.86
+62.60.133.87
+62.60.133.88
+62.60.133.89
+62.60.133.90
+62.60.133.91
+62.60.133.92
+62.60.133.93
+62.60.133.94
+62.60.133.95
+62.60.133.96
+62.60.133.97
+62.60.133.98
+62.60.133.99
+62.60.133.100
+62.60.133.102
+62.60.133.103
+62.60.133.104
+62.60.133.105
+62.60.133.106
+62.60.133.107
+62.60.133.109
+62.60.133.110
+62.60.133.111
+62.60.133.112
+62.60.133.113
+62.60.133.114
+62.60.133.115
+62.60.133.116
+62.60.133.117
+62.60.133.118
+62.60.133.119
+62.60.133.120
+62.60.133.121
+62.60.133.122
+62.60.133.123
+62.60.133.124
+62.60.133.125
+62.60.133.126
+62.60.133.127
+62.60.133.128
+62.60.133.130
+62.60.133.131
+62.60.133.132
+62.60.133.133
+62.60.133.134
+62.60.133.135
+62.60.133.136
+62.60.133.137
+62.60.133.138
+62.60.133.139
+62.60.133.140
+62.60.133.141
+62.60.133.142
+62.60.133.143
+62.60.133.144
+62.60.133.145
+62.60.133.146
+62.60.133.147
+62.60.133.148
+62.60.133.149
+62.60.133.150
+62.60.133.152
+62.60.133.153
+62.60.133.154
+62.60.133.155
+62.60.133.156
+62.60.133.157
+62.60.133.158
+62.60.133.159
+62.60.133.160
+62.60.133.161
+62.60.133.162
+62.60.133.163
+62.60.133.164
+62.60.133.165
+62.60.133.166
+62.60.133.167
+62.60.133.168
+62.60.133.169
+62.60.133.170
+62.60.133.171
+62.60.133.172
+62.60.133.173
+62.60.133.174
+62.60.133.175
+62.60.133.176
+62.60.133.177
+62.60.133.178
+62.60.133.179
+62.60.133.180
+62.60.133.181
+62.60.133.182
+62.60.133.183
+62.60.133.184
+62.60.133.185
+62.60.133.186
+62.60.133.187
+62.60.133.188
+62.60.133.189
+62.60.133.190
+62.60.133.191
+62.60.133.192
+62.60.133.194
+62.60.133.195
+62.60.133.196
+62.60.133.197
+62.60.133.198
+62.60.133.201
+62.60.133.202
+62.60.133.203
+62.60.133.205
+62.60.133.207
+62.60.133.208
+62.60.133.209
+62.60.133.210
+62.60.133.228
+62.60.133.238
+62.60.133.243
+62.60.133.245
+62.60.133.246
+62.60.133.247
+62.60.133.249
+62.60.133.250
+62.60.133.251
+62.60.133.252
+62.60.133.253
+62.60.133.254
+62.60.136.105
+62.60.136.158
+62.60.136.190
+62.60.136.215
+62.60.136.225
+62.60.137.2
+62.60.140.47
+62.60.140.251
+62.60.141.4
+62.60.144.44
+62.60.144.45
+62.60.144.68
+62.60.144.85
+62.60.144.87
+62.60.160.28
+62.60.160.33
+62.60.160.34
+62.60.160.38
+62.60.160.40
+62.60.160.75
+62.60.160.79
+62.60.160.80
+62.60.160.100
+62.60.161.109
+62.60.161.115
+62.60.162.96
+62.60.162.100
+62.60.162.102
+62.60.162.104
+62.60.162.109
+62.60.162.110
+62.60.162.206
+62.60.162.247
+62.60.163.203
+62.60.164.19
+62.60.164.32
+62.60.164.43
+62.60.164.49
+62.60.164.133
+62.60.164.137
+62.60.164.158
+62.60.164.191
+62.60.164.197
+62.60.164.198
+62.60.164.206
+62.60.164.207
+62.60.164.214
+62.60.164.216
+62.60.164.217
+62.60.164.219
+62.60.164.242
+62.60.165.23
+62.60.165.151
+62.60.165.203
+62.60.165.216
+62.60.165.219
+62.60.165.230
+62.60.165.233
+62.60.165.236
+62.60.165.239
+62.60.165.241
+62.60.165.246
+62.60.165.248
+62.60.166.50
+62.60.167.38
+62.60.167.66
+62.60.167.67
+62.60.167.68
+62.60.167.69
+62.60.167.74
+62.60.167.194
+62.60.167.202
+62.60.167.203
+62.60.167.204
+62.60.167.205
+62.60.167.206
+62.60.167.210
+62.60.167.234
+62.60.167.242
+62.60.167.250
+62.60.190.61
+62.60.196.13
+62.60.196.26
+62.60.196.44
+62.60.196.235
+62.60.196.238
+62.60.197.3
+62.60.197.4
+62.60.197.5
+62.60.197.6
+62.60.197.7
+62.60.197.8
+62.60.197.9
+62.60.197.10
+62.60.197.12
+62.60.197.14
+62.60.197.83
+62.60.197.85
+62.60.197.222
+62.60.198.38
+62.60.198.239
+62.60.200.93
+62.60.200.94
+62.60.200.118
+62.60.200.131
+62.60.200.144
+62.60.200.196
+62.60.200.197
+62.60.200.203
+62.60.200.214
+62.60.200.252
+62.60.201.3
+62.60.201.4
+62.60.201.5
+62.60.201.6
+62.60.201.7
+62.60.201.8
+62.60.201.9
+62.60.201.10
+62.60.201.12
+62.60.201.13
+62.60.201.14
+62.60.201.15
+62.60.201.16
+62.60.201.17
+62.60.201.18
+62.60.201.20
+62.60.201.21
+62.60.201.22
+62.60.201.24
+62.60.201.25
+62.60.201.26
+62.60.201.27
+62.60.201.28
+62.60.201.29
+62.60.201.30
+62.60.201.31
+62.60.201.32
+62.60.201.33
+62.60.201.34
+62.60.201.62
+62.60.201.63
+62.60.201.64
+62.60.201.65
+62.60.201.66
+62.60.201.67
+62.60.201.68
+62.60.201.69
+62.60.201.70
+62.60.201.71
+62.60.201.72
+62.60.201.73
+62.60.201.74
+62.60.201.75
+62.60.201.76
+62.60.201.77
+62.60.201.78
+62.60.201.79
+62.60.201.80
+62.60.201.81
+62.60.201.82
+62.60.201.83
+62.60.201.84
+62.60.201.85
+62.60.201.86
+62.60.201.87
+62.60.201.88
+62.60.201.89
+62.60.201.90
+62.60.201.92
+62.60.201.93
+62.60.201.94
+62.60.201.95
+62.60.201.97
+62.60.201.99
+62.60.201.100
+62.60.201.102
+62.60.201.103
+62.60.201.104
+62.60.201.105
+62.60.201.106
+62.60.201.107
+62.60.201.108
+62.60.201.109
+62.60.201.110
+62.60.201.111
+62.60.201.112
+62.60.201.113
+62.60.201.115
+62.60.201.116
+62.60.201.117
+62.60.201.118
+62.60.201.119
+62.60.201.120
+62.60.201.121
+62.60.201.122
+62.60.201.123
+62.60.201.124
+62.60.201.125
+62.60.201.126
+62.60.201.127
+62.60.201.128
+62.60.201.130
+62.60.201.131
+62.60.201.132
+62.60.201.133
+62.60.201.134
+62.60.201.135
+62.60.201.136
+62.60.201.137
+62.60.201.138
+62.60.201.139
+62.60.201.140
+62.60.201.141
+62.60.201.142
+62.60.201.143
+62.60.201.144
+62.60.201.145
+62.60.201.146
+62.60.201.147
+62.60.201.148
+62.60.201.149
+62.60.201.151
+62.60.201.152
+62.60.201.153
+62.60.201.154
+62.60.201.155
+62.60.201.156
+62.60.201.157
+62.60.201.158
+62.60.201.159
+62.60.201.160
+62.60.201.162
+62.60.201.163
+62.60.201.164
+62.60.201.165
+62.60.201.166
+62.60.201.167
+62.60.201.168
+62.60.201.169
+62.60.201.170
+62.60.201.171
+62.60.201.173
+62.60.201.174
+62.60.201.175
+62.60.201.176
+62.60.201.177
+62.60.201.180
+62.60.201.182
+62.60.201.183
+62.60.201.184
+62.60.201.185
+62.60.201.186
+62.60.201.187
+62.60.201.189
+62.60.201.190
+62.60.201.191
+62.60.201.192
+62.60.201.193
+62.60.201.194
+62.60.201.196
+62.60.201.197
+62.60.201.198
+62.60.201.199
+62.60.201.200
+62.60.201.201
+62.60.201.203
+62.60.201.204
+62.60.201.205
+62.60.201.206
+62.60.201.207
+62.60.201.208
+62.60.201.209
+62.60.201.210
+62.60.201.211
+62.60.201.212
+62.60.201.213
+62.60.201.214
+62.60.201.215
+62.60.201.218
+62.60.201.219
+62.60.201.220
+62.60.201.221
+62.60.201.222
+62.60.201.223
+62.60.201.224
+62.60.201.225
+62.60.201.226
+62.60.201.227
+62.60.201.228
+62.60.201.229
+62.60.201.230
+62.60.201.231
+62.60.201.232
+62.60.201.233
+62.60.201.234
+62.60.201.235
+62.60.201.236
+62.60.201.238
+62.60.201.239
+62.60.201.240
+62.60.201.241
+62.60.201.243
+62.60.201.244
+62.60.201.245
+62.60.201.246
+62.60.201.247
+62.60.201.248
+62.60.201.249
+62.60.201.250
+62.60.201.251
+62.60.201.252
+62.60.201.253
+62.60.202.5
+62.60.202.33
+62.60.202.50
+62.60.202.61
+62.60.202.158
+62.60.202.243
+62.60.203.14
+62.60.203.16
+62.60.203.23
+62.60.203.46
+62.60.203.47
+62.60.204.5
+62.60.204.17
+62.60.204.123
+62.60.204.162
+62.60.204.187
+62.60.204.207
+62.60.204.233
+62.60.204.234
+62.60.205.3
+62.60.205.4
+62.60.205.5
+62.60.205.6
+62.60.205.7
+62.60.205.8
+62.60.205.9
+62.60.205.10
+62.60.205.11
+62.60.205.12
+62.60.205.13
+62.60.205.14
+62.60.205.15
+62.60.205.16
+62.60.205.17
+62.60.205.18
+62.60.205.19
+62.60.205.20
+62.60.205.21
+62.60.205.22
+62.60.205.23
+62.60.205.25
+62.60.205.26
+62.60.205.27
+62.60.205.28
+62.60.205.29
+62.60.205.30
+62.60.205.31
+62.60.205.32
+62.60.205.33
+62.60.205.34
+62.60.205.35
+62.60.205.36
+62.60.205.37
+62.60.205.38
+62.60.205.39
+62.60.205.40
+62.60.205.41
+62.60.205.42
+62.60.205.43
+62.60.205.44
+62.60.205.45
+62.60.205.46
+62.60.205.47
+62.60.205.48
+62.60.205.49
+62.60.205.50
+62.60.205.51
+62.60.205.52
+62.60.205.53
+62.60.205.54
+62.60.205.55
+62.60.205.56
+62.60.205.57
+62.60.205.58
+62.60.205.59
+62.60.205.60
+62.60.205.61
+62.60.205.62
+62.60.205.63
+62.60.205.64
+62.60.205.65
+62.60.205.68
+62.60.205.69
+62.60.205.70
+62.60.205.71
+62.60.205.72
+62.60.205.73
+62.60.205.74
+62.60.205.76
+62.60.205.77
+62.60.205.78
+62.60.205.79
+62.60.205.80
+62.60.205.81
+62.60.205.83
+62.60.205.84
+62.60.205.85
+62.60.205.86
+62.60.205.88
+62.60.205.89
+62.60.205.90
+62.60.205.91
+62.60.205.92
+62.60.205.93
+62.60.205.94
+62.60.205.95
+62.60.205.97
+62.60.205.98
+62.60.205.99
+62.60.205.101
+62.60.205.102
+62.60.205.103
+62.60.205.104
+62.60.205.105
+62.60.205.106
+62.60.205.107
+62.60.205.108
+62.60.205.109
+62.60.205.110
+62.60.205.111
+62.60.205.112
+62.60.205.113
+62.60.205.115
+62.60.205.116
+62.60.205.117
+62.60.205.118
+62.60.205.119
+62.60.205.120
+62.60.205.121
+62.60.205.122
+62.60.205.123
+62.60.205.124
+62.60.205.125
+62.60.205.126
+62.60.205.128
+62.60.205.129
+62.60.205.131
+62.60.205.132
+62.60.205.133
+62.60.205.134
+62.60.205.135
+62.60.205.136
+62.60.205.137
+62.60.205.138
+62.60.205.139
+62.60.205.140
+62.60.205.141
+62.60.205.142
+62.60.205.143
+62.60.205.144
+62.60.205.145
+62.60.205.146
+62.60.205.147
+62.60.205.148
+62.60.205.150
+62.60.205.151
+62.60.205.152
+62.60.205.153
+62.60.205.154
+62.60.205.155
+62.60.205.156
+62.60.205.157
+62.60.205.158
+62.60.205.159
+62.60.205.160
+62.60.205.161
+62.60.205.162
+62.60.205.163
+62.60.205.164
+62.60.205.166
+62.60.205.167
+62.60.205.168
+62.60.205.169
+62.60.205.170
+62.60.205.171
+62.60.205.172
+62.60.205.173
+62.60.205.174
+62.60.205.175
+62.60.205.176
+62.60.205.177
+62.60.205.178
+62.60.205.179
+62.60.205.180
+62.60.205.181
+62.60.205.182
+62.60.205.183
+62.60.205.184
+62.60.205.185
+62.60.205.186
+62.60.205.187
+62.60.205.188
+62.60.205.189
+62.60.205.191
+62.60.205.192
+62.60.205.193
+62.60.205.194
+62.60.205.195
+62.60.205.196
+62.60.205.197
+62.60.205.198
+62.60.205.199
+62.60.205.200
+62.60.205.201
+62.60.205.202
+62.60.205.203
+62.60.205.204
+62.60.205.207
+62.60.205.208
+62.60.205.209
+62.60.205.210
+62.60.205.211
+62.60.205.212
+62.60.205.213
+62.60.205.214
+62.60.205.215
+62.60.205.216
+62.60.205.217
+62.60.205.218
+62.60.205.219
+62.60.205.220
+62.60.205.221
+62.60.205.222
+62.60.205.223
+62.60.205.224
+62.60.205.225
+62.60.205.226
+62.60.205.227
+62.60.205.228
+62.60.205.229
+62.60.205.231
+62.60.205.232
+62.60.205.233
+62.60.205.234
+62.60.205.235
+62.60.205.236
+62.60.205.237
+62.60.205.238
+62.60.205.239
+62.60.205.240
+62.60.205.241
+62.60.205.242
+62.60.205.243
+62.60.205.244
+62.60.205.245
+62.60.205.246
+62.60.205.248
+62.60.205.249
+62.60.205.250
+62.60.205.251
+62.60.205.253
+62.60.206.35
+62.60.206.50
+62.60.206.65
+62.60.206.71
+62.60.206.83
+62.60.206.111
+62.60.206.132
+62.60.206.133
+62.60.206.182
+62.60.206.205
+62.60.207.14
+62.60.207.22
+62.60.207.47
+62.60.207.70
+62.60.207.75
+62.60.207.77
+62.60.207.97
+62.60.207.104
+62.60.207.132
+62.60.207.138
+62.60.207.223
+62.60.207.241
+62.60.210.3
+62.60.210.4
+62.60.210.5
+62.60.210.10
+62.60.210.17
+62.60.210.24
+62.60.210.68
+62.60.210.69
+62.60.210.70
+62.60.210.74
+62.60.210.77
+62.60.210.85
+62.60.210.91
+62.60.210.94
+62.60.210.95
+62.60.210.96
+62.60.210.102
+62.60.210.110
+62.60.210.130
+62.60.210.131
+62.60.210.141
+62.60.210.143
+62.60.210.176
+62.60.210.181
+62.60.210.186
+62.60.210.199
+62.60.210.234
+62.60.210.235
+62.60.210.248
+62.60.210.250
+62.60.211.56
+62.60.211.85
+62.60.211.90
+62.60.211.104
+62.60.211.114
+62.60.211.118
+62.60.211.119
+62.60.211.123
+62.60.211.145
+62.60.211.153
+62.60.211.155
+62.60.211.156
+62.60.211.163
+62.60.211.164
+62.60.211.174
+62.60.211.175
+62.60.211.183
+62.60.211.184
+62.60.211.185
+62.60.211.189
+62.60.211.190
+62.60.211.191
+62.60.211.192
+62.60.211.195
+62.60.211.196
+62.60.211.197
+62.60.211.199
+62.60.211.203
+62.60.211.211
+62.60.211.212
+62.60.211.213
+62.60.211.215
+62.60.211.218
+62.60.211.222
+62.60.211.226
+62.60.211.229
+62.60.211.230
+62.60.211.234
+62.60.211.235
+62.60.211.237
+62.60.211.239
+62.60.211.241
+62.60.211.248
+62.60.211.251
+62.60.211.253
+62.60.212.26
+62.60.212.27
+62.60.212.32
+62.60.212.91
+62.60.212.158
+62.60.212.159
+62.60.212.193
+62.60.212.222
+62.60.212.232
+62.60.212.243
+62.60.212.247
+62.60.213.10
+62.60.213.11
+62.60.213.14
+62.60.213.26
+62.60.213.58
+62.60.213.66
+62.60.213.122
+62.60.213.126
+62.60.213.206
+62.60.213.220
+62.60.214.60
+62.60.214.64
+62.60.214.80
+62.60.214.91
+62.60.214.151
+62.60.214.228
+62.60.219.3
+62.106.95.14
+62.106.95.25
+62.106.95.28
+62.106.95.34
+62.106.95.37
+62.106.95.43
+62.106.95.74
+62.106.95.76
+62.106.95.81
+62.106.95.87
+62.106.95.99
+62.106.95.106
+62.106.95.129
+62.106.95.134
+62.106.95.141
+62.106.95.147
+62.106.95.149
+62.106.95.152
+62.106.95.153
+62.106.95.156
+62.106.95.165
+62.106.95.169
+62.106.95.182
+62.106.95.192
+62.106.95.193
+62.106.95.198
+62.106.95.199
+62.106.95.217
+62.106.95.239
+62.106.95.242
+62.106.95.247
+62.106.95.251
+62.106.95.252
+62.193.13.5
+62.193.13.9
+62.204.61.2
+62.204.61.5
+62.204.61.6
+62.204.61.7
+62.204.61.8
+62.204.61.9
+62.204.61.12
+62.204.61.13
+62.204.61.14
+62.204.61.15
+62.204.61.17
+62.204.61.18
+62.204.61.19
+62.204.61.22
+62.204.61.23
+62.204.61.25
+62.204.61.30
+62.204.61.33
+62.204.61.35
+62.204.61.36
+62.204.61.37
+62.204.61.44
+62.204.61.46
+62.204.61.47
+62.204.61.60
+62.204.61.63
+62.204.61.72
+62.204.61.93
+62.204.61.112
+62.204.61.114
+62.204.61.115
+62.204.61.116
+62.204.61.117
+62.204.61.118
+62.204.61.119
+62.204.61.122
+62.204.61.130
+62.204.61.141
+62.204.61.143
+62.204.61.145
+62.204.61.148
+62.204.61.155
+62.204.61.156
+62.204.61.160
+62.204.61.164
+62.204.61.177
+62.204.61.185
+62.204.61.202
+62.204.61.222
+62.204.61.224
+62.204.61.233
+62.204.61.254
+62.220.98.5
+62.220.100.168
+62.220.100.182
+62.220.100.187
+62.220.112.46
+62.220.112.71
+62.220.114.204
+62.220.114.253
+62.220.115.101
+62.220.126.218
+62.220.127.13
+62.220.127.165
+77.36.160.4
+77.36.160.7
+77.36.164.20
+77.36.164.21
+77.36.164.34
+77.36.164.36
+77.36.227.3
+77.74.202.74
+77.74.202.202
+77.81.40.244
+77.81.76.2
+77.81.76.4
+77.81.76.7
+77.81.76.8
+77.81.76.10
+77.81.76.12
+77.81.76.13
+77.81.76.14
+77.81.76.15
+77.81.76.17
+77.81.76.18
+77.81.76.19
+77.81.76.20
+77.81.76.21
+77.81.76.22
+77.81.76.23
+77.81.76.24
+77.81.76.25
+77.81.76.26
+77.81.76.27
+77.81.76.28
+77.81.76.30
+77.81.76.32
+77.81.76.33
+77.81.76.34
+77.81.76.35
+77.81.76.37
+77.81.76.39
+77.81.76.40
+77.81.76.41
+77.81.76.42
+77.81.76.43
+77.81.76.44
+77.81.76.45
+77.81.76.46
+77.81.76.47
+77.81.76.48
+77.81.76.51
+77.81.76.52
+77.81.76.55
+77.81.76.59
+77.81.76.62
+77.81.76.64
+77.81.76.66
+77.81.76.68
+77.81.76.72
+77.81.76.77
+77.81.76.82
+77.81.76.83
+77.81.76.84
+77.81.76.85
+77.81.76.87
+77.81.76.99
+77.81.76.100
+77.81.76.101
+77.81.76.102
+77.81.76.103
+77.81.76.104
+77.81.76.105
+77.81.76.118
+77.81.76.120
+77.81.147.31
+77.81.149.211
+77.81.157.153
+77.81.157.202
+77.81.158.4
+77.81.159.61
+77.104.65.73
+77.104.66.41
+77.104.66.165
+77.104.67.55
+77.104.67.56
+77.104.69.40
+77.104.73.147
+77.104.73.229
+77.104.74.71
+77.104.76.45
+77.104.79.30
+77.104.80.3
+77.104.81.127
+77.104.81.242
+77.104.82.2
+77.104.83.201
+77.104.83.206
+77.104.85.163
+77.104.88.139
+77.104.90.18
+77.104.98.115
+77.104.98.205
+77.104.98.231
+77.104.103.147
+77.104.104.104
+77.104.106.55
+77.104.116.15
+77.104.117.2
+77.104.119.6
+77.237.64.209
+77.237.66.66
+77.237.66.67
+77.237.66.71
+77.237.66.76
+77.237.66.77
+77.237.66.78
+77.237.66.80
+77.237.66.81
+77.237.66.84
+77.237.66.89
+77.237.66.98
+77.237.66.126
+77.237.66.195
+77.237.66.238
+77.237.67.10
+77.237.67.11
+77.237.67.12
+77.237.67.14
+77.237.67.15
+77.237.67.16
+77.237.67.17
+77.237.67.18
+77.237.67.20
+77.237.67.21
+77.237.67.22
+77.237.67.23
+77.237.67.24
+77.237.67.25
+77.237.70.140
+77.237.70.170
+77.237.71.19
+77.237.71.20
+77.237.79.5
+77.237.79.6
+77.237.81.6
+77.237.82.123
+77.237.85.210
+77.237.87.187
+77.237.87.188
+77.237.87.189
+77.237.91.141
+77.238.104.132
+77.238.106.15
+77.238.108.91
+77.238.108.100
+77.238.108.124
+77.238.108.125
+77.238.109.67
+77.238.109.76
+77.238.109.77
+77.238.110.42
+77.238.110.45
+77.238.110.80
+77.238.110.83
+77.238.110.84
+77.238.110.85
+77.238.110.86
+77.238.110.106
+77.238.110.140
+77.238.110.157
+77.238.110.158
+77.238.110.162
+77.238.110.181
+77.238.110.187
+77.238.110.191
+77.238.110.226
+77.238.110.250
+77.238.110.251
+77.238.110.252
+77.238.111.234
+77.238.111.236
+77.238.111.237
+77.238.111.238
+77.238.113.8
+77.238.117.53
+77.238.117.158
+77.238.120.17
+77.238.120.21
+77.238.120.52
+77.238.120.98
+77.238.120.99
+77.238.120.100
+77.238.120.101
+77.238.120.102
+77.238.120.121
+77.238.121.54
+77.238.121.55
+77.238.121.107
+77.238.121.155
+77.238.121.242
+77.238.121.243
+77.238.121.245
+77.238.121.247
+77.238.121.249
+77.238.122.130
+77.238.122.132
+77.238.122.133
+77.238.122.134
+77.238.122.135
+77.238.122.136
+77.238.122.139
+77.238.122.140
+77.238.122.141
+77.238.122.142
+77.238.122.143
+77.238.122.145
+77.238.122.147
+77.238.122.148
+77.238.122.149
+77.238.122.152
+77.238.122.153
+77.238.122.156
+77.238.122.157
+77.238.122.158
+77.238.122.159
+77.238.122.160
+77.238.122.161
+77.238.122.162
+77.238.122.164
+77.238.122.165
+77.238.122.166
+77.238.122.167
+77.238.122.169
+77.238.122.172
+77.238.122.174
+77.238.122.175
+77.238.122.178
+77.238.122.179
+77.238.122.180
+77.238.122.181
+77.238.122.182
+77.238.122.185
+77.238.122.187
+77.238.122.189
+77.238.122.196
+77.238.122.206
+77.238.123.84
+77.238.123.179
+77.238.123.237
+78.31.232.3
+78.31.235.119
+78.38.0.131
+78.38.0.132
+78.38.17.28
+78.38.25.2
+78.38.25.3
+78.38.34.125
+78.38.35.11
+78.38.41.96
+78.38.45.2
+78.38.45.3
+78.38.49.84
+78.38.50.218
+78.38.64.156
+78.38.69.2
+78.38.76.251
+78.38.77.2
+78.38.77.3
+78.38.80.251
+78.38.84.11
+78.38.90.70
+78.38.100.34
+78.38.101.37
+78.38.108.48
+78.38.109.130
+78.38.113.2
+78.38.114.69
+78.38.114.85
+78.38.114.99
+78.38.114.102
+78.38.120.95
+78.38.120.131
+78.38.121.66
+78.38.123.247
+78.38.131.114
+78.38.138.158
+78.38.138.159
+78.38.152.74
+78.38.153.74
+78.38.153.86
+78.38.153.132
+78.38.156.68
+78.38.156.72
+78.38.157.241
+78.38.158.1
+78.38.166.162
+78.38.174.30
+78.38.175.2
+78.38.175.3
+78.38.176.10
+78.38.201.120
+78.38.208.156
+78.38.221.187
+78.38.227.2
+78.38.227.3
+78.38.237.49
+78.38.239.67
+78.38.239.134
+78.38.239.202
+78.38.248.66
+78.38.248.94
+78.38.248.107
+78.39.9.27
+78.39.9.224
+78.39.9.251
+78.39.10.44
+78.39.11.42
+78.39.35.65
+78.39.35.66
+78.39.39.139
+78.39.40.11
+78.39.43.137
+78.39.51.25
+78.39.51.26
+78.39.53.204
+78.39.56.43
+78.39.56.114
+78.39.57.172
+78.39.57.254
+78.39.59.246
+78.39.62.35
+78.39.80.9
+78.39.80.190
+78.39.80.199
+78.39.81.33
+78.39.81.220
+78.39.85.8
+78.39.85.9
+78.39.98.10
+78.39.98.27
+78.39.98.28
+78.39.101.2
+78.39.103.28
+78.39.103.54
+78.39.103.252
+78.39.107.114
+78.39.107.115
+78.39.108.132
+78.39.112.126
+78.39.114.34
+78.39.121.110
+78.39.121.117
+78.39.122.251
+78.39.129.20
+78.39.129.148
+78.39.129.149
+78.39.136.13
+78.39.136.49
+78.39.136.67
+78.39.136.97
+78.39.136.98
+78.39.136.101
+78.39.136.106
+78.39.136.114
+78.39.136.247
+78.39.136.251
+78.39.136.254
+78.39.140.113
+78.39.141.71
+78.39.152.60
+78.39.152.135
+78.39.152.249
+78.39.159.3
+78.39.159.12
+78.39.159.48
+78.39.159.49
+78.39.159.61
+78.39.159.111
+78.39.164.212
+78.39.180.34
+78.39.188.253
+78.39.188.254
+78.39.205.34
+78.39.205.35
+78.39.208.212
+78.39.212.8
+78.39.212.9
+78.39.217.156
+78.39.217.170
+78.39.226.36
+78.39.226.209
+78.39.227.3
+78.39.234.140
+78.39.234.230
+78.39.234.237
+78.39.250.101
+78.39.250.128
+78.39.251.25
+78.39.252.167
+78.41.62.20
+78.41.62.196
+78.109.193.2
+78.109.194.2
+78.109.195.42
+78.109.195.50
+78.109.195.148
+78.109.195.149
+78.109.196.135
+78.109.196.153
+78.109.196.159
+78.109.196.173
+78.109.196.177
+78.109.198.60
+78.109.198.61
+78.109.199.2
+78.109.199.5
+78.109.199.13
+78.109.199.36
+78.109.199.65
+78.109.199.203
+78.109.199.218
+78.109.200.2
+78.109.200.29
+78.109.200.64
+78.109.200.199
+78.109.200.207
+78.109.201.2
+78.109.201.71
+78.109.201.78
+78.109.201.119
+78.109.201.201
+78.109.202.100
+78.109.206.2
+78.109.206.91
+78.109.206.102
+78.109.206.124
+78.109.206.186
+78.109.206.206
+78.110.120.64
+78.110.120.67
+78.110.120.87
+78.110.120.96
+78.110.120.97
+78.110.120.98
+78.110.120.99
+78.110.120.120
+78.110.120.124
+78.110.120.145
+78.110.120.150
+78.110.120.220
+78.110.120.231
+78.110.120.234
+78.110.120.243
+78.110.121.92
+78.110.121.93
+78.110.121.94
+78.110.121.95
+78.110.121.96
+78.110.121.127
+78.110.121.130
+78.110.121.155
+78.110.121.156
+78.110.121.157
+78.110.121.158
+78.110.121.166
+78.110.121.169
+78.110.121.170
+78.110.121.184
+78.110.121.185
+78.110.122.56
+78.110.122.57
+78.110.122.61
+78.110.122.62
+78.110.122.112
+78.110.122.148
+78.110.122.150
+78.110.122.181
+78.110.122.182
+78.110.122.191
+78.110.122.236
+78.110.123.71
+78.110.125.131
+78.111.0.67
+78.111.2.84
+78.111.5.186
+78.111.5.190
+78.111.5.194
+78.111.5.198
+78.111.13.100
+78.157.33.200
+78.157.34.68
+78.157.34.69
+78.157.34.85
+78.157.34.125
+78.157.34.210
+78.157.35.8
+78.157.35.15
+78.157.35.32
+78.157.35.59
+78.157.35.70
+78.157.35.75
+78.157.35.76
+78.157.35.77
+78.157.35.78
+78.157.35.127
+78.157.36.186
+78.157.37.90
+78.157.37.141
+78.157.37.142
+78.157.37.152
+78.157.37.157
+78.157.37.158
+78.157.37.255
+78.157.38.66
+78.157.38.67
+78.157.38.68
+78.157.38.69
+78.157.38.70
+78.157.38.72
+78.157.38.73
+78.157.38.74
+78.157.38.75
+78.157.38.76
+78.157.38.78
+78.157.38.79
+78.157.38.80
+78.157.38.81
+78.157.38.82
+78.157.38.83
+78.157.38.84
+78.157.38.86
+78.157.38.87
+78.157.38.88
+78.157.38.90
+78.157.38.91
+78.157.38.92
+78.157.38.93
+78.157.38.97
+78.157.38.98
+78.157.38.99
+78.157.38.101
+78.157.38.104
+78.157.38.106
+78.157.38.107
+78.157.38.108
+78.157.38.111
+78.157.38.112
+78.157.38.113
+78.157.38.116
+78.157.38.117
+78.157.38.120
+78.157.38.121
+78.157.38.122
+78.157.38.123
+78.157.38.168
+78.157.38.192
+78.157.38.199
+78.157.38.203
+78.157.38.208
+78.157.38.215
+78.157.39.21
+78.157.39.22
+78.157.39.60
+78.157.39.106
+78.157.40.34
+78.157.40.35
+78.157.40.38
+78.157.40.39
+78.157.40.40
+78.157.40.41
+78.157.40.42
+78.157.40.43
+78.157.40.44
+78.157.40.46
+78.157.40.70
+78.157.40.158
+78.157.40.168
+78.157.40.175
+78.157.40.191
+78.157.40.192
+78.157.40.200
+78.157.40.201
+78.157.40.207
+78.157.41.60
+78.157.41.63
+78.157.41.119
+78.157.41.127
+78.157.41.149
+78.157.41.175
+78.157.41.224
+78.157.41.231
+78.157.42.23
+78.157.42.62
+78.157.42.201
+78.157.42.202
+78.157.42.203
+78.157.42.204
+78.157.42.205
+78.157.42.209
+78.157.42.210
+78.157.42.214
+78.157.42.215
+78.157.42.216
+78.157.42.217
+78.157.42.218
+78.157.42.219
+78.157.42.235
+78.157.43.229
+78.157.43.230
+78.157.43.241
+78.157.44.74
+78.157.44.212
+78.157.44.215
+78.157.45.47
+78.157.45.210
+78.157.45.212
+78.157.45.214
+78.157.45.215
+78.157.46.95
+78.157.46.104
+78.157.46.120
+78.157.46.128
+78.157.46.143
+78.157.46.213
+78.157.47.201
+78.157.47.202
+78.157.47.203
+78.157.47.204
+78.157.47.205
+78.157.47.206
+78.157.47.207
+78.157.47.209
+78.157.47.210
+78.157.48.16
+78.157.48.44
+78.157.48.51
+78.157.48.52
+78.157.48.112
+78.157.48.135
+78.157.48.150
+78.157.48.162
+78.157.48.175
+78.157.48.176
+78.157.49.22
+78.157.49.100
+78.157.49.105
+78.157.49.110
+78.157.49.111
+78.157.49.120
+78.157.50.22
+78.157.50.24
+78.157.50.31
+78.157.50.255
+78.157.51.3
+78.157.51.5
+78.157.51.28
+78.157.51.49
+78.157.51.64
+78.157.51.93
+78.157.51.136
+78.157.51.159
+78.157.51.163
+78.157.51.185
+78.157.51.192
+78.157.51.203
+78.157.51.232
+78.157.51.240
+78.157.51.248
+78.157.53.67
+78.157.53.187
+78.157.56.19
+78.157.56.24
+78.157.56.25
+78.157.56.53
+78.157.56.133
+78.157.56.181
+78.157.56.215
+78.157.57.39
+78.157.57.120
+78.157.57.152
+78.157.57.154
+78.157.57.162
+78.157.57.199
+78.157.57.224
+78.157.57.230
+78.157.57.231
+78.157.57.234
+78.157.57.241
+78.157.57.245
+78.157.57.247
+78.157.57.252
+78.157.57.255
+78.157.58.38
+78.157.58.39
+78.157.58.42
+78.157.58.170
+78.157.59.20
+78.157.59.22
+78.157.59.23
+78.157.59.24
+78.157.59.25
+78.157.59.28
+78.157.59.29
+78.157.59.34
+78.157.59.195
+78.157.59.196
+78.157.59.197
+78.157.59.198
+78.157.59.201
+78.157.60.77
+78.157.61.79
+78.157.62.99
+78.157.63.105
+78.157.63.121
+78.158.161.146
+78.158.166.38
+78.158.166.66
+78.158.166.71
+79.127.2.30
+79.127.2.168
+79.127.4.203
+79.127.4.207
+79.127.5.97
+79.127.5.98
+79.127.6.1
+79.127.7.239
+79.127.12.89
+79.127.12.156
+79.127.41.218
+79.127.45.26
+79.127.47.173
+79.127.48.173
+79.127.52.5
+79.127.52.76
+79.127.61.70
+79.127.67.36
+79.127.69.230
+79.127.69.233
+79.127.73.202
+79.127.87.170
+79.127.87.174
+79.127.92.60
+79.127.94.222
+79.127.96.153
+79.127.106.228
+79.127.114.46
+79.127.125.7
+79.127.125.13
+79.127.125.36
+79.127.125.37
+79.127.125.38
+79.127.125.80
+79.127.125.156
+79.127.125.178
+79.127.125.179
+79.127.125.180
+79.127.125.181
+79.127.125.182
+79.127.125.250
+79.127.125.252
+79.127.126.26
+79.127.126.27
+79.127.126.28
+79.127.126.29
+79.127.126.30
+79.127.126.66
+79.127.126.69
+79.127.126.70
+79.127.126.71
+79.127.126.72
+79.127.126.73
+79.127.126.74
+79.127.126.76
+79.127.126.77
+79.127.126.78
+79.127.126.85
+79.127.126.92
+79.127.126.104
+79.127.126.111
+79.127.126.112
+79.127.126.113
+79.127.126.116
+79.127.126.123
+79.127.126.124
+79.127.126.126
+79.127.126.133
+79.127.126.226
+79.127.126.228
+79.127.126.242
+79.127.126.245
+79.127.126.246
+79.127.126.247
+79.127.126.249
+79.127.126.251
+79.127.127.6
+79.127.127.11
+79.127.127.17
+79.127.127.18
+79.127.127.20
+79.127.127.23
+79.127.127.24
+79.127.127.25
+79.127.127.27
+79.127.127.28
+79.127.127.29
+79.127.127.31
+79.127.127.32
+79.127.127.33
+79.127.127.34
+79.127.127.35
+79.127.127.36
+79.127.127.37
+79.127.127.38
+79.127.127.39
+79.127.127.43
+79.127.127.44
+79.127.127.45
+79.127.127.46
+79.127.127.47
+79.127.127.49
+79.127.127.51
+79.127.127.62
+79.127.127.64
+79.127.127.65
+79.127.127.66
+79.127.127.67
+79.127.127.68
+79.127.127.69
+79.127.127.70
+79.127.127.72
+79.127.127.74
+79.127.127.75
+79.127.127.76
+79.127.127.77
+79.127.127.78
+79.127.127.79
+79.127.127.80
+79.127.127.82
+79.127.127.84
+79.127.127.85
+79.127.127.86
+79.127.127.87
+79.127.127.88
+79.127.127.90
+79.127.127.91
+79.127.127.93
+79.127.127.94
+79.127.127.95
+79.127.127.96
+79.127.127.97
+79.127.127.98
+79.127.127.99
+79.127.127.100
+79.127.127.101
+79.127.127.103
+79.127.127.105
+79.127.127.106
+79.127.127.111
+79.127.127.113
+79.127.127.114
+79.127.127.115
+79.127.127.116
+79.127.127.118
+79.127.127.119
+79.127.127.120
+79.127.127.123
+79.127.127.125
+79.127.127.134
+79.127.127.138
+79.127.127.151
+79.127.127.154
+79.127.127.190
+79.127.127.210
+79.127.127.213
+79.127.127.215
+79.132.192.15
+79.132.192.82
+79.132.192.196
+79.132.192.233
+79.132.192.238
+79.132.193.26
+79.132.193.36
+79.132.193.38
+79.132.193.39
+79.132.193.43
+79.132.193.44
+79.132.193.46
+79.132.193.70
+79.132.193.72
+79.132.193.74
+79.132.193.78
+79.132.193.83
+79.132.193.94
+79.132.193.96
+79.132.193.101
+79.132.193.105
+79.132.193.107
+79.132.193.116
+79.132.193.125
+79.132.193.133
+79.132.193.134
+79.132.193.135
+79.132.193.143
+79.132.193.144
+79.132.193.147
+79.132.193.148
+79.132.193.150
+79.132.193.153
+79.132.193.155
+79.132.193.162
+79.132.193.168
+79.132.193.180
+79.132.193.186
+79.132.193.194
+79.132.193.200
+79.132.193.201
+79.132.193.206
+79.132.193.210
+79.132.193.216
+79.132.193.225
+79.132.193.226
+79.132.193.228
+79.132.193.229
+79.132.193.236
+79.132.193.238
+79.132.193.239
+79.132.193.240
+79.132.193.243
+79.132.193.245
+79.132.193.248
+79.132.193.249
+79.132.193.251
+79.132.193.253
+79.132.206.249
+79.132.206.250
+79.132.210.66
+79.143.84.18
+79.143.84.77
+79.143.84.114
+79.143.84.118
+79.143.84.126
+79.143.84.162
+79.143.84.166
+79.143.86.4
+79.143.86.6
+79.143.86.7
+79.143.86.154
+79.143.86.156
+79.143.86.165
+79.143.86.166
+79.143.86.172
+79.174.161.219
+79.174.161.222
+79.174.165.135
+79.174.165.136
+79.175.129.2
+79.175.130.58
+79.175.130.59
+79.175.130.60
+79.175.130.61
+79.175.130.62
+79.175.131.17
+79.175.131.19
+79.175.131.38
+79.175.131.85
+79.175.131.145
+79.175.133.5
+79.175.133.6
+79.175.133.14
+79.175.133.31
+79.175.133.93
+79.175.133.102
+79.175.133.108
+79.175.133.127
+79.175.133.138
+79.175.133.149
+79.175.133.154
+79.175.133.196
+79.175.133.220
+79.175.133.233
+79.175.133.239
+79.175.133.241
+79.175.134.2
+79.175.134.20
+79.175.134.68
+79.175.134.85
+79.175.134.141
+79.175.134.172
+79.175.134.176
+79.175.134.220
+79.175.136.2
+79.175.136.3
+79.175.136.4
+79.175.136.13
+79.175.136.72
+79.175.136.86
+79.175.136.194
+79.175.137.2
+79.175.137.3
+79.175.137.4
+79.175.138.2
+79.175.138.4
+79.175.138.5
+79.175.139.179
+79.175.139.180
+79.175.139.181
+79.175.139.182
+79.175.139.183
+79.175.139.184
+79.175.139.187
+79.175.139.188
+79.175.139.189
+79.175.139.190
+79.175.142.147
+79.175.142.150
+79.175.145.90
+79.175.145.147
+79.175.145.149
+79.175.146.74
+79.175.148.66
+79.175.148.67
+79.175.148.200
+79.175.148.242
+79.175.149.194
+79.175.151.2
+79.175.151.27
+79.175.151.31
+79.175.151.40
+79.175.151.57
+79.175.151.63
+79.175.151.74
+79.175.151.80
+79.175.151.84
+79.175.151.90
+79.175.151.102
+79.175.151.122
+79.175.151.130
+79.175.151.173
+79.175.151.174
+79.175.151.213
+79.175.151.226
+79.175.151.233
+79.175.151.250
+79.175.154.20
+79.175.155.2
+79.175.155.3
+79.175.155.66
+79.175.155.68
+79.175.155.69
+79.175.155.82
+79.175.155.83
+79.175.155.84
+79.175.155.88
+79.175.155.91
+79.175.157.2
+79.175.157.3
+79.175.157.4
+79.175.157.5
+79.175.157.6
+79.175.157.66
+79.175.157.67
+79.175.157.68
+79.175.157.69
+79.175.157.70
+79.175.157.102
+79.175.157.103
+79.175.157.163
+79.175.160.90
+79.175.162.2
+79.175.164.171
+79.175.164.172
+79.175.165.3
+79.175.165.170
+79.175.166.90
+79.175.166.98
+79.175.166.100
+79.175.166.102
+79.175.166.146
+79.175.166.147
+79.175.167.2
+79.175.167.238
+79.175.168.67
+79.175.168.94
+79.175.168.142
+79.175.168.219
+79.175.169.51
+79.175.169.53
+79.175.169.54
+79.175.169.55
+79.175.169.56
+79.175.169.57
+79.175.169.58
+79.175.169.59
+79.175.169.62
+79.175.169.120
+79.175.169.125
+79.175.169.138
+79.175.169.139
+79.175.169.141
+79.175.169.217
+79.175.169.218
+79.175.169.219
+79.175.169.222
+79.175.169.226
+79.175.169.229
+79.175.171.179
+79.175.172.98
+79.175.172.101
+79.175.172.147
+79.175.172.150
+79.175.172.155
+79.175.172.156
+79.175.173.179
+79.175.173.198
+79.175.173.217
+79.175.173.234
+79.175.174.124
+79.175.174.125
+79.175.176.3
+79.175.176.22
+79.175.176.36
+79.175.176.37
+79.175.176.46
+79.175.176.49
+79.175.176.60
+79.175.176.69
+79.175.176.70
+79.175.176.74
+79.175.176.76
+79.175.176.99
+79.175.176.118
+79.175.176.123
+79.175.176.136
+79.175.176.177
+79.175.176.184
+79.175.176.188
+79.175.176.191
+79.175.176.209
+79.175.177.2
+79.175.177.17
+79.175.177.30
+79.175.177.67
+79.175.177.103
+79.175.177.112
+79.175.177.113
+79.175.177.136
+79.175.177.138
+79.175.181.148
+79.175.181.150
+79.175.181.153
+79.175.181.156
+79.175.181.158
+79.175.181.171
+79.175.181.203
+79.175.181.206
+79.175.181.213
+79.175.186.162
+79.175.188.2
+79.175.188.41
+79.175.188.135
+79.175.188.186
+79.175.189.104
+79.175.190.162
+79.175.190.166
+79.175.190.180
+79.175.190.181
+79.175.190.182
+79.175.190.237
+80.66.177.4
+80.66.177.5
+80.66.177.22
+80.66.177.49
+80.71.119.2
+80.71.149.3
+80.71.149.4
+80.71.149.40
+80.71.149.42
+80.71.149.127
+80.71.149.152
+80.71.149.158
+80.71.149.175
+80.71.149.241
+80.71.149.249
+80.75.0.2
+80.75.1.42
+80.75.2.15
+80.75.2.135
+80.75.3.7
+80.75.3.17
+80.75.3.86
+80.75.3.93
+80.75.3.227
+80.75.4.101
+80.75.4.167
+80.75.4.168
+80.75.7.10
+80.75.7.26
+80.75.7.188
+80.75.9.7
+80.75.10.134
+80.75.13.179
+80.75.14.70
+80.75.14.71
+80.75.14.96
+80.75.14.99
+80.75.14.102
+80.75.14.103
+80.75.14.108
+80.75.14.115
+80.75.14.116
+80.75.14.118
+80.75.14.124
+80.75.213.70
+80.75.213.90
+80.75.213.131
+80.75.213.146
+80.75.213.147
+80.75.213.148
+80.75.213.149
+80.75.213.155
+80.75.213.253
+80.91.208.18
+80.91.208.206
+80.191.0.17
+80.191.0.18
+80.191.2.218
+80.191.8.40
+80.191.11.134
+80.191.24.2
+80.191.24.9
+80.191.27.199
+80.191.27.203
+80.191.27.204
+80.191.27.205
+80.191.27.206
+80.191.32.3
+80.191.32.56
+80.191.36.20
+80.191.41.83
+80.191.41.84
+80.191.47.2
+80.191.49.130
+80.191.49.131
+80.191.49.133
+80.191.56.7
+80.191.56.100
+80.191.56.110
+80.191.62.5
+80.191.65.241
+80.191.68.247
+80.191.70.34
+80.191.75.110
+80.191.80.9
+80.191.89.50
+80.191.89.98
+80.191.90.54
+80.191.90.62
+80.191.92.15
+80.191.92.179
+80.191.92.188
+80.191.92.199
+80.191.92.233
+80.191.100.246
+80.191.103.92
+80.191.105.200
+80.191.105.245
+80.191.105.249
+80.191.105.252
+80.191.110.138
+80.191.111.4
+80.191.111.5
+80.191.111.170
+80.191.131.131
+80.191.153.109
+80.191.156.134
+80.191.156.234
+80.191.163.249
+80.191.163.251
+80.191.170.194
+80.191.172.4
+80.191.172.69
+80.191.174.111
+80.191.174.112
+80.191.192.6
+80.191.192.115
+80.191.193.40
+80.191.202.15
+80.191.203.10
+80.191.214.20
+80.191.216.2
+80.191.221.12
+80.191.221.14
+80.191.221.19
+80.191.221.20
+80.191.221.21
+80.191.221.22
+80.191.221.25
+80.191.221.28
+80.191.221.29
+80.191.221.30
+80.191.221.32
+80.191.221.40
+80.191.221.41
+80.191.221.61
+80.191.221.72
+80.191.228.3
+80.191.236.54
+80.191.242.1
+80.191.242.90
+80.191.242.228
+80.191.248.61
+80.191.248.62
+80.210.17.2
+80.210.20.226
+80.210.22.97
+80.210.24.8
+80.210.26.114
+80.210.26.166
+80.210.30.38
+80.210.30.78
+80.210.30.156
+80.210.32.30
+80.210.32.38
+80.210.32.132
+80.210.32.162
+80.210.38.9
+80.210.38.11
+80.210.40.54
+80.210.40.208
+80.210.41.96
+80.210.48.145
+80.210.51.88
+80.210.53.80
+80.210.57.212
+80.210.59.19
+80.210.59.98
+80.210.61.28
+80.210.62.28
+80.210.62.245
+80.210.63.54
+80.210.141.120
+80.210.166.118
+80.210.167.23
+80.210.168.153
+80.210.173.249
+80.253.136.12
+80.253.145.150
+80.253.147.222
+81.12.0.3
+81.12.4.10
+81.12.5.164
+81.12.5.221
+81.12.7.54
+81.12.12.201
+81.12.12.202
+81.12.13.11
+81.12.13.74
+81.12.25.53
+81.12.27.38
+81.12.27.122
+81.12.27.171
+81.12.27.210
+81.12.27.218
+81.12.27.222
+81.12.28.206
+81.12.30.13
+81.12.30.82
+81.12.30.139
+81.12.30.140
+81.12.30.141
+81.12.30.195
+81.12.31.48
+81.12.34.177
+81.12.35.100
+81.12.39.2
+81.12.39.3
+81.12.39.4
+81.12.39.8
+81.12.39.9
+81.12.39.10
+81.12.39.11
+81.12.39.12
+81.12.39.13
+81.12.39.14
+81.12.39.15
+81.12.39.16
+81.12.39.17
+81.12.39.18
+81.12.39.19
+81.12.39.20
+81.12.39.21
+81.12.39.22
+81.12.39.23
+81.12.39.24
+81.12.39.25
+81.12.39.26
+81.12.39.27
+81.12.39.28
+81.12.39.29
+81.12.39.31
+81.12.39.54
+81.12.39.81
+81.12.39.116
+81.12.39.134
+81.12.39.135
+81.12.39.137
+81.12.39.138
+81.12.39.159
+81.12.39.193
+81.12.39.194
+81.12.39.195
+81.12.39.197
+81.12.39.198
+81.12.39.199
+81.12.39.202
+81.12.39.210
+81.12.39.233
+81.12.52.4
+81.12.52.58
+81.12.52.90
+81.12.52.122
+81.12.52.126
+81.12.52.146
+81.12.52.155
+81.12.52.158
+81.12.52.162
+81.12.52.172
+81.12.52.178
+81.12.52.190
+81.12.52.235
+81.12.53.76
+81.12.53.90
+81.12.53.115
+81.12.53.116
+81.12.53.124
+81.12.53.126
+81.12.53.131
+81.12.53.150
+81.12.53.162
+81.12.53.182
+81.12.53.206
+81.12.53.217
+81.12.54.123
+81.12.55.235
+81.12.59.137
+81.12.59.138
+81.12.62.101
+81.12.63.109
+81.12.65.141
+81.12.65.144
+81.12.70.4
+81.12.72.123
+81.12.72.218
+81.12.75.140
+81.12.87.104
+81.12.88.52
+81.12.91.51
+81.12.91.52
+81.12.91.53
+81.12.93.250
+81.12.93.251
+81.12.93.252
+81.12.93.253
+81.12.97.60
+81.12.97.124
+81.12.98.18
+81.12.98.19
+81.12.98.21
+81.12.98.22
+81.12.101.62
+81.12.105.194
+81.12.108.99
+81.12.108.100
+81.12.108.101
+81.12.108.102
+81.12.112.180
+81.12.113.26
+81.12.116.130
+81.12.116.131
+81.12.116.133
+81.12.116.134
+81.12.116.135
+81.12.116.136
+81.12.116.137
+81.12.116.138
+81.12.116.139
+81.12.116.140
+81.12.120.27
+81.12.120.131
+81.12.122.130
+81.12.123.151
+81.16.114.126
+81.16.115.130
+81.16.116.178
+81.16.121.124
+81.16.121.161
+81.16.123.125
+81.16.124.169
+81.16.126.103
+81.16.126.237
+81.16.127.253
+81.28.52.30
+81.28.61.72
+81.29.245.169
+81.29.255.35
+81.31.160.34
+81.31.160.35
+81.31.169.19
+81.31.250.184
+81.31.250.186
+81.31.250.188
+81.31.250.189
+81.90.144.210
+81.90.147.2
+81.90.147.189
+81.90.152.150
+81.90.158.26
+81.90.159.170
+81.91.129.226
+81.91.129.227
+81.91.129.229
+81.91.129.230
+81.91.139.109
+81.91.139.118
+81.91.140.90
+81.91.145.181
+81.91.146.254
+81.91.147.3
+81.91.147.250
+81.91.151.172
+81.91.155.46
+81.91.155.94
+81.91.157.181
+82.99.202.102
+82.99.202.212
+82.99.204.74
+82.99.204.93
+82.99.227.214
+82.99.240.57
+82.99.250.149
+82.99.252.117
+82.99.253.93
+82.102.14.4
+82.102.14.35
+82.102.14.50
+82.102.15.90
+82.102.15.91
+82.102.15.92
+82.102.15.93
+82.102.15.94
+82.102.15.210
+83.147.193.2
+83.147.193.3
+83.147.193.4
+83.147.193.240
+83.150.192.12
+83.150.193.12
+84.47.239.2
+84.47.239.3
+84.47.239.4
+84.47.239.6
+84.47.239.7
+84.47.239.8
+84.47.239.9
+84.47.239.10
+84.47.239.11
+84.47.239.12
+84.47.239.14
+84.47.239.15
+84.47.239.16
+84.47.239.17
+84.47.239.18
+84.47.239.19
+84.47.239.20
+84.47.239.22
+84.47.239.23
+84.47.239.25
+84.241.0.237
+84.241.1.202
+84.241.2.22
+84.241.2.42
+84.241.2.100
+84.241.2.253
+84.241.4.59
+84.241.7.39
+84.241.7.200
+84.241.10.229
+84.241.11.102
+84.241.11.222
+84.241.13.118
+84.241.14.122
+84.241.16.25
+84.241.16.49
+84.241.19.230
+84.241.22.21
+84.241.22.121
+84.241.22.236
+84.241.26.155
+84.241.27.20
+84.241.27.165
+84.241.28.236
+84.241.30.11
+84.241.30.192
+84.241.32.141
+84.241.35.82
+84.241.38.8
+84.241.39.230
+84.241.39.250
+84.241.41.23
+84.241.41.93
+84.241.41.195
+84.241.43.83
+84.241.45.39
+84.241.47.146
+84.241.56.89
+84.241.63.178
+85.9.66.19
+85.9.71.176
+85.9.91.133
+85.9.104.2
+85.9.105.37
+85.9.105.46
+85.9.107.3
+85.9.107.123
+85.9.107.154
+85.9.107.163
+85.9.107.165
+85.9.107.169
+85.9.107.217
+85.9.107.228
+85.9.107.229
+85.9.108.3
+85.9.108.4
+85.9.108.98
+85.9.108.100
+85.9.108.101
+85.9.108.102
+85.9.108.103
+85.9.108.104
+85.9.108.108
+85.9.109.5
+85.9.111.122
+85.9.111.123
+85.9.111.125
+85.9.111.126
+85.9.111.154
+85.9.111.172
+85.9.111.186
+85.9.112.212
+85.9.112.227
+85.9.112.228
+85.9.112.230
+85.9.112.232
+85.9.120.53
+85.9.123.33
+85.9.125.22
+85.15.6.12
+85.15.6.13
+85.15.24.14
+85.133.128.248
+85.133.128.249
+85.133.148.126
+85.133.149.54
+85.133.153.149
+85.133.153.170
+85.133.153.172
+85.133.153.173
+85.133.153.174
+85.133.155.216
+85.133.155.217
+85.133.155.218
+85.133.155.219
+85.133.155.220
+85.133.155.221
+85.133.155.222
+85.133.155.223
+85.133.159.76
+85.133.159.94
+85.133.167.166
+85.133.167.187
+85.133.168.52
+85.133.168.115
+85.133.169.53
+85.133.169.61
+85.133.171.186
+85.133.171.187
+85.133.173.53
+85.133.176.113
+85.133.179.34
+85.133.180.90
+85.133.187.102
+85.133.188.38
+85.133.193.31
+85.133.193.38
+85.133.193.43
+85.133.193.53
+85.133.193.55
+85.133.193.58
+85.133.193.59
+85.133.193.71
+85.133.193.79
+85.133.193.80
+85.133.193.82
+85.133.193.83
+85.133.193.128
+85.133.193.139
+85.133.193.143
+85.133.193.148
+85.133.193.152
+85.133.193.153
+85.133.193.199
+85.133.195.212
+85.133.195.216
+85.133.197.63
+85.133.197.198
+85.133.198.72
+85.133.198.73
+85.133.200.9
+85.133.200.250
+85.133.200.254
+85.133.205.40
+85.133.205.76
+85.133.205.113
+85.133.205.133
+85.133.206.130
+85.133.206.137
+85.133.206.138
+85.133.206.139
+85.133.206.142
+85.133.207.169
+85.133.212.54
+85.133.212.218
+85.133.212.243
+85.133.212.244
+85.133.212.246
+85.133.212.247
+85.133.212.249
+85.133.217.9
+85.133.217.13
+85.133.217.14
+85.133.217.26
+85.133.217.66
+85.133.217.67
+85.133.217.69
+85.133.217.70
+85.133.217.110
+85.133.217.242
+85.133.217.253
+85.133.217.254
+85.133.220.130
+85.133.227.61
+85.133.235.180
+85.133.237.237
+85.133.240.32
+85.133.243.5
+85.133.243.6
+85.133.243.8
+85.133.243.9
+85.133.243.10
+85.133.243.12
+85.133.243.13
+85.133.243.14
+85.133.243.15
+85.133.243.16
+85.133.243.18
+85.133.243.19
+85.133.243.20
+85.133.243.21
+85.133.243.22
+85.133.243.23
+85.133.243.24
+85.133.243.25
+85.133.243.26
+85.133.243.27
+85.133.243.28
+85.133.243.29
+85.133.243.30
+85.133.243.31
+85.133.243.32
+85.133.243.33
+85.133.243.35
+85.133.243.36
+85.133.243.37
+85.133.243.38
+85.133.243.39
+85.133.243.40
+85.133.243.41
+85.133.243.42
+85.133.243.43
+85.133.243.44
+85.133.243.45
+85.133.243.46
+85.133.243.47
+85.133.243.48
+85.133.243.49
+85.133.243.50
+85.133.243.51
+85.133.243.52
+85.133.243.53
+85.133.243.54
+85.133.243.55
+85.133.243.56
+85.133.243.57
+85.133.243.58
+85.133.243.60
+85.133.243.61
+85.133.243.62
+85.133.243.63
+85.133.243.64
+85.133.243.65
+85.133.243.66
+85.133.243.67
+85.133.243.68
+85.133.243.69
+85.133.243.70
+85.133.243.71
+85.133.243.72
+85.133.243.73
+85.133.243.74
+85.133.243.75
+85.133.243.76
+85.133.243.77
+85.133.243.78
+85.133.243.79
+85.133.243.80
+85.133.243.81
+85.133.243.82
+85.133.243.83
+85.133.243.84
+85.133.243.85
+85.133.243.86
+85.133.243.87
+85.133.243.88
+85.133.243.89
+85.133.243.90
+85.133.243.91
+85.133.243.92
+85.133.243.150
+85.133.250.125
+85.133.250.126
+85.133.250.184
+85.133.253.100
+85.133.253.103
+85.185.1.10
+85.185.1.125
+85.185.8.204
+85.185.27.131
+85.185.36.132
+85.185.41.131
+85.185.45.50
+85.185.53.30
+85.185.54.61
+85.185.67.253
+85.185.67.254
+85.185.69.83
+85.185.75.110
+85.185.75.202
+85.185.81.116
+85.185.81.130
+85.185.81.132
+85.185.82.100
+85.185.82.130
+85.185.82.152
+85.185.83.67
+85.185.83.172
+85.185.85.195
+85.185.88.138
+85.185.91.3
+85.185.93.64
+85.185.93.69
+85.185.93.90
+85.185.93.115
+85.185.93.117
+85.185.93.118
+85.185.95.134
+85.185.95.141
+85.185.99.235
+85.185.101.66
+85.185.101.67
+85.185.101.69
+85.185.104.21
+85.185.105.99
+85.185.123.3
+85.185.123.4
+85.185.123.5
+85.185.123.121
+85.185.123.122
+85.185.152.66
+85.185.153.10
+85.185.157.2
+85.185.158.236
+85.185.159.197
+85.185.161.4
+85.185.161.5
+85.185.161.25
+85.185.161.30
+85.185.161.49
+85.185.161.73
+85.185.161.77
+85.185.161.83
+85.185.161.140
+85.185.163.4
+85.185.163.101
+85.185.163.106
+85.185.163.123
+85.185.165.12
+85.185.165.13
+85.185.170.245
+85.185.201.6
+85.185.201.7
+85.185.201.11
+85.185.201.13
+85.185.201.18
+85.185.201.20
+85.185.201.21
+85.185.201.22
+85.185.201.26
+85.185.201.35
+85.185.206.226
+85.185.211.17
+85.185.211.19
+85.185.215.43
+85.185.231.22
+85.185.231.42
+85.185.232.135
+85.185.236.66
+85.185.237.114
+85.185.250.67
+85.185.250.250
+85.185.251.253
+85.185.254.95
+85.198.1.10
+85.198.1.26
+85.198.9.221
+85.198.12.178
+85.198.14.3
+85.198.16.43
+85.198.17.29
+85.198.17.91
+85.198.26.46
+85.198.29.12
+85.204.77.179
+85.204.104.34
+85.204.104.47
+85.208.253.13
+85.208.253.15
+85.208.253.16
+85.208.253.19
+85.208.253.22
+85.208.253.26
+85.208.253.37
+85.208.253.39
+85.208.253.40
+85.208.253.44
+85.208.253.48
+85.208.253.50
+85.208.253.52
+85.208.253.53
+85.208.253.60
+85.208.253.75
+85.208.253.77
+85.208.253.78
+85.208.253.91
+85.208.253.92
+85.208.253.102
+85.208.253.103
+85.208.253.106
+85.208.253.107
+85.208.253.112
+85.208.253.127
+85.208.253.129
+85.208.253.133
+85.208.253.142
+85.208.253.149
+85.208.253.150
+85.208.253.151
+85.208.253.153
+85.208.253.155
+85.208.253.159
+85.208.253.169
+85.208.253.173
+85.208.253.180
+85.208.253.181
+85.208.253.182
+85.208.253.183
+85.208.253.186
+85.208.253.191
+85.208.253.194
+85.208.253.196
+85.208.253.199
+85.208.253.202
+85.208.253.205
+85.208.253.208
+85.208.253.211
+85.208.253.218
+85.208.253.219
+85.208.253.224
+85.208.253.226
+85.208.253.235
+85.208.253.237
+85.208.253.239
+85.208.253.242
+85.208.253.249
+85.208.253.253
+85.208.254.38
+85.208.254.51
+85.208.254.55
+85.208.254.58
+85.208.254.59
+85.208.254.64
+85.208.254.143
+85.208.254.145
+85.208.254.147
+85.208.254.155
+85.208.254.156
+85.208.254.168
+85.208.254.173
+85.208.254.175
+85.208.254.177
+85.208.254.183
+85.208.254.192
+85.208.254.194
+85.208.254.195
+85.208.254.198
+85.208.254.199
+85.208.254.202
+85.208.254.208
+85.208.254.214
+85.208.254.216
+85.208.254.225
+85.208.254.228
+85.208.254.231
+85.208.254.234
+85.208.254.237
+85.208.254.248
+85.208.254.250
+86.104.32.2
+86.104.32.36
+86.104.32.60
+86.104.32.73
+86.104.32.84
+86.104.32.119
+86.104.32.131
+86.104.32.163
+86.104.32.188
+86.104.32.192
+86.104.32.245
+86.104.32.248
+86.104.32.252
+86.104.33.230
+86.104.33.235
+86.104.35.182
+86.104.35.183
+86.104.35.184
+86.104.35.186
+86.104.35.187
+86.104.35.188
+86.104.35.189
+86.104.37.4
+86.104.37.8
+86.104.37.12
+86.104.37.37
+86.104.37.63
+86.104.37.66
+86.104.37.106
+86.104.39.4
+86.104.39.5
+86.104.39.101
+86.104.44.51
+86.104.44.52
+86.104.44.53
+86.104.44.54
+86.104.44.55
+86.104.44.56
+86.104.44.57
+86.104.44.58
+86.104.44.59
+86.104.244.145
+86.106.142.7
+86.106.142.10
+86.106.142.12
+86.106.142.13
+86.106.142.14
+86.106.142.17
+86.106.142.18
+86.106.142.19
+86.106.142.20
+86.106.142.27
+86.106.142.31
+86.106.142.32
+86.106.142.33
+86.106.142.42
+86.106.142.45
+86.106.142.47
+86.106.142.53
+86.106.142.54
+86.106.142.66
+86.106.142.101
+86.106.142.109
+86.106.142.111
+86.106.142.115
+86.106.142.118
+86.106.142.120
+86.106.142.121
+86.106.142.122
+86.106.142.124
+86.107.14.240
+86.107.144.157
+86.107.146.145
+86.107.155.83
+86.107.158.199
+87.107.6.2
+87.107.6.3
+87.107.6.4
+87.107.6.5
+87.107.6.6
+87.107.6.7
+87.107.6.8
+87.107.6.9
+87.107.6.10
+87.107.6.11
+87.107.6.12
+87.107.6.13
+87.107.6.14
+87.107.6.15
+87.107.6.16
+87.107.6.18
+87.107.6.19
+87.107.6.20
+87.107.6.21
+87.107.6.22
+87.107.6.24
+87.107.6.25
+87.107.6.26
+87.107.6.27
+87.107.6.28
+87.107.6.29
+87.107.6.30
+87.107.6.31
+87.107.6.32
+87.107.6.33
+87.107.6.34
+87.107.6.35
+87.107.6.37
+87.107.6.38
+87.107.6.39
+87.107.6.40
+87.107.6.41
+87.107.6.42
+87.107.6.43
+87.107.6.44
+87.107.6.45
+87.107.6.46
+87.107.6.47
+87.107.6.48
+87.107.6.49
+87.107.6.50
+87.107.6.51
+87.107.6.52
+87.107.6.53
+87.107.6.54
+87.107.6.55
+87.107.6.56
+87.107.6.57
+87.107.6.58
+87.107.6.61
+87.107.6.62
+87.107.6.63
+87.107.6.64
+87.107.6.65
+87.107.6.66
+87.107.6.67
+87.107.6.68
+87.107.6.69
+87.107.6.70
+87.107.6.71
+87.107.6.72
+87.107.6.73
+87.107.6.74
+87.107.6.75
+87.107.6.76
+87.107.6.77
+87.107.6.78
+87.107.6.79
+87.107.6.80
+87.107.6.81
+87.107.6.82
+87.107.6.83
+87.107.6.85
+87.107.6.86
+87.107.6.87
+87.107.6.88
+87.107.6.89
+87.107.6.90
+87.107.6.91
+87.107.6.92
+87.107.6.93
+87.107.6.94
+87.107.6.95
+87.107.6.96
+87.107.6.98
+87.107.6.99
+87.107.6.100
+87.107.6.101
+87.107.6.102
+87.107.6.103
+87.107.6.104
+87.107.6.105
+87.107.6.106
+87.107.6.107
+87.107.6.108
+87.107.6.109
+87.107.6.110
+87.107.6.111
+87.107.6.112
+87.107.6.113
+87.107.6.114
+87.107.6.115
+87.107.6.116
+87.107.6.117
+87.107.6.118
+87.107.6.119
+87.107.6.120
+87.107.6.121
+87.107.6.122
+87.107.6.123
+87.107.6.124
+87.107.6.125
+87.107.6.126
+87.107.6.171
+87.107.6.178
+87.107.6.198
+87.107.7.19
+87.107.7.30
+87.107.7.54
+87.107.7.67
+87.107.7.69
+87.107.7.70
+87.107.7.71
+87.107.7.74
+87.107.7.75
+87.107.7.78
+87.107.7.81
+87.107.7.88
+87.107.7.92
+87.107.7.110
+87.107.7.168
+87.107.7.173
+87.107.7.210
+87.107.8.21
+87.107.8.86
+87.107.8.92
+87.107.8.98
+87.107.8.138
+87.107.8.170
+87.107.8.174
+87.107.8.227
+87.107.9.37
+87.107.9.67
+87.107.9.68
+87.107.9.69
+87.107.9.71
+87.107.9.75
+87.107.9.76
+87.107.9.78
+87.107.9.91
+87.107.9.206
+87.107.9.232
+87.107.9.233
+87.107.9.236
+87.107.9.237
+87.107.9.238
+87.107.9.241
+87.107.9.248
+87.107.10.46
+87.107.10.99
+87.107.10.100
+87.107.10.147
+87.107.10.210
+87.107.10.234
+87.107.11.82
+87.107.12.4
+87.107.12.70
+87.107.12.71
+87.107.12.124
+87.107.12.136
+87.107.12.188
+87.107.12.211
+87.107.12.217
+87.107.13.138
+87.107.13.139
+87.107.13.140
+87.107.13.141
+87.107.13.142
+87.107.13.190
+87.107.19.195
+87.107.19.197
+87.107.27.3
+87.107.28.26
+87.107.28.27
+87.107.28.222
+87.107.29.82
+87.107.29.83
+87.107.29.84
+87.107.29.230
+87.107.30.149
+87.107.45.9
+87.107.49.14
+87.107.50.36
+87.107.52.98
+87.107.52.198
+87.107.52.202
+87.107.52.206
+87.107.52.212
+87.107.54.18
+87.107.54.47
+87.107.54.49
+87.107.54.76
+87.107.54.144
+87.107.54.153
+87.107.54.156
+87.107.54.212
+87.107.54.224
+87.107.54.243
+87.107.55.10
+87.107.55.11
+87.107.55.55
+87.107.55.70
+87.107.55.85
+87.107.55.101
+87.107.55.106
+87.107.55.117
+87.107.55.178
+87.107.55.179
+87.107.55.180
+87.107.55.182
+87.107.55.186
+87.107.55.194
+87.107.68.36
+87.107.68.52
+87.107.68.59
+87.107.68.62
+87.107.68.69
+87.107.68.79
+87.107.68.92
+87.107.68.156
+87.107.68.171
+87.107.69.3
+87.107.69.4
+87.107.69.163
+87.107.69.169
+87.107.69.171
+87.107.69.172
+87.107.69.179
+87.107.69.180
+87.107.73.55
+87.107.73.61
+87.107.73.212
+87.107.73.214
+87.107.76.91
+87.107.76.92
+87.107.82.245
+87.107.86.240
+87.107.86.241
+87.107.87.67
+87.107.87.68
+87.107.87.69
+87.107.91.66
+87.107.100.215
+87.107.102.5
+87.107.102.6
+87.107.102.7
+87.107.102.15
+87.107.102.16
+87.107.102.18
+87.107.102.19
+87.107.102.21
+87.107.102.23
+87.107.102.24
+87.107.102.25
+87.107.102.27
+87.107.102.28
+87.107.102.29
+87.107.102.30
+87.107.102.61
+87.107.102.68
+87.107.102.90
+87.107.102.122
+87.107.102.126
+87.107.104.14
+87.107.104.21
+87.107.104.26
+87.107.104.33
+87.107.104.74
+87.107.104.81
+87.107.104.86
+87.107.104.91
+87.107.104.107
+87.107.104.117
+87.107.104.120
+87.107.104.122
+87.107.104.124
+87.107.104.144
+87.107.104.147
+87.107.104.211
+87.107.104.247
+87.107.104.250
+87.107.104.252
+87.107.105.20
+87.107.105.37
+87.107.105.51
+87.107.105.65
+87.107.105.67
+87.107.105.72
+87.107.105.84
+87.107.105.86
+87.107.105.97
+87.107.105.102
+87.107.105.137
+87.107.105.139
+87.107.105.163
+87.107.105.179
+87.107.105.181
+87.107.105.190
+87.107.105.230
+87.107.105.234
+87.107.108.13
+87.107.108.15
+87.107.108.28
+87.107.108.43
+87.107.108.44
+87.107.108.61
+87.107.108.86
+87.107.108.87
+87.107.108.90
+87.107.108.111
+87.107.108.152
+87.107.108.158
+87.107.108.162
+87.107.108.172
+87.107.108.212
+87.107.108.216
+87.107.109.11
+87.107.109.12
+87.107.109.13
+87.107.109.22
+87.107.109.34
+87.107.109.77
+87.107.109.84
+87.107.109.105
+87.107.109.106
+87.107.109.109
+87.107.109.110
+87.107.109.143
+87.107.109.174
+87.107.109.254
+87.107.110.6
+87.107.110.7
+87.107.110.8
+87.107.110.11
+87.107.110.12
+87.107.110.13
+87.107.110.14
+87.107.110.15
+87.107.110.20
+87.107.110.21
+87.107.110.24
+87.107.110.27
+87.107.110.29
+87.107.110.30
+87.107.110.109
+87.107.110.110
+87.107.110.165
+87.107.110.196
+87.107.111.21
+87.107.111.32
+87.107.111.37
+87.107.111.38
+87.107.111.58
+87.107.111.104
+87.107.111.113
+87.107.111.123
+87.107.116.4
+87.107.116.218
+87.107.121.16
+87.107.121.24
+87.107.121.59
+87.107.121.60
+87.107.121.61
+87.107.121.66
+87.107.121.70
+87.107.121.84
+87.107.121.110
+87.107.121.197
+87.107.121.227
+87.107.121.234
+87.107.124.19
+87.107.124.100
+87.107.124.109
+87.107.124.116
+87.107.124.118
+87.107.132.36
+87.107.132.38
+87.107.132.50
+87.107.132.77
+87.107.133.73
+87.107.133.81
+87.107.134.94
+87.107.139.60
+87.107.143.24
+87.107.144.26
+87.107.144.51
+87.107.144.53
+87.107.144.55
+87.107.144.56
+87.107.144.57
+87.107.144.58
+87.107.144.60
+87.107.144.61
+87.107.144.212
+87.107.144.234
+87.107.144.246
+87.107.146.13
+87.107.146.21
+87.107.146.41
+87.107.146.43
+87.107.146.54
+87.107.146.70
+87.107.146.72
+87.107.146.79
+87.107.146.83
+87.107.146.95
+87.107.146.133
+87.107.146.157
+87.107.146.160
+87.107.146.170
+87.107.146.171
+87.107.146.178
+87.107.146.199
+87.107.146.205
+87.107.146.214
+87.107.146.221
+87.107.147.34
+87.107.147.46
+87.107.147.86
+87.107.147.106
+87.107.147.122
+87.107.147.158
+87.107.150.10
+87.107.152.10
+87.107.152.22
+87.107.152.23
+87.107.152.84
+87.107.152.118
+87.107.152.133
+87.107.152.134
+87.107.152.139
+87.107.152.150
+87.107.152.186
+87.107.153.5
+87.107.153.10
+87.107.153.11
+87.107.153.60
+87.107.153.84
+87.107.153.102
+87.107.153.131
+87.107.153.254
+87.107.154.18
+87.107.154.20
+87.107.154.21
+87.107.154.22
+87.107.154.42
+87.107.154.43
+87.107.154.44
+87.107.154.94
+87.107.154.107
+87.107.154.109
+87.107.154.123
+87.107.154.140
+87.107.155.59
+87.107.155.63
+87.107.155.70
+87.107.155.78
+87.107.155.94
+87.107.155.95
+87.107.155.98
+87.107.155.110
+87.107.155.119
+87.107.155.143
+87.107.155.147
+87.107.155.157
+87.107.155.181
+87.107.155.221
+87.107.155.230
+87.107.155.243
+87.107.159.57
+87.107.164.10
+87.107.164.68
+87.107.164.81
+87.107.164.85
+87.107.164.99
+87.107.164.119
+87.107.164.120
+87.107.164.134
+87.107.164.138
+87.107.164.142
+87.107.164.167
+87.107.164.191
+87.107.164.223
+87.107.164.230
+87.107.164.233
+87.107.164.234
+87.107.164.238
+87.107.164.241
+87.107.165.4
+87.107.165.10
+87.107.165.24
+87.107.165.66
+87.107.165.86
+87.107.165.87
+87.107.165.95
+87.107.165.113
+87.107.165.114
+87.107.165.119
+87.107.165.149
+87.107.165.168
+87.107.165.175
+87.107.165.184
+87.107.165.207
+87.107.165.217
+87.107.165.222
+87.107.165.249
+87.107.166.10
+87.107.166.35
+87.107.166.203
+87.107.166.213
+87.107.172.8
+87.107.172.84
+87.107.174.19
+87.107.174.52
+87.107.174.100
+87.107.174.182
+87.107.174.189
+87.107.175.5
+87.107.175.7
+87.107.175.104
+87.107.175.107
+87.107.175.162
+87.107.175.166
+87.107.175.182
+87.107.175.218
+87.107.184.40
+87.107.184.123
+87.107.185.33
+87.107.185.34
+87.107.185.234
+87.107.186.4
+87.107.190.4
+87.107.190.117
+87.107.191.49
+87.236.38.106
+87.236.38.107
+87.236.39.40
+87.236.39.43
+87.236.39.120
+87.236.39.133
+87.236.166.137
+87.236.209.20
+87.236.209.38
+87.236.209.77
+87.236.209.154
+87.236.209.196
+87.236.209.199
+87.236.209.201
+87.236.209.203
+87.236.209.207
+87.236.209.209
+87.236.209.210
+87.236.209.211
+87.236.209.219
+87.236.209.220
+87.236.209.222
+87.236.209.227
+87.236.209.228
+87.236.209.235
+87.236.209.236
+87.236.210.4
+87.236.210.5
+87.236.210.6
+87.236.210.9
+87.236.210.11
+87.236.210.12
+87.236.210.15
+87.236.210.18
+87.236.210.20
+87.236.210.21
+87.236.210.22
+87.236.210.25
+87.236.210.26
+87.236.210.27
+87.236.210.28
+87.236.210.30
+87.236.210.32
+87.236.210.36
+87.236.210.37
+87.236.210.38
+87.236.210.39
+87.236.210.44
+87.236.210.45
+87.236.210.47
+87.236.210.51
+87.236.210.52
+87.236.210.55
+87.236.210.56
+87.236.210.58
+87.236.210.59
+87.236.210.61
+87.236.210.66
+87.236.210.67
+87.236.210.68
+87.236.210.71
+87.236.210.72
+87.236.210.73
+87.236.210.74
+87.236.210.77
+87.236.210.79
+87.236.210.81
+87.236.210.82
+87.236.210.85
+87.236.210.86
+87.236.210.87
+87.236.210.88
+87.236.210.89
+87.236.210.92
+87.236.210.93
+87.236.210.99
+87.236.210.101
+87.236.210.102
+87.236.210.106
+87.236.210.107
+87.236.210.108
+87.236.210.109
+87.236.210.110
+87.236.210.112
+87.236.210.114
+87.236.210.115
+87.236.210.116
+87.236.210.117
+87.236.210.118
+87.236.210.120
+87.236.210.122
+87.236.210.123
+87.236.210.124
+87.236.210.127
+87.236.210.130
+87.236.210.131
+87.236.210.132
+87.236.210.133
+87.236.210.134
+87.236.210.136
+87.236.210.138
+87.236.210.139
+87.236.210.140
+87.236.210.142
+87.236.210.143
+87.236.210.144
+87.236.210.145
+87.236.210.148
+87.236.210.149
+87.236.210.150
+87.236.210.153
+87.236.210.154
+87.236.210.155
+87.236.210.156
+87.236.210.158
+87.236.210.159
+87.236.210.160
+87.236.210.161
+87.236.210.162
+87.236.210.163
+87.236.210.164
+87.236.210.170
+87.236.210.171
+87.236.210.173
+87.236.210.175
+87.236.210.182
+87.236.210.183
+87.236.210.185
+87.236.210.188
+87.236.210.189
+87.236.210.190
+87.236.210.193
+87.236.210.195
+87.236.210.196
+87.236.210.199
+87.236.210.202
+87.236.210.203
+87.236.210.205
+87.236.210.207
+87.236.210.208
+87.236.210.209
+87.236.210.212
+87.236.210.214
+87.236.210.215
+87.236.210.216
+87.236.210.217
+87.236.210.218
+87.236.210.221
+87.236.210.224
+87.236.210.225
+87.236.210.228
+87.236.211.3
+87.236.211.8
+87.236.211.10
+87.236.211.13
+87.236.211.14
+87.236.211.16
+87.236.211.21
+87.236.211.22
+87.236.211.23
+87.236.211.24
+87.236.211.28
+87.236.211.29
+87.236.211.67
+87.236.211.69
+87.236.211.72
+87.236.211.74
+87.236.211.81
+87.236.211.82
+87.236.211.85
+87.236.211.87
+87.236.211.88
+87.236.211.89
+87.236.211.90
+87.236.211.91
+87.236.211.93
+87.236.211.96
+87.236.211.98
+87.236.211.99
+87.236.211.100
+87.236.211.101
+87.236.211.104
+87.236.211.106
+87.236.211.107
+87.236.211.108
+87.236.211.109
+87.236.211.110
+87.236.211.111
+87.236.211.113
+87.236.211.114
+87.236.211.115
+87.236.211.116
+87.236.211.117
+87.236.211.118
+87.236.211.123
+87.236.211.126
+87.236.211.210
+87.236.211.211
+87.236.211.212
+87.236.211.213
+87.236.211.214
+87.236.211.215
+87.236.211.218
+87.236.211.219
+87.236.211.221
+87.236.211.226
+87.236.211.227
+87.236.211.228
+87.236.211.229
+87.236.211.231
+87.236.211.232
+87.236.211.234
+87.236.211.237
+87.236.212.68
+87.236.212.126
+87.236.212.162
+87.236.212.195
+87.236.213.139
+87.236.215.42
+87.236.215.46
+87.236.215.106
+87.236.215.166
+87.236.215.246
+87.247.171.247
+87.247.174.180
+87.247.175.72
+87.247.175.212
+87.247.176.22
+87.247.176.46
+87.247.176.49
+87.247.176.50
+87.247.176.54
+87.247.176.55
+87.247.176.56
+87.247.176.64
+87.247.176.67
+87.247.176.241
+87.247.177.4
+87.247.177.6
+87.247.177.22
+87.247.177.23
+87.247.177.26
+87.247.177.28
+87.247.177.31
+87.247.177.62
+87.247.177.68
+87.247.177.69
+87.247.177.70
+87.247.177.71
+87.247.177.72
+87.247.177.73
+87.247.177.74
+87.247.177.80
+87.247.177.109
+87.247.177.131
+87.247.177.241
+87.247.177.242
+87.247.185.75
+87.247.185.123
+87.247.186.129
+87.247.186.200
+87.247.188.212
+87.248.128.10
+87.248.128.11
+87.248.128.20
+87.248.128.23
+87.248.128.26
+87.248.128.128
+87.248.128.207
+87.248.130.71
+87.248.130.80
+87.248.130.97
+87.248.130.122
+87.248.130.146
+87.248.130.151
+87.248.130.166
+87.248.130.192
+87.248.130.206
+87.248.130.212
+87.248.130.244
+87.248.131.2
+87.248.131.33
+87.248.131.148
+87.248.131.158
+87.248.131.161
+87.248.131.223
+87.248.131.244
+87.248.133.90
+87.248.133.115
+87.248.133.139
+87.248.137.2
+87.248.137.11
+87.248.137.75
+87.248.137.170
+87.248.138.93
+87.248.138.114
+87.248.138.170
+87.248.138.210
+87.248.138.218
+87.248.138.246
+87.248.139.45
+87.248.139.70
+87.248.139.74
+87.248.139.92
+87.248.139.98
+87.248.139.179
+87.248.139.197
+87.248.139.200
+87.248.139.201
+87.248.139.216
+87.248.139.252
+87.248.145.5
+87.248.145.81
+87.248.145.90
+87.248.145.121
+87.248.145.164
+87.248.145.179
+87.248.145.201
+87.248.145.207
+87.248.145.208
+87.248.145.246
+87.248.147.224
+87.248.147.227
+87.248.147.228
+87.248.147.233
+87.248.147.239
+87.248.147.248
+87.248.147.251
+87.248.147.252
+87.248.150.4
+87.248.150.9
+87.248.150.40
+87.248.150.41
+87.248.150.52
+87.248.150.138
+87.248.150.142
+87.248.150.170
+87.248.150.171
+87.248.150.172
+87.248.150.175
+87.248.150.176
+87.248.150.204
+87.248.150.208
+87.248.150.222
+87.248.150.250
+87.248.151.100
+87.248.151.102
+87.248.151.114
+87.248.151.115
+87.248.151.116
+87.248.151.118
+87.248.151.122
+87.248.151.123
+87.248.151.125
+87.248.151.126
+87.248.151.183
+87.248.151.194
+87.248.152.10
+87.248.152.16
+87.248.152.29
+87.248.152.40
+87.248.152.53
+87.248.152.79
+87.248.152.88
+87.248.152.102
+87.248.152.124
+87.248.152.125
+87.248.152.138
+87.248.152.140
+87.248.152.149
+87.248.152.161
+87.248.152.210
+87.248.152.223
+87.248.152.240
+87.248.152.247
+87.248.153.24
+87.248.153.38
+87.248.153.43
+87.248.153.52
+87.248.153.62
+87.248.153.64
+87.248.153.83
+87.248.153.86
+87.248.153.87
+87.248.153.88
+87.248.153.90
+87.248.153.93
+87.248.153.95
+87.248.153.96
+87.248.153.101
+87.248.153.109
+87.248.153.133
+87.248.153.141
+87.248.153.142
+87.248.153.147
+87.248.153.167
+87.248.153.192
+87.248.153.217
+87.248.153.220
+87.248.153.244
+87.248.153.252
+87.248.153.253
+87.248.155.12
+87.248.155.27
+87.248.155.38
+87.248.155.44
+87.248.155.56
+87.248.155.113
+87.248.155.122
+87.248.155.129
+87.248.155.167
+87.248.155.175
+87.248.155.179
+87.248.155.203
+87.248.155.206
+87.248.155.216
+87.248.155.222
+87.248.155.227
+87.248.155.237
+87.248.156.14
+87.248.156.15
+87.248.156.17
+87.248.156.31
+87.248.156.41
+87.248.156.75
+87.248.156.91
+87.248.156.98
+87.248.156.108
+87.248.156.113
+87.248.156.127
+87.248.156.128
+87.248.156.129
+87.248.156.140
+87.248.156.150
+87.248.156.162
+87.248.156.183
+87.248.156.191
+87.248.156.204
+87.248.156.239
+87.248.156.242
+88.135.36.35
+88.135.36.39
+88.135.36.65
+88.135.37.47
+88.135.37.70
+88.135.37.85
+88.135.38.19
+88.135.38.54
+88.135.39.28
+88.135.68.1
+88.135.68.3
+88.135.68.5
+88.135.68.6
+88.135.68.7
+88.135.68.9
+88.135.68.10
+88.135.68.11
+88.135.68.12
+88.135.68.13
+88.135.68.16
+88.135.68.17
+88.135.68.25
+88.135.68.26
+88.135.68.27
+88.135.68.28
+88.135.68.29
+88.135.68.30
+88.135.68.98
+88.135.68.99
+88.135.68.100
+88.135.68.247
+88.135.68.248
+88.135.68.249
+88.135.75.22
+88.135.75.23
+88.135.75.31
+88.135.75.132
+88.135.75.133
+88.135.75.134
+88.135.75.135
+88.135.75.138
+88.135.75.141
+88.135.75.142
+88.135.75.146
+88.135.75.150
+88.135.75.151
+88.135.75.152
+88.135.75.153
+88.135.75.155
+88.135.75.156
+88.135.75.157
+88.135.75.178
+88.135.75.179
+88.135.75.181
+88.135.75.194
+88.135.75.202
+88.135.75.206
+88.218.16.122
+89.32.197.22
+89.32.197.226
+89.32.248.3
+89.32.248.5
+89.32.248.6
+89.32.248.7
+89.32.248.8
+89.32.248.10
+89.32.248.11
+89.32.248.12
+89.32.248.13
+89.32.248.14
+89.32.248.16
+89.32.248.18
+89.32.248.19
+89.32.248.20
+89.32.248.23
+89.32.248.24
+89.32.248.25
+89.32.248.26
+89.32.248.27
+89.32.248.28
+89.32.248.35
+89.32.248.37
+89.32.248.38
+89.32.248.41
+89.32.248.49
+89.32.248.50
+89.32.248.51
+89.32.248.54
+89.32.248.60
+89.32.248.66
+89.32.248.67
+89.32.248.68
+89.32.248.69
+89.32.248.70
+89.32.248.74
+89.32.248.75
+89.32.248.76
+89.32.248.77
+89.32.248.83
+89.32.248.84
+89.32.248.86
+89.32.248.88
+89.32.248.89
+89.32.248.90
+89.32.248.91
+89.32.248.93
+89.32.248.94
+89.32.248.131
+89.32.248.138
+89.32.248.139
+89.32.248.140
+89.32.248.142
+89.32.248.158
+89.32.248.164
+89.32.248.170
+89.32.248.190
+89.32.248.193
+89.32.248.195
+89.32.248.196
+89.32.248.197
+89.32.248.198
+89.32.248.205
+89.32.248.211
+89.32.248.212
+89.32.248.213
+89.32.248.216
+89.32.248.219
+89.32.248.231
+89.32.248.233
+89.32.248.235
+89.32.248.236
+89.32.248.238
+89.32.248.245
+89.32.248.246
+89.32.248.247
+89.32.248.251
+89.32.248.252
+89.32.249.3
+89.32.249.10
+89.32.249.14
+89.32.249.15
+89.32.249.27
+89.32.249.29
+89.32.249.30
+89.32.249.66
+89.32.249.67
+89.32.249.69
+89.32.249.72
+89.32.249.73
+89.32.249.75
+89.32.249.76
+89.32.249.77
+89.32.249.78
+89.32.249.84
+89.32.249.87
+89.32.249.88
+89.32.249.101
+89.32.249.103
+89.32.249.106
+89.32.249.117
+89.32.249.118
+89.32.249.119
+89.32.249.120
+89.32.249.121
+89.32.249.124
+89.32.249.125
+89.32.249.130
+89.32.249.146
+89.32.249.147
+89.32.249.148
+89.32.249.150
+89.32.249.154
+89.32.249.155
+89.32.249.156
+89.32.249.158
+89.32.249.166
+89.32.249.167
+89.32.249.168
+89.32.249.169
+89.32.249.171
+89.32.249.172
+89.32.249.178
+89.32.249.187
+89.32.249.194
+89.32.249.202
+89.32.249.215
+89.32.249.232
+89.32.249.238
+89.32.249.241
+89.32.249.242
+89.32.249.245
+89.32.249.246
+89.32.249.247
+89.32.249.253
+89.32.250.7
+89.32.250.14
+89.32.250.18
+89.32.250.20
+89.32.250.21
+89.32.250.22
+89.32.250.26
+89.32.250.28
+89.32.250.45
+89.32.250.51
+89.32.250.52
+89.32.250.58
+89.32.250.60
+89.32.250.66
+89.32.250.68
+89.32.250.69
+89.32.250.71
+89.32.250.74
+89.32.250.75
+89.32.250.79
+89.32.250.82
+89.32.250.104
+89.32.250.109
+89.32.250.117
+89.32.250.118
+89.32.250.156
+89.32.250.162
+89.32.250.163
+89.32.250.164
+89.32.250.165
+89.32.250.166
+89.32.250.167
+89.32.250.168
+89.32.250.169
+89.32.250.170
+89.32.250.171
+89.32.250.172
+89.32.250.173
+89.32.250.174
+89.32.250.178
+89.32.250.179
+89.32.250.180
+89.32.250.182
+89.32.250.184
+89.32.250.185
+89.32.250.190
+89.32.250.202
+89.32.250.204
+89.32.250.207
+89.32.250.209
+89.32.250.211
+89.32.250.214
+89.32.250.215
+89.32.250.219
+89.32.250.222
+89.32.250.225
+89.32.250.226
+89.32.250.227
+89.32.250.228
+89.32.250.232
+89.32.250.234
+89.32.250.236
+89.32.250.239
+89.32.250.240
+89.32.250.246
+89.32.250.248
+89.32.250.253
+89.32.250.254
+89.32.251.2
+89.32.251.3
+89.32.251.4
+89.32.251.5
+89.32.251.6
+89.32.251.7
+89.32.251.9
+89.32.251.10
+89.32.251.11
+89.32.251.14
+89.32.251.70
+89.32.251.71
+89.32.251.73
+89.32.251.79
+89.32.251.80
+89.32.251.84
+89.32.251.85
+89.32.251.90
+89.32.251.94
+89.32.251.96
+89.32.251.102
+89.32.251.103
+89.32.251.104
+89.32.251.105
+89.32.251.110
+89.32.251.112
+89.32.251.115
+89.32.251.122
+89.32.251.124
+89.32.251.125
+89.32.251.132
+89.32.251.167
+89.33.129.171
+89.33.241.44
+89.34.96.13
+89.34.96.110
+89.34.96.111
+89.34.96.112
+89.34.96.131
+89.34.96.134
+89.34.96.142
+89.34.96.145
+89.34.96.148
+89.34.97.21
+89.34.176.99
+89.35.133.178
+89.35.176.20
+89.35.176.24
+89.37.0.211
+89.37.5.189
+89.37.6.162
+89.37.12.76
+89.37.13.115
+89.37.15.116
+89.37.219.155
+89.37.219.186
+89.37.219.187
+89.37.250.122
+89.39.208.11
+89.39.208.13
+89.39.208.14
+89.39.208.18
+89.39.208.19
+89.39.208.20
+89.39.208.22
+89.39.208.28
+89.39.208.30
+89.39.208.34
+89.39.208.35
+89.39.208.36
+89.39.208.38
+89.39.208.41
+89.39.208.42
+89.39.208.44
+89.39.208.45
+89.39.208.48
+89.39.208.49
+89.39.208.50
+89.39.208.55
+89.39.208.57
+89.39.208.62
+89.39.208.66
+89.39.208.67
+89.39.208.68
+89.39.208.70
+89.39.208.84
+89.39.208.86
+89.39.208.87
+89.39.208.88
+89.39.208.89
+89.39.208.90
+89.39.208.91
+89.39.208.93
+89.39.208.94
+89.39.208.98
+89.39.208.99
+89.39.208.100
+89.39.208.101
+89.39.208.102
+89.39.208.110
+89.39.208.119
+89.39.208.130
+89.39.208.131
+89.39.208.132
+89.39.208.134
+89.39.208.135
+89.39.208.136
+89.39.208.137
+89.39.208.146
+89.39.208.147
+89.39.208.148
+89.39.208.152
+89.39.208.153
+89.39.208.154
+89.39.208.155
+89.39.208.162
+89.39.208.163
+89.39.208.164
+89.39.208.165
+89.39.208.170
+89.39.208.173
+89.39.208.178
+89.39.208.179
+89.39.208.180
+89.39.208.181
+89.39.208.184
+89.39.208.185
+89.39.208.186
+89.39.208.187
+89.39.208.188
+89.39.208.190
+89.39.208.195
+89.39.208.196
+89.39.208.197
+89.39.208.198
+89.39.208.199
+89.39.208.200
+89.39.208.202
+89.39.208.203
+89.39.208.204
+89.39.208.205
+89.39.208.206
+89.39.208.209
+89.39.208.210
+89.39.208.212
+89.39.208.213
+89.39.208.216
+89.39.208.218
+89.39.208.219
+89.39.208.240
+89.39.208.241
+89.39.208.242
+89.39.208.246
+89.39.208.247
+89.39.208.250
+89.39.208.251
+89.40.78.156
+89.40.246.40
+89.40.247.81
+89.42.136.6
+89.42.136.67
+89.42.136.94
+89.42.137.119
+89.42.137.122
+89.42.137.195
+89.42.138.21
+89.42.138.66
+89.42.138.71
+89.42.138.74
+89.42.138.98
+89.42.138.124
+89.42.138.212
+89.42.138.243
+89.42.138.244
+89.42.138.245
+89.42.138.246
+89.42.138.247
+89.42.138.248
+89.42.138.249
+89.42.138.250
+89.42.138.251
+89.42.138.252
+89.42.138.253
+89.42.138.254
+89.42.139.142
+89.42.139.180
+89.42.139.181
+89.42.139.182
+89.42.139.187
+89.42.197.254
+89.42.199.49
+89.42.199.137
+89.42.208.14
+89.42.208.15
+89.42.208.16
+89.42.208.17
+89.42.208.21
+89.42.208.25
+89.42.208.26
+89.42.208.27
+89.42.208.28
+89.42.208.29
+89.42.208.33
+89.42.208.34
+89.42.208.40
+89.42.208.46
+89.42.208.51
+89.42.208.53
+89.42.208.66
+89.42.208.99
+89.42.208.101
+89.42.208.105
+89.42.208.109
+89.42.208.111
+89.42.208.119
+89.42.208.121
+89.42.208.124
+89.42.208.139
+89.42.208.146
+89.42.208.147
+89.42.208.150
+89.42.208.155
+89.42.208.156
+89.42.208.157
+89.42.208.179
+89.42.208.180
+89.42.208.181
+89.42.208.182
+89.42.208.195
+89.42.208.196
+89.42.208.202
+89.42.208.203
+89.42.208.210
+89.42.208.213
+89.42.208.214
+89.42.208.219
+89.42.208.246
+89.42.208.249
+89.42.209.4
+89.42.209.13
+89.42.209.16
+89.42.209.17
+89.42.209.19
+89.42.209.23
+89.42.209.26
+89.42.209.35
+89.42.209.40
+89.42.209.43
+89.42.209.45
+89.42.209.48
+89.42.209.49
+89.42.209.58
+89.42.209.68
+89.42.209.69
+89.42.209.70
+89.42.209.71
+89.42.209.72
+89.42.209.73
+89.42.209.74
+89.42.209.76
+89.42.209.77
+89.42.209.79
+89.42.209.80
+89.42.209.81
+89.42.209.82
+89.42.209.87
+89.42.209.108
+89.42.209.110
+89.42.209.167
+89.42.209.190
+89.42.209.194
+89.42.209.196
+89.42.209.197
+89.42.209.198
+89.42.209.203
+89.42.209.204
+89.42.209.205
+89.42.209.206
+89.42.209.226
+89.42.209.227
+89.42.209.229
+89.42.209.230
+89.42.209.234
+89.42.209.235
+89.42.209.236
+89.42.209.237
+89.42.209.238
+89.42.209.242
+89.42.209.244
+89.42.209.246
+89.42.210.8
+89.42.210.16
+89.42.210.30
+89.42.210.36
+89.42.210.39
+89.42.210.45
+89.42.210.47
+89.42.210.48
+89.42.210.49
+89.42.210.51
+89.42.210.52
+89.42.210.54
+89.42.210.57
+89.42.210.64
+89.42.210.74
+89.42.210.83
+89.42.210.113
+89.42.210.115
+89.42.210.116
+89.42.210.118
+89.42.210.119
+89.42.210.122
+89.42.210.123
+89.42.210.146
+89.42.210.162
+89.42.210.165
+89.42.210.166
+89.42.210.168
+89.42.210.169
+89.42.210.171
+89.42.210.176
+89.42.210.177
+89.42.210.179
+89.42.210.180
+89.42.210.181
+89.42.210.182
+89.42.210.183
+89.42.210.186
+89.42.210.187
+89.42.210.188
+89.42.210.189
+89.42.210.200
+89.42.210.201
+89.42.210.222
+89.42.210.227
+89.42.210.228
+89.42.210.229
+89.42.210.230
+89.42.210.234
+89.42.210.236
+89.42.210.243
+89.42.210.244
+89.42.210.245
+89.42.210.246
+89.42.210.250
+89.42.210.251
+89.42.210.254
+89.42.211.2
+89.42.211.3
+89.42.211.10
+89.42.211.13
+89.42.211.14
+89.42.211.18
+89.42.211.22
+89.42.211.23
+89.42.211.44
+89.42.211.47
+89.42.211.48
+89.42.211.50
+89.42.211.52
+89.42.211.55
+89.42.211.67
+89.42.211.70
+89.42.211.71
+89.42.211.72
+89.42.211.74
+89.42.211.77
+89.42.211.78
+89.42.211.80
+89.42.211.81
+89.42.211.82
+89.42.211.85
+89.42.211.87
+89.42.211.93
+89.42.211.98
+89.42.211.99
+89.42.211.101
+89.42.211.102
+89.42.211.108
+89.42.211.109
+89.42.211.110
+89.42.211.114
+89.42.211.162
+89.42.211.163
+89.42.211.164
+89.42.211.165
+89.42.211.166
+89.42.211.170
+89.42.211.171
+89.42.211.172
+89.42.211.173
+89.42.211.174
+89.42.211.220
+89.42.211.222
+89.42.211.226
+89.42.211.227
+89.42.211.228
+89.42.211.236
+89.43.0.33
+89.43.0.232
+89.43.4.178
+89.43.5.218
+89.43.5.219
+89.43.7.222
+89.43.10.43
+89.43.10.44
+89.43.224.135
+89.43.226.192
+89.43.231.91
+89.43.231.203
+89.44.112.5
+89.44.118.10
+89.44.134.50
+89.44.182.229
+89.45.89.3
+89.45.89.8
+89.45.89.9
+89.46.60.176
+89.46.61.56
+89.46.216.6
+89.46.216.7
+89.46.216.20
+89.46.216.21
+89.46.216.22
+89.46.216.23
+89.46.216.25
+89.46.216.26
+89.46.216.28
+89.46.216.29
+89.46.216.30
+89.46.216.31
+89.46.216.112
+89.46.216.113
+89.46.216.114
+89.46.216.115
+89.46.216.116
+89.46.216.117
+89.46.216.118
+89.46.216.119
+89.46.216.200
+89.46.216.201
+89.46.216.202
+89.46.216.203
+89.46.216.204
+89.46.216.205
+89.46.216.206
+89.46.216.207
+89.46.218.12
+89.46.218.13
+89.46.218.14
+89.46.218.15
+89.46.218.24
+89.46.218.50
+89.46.218.56
+89.46.218.57
+89.46.218.58
+89.46.218.59
+89.46.218.60
+89.46.218.61
+89.46.218.62
+89.46.218.63
+89.46.218.64
+89.46.218.65
+89.46.218.66
+89.46.218.67
+89.46.218.68
+89.46.218.70
+89.46.218.71
+89.46.218.72
+89.46.218.73
+89.46.218.74
+89.46.218.75
+89.46.218.76
+89.46.218.77
+89.46.218.78
+89.46.218.79
+89.46.218.80
+89.46.218.81
+89.46.218.82
+89.46.218.83
+89.46.218.84
+89.46.218.85
+89.46.218.86
+89.46.218.87
+89.46.218.88
+89.46.218.89
+89.46.218.90
+89.46.218.91
+89.46.218.92
+89.46.218.93
+89.46.218.94
+89.46.218.95
+89.46.218.96
+89.46.218.97
+89.46.218.98
+89.46.218.99
+89.46.218.100
+89.46.218.101
+89.46.218.102
+89.46.218.103
+89.46.218.104
+89.46.218.105
+89.46.218.106
+89.46.218.107
+89.46.218.108
+89.46.218.110
+89.46.218.111
+89.46.218.112
+89.46.218.113
+89.46.218.114
+89.46.218.115
+89.46.218.116
+89.46.218.117
+89.46.218.118
+89.46.218.119
+89.46.218.120
+89.46.218.121
+89.46.218.122
+89.46.218.123
+89.46.218.124
+89.46.218.125
+89.46.218.126
+89.46.218.128
+89.46.218.129
+89.46.218.130
+89.46.218.131
+89.46.218.132
+89.46.219.16
+89.46.219.18
+89.46.219.64
+89.46.219.65
+89.46.219.66
+89.46.219.67
+89.46.219.68
+89.46.219.69
+89.46.219.70
+89.46.219.71
+89.46.219.80
+89.46.219.81
+89.46.219.83
+89.46.219.84
+89.46.219.85
+89.46.219.86
+89.46.219.87
+89.46.219.88
+89.46.219.89
+89.46.219.90
+89.46.219.91
+89.46.219.92
+89.46.219.93
+89.46.219.94
+89.46.219.95
+89.46.219.104
+89.46.219.105
+89.46.219.106
+89.46.219.107
+89.46.219.108
+89.46.219.109
+89.46.219.110
+89.46.219.111
+89.46.219.112
+89.46.219.113
+89.46.219.114
+89.46.219.115
+89.46.219.116
+89.46.219.117
+89.46.219.118
+89.46.219.119
+89.46.219.176
+89.46.219.177
+89.46.219.178
+89.46.219.179
+89.46.219.180
+89.46.219.181
+89.46.219.182
+89.46.219.183
+89.46.219.192
+89.46.219.193
+89.46.219.194
+89.46.219.195
+89.46.219.196
+89.46.219.197
+89.46.219.198
+89.46.219.220
+89.46.219.221
+89.46.219.222
+89.46.219.223
+89.144.128.21
+89.144.129.18
+89.144.129.234
+89.144.131.136
+89.144.131.137
+89.144.131.139
+89.144.131.140
+89.144.131.141
+89.144.131.142
+89.144.131.143
+89.144.132.168
+89.144.132.169
+89.144.132.170
+89.144.132.171
+89.144.132.172
+89.144.132.174
+89.144.132.175
+89.144.132.184
+89.144.132.185
+89.144.132.186
+89.144.132.187
+89.144.132.188
+89.144.132.190
+89.144.132.191
+89.144.132.193
+89.144.132.194
+89.144.137.192
+89.144.137.193
+89.144.137.194
+89.144.137.195
+89.144.137.196
+89.144.137.198
+89.144.137.201
+89.144.137.202
+89.144.137.203
+89.144.137.205
+89.144.137.206
+89.144.137.209
+89.144.137.211
+89.144.137.213
+89.144.137.214
+89.144.137.216
+89.144.137.218
+89.144.137.219
+89.144.137.221
+89.144.137.222
+89.144.137.224
+89.144.137.225
+89.144.137.226
+89.144.137.227
+89.144.137.228
+89.144.137.230
+89.144.137.231
+89.144.137.232
+89.144.137.235
+89.144.137.239
+89.144.137.241
+89.144.137.242
+89.144.137.243
+89.144.137.245
+89.144.137.246
+89.144.137.248
+89.144.137.249
+89.144.137.250
+89.144.137.252
+89.144.138.138
+89.144.138.153
+89.144.138.154
+89.144.138.157
+89.144.138.158
+89.144.138.159
+89.144.139.0
+89.144.139.2
+89.144.139.3
+89.144.139.5
+89.144.139.6
+89.144.139.8
+89.144.139.9
+89.144.139.10
+89.144.139.12
+89.144.139.13
+89.144.139.15
+89.144.139.17
+89.144.139.18
+89.144.139.20
+89.144.139.21
+89.144.139.22
+89.144.139.23
+89.144.139.24
+89.144.139.26
+89.144.139.27
+89.144.139.28
+89.144.139.29
+89.144.139.30
+89.144.139.31
+89.144.139.32
+89.144.139.33
+89.144.139.34
+89.144.139.35
+89.144.139.37
+89.144.139.38
+89.144.139.39
+89.144.139.40
+89.144.139.41
+89.144.139.42
+89.144.139.43
+89.144.139.44
+89.144.139.45
+89.144.139.46
+89.144.139.47
+89.144.139.48
+89.144.139.49
+89.144.139.50
+89.144.139.51
+89.144.139.52
+89.144.139.53
+89.144.139.54
+89.144.139.55
+89.144.139.56
+89.144.139.57
+89.144.139.59
+89.144.139.62
+89.144.139.63
+89.144.139.64
+89.144.139.65
+89.144.139.66
+89.144.139.67
+89.144.139.68
+89.144.139.70
+89.144.139.71
+89.144.139.72
+89.144.139.73
+89.144.139.74
+89.144.139.75
+89.144.139.76
+89.144.139.77
+89.144.139.78
+89.144.139.79
+89.144.139.82
+89.144.139.84
+89.144.139.85
+89.144.139.87
+89.144.139.88
+89.144.139.89
+89.144.139.90
+89.144.139.91
+89.144.139.92
+89.144.139.93
+89.144.139.95
+89.144.139.96
+89.144.139.97
+89.144.139.102
+89.144.139.103
+89.144.139.104
+89.144.139.105
+89.144.139.106
+89.144.139.108
+89.144.139.110
+89.144.139.112
+89.144.139.114
+89.144.139.115
+89.144.139.116
+89.144.139.117
+89.144.139.118
+89.144.139.121
+89.144.139.122
+89.144.139.123
+89.144.139.124
+89.144.139.125
+89.144.139.126
+89.144.139.127
+89.144.140.34
+89.144.141.159
+89.144.141.220
+89.144.143.130
+89.144.144.118
+89.144.144.144
+89.144.145.210
+89.144.145.212
+89.144.145.213
+89.144.145.214
+89.144.145.215
+89.144.151.22
+89.144.151.251
+89.144.151.252
+89.144.154.98
+89.144.156.249
+89.144.166.144
+89.144.166.145
+89.144.166.146
+89.144.166.147
+89.144.166.148
+89.144.166.149
+89.144.166.150
+89.144.166.151
+89.144.166.152
+89.144.166.153
+89.144.166.154
+89.144.166.155
+89.144.166.156
+89.144.166.157
+89.144.166.158
+89.144.166.159
+89.144.166.160
+89.144.166.166
+89.144.166.167
+89.144.166.168
+89.144.166.169
+89.144.166.170
+89.144.166.171
+89.144.166.173
+89.144.166.174
+89.144.166.175
+89.144.166.176
+89.144.166.177
+89.144.166.178
+89.144.166.179
+89.144.166.180
+89.144.166.181
+89.144.166.182
+89.144.166.183
+89.144.166.184
+89.144.166.185
+89.144.166.186
+89.144.166.187
+89.144.166.189
+89.144.166.190
+89.144.166.192
+89.144.166.194
+89.144.166.195
+89.144.166.196
+89.144.166.197
+89.144.166.198
+89.144.166.199
+89.144.166.200
+89.144.166.201
+89.144.166.202
+89.144.166.203
+89.144.166.204
+89.144.166.205
+89.144.166.206
+89.144.166.207
+89.144.166.208
+89.144.166.209
+89.144.166.210
+89.144.166.211
+89.144.166.212
+89.144.166.213
+89.144.166.214
+89.144.166.215
+89.144.166.216
+89.144.166.218
+89.144.166.219
+89.144.166.220
+89.144.166.221
+89.144.166.222
+89.144.166.223
+89.144.166.224
+89.144.166.225
+89.144.166.226
+89.144.166.227
+89.144.166.228
+89.144.166.229
+89.144.166.230
+89.144.166.231
+89.144.166.240
+89.144.166.241
+89.144.166.243
+89.144.166.244
+89.144.166.245
+89.144.166.246
+89.144.166.247
+89.144.166.248
+89.144.166.249
+89.144.166.250
+89.144.166.251
+89.144.166.252
+89.144.166.253
+89.144.166.254
+89.144.166.255
+89.144.176.190
+89.144.182.3
+89.144.183.0
+89.144.183.1
+89.144.183.2
+89.144.183.3
+89.144.183.4
+89.144.183.5
+89.144.183.6
+89.144.183.7
+89.144.183.16
+89.144.183.17
+89.144.183.18
+89.144.183.19
+89.144.183.22
+89.144.183.23
+89.144.183.42
+89.144.187.66
+89.144.187.67
+89.144.187.68
+89.144.188.87
+89.144.189.112
+89.144.189.115
+89.144.189.118
+89.144.189.119
+89.144.189.121
+89.144.189.122
+89.144.189.123
+89.144.189.125
+89.144.189.126
+89.144.189.127
+89.144.189.128
+89.144.189.130
+89.144.189.131
+89.144.189.134
+89.144.189.135
+89.144.189.139
+89.144.189.141
+89.144.189.143
+89.144.189.144
+89.144.189.145
+89.144.189.146
+89.144.189.148
+89.144.189.149
+89.144.189.150
+89.144.189.158
+89.144.189.163
+89.144.189.167
+89.144.189.169
+89.144.189.171
+89.144.189.173
+89.144.189.175
+89.144.189.178
+89.144.189.179
+89.144.189.180
+89.144.189.182
+89.144.189.183
+89.144.189.184
+89.144.189.187
+89.144.189.188
+89.144.189.190
+89.144.189.193
+89.144.189.195
+89.144.189.199
+89.144.189.200
+89.144.189.201
+89.144.189.203
+89.144.189.205
+89.144.189.206
+89.144.189.210
+89.144.189.212
+89.144.189.215
+89.144.189.216
+89.144.189.217
+89.144.189.218
+89.144.189.220
+89.144.189.221
+89.144.189.222
+89.144.189.224
+89.144.189.225
+89.144.189.226
+89.144.189.229
+89.144.189.231
+89.144.189.233
+89.144.189.235
+89.144.189.238
+89.144.189.242
+89.144.189.243
+89.144.189.244
+89.144.189.245
+89.144.189.246
+89.144.189.247
+89.144.189.249
+89.144.189.250
+89.144.189.251
+89.144.189.253
+89.144.189.254
+89.144.189.255
+89.165.0.13
+89.165.0.14
+89.165.1.212
+89.165.1.232
+89.165.56.19
+89.219.64.58
+89.219.64.157
+89.219.65.151
+89.219.66.83
+89.219.66.163
+89.219.79.161
+89.219.81.18
+89.219.83.86
+89.219.83.227
+89.219.84.161
+89.219.84.162
+89.219.89.61
+89.219.92.21
+89.219.94.12
+89.219.96.28
+89.219.112.149
+89.219.192.22
+89.219.200.102
+89.219.216.206
+89.219.219.255
+89.219.220.231
+89.219.233.8
+89.219.237.50
+89.219.237.81
+89.219.237.239
+89.219.239.108
+89.219.252.233
+89.221.80.9
+89.221.80.10
+89.221.81.31
+89.221.81.140
+89.221.83.12
+89.221.83.20
+89.235.64.65
+89.235.64.66
+89.235.66.5
+89.235.66.6
+89.235.67.4
+89.235.67.5
+89.235.68.2
+89.235.68.5
+89.235.69.2
+89.235.79.4
+89.235.79.5
+89.235.79.6
+89.235.79.8
+89.235.79.9
+89.235.79.13
+89.235.79.15
+89.235.79.16
+89.235.79.19
+89.235.79.20
+89.235.79.21
+89.235.79.22
+89.235.79.23
+89.235.79.24
+89.235.79.26
+89.235.79.27
+89.235.79.29
+89.235.79.32
+89.235.79.35
+89.235.79.39
+89.235.79.41
+89.235.79.43
+89.235.79.44
+89.235.79.45
+89.235.79.46
+89.235.79.47
+89.235.79.48
+89.235.79.51
+89.235.79.52
+89.235.79.54
+89.235.79.55
+89.235.79.56
+89.235.79.57
+89.235.79.58
+89.235.79.59
+89.235.79.60
+89.235.79.67
+89.235.79.68
+89.235.79.110
+89.235.116.201
+89.235.116.202
+89.235.116.203
+89.235.116.211
+89.235.116.216
+91.92.114.189
+91.92.121.183
+91.92.121.200
+91.92.125.90
+91.92.126.55
+91.92.127.236
+91.92.130.216
+91.92.132.42
+91.92.158.85
+91.92.158.146
+91.92.158.186
+91.92.159.116
+91.92.180.77
+91.92.180.198
+91.92.182.182
+91.92.186.205
+91.92.187.146
+91.92.188.192
+91.92.190.5
+91.92.190.17
+91.92.191.165
+91.92.204.208
+91.92.204.220
+91.92.209.6
+91.92.209.151
+91.92.213.228
+91.92.214.28
+91.92.214.110
+91.92.214.241
+91.92.215.66
+91.92.215.250
+91.106.65.46
+91.106.65.47
+91.106.78.194
+91.106.85.10
+91.106.86.218
+91.106.87.54
+91.106.91.5
+91.106.91.6
+91.108.128.18
+91.108.129.121
+91.108.130.18
+91.108.130.203
+91.108.130.204
+91.108.130.206
+91.108.152.115
+91.108.152.116
+91.185.133.81
+91.186.193.4
+91.186.193.20
+91.186.193.21
+91.186.193.29
+91.186.193.32
+91.186.193.35
+91.186.193.41
+91.186.193.89
+91.186.193.108
+91.186.193.125
+91.186.193.130
+91.186.193.131
+91.186.193.132
+91.186.193.133
+91.186.193.134
+91.186.193.162
+91.186.193.192
+91.186.193.193
+91.186.193.194
+91.186.193.196
+91.186.193.229
+91.186.193.230
+91.186.193.232
+91.197.242.5
+91.197.242.6
+91.199.9.87
+91.199.9.199
+91.199.27.62
+91.199.27.83
+91.199.27.185
+91.199.27.237
+91.199.30.171
+91.199.30.196
+91.199.215.3
+91.199.215.26
+91.199.215.30
+91.199.215.69
+91.199.215.70
+91.199.215.72
+91.199.215.73
+91.199.215.77
+91.199.215.78
+91.199.215.115
+91.199.215.248
+91.207.138.55
+91.207.205.4
+91.207.205.5
+91.207.205.6
+91.207.205.8
+91.207.205.9
+91.207.205.10
+91.207.205.11
+91.207.205.12
+91.207.205.13
+91.207.205.14
+91.207.205.15
+91.207.205.16
+91.207.205.17
+91.207.205.18
+91.207.205.19
+91.207.205.20
+91.207.205.21
+91.207.205.22
+91.207.205.24
+91.207.205.26
+91.207.205.29
+91.207.205.30
+91.207.205.34
+91.207.205.35
+91.207.205.36
+91.207.205.37
+91.207.205.38
+91.207.205.41
+91.207.205.44
+91.207.205.46
+91.207.205.47
+91.207.205.48
+91.207.205.50
+91.208.163.196
+91.212.174.5
+91.212.174.10
+91.212.174.21
+91.212.174.28
+91.212.174.39
+91.212.174.43
+91.212.174.48
+91.212.174.50
+91.212.174.56
+91.212.174.80
+91.212.174.86
+91.212.174.95
+91.212.174.98
+91.212.174.100
+91.212.174.105
+91.212.174.114
+91.212.174.119
+91.212.174.131
+91.212.174.133
+91.212.174.136
+91.212.174.138
+91.212.174.141
+91.212.174.148
+91.212.174.149
+91.212.174.163
+91.212.174.178
+91.212.174.183
+91.212.174.184
+91.212.174.185
+91.212.174.191
+91.212.174.196
+91.212.174.205
+91.212.174.226
+91.212.174.233
+91.212.174.250
+91.212.252.53
+91.212.252.54
+91.212.252.184
+91.212.252.200
+91.212.252.201
+91.216.171.3
+91.216.171.4
+91.216.171.8
+91.220.113.2
+91.220.113.7
+91.220.113.18
+91.220.113.22
+91.220.113.40
+91.220.113.47
+91.220.113.119
+91.220.113.125
+91.220.113.151
+91.220.113.157
+91.220.113.167
+91.220.113.172
+91.220.113.185
+91.220.113.199
+91.220.113.200
+91.220.113.207
+91.220.113.221
+91.220.113.231
+91.220.113.239
+91.220.113.241
+91.220.113.245
+91.220.113.246
+91.220.113.251
+91.220.113.252
+91.221.241.200
+91.222.199.9
+91.222.199.95
+91.222.199.98
+91.222.199.250
+91.222.199.251
+91.222.199.252
+91.223.116.1
+91.223.116.15
+91.223.116.50
+91.223.116.52
+91.223.116.61
+91.223.116.116
+91.223.116.128
+91.223.116.130
+91.223.116.134
+91.223.116.135
+91.223.116.136
+91.223.116.137
+91.223.116.138
+91.223.116.143
+91.223.116.144
+91.223.116.146
+91.223.116.147
+91.223.116.152
+91.223.116.153
+91.223.116.156
+91.223.116.158
+91.223.116.161
+91.223.116.163
+91.223.116.167
+91.223.116.168
+91.223.116.170
+91.223.116.171
+91.223.116.172
+91.223.116.175
+91.223.116.187
+91.223.116.194
+91.223.116.196
+91.223.116.200
+91.223.116.206
+91.223.116.220
+91.223.116.221
+91.223.116.234
+91.223.116.249
+91.223.146.10
+91.223.146.20
+91.224.110.2
+91.224.110.56
+91.224.110.58
+91.224.111.101
+91.225.54.67
+91.225.54.70
+91.228.132.6
+91.228.132.21
+91.228.132.23
+91.228.132.91
+91.228.133.91
+91.232.73.11
+91.232.73.12
+91.232.73.55
+91.232.73.56
+91.232.73.66
+91.232.73.67
+91.234.39.11
+91.234.39.15
+91.234.39.16
+91.234.39.32
+91.234.39.33
+91.234.39.44
+91.234.39.58
+91.234.39.61
+91.234.39.68
+91.234.39.112
+91.234.39.115
+91.234.39.179
+91.234.39.181
+91.234.39.203
+91.234.39.208
+91.234.39.214
+91.234.39.228
+91.234.39.234
+91.236.168.56
+91.236.168.68
+91.236.168.84
+91.236.168.121
+91.236.168.145
+91.236.168.164
+91.236.168.167
+91.236.168.178
+91.236.168.179
+91.236.168.208
+91.236.168.210
+91.236.168.220
+91.236.168.249
+91.236.168.250
+91.236.168.251
+91.236.168.252
+91.236.168.253
+91.236.169.187
+91.239.14.3
+91.239.14.4
+91.239.214.2
+91.239.214.130
+91.240.60.5
+91.240.60.10
+91.240.60.15
+91.240.60.60
+91.240.60.61
+91.240.61.110
+91.240.62.2
+91.240.62.10
+91.240.62.11
+91.240.63.37
+91.240.63.114
+91.240.63.115
+91.240.180.10
+91.240.180.11
+91.240.180.215
+91.240.180.216
+91.240.182.210
+91.240.182.211
+91.242.44.228
+91.243.127.102
+91.243.171.83
+91.243.171.172
+91.245.228.96
+91.245.228.101
+91.245.228.102
+91.245.228.250
+91.245.228.251
+91.245.229.1
+91.245.229.66
+91.246.31.25
+91.246.44.9
+91.246.44.112
+91.247.171.14
+91.247.171.36
+91.247.171.61
+91.247.171.65
+91.247.171.75
+91.247.171.80
+91.247.171.135
+91.247.171.146
+91.247.171.154
+91.247.171.203
+91.247.171.231
+91.247.174.1
+92.42.50.58
+92.42.50.209
+92.42.50.210
+92.42.51.109
+92.42.51.209
+92.42.53.28
+92.42.53.29
+92.42.207.35
+92.43.163.198
+92.61.181.55
+92.61.181.181
+92.61.181.253
+92.61.181.254
+92.61.183.8
+92.61.183.136
+92.61.183.141
+92.61.183.146
+92.114.17.228
+92.114.17.229
+92.114.17.230
+92.114.18.46
+92.114.18.100
+92.114.18.102
+92.114.18.104
+92.114.18.111
+92.114.18.116
+92.114.18.117
+92.114.19.9
+92.114.19.28
+92.114.19.29
+92.114.19.41
+92.114.19.226
+92.114.19.251
+92.114.19.252
+92.114.24.110
+92.114.28.66
+92.114.31.112
+92.114.50.2
+92.114.51.151
+92.119.57.68
+92.119.57.75
+92.119.57.82
+92.119.57.108
+92.119.57.109
+92.119.57.110
+92.119.57.134
+92.119.57.147
+92.119.57.164
+92.119.57.176
+92.119.57.210
+92.119.58.22
+92.119.58.32
+92.119.58.59
+92.119.58.60
+92.119.58.62
+92.119.58.114
+92.119.58.158
+92.242.195.53
+92.242.195.54
+92.242.198.7
+92.242.198.21
+92.242.198.22
+92.242.198.42
+92.242.198.50
+92.242.198.51
+92.242.198.52
+92.242.198.123
+92.242.198.166
+92.242.198.181
+92.242.198.230
+92.242.198.233
+92.242.198.253
+92.242.201.2
+92.242.201.10
+92.242.201.11
+92.242.203.85
+92.242.204.73
+92.242.204.74
+92.242.205.40
+92.242.207.200
+92.242.210.6
+92.242.212.103
+92.242.216.50
+92.242.216.150
+92.242.216.248
+92.242.220.116
+92.242.220.122
+92.242.220.162
+92.242.220.200
+92.242.220.228
+92.242.220.238
+92.242.223.115
+92.242.223.116
+92.246.144.179
+92.246.144.205
+92.246.145.99
+92.246.146.139
+93.113.224.58
+93.113.224.60
+93.113.224.62
+93.113.225.7
+93.113.225.8
+93.113.226.82
+93.113.234.62
+93.113.234.67
+93.113.235.105
+93.113.235.106
+93.113.235.107
+93.113.235.108
+93.113.236.50
+93.113.236.52
+93.113.236.53
+93.113.237.170
+93.113.238.2
+93.113.239.55
+93.113.239.56
+93.113.239.57
+93.113.239.58
+93.114.110.20
+93.115.126.14
+93.115.127.9
+93.115.144.212
+93.115.148.150
+93.115.149.88
+93.115.150.27
+93.115.150.28
+93.115.150.29
+93.115.150.66
+93.115.150.68
+93.115.150.229
+93.115.150.230
+93.115.150.231
+93.115.150.235
+93.115.150.236
+93.115.150.237
+93.115.150.238
+93.115.151.75
+93.115.151.76
+93.115.151.77
+93.115.151.78
+93.115.151.100
+93.115.151.138
+93.115.219.48
+93.117.27.61
+93.117.30.40
+93.117.30.53
+93.117.36.33
+93.117.37.237
+93.117.39.171
+93.117.43.82
+93.117.46.181
+93.117.46.187
+93.117.47.43
+93.117.127.141
+93.118.99.182
+93.118.104.137
+93.118.108.162
+93.118.109.213
+93.118.110.144
+93.118.112.28
+93.118.112.76
+93.118.112.118
+93.118.115.173
+93.118.116.13
+93.118.117.12
+93.118.121.130
+93.118.122.27
+93.118.123.140
+93.118.125.167
+93.118.126.176
+93.118.126.196
+93.118.127.96
+93.118.132.34
+93.118.134.242
+93.118.135.237
+93.118.137.33
+93.118.137.209
+93.118.138.109
+93.118.140.95
+93.118.140.160
+93.118.144.69
+93.118.145.139
+93.118.146.112
+93.118.148.134
+93.118.153.59
+93.118.153.218
+93.118.156.84
+93.118.160.148
+93.118.160.151
+93.118.163.159
+93.118.163.238
+93.118.164.87
+93.118.164.193
+93.118.165.89
+93.118.166.2
+93.118.167.175
+93.118.182.221
+93.118.183.120
+93.119.57.119
+93.126.2.3
+93.126.2.4
+93.126.2.77
+93.126.2.212
+93.126.3.99
+93.126.3.169
+93.126.6.131
+93.126.6.132
+93.126.6.133
+93.126.6.134
+93.126.6.145
+93.126.6.146
+93.126.6.147
+93.126.6.150
+93.126.6.151
+93.126.6.176
+93.126.6.178
+93.126.6.182
+93.126.6.186
+93.126.23.245
+93.126.23.251
+93.126.25.8
+93.126.25.10
+93.126.25.15
+93.126.31.166
+94.74.128.2
+94.74.128.3
+94.74.128.4
+94.74.128.12
+94.74.128.13
+94.74.128.18
+94.74.128.110
+94.74.128.129
+94.74.128.234
+94.74.128.252
+94.74.145.11
+94.74.145.14
+94.74.145.16
+94.74.145.23
+94.74.145.24
+94.74.145.27
+94.74.145.122
+94.74.145.130
+94.74.145.155
+94.74.145.173
+94.74.145.178
+94.74.145.191
+94.74.145.202
+94.74.163.130
+94.74.168.36
+94.74.168.179
+94.74.170.119
+94.74.170.162
+94.74.170.167
+94.101.136.138
+94.101.140.196
+94.101.176.219
+94.101.177.8
+94.101.177.34
+94.101.177.39
+94.101.178.79
+94.101.179.19
+94.101.179.98
+94.101.179.105
+94.101.180.19
+94.101.180.39
+94.101.180.41
+94.101.184.158
+94.101.184.190
+94.101.184.222
+94.101.184.254
+94.101.185.65
+94.101.185.73
+94.101.185.75
+94.101.185.151
+94.101.186.22
+94.101.186.40
+94.101.186.107
+94.101.186.138
+94.101.186.151
+94.101.187.89
+94.101.187.195
+94.101.190.208
+94.101.190.209
+94.182.17.202
+94.182.17.205
+94.182.17.206
+94.182.17.214
+94.182.18.246
+94.182.20.10
+94.182.28.3
+94.182.28.56
+94.182.37.50
+94.182.40.34
+94.182.40.35
+94.182.40.70
+94.182.40.78
+94.182.42.194
+94.182.44.54
+94.182.50.77
+94.182.83.197
+94.182.83.200
+94.182.83.201
+94.182.83.202
+94.182.83.205
+94.182.83.206
+94.182.83.209
+94.182.83.210
+94.182.83.211
+94.182.83.212
+94.182.83.214
+94.182.83.216
+94.182.83.219
+94.182.83.233
+94.182.83.234
+94.182.83.235
+94.182.83.236
+94.182.83.237
+94.182.83.238
+94.182.83.246
+94.182.83.247
+94.182.83.248
+94.182.83.252
+94.182.84.172
+94.182.85.227
+94.182.85.231
+94.182.85.232
+94.182.85.237
+94.182.85.244
+94.182.85.250
+94.182.85.252
+94.182.86.187
+94.182.86.190
+94.182.87.209
+94.182.87.210
+94.182.87.211
+94.182.87.212
+94.182.87.214
+94.182.87.215
+94.182.87.216
+94.182.87.217
+94.182.87.218
+94.182.87.219
+94.182.87.220
+94.182.87.222
+94.182.88.18
+94.182.88.20
+94.182.88.21
+94.182.88.22
+94.182.88.116
+94.182.88.120
+94.182.89.41
+94.182.89.107
+94.182.89.131
+94.182.89.132
+94.182.89.133
+94.182.89.135
+94.182.89.136
+94.182.89.137
+94.182.89.138
+94.182.89.139
+94.182.89.142
+94.182.89.143
+94.182.89.145
+94.182.89.146
+94.182.89.147
+94.182.89.148
+94.182.89.150
+94.182.89.152
+94.182.89.154
+94.182.89.155
+94.182.89.156
+94.182.89.157
+94.182.89.159
+94.182.89.161
+94.182.89.163
+94.182.89.167
+94.182.89.169
+94.182.89.170
+94.182.89.174
+94.182.89.175
+94.182.89.179
+94.182.89.182
+94.182.89.224
+94.182.89.227
+94.182.89.235
+94.182.89.236
+94.182.89.237
+94.182.89.247
+94.182.90.18
+94.182.90.19
+94.182.90.20
+94.182.90.21
+94.182.90.66
+94.182.90.149
+94.182.90.170
+94.182.90.200
+94.182.90.210
+94.182.90.213
+94.182.90.216
+94.182.90.217
+94.182.91.114
+94.182.91.126
+94.182.91.130
+94.182.91.133
+94.182.91.134
+94.182.92.19
+94.182.92.57
+94.182.92.80
+94.182.92.165
+94.182.93.45
+94.182.93.133
+94.182.94.5
+94.182.94.67
+94.182.94.75
+94.182.94.121
+94.182.94.170
+94.182.94.217
+94.182.95.2
+94.182.95.3
+94.182.95.4
+94.182.95.6
+94.182.95.8
+94.182.95.246
+94.182.97.45
+94.182.102.102
+94.182.102.200
+94.182.104.11
+94.182.104.12
+94.182.104.13
+94.182.104.14
+94.182.105.213
+94.182.105.215
+94.182.107.227
+94.182.108.98
+94.182.108.150
+94.182.110.234
+94.182.110.235
+94.182.110.236
+94.182.110.237
+94.182.110.238
+94.182.113.117
+94.182.115.130
+94.182.115.173
+94.182.128.123
+94.182.128.124
+94.182.129.5
+94.182.129.114
+94.182.129.121
+94.182.130.2
+94.182.130.91
+94.182.130.93
+94.182.133.6
+94.182.133.36
+94.182.133.70
+94.182.133.73
+94.182.133.130
+94.182.133.254
+94.182.135.77
+94.182.135.254
+94.182.136.19
+94.182.136.39
+94.182.136.45
+94.182.136.50
+94.182.136.51
+94.182.136.106
+94.182.138.37
+94.182.140.18
+94.182.140.19
+94.182.140.20
+94.182.140.21
+94.182.140.22
+94.182.142.40
+94.182.142.41
+94.182.142.42
+94.182.142.43
+94.182.142.45
+94.182.142.48
+94.182.142.49
+94.182.142.50
+94.182.142.54
+94.182.142.152
+94.182.142.176
+94.182.142.177
+94.182.142.201
+94.182.142.205
+94.182.142.216
+94.182.142.248
+94.182.146.2
+94.182.146.116
+94.182.146.191
+94.182.146.252
+94.182.147.138
+94.182.150.180
+94.182.150.181
+94.182.151.14
+94.182.153.4
+94.182.153.26
+94.182.153.30
+94.182.153.34
+94.182.153.38
+94.182.153.78
+94.182.153.99
+94.182.153.100
+94.182.153.164
+94.182.153.169
+94.182.153.170
+94.182.153.173
+94.182.153.174
+94.182.153.175
+94.182.153.197
+94.182.154.12
+94.182.154.20
+94.182.154.22
+94.182.154.67
+94.182.154.68
+94.182.154.69
+94.182.154.71
+94.182.154.105
+94.182.154.111
+94.182.154.201
+94.182.154.220
+94.182.154.246
+94.182.154.247
+94.182.154.251
+94.182.155.10
+94.182.155.111
+94.182.155.121
+94.182.156.91
+94.182.156.118
+94.182.156.122
+94.182.156.187
+94.182.156.220
+94.182.157.181
+94.182.157.185
+94.182.157.187
+94.182.159.34
+94.182.159.35
+94.182.159.36
+94.182.159.37
+94.182.159.38
+94.182.159.41
+94.182.159.51
+94.182.159.55
+94.182.159.56
+94.182.169.52
+94.182.169.120
+94.182.169.124
+94.182.170.219
+94.182.171.83
+94.182.171.85
+94.182.171.94
+94.182.172.17
+94.182.172.18
+94.182.172.21
+94.182.172.36
+94.182.172.46
+94.182.172.47
+94.182.172.48
+94.182.172.49
+94.182.172.51
+94.182.172.52
+94.182.172.53
+94.182.172.194
+94.182.172.196
+94.182.172.197
+94.182.172.198
+94.182.172.200
+94.182.172.203
+94.182.172.204
+94.182.172.206
+94.182.172.209
+94.182.172.210
+94.182.172.211
+94.182.172.212
+94.182.172.213
+94.182.172.216
+94.182.172.218
+94.182.172.219
+94.182.172.251
+94.182.172.254
+94.182.173.82
+94.182.173.189
+94.182.174.43
+94.182.174.165
+94.182.174.172
+94.182.174.173
+94.182.175.2
+94.182.175.4
+94.182.175.5
+94.182.175.6
+94.182.175.10
+94.182.175.11
+94.182.175.12
+94.182.175.14
+94.182.175.15
+94.182.175.17
+94.182.175.20
+94.182.175.35
+94.182.175.38
+94.182.175.44
+94.182.175.50
+94.182.175.53
+94.182.175.55
+94.182.175.56
+94.182.176.184
+94.182.176.188
+94.182.177.43
+94.182.177.67
+94.182.177.68
+94.182.177.70
+94.182.177.72
+94.182.177.73
+94.182.177.80
+94.182.177.81
+94.182.177.82
+94.182.178.50
+94.182.178.52
+94.182.178.53
+94.182.178.54
+94.182.178.55
+94.182.178.71
+94.182.178.73
+94.182.178.75
+94.182.178.80
+94.182.178.81
+94.182.178.83
+94.182.178.85
+94.182.178.88
+94.182.178.91
+94.182.178.92
+94.182.178.93
+94.182.178.94
+94.182.178.95
+94.182.178.97
+94.182.178.98
+94.182.178.100
+94.182.178.107
+94.182.178.109
+94.182.178.110
+94.182.178.111
+94.182.178.112
+94.182.178.113
+94.182.178.114
+94.182.178.115
+94.182.178.116
+94.182.178.117
+94.182.178.118
+94.182.178.119
+94.182.178.120
+94.182.178.121
+94.182.178.122
+94.182.178.132
+94.182.178.233
+94.182.179.232
+94.182.180.140
+94.182.181.50
+94.182.181.222
+94.182.182.98
+94.182.183.211
+94.182.184.190
+94.182.185.95
+94.182.185.97
+94.182.185.126
+94.182.185.226
+94.182.185.227
+94.182.186.79
+94.182.186.231
+94.182.186.232
+94.182.186.250
+94.182.187.148
+94.182.187.149
+94.182.190.229
+94.182.190.245
+94.182.192.178
+94.182.195.42
+94.182.195.54
+94.182.195.107
+94.182.195.158
+94.182.195.164
+94.182.195.182
+94.182.195.183
+94.182.195.188
+94.182.195.194
+94.182.195.218
+94.182.195.223
+94.182.195.225
+94.182.195.231
+94.182.195.243
+94.182.195.247
+94.182.196.187
+94.182.198.62
+94.182.198.146
+94.182.199.222
+94.182.202.78
+94.182.208.45
+94.182.208.46
+94.182.209.58
+94.182.209.66
+94.182.209.70
+94.182.209.71
+94.182.214.34
+94.182.214.182
+94.182.215.6
+94.182.215.72
+94.182.215.75
+94.182.215.90
+94.182.227.5
+94.182.227.8
+94.182.227.10
+94.182.227.19
+94.182.227.34
+94.182.227.37
+94.182.227.38
+94.182.227.40
+94.182.227.42
+94.182.227.56
+94.182.227.61
+94.182.227.80
+94.182.227.83
+94.182.227.85
+94.182.227.96
+94.182.227.99
+94.182.227.103
+94.182.227.120
+94.182.227.121
+94.182.227.131
+94.182.227.134
+94.182.227.164
+94.182.227.165
+94.182.227.166
+94.182.227.167
+94.182.227.170
+94.182.227.181
+94.182.227.194
+94.182.227.195
+94.182.227.200
+94.182.227.209
+94.182.227.219
+94.182.227.225
+94.182.227.229
+94.182.227.237
+94.182.227.238
+94.182.227.241
+94.182.227.242
+94.182.227.246
+94.182.227.247
+94.182.242.13
+94.182.249.11
+94.182.250.30
+94.182.251.16
+94.182.255.154
+94.183.0.19
+94.183.2.164
+94.183.3.131
+94.183.3.199
+94.183.3.233
+94.183.8.70
+94.183.10.192
+94.183.10.193
+94.183.12.86
+94.183.14.129
+94.183.14.154
+94.183.17.153
+94.183.25.223
+94.183.26.90
+94.183.27.1
+94.183.29.64
+94.183.30.17
+94.183.31.47
+94.183.32.45
+94.183.33.193
+94.183.36.82
+94.183.42.239
+94.183.47.239
+94.183.51.96
+94.183.51.149
+94.183.53.16
+94.183.53.17
+94.183.53.18
+94.183.53.19
+94.183.57.172
+94.183.58.73
+94.183.59.36
+94.183.62.83
+94.183.62.232
+94.183.84.184
+94.183.84.227
+94.183.85.177
+94.183.88.99
+94.183.90.243
+94.183.100.148
+94.183.108.245
+94.183.110.118
+94.183.117.238
+94.183.118.64
+94.183.119.8
+94.183.122.41
+94.183.123.216
+94.183.124.28
+94.183.124.97
+94.183.124.129
+94.183.125.86
+94.183.125.191
+94.183.126.155
+94.183.127.185
+94.183.128.221
+94.183.130.253
+94.183.132.106
+94.183.132.251
+94.183.137.113
+94.183.141.177
+94.183.146.170
+94.183.146.198
+94.183.146.205
+94.183.150.71
+94.183.150.80
+94.183.150.85
+94.183.150.86
+94.183.150.122
+94.183.156.141
+94.183.157.7
+94.183.157.188
+94.183.160.175
+94.183.160.239
+94.183.162.8
+94.183.163.63
+94.183.163.90
+94.183.163.132
+94.183.163.180
+94.183.163.181
+94.183.172.3
+94.183.172.103
+94.183.172.253
+94.183.175.24
+94.183.175.25
+94.183.176.60
+94.183.176.65
+94.183.177.100
+94.184.9.31
+94.184.10.82
+94.184.16.6
+94.184.17.197
+94.184.22.5
+94.184.22.62
+94.184.29.217
+94.184.29.219
+94.184.29.220
+94.184.89.2
+94.184.120.67
+94.184.141.137
+94.184.141.141
+94.184.176.5
+94.184.176.6
+94.184.176.201
+94.184.224.196
+94.184.225.25
+94.184.236.20
+94.184.236.32
+94.184.236.50
+94.184.239.20
+94.199.0.166
+94.232.168.26
+94.232.168.103
+94.232.168.105
+94.232.168.151
+94.232.168.211
+94.232.170.65
+94.232.170.66
+94.232.170.67
+94.232.170.68
+94.232.171.86
+94.232.171.140
+94.232.171.141
+94.232.171.150
+94.232.171.151
+94.232.172.2
+94.232.172.96
+94.232.172.104
+94.232.172.135
+94.232.173.4
+94.232.173.28
+94.232.173.52
+94.232.173.69
+94.232.173.70
+94.232.173.71
+94.232.173.100
+94.232.173.114
+94.232.173.128
+94.232.173.137
+94.232.173.148
+94.232.173.150
+94.232.173.153
+94.232.173.154
+94.232.173.155
+94.232.173.199
+94.232.173.229
+94.232.174.1
+94.232.174.28
+94.232.174.35
+94.232.174.84
+94.232.174.176
+94.232.174.181
+94.232.174.222
+94.232.174.247
+94.232.174.249
+94.232.174.250
+94.232.175.29
+94.232.175.32
+94.232.175.85
+94.232.175.194
+95.38.13.239
+95.38.24.138
+95.38.34.53
+95.38.40.169
+95.38.47.170
+95.38.47.171
+95.38.47.172
+95.38.47.174
+95.38.48.56
+95.38.60.141
+95.38.60.173
+95.38.60.185
+95.38.60.251
+95.38.65.161
+95.38.65.237
+95.38.72.30
+95.38.77.158
+95.38.86.17
+95.38.102.86
+95.38.102.117
+95.38.102.190
+95.38.103.189
+95.38.103.220
+95.38.103.221
+95.38.103.222
+95.38.125.44
+95.38.130.112
+95.38.130.131
+95.38.134.99
+95.38.135.150
+95.38.137.129
+95.38.138.3
+95.38.153.168
+95.38.155.35
+95.38.155.58
+95.38.201.199
+95.38.209.3
+95.38.245.135
+95.38.250.86
+95.80.141.218
+95.80.155.159
+95.80.164.5
+95.80.164.6
+95.80.164.10
+95.80.168.55
+95.80.173.169
+95.80.182.185
+95.80.184.15
+95.80.184.19
+95.80.184.180
+95.80.184.184
+95.80.185.180
+95.80.185.185
+95.130.56.37
+95.130.56.40
+95.130.245.66
+95.142.224.142
+95.142.226.4
+95.142.226.26
+95.142.227.6
+95.142.227.7
+95.142.227.50
+95.142.227.178
+95.142.227.195
+95.142.227.206
+95.142.227.227
+95.142.227.230
+95.142.227.231
+95.142.231.137
+95.142.235.40
+95.142.237.3
+95.142.237.4
+95.142.237.20
+95.142.237.52
+95.142.237.82
+95.142.237.190
+95.142.237.254
+95.156.252.219
+95.156.253.8
+95.156.253.9
+95.156.253.10
+95.156.253.11
+95.156.253.12
+95.156.253.13
+95.156.253.14
+95.156.253.17
+95.156.253.18
+95.156.253.20
+95.156.253.21
+95.156.253.24
+95.156.253.27
+95.156.253.30
+95.156.253.31
+95.156.253.33
+95.156.253.36
+95.156.253.38
+95.156.253.39
+95.156.253.43
+95.156.253.44
+95.156.253.45
+95.156.253.49
+95.156.253.52
+95.156.253.53
+95.156.253.54
+95.156.253.55
+95.156.253.59
+95.156.253.61
+95.156.253.99
+95.156.253.100
+95.156.253.174
+95.156.253.177
+95.156.254.227
+95.156.254.228
+95.156.254.229
+95.156.254.234
+95.156.254.235
+95.156.254.236
+95.215.59.90
+95.215.59.121
+95.215.59.147
+95.215.59.173
+95.215.59.189
+95.215.59.195
+95.215.173.178
+95.215.173.180
+95.216.224.204
+95.216.224.214
+95.216.224.227
+95.216.224.232
+95.216.224.245
+102.22.27.125
+102.22.31.74
+102.22.72.46
+102.22.80.182
+102.22.80.183
+102.22.80.250
+102.22.81.11
+102.22.81.13
+102.22.81.19
+102.22.81.20
+102.22.81.34
+102.22.81.37
+102.22.81.41
+102.22.81.42
+102.22.81.45
+102.22.81.52
+102.22.81.74
+102.22.81.75
+102.22.81.85
+102.22.81.99
+102.22.81.110
+102.22.81.122
+102.22.81.140
+102.22.81.141
+102.22.81.151
+102.22.81.171
+102.22.81.175
+102.22.81.193
+102.22.81.195
+102.22.81.201
+102.22.81.211
+102.22.81.212
+102.22.81.213
+102.22.81.225
+102.22.81.249
+102.22.81.254
+102.22.82.4
+102.22.82.5
+102.22.82.17
+102.22.82.45
+102.22.82.53
+102.22.82.56
+102.22.82.59
+102.22.82.70
+102.22.82.71
+102.22.82.94
+102.22.82.95
+102.22.82.129
+102.22.82.214
+102.22.82.221
+102.22.82.227
+102.22.82.233
+102.22.82.242
+102.22.83.12
+102.22.83.14
+102.22.83.46
+102.22.83.71
+102.22.83.72
+102.22.83.78
+102.22.83.102
+102.22.83.103
+102.22.83.113
+102.22.83.114
+102.22.83.139
+102.22.83.142
+102.22.83.149
+102.22.83.155
+102.22.83.207
+102.22.108.2
+102.22.108.13
+102.22.108.14
+102.22.108.20
+102.22.108.21
+102.22.108.22
+102.22.108.23
+102.22.108.25
+102.22.109.1
+102.22.109.225
+102.22.124.69
+102.22.124.70
+102.22.127.147
+102.22.195.106
+102.22.195.246
+102.22.207.4
+102.22.207.42
+102.22.237.8
+102.22.237.9
+102.22.247.162
+102.22.254.116
+102.22.254.232
+102.23.5.166
+102.23.7.83
+102.23.121.15
+102.23.121.16
+102.23.122.120
+102.23.122.251
+102.23.123.90
+102.23.123.91
+102.23.132.42
+102.23.133.10
+102.23.133.12
+102.23.136.215
+102.23.140.2
+102.23.140.42
+102.23.163.244
+102.23.168.24
+102.23.196.253
+102.23.198.210
+102.23.208.4
+102.23.208.30
+102.23.226.27
+102.23.226.70
+102.23.226.71
+102.23.230.23
+102.23.231.69
+102.23.231.82
+102.23.231.84
+102.23.231.87
+102.23.231.172
+102.23.231.253
+102.23.237.76
+102.23.252.83
+102.37.16.226
+102.37.21.224
+102.37.109.39
+102.37.113.11
+102.37.113.89
+102.37.116.18
+102.37.118.18
+102.37.142.149
+102.37.144.57
+102.37.145.202
+102.37.158.250
+102.37.176.63
+102.37.213.24
+102.37.214.202
+102.37.216.211
+102.37.217.70
+102.37.217.174
+102.37.218.157
+102.37.220.188
+102.133.128.244
+102.133.129.203
+102.133.132.86
+102.133.132.90
+102.133.136.51
+102.133.136.53
+102.133.136.58
+102.133.136.65
+102.133.138.26
+102.133.138.30
+102.133.138.66
+102.133.139.5
+102.133.139.31
+102.133.139.152
+102.133.139.153
+102.133.139.154
+102.133.146.143
+102.133.160.77
+102.133.171.26
+102.133.227.168
+102.133.235.79
+102.215.242.87
+103.130.144.1
+103.130.144.2
+103.130.144.3
+103.215.222.11
+103.215.222.12
+103.215.222.33
+103.215.222.44
+103.215.222.55
+103.215.222.66
+103.215.222.102
+103.215.222.103
+103.215.222.104
+103.215.222.105
+103.215.222.106
+103.215.222.107
+103.215.222.108
+103.215.222.109
+103.215.222.112
+103.215.222.113
+103.215.222.114
+103.215.222.115
+103.215.222.116
+103.215.222.118
+103.215.222.119
+103.215.222.122
+103.215.222.124
+103.215.222.126
+103.215.222.127
+103.215.222.128
+103.215.222.129
+103.215.222.130
+103.215.222.131
+103.215.222.132
+103.215.222.133
+103.215.222.135
+103.215.222.136
+103.215.222.140
+103.215.222.141
+103.215.222.142
+103.215.222.143
+103.215.222.144
+103.215.222.145
+103.215.222.146
+103.215.222.147
+103.215.222.149
+103.215.222.150
+103.215.222.151
+103.215.222.153
+103.215.222.154
+103.215.222.157
+103.215.223.4
+103.215.223.9
+103.215.223.10
+103.215.223.11
+103.215.223.14
+103.215.223.19
+103.215.223.26
+103.215.223.40
+103.215.223.42
+103.215.223.58
+103.215.223.166
+103.215.223.214
+103.215.223.240
+103.215.223.241
+103.216.60.29
+103.216.60.37
+103.216.60.40
+103.216.60.46
+103.216.61.154
+103.216.62.68
+103.216.62.102
+109.72.192.37
+109.72.192.40
+109.72.197.38
+109.95.61.174
+109.95.61.207
+109.95.61.239
+109.95.61.249
+109.95.61.251
+109.95.67.210
+109.95.68.12
+109.95.68.14
+109.95.68.16
+109.95.68.21
+109.95.68.29
+109.95.68.32
+109.95.70.246
+109.95.71.29
+109.109.32.0
+109.109.32.1
+109.109.32.4
+109.109.32.5
+109.109.32.6
+109.109.32.7
+109.109.32.8
+109.109.32.10
+109.109.32.11
+109.109.32.13
+109.109.32.14
+109.109.32.15
+109.109.32.16
+109.109.32.17
+109.109.32.18
+109.109.32.19
+109.109.32.20
+109.109.32.21
+109.109.32.22
+109.109.32.23
+109.109.32.24
+109.109.32.25
+109.109.32.26
+109.109.32.27
+109.109.32.28
+109.109.32.29
+109.109.32.30
+109.109.32.31
+109.109.32.44
+109.109.32.45
+109.109.32.47
+109.109.32.56
+109.109.32.58
+109.109.32.59
+109.109.32.60
+109.109.32.61
+109.109.32.62
+109.109.32.63
+109.109.32.64
+109.109.32.65
+109.109.32.66
+109.109.32.67
+109.109.32.68
+109.109.32.69
+109.109.32.70
+109.109.32.71
+109.109.32.72
+109.109.32.73
+109.109.32.74
+109.109.32.75
+109.109.32.76
+109.109.32.77
+109.109.32.78
+109.109.32.79
+109.109.32.88
+109.109.32.90
+109.109.32.91
+109.109.32.92
+109.109.32.93
+109.109.32.94
+109.109.32.95
+109.109.32.96
+109.109.32.99
+109.109.32.100
+109.109.32.101
+109.109.32.102
+109.109.32.104
+109.109.32.105
+109.109.32.106
+109.109.32.107
+109.109.32.108
+109.109.32.109
+109.109.32.110
+109.109.32.111
+109.109.32.112
+109.109.32.113
+109.109.32.114
+109.109.32.115
+109.109.32.116
+109.109.32.117
+109.109.32.118
+109.109.32.119
+109.109.32.120
+109.109.32.121
+109.109.32.122
+109.109.32.123
+109.109.32.124
+109.109.32.125
+109.109.32.126
+109.109.32.152
+109.109.32.153
+109.109.32.154
+109.109.32.155
+109.109.32.156
+109.109.32.158
+109.109.32.159
+109.109.32.216
+109.109.32.218
+109.109.32.219
+109.109.32.220
+109.109.32.221
+109.109.32.222
+109.109.32.223
+109.109.34.72
+109.109.34.73
+109.109.34.74
+109.109.34.75
+109.109.34.77
+109.109.34.78
+109.109.34.79
+109.109.34.80
+109.109.34.81
+109.109.34.82
+109.109.34.83
+109.109.34.84
+109.109.34.86
+109.109.34.87
+109.109.34.88
+109.109.34.89
+109.109.34.90
+109.109.34.91
+109.109.34.92
+109.109.34.93
+109.109.34.94
+109.109.34.95
+109.109.34.96
+109.109.34.98
+109.109.34.99
+109.109.34.100
+109.109.34.101
+109.109.34.102
+109.109.34.103
+109.109.34.104
+109.109.34.105
+109.109.34.106
+109.109.34.107
+109.109.34.108
+109.109.34.109
+109.109.34.110
+109.109.34.111
+109.109.34.112
+109.109.34.113
+109.109.34.114
+109.109.34.115
+109.109.34.116
+109.109.34.117
+109.109.34.118
+109.109.34.119
+109.109.34.120
+109.109.34.121
+109.109.34.122
+109.109.34.124
+109.109.34.125
+109.109.34.127
+109.109.34.128
+109.109.34.129
+109.109.34.130
+109.109.34.131
+109.109.34.132
+109.109.34.133
+109.109.34.134
+109.109.34.135
+109.109.34.136
+109.109.34.137
+109.109.34.138
+109.109.34.140
+109.109.34.141
+109.109.34.142
+109.109.34.143
+109.109.34.144
+109.109.34.145
+109.109.34.146
+109.109.34.147
+109.109.34.148
+109.109.34.149
+109.109.34.150
+109.109.34.151
+109.109.34.152
+109.109.34.153
+109.109.34.154
+109.109.34.155
+109.109.34.156
+109.109.34.157
+109.109.34.158
+109.109.34.159
+109.109.34.160
+109.109.34.161
+109.109.34.162
+109.109.34.163
+109.109.34.164
+109.109.34.165
+109.109.34.167
+109.109.34.168
+109.109.34.169
+109.109.34.170
+109.109.34.171
+109.109.34.172
+109.109.34.173
+109.109.34.174
+109.109.34.175
+109.109.34.176
+109.109.34.177
+109.109.34.178
+109.109.34.179
+109.109.34.180
+109.109.34.181
+109.109.34.182
+109.109.34.184
+109.109.34.186
+109.109.34.187
+109.109.34.189
+109.109.34.191
+109.109.34.192
+109.109.34.193
+109.109.34.194
+109.109.34.195
+109.109.34.196
+109.109.34.197
+109.109.34.198
+109.109.34.200
+109.109.34.201
+109.109.34.202
+109.109.34.203
+109.109.34.204
+109.109.34.205
+109.109.34.206
+109.109.34.207
+109.109.34.208
+109.109.34.209
+109.109.34.210
+109.109.34.211
+109.109.34.212
+109.109.34.214
+109.109.34.215
+109.109.34.216
+109.109.34.217
+109.109.34.219
+109.109.34.220
+109.109.34.221
+109.109.34.222
+109.109.34.223
+109.109.34.224
+109.109.34.225
+109.109.34.226
+109.109.34.227
+109.109.34.228
+109.109.34.229
+109.109.34.230
+109.109.34.232
+109.109.34.233
+109.109.34.235
+109.109.34.236
+109.109.34.238
+109.109.34.239
+109.109.34.240
+109.109.34.241
+109.109.34.242
+109.109.34.243
+109.109.34.244
+109.109.34.245
+109.109.34.246
+109.109.34.247
+109.109.34.248
+109.109.34.250
+109.109.34.251
+109.109.34.252
+109.109.34.253
+109.109.34.254
+109.109.35.0
+109.109.35.1
+109.109.35.2
+109.109.35.3
+109.109.35.4
+109.109.35.5
+109.109.35.6
+109.109.35.7
+109.109.35.8
+109.109.35.9
+109.109.35.10
+109.109.35.11
+109.109.35.13
+109.109.35.14
+109.109.35.15
+109.109.35.16
+109.109.35.17
+109.109.35.18
+109.109.35.19
+109.109.35.20
+109.109.35.21
+109.109.35.22
+109.109.35.23
+109.109.35.24
+109.109.35.25
+109.109.35.26
+109.109.35.27
+109.109.35.28
+109.109.35.29
+109.109.35.30
+109.109.35.31
+109.109.35.32
+109.109.35.33
+109.109.35.34
+109.109.35.35
+109.109.35.36
+109.109.35.37
+109.109.35.38
+109.109.35.39
+109.109.35.40
+109.109.35.41
+109.109.35.42
+109.109.35.43
+109.109.35.44
+109.109.35.45
+109.109.35.46
+109.109.35.47
+109.109.35.48
+109.109.35.49
+109.109.35.50
+109.109.35.51
+109.109.35.52
+109.109.35.53
+109.109.35.54
+109.109.35.55
+109.109.35.56
+109.109.35.57
+109.109.35.59
+109.109.35.60
+109.109.35.61
+109.109.35.62
+109.109.35.63
+109.109.35.64
+109.109.35.65
+109.109.35.66
+109.109.35.67
+109.109.35.69
+109.109.35.70
+109.109.35.71
+109.109.35.72
+109.109.35.73
+109.109.35.76
+109.109.35.77
+109.109.35.78
+109.109.35.79
+109.109.35.80
+109.109.35.81
+109.109.35.82
+109.109.35.83
+109.109.35.84
+109.109.35.85
+109.109.35.86
+109.109.35.88
+109.109.35.89
+109.109.35.90
+109.109.35.91
+109.109.35.92
+109.109.35.93
+109.109.35.94
+109.109.35.95
+109.109.35.96
+109.109.35.97
+109.109.35.98
+109.109.35.99
+109.109.35.100
+109.109.35.101
+109.109.35.102
+109.109.35.103
+109.109.35.104
+109.109.35.105
+109.109.35.106
+109.109.35.108
+109.109.35.109
+109.109.35.110
+109.109.35.111
+109.109.35.112
+109.109.35.113
+109.109.35.114
+109.109.35.115
+109.109.35.116
+109.109.35.117
+109.109.35.118
+109.109.35.119
+109.109.35.120
+109.109.35.121
+109.109.35.122
+109.109.35.123
+109.109.35.124
+109.109.35.126
+109.109.35.127
+109.109.42.73
+109.109.43.128
+109.109.43.130
+109.109.43.131
+109.109.43.133
+109.109.43.134
+109.109.43.135
+109.109.43.138
+109.109.43.139
+109.109.43.140
+109.109.43.143
+109.109.43.144
+109.109.43.151
+109.109.43.155
+109.109.43.162
+109.109.43.164
+109.109.43.168
+109.109.43.172
+109.109.43.173
+109.109.43.174
+109.109.43.175
+109.109.43.177
+109.109.43.180
+109.109.43.183
+109.109.43.185
+109.109.43.188
+109.109.43.191
+109.109.43.193
+109.109.43.195
+109.109.43.196
+109.109.43.200
+109.109.43.201
+109.109.43.206
+109.109.43.209
+109.109.43.212
+109.109.43.213
+109.109.43.215
+109.109.43.220
+109.109.43.221
+109.109.43.223
+109.109.43.229
+109.109.43.230
+109.109.43.232
+109.109.43.233
+109.109.43.235
+109.109.43.236
+109.109.43.241
+109.109.43.242
+109.109.43.243
+109.109.43.247
+109.109.43.250
+109.109.43.255
+109.109.45.0
+109.109.45.1
+109.109.45.2
+109.109.45.3
+109.109.45.4
+109.109.45.5
+109.109.45.6
+109.109.45.7
+109.109.45.8
+109.109.45.9
+109.109.45.10
+109.109.45.11
+109.109.45.12
+109.109.45.13
+109.109.45.14
+109.109.45.15
+109.109.45.16
+109.109.45.17
+109.109.45.18
+109.109.45.19
+109.109.45.20
+109.109.45.22
+109.109.45.23
+109.109.45.24
+109.109.45.25
+109.109.45.26
+109.109.45.27
+109.109.45.28
+109.109.45.29
+109.109.45.30
+109.109.45.31
+109.109.45.40
+109.109.45.41
+109.109.45.42
+109.109.45.43
+109.109.45.44
+109.109.45.45
+109.109.45.46
+109.109.45.47
+109.109.45.48
+109.109.45.49
+109.109.45.50
+109.109.45.51
+109.109.45.52
+109.109.45.54
+109.109.45.55
+109.109.45.56
+109.109.45.57
+109.109.45.58
+109.109.45.59
+109.109.45.60
+109.109.45.61
+109.109.45.62
+109.109.45.63
+109.109.45.64
+109.109.45.65
+109.109.45.66
+109.109.45.67
+109.109.45.68
+109.109.45.70
+109.109.45.71
+109.109.45.72
+109.109.45.73
+109.109.45.74
+109.109.45.75
+109.109.45.76
+109.109.45.77
+109.109.45.78
+109.109.45.79
+109.109.45.80
+109.109.45.81
+109.109.45.84
+109.109.45.87
+109.109.45.88
+109.109.45.89
+109.109.45.90
+109.109.45.91
+109.109.45.92
+109.109.45.93
+109.109.45.94
+109.109.45.95
+109.109.45.96
+109.109.45.98
+109.109.45.99
+109.109.45.100
+109.109.45.101
+109.109.45.102
+109.109.45.103
+109.109.45.104
+109.109.45.105
+109.109.45.106
+109.109.45.107
+109.109.45.108
+109.109.45.109
+109.109.45.110
+109.109.45.111
+109.109.45.112
+109.109.45.113
+109.109.45.115
+109.109.45.116
+109.109.45.117
+109.109.45.119
+109.109.45.120
+109.109.45.121
+109.109.45.123
+109.109.45.124
+109.109.45.125
+109.109.45.126
+109.109.45.127
+109.109.47.0
+109.109.47.2
+109.109.47.3
+109.109.47.4
+109.109.47.5
+109.109.47.8
+109.109.47.10
+109.109.47.13
+109.109.47.16
+109.109.47.17
+109.109.47.18
+109.109.47.19
+109.109.47.23
+109.109.47.25
+109.109.47.27
+109.109.47.29
+109.109.47.32
+109.109.47.34
+109.109.47.35
+109.109.47.43
+109.109.47.50
+109.109.47.51
+109.109.47.52
+109.109.47.54
+109.109.47.57
+109.109.47.59
+109.109.47.62
+109.109.47.63
+109.109.47.64
+109.109.47.65
+109.109.47.67
+109.109.47.70
+109.109.47.72
+109.109.47.73
+109.109.47.74
+109.109.47.76
+109.109.47.78
+109.109.47.80
+109.109.47.81
+109.109.47.82
+109.109.47.83
+109.109.47.84
+109.109.47.85
+109.109.47.86
+109.109.47.87
+109.109.47.90
+109.109.47.91
+109.109.47.92
+109.109.47.94
+109.109.47.95
+109.109.47.97
+109.109.47.101
+109.109.47.102
+109.109.47.103
+109.109.47.104
+109.109.47.106
+109.109.47.107
+109.109.47.108
+109.109.47.109
+109.109.47.113
+109.109.47.115
+109.109.47.116
+109.109.47.117
+109.109.47.119
+109.109.47.120
+109.109.47.121
+109.109.47.122
+109.109.47.123
+109.109.47.124
+109.109.47.125
+109.109.47.126
+109.109.51.111
+109.109.51.178
+109.109.52.111
+109.109.54.0
+109.109.54.4
+109.109.54.7
+109.109.54.11
+109.109.54.12
+109.109.54.13
+109.109.54.14
+109.109.54.20
+109.109.54.22
+109.109.54.23
+109.109.54.34
+109.109.54.35
+109.109.54.36
+109.109.54.37
+109.109.54.40
+109.109.54.41
+109.109.54.42
+109.109.54.45
+109.109.54.49
+109.109.54.52
+109.109.54.56
+109.109.54.57
+109.109.54.59
+109.109.54.61
+109.109.54.63
+109.109.54.64
+109.109.54.65
+109.109.54.66
+109.109.54.67
+109.109.54.70
+109.109.54.71
+109.109.54.72
+109.109.54.73
+109.109.54.74
+109.109.54.75
+109.109.54.76
+109.109.54.78
+109.109.54.79
+109.109.54.80
+109.109.54.81
+109.109.54.82
+109.109.54.85
+109.109.54.88
+109.109.54.90
+109.109.54.95
+109.109.54.96
+109.109.54.99
+109.109.54.100
+109.109.54.102
+109.109.54.103
+109.109.54.105
+109.109.54.106
+109.109.54.107
+109.109.54.110
+109.109.54.111
+109.109.54.112
+109.109.54.121
+109.109.54.123
+109.109.54.124
+109.109.54.125
+109.109.54.127
+109.109.54.136
+109.109.54.137
+109.109.54.138
+109.109.54.139
+109.109.54.140
+109.109.54.143
+109.109.54.144
+109.109.54.145
+109.109.54.147
+109.109.54.149
+109.109.54.151
+109.109.54.154
+109.109.54.157
+109.109.54.158
+109.109.54.160
+109.109.54.161
+109.109.54.162
+109.109.54.163
+109.109.54.165
+109.109.54.167
+109.109.54.170
+109.109.54.172
+109.109.54.175
+109.109.54.176
+109.109.54.179
+109.109.54.180
+109.109.54.181
+109.109.54.182
+109.109.54.184
+109.109.54.185
+109.109.54.186
+109.109.54.188
+109.109.54.190
+109.109.54.191
+109.109.54.192
+109.109.54.193
+109.109.54.194
+109.109.54.195
+109.109.54.196
+109.109.54.197
+109.109.54.201
+109.109.54.202
+109.109.54.203
+109.109.54.204
+109.109.54.205
+109.109.54.206
+109.109.54.208
+109.109.54.210
+109.109.54.211
+109.109.54.213
+109.109.54.214
+109.109.54.215
+109.109.54.216
+109.109.54.217
+109.109.54.218
+109.109.54.220
+109.109.54.221
+109.109.54.222
+109.109.54.223
+109.109.54.224
+109.109.54.225
+109.109.54.226
+109.109.54.227
+109.109.54.228
+109.109.54.229
+109.109.54.230
+109.109.54.231
+109.109.54.237
+109.109.54.238
+109.109.54.240
+109.109.54.241
+109.109.54.242
+109.109.54.243
+109.109.54.244
+109.109.54.245
+109.109.54.246
+109.109.54.247
+109.109.54.248
+109.109.54.249
+109.109.54.250
+109.109.54.251
+109.109.54.252
+109.109.54.254
+109.109.54.255
+109.109.56.137
+109.109.58.0
+109.109.58.1
+109.109.58.2
+109.109.58.3
+109.109.58.4
+109.109.58.5
+109.109.58.6
+109.109.58.7
+109.109.58.9
+109.109.58.10
+109.109.58.11
+109.109.58.12
+109.109.58.13
+109.109.58.14
+109.109.58.15
+109.109.58.16
+109.109.58.17
+109.109.58.18
+109.109.58.19
+109.109.58.20
+109.109.58.21
+109.109.58.22
+109.109.58.23
+109.109.58.24
+109.109.58.25
+109.109.58.26
+109.109.58.27
+109.109.58.28
+109.109.58.29
+109.109.58.30
+109.109.58.31
+109.109.58.32
+109.109.58.33
+109.109.58.34
+109.109.58.35
+109.109.58.37
+109.109.58.38
+109.109.58.39
+109.109.58.40
+109.109.58.41
+109.109.58.42
+109.109.58.44
+109.109.58.45
+109.109.58.46
+109.109.58.47
+109.109.58.48
+109.109.58.49
+109.109.58.50
+109.109.58.51
+109.109.58.52
+109.109.58.53
+109.109.58.54
+109.109.58.55
+109.109.58.56
+109.109.58.57
+109.109.58.58
+109.109.58.59
+109.109.58.60
+109.109.58.61
+109.109.58.62
+109.109.58.63
+109.109.58.128
+109.109.58.129
+109.109.58.131
+109.109.58.132
+109.109.58.133
+109.109.58.134
+109.109.58.135
+109.109.58.136
+109.109.58.137
+109.109.58.138
+109.109.58.139
+109.109.58.140
+109.109.58.141
+109.109.58.142
+109.109.58.143
+109.109.58.160
+109.109.58.161
+109.109.58.162
+109.109.58.163
+109.109.58.164
+109.109.58.165
+109.109.58.168
+109.109.58.169
+109.109.58.170
+109.109.58.171
+109.109.58.172
+109.109.58.173
+109.109.58.174
+109.109.58.175
+109.109.59.0
+109.109.59.2
+109.109.59.3
+109.109.59.4
+109.109.59.5
+109.109.59.7
+109.109.59.32
+109.109.59.33
+109.109.59.37
+109.109.59.38
+109.109.59.39
+109.109.59.40
+109.109.59.41
+109.109.59.42
+109.109.59.43
+109.109.59.44
+109.109.59.45
+109.109.59.46
+109.109.59.47
+109.109.59.48
+109.109.59.49
+109.109.59.50
+109.109.59.51
+109.109.59.60
+109.109.59.61
+109.109.59.62
+109.109.59.63
+109.109.59.64
+109.109.59.65
+109.109.59.66
+109.109.59.67
+109.109.59.68
+109.109.59.69
+109.109.59.70
+109.109.59.71
+109.109.59.72
+109.109.59.73
+109.109.59.74
+109.109.59.75
+109.109.59.76
+109.109.59.78
+109.109.59.80
+109.109.59.81
+109.109.59.82
+109.109.59.83
+109.109.59.85
+109.109.59.87
+109.109.59.89
+109.109.59.90
+109.109.59.91
+109.109.59.92
+109.109.59.93
+109.109.59.94
+109.109.59.95
+109.109.59.96
+109.109.59.97
+109.109.59.98
+109.109.59.100
+109.109.59.101
+109.109.59.102
+109.109.59.103
+109.109.59.104
+109.109.59.105
+109.109.59.106
+109.109.59.107
+109.109.59.109
+109.109.59.110
+109.109.59.111
+109.109.59.112
+109.109.59.113
+109.109.59.114
+109.109.59.115
+109.109.59.116
+109.109.59.117
+109.109.59.118
+109.109.59.119
+109.109.59.120
+109.109.59.121
+109.109.59.122
+109.109.59.123
+109.109.59.124
+109.109.59.125
+109.109.59.126
+109.109.59.127
+109.109.60.0
+109.109.60.1
+109.109.60.2
+109.109.60.3
+109.109.60.4
+109.109.60.5
+109.109.60.6
+109.109.60.8
+109.109.60.10
+109.109.60.11
+109.109.60.12
+109.109.60.13
+109.109.60.14
+109.109.60.15
+109.109.60.17
+109.109.60.18
+109.109.60.19
+109.109.60.20
+109.109.60.21
+109.109.60.22
+109.109.60.27
+109.109.60.28
+109.109.60.29
+109.109.60.30
+109.109.60.33
+109.109.60.35
+109.109.60.37
+109.109.60.38
+109.109.60.41
+109.109.60.45
+109.109.60.47
+109.109.60.50
+109.109.60.52
+109.109.60.53
+109.109.60.55
+109.109.60.57
+109.109.60.58
+109.109.60.59
+109.109.60.60
+109.109.60.61
+109.109.60.62
+109.109.60.63
+109.109.60.64
+109.109.60.65
+109.109.60.66
+109.109.60.67
+109.109.60.68
+109.109.60.72
+109.109.60.76
+109.109.60.77
+109.109.60.79
+109.109.60.84
+109.109.60.85
+109.109.60.87
+109.109.60.88
+109.109.60.89
+109.109.60.92
+109.109.60.94
+109.109.60.96
+109.109.60.97
+109.109.60.103
+109.109.60.104
+109.109.60.106
+109.109.60.109
+109.109.60.110
+109.109.60.111
+109.109.60.112
+109.109.60.114
+109.109.60.117
+109.109.60.118
+109.109.60.120
+109.109.60.122
+109.109.60.123
+109.109.60.125
+109.109.60.126
+109.109.60.127
+109.109.60.128
+109.109.60.129
+109.109.60.130
+109.109.60.131
+109.109.60.132
+109.109.60.133
+109.109.60.134
+109.109.60.135
+109.109.60.136
+109.109.60.137
+109.109.60.138
+109.109.60.139
+109.109.60.140
+109.109.60.141
+109.109.60.142
+109.109.60.143
+109.109.60.144
+109.109.60.145
+109.109.60.146
+109.109.60.147
+109.109.60.148
+109.109.60.149
+109.109.60.152
+109.109.60.153
+109.109.60.154
+109.109.60.155
+109.109.60.156
+109.109.60.157
+109.109.60.158
+109.109.60.159
+109.109.60.160
+109.109.60.161
+109.109.60.162
+109.109.60.163
+109.109.60.164
+109.109.60.165
+109.109.60.166
+109.109.60.167
+109.109.60.168
+109.109.60.169
+109.109.60.170
+109.109.60.171
+109.109.60.172
+109.109.60.173
+109.109.60.174
+109.109.60.175
+109.109.60.177
+109.109.60.178
+109.109.60.179
+109.109.60.180
+109.109.60.181
+109.109.60.182
+109.109.60.183
+109.109.60.184
+109.109.60.185
+109.109.60.186
+109.109.60.187
+109.109.60.188
+109.109.60.189
+109.109.60.190
+109.109.60.191
+109.109.60.192
+109.109.60.193
+109.109.60.194
+109.109.60.195
+109.109.60.196
+109.109.60.197
+109.109.60.198
+109.109.60.199
+109.109.60.200
+109.109.60.201
+109.109.60.202
+109.109.60.203
+109.109.60.205
+109.109.60.207
+109.109.60.208
+109.109.60.209
+109.109.60.210
+109.109.60.211
+109.109.60.212
+109.109.60.213
+109.109.60.214
+109.109.60.215
+109.109.60.216
+109.109.60.217
+109.109.60.218
+109.109.60.219
+109.109.60.220
+109.109.60.221
+109.109.60.222
+109.109.60.223
+109.109.60.224
+109.109.60.225
+109.109.60.226
+109.109.60.227
+109.109.60.228
+109.109.60.229
+109.109.60.230
+109.109.60.231
+109.109.60.232
+109.109.60.233
+109.109.60.234
+109.109.60.235
+109.109.60.236
+109.109.60.237
+109.109.60.238
+109.109.60.239
+109.109.61.99
+109.109.61.192
+109.109.61.193
+109.109.61.194
+109.109.61.196
+109.109.61.197
+109.109.61.198
+109.109.61.199
+109.109.61.200
+109.109.61.201
+109.109.61.202
+109.109.61.203
+109.109.61.204
+109.109.61.205
+109.109.61.206
+109.109.61.207
+109.109.61.210
+109.109.61.211
+109.109.61.212
+109.109.61.213
+109.109.61.214
+109.109.61.215
+109.109.61.217
+109.109.61.219
+109.109.61.220
+109.109.61.221
+109.109.61.222
+109.109.61.223
+109.109.61.224
+109.109.61.225
+109.109.61.226
+109.109.61.227
+109.109.61.228
+109.109.61.229
+109.109.61.230
+109.109.61.231
+109.109.61.233
+109.109.61.234
+109.109.61.235
+109.109.61.236
+109.109.61.237
+109.109.61.238
+109.109.61.240
+109.109.61.241
+109.109.61.242
+109.109.61.243
+109.109.61.244
+109.109.61.245
+109.109.61.246
+109.109.61.247
+109.109.61.248
+109.109.61.249
+109.109.61.250
+109.109.61.251
+109.109.61.252
+109.109.61.253
+109.109.61.254
+109.109.61.255
+109.109.62.1
+109.109.62.3
+109.109.62.4
+109.109.62.5
+109.109.62.6
+109.109.62.40
+109.109.62.41
+109.109.62.42
+109.109.62.43
+109.109.62.44
+109.109.62.45
+109.109.62.46
+109.109.62.47
+109.109.62.48
+109.109.62.49
+109.109.62.50
+109.109.62.51
+109.109.62.52
+109.109.62.54
+109.109.62.55
+109.109.63.128
+109.109.63.129
+109.109.63.131
+109.109.63.132
+109.109.63.133
+109.109.63.134
+109.109.63.135
+109.109.63.137
+109.109.63.138
+109.109.63.139
+109.109.63.140
+109.109.63.141
+109.109.63.142
+109.109.63.143
+109.109.63.144
+109.109.63.145
+109.109.63.146
+109.109.63.147
+109.109.63.148
+109.109.63.149
+109.109.63.150
+109.109.63.151
+109.109.63.153
+109.109.63.154
+109.109.63.155
+109.109.63.156
+109.109.63.157
+109.109.63.158
+109.109.63.159
+109.109.63.160
+109.109.63.161
+109.109.63.162
+109.109.63.163
+109.109.63.164
+109.109.63.165
+109.109.63.166
+109.109.63.167
+109.109.63.168
+109.109.63.169
+109.109.63.170
+109.109.63.171
+109.109.63.172
+109.109.63.173
+109.109.63.174
+109.109.63.175
+109.109.63.184
+109.109.63.185
+109.109.63.186
+109.109.63.187
+109.109.63.188
+109.109.63.189
+109.109.63.190
+109.109.63.191
+109.109.63.192
+109.109.63.194
+109.109.63.195
+109.109.63.197
+109.109.63.198
+109.109.63.199
+109.109.63.200
+109.109.63.201
+109.109.63.202
+109.109.63.203
+109.109.63.204
+109.109.63.205
+109.109.63.206
+109.109.63.207
+109.109.63.209
+109.109.63.210
+109.109.63.211
+109.109.63.212
+109.109.63.213
+109.109.63.214
+109.109.63.215
+109.109.63.224
+109.109.63.226
+109.109.63.227
+109.109.63.228
+109.109.63.229
+109.109.63.230
+109.109.63.231
+109.109.63.232
+109.109.63.233
+109.109.63.234
+109.109.63.235
+109.109.63.236
+109.109.63.237
+109.109.63.238
+109.109.63.239
+109.109.63.240
+109.109.63.242
+109.109.63.243
+109.109.63.244
+109.109.63.245
+109.109.63.246
+109.109.63.247
+109.109.63.248
+109.109.63.249
+109.109.63.250
+109.109.63.251
+109.109.63.252
+109.109.63.254
+109.109.63.255
+109.122.235.163
+109.122.240.164
+109.122.245.12
+109.122.245.14
+109.122.245.20
+109.122.245.28
+109.122.245.32
+109.122.245.34
+109.122.245.37
+109.122.245.47
+109.122.245.48
+109.122.245.49
+109.122.245.50
+109.122.245.52
+109.122.245.55
+109.122.245.57
+109.122.245.83
+109.122.245.90
+109.122.245.94
+109.122.245.114
+109.122.245.115
+109.122.245.116
+109.122.245.117
+109.122.245.118
+109.122.245.122
+109.122.245.138
+109.122.245.163
+109.122.245.196
+109.122.246.22
+109.122.246.32
+109.122.246.41
+109.122.246.51
+109.122.246.122
+109.122.246.172
+109.122.246.210
+109.122.246.226
+109.122.246.250
+109.122.246.252
+109.122.251.4
+109.122.251.5
+109.122.251.10
+109.122.251.12
+109.122.251.13
+109.122.251.118
+109.122.253.18
+109.125.129.255
+109.125.130.0
+109.125.131.87
+109.125.135.109
+109.125.150.34
+109.125.151.67
+109.125.160.14
+109.125.160.170
+109.201.24.195
+109.201.24.197
+109.201.24.198
+109.201.24.199
+109.201.24.200
+109.201.24.201
+109.201.24.202
+109.201.24.203
+109.201.24.204
+109.201.24.205
+109.201.24.206
+109.206.252.44
+109.206.252.198
+109.206.254.13
+109.206.254.140
+109.206.255.13
+109.206.255.146
+109.206.255.148
+109.206.255.149
+109.206.255.178
+109.206.255.188
+109.230.81.238
+109.230.82.34
+109.230.83.227
+109.230.83.234
+109.230.88.171
+109.230.89.74
+109.230.89.75
+109.230.89.76
+109.230.89.77
+109.230.89.78
+109.230.89.90
+109.230.89.91
+109.230.89.94
+109.230.92.50
+109.230.94.82
+109.230.95.153
+109.230.95.164
+109.230.200.117
+109.230.200.118
+109.230.200.119
+109.230.200.120
+109.230.200.188
+109.230.204.17
+109.230.204.95
+109.230.204.180
+109.230.205.16
+109.230.205.20
+109.230.205.21
+109.230.205.139
+109.230.205.154
+109.230.205.164
+109.230.206.171
+109.230.206.174
+109.230.206.175
+109.230.206.180
+109.230.221.102
+109.230.221.103
+109.230.221.106
+109.230.223.74
+109.230.223.75
+109.230.223.170
+109.230.223.182
+109.230.242.117
+109.232.1.6
+109.232.1.59
+109.232.1.60
+109.232.1.62
+109.232.1.138
+109.232.1.217
+109.232.1.219
+109.232.2.123
+109.238.191.251
+128.65.181.137
+128.65.183.223
+128.65.184.126
+128.65.187.239
+128.65.188.31
+130.185.72.53
+130.185.72.61
+130.185.72.64
+130.185.72.84
+130.185.72.85
+130.185.72.94
+130.185.72.98
+130.185.72.105
+130.185.72.107
+130.185.72.108
+130.185.72.115
+130.185.72.119
+130.185.72.120
+130.185.72.125
+130.185.72.131
+130.185.72.138
+130.185.72.142
+130.185.72.149
+130.185.72.170
+130.185.72.172
+130.185.72.181
+130.185.72.213
+130.185.72.216
+130.185.72.223
+130.185.72.248
+130.185.72.249
+130.185.73.3
+130.185.73.4
+130.185.73.5
+130.185.73.6
+130.185.73.8
+130.185.73.12
+130.185.73.13
+130.185.73.18
+130.185.73.19
+130.185.73.22
+130.185.73.30
+130.185.73.32
+130.185.73.34
+130.185.73.58
+130.185.73.64
+130.185.73.65
+130.185.73.70
+130.185.73.88
+130.185.73.90
+130.185.73.96
+130.185.73.100
+130.185.73.102
+130.185.73.104
+130.185.73.105
+130.185.73.106
+130.185.73.108
+130.185.73.111
+130.185.73.126
+130.185.73.131
+130.185.73.134
+130.185.73.137
+130.185.73.140
+130.185.73.141
+130.185.73.144
+130.185.73.146
+130.185.73.149
+130.185.73.153
+130.185.73.156
+130.185.73.160
+130.185.73.165
+130.185.73.176
+130.185.73.189
+130.185.73.190
+130.185.73.194
+130.185.73.197
+130.185.73.200
+130.185.73.209
+130.185.73.214
+130.185.73.217
+130.185.73.220
+130.185.73.230
+130.185.73.239
+130.185.73.242
+130.185.73.245
+130.185.73.246
+130.185.74.11
+130.185.74.18
+130.185.74.26
+130.185.74.28
+130.185.74.33
+130.185.74.43
+130.185.74.47
+130.185.74.51
+130.185.74.65
+130.185.74.76
+130.185.74.79
+130.185.74.84
+130.185.74.85
+130.185.74.86
+130.185.74.90
+130.185.74.91
+130.185.74.94
+130.185.74.96
+130.185.74.97
+130.185.74.105
+130.185.74.106
+130.185.74.116
+130.185.74.120
+130.185.74.122
+130.185.74.123
+130.185.74.125
+130.185.74.126
+130.185.74.133
+130.185.74.134
+130.185.74.136
+130.185.74.140
+130.185.74.145
+130.185.74.147
+130.185.74.150
+130.185.74.152
+130.185.74.155
+130.185.74.160
+130.185.74.161
+130.185.74.163
+130.185.74.168
+130.185.74.170
+130.185.74.183
+130.185.74.185
+130.185.74.193
+130.185.74.197
+130.185.74.198
+130.185.74.204
+130.185.74.208
+130.185.74.218
+130.185.74.227
+130.185.74.234
+130.185.74.239
+130.185.74.245
+130.185.74.246
+130.185.74.249
+130.185.74.250
+130.185.75.5
+130.185.75.7
+130.185.75.8
+130.185.75.11
+130.185.75.15
+130.185.75.27
+130.185.75.29
+130.185.75.33
+130.185.75.40
+130.185.75.43
+130.185.75.46
+130.185.75.54
+130.185.75.57
+130.185.75.75
+130.185.75.76
+130.185.75.78
+130.185.75.80
+130.185.75.85
+130.185.75.92
+130.185.75.93
+130.185.75.100
+130.185.75.116
+130.185.75.121
+130.185.75.123
+130.185.75.135
+130.185.75.138
+130.185.75.144
+130.185.75.149
+130.185.75.152
+130.185.75.159
+130.185.75.163
+130.185.75.165
+130.185.75.168
+130.185.75.170
+130.185.75.179
+130.185.75.180
+130.185.75.182
+130.185.75.184
+130.185.75.185
+130.185.75.186
+130.185.75.189
+130.185.75.190
+130.185.75.197
+130.185.75.206
+130.185.75.207
+130.185.75.216
+130.185.75.217
+130.185.75.219
+130.185.75.224
+130.185.75.229
+130.185.75.232
+130.185.75.233
+130.185.75.234
+130.185.75.241
+130.185.75.243
+130.185.75.244
+130.185.75.252
+130.185.76.7
+130.185.76.9
+130.185.76.12
+130.185.76.20
+130.185.76.21
+130.185.76.26
+130.185.76.28
+130.185.76.31
+130.185.76.48
+130.185.76.52
+130.185.76.53
+130.185.76.64
+130.185.76.66
+130.185.76.69
+130.185.76.70
+130.185.76.74
+130.185.76.78
+130.185.76.84
+130.185.76.86
+130.185.76.91
+130.185.76.94
+130.185.76.103
+130.185.76.104
+130.185.76.106
+130.185.76.114
+130.185.76.123
+130.185.76.127
+130.185.76.132
+130.185.76.140
+130.185.76.149
+130.185.76.150
+130.185.76.152
+130.185.76.156
+130.185.76.162
+130.185.76.165
+130.185.76.170
+130.185.76.172
+130.185.76.176
+130.185.76.185
+130.185.76.188
+130.185.76.191
+130.185.76.197
+130.185.76.200
+130.185.76.205
+130.185.76.225
+130.185.76.231
+130.185.76.238
+130.185.76.240
+130.185.76.243
+130.185.76.248
+130.185.76.251
+130.185.77.10
+130.185.77.12
+130.185.77.16
+130.185.77.17
+130.185.77.22
+130.185.77.29
+130.185.77.34
+130.185.77.40
+130.185.77.43
+130.185.77.44
+130.185.77.46
+130.185.77.48
+130.185.77.54
+130.185.77.61
+130.185.77.62
+130.185.77.63
+130.185.77.64
+130.185.77.67
+130.185.77.69
+130.185.77.71
+130.185.77.72
+130.185.77.77
+130.185.77.78
+130.185.77.79
+130.185.77.86
+130.185.77.88
+130.185.77.89
+130.185.77.91
+130.185.77.97
+130.185.77.101
+130.185.77.114
+130.185.77.118
+130.185.77.124
+130.185.77.129
+130.185.77.131
+130.185.77.132
+130.185.77.133
+130.185.77.145
+130.185.77.146
+130.185.77.158
+130.185.77.160
+130.185.77.162
+130.185.77.165
+130.185.77.173
+130.185.77.181
+130.185.77.195
+130.185.77.199
+130.185.77.206
+130.185.77.214
+130.185.77.218
+130.185.77.221
+130.185.77.222
+130.185.77.225
+130.185.77.227
+130.185.77.230
+130.185.77.237
+130.185.77.242
+130.185.77.246
+130.185.77.247
+130.185.77.249
+130.185.78.5
+130.185.78.18
+130.185.78.40
+130.185.78.44
+130.185.78.51
+130.185.78.64
+130.185.78.67
+130.185.78.72
+130.185.78.74
+130.185.78.76
+130.185.78.81
+130.185.78.84
+130.185.78.85
+130.185.78.87
+130.185.78.95
+130.185.78.100
+130.185.78.101
+130.185.78.113
+130.185.78.117
+130.185.78.124
+130.185.78.127
+130.185.78.140
+130.185.78.148
+130.185.78.151
+130.185.78.152
+130.185.78.155
+130.185.78.167
+130.185.78.170
+130.185.78.171
+130.185.78.177
+130.185.78.179
+130.185.78.182
+130.185.78.184
+130.185.78.185
+130.185.78.186
+130.185.78.189
+130.185.78.201
+130.185.78.212
+130.185.78.217
+130.185.78.218
+130.185.78.220
+130.185.78.223
+130.185.78.225
+130.185.78.228
+130.185.78.229
+130.185.78.230
+130.185.78.233
+130.185.78.234
+130.185.78.247
+130.185.78.248
+130.185.78.249
+130.185.79.138
+130.185.79.170
+130.185.79.180
+130.185.79.181
+130.185.79.184
+130.185.79.187
+130.185.79.197
+130.193.77.5
+130.193.77.35
+130.193.77.61
+130.193.77.62
+130.193.77.82
+130.193.77.91
+130.193.77.98
+130.193.77.99
+130.193.77.100
+130.193.77.101
+130.193.77.102
+130.193.77.103
+130.193.77.104
+130.193.77.105
+130.193.77.106
+130.193.77.107
+130.193.77.108
+130.193.77.109
+130.193.77.110
+130.193.77.111
+130.193.77.112
+130.193.77.113
+130.193.77.114
+130.193.77.115
+130.193.77.116
+130.193.77.117
+130.193.77.118
+130.193.77.119
+130.193.77.120
+130.193.77.121
+130.193.77.122
+130.193.77.123
+130.193.77.126
+130.193.77.198
+130.193.77.199
+130.193.77.201
+130.193.77.202
+130.193.77.204
+130.193.77.205
+130.193.77.207
+130.193.77.211
+130.193.77.212
+130.193.77.214
+130.193.77.215
+130.193.77.216
+130.193.77.217
+130.193.77.222
+130.193.77.236
+130.193.77.247
+130.193.77.248
+130.193.77.249
+134.255.200.50
+134.255.200.52
+134.255.200.54
+134.255.200.130
+134.255.200.133
+134.255.200.147
+134.255.200.151
+134.255.200.154
+134.255.200.218
+134.255.200.250
+134.255.201.29
+134.255.201.91
+134.255.201.92
+134.255.201.94
+134.255.201.162
+134.255.202.7
+134.255.202.82
+134.255.202.164
+134.255.202.188
+134.255.203.50
+134.255.203.67
+134.255.203.68
+134.255.203.142
+134.255.203.171
+134.255.203.172
+134.255.203.174
+134.255.204.3
+138.128.224.53
+138.128.225.53
+146.19.212.5
+146.19.212.10
+146.19.212.12
+146.19.212.14
+146.19.212.22
+146.19.212.34
+146.19.212.51
+146.19.212.69
+146.19.212.70
+146.19.212.71
+146.19.212.74
+146.19.212.79
+146.19.212.80
+146.19.212.87
+146.19.212.88
+146.19.212.94
+146.19.212.99
+146.19.212.103
+146.19.212.104
+146.19.212.107
+146.19.212.108
+146.19.212.120
+146.19.212.121
+146.19.212.122
+146.19.212.136
+146.19.212.144
+146.19.212.145
+146.19.212.154
+146.19.212.156
+146.19.212.161
+146.19.212.163
+146.19.212.172
+146.19.212.173
+146.19.212.178
+146.19.212.183
+146.19.212.185
+146.19.212.186
+146.19.212.187
+146.19.212.192
+146.19.212.206
+146.19.212.212
+146.19.212.215
+146.19.212.217
+146.19.212.220
+146.19.212.224
+146.19.212.225
+146.19.212.227
+146.19.212.245
+146.19.212.249
+146.66.134.55
+146.66.135.55
+151.232.0.133
+151.232.8.90
+151.232.10.25
+151.232.20.66
+151.232.36.4
+151.232.36.5
+151.232.36.131
+151.232.36.132
+151.232.39.202
+151.232.103.94
+151.232.103.130
+151.232.133.244
+151.233.50.143
+151.233.50.216
+151.233.52.156
+151.233.53.44
+151.233.54.25
+151.233.54.200
+151.233.55.181
+151.233.56.110
+151.233.59.182
+151.233.74.80
+151.234.29.148
+151.234.121.165
+151.234.123.36
+151.234.127.139
+151.234.161.32
+151.234.161.33
+151.234.161.34
+151.235.91.187
+151.235.98.108
+151.235.99.85
+151.235.102.146
+151.235.113.194
+151.235.113.225
+151.235.117.185
+151.235.122.252
+151.235.127.103
+151.235.136.138
+151.235.181.165
+151.235.218.81
+151.235.237.253
+157.119.188.90
+157.119.188.122
+157.119.188.140
+157.119.190.146
+157.119.190.148
+157.119.190.150
+157.119.190.151
+157.119.190.153
+157.119.190.154
+157.119.190.155
+157.119.190.156
+157.119.190.157
+157.119.190.229
+157.119.191.50
+157.119.191.132
+157.119.191.134
+157.119.191.181
+158.58.184.68
+158.58.184.73
+158.58.184.74
+158.58.184.75
+158.58.184.76
+158.58.184.118
+158.58.184.138
+158.58.184.147
+158.58.184.148
+158.58.184.166
+158.58.184.170
+158.58.184.180
+158.58.184.243
+158.58.184.250
+158.58.184.251
+158.58.184.252
+158.58.184.253
+158.58.184.254
+158.58.185.5
+158.58.185.6
+158.58.185.7
+158.58.185.8
+158.58.185.12
+158.58.185.13
+158.58.185.38
+158.58.185.39
+158.58.185.56
+158.58.185.58
+158.58.185.59
+158.58.185.60
+158.58.185.61
+158.58.185.62
+158.58.185.72
+158.58.185.78
+158.58.185.79
+158.58.185.83
+158.58.185.85
+158.58.185.88
+158.58.185.89
+158.58.185.94
+158.58.185.95
+158.58.185.100
+158.58.185.103
+158.58.185.108
+158.58.185.111
+158.58.185.114
+158.58.185.115
+158.58.185.117
+158.58.185.120
+158.58.185.121
+158.58.185.122
+158.58.185.164
+158.58.185.174
+158.58.185.209
+158.58.185.210
+158.58.185.244
+158.58.185.246
+158.58.185.248
+158.58.185.250
+158.58.185.252
+158.58.186.34
+158.58.187.4
+158.58.187.6
+158.58.187.12
+158.58.187.13
+158.58.187.14
+158.58.187.20
+158.58.187.22
+158.58.187.38
+158.58.187.44
+158.58.187.50
+158.58.187.68
+158.58.187.70
+158.58.187.75
+158.58.187.76
+158.58.187.78
+158.58.187.91
+158.58.187.108
+158.58.187.109
+158.58.187.116
+158.58.187.118
+158.58.187.124
+158.58.187.131
+158.58.187.132
+158.58.187.134
+158.58.187.139
+158.58.187.141
+158.58.187.142
+158.58.187.148
+158.58.187.149
+158.58.187.155
+158.58.187.157
+158.58.187.163
+158.58.187.164
+158.58.187.165
+158.58.187.166
+158.58.187.171
+158.58.187.172
+158.58.187.173
+158.58.187.179
+158.58.187.180
+158.58.187.187
+158.58.187.194
+158.58.187.203
+158.58.187.204
+158.58.187.205
+158.58.187.211
+158.58.187.214
+158.58.187.220
+158.58.187.221
+158.58.187.226
+158.58.187.234
+158.58.187.243
+158.58.187.244
+158.58.187.246
+158.58.188.147
+158.58.188.148
+158.58.188.152
+158.58.188.155
+158.58.190.43
+158.58.191.20
+158.58.191.21
+158.58.191.36
+158.58.191.37
+158.58.191.39
+158.58.191.40
+158.58.191.41
+158.58.191.42
+158.58.191.43
+158.58.191.44
+158.58.191.45
+158.58.191.107
+158.58.191.108
+158.58.191.109
+158.58.191.130
+158.58.191.186
+158.58.191.190
+158.255.74.8
+158.255.74.27
+158.255.74.33
+158.255.74.38
+158.255.74.49
+158.255.74.52
+158.255.74.54
+158.255.74.60
+158.255.74.69
+158.255.74.71
+158.255.74.75
+158.255.74.79
+158.255.74.89
+158.255.74.100
+158.255.74.117
+158.255.74.124
+158.255.74.130
+158.255.74.133
+158.255.74.144
+158.255.74.150
+158.255.74.159
+158.255.74.164
+158.255.74.166
+158.255.74.167
+158.255.74.172
+158.255.74.174
+158.255.74.177
+158.255.74.184
+158.255.74.185
+158.255.74.190
+158.255.74.194
+158.255.74.196
+158.255.74.198
+158.255.74.200
+158.255.74.208
+158.255.74.212
+158.255.74.216
+158.255.74.218
+158.255.74.221
+158.255.74.223
+158.255.74.229
+158.255.74.246
+158.255.74.251
+158.255.78.168
+159.20.96.122
+159.20.102.136
+159.20.102.137
+159.20.102.138
+159.20.102.139
+159.20.102.140
+159.20.102.141
+159.20.102.142
+159.20.102.143
+164.138.16.1
+164.138.16.2
+164.138.16.4
+164.138.16.6
+164.138.16.7
+164.138.16.9
+164.138.16.40
+164.138.16.41
+164.138.16.42
+164.138.16.43
+164.138.16.44
+164.138.16.45
+164.138.16.47
+164.138.16.48
+164.138.16.49
+164.138.16.50
+164.138.16.51
+164.138.16.52
+164.138.16.53
+164.138.16.54
+164.138.16.55
+164.138.16.56
+164.138.16.57
+164.138.16.58
+164.138.16.59
+164.138.16.89
+164.138.16.100
+164.138.16.110
+164.138.16.111
+164.138.16.112
+164.138.16.130
+164.138.16.131
+164.138.16.132
+164.138.16.133
+164.138.16.134
+164.138.16.135
+164.138.16.136
+164.138.16.137
+164.138.16.138
+164.138.16.139
+164.138.16.140
+164.138.16.141
+164.138.16.142
+164.138.16.143
+164.138.16.144
+164.138.16.145
+164.138.16.150
+164.138.16.151
+164.138.16.164
+164.138.16.180
+164.138.16.183
+164.138.16.187
+164.138.17.1
+164.138.17.9
+164.138.17.10
+164.138.17.11
+164.138.17.12
+164.138.17.13
+164.138.17.66
+164.138.17.99
+164.138.17.100
+164.138.17.114
+164.138.17.122
+164.138.17.137
+164.138.17.161
+164.138.17.162
+164.138.17.163
+164.138.17.164
+164.138.17.165
+164.138.17.170
+164.138.17.201
+164.138.17.233
+164.138.17.235
+164.138.17.236
+164.138.17.250
+164.138.17.251
+164.138.17.252
+164.138.17.253
+164.138.18.65
+164.138.18.66
+164.138.18.67
+164.138.18.68
+164.138.18.69
+164.138.18.71
+164.138.18.72
+164.138.18.74
+164.138.18.75
+164.138.18.76
+164.138.18.105
+164.138.18.106
+164.138.18.153
+164.138.18.154
+164.138.18.155
+164.138.18.156
+164.138.18.157
+164.138.18.169
+164.138.18.170
+164.138.18.171
+164.138.18.172
+164.138.18.173
+164.138.19.1
+164.138.19.2
+164.138.19.4
+164.138.19.5
+164.138.19.6
+164.138.19.7
+164.138.19.8
+164.138.19.11
+164.138.19.13
+164.138.19.17
+164.138.19.18
+164.138.19.19
+164.138.19.34
+164.138.19.35
+164.138.19.49
+164.138.19.50
+164.138.19.97
+164.138.19.98
+164.138.19.99
+164.138.19.100
+164.138.19.101
+164.138.19.139
+164.138.19.185
+164.138.19.193
+164.138.19.194
+164.138.19.195
+164.138.19.196
+164.138.19.197
+164.138.19.198
+164.138.19.199
+164.138.19.200
+164.138.19.201
+164.138.19.202
+164.138.19.204
+164.138.19.225
+164.138.19.226
+164.138.19.227
+164.138.19.234
+164.138.19.250
+164.138.19.251
+164.138.19.252
+164.138.19.253
+164.138.20.81
+164.138.20.82
+164.138.20.83
+164.138.20.84
+164.138.20.85
+164.138.20.89
+164.138.20.90
+164.138.20.91
+164.138.20.92
+164.138.20.93
+164.138.20.98
+164.138.20.99
+164.138.20.100
+164.138.20.101
+164.138.20.121
+164.138.20.122
+164.138.20.123
+164.138.20.124
+164.138.20.125
+164.138.20.129
+164.138.20.130
+164.138.20.131
+164.138.20.132
+164.138.20.155
+164.138.20.156
+164.138.20.217
+164.138.20.218
+164.138.20.221
+164.138.21.1
+164.138.21.2
+164.138.21.4
+164.138.21.17
+164.138.21.18
+164.138.21.49
+164.138.21.57
+164.138.21.58
+164.138.21.59
+164.138.21.60
+164.138.21.73
+164.138.21.81
+164.138.21.82
+164.138.21.83
+164.138.21.84
+164.138.21.85
+164.138.21.105
+164.138.21.106
+164.138.21.107
+164.138.21.108
+164.138.21.109
+164.138.21.121
+164.138.21.122
+164.138.21.123
+164.138.21.124
+164.138.21.169
+164.138.21.170
+164.138.21.171
+164.138.21.172
+164.138.21.173
+164.138.21.201
+164.138.21.202
+164.138.21.204
+164.138.21.209
+164.138.21.210
+164.138.21.211
+164.138.22.9
+164.138.22.10
+164.138.22.11
+164.138.22.13
+164.138.22.65
+164.138.22.66
+164.138.22.114
+164.138.22.117
+164.138.22.118
+164.138.22.119
+164.138.22.120
+164.138.22.121
+164.138.22.122
+164.138.22.123
+164.138.22.124
+164.138.22.129
+164.138.22.130
+164.138.22.131
+164.138.22.132
+164.138.22.133
+164.138.22.134
+164.138.22.137
+164.138.22.138
+164.138.22.139
+164.138.22.140
+164.138.22.141
+164.138.22.169
+164.138.22.177
+164.138.22.179
+164.138.22.180
+164.138.22.181
+164.138.22.186
+164.138.22.187
+164.138.23.50
+164.138.23.51
+164.138.23.52
+164.138.23.173
+164.138.23.233
+164.138.23.237
+164.138.206.100
+164.215.57.55
+164.215.57.56
+164.215.59.37
+164.215.59.117
+168.119.88.234
+171.22.24.5
+171.22.24.13
+171.22.24.15
+171.22.24.16
+171.22.24.24
+171.22.24.34
+171.22.24.38
+171.22.24.42
+171.22.24.50
+171.22.24.54
+171.22.24.80
+171.22.24.88
+171.22.24.91
+171.22.24.103
+171.22.24.105
+171.22.24.112
+171.22.24.115
+171.22.24.130
+171.22.24.134
+171.22.24.137
+171.22.24.146
+171.22.24.150
+171.22.24.155
+171.22.24.157
+171.22.24.159
+171.22.24.161
+171.22.24.164
+171.22.24.165
+171.22.24.169
+171.22.24.176
+171.22.24.182
+171.22.24.187
+171.22.24.188
+171.22.24.211
+171.22.24.221
+171.22.24.231
+171.22.24.236
+171.22.24.246
+171.22.25.10
+171.22.25.18
+171.22.25.19
+171.22.25.20
+171.22.25.24
+171.22.25.25
+171.22.25.26
+171.22.25.31
+171.22.25.32
+171.22.25.41
+171.22.25.44
+171.22.25.49
+171.22.25.50
+171.22.25.54
+171.22.25.63
+171.22.25.64
+171.22.25.65
+171.22.25.69
+171.22.25.71
+171.22.25.73
+171.22.25.75
+171.22.25.79
+171.22.25.80
+171.22.25.83
+171.22.25.84
+171.22.25.86
+171.22.25.90
+171.22.25.91
+171.22.25.96
+171.22.25.99
+171.22.25.100
+171.22.25.102
+171.22.25.104
+171.22.25.105
+171.22.25.107
+171.22.25.110
+171.22.25.113
+171.22.25.128
+171.22.25.133
+171.22.25.140
+171.22.25.148
+171.22.25.149
+171.22.25.150
+171.22.25.155
+171.22.25.156
+171.22.25.161
+171.22.25.174
+171.22.25.185
+171.22.25.190
+171.22.25.191
+171.22.25.198
+171.22.25.222
+171.22.25.234
+171.22.25.253
+171.22.26.13
+171.22.26.31
+171.22.26.35
+171.22.26.41
+171.22.26.44
+171.22.26.46
+171.22.26.50
+171.22.26.69
+171.22.26.73
+171.22.26.75
+171.22.26.76
+171.22.26.82
+171.22.26.88
+171.22.26.90
+171.22.26.92
+171.22.26.95
+171.22.26.99
+171.22.26.104
+171.22.26.106
+171.22.26.108
+171.22.26.116
+171.22.26.120
+171.22.26.121
+171.22.26.127
+171.22.26.129
+171.22.26.131
+171.22.26.135
+171.22.26.140
+171.22.26.143
+171.22.26.145
+171.22.26.146
+171.22.26.151
+171.22.26.157
+171.22.26.165
+171.22.26.172
+171.22.26.176
+171.22.26.180
+171.22.26.193
+171.22.26.194
+171.22.26.196
+171.22.26.199
+171.22.26.202
+171.22.26.204
+171.22.26.205
+171.22.26.206
+171.22.26.207
+171.22.26.210
+171.22.26.212
+171.22.26.225
+171.22.26.233
+171.22.26.234
+171.22.26.238
+171.22.26.250
+171.22.27.13
+171.22.27.16
+171.22.27.29
+171.22.27.45
+171.22.27.49
+171.22.27.57
+171.22.27.75
+171.22.27.76
+171.22.27.83
+171.22.27.93
+171.22.27.98
+171.22.27.106
+171.22.27.108
+171.22.27.109
+171.22.27.110
+171.22.27.115
+171.22.27.119
+171.22.27.122
+171.22.27.123
+171.22.27.125
+171.22.27.130
+171.22.27.132
+171.22.27.133
+171.22.27.137
+171.22.27.143
+171.22.27.145
+171.22.27.146
+171.22.27.151
+171.22.27.152
+171.22.27.155
+171.22.27.158
+171.22.27.159
+171.22.27.160
+171.22.27.162
+171.22.27.164
+171.22.27.170
+171.22.27.172
+171.22.27.173
+171.22.27.175
+171.22.27.184
+171.22.27.189
+171.22.27.194
+171.22.27.197
+171.22.27.200
+171.22.27.201
+171.22.27.207
+171.22.27.225
+171.22.27.240
+171.22.27.244
+171.22.27.247
+171.22.27.251
+176.10.95.10
+176.56.156.4
+176.56.157.4
+176.62.144.36
+176.62.144.43
+176.62.144.45
+176.62.144.46
+176.65.191.39
+176.65.224.205
+176.65.225.161
+176.65.240.45
+176.65.240.46
+176.65.240.50
+176.65.240.51
+176.65.240.87
+176.65.240.89
+176.65.240.162
+176.65.240.163
+176.65.241.162
+176.65.241.164
+176.65.241.165
+176.65.242.131
+176.65.242.204
+176.65.242.205
+176.65.243.44
+176.65.243.51
+176.65.243.52
+176.65.243.53
+176.65.243.57
+176.65.243.61
+176.65.243.196
+176.65.243.230
+176.65.252.158
+176.97.218.7
+176.97.218.9
+176.97.218.30
+176.97.218.31
+176.97.218.35
+176.97.218.36
+176.97.218.37
+176.97.218.42
+176.97.218.46
+176.97.218.49
+176.97.218.50
+176.97.218.65
+176.97.218.66
+176.97.218.70
+176.97.218.73
+176.97.218.74
+176.97.218.75
+176.97.218.86
+176.97.218.98
+176.97.218.99
+176.97.218.105
+176.97.218.142
+176.97.218.144
+176.97.218.150
+176.97.218.152
+176.97.218.156
+176.97.218.159
+176.97.218.161
+176.97.218.166
+176.97.218.189
+176.97.218.215
+176.97.218.217
+176.97.218.226
+176.97.218.237
+176.97.218.246
+176.97.218.248
+176.97.218.252
+176.97.220.34
+176.97.220.69
+176.97.220.70
+176.97.220.162
+176.97.220.235
+176.97.220.236
+176.97.220.237
+176.97.220.238
+176.101.33.161
+176.101.48.167
+176.101.48.192
+176.101.48.195
+176.102.224.6
+176.102.224.7
+176.120.16.4
+176.120.16.21
+176.120.16.25
+176.120.16.55
+176.120.16.56
+176.120.16.60
+176.120.16.85
+176.120.16.88
+176.120.16.96
+176.120.16.104
+176.120.16.122
+176.120.16.136
+176.120.16.163
+176.120.16.181
+176.120.16.186
+176.120.16.205
+176.120.16.212
+176.120.16.217
+176.120.16.224
+176.120.16.228
+176.120.16.229
+176.120.16.232
+176.120.16.252
+176.120.16.254
+176.122.210.2
+176.122.210.6
+176.122.210.10
+176.122.210.78
+176.122.210.98
+176.126.120.3
+176.126.120.5
+176.126.120.8
+176.126.120.19
+176.126.120.33
+176.126.120.101
+176.126.120.108
+176.126.120.199
+176.126.120.207
+176.126.120.208
+176.126.120.209
+176.126.120.217
+176.126.120.218
+176.126.120.234
+176.126.120.235
+176.126.120.236
+176.126.120.237
+176.126.120.238
+176.126.120.243
+178.21.40.17
+178.21.40.20
+178.21.40.21
+178.21.41.20
+178.21.45.10
+178.21.45.11
+178.21.46.10
+178.21.46.11
+178.21.161.12
+178.21.161.13
+178.21.161.53
+178.21.161.137
+178.21.162.38
+178.21.162.44
+178.21.162.47
+178.21.162.49
+178.21.162.56
+178.21.163.51
+178.21.163.60
+178.21.163.81
+178.21.163.97
+178.21.164.113
+178.21.164.247
+178.22.120.85
+178.22.120.100
+178.22.120.103
+178.22.120.110
+178.22.120.113
+178.22.120.140
+178.22.120.238
+178.22.121.70
+178.22.121.72
+178.22.121.139
+178.22.121.148
+178.22.121.149
+178.22.121.212
+178.22.121.214
+178.22.122.72
+178.22.122.75
+178.22.122.101
+178.22.122.103
+178.22.122.122
+178.22.122.232
+178.22.123.10
+178.22.123.42
+178.22.123.43
+178.22.123.44
+178.22.123.45
+178.22.123.114
+178.22.123.198
+178.22.124.7
+178.22.124.17
+178.22.124.20
+178.22.124.21
+178.22.124.25
+178.22.124.29
+178.22.124.230
+178.22.124.231
+178.22.124.237
+178.22.126.2
+178.22.126.18
+178.22.126.26
+178.22.126.30
+178.22.126.42
+178.22.127.57
+178.22.127.58
+178.22.127.179
+178.22.127.180
+178.131.8.229
+178.131.78.211
+178.131.88.93
+178.131.89.118
+178.131.109.152
+178.131.110.148
+178.131.119.93
+178.131.120.31
+178.131.120.32
+178.131.120.33
+178.131.120.34
+178.131.123.31
+178.131.123.32
+178.131.124.31
+178.131.124.32
+178.131.125.31
+178.131.125.32
+178.131.127.31
+178.173.128.7
+178.173.128.16
+178.173.128.28
+178.173.128.29
+178.173.140.108
+178.173.141.28
+178.173.141.47
+178.173.143.43
+178.173.144.93
+178.173.145.26
+178.173.145.137
+178.173.149.25
+178.173.151.16
+178.173.151.23
+178.173.161.190
+178.173.170.83
+178.173.171.82
+178.173.190.9
+178.173.190.58
+178.173.212.160
+178.173.214.4
+178.173.219.7
+178.215.8.18
+178.215.8.54
+178.216.248.4
+178.216.248.30
+178.216.248.100
+178.216.248.106
+178.216.248.108
+178.216.248.110
+178.216.248.251
+178.216.249.55
+178.216.249.194
+178.216.249.202
+178.216.249.206
+178.216.250.162
+178.216.250.163
+178.216.250.167
+178.216.250.173
+178.216.250.181
+178.216.250.182
+178.216.250.183
+178.216.250.184
+178.216.250.186
+178.216.250.188
+178.216.250.189
+178.216.251.14
+178.216.251.34
+178.216.251.106
+178.216.251.219
+178.216.251.220
+178.216.251.226
+178.216.251.229
+178.216.251.231
+178.216.251.232
+178.216.251.233
+178.216.251.234
+178.216.251.235
+178.216.251.240
+178.216.251.241
+178.216.251.242
+178.216.251.243
+178.216.251.245
+178.216.251.246
+178.216.251.248
+178.216.251.249
+178.216.251.252
+178.216.251.253
+178.216.251.254
+178.219.238.55
+178.236.105.45
+178.236.108.24
+178.236.108.72
+178.238.193.14
+178.238.195.158
+178.238.197.244
+178.239.145.30
+178.239.147.62
+178.239.147.71
+178.239.147.86
+178.239.147.91
+178.239.147.98
+178.239.147.99
+178.239.147.100
+178.239.147.101
+178.239.147.102
+178.239.147.106
+178.239.147.107
+178.239.147.108
+178.239.147.109
+178.239.147.114
+178.239.147.115
+178.239.147.116
+178.239.147.117
+178.239.147.118
+178.239.147.119
+178.239.147.120
+178.239.147.121
+178.239.147.122
+178.239.147.123
+178.239.147.137
+178.239.147.139
+178.239.147.146
+178.239.148.110
+178.239.148.129
+178.239.148.133
+178.239.151.13
+178.239.151.16
+178.239.151.20
+178.239.151.26
+178.239.151.28
+178.239.151.42
+178.239.151.60
+178.239.151.64
+178.239.151.84
+178.239.151.86
+178.239.151.87
+178.239.151.89
+178.239.151.97
+178.239.151.100
+178.239.151.112
+178.239.151.123
+178.239.151.130
+178.239.151.136
+178.239.151.137
+178.239.151.139
+178.239.151.160
+178.239.151.179
+178.239.151.185
+178.239.151.186
+178.239.151.193
+178.239.151.196
+178.239.151.200
+178.239.151.207
+178.239.151.225
+178.239.151.226
+178.239.151.228
+178.239.151.239
+178.239.151.240
+178.239.158.14
+178.239.158.56
+178.239.158.60
+178.239.158.61
+178.239.158.64
+178.239.158.65
+178.239.158.67
+178.239.158.76
+178.239.158.80
+178.239.158.90
+178.239.158.91
+178.239.158.95
+178.239.158.96
+178.239.158.103
+178.239.158.117
+178.239.158.118
+178.239.158.128
+178.239.158.140
+178.239.158.141
+178.239.158.145
+178.252.128.66
+178.252.128.67
+178.252.130.200
+178.252.132.131
+178.252.132.202
+178.252.134.6
+178.252.134.106
+178.252.137.98
+178.252.137.99
+178.252.137.100
+178.252.138.62
+178.252.140.186
+178.252.140.198
+178.252.140.210
+178.252.140.211
+178.252.140.212
+178.252.141.66
+178.252.141.72
+178.252.141.73
+178.252.141.74
+178.252.141.75
+178.252.141.76
+178.252.141.77
+178.252.141.78
+178.252.141.228
+178.252.143.122
+178.252.143.123
+178.252.143.124
+178.252.143.125
+178.252.143.126
+178.252.143.132
+178.252.143.133
+178.252.144.227
+178.252.144.228
+178.252.146.186
+178.252.147.66
+178.252.147.69
+178.252.147.219
+178.252.148.244
+178.252.149.134
+178.252.149.237
+178.252.153.60
+178.252.153.197
+178.252.166.35
+178.252.166.147
+178.252.166.148
+178.252.166.150
+178.252.166.151
+178.252.166.152
+178.252.167.151
+178.252.178.34
+178.252.178.35
+178.252.178.40
+178.252.178.44
+178.252.180.195
+178.252.181.45
+178.252.181.52
+178.252.181.73
+178.252.181.246
+178.252.181.247
+178.252.182.180
+178.252.183.11
+178.252.190.15
+185.2.13.98
+185.2.13.193
+185.2.13.207
+185.2.13.208
+185.2.13.211
+185.2.13.212
+185.2.13.213
+185.2.13.214
+185.2.13.217
+185.2.13.218
+185.2.13.219
+185.2.13.220
+185.2.13.221
+185.2.13.222
+185.2.14.3
+185.2.14.4
+185.2.14.5
+185.2.14.7
+185.2.14.12
+185.2.14.37
+185.2.14.39
+185.2.14.42
+185.2.14.59
+185.2.14.61
+185.2.14.62
+185.2.14.67
+185.2.14.70
+185.2.14.75
+185.2.14.76
+185.2.14.77
+185.2.14.86
+185.2.14.91
+185.2.14.93
+185.2.14.126
+185.2.14.131
+185.2.14.132
+185.2.14.156
+185.2.14.157
+185.2.14.164
+185.2.14.179
+185.2.14.180
+185.2.14.181
+185.2.14.197
+185.2.14.198
+185.2.14.201
+185.2.14.214
+185.2.14.219
+185.2.14.220
+185.2.14.227
+185.2.14.236
+185.2.14.237
+185.2.14.238
+185.2.14.243
+185.2.14.252
+185.2.14.254
+185.3.124.35
+185.3.124.36
+185.3.124.42
+185.3.124.51
+185.3.124.52
+185.3.124.53
+185.3.124.54
+185.3.124.58
+185.3.124.68
+185.3.124.94
+185.3.124.98
+185.3.124.99
+185.3.124.106
+185.3.124.131
+185.3.124.150
+185.3.124.206
+185.3.124.226
+185.3.124.247
+185.3.124.253
+185.3.126.3
+185.3.126.4
+185.3.201.195
+185.3.201.240
+185.3.201.241
+185.3.201.242
+185.3.201.243
+185.3.201.244
+185.3.201.245
+185.3.201.246
+185.3.201.247
+185.3.201.248
+185.3.201.249
+185.3.201.250
+185.3.201.251
+185.3.201.252
+185.3.201.253
+185.3.201.254
+185.3.201.255
+185.3.202.148
+185.3.203.32
+185.3.203.33
+185.3.203.35
+185.3.203.203
+185.4.1.14
+185.4.1.15
+185.4.1.20
+185.4.1.21
+185.4.1.23
+185.4.1.26
+185.4.1.30
+185.4.1.37
+185.4.1.38
+185.4.1.39
+185.4.1.41
+185.4.1.44
+185.4.1.47
+185.4.1.62
+185.4.1.64
+185.4.1.67
+185.4.1.70
+185.4.1.72
+185.4.1.76
+185.4.1.87
+185.4.1.90
+185.4.1.98
+185.4.1.100
+185.4.1.154
+185.4.1.170
+185.4.2.50
+185.4.3.12
+185.4.3.14
+185.4.3.15
+185.4.3.16
+185.4.3.17
+185.4.3.26
+185.4.3.27
+185.4.3.28
+185.4.3.29
+185.4.3.30
+185.4.3.31
+185.4.3.32
+185.4.3.33
+185.4.3.34
+185.4.3.37
+185.4.3.42
+185.4.3.43
+185.4.3.44
+185.4.3.45
+185.4.3.54
+185.4.3.64
+185.4.3.65
+185.4.3.66
+185.4.3.74
+185.4.3.75
+185.4.3.78
+185.4.28.184
+185.4.29.181
+185.4.29.196
+185.4.30.4
+185.4.30.13
+185.4.30.24
+185.4.30.31
+185.4.30.32
+185.4.30.33
+185.4.30.41
+185.4.30.42
+185.4.30.44
+185.4.30.54
+185.4.30.62
+185.4.30.64
+185.4.30.66
+185.4.30.69
+185.4.30.73
+185.4.30.74
+185.4.30.82
+185.4.30.87
+185.4.30.88
+185.4.30.89
+185.4.30.90
+185.4.30.91
+185.4.30.111
+185.4.30.120
+185.4.30.130
+185.4.30.173
+185.4.30.174
+185.4.30.175
+185.4.30.176
+185.4.30.177
+185.4.30.178
+185.4.30.179
+185.4.30.180
+185.4.30.181
+185.4.30.182
+185.4.30.234
+185.4.31.6
+185.7.172.4
+185.7.172.5
+185.7.172.11
+185.7.172.12
+185.7.172.34
+185.7.172.53
+185.7.172.56
+185.7.172.58
+185.7.172.59
+185.7.172.66
+185.7.172.67
+185.7.172.68
+185.7.172.74
+185.7.172.82
+185.7.172.122
+185.7.172.130
+185.7.172.133
+185.7.172.134
+185.7.172.136
+185.7.172.137
+185.7.172.150
+185.7.212.4
+185.7.212.5
+185.7.212.16
+185.7.212.29
+185.7.212.32
+185.7.212.37
+185.7.212.53
+185.7.212.60
+185.7.212.63
+185.7.212.72
+185.7.212.83
+185.7.212.87
+185.7.212.95
+185.7.212.101
+185.7.212.109
+185.7.212.111
+185.7.212.112
+185.7.212.120
+185.7.212.135
+185.7.212.139
+185.7.212.145
+185.7.212.154
+185.7.212.155
+185.7.212.166
+185.7.212.168
+185.7.212.169
+185.7.212.170
+185.7.212.171
+185.7.212.172
+185.7.212.181
+185.7.212.183
+185.7.212.192
+185.7.212.195
+185.7.212.201
+185.7.212.204
+185.7.212.217
+185.7.212.218
+185.7.212.219
+185.7.212.221
+185.7.212.232
+185.7.212.236
+185.7.212.245
+185.7.212.246
+185.7.212.252
+185.8.172.6
+185.8.172.12
+185.8.172.14
+185.8.172.15
+185.8.172.19
+185.8.172.22
+185.8.172.25
+185.8.172.35
+185.8.172.56
+185.8.172.58
+185.8.172.67
+185.8.172.68
+185.8.172.69
+185.8.172.81
+185.8.172.83
+185.8.172.101
+185.8.172.104
+185.8.172.105
+185.8.172.107
+185.8.172.117
+185.8.172.118
+185.8.172.119
+185.8.172.120
+185.8.172.125
+185.8.172.137
+185.8.172.139
+185.8.172.145
+185.8.172.146
+185.8.172.147
+185.8.172.151
+185.8.172.155
+185.8.172.156
+185.8.172.159
+185.8.172.161
+185.8.172.165
+185.8.172.168
+185.8.172.170
+185.8.172.172
+185.8.172.180
+185.8.172.196
+185.8.172.197
+185.8.172.198
+185.8.172.205
+185.8.172.208
+185.8.172.211
+185.8.172.216
+185.8.172.217
+185.8.172.218
+185.8.172.227
+185.8.172.233
+185.8.172.243
+185.8.172.249
+185.8.173.13
+185.8.173.16
+185.8.173.36
+185.8.173.39
+185.8.173.42
+185.8.173.44
+185.8.173.45
+185.8.173.53
+185.8.173.59
+185.8.173.71
+185.8.173.72
+185.8.173.79
+185.8.173.83
+185.8.173.102
+185.8.173.104
+185.8.173.107
+185.8.173.110
+185.8.173.122
+185.8.173.126
+185.8.173.127
+185.8.173.128
+185.8.173.129
+185.8.173.131
+185.8.173.136
+185.8.173.137
+185.8.173.140
+185.8.173.142
+185.8.173.146
+185.8.173.151
+185.8.173.153
+185.8.173.154
+185.8.173.159
+185.8.173.163
+185.8.173.168
+185.8.173.170
+185.8.173.172
+185.8.173.181
+185.8.173.182
+185.8.173.193
+185.8.173.196
+185.8.173.198
+185.8.173.201
+185.8.173.206
+185.8.173.212
+185.8.173.213
+185.8.173.217
+185.8.173.218
+185.8.173.226
+185.8.173.229
+185.8.173.248
+185.8.173.249
+185.8.174.6
+185.8.174.7
+185.8.174.16
+185.8.174.18
+185.8.174.37
+185.8.174.39
+185.8.174.40
+185.8.174.43
+185.8.174.49
+185.8.174.55
+185.8.174.62
+185.8.174.65
+185.8.174.70
+185.8.174.82
+185.8.174.86
+185.8.174.87
+185.8.174.88
+185.8.174.92
+185.8.174.98
+185.8.174.100
+185.8.174.105
+185.8.174.110
+185.8.174.111
+185.8.174.112
+185.8.174.116
+185.8.174.117
+185.8.174.121
+185.8.174.123
+185.8.174.133
+185.8.174.139
+185.8.174.140
+185.8.174.143
+185.8.174.144
+185.8.174.145
+185.8.174.148
+185.8.174.149
+185.8.174.150
+185.8.174.151
+185.8.174.155
+185.8.174.159
+185.8.174.160
+185.8.174.162
+185.8.174.167
+185.8.174.168
+185.8.174.171
+185.8.174.178
+185.8.174.179
+185.8.174.181
+185.8.174.182
+185.8.174.189
+185.8.174.190
+185.8.174.193
+185.8.174.196
+185.8.174.198
+185.8.174.199
+185.8.174.200
+185.8.174.211
+185.8.174.218
+185.8.174.219
+185.8.174.222
+185.8.174.224
+185.8.174.231
+185.8.174.232
+185.8.174.234
+185.8.174.244
+185.8.174.245
+185.8.174.247
+185.8.174.251
+185.8.175.13
+185.8.175.27
+185.8.175.29
+185.8.175.31
+185.8.175.37
+185.8.175.40
+185.8.175.45
+185.8.175.46
+185.8.175.49
+185.8.175.51
+185.8.175.52
+185.8.175.58
+185.8.175.61
+185.8.175.64
+185.8.175.92
+185.8.175.96
+185.8.175.101
+185.8.175.102
+185.8.175.104
+185.8.175.107
+185.8.175.109
+185.8.175.117
+185.8.175.118
+185.8.175.126
+185.8.175.132
+185.8.175.134
+185.8.175.137
+185.8.175.144
+185.8.175.145
+185.8.175.146
+185.8.175.159
+185.8.175.162
+185.8.175.163
+185.8.175.169
+185.8.175.170
+185.8.175.171
+185.8.175.173
+185.8.175.198
+185.8.175.199
+185.8.175.203
+185.8.175.206
+185.8.175.208
+185.8.175.213
+185.8.175.223
+185.8.175.224
+185.8.175.228
+185.8.175.230
+185.8.175.234
+185.8.175.238
+185.10.71.138
+185.10.72.35
+185.10.72.41
+185.10.72.49
+185.10.72.64
+185.10.72.65
+185.10.72.66
+185.10.72.67
+185.10.72.70
+185.10.72.76
+185.10.72.83
+185.10.72.90
+185.10.72.121
+185.10.72.123
+185.10.72.136
+185.10.72.141
+185.10.72.150
+185.10.72.156
+185.10.72.165
+185.10.72.168
+185.10.72.182
+185.10.72.184
+185.10.72.216
+185.10.73.10
+185.10.73.11
+185.10.73.12
+185.10.73.15
+185.10.73.17
+185.10.73.19
+185.10.73.53
+185.10.73.72
+185.10.73.83
+185.10.73.84
+185.10.73.88
+185.10.73.96
+185.10.73.114
+185.10.73.116
+185.10.73.145
+185.10.73.152
+185.10.73.190
+185.10.73.192
+185.10.73.200
+185.10.73.227
+185.10.73.230
+185.10.74.2
+185.10.74.33
+185.10.74.37
+185.10.74.44
+185.10.74.47
+185.10.74.55
+185.10.74.56
+185.10.74.64
+185.10.74.72
+185.10.74.91
+185.10.74.105
+185.10.74.110
+185.10.74.123
+185.10.74.137
+185.10.74.149
+185.10.74.154
+185.10.74.156
+185.10.74.159
+185.10.74.184
+185.10.74.207
+185.10.74.240
+185.10.74.244
+185.10.74.245
+185.10.74.251
+185.10.74.253
+185.10.75.10
+185.10.75.51
+185.10.75.67
+185.10.75.69
+185.10.75.71
+185.10.75.73
+185.10.75.79
+185.10.75.85
+185.10.75.88
+185.10.75.89
+185.10.75.93
+185.10.75.94
+185.10.75.100
+185.10.75.102
+185.10.75.103
+185.10.75.104
+185.10.75.106
+185.10.75.109
+185.10.75.110
+185.10.75.112
+185.10.75.114
+185.10.75.116
+185.10.75.117
+185.10.75.122
+185.10.75.125
+185.10.75.126
+185.10.75.132
+185.10.75.136
+185.10.75.139
+185.10.75.142
+185.10.75.147
+185.10.75.154
+185.10.75.155
+185.10.75.160
+185.10.75.163
+185.10.75.165
+185.10.75.172
+185.10.75.174
+185.10.75.178
+185.10.75.179
+185.10.75.180
+185.10.75.181
+185.10.75.182
+185.10.75.183
+185.10.75.185
+185.10.75.186
+185.10.75.188
+185.10.75.189
+185.10.75.195
+185.10.75.216
+185.11.68.7
+185.11.68.8
+185.11.68.14
+185.11.68.29
+185.11.68.30
+185.11.69.99
+185.11.89.100
+185.12.101.11
+185.12.101.18
+185.13.228.45
+185.13.228.50
+185.13.228.59
+185.13.228.130
+185.13.228.135
+185.13.228.136
+185.13.228.137
+185.13.228.139
+185.13.228.150
+185.13.228.153
+185.13.228.154
+185.13.228.155
+185.13.228.157
+185.13.228.158
+185.13.228.162
+185.13.228.218
+185.13.228.244
+185.13.229.3
+185.13.229.4
+185.13.229.53
+185.13.229.228
+185.13.230.75
+185.13.230.115
+185.13.230.117
+185.13.230.118
+185.13.230.156
+185.13.231.11
+185.14.162.68
+185.14.162.80
+185.14.163.6
+185.14.163.7
+185.14.163.75
+185.18.212.19
+185.18.212.65
+185.18.212.71
+185.18.212.83
+185.18.212.85
+185.18.212.96
+185.18.212.100
+185.18.212.102
+185.18.212.113
+185.18.212.132
+185.18.212.136
+185.18.212.137
+185.18.212.176
+185.18.212.177
+185.18.212.185
+185.18.212.188
+185.18.212.200
+185.18.212.216
+185.18.213.17
+185.18.213.18
+185.18.213.20
+185.18.213.22
+185.18.213.43
+185.18.213.52
+185.18.213.56
+185.18.213.59
+185.18.213.78
+185.18.213.82
+185.18.213.86
+185.18.213.164
+185.18.213.191
+185.18.213.211
+185.18.213.218
+185.18.213.224
+185.18.213.225
+185.18.213.226
+185.18.213.227
+185.18.214.23
+185.18.214.26
+185.18.214.28
+185.18.214.76
+185.18.214.82
+185.18.214.92
+185.18.214.130
+185.18.214.154
+185.18.214.243
+185.18.214.249
+185.18.214.250
+185.18.215.6
+185.18.215.18
+185.18.215.35
+185.18.215.42
+185.18.215.43
+185.18.215.109
+185.18.215.110
+185.18.215.120
+185.18.215.134
+185.18.215.136
+185.18.215.138
+185.18.215.209
+185.18.215.213
+185.18.215.214
+185.18.215.241
+185.19.201.19
+185.19.201.21
+185.19.201.25
+185.19.201.39
+185.19.201.41
+185.19.201.43
+185.19.201.49
+185.19.201.59
+185.19.201.60
+185.19.201.65
+185.19.201.78
+185.19.201.89
+185.19.201.106
+185.19.201.110
+185.19.201.116
+185.19.201.125
+185.19.201.142
+185.19.201.144
+185.19.201.148
+185.19.201.162
+185.19.201.167
+185.19.201.183
+185.19.201.190
+185.19.201.200
+185.20.162.8
+185.20.162.9
+185.21.70.234
+185.24.136.90
+185.24.139.71
+185.24.139.91
+185.24.252.133
+185.24.252.166
+185.24.252.195
+185.24.252.199
+185.24.255.71
+185.24.255.75
+185.24.255.195
+185.24.255.200
+185.26.32.33
+185.26.32.137
+185.31.124.3
+185.31.124.7
+185.31.125.3
+185.31.125.7
+185.31.126.3
+185.31.127.3
+185.36.228.117
+185.36.228.160
+185.36.228.161
+185.36.228.174
+185.36.231.11
+185.36.231.47
+185.36.231.88
+185.36.231.91
+185.36.231.93
+185.36.231.157
+185.36.231.231
+185.37.52.36
+185.37.52.37
+185.37.52.126
+185.37.53.209
+185.37.54.19
+185.37.54.20
+185.37.54.30
+185.37.54.112
+185.37.54.113
+185.37.54.133
+185.37.54.152
+185.37.54.191
+185.37.54.253
+185.37.54.254
+185.37.55.30
+185.37.55.127
+185.37.55.169
+185.37.55.203
+185.37.55.243
+185.37.55.247
+185.39.180.119
+185.39.180.120
+185.39.180.181
+185.39.182.228
+185.39.182.230
+185.39.182.232
+185.39.182.233
+185.39.182.234
+185.40.16.42
+185.40.16.194
+185.40.16.198
+185.41.1.130
+185.41.1.134
+185.41.1.141
+185.41.3.2
+185.41.3.3
+185.41.3.4
+185.41.3.6
+185.41.3.7
+185.41.3.8
+185.41.3.9
+185.41.3.10
+185.41.3.11
+185.41.3.12
+185.41.3.13
+185.41.3.14
+185.41.3.15
+185.41.3.16
+185.41.3.17
+185.41.3.18
+185.41.3.19
+185.41.3.20
+185.41.3.21
+185.41.3.22
+185.41.3.23
+185.41.3.24
+185.41.3.25
+185.41.3.26
+185.41.3.27
+185.41.3.28
+185.41.3.29
+185.41.3.30
+185.41.3.34
+185.41.3.98
+185.41.3.99
+185.41.3.100
+185.41.3.101
+185.41.3.102
+185.41.3.103
+185.41.3.104
+185.41.3.105
+185.41.3.107
+185.41.3.108
+185.41.3.109
+185.41.3.110
+185.41.3.111
+185.41.3.112
+185.41.3.113
+185.41.3.114
+185.41.3.115
+185.41.3.116
+185.41.3.117
+185.41.3.118
+185.41.3.119
+185.41.3.120
+185.41.3.121
+185.41.3.122
+185.41.3.123
+185.41.3.124
+185.41.3.125
+185.41.3.126
+185.42.224.5
+185.42.224.7
+185.42.225.31
+185.42.226.18
+185.44.36.36
+185.44.36.216
+185.44.36.248
+185.46.217.234
+185.47.48.26
+185.47.50.162
+185.47.50.166
+185.49.84.18
+185.49.84.34
+185.49.84.51
+185.49.84.68
+185.49.84.83
+185.49.84.84
+185.49.84.90
+185.49.84.91
+185.49.84.92
+185.49.84.93
+185.49.84.134
+185.49.84.143
+185.49.84.157
+185.49.84.166
+185.49.84.209
+185.49.84.226
+185.49.84.228
+185.49.84.229
+185.49.84.230
+185.49.84.231
+185.49.84.232
+185.49.84.233
+185.49.84.234
+185.49.84.235
+185.49.84.236
+185.49.84.237
+185.49.84.238
+185.49.84.239
+185.49.84.240
+185.49.84.241
+185.49.84.242
+185.49.84.243
+185.49.84.244
+185.49.84.245
+185.49.84.246
+185.49.84.248
+185.49.84.252
+185.49.85.2
+185.49.85.5
+185.49.85.19
+185.49.85.27
+185.49.85.28
+185.49.85.34
+185.49.85.35
+185.49.85.36
+185.49.85.37
+185.49.85.38
+185.49.85.39
+185.49.85.40
+185.49.85.41
+185.49.85.42
+185.49.85.43
+185.49.85.44
+185.49.85.45
+185.49.85.46
+185.49.85.130
+185.49.85.131
+185.49.85.133
+185.49.85.135
+185.49.85.138
+185.49.85.142
+185.49.85.143
+185.49.85.146
+185.49.85.149
+185.49.85.152
+185.49.85.154
+185.49.85.157
+185.49.85.163
+185.49.85.168
+185.49.85.172
+185.49.85.173
+185.49.85.204
+185.49.85.206
+185.49.85.212
+185.49.85.244
+185.49.86.13
+185.49.86.42
+185.49.86.56
+185.49.86.57
+185.49.86.111
+185.49.86.194
+185.49.86.202
+185.49.86.213
+185.49.87.94
+185.49.87.180
+185.49.87.181
+185.49.87.182
+185.49.87.218
+185.49.87.219
+185.49.87.240
+185.49.96.252
+185.49.96.253
+185.50.37.15
+185.50.37.46
+185.50.37.48
+185.50.37.52
+185.50.37.56
+185.50.37.66
+185.50.37.91
+185.50.37.166
+185.50.37.168
+185.50.37.171
+185.50.37.174
+185.50.37.175
+185.50.38.29
+185.50.38.33
+185.50.38.38
+185.50.38.72
+185.50.38.128
+185.50.38.135
+185.50.38.145
+185.50.38.148
+185.50.38.168
+185.50.38.171
+185.50.38.191
+185.50.38.201
+185.50.38.216
+185.50.38.220
+185.50.38.225
+185.50.38.236
+185.50.39.3
+185.50.39.32
+185.50.39.49
+185.50.39.50
+185.50.39.53
+185.50.39.94
+185.50.39.96
+185.50.39.97
+185.50.39.159
+185.51.43.2
+185.51.200.1
+185.51.200.5
+185.51.200.58
+185.51.200.182
+185.51.201.58
+185.51.201.77
+185.51.201.195
+185.51.201.255
+185.51.202.251
+185.53.140.6
+185.53.140.43
+185.53.141.45
+185.53.141.54
+185.53.141.120
+185.53.141.182
+185.53.141.187
+185.53.141.194
+185.53.141.195
+185.53.141.218
+185.53.141.229
+185.53.142.2
+185.53.142.3
+185.53.142.4
+185.53.142.5
+185.53.142.6
+185.53.142.35
+185.53.142.37
+185.53.142.123
+185.53.142.174
+185.53.142.180
+185.53.142.211
+185.53.142.212
+185.53.142.213
+185.53.142.214
+185.53.143.3
+185.53.143.74
+185.53.143.133
+185.53.143.134
+185.53.143.135
+185.53.143.136
+185.53.143.137
+185.53.143.139
+185.53.143.141
+185.53.143.142
+185.53.143.143
+185.53.143.146
+185.53.143.156
+185.53.143.157
+185.53.143.186
+185.53.143.244
+185.55.224.3
+185.55.224.4
+185.55.224.8
+185.55.224.10
+185.55.224.11
+185.55.224.12
+185.55.224.13
+185.55.224.14
+185.55.224.15
+185.55.224.16
+185.55.224.17
+185.55.224.18
+185.55.224.20
+185.55.224.21
+185.55.224.22
+185.55.224.23
+185.55.224.27
+185.55.224.28
+185.55.224.29
+185.55.224.30
+185.55.224.31
+185.55.224.32
+185.55.224.33
+185.55.224.34
+185.55.224.35
+185.55.224.36
+185.55.224.38
+185.55.224.39
+185.55.224.45
+185.55.224.46
+185.55.224.48
+185.55.224.49
+185.55.224.50
+185.55.224.51
+185.55.224.52
+185.55.224.53
+185.55.224.54
+185.55.224.55
+185.55.224.56
+185.55.224.57
+185.55.224.59
+185.55.224.60
+185.55.224.61
+185.55.224.62
+185.55.224.63
+185.55.224.64
+185.55.224.65
+185.55.224.66
+185.55.224.67
+185.55.224.68
+185.55.224.69
+185.55.224.70
+185.55.224.71
+185.55.224.72
+185.55.224.73
+185.55.224.74
+185.55.224.75
+185.55.224.76
+185.55.224.77
+185.55.224.78
+185.55.224.80
+185.55.224.81
+185.55.224.82
+185.55.224.83
+185.55.224.84
+185.55.224.85
+185.55.224.86
+185.55.224.87
+185.55.224.88
+185.55.224.93
+185.55.224.94
+185.55.224.96
+185.55.224.97
+185.55.224.98
+185.55.224.99
+185.55.224.101
+185.55.224.102
+185.55.224.104
+185.55.224.105
+185.55.224.106
+185.55.224.108
+185.55.224.110
+185.55.224.111
+185.55.224.112
+185.55.224.113
+185.55.224.114
+185.55.224.117
+185.55.224.118
+185.55.224.120
+185.55.224.122
+185.55.224.123
+185.55.224.124
+185.55.224.125
+185.55.224.126
+185.55.224.127
+185.55.224.128
+185.55.224.129
+185.55.224.132
+185.55.224.134
+185.55.224.135
+185.55.224.136
+185.55.224.137
+185.55.224.138
+185.55.224.139
+185.55.224.140
+185.55.224.141
+185.55.224.142
+185.55.224.143
+185.55.224.144
+185.55.224.145
+185.55.224.146
+185.55.224.148
+185.55.224.149
+185.55.224.150
+185.55.224.152
+185.55.224.153
+185.55.224.154
+185.55.224.155
+185.55.224.156
+185.55.224.157
+185.55.224.158
+185.55.224.159
+185.55.224.160
+185.55.224.161
+185.55.224.162
+185.55.224.165
+185.55.224.166
+185.55.224.172
+185.55.224.179
+185.55.224.180
+185.55.224.181
+185.55.224.182
+185.55.224.183
+185.55.224.184
+185.55.224.185
+185.55.224.188
+185.55.224.191
+185.55.224.192
+185.55.224.194
+185.55.224.195
+185.55.224.196
+185.55.224.197
+185.55.224.198
+185.55.224.199
+185.55.224.201
+185.55.224.203
+185.55.224.204
+185.55.224.206
+185.55.224.207
+185.55.224.208
+185.55.224.209
+185.55.224.211
+185.55.224.212
+185.55.224.213
+185.55.224.215
+185.55.224.216
+185.55.224.217
+185.55.224.218
+185.55.224.219
+185.55.224.220
+185.55.224.221
+185.55.224.227
+185.55.224.229
+185.55.224.230
+185.55.224.231
+185.55.224.232
+185.55.224.233
+185.55.224.234
+185.55.224.235
+185.55.224.236
+185.55.224.237
+185.55.224.245
+185.55.224.246
+185.55.224.247
+185.55.224.251
+185.55.225.2
+185.55.225.3
+185.55.225.4
+185.55.225.5
+185.55.225.6
+185.55.225.7
+185.55.225.8
+185.55.225.9
+185.55.225.10
+185.55.225.11
+185.55.225.15
+185.55.225.16
+185.55.225.17
+185.55.225.18
+185.55.225.19
+185.55.225.20
+185.55.225.21
+185.55.225.22
+185.55.225.23
+185.55.225.24
+185.55.225.26
+185.55.225.27
+185.55.225.28
+185.55.225.29
+185.55.225.34
+185.55.225.35
+185.55.225.36
+185.55.225.37
+185.55.225.38
+185.55.225.39
+185.55.225.41
+185.55.225.42
+185.55.225.43
+185.55.225.44
+185.55.225.45
+185.55.225.46
+185.55.225.47
+185.55.225.48
+185.55.225.49
+185.55.225.50
+185.55.225.51
+185.55.225.52
+185.55.225.53
+185.55.225.54
+185.55.225.55
+185.55.225.56
+185.55.225.57
+185.55.225.59
+185.55.225.60
+185.55.225.61
+185.55.225.62
+185.55.225.63
+185.55.225.65
+185.55.225.66
+185.55.225.67
+185.55.225.69
+185.55.225.72
+185.55.225.73
+185.55.225.77
+185.55.225.78
+185.55.225.79
+185.55.225.80
+185.55.225.81
+185.55.225.82
+185.55.225.83
+185.55.225.84
+185.55.225.85
+185.55.225.86
+185.55.225.87
+185.55.225.88
+185.55.225.89
+185.55.225.90
+185.55.225.91
+185.55.225.92
+185.55.225.93
+185.55.225.94
+185.55.225.95
+185.55.225.96
+185.55.225.98
+185.55.225.99
+185.55.225.100
+185.55.225.102
+185.55.225.103
+185.55.225.104
+185.55.225.105
+185.55.225.106
+185.55.225.107
+185.55.225.108
+185.55.225.110
+185.55.225.111
+185.55.225.112
+185.55.225.113
+185.55.225.114
+185.55.225.115
+185.55.225.116
+185.55.225.117
+185.55.225.118
+185.55.225.119
+185.55.225.120
+185.55.225.121
+185.55.225.122
+185.55.225.123
+185.55.225.124
+185.55.225.125
+185.55.225.126
+185.55.225.127
+185.55.225.128
+185.55.225.129
+185.55.225.130
+185.55.225.131
+185.55.225.132
+185.55.225.133
+185.55.225.134
+185.55.225.135
+185.55.225.136
+185.55.225.137
+185.55.225.138
+185.55.225.139
+185.55.225.140
+185.55.225.141
+185.55.225.142
+185.55.225.143
+185.55.225.144
+185.55.225.145
+185.55.225.146
+185.55.225.147
+185.55.225.148
+185.55.225.149
+185.55.225.152
+185.55.225.153
+185.55.225.154
+185.55.225.155
+185.55.225.156
+185.55.225.157
+185.55.225.159
+185.55.225.160
+185.55.225.161
+185.55.225.162
+185.55.225.164
+185.55.225.165
+185.55.225.166
+185.55.225.167
+185.55.225.168
+185.55.225.169
+185.55.225.170
+185.55.225.172
+185.55.225.173
+185.55.225.174
+185.55.225.175
+185.55.225.177
+185.55.225.178
+185.55.225.179
+185.55.225.180
+185.55.225.181
+185.55.225.183
+185.55.225.184
+185.55.225.185
+185.55.225.186
+185.55.225.187
+185.55.225.188
+185.55.225.191
+185.55.225.192
+185.55.225.193
+185.55.225.194
+185.55.225.195
+185.55.225.196
+185.55.225.197
+185.55.225.198
+185.55.225.199
+185.55.225.200
+185.55.225.201
+185.55.225.202
+185.55.225.203
+185.55.225.204
+185.55.225.205
+185.55.225.206
+185.55.225.207
+185.55.225.208
+185.55.225.209
+185.55.225.211
+185.55.225.212
+185.55.225.213
+185.55.225.214
+185.55.225.215
+185.55.225.216
+185.55.225.217
+185.55.225.218
+185.55.225.219
+185.55.225.220
+185.55.225.221
+185.55.225.222
+185.55.225.223
+185.55.225.224
+185.55.225.225
+185.55.225.227
+185.55.225.228
+185.55.225.229
+185.55.225.230
+185.55.225.231
+185.55.225.232
+185.55.225.233
+185.55.225.234
+185.55.225.235
+185.55.225.236
+185.55.225.237
+185.55.225.240
+185.55.225.241
+185.55.225.242
+185.55.225.243
+185.55.225.244
+185.55.225.245
+185.55.225.246
+185.55.225.247
+185.55.225.248
+185.55.225.251
+185.55.226.20
+185.55.226.39
+185.55.226.100
+185.55.226.116
+185.55.226.121
+185.55.226.124
+185.55.226.145
+185.55.226.171
+185.55.226.173
+185.55.226.181
+185.55.226.194
+185.55.226.211
+185.55.226.226
+185.55.226.231
+185.55.226.239
+185.55.227.2
+185.55.227.7
+185.55.227.9
+185.55.227.12
+185.55.227.15
+185.55.227.20
+185.55.227.21
+185.55.227.22
+185.55.227.23
+185.55.227.24
+185.55.227.26
+185.55.227.29
+185.55.227.31
+185.55.227.32
+185.55.227.33
+185.55.227.35
+185.55.227.44
+185.55.227.49
+185.55.227.50
+185.55.227.51
+185.55.227.53
+185.55.227.54
+185.55.227.55
+185.55.227.56
+185.55.227.57
+185.55.227.58
+185.55.227.59
+185.55.227.60
+185.55.227.61
+185.55.227.62
+185.55.227.63
+185.55.227.64
+185.55.227.65
+185.55.227.66
+185.55.227.67
+185.55.227.68
+185.55.227.69
+185.55.227.70
+185.55.227.71
+185.55.227.72
+185.55.227.73
+185.55.227.76
+185.55.227.77
+185.55.227.78
+185.55.227.79
+185.55.227.80
+185.55.227.81
+185.55.227.82
+185.55.227.83
+185.55.227.84
+185.55.227.85
+185.55.227.86
+185.55.227.87
+185.55.227.88
+185.55.227.89
+185.55.227.91
+185.55.227.92
+185.55.227.93
+185.55.227.94
+185.55.227.95
+185.55.227.96
+185.55.227.97
+185.55.227.98
+185.55.227.99
+185.55.227.100
+185.55.227.102
+185.55.227.103
+185.55.227.104
+185.55.227.106
+185.55.227.107
+185.55.227.108
+185.55.227.109
+185.55.227.110
+185.55.227.111
+185.55.227.112
+185.55.227.113
+185.55.227.114
+185.55.227.115
+185.55.227.116
+185.55.227.117
+185.55.227.118
+185.55.227.119
+185.55.227.120
+185.55.227.122
+185.55.227.123
+185.55.227.124
+185.55.227.125
+185.55.227.126
+185.55.227.127
+185.55.227.128
+185.55.227.129
+185.55.227.130
+185.55.227.131
+185.55.227.132
+185.55.227.133
+185.55.227.134
+185.55.227.139
+185.55.227.140
+185.55.227.144
+185.55.227.145
+185.55.227.146
+185.55.227.148
+185.55.227.149
+185.55.227.150
+185.55.227.151
+185.55.227.152
+185.55.227.153
+185.55.227.154
+185.55.227.155
+185.55.227.156
+185.55.227.157
+185.55.227.158
+185.55.227.159
+185.55.227.160
+185.55.227.161
+185.55.227.162
+185.55.227.163
+185.55.227.164
+185.55.227.165
+185.55.227.166
+185.55.227.168
+185.55.227.169
+185.55.227.171
+185.55.227.172
+185.55.227.174
+185.55.227.176
+185.55.227.177
+185.55.227.178
+185.55.227.179
+185.55.227.180
+185.55.227.181
+185.55.227.182
+185.55.227.183
+185.55.227.184
+185.55.227.185
+185.55.227.189
+185.55.227.190
+185.55.227.191
+185.55.227.194
+185.55.227.196
+185.55.227.197
+185.55.227.198
+185.55.227.199
+185.55.227.201
+185.55.227.202
+185.55.227.203
+185.55.227.204
+185.55.227.206
+185.55.227.207
+185.55.227.208
+185.55.227.210
+185.55.227.211
+185.55.227.213
+185.55.227.215
+185.55.227.216
+185.55.227.218
+185.55.227.220
+185.55.227.222
+185.55.227.223
+185.55.227.224
+185.55.227.225
+185.55.227.226
+185.55.227.228
+185.55.227.229
+185.55.227.231
+185.55.227.233
+185.55.227.235
+185.55.227.236
+185.55.227.239
+185.55.227.240
+185.55.227.241
+185.55.227.243
+185.55.227.245
+185.56.93.100
+185.56.93.101
+185.57.164.4
+185.57.164.5
+185.57.164.177
+185.57.165.93
+185.58.240.15
+185.58.240.80
+185.58.240.81
+185.58.240.105
+185.58.240.114
+185.58.240.115
+185.58.240.120
+185.58.240.167
+185.58.240.216
+185.58.240.251
+185.58.241.5
+185.58.241.12
+185.58.241.27
+185.58.241.44
+185.58.241.54
+185.58.241.62
+185.58.241.139
+185.58.241.148
+185.58.241.169
+185.58.241.225
+185.58.241.226
+185.58.241.227
+185.58.241.235
+185.58.242.19
+185.58.242.37
+185.58.242.129
+185.58.242.215
+185.58.242.230
+185.58.242.236
+185.58.242.253
+185.58.243.65
+185.59.112.218
+185.60.136.90
+185.60.136.128
+185.60.136.140
+185.60.137.149
+185.63.113.16
+185.63.113.17
+185.63.113.18
+185.63.113.20
+185.63.113.25
+185.63.113.30
+185.63.113.35
+185.63.113.37
+185.63.113.131
+185.63.113.134
+185.63.113.137
+185.63.113.141
+185.63.113.145
+185.63.113.148
+185.63.113.156
+185.63.113.158
+185.63.113.173
+185.63.113.194
+185.63.113.196
+185.63.113.211
+185.63.113.212
+185.63.113.219
+185.63.113.236
+185.63.113.242
+185.63.113.245
+185.63.114.119
+185.63.237.12
+185.66.224.4
+185.66.224.24
+185.66.226.83
+185.66.230.194
+185.66.230.195
+185.66.230.253
+185.67.12.11
+185.67.12.12
+185.67.14.11
+185.67.156.5
+185.67.156.7
+185.67.213.50
+185.67.214.50
+185.71.193.84
+185.71.194.171
+185.72.25.204
+185.72.25.205
+185.72.25.226
+185.73.78.10
+185.73.112.39
+185.73.112.41
+185.73.112.62
+185.73.112.163
+185.73.112.180
+185.73.112.227
+185.73.112.228
+185.73.114.28
+185.73.114.67
+185.73.114.82
+185.73.114.86
+185.73.114.123
+185.73.114.207
+185.73.114.232
+185.73.114.247
+185.73.114.254
+185.73.226.237
+185.73.226.241
+185.73.226.242
+185.73.226.243
+185.74.221.2
+185.74.221.51
+185.74.221.155
+185.74.221.180
+185.74.221.197
+185.74.221.238
+185.78.21.33
+185.78.21.35
+185.78.21.40
+185.78.21.42
+185.78.21.43
+185.78.21.49
+185.78.21.50
+185.78.21.51
+185.78.22.2
+185.78.22.174
+185.78.22.175
+185.78.23.202
+185.79.62.4
+185.79.62.5
+185.79.96.67
+185.79.156.78
+185.79.156.88
+185.79.156.92
+185.79.156.105
+185.79.156.107
+185.79.156.122
+185.79.156.132
+185.79.156.148
+185.79.156.149
+185.79.156.151
+185.79.156.155
+185.79.156.160
+185.79.156.165
+185.79.156.172
+185.79.156.173
+185.79.156.174
+185.79.156.199
+185.79.156.214
+185.79.156.228
+185.79.156.229
+185.79.156.234
+185.79.157.2
+185.79.157.3
+185.79.157.5
+185.79.157.7
+185.79.157.16
+185.79.157.23
+185.79.157.60
+185.79.157.153
+185.79.157.161
+185.79.157.188
+185.79.157.192
+185.79.157.195
+185.79.157.199
+185.79.157.205
+185.79.157.208
+185.79.157.232
+185.79.157.247
+185.79.157.254
+185.79.158.8
+185.79.158.22
+185.79.158.23
+185.79.158.33
+185.79.158.75
+185.79.158.165
+185.79.158.166
+185.79.158.169
+185.79.158.212
+185.79.159.136
+185.81.96.5
+185.81.96.10
+185.81.96.15
+185.81.96.16
+185.81.96.20
+185.81.96.27
+185.81.96.28
+185.81.96.31
+185.81.96.35
+185.81.96.38
+185.81.96.42
+185.81.96.103
+185.81.96.114
+185.81.96.129
+185.81.96.195
+185.81.96.211
+185.81.96.221
+185.81.96.240
+185.81.97.5
+185.81.97.17
+185.81.97.25
+185.81.97.26
+185.81.97.28
+185.81.97.55
+185.81.97.56
+185.81.97.59
+185.81.97.69
+185.81.97.77
+185.81.97.89
+185.81.97.148
+185.81.97.155
+185.81.97.163
+185.81.97.165
+185.81.97.175
+185.81.97.181
+185.81.97.191
+185.81.97.193
+185.81.97.222
+185.81.97.235
+185.81.97.250
+185.81.99.46
+185.81.99.76
+185.81.99.119
+185.81.99.120
+185.81.99.123
+185.81.99.135
+185.81.99.140
+185.81.99.151
+185.81.99.156
+185.81.99.171
+185.81.99.185
+185.81.99.222
+185.81.99.223
+185.81.99.228
+185.81.99.239
+185.82.136.19
+185.82.216.236
+185.83.88.19
+185.83.88.23
+185.83.88.24
+185.83.88.27
+185.83.91.3
+185.83.112.67
+185.83.112.99
+185.83.112.110
+185.83.112.212
+185.83.113.28
+185.83.113.39
+185.83.113.46
+185.83.113.57
+185.83.113.59
+185.83.113.77
+185.83.113.78
+185.83.113.80
+185.83.113.92
+185.83.113.104
+185.83.113.123
+185.83.113.124
+185.83.113.142
+185.83.113.172
+185.83.113.176
+185.83.113.178
+185.83.113.180
+185.83.113.184
+185.83.113.192
+185.83.113.198
+185.83.113.210
+185.83.113.213
+185.83.113.214
+185.83.113.216
+185.83.113.217
+185.83.113.218
+185.83.113.219
+185.83.113.220
+185.83.113.225
+185.83.113.226
+185.83.113.227
+185.83.113.228
+185.83.113.230
+185.83.113.231
+185.83.113.234
+185.83.113.236
+185.83.113.241
+185.83.113.244
+185.83.113.246
+185.83.113.247
+185.83.113.251
+185.83.113.252
+185.83.114.57
+185.83.114.67
+185.83.114.69
+185.83.114.75
+185.83.114.110
+185.83.114.116
+185.83.114.118
+185.83.114.122
+185.83.114.128
+185.83.114.142
+185.83.114.148
+185.83.114.153
+185.83.114.159
+185.83.114.162
+185.83.114.172
+185.83.114.186
+185.83.114.244
+185.83.114.251
+185.83.115.42
+185.83.115.43
+185.83.115.44
+185.83.115.46
+185.83.115.182
+185.83.181.58
+185.83.181.100
+185.83.181.101
+185.83.181.120
+185.83.181.121
+185.83.181.190
+185.83.182.19
+185.83.182.22
+185.83.182.29
+185.83.182.85
+185.83.182.107
+185.83.182.120
+185.83.182.172
+185.83.183.3
+185.83.183.4
+185.83.183.5
+185.83.183.8
+185.83.183.14
+185.83.183.17
+185.83.183.19
+185.83.183.23
+185.83.183.24
+185.83.183.27
+185.83.183.30
+185.83.183.37
+185.83.183.38
+185.83.183.39
+185.83.183.41
+185.83.183.44
+185.83.183.45
+185.83.183.46
+185.83.183.49
+185.83.183.56
+185.83.183.57
+185.83.183.59
+185.83.183.92
+185.83.183.94
+185.83.183.97
+185.83.183.99
+185.83.183.100
+185.83.183.102
+185.83.183.107
+185.83.183.114
+185.83.183.115
+185.83.183.116
+185.83.183.128
+185.83.183.130
+185.83.183.131
+185.83.183.132
+185.83.183.134
+185.83.183.135
+185.83.183.136
+185.83.183.139
+185.83.183.147
+185.83.183.152
+185.83.183.153
+185.83.183.154
+185.83.183.159
+185.83.183.161
+185.83.183.163
+185.83.183.164
+185.83.183.184
+185.83.183.187
+185.83.183.195
+185.83.183.197
+185.83.183.199
+185.83.183.200
+185.83.183.202
+185.83.183.203
+185.83.183.205
+185.83.183.207
+185.83.183.210
+185.83.183.215
+185.83.183.216
+185.83.183.217
+185.83.183.218
+185.83.183.220
+185.83.183.221
+185.83.183.223
+185.83.183.225
+185.83.183.228
+185.83.183.229
+185.83.183.234
+185.83.183.236
+185.83.183.240
+185.83.183.241
+185.83.183.242
+185.83.183.244
+185.83.183.245
+185.83.183.246
+185.83.183.247
+185.83.183.248
+185.83.183.249
+185.83.183.254
+185.83.197.81
+185.83.197.83
+185.83.197.84
+185.83.197.87
+185.83.198.46
+185.83.199.97
+185.83.208.2
+185.83.208.3
+185.83.208.10
+185.83.208.13
+185.83.208.14
+185.83.208.15
+185.83.208.23
+185.83.208.24
+185.83.208.25
+185.83.208.26
+185.83.208.35
+185.83.208.39
+185.83.208.43
+185.83.208.44
+185.83.208.45
+185.83.208.106
+185.83.208.109
+185.83.208.111
+185.83.208.112
+185.83.208.114
+185.83.208.115
+185.83.208.116
+185.83.208.118
+185.83.208.119
+185.83.208.136
+185.83.208.140
+185.83.208.150
+185.83.208.158
+185.83.208.160
+185.83.208.162
+185.83.208.167
+185.83.208.169
+185.83.208.172
+185.83.208.173
+185.83.208.174
+185.83.208.175
+185.83.208.177
+185.83.208.182
+185.83.208.184
+185.83.208.188
+185.83.208.189
+185.83.208.201
+185.83.208.204
+185.83.208.205
+185.83.208.207
+185.83.208.208
+185.83.208.209
+185.83.208.226
+185.83.208.234
+185.83.208.249
+185.83.209.9
+185.83.209.10
+185.83.209.34
+185.83.209.35
+185.83.209.36
+185.83.209.37
+185.83.209.38
+185.83.209.39
+185.83.210.2
+185.83.210.3
+185.83.210.5
+185.83.210.6
+185.83.210.7
+185.83.210.9
+185.83.210.14
+185.83.210.34
+185.83.210.66
+185.83.210.67
+185.83.210.68
+185.83.210.70
+185.83.210.82
+185.83.210.98
+185.83.210.136
+185.83.210.138
+185.83.210.143
+185.83.210.184
+185.84.158.6
+185.84.158.79
+185.84.220.5
+185.84.222.22
+185.86.36.97
+185.86.36.98
+185.86.36.99
+185.86.36.100
+185.86.36.101
+185.86.36.102
+185.86.36.103
+185.86.36.104
+185.86.36.105
+185.86.36.106
+185.86.36.107
+185.86.36.108
+185.86.36.109
+185.86.36.161
+185.86.36.185
+185.86.36.201
+185.86.36.202
+185.86.180.71
+185.86.180.218
+185.86.181.21
+185.86.181.28
+185.86.181.29
+185.86.181.30
+185.86.181.102
+185.86.181.106
+185.86.181.108
+185.86.181.117
+185.86.181.146
+185.86.181.182
+185.86.181.183
+185.86.181.184
+185.86.181.214
+185.86.181.235
+185.86.181.237
+185.86.181.238
+185.88.152.3
+185.88.152.4
+185.88.152.12
+185.88.152.16
+185.88.152.22
+185.88.152.26
+185.88.152.27
+185.88.152.31
+185.88.152.40
+185.88.152.41
+185.88.152.42
+185.88.152.44
+185.88.152.45
+185.88.152.46
+185.88.152.63
+185.88.152.64
+185.88.152.66
+185.88.152.68
+185.88.152.70
+185.88.152.76
+185.88.152.77
+185.88.152.78
+185.88.152.81
+185.88.152.85
+185.88.152.86
+185.88.152.87
+185.88.152.88
+185.88.152.92
+185.88.152.93
+185.88.152.94
+185.88.152.97
+185.88.152.98
+185.88.152.103
+185.88.152.109
+185.88.152.110
+185.88.152.113
+185.88.152.115
+185.88.152.117
+185.88.152.123
+185.88.152.124
+185.88.152.126
+185.88.152.127
+185.88.152.129
+185.88.152.130
+185.88.152.134
+185.88.152.138
+185.88.152.140
+185.88.152.142
+185.88.152.154
+185.88.152.156
+185.88.152.161
+185.88.152.162
+185.88.152.163
+185.88.152.173
+185.88.152.178
+185.88.152.186
+185.88.152.187
+185.88.152.192
+185.88.152.193
+185.88.152.197
+185.88.152.199
+185.88.152.201
+185.88.152.202
+185.88.152.206
+185.88.152.213
+185.88.152.215
+185.88.152.218
+185.88.152.222
+185.88.152.223
+185.88.152.228
+185.88.152.232
+185.88.152.236
+185.88.152.238
+185.88.152.242
+185.88.152.248
+185.88.152.250
+185.88.152.254
+185.88.153.10
+185.88.153.15
+185.88.153.18
+185.88.153.20
+185.88.153.29
+185.88.153.31
+185.88.153.33
+185.88.153.34
+185.88.153.39
+185.88.153.42
+185.88.153.43
+185.88.153.50
+185.88.153.52
+185.88.153.64
+185.88.153.66
+185.88.153.67
+185.88.153.70
+185.88.153.71
+185.88.153.72
+185.88.153.75
+185.88.153.76
+185.88.153.80
+185.88.153.82
+185.88.153.83
+185.88.153.85
+185.88.153.88
+185.88.153.90
+185.88.153.98
+185.88.153.99
+185.88.153.103
+185.88.153.104
+185.88.153.108
+185.88.153.111
+185.88.153.112
+185.88.153.115
+185.88.153.116
+185.88.153.117
+185.88.153.118
+185.88.153.119
+185.88.153.122
+185.88.153.123
+185.88.153.124
+185.88.153.128
+185.88.153.130
+185.88.153.146
+185.88.153.147
+185.88.153.150
+185.88.153.153
+185.88.153.162
+185.88.153.166
+185.88.153.169
+185.88.153.170
+185.88.153.172
+185.88.153.173
+185.88.153.179
+185.88.153.180
+185.88.153.186
+185.88.153.189
+185.88.153.191
+185.88.153.196
+185.88.153.198
+185.88.153.199
+185.88.153.214
+185.88.153.218
+185.88.153.219
+185.88.153.222
+185.88.153.227
+185.88.153.228
+185.88.153.233
+185.88.153.234
+185.88.153.237
+185.88.153.240
+185.88.153.241
+185.88.153.243
+185.88.153.249
+185.88.153.254
+185.88.154.2
+185.88.154.22
+185.88.154.23
+185.88.154.26
+185.88.154.27
+185.88.154.29
+185.88.154.32
+185.88.154.35
+185.88.154.37
+185.88.154.38
+185.88.154.40
+185.88.154.41
+185.88.154.47
+185.88.154.55
+185.88.154.56
+185.88.154.62
+185.88.154.71
+185.88.154.76
+185.88.154.78
+185.88.154.85
+185.88.154.101
+185.88.154.108
+185.88.154.111
+185.88.154.116
+185.88.154.121
+185.88.154.123
+185.88.154.124
+185.88.154.125
+185.88.154.126
+185.88.154.128
+185.88.154.129
+185.88.154.130
+185.88.154.133
+185.88.154.134
+185.88.154.138
+185.88.154.151
+185.88.154.153
+185.88.154.160
+185.88.154.167
+185.88.154.174
+185.88.154.175
+185.88.154.181
+185.88.154.183
+185.88.154.187
+185.88.154.189
+185.88.154.192
+185.88.154.195
+185.88.154.197
+185.88.154.198
+185.88.154.215
+185.88.154.221
+185.88.154.224
+185.88.154.225
+185.88.154.233
+185.88.154.235
+185.88.154.240
+185.88.154.242
+185.88.154.248
+185.88.155.7
+185.88.155.53
+185.88.155.98
+185.88.155.122
+185.88.155.125
+185.88.155.150
+185.88.155.166
+185.88.155.167
+185.88.155.172
+185.88.155.189
+185.88.155.192
+185.88.176.138
+185.88.176.152
+185.88.176.210
+185.88.176.211
+185.88.176.212
+185.88.176.213
+185.88.176.218
+185.88.176.219
+185.88.176.221
+185.88.176.222
+185.88.177.2
+185.88.177.3
+185.88.177.5
+185.88.177.6
+185.88.177.7
+185.88.177.8
+185.88.177.9
+185.88.177.17
+185.88.177.18
+185.88.177.19
+185.88.177.20
+185.88.177.22
+185.88.177.25
+185.88.177.26
+185.88.177.27
+185.88.177.33
+185.88.177.34
+185.88.177.35
+185.88.177.50
+185.88.177.55
+185.88.177.56
+185.88.177.57
+185.88.177.60
+185.88.177.64
+185.88.177.67
+185.88.177.68
+185.88.177.69
+185.88.177.70
+185.88.177.72
+185.88.177.79
+185.88.177.81
+185.88.177.88
+185.88.177.90
+185.88.177.92
+185.88.177.94
+185.88.177.103
+185.88.177.104
+185.88.177.105
+185.88.177.110
+185.88.177.111
+185.88.177.112
+185.88.177.113
+185.88.177.117
+185.88.177.118
+185.88.177.120
+185.88.177.122
+185.88.177.123
+185.88.177.124
+185.88.177.135
+185.88.177.138
+185.88.177.139
+185.88.177.140
+185.88.177.141
+185.88.177.142
+185.88.177.143
+185.88.177.144
+185.88.177.145
+185.88.177.146
+185.88.177.147
+185.88.177.148
+185.88.177.149
+185.88.177.150
+185.88.177.151
+185.88.177.152
+185.88.177.153
+185.88.177.154
+185.88.177.155
+185.88.177.156
+185.88.177.157
+185.88.177.159
+185.88.177.162
+185.88.177.163
+185.88.177.164
+185.88.177.165
+185.88.177.167
+185.88.177.173
+185.88.177.175
+185.88.177.181
+185.88.177.182
+185.88.177.183
+185.88.177.184
+185.88.177.185
+185.88.177.188
+185.88.177.199
+185.88.177.206
+185.88.177.214
+185.88.177.222
+185.88.177.223
+185.88.177.226
+185.88.177.227
+185.88.177.228
+185.88.177.231
+185.88.177.232
+185.88.177.233
+185.88.177.236
+185.88.177.242
+185.88.177.243
+185.88.177.244
+185.88.177.246
+185.88.177.247
+185.88.177.248
+185.88.177.250
+185.88.177.252
+185.88.178.5
+185.88.178.6
+185.88.178.7
+185.88.178.9
+185.88.178.11
+185.88.178.15
+185.88.178.16
+185.88.178.17
+185.88.178.18
+185.88.178.20
+185.88.178.27
+185.88.178.28
+185.88.178.30
+185.88.178.35
+185.88.178.38
+185.88.178.39
+185.88.178.40
+185.88.178.42
+185.88.178.44
+185.88.178.45
+185.88.178.47
+185.88.178.49
+185.88.178.52
+185.88.178.55
+185.88.178.56
+185.88.178.58
+185.88.178.66
+185.88.178.67
+185.88.178.68
+185.88.178.69
+185.88.178.71
+185.88.178.72
+185.88.178.73
+185.88.178.75
+185.88.178.76
+185.88.178.77
+185.88.178.81
+185.88.178.89
+185.88.178.90
+185.88.178.91
+185.88.178.98
+185.88.178.101
+185.88.178.102
+185.88.178.103
+185.88.178.106
+185.88.178.107
+185.88.178.108
+185.88.178.109
+185.88.178.110
+185.88.178.113
+185.88.178.115
+185.88.178.117
+185.88.178.118
+185.88.178.119
+185.88.178.122
+185.88.178.123
+185.88.178.125
+185.88.178.132
+185.88.178.158
+185.88.178.177
+185.88.178.179
+185.88.178.196
+185.88.178.197
+185.88.178.199
+185.88.178.202
+185.88.178.206
+185.88.179.68
+185.88.179.71
+185.88.179.72
+185.88.179.73
+185.88.179.74
+185.88.179.76
+185.88.179.78
+185.88.179.83
+185.88.179.85
+185.88.179.87
+185.88.179.88
+185.88.179.90
+185.88.179.91
+185.88.179.92
+185.88.179.146
+185.88.179.148
+185.88.179.149
+185.88.179.196
+185.88.179.197
+185.88.179.198
+185.88.179.199
+185.88.179.200
+185.88.179.201
+185.88.179.202
+185.88.179.203
+185.88.179.204
+185.88.179.206
+185.88.179.211
+185.88.179.212
+185.88.179.213
+185.88.179.217
+185.88.179.218
+185.88.179.219
+185.88.179.226
+185.88.179.230
+185.88.179.231
+185.88.179.236
+185.88.179.237
+185.88.179.238
+185.88.179.252
+185.88.179.253
+185.88.255.10
+185.89.22.2
+185.89.22.6
+185.89.22.14
+185.89.22.100
+185.89.22.138
+185.89.22.186
+185.89.22.194
+185.89.22.210
+185.89.22.234
+185.89.112.20
+185.89.112.26
+185.89.113.121
+185.89.115.195
+185.94.96.2
+185.94.96.6
+185.94.96.10
+185.94.96.22
+185.94.96.34
+185.94.96.38
+185.94.96.42
+185.94.96.46
+185.94.96.56
+185.94.96.58
+185.94.96.76
+185.94.96.87
+185.94.96.89
+185.94.96.98
+185.94.96.100
+185.94.96.101
+185.94.96.102
+185.94.96.106
+185.94.96.110
+185.94.96.118
+185.94.96.130
+185.94.96.134
+185.94.96.138
+185.94.96.146
+185.94.96.154
+185.94.96.158
+185.94.96.162
+185.94.96.174
+185.94.96.178
+185.94.96.186
+185.94.96.190
+185.94.96.194
+185.94.96.196
+185.94.96.197
+185.94.96.204
+185.94.96.207
+185.94.96.210
+185.94.96.214
+185.94.96.216
+185.94.96.217
+185.94.96.218
+185.94.96.226
+185.94.96.229
+185.94.96.231
+185.94.96.233
+185.94.96.237
+185.94.96.242
+185.94.97.2
+185.94.97.5
+185.94.97.6
+185.94.97.7
+185.94.97.8
+185.94.97.9
+185.94.97.10
+185.94.97.13
+185.94.97.14
+185.94.97.18
+185.94.97.30
+185.94.97.34
+185.94.97.37
+185.94.97.46
+185.94.97.50
+185.94.97.54
+185.94.97.62
+185.94.97.74
+185.94.97.85
+185.94.97.87
+185.94.97.90
+185.94.97.92
+185.94.97.98
+185.94.97.102
+185.94.97.150
+185.94.97.198
+185.94.97.206
+185.94.97.210
+185.94.97.222
+185.94.97.227
+185.94.97.229
+185.94.97.230
+185.94.97.231
+185.94.97.233
+185.94.97.235
+185.94.97.236
+185.94.97.254
+185.94.98.3
+185.94.98.4
+185.94.98.6
+185.94.98.11
+185.94.98.17
+185.94.98.34
+185.94.98.42
+185.94.98.44
+185.94.98.45
+185.94.98.54
+185.94.98.69
+185.94.98.74
+185.94.98.78
+185.94.98.90
+185.94.98.92
+185.94.98.93
+185.94.98.94
+185.94.98.110
+185.94.98.114
+185.94.98.117
+185.94.98.118
+185.94.98.119
+185.94.98.121
+185.94.98.122
+185.94.98.123
+185.94.98.126
+185.94.98.130
+185.94.98.133
+185.94.98.134
+185.94.98.146
+185.94.98.151
+185.94.98.156
+185.94.98.171
+185.94.98.172
+185.94.98.194
+185.94.98.197
+185.94.98.198
+185.94.98.199
+185.94.98.201
+185.94.98.202
+185.94.98.203
+185.94.98.205
+185.94.98.206
+185.94.98.209
+185.94.98.216
+185.94.98.218
+185.94.98.227
+185.94.98.229
+185.94.98.230
+185.94.98.234
+185.94.98.236
+185.94.98.237
+185.94.98.242
+185.94.98.250
+185.94.98.251
+185.94.98.252
+185.94.98.253
+185.94.99.11
+185.94.99.13
+185.94.99.15
+185.94.99.18
+185.94.99.27
+185.94.99.36
+185.94.99.45
+185.94.99.50
+185.94.99.70
+185.94.99.82
+185.94.99.93
+185.94.99.100
+185.94.99.103
+185.94.99.105
+185.94.99.106
+185.94.99.130
+185.94.99.138
+185.94.99.142
+185.94.99.162
+185.94.99.166
+185.94.99.170
+185.94.99.171
+185.94.99.172
+185.94.99.174
+185.94.99.178
+185.94.99.181
+185.94.99.195
+185.94.99.201
+185.94.99.202
+185.94.99.203
+185.94.99.204
+185.94.99.209
+185.94.99.211
+185.94.99.215
+185.94.99.219
+185.94.99.220
+185.94.99.226
+185.94.99.228
+185.94.99.229
+185.94.99.230
+185.94.99.231
+185.94.99.232
+185.94.99.233
+185.94.99.234
+185.94.99.235
+185.94.99.236
+185.94.99.237
+185.94.99.238
+185.94.99.239
+185.94.99.240
+185.94.99.241
+185.94.99.243
+185.94.99.244
+185.94.99.246
+185.94.99.247
+185.94.99.248
+185.94.99.249
+185.94.99.250
+185.94.99.251
+185.94.99.253
+185.94.99.254
+185.95.152.11
+185.95.152.12
+185.95.152.155
+185.95.154.130
+185.95.155.164
+185.95.155.167
+185.95.180.131
+185.95.180.230
+185.97.116.107
+185.97.116.131
+185.97.116.166
+185.97.116.180
+185.97.116.204
+185.97.116.205
+185.97.117.54
+185.97.117.66
+185.97.117.159
+185.97.118.139
+185.97.119.4
+185.97.119.111
+185.98.113.34
+185.98.113.113
+185.98.113.115
+185.98.113.141
+185.98.113.142
+185.98.114.114
+185.98.114.116
+185.100.45.85
+185.100.47.7
+185.100.47.8
+185.100.47.11
+185.100.47.16
+185.100.47.82
+185.103.129.109
+185.103.129.113
+185.103.130.201
+185.103.130.202
+185.103.201.147
+185.103.250.250
+185.104.243.9
+185.105.101.58
+185.105.121.10
+185.105.121.11
+185.105.184.40
+185.105.184.41
+185.105.184.42
+185.105.184.52
+185.105.184.53
+185.105.184.70
+185.105.184.76
+185.105.184.89
+185.105.184.91
+185.105.184.108
+185.105.184.121
+185.105.184.205
+185.105.184.206
+185.105.184.227
+185.105.185.25
+185.105.185.28
+185.105.185.36
+185.105.185.41
+185.105.185.149
+185.105.185.151
+185.105.185.155
+185.105.187.14
+185.105.187.160
+185.105.187.186
+185.105.187.189
+185.105.187.226
+185.105.187.242
+185.105.187.243
+185.105.237.96
+185.105.237.252
+185.105.237.253
+185.105.238.196
+185.105.238.200
+185.105.238.210
+185.105.238.253
+185.105.239.10
+185.105.239.11
+185.105.239.29
+185.105.239.50
+185.105.239.68
+185.105.239.78
+185.105.239.79
+185.105.239.97
+185.105.239.102
+185.105.239.104
+185.105.239.107
+185.105.239.115
+185.105.239.119
+185.105.239.123
+185.105.239.129
+185.105.239.132
+185.105.239.139
+185.105.239.141
+185.105.239.169
+185.105.239.172
+185.105.239.175
+185.105.239.178
+185.105.239.187
+185.105.239.189
+185.105.239.191
+185.105.239.194
+185.105.239.198
+185.105.239.201
+185.105.239.208
+185.105.239.211
+185.105.239.214
+185.105.239.216
+185.105.239.217
+185.105.239.220
+185.105.239.231
+185.105.239.232
+185.105.239.236
+185.106.144.149
+185.106.146.179
+185.106.146.180
+185.107.32.115
+185.107.32.117
+185.107.32.120
+185.107.32.122
+185.109.61.27
+185.109.75.241
+185.109.75.242
+185.109.80.137
+185.109.82.15
+185.109.244.91
+185.109.244.94
+185.109.250.245
+185.110.29.251
+185.110.219.23
+185.110.219.139
+185.110.236.10
+185.110.236.120
+185.110.236.122
+185.110.244.7
+185.110.244.23
+185.110.244.98
+185.110.244.105
+185.110.244.112
+185.110.244.120
+185.110.244.150
+185.110.244.151
+185.110.245.16
+185.110.245.19
+185.110.245.26
+185.110.245.30
+185.110.245.83
+185.110.245.94
+185.110.245.100
+185.110.245.140
+185.110.245.178
+185.110.245.187
+185.110.245.197
+185.110.245.213
+185.110.247.9
+185.110.247.11
+185.110.247.16
+185.110.247.63
+185.110.247.72
+185.110.247.93
+185.110.247.101
+185.110.247.110
+185.110.247.118
+185.110.247.154
+185.110.247.179
+185.110.247.195
+185.110.247.213
+185.110.253.2
+185.111.83.58
+185.112.32.43
+185.112.32.45
+185.112.32.52
+185.112.32.56
+185.112.32.62
+185.112.32.212
+185.112.33.51
+185.112.33.54
+185.112.33.60
+185.112.33.107
+185.112.33.110
+185.112.33.219
+185.112.33.220
+185.112.33.221
+185.112.33.222
+185.112.34.83
+185.112.34.92
+185.112.34.139
+185.112.34.181
+185.112.34.235
+185.112.34.236
+185.112.35.2
+185.112.35.20
+185.112.35.38
+185.112.35.194
+185.112.35.195
+185.112.35.196
+185.112.35.197
+185.112.39.18
+185.112.39.33
+185.112.39.112
+185.112.149.98
+185.112.149.116
+185.112.149.117
+185.112.149.119
+185.112.150.7
+185.112.150.13
+185.112.150.54
+185.112.150.55
+185.112.150.56
+185.112.150.92
+185.112.150.134
+185.112.150.149
+185.112.150.204
+185.112.150.242
+185.112.150.246
+185.112.151.97
+185.112.151.198
+185.112.151.213
+185.112.151.214
+185.112.151.231
+185.112.151.232
+185.112.151.249
+185.112.151.254
+185.113.9.3
+185.113.9.5
+185.113.9.6
+185.113.9.7
+185.113.9.9
+185.113.9.10
+185.113.9.13
+185.113.9.16
+185.113.9.18
+185.113.9.20
+185.113.9.22
+185.113.9.24
+185.113.9.33
+185.113.9.34
+185.113.9.35
+185.113.9.37
+185.113.9.38
+185.113.9.43
+185.113.9.44
+185.113.9.45
+185.113.9.46
+185.113.9.47
+185.113.9.48
+185.113.9.49
+185.113.9.50
+185.113.9.52
+185.113.9.53
+185.113.9.54
+185.113.9.55
+185.113.9.57
+185.113.9.61
+185.113.9.65
+185.113.9.66
+185.113.9.68
+185.113.9.71
+185.113.9.73
+185.113.9.74
+185.113.9.75
+185.113.9.76
+185.113.9.77
+185.113.9.80
+185.113.9.82
+185.113.9.86
+185.113.9.87
+185.113.9.88
+185.113.9.90
+185.113.9.91
+185.113.9.92
+185.113.9.94
+185.113.9.97
+185.113.9.102
+185.113.9.106
+185.113.9.108
+185.113.9.110
+185.113.9.111
+185.113.9.118
+185.113.9.120
+185.113.9.122
+185.113.9.123
+185.113.9.125
+185.113.9.133
+185.113.9.135
+185.113.9.144
+185.113.9.151
+185.113.9.157
+185.113.9.162
+185.113.9.163
+185.113.9.165
+185.113.9.170
+185.113.9.171
+185.113.9.172
+185.113.9.173
+185.113.9.174
+185.113.9.176
+185.113.9.178
+185.113.9.181
+185.113.9.186
+185.113.9.189
+185.113.9.190
+185.113.9.194
+185.113.9.196
+185.113.9.197
+185.113.9.205
+185.113.9.210
+185.113.9.213
+185.113.9.214
+185.113.9.215
+185.113.9.216
+185.113.9.220
+185.113.9.222
+185.113.9.225
+185.113.9.226
+185.113.9.229
+185.113.9.231
+185.113.9.236
+185.113.9.237
+185.113.9.238
+185.113.9.239
+185.113.9.241
+185.113.9.242
+185.113.9.245
+185.113.9.251
+185.113.56.68
+185.113.56.123
+185.113.56.124
+185.113.56.126
+185.113.59.131
+185.113.59.181
+185.113.115.23
+185.113.115.33
+185.113.115.34
+185.114.188.20
+185.114.188.34
+185.115.168.163
+185.116.20.54
+185.116.23.23
+185.116.24.2
+185.116.24.100
+185.116.112.12
+185.116.160.10
+185.116.160.18
+185.116.160.19
+185.116.160.22
+185.116.160.26
+185.116.160.27
+185.116.160.28
+185.116.160.32
+185.116.160.38
+185.116.160.39
+185.116.160.41
+185.116.160.44
+185.116.160.51
+185.116.160.55
+185.116.160.68
+185.116.160.83
+185.116.160.91
+185.116.160.107
+185.116.160.110
+185.116.160.111
+185.116.160.113
+185.116.160.121
+185.116.160.130
+185.116.160.132
+185.116.160.139
+185.116.160.140
+185.116.160.141
+185.116.160.142
+185.116.160.154
+185.116.160.233
+185.116.161.5
+185.116.161.7
+185.116.161.15
+185.116.161.24
+185.116.161.32
+185.116.161.34
+185.116.161.39
+185.116.161.42
+185.116.161.49
+185.116.161.59
+185.116.161.60
+185.116.161.61
+185.116.161.67
+185.116.161.80
+185.116.161.87
+185.116.161.89
+185.116.161.90
+185.116.161.93
+185.116.161.94
+185.116.161.95
+185.116.161.96
+185.116.161.98
+185.116.161.99
+185.116.161.103
+185.116.161.105
+185.116.161.106
+185.116.161.109
+185.116.161.116
+185.116.161.125
+185.116.161.126
+185.116.161.135
+185.116.161.156
+185.116.161.157
+185.116.161.167
+185.116.161.184
+185.116.161.230
+185.116.161.231
+185.116.161.232
+185.116.161.248
+185.116.162.11
+185.116.162.16
+185.116.162.20
+185.116.162.22
+185.116.162.23
+185.116.162.24
+185.116.163.1
+185.116.163.2
+185.116.163.4
+185.116.163.6
+185.116.163.12
+185.116.163.14
+185.116.163.16
+185.116.163.18
+185.116.163.19
+185.116.163.20
+185.116.163.21
+185.116.163.24
+185.116.163.27
+185.116.163.31
+185.116.163.43
+185.116.163.46
+185.116.163.49
+185.116.163.56
+185.116.163.61
+185.116.163.63
+185.116.163.64
+185.116.163.69
+185.116.163.73
+185.116.163.78
+185.116.163.101
+185.116.163.102
+185.116.163.103
+185.116.163.115
+185.116.163.117
+185.116.163.123
+185.116.163.144
+185.116.163.149
+185.116.163.150
+185.116.163.161
+185.116.163.180
+185.116.163.184
+185.116.163.186
+185.116.163.204
+185.116.163.215
+185.116.163.225
+185.117.139.47
+185.117.139.77
+185.118.14.244
+185.118.152.195
+185.118.152.197
+185.119.4.216
+185.119.5.15
+185.119.5.16
+185.119.241.241
+185.120.160.3
+185.120.160.4
+185.120.160.5
+185.120.160.6
+185.120.162.76
+185.120.168.30
+185.120.201.133
+185.120.201.141
+185.120.217.242
+185.120.220.29
+185.120.220.75
+185.120.220.76
+185.120.220.77
+185.120.220.110
+185.120.220.114
+185.120.220.139
+185.120.220.164
+185.120.220.166
+185.120.220.179
+185.120.220.180
+185.120.220.181
+185.120.220.182
+185.120.220.188
+185.120.220.200
+185.120.221.44
+185.120.221.46
+185.120.221.106
+185.120.221.108
+185.120.221.110
+185.120.221.195
+185.120.221.244
+185.120.221.247
+185.120.221.248
+185.120.221.250
+185.120.221.252
+185.120.221.253
+185.120.221.254
+185.120.222.106
+185.120.222.107
+185.120.222.108
+185.120.222.109
+185.120.222.110
+185.120.222.132
+185.120.222.133
+185.120.222.135
+185.120.222.137
+185.120.222.140
+185.120.222.141
+185.120.222.142
+185.120.222.144
+185.120.222.146
+185.120.222.147
+185.120.222.148
+185.120.222.149
+185.120.222.151
+185.120.222.152
+185.120.222.153
+185.120.222.154
+185.120.222.155
+185.120.222.156
+185.120.222.157
+185.120.222.158
+185.120.222.159
+185.120.222.160
+185.120.222.162
+185.120.222.163
+185.120.222.164
+185.120.222.167
+185.120.222.168
+185.120.222.169
+185.120.222.171
+185.120.222.172
+185.120.222.173
+185.120.222.175
+185.120.222.177
+185.120.222.178
+185.120.222.179
+185.120.222.180
+185.120.222.181
+185.120.222.182
+185.120.222.183
+185.120.222.186
+185.120.222.187
+185.120.222.188
+185.120.222.190
+185.120.222.191
+185.120.222.192
+185.120.222.193
+185.120.222.194
+185.120.222.195
+185.120.222.196
+185.120.222.197
+185.120.222.199
+185.120.222.200
+185.120.222.201
+185.120.222.202
+185.120.222.203
+185.120.222.205
+185.120.222.207
+185.120.222.208
+185.120.222.210
+185.120.222.212
+185.120.222.213
+185.120.222.214
+185.120.222.215
+185.120.222.216
+185.120.222.220
+185.120.222.221
+185.120.222.222
+185.120.222.223
+185.120.222.224
+185.120.222.225
+185.120.222.226
+185.120.222.227
+185.120.222.228
+185.120.222.236
+185.120.222.237
+185.120.222.238
+185.120.222.240
+185.120.222.241
+185.120.222.243
+185.120.222.244
+185.120.222.246
+185.120.222.249
+185.120.222.250
+185.120.222.252
+185.120.239.45
+185.120.248.116
+185.120.250.9
+185.121.130.187
+185.122.80.68
+185.122.81.4
+185.123.68.2
+185.123.68.36
+185.124.112.19
+185.124.112.25
+185.124.115.18
+185.124.157.91
+185.124.172.8
+185.124.172.9
+185.124.174.19
+185.126.2.239
+185.126.3.244
+185.126.4.18
+185.126.4.52
+185.126.4.53
+185.126.4.54
+185.126.4.55
+185.126.4.59
+185.126.4.61
+185.126.4.70
+185.126.4.104
+185.126.4.130
+185.126.4.133
+185.126.4.134
+185.126.4.135
+185.126.4.222
+185.126.5.50
+185.126.5.62
+185.126.6.204
+185.126.6.206
+185.126.6.219
+185.126.6.220
+185.126.6.234
+185.126.6.235
+185.126.7.6
+185.126.7.7
+185.126.7.8
+185.126.7.18
+185.126.7.20
+185.126.8.35
+185.126.8.52
+185.126.8.58
+185.126.8.77
+185.126.8.158
+185.126.8.234
+185.126.9.181
+185.126.9.188
+185.126.9.189
+185.126.10.58
+185.126.10.100
+185.126.10.130
+185.126.10.131
+185.126.10.133
+185.126.10.135
+185.126.10.139
+185.126.10.141
+185.126.10.182
+185.126.10.220
+185.126.10.221
+185.126.10.222
+185.126.11.84
+185.126.11.130
+185.126.11.131
+185.126.11.132
+185.126.11.133
+185.126.11.135
+185.126.11.142
+185.126.11.211
+185.126.11.212
+185.126.11.213
+185.126.11.219
+185.126.11.221
+185.126.14.11
+185.126.14.12
+185.126.14.20
+185.126.14.21
+185.126.14.99
+185.126.14.100
+185.126.14.139
+185.126.14.210
+185.126.14.243
+185.126.14.246
+185.126.14.248
+185.126.15.215
+185.126.16.27
+185.126.16.55
+185.126.40.242
+185.126.133.37
+185.126.200.14
+185.126.200.21
+185.126.200.32
+185.126.200.39
+185.126.200.45
+185.126.200.65
+185.126.200.127
+185.126.200.159
+185.126.200.200
+185.126.200.212
+185.126.201.29
+185.126.201.183
+185.126.201.198
+185.126.201.246
+185.126.202.44
+185.126.202.52
+185.126.202.62
+185.126.202.99
+185.126.202.100
+185.126.202.110
+185.126.202.120
+185.126.202.122
+185.126.202.124
+185.126.202.156
+185.126.202.175
+185.126.202.235
+185.126.202.236
+185.126.202.247
+185.126.203.22
+185.126.203.23
+185.126.203.24
+185.126.203.61
+185.126.203.103
+185.126.203.147
+185.126.203.148
+185.126.203.150
+185.126.203.178
+185.126.203.210
+185.126.203.211
+185.126.203.252
+185.128.80.27
+185.128.80.28
+185.128.80.30
+185.128.80.33
+185.128.80.34
+185.128.80.35
+185.128.80.39
+185.128.80.40
+185.128.80.41
+185.128.80.42
+185.128.80.46
+185.128.80.48
+185.128.80.50
+185.128.80.53
+185.128.80.65
+185.128.80.79
+185.128.80.81
+185.128.81.35
+185.128.81.37
+185.128.81.45
+185.128.81.60
+185.128.81.70
+185.128.81.78
+185.128.81.80
+185.128.81.90
+185.128.81.95
+185.128.81.100
+185.128.81.101
+185.128.81.120
+185.128.81.125
+185.128.81.130
+185.128.81.135
+185.128.81.140
+185.128.81.155
+185.128.81.160
+185.128.81.193
+185.128.81.220
+185.128.82.5
+185.128.82.90
+185.128.83.10
+185.128.136.7
+185.128.136.48
+185.128.136.49
+185.128.136.60
+185.128.136.163
+185.128.136.167
+185.128.136.169
+185.128.136.185
+185.128.136.186
+185.128.136.188
+185.128.137.154
+185.128.137.187
+185.128.137.192
+185.128.137.193
+185.128.137.212
+185.128.138.1
+185.128.138.13
+185.128.138.14
+185.128.138.129
+185.128.138.130
+185.128.138.132
+185.128.138.142
+185.128.138.172
+185.128.138.174
+185.128.138.196
+185.128.138.199
+185.128.138.206
+185.128.138.214
+185.128.138.218
+185.128.138.249
+185.128.138.250
+185.128.138.251
+185.128.139.26
+185.128.139.29
+185.128.139.45
+185.128.139.48
+185.128.139.57
+185.128.139.61
+185.128.139.65
+185.128.139.84
+185.128.139.116
+185.128.139.119
+185.128.139.149
+185.128.139.168
+185.128.139.188
+185.128.139.194
+185.128.139.216
+185.128.139.222
+185.129.83.20
+185.129.83.32
+185.129.111.248
+185.129.116.109
+185.129.116.115
+185.129.116.147
+185.129.116.242
+185.129.117.204
+185.129.118.51
+185.129.118.62
+185.129.118.72
+185.129.118.125
+185.129.118.207
+185.129.119.12
+185.129.119.36
+185.129.119.55
+185.129.119.59
+185.129.119.105
+185.129.119.202
+185.129.119.210
+185.129.168.15
+185.129.168.16
+185.129.168.27
+185.129.168.28
+185.129.168.31
+185.129.168.35
+185.129.168.50
+185.129.168.51
+185.129.168.53
+185.129.168.60
+185.129.168.62
+185.129.168.65
+185.129.168.68
+185.129.168.72
+185.129.168.75
+185.129.168.81
+185.129.168.85
+185.129.168.86
+185.129.168.90
+185.129.168.97
+185.129.168.99
+185.129.168.104
+185.129.168.114
+185.129.168.120
+185.129.168.125
+185.129.168.128
+185.129.168.132
+185.129.168.133
+185.129.168.139
+185.129.168.143
+185.129.168.144
+185.129.168.148
+185.129.168.188
+185.129.168.191
+185.129.168.192
+185.129.168.194
+185.129.168.217
+185.129.168.220
+185.129.168.229
+185.129.168.232
+185.129.168.233
+185.129.168.241
+185.129.168.249
+185.129.168.250
+185.129.168.251
+185.129.168.253
+185.129.169.21
+185.129.169.22
+185.129.169.25
+185.129.169.26
+185.129.169.27
+185.129.169.35
+185.129.169.37
+185.129.169.40
+185.129.169.44
+185.129.169.49
+185.129.169.53
+185.129.169.65
+185.129.169.71
+185.129.169.76
+185.129.169.79
+185.129.169.84
+185.129.169.88
+185.129.169.89
+185.129.169.107
+185.129.169.109
+185.129.169.110
+185.129.169.111
+185.129.169.112
+185.129.169.121
+185.129.169.125
+185.129.169.130
+185.129.169.136
+185.129.169.138
+185.129.169.145
+185.129.169.147
+185.129.169.149
+185.129.169.156
+185.129.169.163
+185.129.169.175
+185.129.169.187
+185.129.169.196
+185.129.169.198
+185.129.169.199
+185.129.169.206
+185.129.169.208
+185.129.169.209
+185.129.169.210
+185.129.169.212
+185.129.169.231
+185.129.169.238
+185.129.169.240
+185.129.169.241
+185.129.169.243
+185.129.169.244
+185.129.169.245
+185.129.169.247
+185.129.169.248
+185.129.169.250
+185.129.169.251
+185.129.169.253
+185.129.170.31
+185.129.170.46
+185.129.170.75
+185.129.170.77
+185.129.170.89
+185.129.170.90
+185.129.170.100
+185.129.170.116
+185.129.170.138
+185.129.170.150
+185.129.171.10
+185.129.171.15
+185.129.171.22
+185.129.171.56
+185.129.171.57
+185.129.171.61
+185.129.171.75
+185.129.171.80
+185.129.171.83
+185.129.171.89
+185.129.171.93
+185.129.171.102
+185.129.171.117
+185.129.171.127
+185.129.197.4
+185.129.203.240
+185.129.230.35
+185.130.50.5
+185.130.50.6
+185.130.50.7
+185.130.50.8
+185.130.50.9
+185.130.50.10
+185.130.50.15
+185.130.50.19
+185.130.50.37
+185.130.50.38
+185.130.50.39
+185.130.50.40
+185.130.50.41
+185.130.50.42
+185.130.50.43
+185.130.50.44
+185.130.50.45
+185.130.50.46
+185.130.50.47
+185.130.50.50
+185.130.50.51
+185.130.50.63
+185.130.50.64
+185.130.50.65
+185.130.50.66
+185.130.50.68
+185.130.50.69
+185.130.50.70
+185.130.50.71
+185.130.50.72
+185.130.50.77
+185.130.50.78
+185.130.50.80
+185.130.50.81
+185.130.50.83
+185.130.50.84
+185.130.50.85
+185.130.50.89
+185.130.50.91
+185.130.50.93
+185.130.50.97
+185.130.50.99
+185.130.50.100
+185.130.50.101
+185.130.50.109
+185.130.50.110
+185.130.50.112
+185.130.50.115
+185.130.50.116
+185.130.50.117
+185.130.50.118
+185.130.50.119
+185.130.50.133
+185.130.50.139
+185.130.50.140
+185.130.50.143
+185.130.50.144
+185.130.50.146
+185.130.50.149
+185.130.50.150
+185.130.50.160
+185.130.50.166
+185.130.50.169
+185.130.50.171
+185.130.50.180
+185.130.50.184
+185.130.50.188
+185.130.50.192
+185.130.50.201
+185.130.50.222
+185.130.50.224
+185.130.50.233
+185.130.50.239
+185.130.50.242
+185.130.50.251
+185.130.76.2
+185.130.76.4
+185.130.76.72
+185.130.76.74
+185.130.78.123
+185.130.78.142
+185.130.79.21
+185.130.79.253
+185.131.28.254
+185.131.92.31
+185.131.116.150
+185.131.116.173
+185.132.124.53
+185.132.124.198
+185.132.124.199
+185.132.212.29
+185.132.212.129
+185.132.212.130
+185.132.212.135
+185.132.212.136
+185.132.213.19
+185.132.213.61
+185.132.213.62
+185.132.213.63
+185.132.213.64
+185.134.97.210
+185.135.47.10
+185.135.47.11
+185.135.47.12
+185.135.47.13
+185.135.47.14
+185.135.47.15
+185.135.47.16
+185.135.47.17
+185.135.47.18
+185.135.47.21
+185.135.47.22
+185.135.47.23
+185.135.47.24
+185.135.47.25
+185.135.47.30
+185.135.47.52
+185.135.47.57
+185.135.47.60
+185.135.47.61
+185.135.47.64
+185.135.47.74
+185.135.47.107
+185.135.47.108
+185.135.47.120
+185.136.133.72
+185.136.180.2
+185.136.181.99
+185.136.181.105
+185.136.181.197
+185.137.24.10
+185.137.24.18
+185.137.24.83
+185.137.24.100
+185.137.24.165
+185.137.24.202
+185.137.24.206
+185.137.24.245
+185.137.25.41
+185.137.25.72
+185.137.25.74
+185.137.25.78
+185.137.25.79
+185.137.25.102
+185.137.25.146
+185.137.25.213
+185.137.25.214
+185.137.25.215
+185.137.25.216
+185.137.25.223
+185.137.25.234
+185.137.26.14
+185.137.26.50
+185.137.26.58
+185.137.26.165
+185.137.26.184
+185.137.26.185
+185.137.26.186
+185.137.26.189
+185.137.26.190
+185.137.26.197
+185.137.26.227
+185.137.26.237
+185.137.26.243
+185.137.26.244
+185.137.27.3
+185.137.27.4
+185.137.27.22
+185.137.27.27
+185.137.27.40
+185.137.27.42
+185.137.27.43
+185.137.27.44
+185.137.27.45
+185.137.27.46
+185.137.27.86
+185.137.27.138
+185.137.27.164
+185.137.27.179
+185.137.27.188
+185.137.27.217
+185.137.27.227
+185.139.64.9
+185.139.64.21
+185.140.4.4
+185.140.4.5
+185.140.5.127
+185.140.5.232
+185.140.5.244
+185.140.240.238
+185.141.36.54
+185.141.36.82
+185.141.48.53
+185.141.48.54
+185.141.104.69
+185.141.104.107
+185.141.104.118
+185.141.104.126
+185.141.104.136
+185.141.104.141
+185.141.104.142
+185.141.104.211
+185.141.104.242
+185.141.105.27
+185.141.105.100
+185.141.105.105
+185.141.105.107
+185.141.105.109
+185.141.105.113
+185.141.105.119
+185.141.105.138
+185.141.105.139
+185.141.105.217
+185.141.105.230
+185.141.105.232
+185.141.105.233
+185.141.106.39
+185.141.106.64
+185.141.106.68
+185.141.106.71
+185.141.106.82
+185.141.106.84
+185.141.106.117
+185.141.106.121
+185.141.106.126
+185.141.106.149
+185.141.106.150
+185.141.106.153
+185.141.106.154
+185.141.106.169
+185.141.106.225
+185.141.106.228
+185.141.106.230
+185.141.106.231
+185.141.106.232
+185.141.106.238
+185.141.106.240
+185.141.106.243
+185.141.107.17
+185.141.107.27
+185.141.107.38
+185.141.107.50
+185.141.107.51
+185.141.107.163
+185.141.107.197
+185.141.107.228
+185.141.107.244
+185.141.132.11
+185.141.132.23
+185.141.132.44
+185.141.132.45
+185.141.132.46
+185.141.132.47
+185.141.132.60
+185.141.132.89
+185.141.132.92
+185.141.132.95
+185.141.132.127
+185.141.132.216
+185.141.132.218
+185.141.133.3
+185.141.133.5
+185.141.133.6
+185.141.133.18
+185.141.133.19
+185.141.133.28
+185.141.133.50
+185.141.133.66
+185.141.133.67
+185.141.133.76
+185.141.133.120
+185.141.133.145
+185.141.133.216
+185.141.133.217
+185.141.133.218
+185.141.134.49
+185.141.134.64
+185.141.134.68
+185.141.134.74
+185.141.134.77
+185.141.134.88
+185.141.134.93
+185.141.134.114
+185.141.134.151
+185.141.134.191
+185.141.134.206
+185.141.134.221
+185.141.135.113
+185.141.135.115
+185.141.168.117
+185.141.168.122
+185.141.168.123
+185.141.168.124
+185.141.168.130
+185.141.168.133
+185.141.168.134
+185.141.168.135
+185.141.168.136
+185.141.168.137
+185.141.168.138
+185.141.168.139
+185.141.168.140
+185.141.168.141
+185.141.169.42
+185.141.169.155
+185.141.169.220
+185.141.169.226
+185.141.169.227
+185.141.169.228
+185.141.169.229
+185.141.169.230
+185.141.169.231
+185.141.169.232
+185.141.169.234
+185.141.169.235
+185.141.169.236
+185.141.169.237
+185.141.169.238
+185.141.169.239
+185.141.169.241
+185.141.169.242
+185.141.169.243
+185.141.169.244
+185.141.169.245
+185.141.169.246
+185.141.169.247
+185.141.170.2
+185.141.170.74
+185.141.170.99
+185.141.170.132
+185.141.170.195
+185.141.171.30
+185.141.212.11
+185.141.212.139
+185.141.212.140
+185.141.212.141
+185.141.212.142
+185.141.212.170
+185.141.212.171
+185.141.212.172
+185.141.212.173
+185.141.212.174
+185.141.213.4
+185.141.213.5
+185.141.213.12
+185.141.213.61
+185.141.213.133
+185.141.213.166
+185.141.213.167
+185.141.213.172
+185.141.213.180
+185.141.213.181
+185.141.213.244
+185.141.213.248
+185.141.213.249
+185.141.213.250
+185.141.213.251
+185.141.214.71
+185.142.95.68
+185.142.95.69
+185.142.156.11
+185.142.156.12
+185.142.156.85
+185.142.156.214
+185.142.156.227
+185.142.156.235
+185.142.157.5
+185.142.157.12
+185.142.157.29
+185.142.157.37
+185.142.157.39
+185.142.157.53
+185.142.157.75
+185.142.157.81
+185.142.157.95
+185.142.157.96
+185.142.157.119
+185.142.157.120
+185.142.157.121
+185.142.157.123
+185.142.157.124
+185.142.157.151
+185.142.157.168
+185.142.157.231
+185.142.157.246
+185.142.157.251
+185.142.158.28
+185.142.158.98
+185.142.158.99
+185.142.158.140
+185.142.158.141
+185.142.158.162
+185.142.159.172
+185.142.159.195
+185.142.159.210
+185.142.159.212
+185.142.159.229
+185.142.159.230
+185.142.159.232
+185.142.159.234
+185.142.159.235
+185.142.159.243
+185.142.159.251
+185.143.207.131
+185.143.207.246
+185.143.232.253
+185.143.233.253
+185.143.234.253
+185.143.235.253
+185.144.65.6
+185.145.11.246
+185.145.186.32
+185.145.186.130
+185.147.40.115
+185.147.40.160
+185.147.84.105
+185.147.85.105
+185.147.160.21
+185.147.160.22
+185.147.160.107
+185.147.160.109
+185.147.161.170
+185.147.162.26
+185.147.162.68
+185.147.162.130
+185.147.162.132
+185.147.162.195
+185.147.163.46
+185.147.163.62
+185.147.163.168
+185.147.163.169
+185.147.163.196
+185.147.163.202
+185.147.176.189
+185.147.176.221
+185.147.177.111
+185.147.177.112
+185.147.177.113
+185.147.177.224
+185.147.177.232
+185.149.192.18
+185.149.192.28
+185.149.192.30
+185.149.192.32
+185.149.192.33
+185.149.192.47
+185.149.192.54
+185.149.192.132
+185.149.192.133
+185.149.192.134
+185.149.192.150
+185.149.192.155
+185.149.192.218
+185.153.208.77
+185.155.9.40
+185.155.14.130
+185.155.15.140
+185.155.236.2
+185.155.236.3
+185.155.236.4
+185.158.172.3
+185.158.173.8
+185.158.173.165
+185.159.153.2
+185.159.153.3
+185.159.153.5
+185.159.153.6
+185.159.153.10
+185.159.153.12
+185.159.153.13
+185.159.153.15
+185.159.153.16
+185.159.153.17
+185.159.153.19
+185.159.153.20
+185.159.153.21
+185.159.153.23
+185.159.153.24
+185.159.153.25
+185.159.153.26
+185.159.153.27
+185.159.153.29
+185.159.153.30
+185.159.153.31
+185.159.153.32
+185.159.153.33
+185.159.153.34
+185.159.153.35
+185.159.153.36
+185.159.153.38
+185.159.153.39
+185.159.153.40
+185.159.153.42
+185.159.153.44
+185.159.153.45
+185.159.153.46
+185.159.153.47
+185.159.153.48
+185.159.153.50
+185.159.153.51
+185.159.153.52
+185.159.153.53
+185.159.153.54
+185.159.153.55
+185.159.153.56
+185.159.153.57
+185.159.153.58
+185.159.153.59
+185.159.153.60
+185.159.153.61
+185.159.153.64
+185.159.153.66
+185.159.153.67
+185.159.153.68
+185.159.153.69
+185.159.153.70
+185.159.153.71
+185.159.153.72
+185.159.153.73
+185.159.153.74
+185.159.153.75
+185.159.153.77
+185.159.153.78
+185.159.153.79
+185.159.153.80
+185.159.153.81
+185.159.153.82
+185.159.153.83
+185.159.153.84
+185.159.153.85
+185.159.153.86
+185.159.153.87
+185.159.153.88
+185.159.153.89
+185.159.153.90
+185.159.153.91
+185.159.153.92
+185.159.153.93
+185.159.153.98
+185.159.153.99
+185.159.153.100
+185.159.153.102
+185.159.153.103
+185.159.153.104
+185.159.153.105
+185.159.153.106
+185.159.153.108
+185.159.153.110
+185.159.153.111
+185.159.153.112
+185.159.153.113
+185.159.153.114
+185.159.153.115
+185.159.153.116
+185.159.153.119
+185.159.153.120
+185.159.153.121
+185.159.153.122
+185.159.153.123
+185.159.153.124
+185.159.153.125
+185.159.153.126
+185.159.153.127
+185.159.153.128
+185.159.153.129
+185.159.153.131
+185.159.153.132
+185.159.153.133
+185.159.153.134
+185.159.153.135
+185.159.153.136
+185.159.153.137
+185.159.153.140
+185.159.153.141
+185.159.153.142
+185.159.153.145
+185.159.153.147
+185.159.153.148
+185.159.153.149
+185.159.153.150
+185.159.153.151
+185.159.153.152
+185.159.153.153
+185.159.153.154
+185.159.153.156
+185.159.153.157
+185.159.153.158
+185.159.153.159
+185.159.153.160
+185.159.153.161
+185.159.153.162
+185.159.153.163
+185.159.153.165
+185.159.153.166
+185.159.153.171
+185.159.153.172
+185.159.153.174
+185.159.153.175
+185.159.153.176
+185.159.153.177
+185.159.153.186
+185.159.153.187
+185.159.153.189
+185.159.153.191
+185.159.153.193
+185.159.153.194
+185.159.153.196
+185.159.153.199
+185.159.153.200
+185.159.153.201
+185.159.153.202
+185.159.153.203
+185.159.153.204
+185.159.153.205
+185.159.153.207
+185.159.153.208
+185.159.153.211
+185.159.153.214
+185.159.153.216
+185.159.153.218
+185.159.153.219
+185.159.153.220
+185.159.153.226
+185.159.153.227
+185.159.153.228
+185.159.153.235
+185.159.153.253
+185.159.154.2
+185.159.154.3
+185.159.154.4
+185.159.154.5
+185.159.154.7
+185.159.154.9
+185.159.154.10
+185.159.154.14
+185.159.154.16
+185.159.154.17
+185.159.154.19
+185.159.154.20
+185.159.154.21
+185.159.154.22
+185.159.154.23
+185.159.154.25
+185.159.154.26
+185.159.154.27
+185.159.154.28
+185.159.154.29
+185.159.154.30
+185.159.154.31
+185.159.154.32
+185.159.154.33
+185.159.154.34
+185.159.154.35
+185.159.154.36
+185.159.154.37
+185.159.154.38
+185.159.154.39
+185.159.154.40
+185.159.154.41
+185.159.154.42
+185.159.154.43
+185.159.154.44
+185.159.154.45
+185.159.154.46
+185.159.154.47
+185.159.154.48
+185.159.154.49
+185.159.154.50
+185.159.154.51
+185.159.154.52
+185.159.154.53
+185.159.154.54
+185.159.154.55
+185.159.154.56
+185.159.154.57
+185.159.154.61
+185.159.154.63
+185.159.154.64
+185.159.154.65
+185.159.154.66
+185.159.154.67
+185.159.154.68
+185.159.154.69
+185.159.154.70
+185.159.154.71
+185.159.154.72
+185.159.154.73
+185.159.154.74
+185.159.154.75
+185.159.154.79
+185.159.154.81
+185.159.154.82
+185.159.154.84
+185.159.154.85
+185.159.154.86
+185.159.154.87
+185.159.154.88
+185.159.154.89
+185.159.154.90
+185.159.154.91
+185.159.154.92
+185.159.154.93
+185.159.154.94
+185.159.154.98
+185.159.154.99
+185.159.154.100
+185.159.154.102
+185.159.154.104
+185.159.154.105
+185.159.154.106
+185.159.154.107
+185.159.154.108
+185.159.154.109
+185.159.154.111
+185.159.154.114
+185.159.154.115
+185.159.154.118
+185.159.154.120
+185.159.154.124
+185.159.154.125
+185.159.154.127
+185.159.154.128
+185.159.154.130
+185.159.154.132
+185.159.154.133
+185.159.154.134
+185.159.154.137
+185.159.154.143
+185.159.154.147
+185.159.154.149
+185.159.154.150
+185.159.154.151
+185.159.154.152
+185.159.154.153
+185.159.154.154
+185.159.154.157
+185.159.154.159
+185.159.154.161
+185.159.154.162
+185.159.154.163
+185.159.154.164
+185.159.154.165
+185.159.154.167
+185.159.154.168
+185.159.154.169
+185.159.154.170
+185.159.154.171
+185.159.154.172
+185.159.154.173
+185.159.154.177
+185.159.154.178
+185.159.154.179
+185.159.154.180
+185.159.154.181
+185.159.154.188
+185.159.154.189
+185.159.154.190
+185.159.154.191
+185.159.154.192
+185.159.154.197
+185.159.154.198
+185.159.154.199
+185.159.154.200
+185.159.154.201
+185.159.154.202
+185.159.154.204
+185.159.154.207
+185.159.154.208
+185.159.154.209
+185.159.154.210
+185.159.154.211
+185.159.154.212
+185.159.154.213
+185.159.154.214
+185.159.154.215
+185.159.154.219
+185.159.154.221
+185.159.154.222
+185.159.154.224
+185.159.154.225
+185.159.154.226
+185.159.154.227
+185.159.154.228
+185.159.154.242
+185.159.154.245
+185.159.154.249
+185.159.154.250
+185.159.154.251
+185.159.154.252
+185.159.154.253
+185.159.155.2
+185.159.155.3
+185.159.179.1
+185.159.179.2
+185.159.179.71
+185.159.179.72
+185.159.179.74
+185.159.179.75
+185.159.179.80
+185.160.104.84
+185.160.105.54
+185.160.205.18
+185.161.39.242
+185.161.112.33
+185.161.112.34
+185.161.112.35
+185.161.112.247
+185.161.113.253
+185.161.121.152
+185.164.72.4
+185.164.72.5
+185.164.72.7
+185.164.72.10
+185.164.72.14
+185.164.72.18
+185.164.72.23
+185.164.72.24
+185.164.72.25
+185.164.72.27
+185.164.72.36
+185.164.72.44
+185.164.72.46
+185.164.72.53
+185.164.72.56
+185.164.72.62
+185.164.72.70
+185.164.72.71
+185.164.72.72
+185.164.72.77
+185.164.72.82
+185.164.72.83
+185.164.72.85
+185.164.72.89
+185.164.72.92
+185.164.72.97
+185.164.72.99
+185.164.72.107
+185.164.72.108
+185.164.72.118
+185.164.72.119
+185.164.72.128
+185.164.72.131
+185.164.72.135
+185.164.72.140
+185.164.72.142
+185.164.72.149
+185.164.72.157
+185.164.72.160
+185.164.72.170
+185.164.72.173
+185.164.72.174
+185.164.72.179
+185.164.72.185
+185.164.72.194
+185.164.72.195
+185.164.72.199
+185.164.72.215
+185.164.72.219
+185.164.72.225
+185.164.72.227
+185.164.72.237
+185.164.72.249
+185.164.72.252
+185.164.73.9
+185.164.73.14
+185.164.73.18
+185.164.73.21
+185.164.73.22
+185.164.73.30
+185.164.73.34
+185.164.73.38
+185.164.73.47
+185.164.73.49
+185.164.73.53
+185.164.73.57
+185.164.73.64
+185.164.73.65
+185.164.73.73
+185.164.73.75
+185.164.73.76
+185.164.73.81
+185.164.73.87
+185.164.73.94
+185.164.73.103
+185.164.73.104
+185.164.73.108
+185.164.73.109
+185.164.73.115
+185.164.73.119
+185.164.73.121
+185.164.73.123
+185.164.73.125
+185.164.73.133
+185.164.73.135
+185.164.73.140
+185.164.73.141
+185.164.73.152
+185.164.73.158
+185.164.73.160
+185.164.73.164
+185.164.73.168
+185.164.73.171
+185.164.73.174
+185.164.73.177
+185.164.73.180
+185.164.73.187
+185.164.73.190
+185.164.73.191
+185.164.73.205
+185.164.73.224
+185.164.73.229
+185.164.73.243
+185.164.253.26
+185.165.28.12
+185.165.28.33
+185.165.28.34
+185.165.28.251
+185.165.28.252
+185.165.29.17
+185.165.29.28
+185.165.29.33
+185.165.29.50
+185.165.29.65
+185.165.29.128
+185.165.29.136
+185.165.29.175
+185.165.29.176
+185.165.29.177
+185.165.29.179
+185.165.29.182
+185.165.29.186
+185.165.29.189
+185.165.29.194
+185.165.29.206
+185.165.29.211
+185.165.29.220
+185.165.29.223
+185.165.29.240
+185.165.29.242
+185.165.29.247
+185.165.30.93
+185.165.30.94
+185.165.116.1
+185.165.116.13
+185.165.116.19
+185.165.116.20
+185.165.116.21
+185.165.116.22
+185.165.116.23
+185.165.116.24
+185.165.116.26
+185.165.116.30
+185.165.116.31
+185.165.116.32
+185.165.116.34
+185.165.116.36
+185.165.116.41
+185.165.116.43
+185.165.116.47
+185.165.116.49
+185.165.116.52
+185.165.116.57
+185.165.116.58
+185.165.116.60
+185.165.116.62
+185.165.116.63
+185.165.116.66
+185.165.116.72
+185.165.116.75
+185.165.116.79
+185.165.116.80
+185.165.116.85
+185.165.116.90
+185.165.116.93
+185.165.116.102
+185.165.116.116
+185.165.116.133
+185.165.116.134
+185.165.116.135
+185.165.116.136
+185.165.116.139
+185.165.116.140
+185.165.116.144
+185.165.116.145
+185.165.116.149
+185.165.116.152
+185.165.116.155
+185.165.116.156
+185.165.116.158
+185.165.116.159
+185.165.116.161
+185.165.116.164
+185.165.116.168
+185.165.116.173
+185.165.116.182
+185.165.116.195
+185.165.116.196
+185.165.116.198
+185.165.116.202
+185.165.116.204
+185.165.116.210
+185.165.116.213
+185.165.116.214
+185.165.116.219
+185.165.116.235
+185.165.116.253
+185.165.117.1
+185.165.117.11
+185.165.117.120
+185.165.117.244
+185.165.118.1
+185.165.118.35
+185.165.118.49
+185.165.118.51
+185.165.118.58
+185.165.118.59
+185.165.118.72
+185.165.118.74
+185.165.118.80
+185.165.118.92
+185.165.118.98
+185.165.118.138
+185.165.118.193
+185.165.118.195
+185.165.118.197
+185.165.118.201
+185.165.118.205
+185.165.118.210
+185.165.118.211
+185.165.118.215
+185.165.118.216
+185.165.118.224
+185.165.118.227
+185.165.118.228
+185.165.118.235
+185.165.118.237
+185.165.119.1
+185.165.119.59
+185.165.119.60
+185.165.119.63
+185.166.63.43
+185.166.104.53
+185.166.104.54
+185.167.73.25
+185.167.75.25
+185.167.124.244
+185.169.6.18
+185.169.6.44
+185.169.6.58
+185.169.6.94
+185.169.6.106
+185.169.6.146
+185.169.6.154
+185.169.6.166
+185.169.6.174
+185.169.6.194
+185.169.6.196
+185.169.6.211
+185.169.6.226
+185.169.20.106
+185.169.20.107
+185.169.21.62
+185.170.8.5
+185.170.8.11
+185.170.8.195
+185.170.8.236
+185.170.8.241
+185.170.8.248
+185.170.8.254
+185.170.236.26
+185.170.236.27
+185.170.236.28
+185.170.236.30
+185.171.53.3
+185.171.53.4
+185.171.53.57
+185.171.53.58
+185.171.53.60
+185.171.53.61
+185.171.53.62
+185.171.53.66
+185.171.53.70
+185.171.53.75
+185.171.53.149
+185.171.53.158
+185.171.53.163
+185.171.53.164
+185.171.53.171
+185.171.53.174
+185.171.53.186
+185.172.212.26
+185.172.212.210
+185.172.213.2
+185.172.213.3
+185.172.213.4
+185.172.213.5
+185.172.213.6
+185.172.213.7
+185.172.213.51
+185.173.104.18
+185.173.104.41
+185.173.104.44
+185.173.104.46
+185.173.104.48
+185.173.104.50
+185.173.104.59
+185.173.104.68
+185.173.104.72
+185.173.104.74
+185.173.104.78
+185.173.104.81
+185.173.104.83
+185.173.104.87
+185.173.104.88
+185.173.104.90
+185.173.104.95
+185.173.104.102
+185.173.104.107
+185.173.104.119
+185.173.104.129
+185.173.104.134
+185.173.104.141
+185.173.104.146
+185.173.104.148
+185.173.104.151
+185.173.104.152
+185.173.104.167
+185.173.104.177
+185.173.104.179
+185.173.104.181
+185.173.104.202
+185.173.104.206
+185.173.104.207
+185.173.104.211
+185.173.104.228
+185.173.104.229
+185.173.104.230
+185.173.104.235
+185.173.104.238
+185.173.104.246
+185.173.105.6
+185.173.105.22
+185.173.105.26
+185.173.105.122
+185.173.105.126
+185.173.105.134
+185.173.105.154
+185.173.105.170
+185.173.105.210
+185.173.105.211
+185.173.105.218
+185.173.105.219
+185.173.105.221
+185.173.106.22
+185.173.106.32
+185.173.106.54
+185.173.106.56
+185.173.106.90
+185.173.106.105
+185.173.106.109
+185.173.106.155
+185.173.106.164
+185.173.106.171
+185.173.106.172
+185.173.106.177
+185.173.106.188
+185.173.106.196
+185.173.106.199
+185.173.106.200
+185.173.106.207
+185.173.106.238
+185.173.106.239
+185.173.107.40
+185.173.107.68
+185.173.107.125
+185.173.107.154
+185.173.107.158
+185.173.107.171
+185.173.107.179
+185.173.107.207
+185.173.107.212
+185.173.129.48
+185.173.129.137
+185.173.129.143
+185.173.129.200
+185.173.129.208
+185.173.130.100
+185.173.130.149
+185.173.130.160
+185.173.130.249
+185.173.168.3
+185.173.168.14
+185.173.168.18
+185.173.168.57
+185.173.168.59
+185.173.168.107
+185.173.168.175
+185.173.168.183
+185.173.168.185
+185.173.168.209
+185.173.168.210
+185.173.168.244
+185.173.168.245
+185.173.168.246
+185.173.168.247
+185.173.168.248
+185.173.168.249
+185.173.168.252
+185.173.168.254
+185.173.169.169
+185.173.169.254
+185.173.170.11
+185.173.171.251
+185.173.171.252
+185.173.171.253
+185.173.171.254
+185.174.250.20
+185.174.250.51
+185.174.250.52
+185.174.251.22
+185.175.76.140
+185.176.58.58
+185.177.158.4
+185.178.220.15
+185.178.220.55
+185.179.90.10
+185.179.90.54
+185.179.90.61
+185.179.90.66
+185.179.90.75
+185.179.90.125
+185.179.90.130
+185.179.90.150
+185.179.90.179
+185.179.90.227
+185.179.168.9
+185.179.168.12
+185.179.168.24
+185.179.168.30
+185.179.168.50
+185.179.168.51
+185.179.168.56
+185.179.168.168
+185.179.169.13
+185.179.169.90
+185.179.171.127
+185.179.220.9
+185.180.128.92
+185.180.129.219
+185.181.180.14
+185.181.180.54
+185.181.180.62
+185.181.180.116
+185.181.180.119
+185.181.180.120
+185.181.180.122
+185.181.180.123
+185.181.180.130
+185.181.180.156
+185.181.180.205
+185.181.180.206
+185.181.180.208
+185.181.180.209
+185.181.180.222
+185.181.180.237
+185.181.180.244
+185.181.181.2
+185.181.181.5
+185.181.181.9
+185.181.181.30
+185.181.181.85
+185.181.181.87
+185.181.181.88
+185.181.181.166
+185.181.181.183
+185.181.181.187
+185.181.181.188
+185.181.182.15
+185.181.182.17
+185.181.182.52
+185.181.182.64
+185.181.182.75
+185.181.182.84
+185.181.182.85
+185.181.182.88
+185.181.182.91
+185.181.182.95
+185.181.182.102
+185.181.182.107
+185.181.182.128
+185.181.182.133
+185.181.182.157
+185.181.182.161
+185.181.182.173
+185.181.182.177
+185.181.182.178
+185.181.182.190
+185.181.182.202
+185.181.182.206
+185.181.182.224
+185.181.182.230
+185.181.183.25
+185.181.183.38
+185.181.183.47
+185.181.183.56
+185.181.183.58
+185.181.183.87
+185.181.183.94
+185.181.183.109
+185.181.183.111
+185.181.183.112
+185.181.183.114
+185.181.183.125
+185.181.183.144
+185.181.183.145
+185.181.183.157
+185.181.183.166
+185.182.222.85
+185.182.222.219
+185.185.16.116
+185.185.240.4
+185.186.50.44
+185.186.50.67
+185.186.50.108
+185.186.50.124
+185.186.50.130
+185.186.50.243
+185.186.50.245
+185.186.50.247
+185.186.51.10
+185.186.51.115
+185.186.51.243
+185.186.240.240
+185.186.241.3
+185.186.241.8
+185.186.241.10
+185.186.241.133
+185.186.242.21
+185.186.242.135
+185.186.242.141
+185.186.242.157
+185.186.243.250
+185.187.48.3
+185.187.50.4
+185.187.50.37
+185.187.50.40
+185.187.51.250
+185.187.86.5
+185.187.86.10
+185.188.104.10
+185.188.104.11
+185.188.104.12
+185.188.104.13
+185.188.105.10
+185.188.105.11
+185.188.105.12
+185.188.106.10
+185.188.106.11
+185.190.39.7
+185.190.39.18
+185.190.39.27
+185.190.39.31
+185.190.39.34
+185.190.39.40
+185.190.39.46
+185.190.39.63
+185.190.39.69
+185.190.39.75
+185.190.39.85
+185.190.39.91
+185.190.39.93
+185.190.39.103
+185.190.39.113
+185.190.39.120
+185.190.39.133
+185.190.39.137
+185.190.39.143
+185.190.39.145
+185.190.39.148
+185.190.39.154
+185.190.39.159
+185.190.39.166
+185.190.39.172
+185.190.39.176
+185.190.39.179
+185.190.39.189
+185.190.39.193
+185.190.39.195
+185.190.39.213
+185.190.39.222
+185.190.39.225
+185.190.39.227
+185.190.39.231
+185.190.39.232
+185.190.39.235
+185.190.39.241
+185.190.39.251
+185.191.76.3
+185.191.76.5
+185.191.76.8
+185.191.76.9
+185.191.76.10
+185.191.76.11
+185.191.76.12
+185.191.76.13
+185.191.76.19
+185.191.76.27
+185.191.76.30
+185.191.76.84
+185.191.76.142
+185.191.76.147
+185.191.76.148
+185.191.76.149
+185.191.76.150
+185.191.76.163
+185.191.76.210
+185.191.77.50
+185.191.77.54
+185.191.77.122
+185.191.77.138
+185.191.77.142
+185.191.77.197
+185.191.77.210
+185.191.77.221
+185.191.77.229
+185.191.77.235
+185.191.77.236
+185.191.77.237
+185.191.77.241
+185.191.77.244
+185.191.77.245
+185.191.77.249
+185.191.77.250
+185.191.77.251
+185.191.77.252
+185.191.78.22
+185.191.78.74
+185.191.78.187
+185.191.78.214
+185.191.78.226
+185.191.78.227
+185.191.78.228
+185.191.78.231
+185.191.79.8
+185.191.79.10
+185.191.79.13
+185.191.79.14
+185.191.79.17
+185.191.79.22
+185.191.79.23
+185.191.79.55
+185.191.79.102
+185.191.79.138
+185.191.79.208
+185.191.79.211
+185.192.10.3
+185.192.112.2
+185.192.112.3
+185.192.112.5
+185.192.112.7
+185.192.112.8
+185.192.112.9
+185.192.112.13
+185.192.112.14
+185.192.112.15
+185.192.112.19
+185.192.112.20
+185.192.112.21
+185.192.112.22
+185.192.112.24
+185.192.112.26
+185.192.112.29
+185.192.112.30
+185.192.112.31
+185.192.112.38
+185.192.112.41
+185.192.112.44
+185.192.112.49
+185.192.112.53
+185.192.112.55
+185.192.112.56
+185.192.112.57
+185.192.112.58
+185.192.112.64
+185.192.112.68
+185.192.112.70
+185.192.112.75
+185.192.112.79
+185.192.112.81
+185.192.112.82
+185.192.112.83
+185.192.112.84
+185.192.112.87
+185.192.112.88
+185.192.112.93
+185.192.112.96
+185.192.112.97
+185.192.112.98
+185.192.112.99
+185.192.112.101
+185.192.112.103
+185.192.112.104
+185.192.112.108
+185.192.112.109
+185.192.112.110
+185.192.112.114
+185.192.112.117
+185.192.112.118
+185.192.112.119
+185.192.112.125
+185.192.112.126
+185.192.112.130
+185.192.112.131
+185.192.112.132
+185.192.112.133
+185.192.112.137
+185.192.112.138
+185.192.112.139
+185.192.112.144
+185.192.112.145
+185.192.112.146
+185.192.112.152
+185.192.112.153
+185.192.112.157
+185.192.112.161
+185.192.112.162
+185.192.112.163
+185.192.112.164
+185.192.112.201
+185.192.112.202
+185.192.112.203
+185.192.112.205
+185.192.112.207
+185.192.112.208
+185.192.112.209
+185.192.112.211
+185.192.112.212
+185.192.112.213
+185.192.112.214
+185.192.112.215
+185.192.112.216
+185.192.112.217
+185.192.112.218
+185.192.112.219
+185.192.112.221
+185.192.112.223
+185.192.112.224
+185.192.112.225
+185.192.112.227
+185.192.112.229
+185.192.112.230
+185.192.112.231
+185.192.112.241
+185.192.112.243
+185.192.112.244
+185.192.112.245
+185.192.112.246
+185.192.112.247
+185.192.112.248
+185.192.112.251
+185.192.112.253
+185.192.112.254
+185.192.113.6
+185.192.113.11
+185.192.113.12
+185.192.113.14
+185.192.113.15
+185.192.113.16
+185.192.113.17
+185.192.113.18
+185.192.113.20
+185.192.113.23
+185.192.113.25
+185.192.113.26
+185.192.113.30
+185.192.113.31
+185.192.113.32
+185.192.113.34
+185.192.113.35
+185.192.113.43
+185.192.113.44
+185.192.113.47
+185.192.113.49
+185.192.113.82
+185.192.113.86
+185.192.113.90
+185.192.113.92
+185.192.113.102
+185.192.113.103
+185.192.113.110
+185.192.113.111
+185.192.113.112
+185.192.113.114
+185.192.113.115
+185.192.113.117
+185.192.113.118
+185.192.113.119
+185.192.113.122
+185.192.113.123
+185.192.113.124
+185.192.113.126
+185.192.113.127
+185.192.113.128
+185.192.113.129
+185.192.113.130
+185.192.113.133
+185.192.113.140
+185.192.113.141
+185.192.113.143
+185.192.113.145
+185.192.113.150
+185.192.113.151
+185.192.113.152
+185.192.113.153
+185.192.113.157
+185.192.113.159
+185.192.113.163
+185.192.113.164
+185.192.113.174
+185.192.113.175
+185.192.113.177
+185.192.113.183
+185.192.113.185
+185.192.113.186
+185.192.113.193
+185.192.113.201
+185.192.113.203
+185.192.113.206
+185.192.113.209
+185.192.113.242
+185.192.113.251
+185.192.113.252
+185.192.114.12
+185.192.114.13
+185.192.114.15
+185.192.114.16
+185.192.114.17
+185.192.114.20
+185.192.114.23
+185.192.114.24
+185.192.114.25
+185.192.114.26
+185.192.114.28
+185.192.114.30
+185.192.114.39
+185.192.114.40
+185.192.114.41
+185.192.114.47
+185.192.114.48
+185.192.114.49
+185.192.114.53
+185.192.114.54
+185.192.114.65
+185.192.114.83
+185.192.114.101
+185.192.114.102
+185.192.114.103
+185.192.114.104
+185.192.114.105
+185.192.114.108
+185.192.114.112
+185.192.114.114
+185.192.114.116
+185.192.114.117
+185.192.114.118
+185.192.114.123
+185.192.114.126
+185.192.114.127
+185.192.114.129
+185.192.114.130
+185.192.114.133
+185.192.114.135
+185.192.114.140
+185.192.114.148
+185.192.114.153
+185.192.114.154
+185.192.114.158
+185.192.114.159
+185.192.114.162
+185.192.114.165
+185.192.114.172
+185.192.114.201
+185.192.114.203
+185.192.114.204
+185.192.114.205
+185.192.114.209
+185.192.114.211
+185.192.114.254
+185.193.47.15
+185.193.47.16
+185.194.79.2
+185.194.79.3
+185.194.79.4
+185.196.148.112
+185.198.160.2
+185.198.160.3
+185.201.49.149
+185.201.49.228
+185.201.50.101
+185.201.50.104
+185.201.50.105
+185.201.50.220
+185.202.59.66
+185.204.197.12
+185.204.197.13
+185.204.197.15
+185.204.197.16
+185.204.197.19
+185.204.197.21
+185.204.197.24
+185.204.197.28
+185.204.197.33
+185.204.197.41
+185.204.197.42
+185.204.197.60
+185.204.197.71
+185.204.197.85
+185.204.197.96
+185.204.197.97
+185.204.197.98
+185.204.197.99
+185.204.197.106
+185.204.197.110
+185.204.197.116
+185.204.197.120
+185.204.197.123
+185.204.197.129
+185.204.197.132
+185.204.197.133
+185.204.197.140
+185.204.197.145
+185.204.197.155
+185.204.197.160
+185.204.197.164
+185.204.197.169
+185.204.197.171
+185.204.197.172
+185.204.197.178
+185.204.197.182
+185.204.197.186
+185.204.197.187
+185.204.197.188
+185.204.197.195
+185.204.197.198
+185.204.197.199
+185.204.197.203
+185.204.197.204
+185.204.197.210
+185.204.197.215
+185.204.197.216
+185.204.197.225
+185.204.197.232
+185.204.197.235
+185.204.197.239
+185.204.197.248
+185.205.203.85
+185.205.203.153
+185.205.203.189
+185.205.203.230
+185.205.203.253
+185.206.92.90
+185.206.92.250
+185.206.92.253
+185.206.93.158
+185.206.93.186
+185.206.93.230
+185.206.94.60
+185.206.94.193
+185.206.95.17
+185.206.95.33
+185.206.95.87
+185.206.95.198
+185.206.229.76
+185.206.229.79
+185.206.229.81
+185.206.229.82
+185.206.229.99
+185.206.229.100
+185.206.229.109
+185.206.229.134
+185.206.229.137
+185.206.229.142
+185.206.229.210
+185.206.231.5
+185.206.238.18
+185.206.238.20
+185.206.238.23
+185.206.238.42
+185.206.238.146
+185.206.238.147
+185.206.238.170
+185.207.72.6
+185.207.73.6
+185.208.77.86
+185.208.78.38
+185.208.78.214
+185.208.79.6
+185.208.79.48
+185.208.79.49
+185.208.79.65
+185.208.79.68
+185.208.79.72
+185.208.79.82
+185.208.79.99
+185.208.79.104
+185.208.79.106
+185.208.79.128
+185.208.79.129
+185.208.79.191
+185.208.79.199
+185.208.79.206
+185.208.79.209
+185.208.79.210
+185.208.79.221
+185.208.79.230
+185.208.79.243
+185.208.149.56
+185.208.149.142
+185.208.174.5
+185.208.174.7
+185.208.174.8
+185.208.174.16
+185.208.174.22
+185.208.174.23
+185.208.174.28
+185.208.174.33
+185.208.174.35
+185.208.174.37
+185.208.174.42
+185.208.174.45
+185.208.174.48
+185.208.174.51
+185.208.174.59
+185.208.174.60
+185.208.174.61
+185.208.174.64
+185.208.174.65
+185.208.174.67
+185.208.174.69
+185.208.174.76
+185.208.174.79
+185.208.174.85
+185.208.174.88
+185.208.174.95
+185.208.174.97
+185.208.174.99
+185.208.174.100
+185.208.174.103
+185.208.174.113
+185.208.174.115
+185.208.174.116
+185.208.174.124
+185.208.174.128
+185.208.174.129
+185.208.174.130
+185.208.174.134
+185.208.174.135
+185.208.174.136
+185.208.174.139
+185.208.174.141
+185.208.174.144
+185.208.174.147
+185.208.174.152
+185.208.174.155
+185.208.174.156
+185.208.174.159
+185.208.174.164
+185.208.174.165
+185.208.174.166
+185.208.174.167
+185.208.174.173
+185.208.174.176
+185.208.174.180
+185.208.174.181
+185.208.174.182
+185.208.174.183
+185.208.174.190
+185.208.174.198
+185.208.174.200
+185.208.174.201
+185.208.174.205
+185.208.174.206
+185.208.174.214
+185.208.174.219
+185.208.174.220
+185.208.174.222
+185.208.174.225
+185.208.174.231
+185.208.174.242
+185.208.174.249
+185.208.174.251
+185.208.175.4
+185.208.175.15
+185.208.175.17
+185.208.175.18
+185.208.175.21
+185.208.175.24
+185.208.175.31
+185.208.175.41
+185.208.175.43
+185.208.175.53
+185.208.175.59
+185.208.175.60
+185.208.175.64
+185.208.175.67
+185.208.175.69
+185.208.175.70
+185.208.175.71
+185.208.175.75
+185.208.175.82
+185.208.175.84
+185.208.175.92
+185.208.175.93
+185.208.175.94
+185.208.175.97
+185.208.175.98
+185.208.175.104
+185.208.175.108
+185.208.175.109
+185.208.175.115
+185.208.175.118
+185.208.175.123
+185.208.175.125
+185.208.175.126
+185.208.175.131
+185.208.175.132
+185.208.175.139
+185.208.175.140
+185.208.175.144
+185.208.175.149
+185.208.175.151
+185.208.175.158
+185.208.175.163
+185.208.175.170
+185.208.175.172
+185.208.175.174
+185.208.175.176
+185.208.175.182
+185.208.175.186
+185.208.175.189
+185.208.175.191
+185.208.175.192
+185.208.175.193
+185.208.175.195
+185.208.175.197
+185.208.175.205
+185.208.175.206
+185.208.175.210
+185.208.175.214
+185.208.175.217
+185.208.175.220
+185.208.175.223
+185.208.175.228
+185.208.175.239
+185.208.175.246
+185.208.175.250
+185.208.175.251
+185.208.180.23
+185.208.180.35
+185.208.180.44
+185.208.180.52
+185.208.180.60
+185.208.180.91
+185.208.180.92
+185.208.180.94
+185.208.180.132
+185.208.180.133
+185.208.180.134
+185.208.180.135
+185.208.180.136
+185.208.180.137
+185.208.180.139
+185.208.180.141
+185.208.180.149
+185.208.180.151
+185.208.180.153
+185.208.180.155
+185.208.180.157
+185.208.180.166
+185.208.180.169
+185.208.180.171
+185.208.180.244
+185.208.180.249
+185.208.180.251
+185.208.180.253
+185.208.181.34
+185.208.181.130
+185.208.181.211
+185.208.181.252
+185.208.181.253
+185.208.181.254
+185.208.182.20
+185.208.182.24
+185.208.182.28
+185.208.182.42
+185.208.182.53
+185.208.182.60
+185.208.182.78
+185.208.182.139
+185.208.182.140
+185.208.182.142
+185.208.182.152
+185.208.182.153
+185.208.182.154
+185.208.182.159
+185.208.182.178
+185.208.182.212
+185.208.182.214
+185.208.182.251
+185.208.182.252
+185.208.183.21
+185.208.183.29
+185.208.183.35
+185.208.183.126
+185.208.183.133
+185.208.183.245
+185.209.42.88
+185.209.42.151
+185.209.42.219
+185.209.42.224
+185.210.200.253
+185.210.200.254
+185.211.56.3
+185.211.56.4
+185.211.56.14
+185.211.56.22
+185.211.56.24
+185.211.56.25
+185.211.56.33
+185.211.56.40
+185.211.56.43
+185.211.56.44
+185.211.56.59
+185.211.56.63
+185.211.56.64
+185.211.56.76
+185.211.56.82
+185.211.56.84
+185.211.56.96
+185.211.56.99
+185.211.56.112
+185.211.56.130
+185.211.56.132
+185.211.56.134
+185.211.56.147
+185.211.56.163
+185.211.56.165
+185.211.56.168
+185.211.56.169
+185.211.56.183
+185.211.56.188
+185.211.56.210
+185.211.56.233
+185.211.56.254
+185.211.57.7
+185.211.57.18
+185.211.57.24
+185.211.57.34
+185.211.57.53
+185.211.57.54
+185.211.57.69
+185.211.57.76
+185.211.57.78
+185.211.57.84
+185.211.57.89
+185.211.57.98
+185.211.57.106
+185.211.57.107
+185.211.57.129
+185.211.57.140
+185.211.57.163
+185.211.57.172
+185.211.57.176
+185.211.57.181
+185.211.57.191
+185.211.57.193
+185.211.57.197
+185.211.57.217
+185.211.57.222
+185.211.58.8
+185.211.58.37
+185.211.58.41
+185.211.58.44
+185.211.58.83
+185.211.58.84
+185.211.58.91
+185.211.58.192
+185.211.58.198
+185.211.58.214
+185.211.58.216
+185.211.58.217
+185.211.58.235
+185.211.58.242
+185.211.58.243
+185.211.59.7
+185.211.59.27
+185.211.59.41
+185.211.59.56
+185.211.59.84
+185.211.59.103
+185.211.59.111
+185.211.59.121
+185.211.59.127
+185.211.59.128
+185.211.59.131
+185.211.59.141
+185.211.59.142
+185.211.59.143
+185.211.59.144
+185.211.59.151
+185.211.59.163
+185.211.59.168
+185.211.59.175
+185.211.59.184
+185.211.59.196
+185.211.59.198
+185.211.59.202
+185.211.59.204
+185.211.59.211
+185.211.59.216
+185.211.59.232
+185.211.88.6
+185.211.89.14
+185.211.90.9
+185.212.51.67
+185.212.51.69
+185.212.51.70
+185.212.51.72
+185.212.51.75
+185.212.51.76
+185.212.51.78
+185.212.51.79
+185.212.51.81
+185.212.51.110
+185.212.51.114
+185.212.51.211
+185.212.51.242
+185.212.194.28
+185.212.194.53
+185.212.194.66
+185.212.194.141
+185.212.194.146
+185.212.194.161
+185.212.195.160
+185.213.8.40
+185.213.9.40
+185.213.10.18
+185.213.10.22
+185.213.10.29
+185.213.10.35
+185.213.10.37
+185.213.10.38
+185.213.10.39
+185.213.10.40
+185.213.10.41
+185.213.10.42
+185.213.10.43
+185.213.10.44
+185.213.10.45
+185.213.10.46
+185.213.10.70
+185.213.10.100
+185.213.10.116
+185.213.10.167
+185.213.10.172
+185.213.10.227
+185.213.10.230
+185.213.10.234
+185.213.10.237
+185.213.11.19
+185.213.11.20
+185.213.11.21
+185.213.11.22
+185.213.11.34
+185.213.11.60
+185.213.11.82
+185.213.11.84
+185.213.11.85
+185.213.11.201
+185.213.11.202
+185.213.11.217
+185.213.164.7
+185.213.164.12
+185.213.164.15
+185.213.164.24
+185.213.164.26
+185.213.164.28
+185.213.164.29
+185.213.164.31
+185.213.164.38
+185.213.164.39
+185.213.164.40
+185.213.164.41
+185.213.164.42
+185.213.164.43
+185.213.164.50
+185.213.164.53
+185.213.164.56
+185.213.164.59
+185.213.164.62
+185.213.164.65
+185.213.164.68
+185.213.164.69
+185.213.164.71
+185.213.164.78
+185.213.164.84
+185.213.164.96
+185.213.164.112
+185.213.164.113
+185.213.164.120
+185.213.164.121
+185.213.164.124
+185.213.164.128
+185.213.164.130
+185.213.164.131
+185.213.164.137
+185.213.164.138
+185.213.164.144
+185.213.164.149
+185.213.164.155
+185.213.164.160
+185.213.164.167
+185.213.164.168
+185.213.164.185
+185.213.164.187
+185.213.164.188
+185.213.164.189
+185.213.164.192
+185.213.164.195
+185.213.164.220
+185.213.164.221
+185.213.164.230
+185.213.164.231
+185.213.164.232
+185.213.164.235
+185.213.164.239
+185.213.164.245
+185.213.164.252
+185.213.165.10
+185.213.165.12
+185.213.165.16
+185.213.165.18
+185.213.165.24
+185.213.165.39
+185.213.165.44
+185.213.165.47
+185.213.165.51
+185.213.165.59
+185.213.165.63
+185.213.165.68
+185.213.165.74
+185.213.165.76
+185.213.165.79
+185.213.165.81
+185.213.165.94
+185.213.165.100
+185.213.165.119
+185.213.165.127
+185.213.165.134
+185.213.165.143
+185.213.165.148
+185.213.165.162
+185.213.165.165
+185.213.165.173
+185.213.165.179
+185.213.165.181
+185.213.165.185
+185.213.165.188
+185.213.165.191
+185.213.165.197
+185.213.165.205
+185.213.165.208
+185.213.165.209
+185.213.165.217
+185.213.165.229
+185.213.165.231
+185.213.165.234
+185.213.165.235
+185.213.165.236
+185.213.165.237
+185.213.195.127
+185.213.195.190
+185.215.125.6
+185.215.126.9
+185.215.126.220
+185.215.154.123
+185.215.229.2
+185.215.235.253
+185.217.6.82
+185.217.6.87
+185.217.6.89
+185.217.6.118
+185.218.139.28
+185.218.139.30
+185.218.139.36
+185.218.139.45
+185.218.139.74
+185.218.139.103
+185.218.139.138
+185.218.139.150
+185.218.139.162
+185.218.139.196
+185.218.139.201
+185.218.139.205
+185.218.139.223
+185.218.139.225
+185.218.139.229
+185.218.139.248
+185.218.139.252
+185.218.139.253
+185.221.239.27
+185.221.239.85
+185.221.239.97
+185.221.239.105
+185.221.239.108
+185.221.239.112
+185.221.239.131
+185.221.239.137
+185.221.239.144
+185.221.239.150
+185.221.239.161
+185.221.239.192
+185.221.239.198
+185.221.239.219
+185.221.239.235
+185.221.239.245
+185.222.163.16
+185.222.163.28
+185.222.163.82
+185.222.163.90
+185.222.163.91
+185.222.163.92
+185.222.163.94
+185.222.163.107
+185.222.163.112
+185.222.163.117
+185.222.163.123
+185.222.163.124
+185.222.163.125
+185.222.163.131
+185.222.163.141
+185.222.163.144
+185.222.163.145
+185.222.163.146
+185.222.163.147
+185.222.163.148
+185.222.163.149
+185.222.163.150
+185.222.163.153
+185.222.163.174
+185.222.163.181
+185.222.163.186
+185.222.163.202
+185.222.163.210
+185.222.182.90
+185.222.183.90
+185.225.80.15
+185.225.80.17
+185.225.80.40
+185.225.80.41
+185.225.80.42
+185.225.80.46
+185.225.80.50
+185.225.80.55
+185.225.80.57
+185.225.80.60
+185.225.80.112
+185.225.80.132
+185.225.80.133
+185.225.80.134
+185.225.80.136
+185.225.80.137
+185.225.82.115
+185.225.83.236
+185.226.117.3
+185.226.117.66
+185.226.117.240
+185.226.118.54
+185.226.118.108
+185.226.118.201
+185.226.119.17
+185.226.119.48
+185.226.134.182
+185.226.141.41
+185.226.141.141
+185.226.143.43
+185.226.143.143
+185.229.28.6
+185.229.28.28
+185.229.28.29
+185.229.28.135
+185.229.28.136
+185.229.28.162
+185.229.28.163
+185.229.29.147
+185.229.29.148
+185.229.29.149
+185.229.29.150
+185.229.133.6
+185.229.133.44
+185.229.204.52
+185.229.204.107
+185.229.204.108
+185.229.204.120
+185.229.204.123
+185.229.204.124
+185.229.204.125
+185.229.204.141
+185.229.204.151
+185.229.204.155
+185.229.204.231
+185.231.65.27
+185.231.112.9
+185.231.112.10
+185.231.112.26
+185.231.112.34
+185.231.112.45
+185.231.112.46
+185.231.112.53
+185.231.112.56
+185.231.112.61
+185.231.112.68
+185.231.112.88
+185.231.112.103
+185.231.112.110
+185.231.112.115
+185.231.112.116
+185.231.112.117
+185.231.112.131
+185.231.112.134
+185.231.112.138
+185.231.112.143
+185.231.112.158
+185.231.112.159
+185.231.112.164
+185.231.112.167
+185.231.112.178
+185.231.112.182
+185.231.112.190
+185.231.112.191
+185.231.112.192
+185.231.112.198
+185.231.112.203
+185.231.112.208
+185.231.112.210
+185.231.112.213
+185.231.112.215
+185.231.112.221
+185.231.112.231
+185.231.112.239
+185.231.112.241
+185.231.112.244
+185.231.113.22
+185.231.114.218
+185.231.115.15
+185.231.115.16
+185.231.115.18
+185.231.115.23
+185.231.115.31
+185.231.115.32
+185.231.115.34
+185.231.115.47
+185.231.115.50
+185.231.115.54
+185.231.115.58
+185.231.115.67
+185.231.115.73
+185.231.115.91
+185.231.115.103
+185.231.115.112
+185.231.115.125
+185.231.115.127
+185.231.115.130
+185.231.115.135
+185.231.115.143
+185.231.115.147
+185.231.115.170
+185.231.115.174
+185.231.115.175
+185.231.115.177
+185.231.115.178
+185.231.115.183
+185.231.115.187
+185.231.115.193
+185.231.115.197
+185.231.115.202
+185.231.115.203
+185.231.115.206
+185.231.115.216
+185.231.115.226
+185.231.115.235
+185.231.115.238
+185.231.115.247
+185.231.115.252
+185.231.180.29
+185.231.180.181
+185.231.180.203
+185.231.180.228
+185.231.181.14
+185.231.181.143
+185.231.181.159
+185.231.181.206
+185.231.181.221
+185.231.182.207
+185.231.182.208
+185.231.183.19
+185.231.183.238
+185.232.154.69
+185.234.14.34
+185.234.14.43
+185.234.14.65
+185.234.14.94
+185.234.14.101
+185.234.14.102
+185.234.14.111
+185.234.14.129
+185.234.14.137
+185.234.192.17
+185.234.195.13
+185.235.136.20
+185.235.196.9
+185.235.196.10
+185.235.196.11
+185.235.196.12
+185.235.196.13
+185.235.196.14
+185.235.196.16
+185.235.196.17
+185.235.196.18
+185.235.196.19
+185.235.196.20
+185.235.196.22
+185.235.196.25
+185.235.196.38
+185.235.196.39
+185.235.196.48
+185.235.196.49
+185.235.196.52
+185.235.196.53
+185.235.196.136
+185.235.196.242
+185.235.196.243
+185.235.196.244
+185.235.196.245
+185.235.197.6
+185.235.197.8
+185.235.197.31
+185.235.197.216
+185.235.198.200
+185.235.245.12
+185.235.245.30
+185.235.245.49
+185.235.245.51
+185.235.245.91
+185.235.245.239
+185.235.245.246
+185.235.245.247
+185.236.36.21
+185.236.37.15
+185.236.37.179
+185.236.37.198
+185.236.38.92
+185.237.84.10
+185.237.84.11
+185.237.85.4
+185.237.85.5
+185.237.85.9
+185.237.85.10
+185.237.85.16
+185.237.85.21
+185.237.85.26
+185.237.85.40
+185.237.85.42
+185.237.85.47
+185.237.85.54
+185.237.85.55
+185.237.85.56
+185.237.85.95
+185.237.85.96
+185.237.85.97
+185.237.85.114
+185.237.85.117
+185.237.85.118
+185.237.85.252
+185.237.87.84
+185.237.87.85
+185.237.87.139
+185.238.140.195
+185.238.143.229
+185.239.0.12
+185.239.0.22
+185.239.0.53
+185.239.0.86
+185.239.0.127
+185.239.0.190
+185.239.0.232
+185.239.0.239
+185.239.0.246
+185.239.1.179
+185.239.2.31
+185.239.3.47
+185.239.3.86
+185.239.3.112
+185.239.3.117
+185.239.3.124
+185.239.3.151
+185.239.3.152
+185.239.3.187
+185.239.3.199
+185.239.3.208
+185.239.3.220
+185.239.3.222
+185.239.3.224
+185.239.3.236
+185.239.104.106
+185.239.105.144
+185.239.106.86
+185.243.48.4
+185.243.48.13
+185.243.48.15
+185.243.48.28
+185.243.48.31
+185.243.48.45
+185.243.48.52
+185.243.48.57
+185.243.48.58
+185.243.48.70
+185.243.48.78
+185.243.48.102
+185.243.48.109
+185.243.48.126
+185.243.48.127
+185.243.48.131
+185.243.48.132
+185.243.48.134
+185.243.48.135
+185.243.48.140
+185.243.48.145
+185.243.48.159
+185.243.48.170
+185.243.48.173
+185.243.48.176
+185.243.48.181
+185.243.48.189
+185.243.48.196
+185.243.48.198
+185.243.48.199
+185.243.48.200
+185.243.48.202
+185.243.48.204
+185.243.48.211
+185.243.48.215
+185.243.48.226
+185.243.48.227
+185.243.48.231
+185.243.48.233
+185.243.48.237
+185.243.48.242
+185.243.48.243
+185.243.48.251
+185.243.51.50
+185.243.51.58
+185.246.6.178
+185.246.6.179
+185.252.28.13
+185.252.28.16
+185.252.28.19
+185.252.28.20
+185.252.28.21
+185.252.28.30
+185.252.28.31
+185.252.28.32
+185.252.28.34
+185.252.28.42
+185.252.28.44
+185.252.28.46
+185.252.28.47
+185.252.28.56
+185.252.28.63
+185.252.28.68
+185.252.28.77
+185.252.28.86
+185.252.28.105
+185.252.28.106
+185.252.28.116
+185.252.28.117
+185.252.28.120
+185.252.28.123
+185.252.28.124
+185.252.28.127
+185.252.28.128
+185.252.28.129
+185.252.28.130
+185.252.28.136
+185.252.28.137
+185.252.28.138
+185.252.28.140
+185.252.28.150
+185.252.28.165
+185.252.28.166
+185.252.28.170
+185.252.28.178
+185.252.28.179
+185.252.28.180
+185.252.28.182
+185.252.28.186
+185.252.28.188
+185.252.28.192
+185.252.28.194
+185.252.28.195
+185.252.28.200
+185.252.28.207
+185.252.28.210
+185.252.28.211
+185.252.28.228
+185.252.28.229
+185.252.28.230
+185.252.29.11
+185.252.29.14
+185.252.29.17
+185.252.29.18
+185.252.29.27
+185.252.29.29
+185.252.29.31
+185.252.29.32
+185.252.29.35
+185.252.29.47
+185.252.29.50
+185.252.29.53
+185.252.29.54
+185.252.29.60
+185.252.29.62
+185.252.29.68
+185.252.29.72
+185.252.29.74
+185.252.29.99
+185.252.29.102
+185.252.29.121
+185.252.29.133
+185.252.29.141
+185.252.29.143
+185.252.29.145
+185.252.29.151
+185.252.29.154
+185.252.29.160
+185.252.29.161
+185.252.29.162
+185.252.29.234
+185.252.29.235
+185.252.29.239
+185.252.30.39
+185.252.30.40
+185.252.30.41
+185.252.30.42
+185.252.30.43
+185.252.30.175
+185.252.30.188
+185.252.30.200
+185.252.30.206
+185.252.31.4
+185.252.31.5
+185.252.31.8
+185.252.31.10
+185.252.31.19
+185.252.31.21
+185.252.31.22
+185.252.31.27
+185.252.31.28
+185.252.31.32
+185.252.31.33
+185.252.31.40
+185.252.31.42
+185.252.31.43
+185.252.31.62
+185.252.31.63
+185.252.31.65
+185.252.31.99
+185.252.31.103
+185.252.31.105
+185.252.31.116
+185.252.31.119
+185.252.31.120
+185.252.31.138
+185.252.31.140
+185.252.31.142
+185.252.31.146
+185.252.31.161
+185.252.31.164
+185.252.31.165
+185.252.31.166
+185.252.31.201
+185.252.31.203
+185.252.31.213
+185.252.31.223
+185.252.86.15
+185.252.86.17
+185.252.86.20
+185.252.86.30
+185.252.86.31
+185.252.86.34
+185.252.86.36
+185.252.86.38
+185.252.86.43
+185.252.86.49
+185.252.86.56
+185.252.86.75
+185.252.86.77
+185.252.86.79
+185.252.86.81
+185.252.86.102
+185.252.86.107
+185.252.86.110
+185.252.86.120
+185.252.86.121
+185.252.86.125
+185.252.86.126
+185.252.86.145
+185.252.86.164
+185.252.86.165
+185.252.86.168
+185.252.86.171
+185.252.86.181
+185.252.86.183
+185.252.86.185
+185.252.200.157
+185.254.165.5
+185.255.88.3
+185.255.88.11
+185.255.88.12
+185.255.88.13
+185.255.88.15
+185.255.88.18
+185.255.88.19
+185.255.88.24
+185.255.88.36
+185.255.88.42
+185.255.88.59
+185.255.88.61
+185.255.88.63
+185.255.88.64
+185.255.88.66
+185.255.88.68
+185.255.88.74
+185.255.88.79
+185.255.88.85
+185.255.88.102
+185.255.88.106
+185.255.88.107
+185.255.88.109
+185.255.88.110
+185.255.88.112
+185.255.88.113
+185.255.88.115
+185.255.88.117
+185.255.88.118
+185.255.88.119
+185.255.88.123
+185.255.88.124
+185.255.88.126
+185.255.88.130
+185.255.88.131
+185.255.88.132
+185.255.88.134
+185.255.88.135
+185.255.88.136
+185.255.88.137
+185.255.88.139
+185.255.88.140
+185.255.88.142
+185.255.88.145
+185.255.88.148
+185.255.88.149
+185.255.88.150
+185.255.88.152
+185.255.88.156
+185.255.88.157
+185.255.88.160
+185.255.88.161
+185.255.88.164
+185.255.88.167
+185.255.88.169
+185.255.88.171
+185.255.88.172
+185.255.88.173
+185.255.88.174
+185.255.88.175
+185.255.88.176
+185.255.88.177
+185.255.88.182
+185.255.88.188
+185.255.88.190
+185.255.88.191
+185.255.88.194
+185.255.88.198
+185.255.88.200
+185.255.88.203
+185.255.88.207
+185.255.88.212
+185.255.88.214
+185.255.88.216
+185.255.88.217
+185.255.88.218
+185.255.88.219
+185.255.89.6
+185.255.89.7
+185.255.89.8
+185.255.89.10
+185.255.89.12
+185.255.89.13
+185.255.89.14
+185.255.89.15
+185.255.89.18
+185.255.89.26
+185.255.89.37
+185.255.89.38
+185.255.89.40
+185.255.89.46
+185.255.89.57
+185.255.89.60
+185.255.89.66
+185.255.89.86
+185.255.89.90
+185.255.89.94
+185.255.89.102
+185.255.89.103
+185.255.89.104
+185.255.89.106
+185.255.89.110
+185.255.89.112
+185.255.89.116
+185.255.89.118
+185.255.89.119
+185.255.89.120
+185.255.89.122
+185.255.89.123
+185.255.89.126
+185.255.89.128
+185.255.89.131
+185.255.89.132
+185.255.89.134
+185.255.89.139
+185.255.89.142
+185.255.89.143
+185.255.89.147
+185.255.89.149
+185.255.89.150
+185.255.89.151
+185.255.89.152
+185.255.89.153
+185.255.89.157
+185.255.89.160
+185.255.89.166
+185.255.89.168
+185.255.89.171
+185.255.89.173
+185.255.89.181
+185.255.89.191
+185.255.89.199
+185.255.89.200
+185.255.89.205
+185.255.89.207
+185.255.89.210
+185.255.89.216
+185.255.89.229
+185.255.89.233
+185.255.89.237
+185.255.89.243
+185.255.89.244
+185.255.90.15
+185.255.90.17
+185.255.90.41
+185.255.90.48
+185.255.90.82
+185.255.90.104
+185.255.90.105
+185.255.90.109
+185.255.90.123
+185.255.90.125
+185.255.90.129
+185.255.90.137
+185.255.90.148
+185.255.90.152
+185.255.90.159
+185.255.90.162
+185.255.90.163
+185.255.90.202
+185.255.90.205
+185.255.91.15
+185.255.91.20
+185.255.91.32
+185.255.91.36
+185.255.91.48
+185.255.91.58
+185.255.91.60
+185.255.91.80
+185.255.91.116
+185.255.91.120
+185.255.91.132
+185.255.91.140
+185.255.91.144
+185.255.91.147
+185.255.91.160
+185.255.91.173
+185.255.91.182
+185.255.91.190
+185.255.91.208
+185.255.91.212
+185.255.91.213
+185.255.91.215
+185.255.91.219
+185.255.91.227
+185.255.91.229
+185.255.91.232
+185.255.91.234
+185.255.91.235
+185.255.91.237
+185.255.91.242
+185.255.91.243
+185.255.91.244
+185.255.208.144
+185.255.208.221
+185.255.208.222
+185.255.208.243
+185.255.209.48
+188.0.240.12
+188.0.240.13
+188.0.240.42
+188.0.240.43
+188.0.240.44
+188.0.240.85
+188.0.240.130
+188.0.240.131
+188.0.240.134
+188.0.240.186
+188.0.240.187
+188.0.240.188
+188.0.240.189
+188.0.240.190
+188.0.240.194
+188.0.240.195
+188.0.240.217
+188.0.241.19
+188.0.241.76
+188.0.241.77
+188.0.241.78
+188.0.241.101
+188.0.241.248
+188.0.248.66
+188.0.248.233
+188.0.253.168
+188.75.65.222
+188.75.78.130
+188.75.78.136
+188.75.78.138
+188.75.78.162
+188.75.78.164
+188.75.78.172
+188.75.78.174
+188.75.78.184
+188.75.78.187
+188.75.78.189
+188.75.80.176
+188.75.82.172
+188.75.82.173
+188.75.95.22
+188.75.95.66
+188.75.106.66
+188.75.106.69
+188.75.106.70
+188.75.106.178
+188.75.106.179
+188.75.106.184
+188.75.106.185
+188.121.96.94
+188.121.97.2
+188.121.99.119
+188.121.99.121
+188.121.99.199
+188.121.100.85
+188.121.100.96
+188.121.100.104
+188.121.100.200
+188.121.100.251
+188.121.101.238
+188.121.102.172
+188.121.102.175
+188.121.102.244
+188.121.103.36
+188.121.103.186
+188.121.103.193
+188.121.104.41
+188.121.105.164
+188.121.105.234
+188.121.107.156
+188.121.109.173
+188.121.110.50
+188.121.110.163
+188.121.110.254
+188.121.112.58
+188.121.112.78
+188.121.112.92
+188.121.112.127
+188.121.112.198
+188.121.113.10
+188.121.113.74
+188.121.113.102
+188.121.113.191
+188.121.113.210
+188.121.113.213
+188.121.114.188
+188.121.114.240
+188.121.114.247
+188.121.115.45
+188.121.115.61
+188.121.116.50
+188.121.116.80
+188.121.116.139
+188.121.116.237
+188.121.116.252
+188.121.117.27
+188.121.117.64
+188.121.117.146
+188.121.117.170
+188.121.118.14
+188.121.118.52
+188.121.118.134
+188.121.118.179
+188.121.119.37
+188.121.119.58
+188.121.119.90
+188.121.119.103
+188.121.119.202
+188.121.120.171
+188.121.122.33
+188.121.123.26
+188.121.123.159
+188.121.124.11
+188.121.125.89
+188.121.132.140
+188.121.157.234
+188.121.158.211
+188.136.136.9
+188.136.136.18
+188.136.136.44
+188.136.137.137
+188.136.137.138
+188.136.138.16
+188.136.138.17
+188.136.138.18
+188.136.138.19
+188.136.138.21
+188.136.138.23
+188.136.138.30
+188.136.138.31
+188.136.138.32
+188.136.138.33
+188.136.138.35
+188.136.138.36
+188.136.138.37
+188.136.138.38
+188.136.138.39
+188.136.138.40
+188.136.138.41
+188.136.138.42
+188.136.138.43
+188.136.138.44
+188.136.138.100
+188.136.142.225
+188.136.154.151
+188.136.172.3
+188.136.172.170
+188.136.194.102
+188.136.208.245
+188.191.176.47
+188.191.176.48
+188.208.144.158
+188.208.149.251
+188.209.7.172
+188.209.8.200
+188.209.9.1
+188.209.67.214
+188.209.68.97
+188.209.72.9
+188.209.79.76
+188.209.152.106
+188.210.112.2
+188.210.115.164
+188.210.115.245
+188.210.120.63
+188.210.121.66
+188.211.36.201
+188.211.36.224
+188.211.66.248
+188.211.69.120
+188.211.72.197
+188.211.74.26
+188.211.79.18
+188.211.79.68
+188.211.81.31
+188.211.83.163
+188.211.85.185
+188.211.86.127
+188.211.91.220
+188.211.98.243
+188.211.100.56
+188.211.100.115
+188.211.102.37
+188.211.102.179
+188.211.102.212
+188.211.108.253
+188.211.111.51
+188.211.113.70
+188.211.119.60
+188.211.124.229
+188.212.22.5
+188.212.22.7
+188.212.22.10
+188.212.22.17
+188.212.22.19
+188.212.22.20
+188.212.22.22
+188.212.22.23
+188.212.22.36
+188.212.22.38
+188.212.22.39
+188.212.22.40
+188.212.22.41
+188.212.22.46
+188.212.22.53
+188.212.22.54
+188.212.22.59
+188.212.22.81
+188.212.22.82
+188.212.22.99
+188.212.22.106
+188.212.22.116
+188.212.22.122
+188.212.22.130
+188.212.22.131
+188.212.22.133
+188.212.22.134
+188.212.22.152
+188.212.22.158
+188.212.22.163
+188.212.22.164
+188.212.22.167
+188.212.22.171
+188.212.22.178
+188.212.22.179
+188.212.22.180
+188.212.22.187
+188.212.22.190
+188.212.22.195
+188.212.22.198
+188.212.22.199
+188.212.22.200
+188.212.22.201
+188.212.22.205
+188.212.22.213
+188.212.22.214
+188.212.22.216
+188.212.22.226
+188.212.22.227
+188.212.22.228
+188.212.22.229
+188.212.22.230
+188.212.22.234
+188.212.22.235
+188.212.22.236
+188.212.22.237
+188.212.22.238
+188.212.22.242
+188.212.22.243
+188.212.22.248
+188.212.22.249
+188.212.22.251
+188.212.22.252
+188.212.22.253
+188.212.22.254
+188.212.86.72
+188.212.148.101
+188.212.163.97
+188.213.65.54
+188.213.65.140
+188.213.65.141
+188.213.65.156
+188.213.66.6
+188.213.66.9
+188.213.66.12
+188.213.66.13
+188.213.66.14
+188.213.66.16
+188.213.66.17
+188.213.66.18
+188.213.66.21
+188.213.66.23
+188.213.66.24
+188.213.66.26
+188.213.66.30
+188.213.66.91
+188.213.66.139
+188.213.66.141
+188.213.66.156
+188.213.66.157
+188.213.66.158
+188.213.66.172
+188.213.68.3
+188.213.68.4
+188.213.68.5
+188.213.68.7
+188.213.68.12
+188.213.68.13
+188.213.68.99
+188.213.72.13
+188.213.72.71
+188.213.72.84
+188.213.72.85
+188.213.75.5
+188.213.75.51
+188.213.154.188
+188.213.187.132
+188.213.188.41
+188.213.188.123
+188.213.196.191
+188.213.196.202
+188.213.198.4
+188.213.198.90
+188.213.198.236
+188.213.199.7
+188.213.199.80
+188.213.199.141
+188.213.209.31
+188.213.209.49
+188.215.160.93
+188.215.174.178
+188.240.212.208
+188.240.212.209
+188.240.212.210
+188.240.212.211
+188.240.212.212
+188.240.212.213
+188.240.212.214
+188.240.212.215
+188.253.2.6
+188.253.2.16
+188.253.2.19
+188.253.2.22
+188.253.2.24
+188.253.2.25
+188.253.2.30
+188.253.2.31
+188.253.2.33
+188.253.2.37
+188.253.2.38
+188.253.2.42
+188.253.2.50
+188.253.2.52
+188.253.2.53
+188.253.2.56
+188.253.2.57
+188.253.2.58
+188.253.2.63
+188.253.2.64
+188.253.2.65
+188.253.2.68
+188.253.2.70
+188.253.2.76
+188.253.2.79
+188.253.2.85
+188.253.2.88
+188.253.2.92
+188.253.2.95
+188.253.2.98
+188.253.2.99
+188.253.2.112
+188.253.2.120
+188.253.2.122
+188.253.2.123
+188.253.2.124
+188.253.2.125
+188.253.2.136
+188.253.2.138
+188.253.2.146
+188.253.2.150
+188.253.2.156
+188.253.2.165
+188.253.2.166
+188.253.2.171
+188.253.2.174
+188.253.2.180
+188.253.2.184
+188.253.2.186
+188.253.2.188
+188.253.2.189
+188.253.2.191
+188.253.2.198
+188.253.2.200
+188.253.2.206
+188.253.2.207
+188.253.2.211
+188.253.2.214
+188.253.2.220
+188.253.2.245
+188.253.2.248
+188.253.2.249
+188.253.2.251
+188.253.3.7
+188.253.3.17
+188.253.3.18
+188.253.3.34
+188.253.3.35
+188.253.3.37
+188.253.3.38
+188.253.3.39
+188.253.3.43
+188.253.3.50
+188.253.3.54
+188.253.3.59
+188.253.3.60
+188.253.3.61
+188.253.3.69
+188.253.3.74
+188.253.3.77
+188.253.3.78
+188.253.3.79
+188.253.3.89
+188.253.3.104
+188.253.3.124
+188.253.3.125
+188.253.3.127
+188.253.3.130
+188.253.3.137
+188.253.3.148
+188.253.3.149
+188.253.3.188
+188.253.3.194
+188.253.3.195
+188.253.3.196
+188.253.3.197
+188.253.3.198
+188.253.3.226
+188.253.3.250
+192.36.148.17
+193.3.31.11
+193.3.31.12
+193.3.31.20
+193.3.182.25
+193.3.182.59
+193.3.231.146
+193.3.231.150
+193.3.231.158
+193.3.231.194
+193.3.231.210
+193.3.231.218
+193.3.231.222
+193.3.231.230
+193.3.231.254
+193.5.44.11
+193.5.44.12
+193.5.44.14
+193.5.44.26
+193.5.44.30
+193.5.44.58
+193.5.44.62
+193.5.44.67
+193.5.44.80
+193.5.44.86
+193.5.44.88
+193.5.44.92
+193.5.44.94
+193.5.44.105
+193.5.44.107
+193.5.44.110
+193.5.44.115
+193.5.44.152
+193.5.44.158
+193.5.44.159
+193.5.44.161
+193.5.44.192
+193.5.44.237
+193.8.139.55
+193.8.139.56
+193.19.147.244
+193.19.147.245
+193.35.62.1
+193.35.230.4
+193.35.230.5
+193.35.230.6
+193.35.230.7
+193.35.230.8
+193.35.230.10
+193.35.230.13
+193.35.230.14
+193.35.230.15
+193.35.230.16
+193.35.230.17
+193.35.230.18
+193.35.230.19
+193.35.230.20
+193.35.230.21
+193.35.230.22
+193.35.230.23
+193.35.230.24
+193.35.230.25
+193.35.230.26
+193.35.230.27
+193.35.230.28
+193.35.230.29
+193.35.230.30
+193.35.230.31
+193.35.230.32
+193.37.37.38
+193.37.37.243
+193.39.9.3
+193.39.9.32
+193.39.9.54
+193.39.9.92
+193.39.9.105
+193.39.9.107
+193.39.9.117
+193.39.9.162
+193.39.9.166
+193.39.9.188
+193.39.9.191
+193.39.9.214
+193.39.9.236
+193.39.9.250
+193.56.61.66
+193.56.61.67
+193.56.118.1
+193.58.119.50
+193.58.119.130
+193.58.119.198
+193.58.119.234
+193.58.119.247
+193.84.255.2
+193.84.255.20
+193.84.255.66
+193.84.255.95
+193.105.2.90
+193.105.2.91
+193.105.6.15
+193.105.6.30
+193.105.6.118
+193.105.6.120
+193.105.6.121
+193.105.6.131
+193.105.6.133
+193.105.6.235
+193.105.234.13
+193.105.234.17
+193.105.234.19
+193.105.234.20
+193.105.234.29
+193.105.234.38
+193.105.234.58
+193.105.234.68
+193.105.234.81
+193.105.234.85
+193.105.234.87
+193.105.234.88
+193.105.234.90
+193.105.234.93
+193.105.234.96
+193.105.234.100
+193.105.234.104
+193.105.234.105
+193.105.234.111
+193.105.234.115
+193.105.234.119
+193.105.234.131
+193.105.234.143
+193.105.234.144
+193.105.234.151
+193.105.234.164
+193.105.234.165
+193.105.234.167
+193.105.234.180
+193.105.234.191
+193.105.234.207
+193.105.234.216
+193.105.234.223
+193.105.234.229
+193.105.234.230
+193.105.234.231
+193.105.234.234
+193.105.234.237
+193.105.234.243
+193.107.48.72
+193.107.48.203
+193.107.48.222
+193.111.76.3
+193.111.76.10
+193.111.234.35
+193.111.234.40
+193.111.234.61
+193.111.234.72
+193.111.234.114
+193.111.234.147
+193.111.234.152
+193.111.234.153
+193.111.234.196
+193.111.235.7
+193.111.235.77
+193.111.235.103
+193.111.235.115
+193.111.235.160
+193.111.235.179
+193.111.236.99
+193.111.236.101
+193.111.236.103
+193.134.100.12
+193.134.100.60
+193.134.100.148
+193.134.100.155
+193.134.101.20
+193.134.101.172
+193.134.101.173
+193.141.64.5
+193.141.64.7
+193.141.64.10
+193.141.64.11
+193.141.64.23
+193.141.64.32
+193.141.64.35
+193.141.64.38
+193.141.64.44
+193.141.64.47
+193.141.64.48
+193.141.64.55
+193.141.64.61
+193.141.64.66
+193.141.64.68
+193.141.64.88
+193.141.64.90
+193.141.64.103
+193.141.64.107
+193.141.64.109
+193.141.64.110
+193.141.64.111
+193.141.64.115
+193.141.64.117
+193.141.64.118
+193.141.64.119
+193.141.64.120
+193.141.64.121
+193.141.64.122
+193.141.64.123
+193.141.64.125
+193.141.64.126
+193.141.64.128
+193.141.64.129
+193.141.64.130
+193.141.64.134
+193.141.64.140
+193.141.64.142
+193.141.64.143
+193.141.64.146
+193.141.64.149
+193.141.64.152
+193.141.64.153
+193.141.64.154
+193.141.64.157
+193.141.64.158
+193.141.64.160
+193.141.64.174
+193.141.64.182
+193.141.64.191
+193.141.64.192
+193.141.64.212
+193.141.64.213
+193.141.64.215
+193.141.64.217
+193.141.64.221
+193.141.64.231
+193.141.64.239
+193.141.64.241
+193.141.64.242
+193.141.64.247
+193.141.64.248
+193.141.65.17
+193.141.65.24
+193.141.65.26
+193.141.65.28
+193.141.65.34
+193.141.65.42
+193.141.65.45
+193.141.65.56
+193.141.65.67
+193.141.65.68
+193.141.65.73
+193.141.65.78
+193.141.65.81
+193.141.65.82
+193.141.65.92
+193.141.65.94
+193.141.65.97
+193.141.65.99
+193.141.65.100
+193.141.65.101
+193.141.65.106
+193.141.65.107
+193.141.65.112
+193.141.65.115
+193.141.65.125
+193.141.65.129
+193.141.65.131
+193.141.65.142
+193.141.65.146
+193.141.65.155
+193.141.65.160
+193.141.65.167
+193.141.65.168
+193.141.65.169
+193.141.65.178
+193.141.65.185
+193.141.65.186
+193.141.65.188
+193.141.65.221
+193.141.65.222
+193.141.65.224
+193.141.65.228
+193.141.65.234
+193.141.65.244
+193.141.65.253
+193.148.64.119
+193.148.65.65
+193.148.66.1
+193.148.66.11
+193.148.66.66
+193.148.66.190
+193.151.128.225
+193.151.130.4
+193.151.131.113
+193.151.131.151
+193.151.134.65
+193.151.134.90
+193.151.134.104
+193.151.134.156
+193.151.134.206
+193.151.135.112
+193.151.135.182
+193.151.136.80
+193.151.137.194
+193.151.140.11
+193.151.144.140
+193.151.144.201
+193.151.145.107
+193.151.145.125
+193.151.146.234
+193.151.149.64
+193.151.149.160
+193.151.153.95
+193.151.153.225
+193.151.154.24
+193.151.155.149
+193.151.157.12
+193.151.157.13
+193.151.157.14
+193.151.157.15
+193.151.157.16
+193.151.157.17
+193.151.157.19
+193.151.157.20
+193.151.157.29
+193.151.157.30
+193.151.159.58
+193.151.159.59
+193.151.159.60
+193.151.159.61
+193.151.159.62
+193.151.159.226
+193.151.159.227
+193.151.159.228
+193.151.159.245
+193.151.159.246
+193.151.159.247
+193.151.159.253
+193.151.159.254
+193.162.129.10
+193.162.129.11
+193.162.129.14
+193.162.129.35
+193.162.129.59
+193.162.129.63
+193.162.129.77
+193.162.129.78
+193.162.129.156
+193.162.129.170
+193.162.129.212
+193.162.129.216
+193.162.129.217
+193.162.129.223
+193.162.129.224
+193.162.129.226
+193.162.129.233
+193.162.129.242
+193.162.129.248
+193.176.97.94
+193.178.200.3
+193.178.200.5
+193.186.32.5
+193.186.32.7
+193.186.32.32
+193.186.32.45
+193.186.32.56
+193.186.32.58
+193.186.32.59
+193.186.32.81
+193.186.32.87
+193.186.32.105
+193.186.32.106
+193.186.32.108
+193.186.32.109
+193.186.32.111
+193.186.32.113
+193.186.32.123
+193.186.32.139
+193.186.32.141
+193.186.32.145
+193.186.32.148
+193.186.32.152
+193.186.32.155
+193.186.32.156
+193.186.32.162
+193.186.32.170
+193.186.32.178
+193.186.32.184
+193.186.32.197
+193.186.32.199
+193.186.32.201
+193.186.32.203
+193.186.32.216
+193.186.32.222
+193.186.32.227
+193.186.32.239
+193.186.32.242
+193.186.32.246
+193.186.32.247
+193.186.32.248
+193.186.32.249
+193.186.32.251
+193.186.32.252
+193.200.148.9
+193.200.148.66
+193.222.51.1
+193.228.90.2
+193.228.90.3
+193.228.90.4
+193.228.90.5
+193.228.90.6
+193.228.90.7
+193.228.90.8
+193.228.90.13
+193.228.90.19
+193.228.90.20
+193.228.90.21
+193.228.90.23
+193.228.90.25
+193.228.90.27
+193.228.90.28
+193.228.90.35
+193.228.90.37
+193.228.90.39
+193.228.90.40
+193.228.90.42
+193.228.90.43
+193.228.90.46
+193.228.90.48
+193.228.90.57
+193.228.90.63
+193.228.90.64
+193.228.90.70
+193.228.90.72
+193.228.90.76
+193.228.90.78
+193.228.90.82
+193.228.90.87
+193.228.90.90
+193.228.90.91
+193.228.90.92
+193.228.90.93
+193.228.90.99
+193.228.90.101
+193.228.90.102
+193.228.90.111
+193.228.90.112
+193.228.90.113
+193.228.90.119
+193.228.90.120
+193.228.90.130
+193.228.90.131
+193.228.90.132
+193.228.90.136
+193.228.90.139
+193.228.90.141
+193.228.90.144
+193.228.90.145
+193.228.90.147
+193.228.90.148
+193.228.90.156
+193.228.90.161
+193.228.90.180
+193.228.90.182
+193.228.90.185
+193.228.90.186
+193.228.90.188
+193.228.90.189
+193.228.90.191
+193.228.90.198
+193.228.90.199
+193.228.90.238
+193.228.90.244
+193.228.90.245
+193.228.90.253
+193.228.90.254
+193.228.169.51
+193.228.169.234
+193.242.125.12
+193.242.125.15
+193.242.125.25
+193.242.125.28
+193.242.125.29
+193.242.125.35
+193.242.125.38
+193.242.125.47
+193.242.125.51
+193.242.125.61
+193.242.125.63
+193.242.125.65
+193.242.125.69
+193.242.125.73
+193.242.125.83
+193.242.125.93
+193.242.125.112
+193.242.125.124
+193.242.125.135
+193.242.125.141
+193.242.125.156
+193.242.125.186
+193.242.125.189
+193.242.125.197
+193.242.125.198
+193.242.125.217
+193.242.125.221
+193.242.125.223
+193.242.125.232
+193.242.125.241
+193.242.125.251
+193.242.125.254
+193.242.208.10
+193.242.208.21
+193.242.208.94
+193.242.208.110
+193.242.208.124
+193.242.208.128
+193.242.208.166
+193.242.208.185
+193.242.208.245
+193.246.200.118
+193.246.200.121
+194.1.155.45
+194.5.175.15
+194.5.175.22
+194.5.175.24
+194.5.175.29
+194.5.175.33
+194.5.175.35
+194.5.175.37
+194.5.175.38
+194.5.175.42
+194.5.175.44
+194.5.175.46
+194.5.175.52
+194.5.175.61
+194.5.175.73
+194.5.175.74
+194.5.175.75
+194.5.175.76
+194.5.175.81
+194.5.175.89
+194.5.175.90
+194.5.175.104
+194.5.175.113
+194.5.175.114
+194.5.175.115
+194.5.175.117
+194.5.175.119
+194.5.175.132
+194.5.175.139
+194.5.175.144
+194.5.175.145
+194.5.175.146
+194.5.175.154
+194.5.175.157
+194.5.175.158
+194.5.175.164
+194.5.175.169
+194.5.175.170
+194.5.175.178
+194.5.175.181
+194.5.175.183
+194.5.175.186
+194.5.175.190
+194.5.175.200
+194.5.175.202
+194.5.175.216
+194.5.175.217
+194.5.175.236
+194.5.175.242
+194.5.175.244
+194.5.175.246
+194.5.175.247
+194.5.175.249
+194.5.175.251
+194.5.176.46
+194.5.176.203
+194.5.176.206
+194.5.177.120
+194.5.178.48
+194.5.178.81
+194.5.179.79
+194.5.179.181
+194.5.188.18
+194.5.188.40
+194.5.188.41
+194.5.188.42
+194.5.188.53
+194.5.188.56
+194.5.188.59
+194.5.188.63
+194.5.188.66
+194.5.188.76
+194.5.188.79
+194.5.188.83
+194.5.188.93
+194.5.188.112
+194.5.188.124
+194.5.188.126
+194.5.188.128
+194.5.188.132
+194.5.188.136
+194.5.188.147
+194.5.188.148
+194.5.188.159
+194.5.188.161
+194.5.188.169
+194.5.188.183
+194.5.188.193
+194.5.188.194
+194.5.188.198
+194.5.188.208
+194.5.188.214
+194.5.188.216
+194.5.188.222
+194.5.188.225
+194.5.188.226
+194.5.188.230
+194.5.188.231
+194.5.188.236
+194.5.188.237
+194.5.188.240
+194.5.188.241
+194.5.188.242
+194.5.188.243
+194.5.188.246
+194.5.188.247
+194.5.188.251
+194.5.188.252
+194.5.195.14
+194.5.195.20
+194.5.195.23
+194.5.195.24
+194.5.195.33
+194.5.195.37
+194.5.195.50
+194.5.195.53
+194.5.195.62
+194.5.195.66
+194.5.195.69
+194.5.195.76
+194.5.195.79
+194.5.195.80
+194.5.195.89
+194.5.195.91
+194.5.195.92
+194.5.195.93
+194.5.195.96
+194.5.195.100
+194.5.195.101
+194.5.195.104
+194.5.195.117
+194.5.195.120
+194.5.195.126
+194.5.195.129
+194.5.195.133
+194.5.195.134
+194.5.195.143
+194.5.195.146
+194.5.195.152
+194.5.195.153
+194.5.195.154
+194.5.195.155
+194.5.195.156
+194.5.195.158
+194.5.195.161
+194.5.195.162
+194.5.195.163
+194.5.195.164
+194.5.195.167
+194.5.195.168
+194.5.195.172
+194.5.195.175
+194.5.195.176
+194.5.195.185
+194.5.195.188
+194.5.195.191
+194.5.195.192
+194.5.195.200
+194.5.195.205
+194.5.195.215
+194.5.195.219
+194.5.195.221
+194.5.195.226
+194.5.195.227
+194.5.195.234
+194.5.195.244
+194.5.195.247
+194.5.195.248
+194.5.195.249
+194.5.205.10
+194.5.205.11
+194.5.205.12
+194.5.205.16
+194.5.205.31
+194.5.205.32
+194.5.205.34
+194.5.205.36
+194.5.205.37
+194.5.205.39
+194.5.205.40
+194.5.205.64
+194.5.205.70
+194.5.205.85
+194.5.205.86
+194.5.205.88
+194.5.205.89
+194.5.205.91
+194.5.205.92
+194.5.205.93
+194.5.205.97
+194.5.205.110
+194.5.205.117
+194.5.205.121
+194.5.205.128
+194.5.205.149
+194.5.205.150
+194.5.205.158
+194.5.205.161
+194.5.205.163
+194.5.205.166
+194.5.205.168
+194.5.205.169
+194.5.205.170
+194.5.205.172
+194.5.205.176
+194.5.205.178
+194.5.205.179
+194.5.205.181
+194.5.205.191
+194.5.205.192
+194.5.205.193
+194.5.205.200
+194.5.205.203
+194.5.205.213
+194.5.205.214
+194.5.205.231
+194.5.205.237
+194.5.205.239
+194.5.205.247
+194.5.205.249
+194.5.205.250
+194.9.56.58
+194.9.56.62
+194.9.56.102
+194.9.56.124
+194.9.56.138
+194.9.57.212
+194.9.80.10
+194.9.80.19
+194.9.80.45
+194.9.80.58
+194.9.80.75
+194.9.80.153
+194.9.80.154
+194.9.80.155
+194.9.80.156
+194.9.80.157
+194.9.80.158
+194.9.80.160
+194.9.80.193
+194.9.80.202
+194.9.81.51
+194.9.81.131
+194.31.108.2
+194.31.108.3
+194.31.108.4
+194.31.108.7
+194.31.108.8
+194.31.108.9
+194.31.108.14
+194.31.108.15
+194.31.108.16
+194.31.108.24
+194.31.108.27
+194.31.108.28
+194.31.108.83
+194.31.108.88
+194.31.194.2
+194.31.194.36
+194.31.194.37
+194.31.194.42
+194.31.194.100
+194.31.194.105
+194.31.194.114
+194.31.194.125
+194.31.194.130
+194.31.194.143
+194.31.194.145
+194.31.194.146
+194.31.194.148
+194.31.194.158
+194.31.194.163
+194.31.194.178
+194.31.194.194
+194.31.194.195
+194.31.194.205
+194.31.194.217
+194.31.194.221
+194.33.105.28
+194.33.105.69
+194.33.105.71
+194.33.105.72
+194.33.105.134
+194.33.105.139
+194.33.105.152
+194.33.105.168
+194.33.105.169
+194.33.105.206
+194.33.105.209
+194.33.105.222
+194.33.105.232
+194.33.105.234
+194.33.106.103
+194.33.107.107
+194.33.107.108
+194.33.107.240
+194.34.162.150
+194.34.163.53
+194.34.163.54
+194.36.174.2
+194.36.174.31
+194.36.174.56
+194.36.174.57
+194.36.174.64
+194.36.174.78
+194.36.174.80
+194.36.174.108
+194.36.174.110
+194.36.174.111
+194.36.174.151
+194.36.174.152
+194.36.174.153
+194.36.174.161
+194.36.174.162
+194.36.174.167
+194.36.174.172
+194.36.174.175
+194.36.174.190
+194.36.174.200
+194.36.174.209
+194.36.174.231
+194.39.254.42
+194.39.254.43
+194.39.254.50
+194.39.254.51
+194.39.254.52
+194.39.254.53
+194.39.254.59
+194.41.48.20
+194.41.51.34
+194.48.198.15
+194.48.198.16
+194.48.198.18
+194.48.198.29
+194.48.198.37
+194.48.198.38
+194.48.198.40
+194.48.198.65
+194.48.198.70
+194.48.198.74
+194.48.198.75
+194.48.198.85
+194.48.198.92
+194.48.198.93
+194.48.198.95
+194.48.198.100
+194.48.198.105
+194.48.198.108
+194.48.198.121
+194.48.198.133
+194.48.198.145
+194.48.198.147
+194.48.198.164
+194.48.198.178
+194.48.198.193
+194.48.198.206
+194.48.198.208
+194.48.198.216
+194.48.198.226
+194.48.198.232
+194.48.198.234
+194.48.198.239
+194.48.198.244
+194.48.198.248
+194.50.169.217
+194.53.122.10
+194.53.122.11
+194.53.122.13
+194.53.122.14
+194.53.122.15
+194.53.122.16
+194.53.122.17
+194.53.122.18
+194.53.122.19
+194.53.122.20
+194.53.122.21
+194.53.122.25
+194.53.122.26
+194.53.122.27
+194.53.122.28
+194.53.122.29
+194.53.122.30
+194.53.122.31
+194.53.122.32
+194.53.122.33
+194.53.122.34
+194.53.122.35
+194.53.122.36
+194.53.122.37
+194.53.122.38
+194.53.122.39
+194.53.122.40
+194.53.122.42
+194.53.122.43
+194.53.122.44
+194.53.122.45
+194.53.122.46
+194.53.122.47
+194.53.122.48
+194.53.122.49
+194.53.122.50
+194.53.122.51
+194.53.122.52
+194.53.122.53
+194.53.122.54
+194.53.122.55
+194.53.122.56
+194.53.122.57
+194.53.122.58
+194.53.122.59
+194.53.122.60
+194.53.122.62
+194.53.122.63
+194.53.122.64
+194.53.122.65
+194.53.122.66
+194.53.122.67
+194.53.122.68
+194.53.122.69
+194.53.122.71
+194.53.122.72
+194.53.122.73
+194.53.122.74
+194.53.122.77
+194.53.122.78
+194.53.122.79
+194.53.122.80
+194.53.122.81
+194.53.122.82
+194.53.122.84
+194.53.122.85
+194.53.122.86
+194.53.122.87
+194.53.122.88
+194.53.122.89
+194.53.122.90
+194.53.122.91
+194.53.122.92
+194.53.122.93
+194.53.122.94
+194.53.122.95
+194.53.122.96
+194.53.122.97
+194.53.122.98
+194.53.122.99
+194.53.122.100
+194.53.122.102
+194.53.122.103
+194.53.122.104
+194.53.122.105
+194.53.122.106
+194.53.122.107
+194.53.122.108
+194.53.122.109
+194.53.122.110
+194.53.122.111
+194.53.122.112
+194.53.122.113
+194.53.122.114
+194.53.122.115
+194.53.122.116
+194.53.122.117
+194.53.122.118
+194.53.122.120
+194.53.122.121
+194.53.122.122
+194.53.122.124
+194.53.122.125
+194.53.122.127
+194.53.122.128
+194.53.122.129
+194.53.122.130
+194.53.122.131
+194.53.122.132
+194.53.122.133
+194.53.122.134
+194.53.122.135
+194.53.122.136
+194.53.122.137
+194.53.122.138
+194.53.122.139
+194.53.122.140
+194.53.122.142
+194.53.122.144
+194.53.122.145
+194.53.122.146
+194.53.122.147
+194.53.122.148
+194.53.122.149
+194.53.122.151
+194.53.122.152
+194.53.122.153
+194.53.122.154
+194.53.122.155
+194.53.122.156
+194.53.122.157
+194.53.122.158
+194.53.122.159
+194.53.122.160
+194.53.122.161
+194.53.122.162
+194.53.122.163
+194.53.122.164
+194.53.122.165
+194.53.122.166
+194.53.122.167
+194.53.122.168
+194.53.122.169
+194.53.122.170
+194.53.122.171
+194.53.122.172
+194.53.122.173
+194.53.122.174
+194.53.122.175
+194.53.122.176
+194.53.122.177
+194.53.122.179
+194.53.122.180
+194.53.122.181
+194.53.122.182
+194.53.122.183
+194.53.122.184
+194.53.122.185
+194.53.122.186
+194.53.122.187
+194.53.122.188
+194.53.122.189
+194.53.122.190
+194.53.122.191
+194.53.122.192
+194.53.122.193
+194.53.122.194
+194.53.122.195
+194.53.122.196
+194.53.122.197
+194.53.122.198
+194.53.122.199
+194.53.122.200
+194.53.122.201
+194.53.122.202
+194.53.122.203
+194.53.122.204
+194.53.122.205
+194.53.122.206
+194.53.122.207
+194.53.122.208
+194.53.122.209
+194.53.122.210
+194.53.122.211
+194.53.122.212
+194.53.122.213
+194.53.122.214
+194.53.122.215
+194.53.122.216
+194.53.122.217
+194.53.122.218
+194.53.122.219
+194.53.122.220
+194.53.122.221
+194.53.122.222
+194.53.122.223
+194.53.122.225
+194.53.122.226
+194.53.122.227
+194.53.122.228
+194.53.122.229
+194.53.122.230
+194.53.122.231
+194.53.122.232
+194.53.122.233
+194.53.122.234
+194.53.122.235
+194.53.122.236
+194.53.122.237
+194.53.122.238
+194.53.122.239
+194.53.122.240
+194.53.122.241
+194.53.122.242
+194.53.122.243
+194.53.122.244
+194.53.122.245
+194.53.122.246
+194.53.122.247
+194.53.122.249
+194.53.122.250
+194.56.148.22
+194.56.148.76
+194.56.148.179
+194.56.148.222
+194.59.170.5
+194.59.170.6
+194.59.170.15
+194.59.170.19
+194.59.170.21
+194.59.170.22
+194.59.170.23
+194.59.170.24
+194.59.170.25
+194.59.170.26
+194.59.170.27
+194.59.170.28
+194.59.170.29
+194.59.170.30
+194.59.170.49
+194.59.170.60
+194.59.170.61
+194.59.170.75
+194.59.170.82
+194.59.170.83
+194.59.170.90
+194.59.170.100
+194.59.170.115
+194.59.170.117
+194.59.170.119
+194.59.170.120
+194.59.170.132
+194.59.170.138
+194.59.170.144
+194.59.170.146
+194.59.170.154
+194.59.170.166
+194.59.170.174
+194.59.170.192
+194.59.170.207
+194.59.170.228
+194.59.170.232
+194.59.170.243
+194.59.171.11
+194.59.171.53
+194.59.171.153
+194.59.171.154
+194.59.171.185
+194.59.214.2
+194.59.214.3
+194.59.214.4
+194.59.214.7
+194.59.214.10
+194.59.214.30
+194.59.214.31
+194.59.214.35
+194.59.214.36
+194.59.214.37
+194.59.214.38
+194.59.214.55
+194.59.214.71
+194.59.214.74
+194.59.214.75
+194.59.214.76
+194.59.214.85
+194.59.214.91
+194.59.214.92
+194.59.214.93
+194.59.214.99
+194.59.214.100
+194.59.214.102
+194.59.214.103
+194.59.214.104
+194.59.214.105
+194.59.214.106
+194.59.214.108
+194.59.214.110
+194.59.214.116
+194.59.214.120
+194.59.214.121
+194.59.214.123
+194.59.214.124
+194.59.214.125
+194.59.214.129
+194.59.214.148
+194.59.214.160
+194.59.214.161
+194.59.214.162
+194.59.214.163
+194.59.214.164
+194.59.214.165
+194.59.214.166
+194.59.214.174
+194.59.214.176
+194.59.214.195
+194.59.214.200
+194.59.214.202
+194.59.214.203
+194.59.214.205
+194.59.214.209
+194.59.214.210
+194.59.215.11
+194.59.215.36
+194.59.215.37
+194.59.215.49
+194.59.215.51
+194.59.215.242
+194.59.215.246
+194.60.209.91
+194.60.210.66
+194.60.210.67
+194.60.230.25
+194.60.230.28
+194.60.230.50
+194.60.230.53
+194.60.230.55
+194.60.230.58
+194.60.230.75
+194.60.230.78
+194.60.230.84
+194.60.230.88
+194.60.230.92
+194.60.230.148
+194.60.230.161
+194.60.230.174
+194.60.230.194
+194.60.230.195
+194.60.230.203
+194.60.230.208
+194.60.231.12
+194.60.231.30
+194.60.231.34
+194.60.231.47
+194.60.231.77
+194.60.231.84
+194.60.231.112
+194.60.231.122
+194.60.231.149
+194.60.231.156
+194.60.231.157
+194.60.231.182
+194.60.231.196
+194.60.231.234
+194.62.17.18
+194.62.17.22
+194.62.17.26
+194.62.17.43
+194.62.17.50
+194.62.17.59
+194.62.17.60
+194.62.17.70
+194.62.17.146
+194.62.17.155
+194.62.17.174
+194.62.17.178
+194.62.17.190
+194.62.17.203
+194.62.17.206
+194.62.17.212
+194.62.17.234
+194.62.17.254
+194.62.43.5
+194.62.43.6
+194.62.43.14
+194.62.43.15
+194.62.43.44
+194.62.43.45
+194.62.43.55
+194.62.43.58
+194.62.43.66
+194.62.43.67
+194.62.43.80
+194.62.43.83
+194.62.43.91
+194.62.43.92
+194.62.43.94
+194.62.43.99
+194.62.43.100
+194.62.43.101
+194.62.43.102
+194.62.43.104
+194.62.43.108
+194.62.43.123
+194.62.43.126
+194.62.43.129
+194.62.43.139
+194.62.43.140
+194.62.43.141
+194.62.43.146
+194.62.43.155
+194.62.43.175
+194.62.43.180
+194.62.43.183
+194.62.43.184
+194.62.43.194
+194.62.43.207
+194.62.43.208
+194.62.43.216
+194.62.43.218
+194.62.43.227
+194.62.43.233
+194.62.43.236
+194.62.43.237
+194.62.43.238
+194.62.43.240
+194.62.43.241
+194.143.140.9
+194.143.141.9
+194.146.151.18
+194.146.151.19
+194.146.151.20
+194.146.151.22
+194.146.239.28
+194.146.239.32
+194.146.239.35
+194.146.239.39
+194.146.239.40
+194.146.239.41
+194.146.239.44
+194.146.239.57
+194.146.239.58
+194.146.239.60
+194.146.239.65
+194.146.239.68
+194.146.239.70
+194.146.239.77
+194.146.239.78
+194.146.239.79
+194.146.239.111
+194.146.239.124
+194.146.239.154
+194.146.239.155
+194.146.239.165
+194.146.239.171
+194.146.239.173
+194.146.239.178
+194.146.239.194
+194.146.239.197
+194.146.239.200
+194.147.142.10
+194.147.142.29
+194.147.142.35
+194.147.142.39
+194.147.142.41
+194.147.142.44
+194.147.142.57
+194.147.142.64
+194.147.142.67
+194.147.142.71
+194.147.142.72
+194.147.142.78
+194.147.142.79
+194.147.142.82
+194.147.142.94
+194.147.142.100
+194.147.142.104
+194.147.142.122
+194.147.142.123
+194.147.142.125
+194.147.142.131
+194.147.142.136
+194.147.142.153
+194.147.142.174
+194.147.142.180
+194.147.142.186
+194.147.142.192
+194.147.142.195
+194.147.142.200
+194.147.142.213
+194.147.142.218
+194.147.142.233
+194.147.142.239
+194.147.142.242
+194.147.142.243
+194.147.142.250
+194.147.164.49
+194.147.222.37
+194.147.222.53
+194.147.222.68
+194.147.222.76
+194.147.222.82
+194.147.222.84
+194.147.222.85
+194.147.222.86
+194.147.222.87
+194.147.222.94
+194.147.222.96
+194.147.222.131
+194.147.222.137
+194.147.222.143
+194.147.222.144
+194.147.222.146
+194.147.222.150
+194.147.222.153
+194.147.222.162
+194.147.222.176
+194.147.222.228
+194.147.222.229
+194.147.222.230
+194.150.68.28
+194.150.68.29
+194.150.68.44
+194.150.68.45
+194.150.68.51
+194.150.69.119
+194.150.69.164
+194.150.70.11
+194.150.70.12
+194.150.71.198
+194.150.71.230
+194.180.11.12
+194.180.11.14
+194.180.11.17
+194.180.11.26
+194.180.11.28
+194.180.11.37
+194.180.11.43
+194.180.11.56
+194.180.11.64
+194.180.11.79
+194.180.11.85
+194.180.11.94
+194.180.11.110
+194.180.11.117
+194.180.11.118
+194.180.11.128
+194.180.11.134
+194.180.11.142
+194.180.11.148
+194.180.11.153
+194.180.11.177
+194.180.11.185
+194.180.11.204
+194.180.11.206
+194.180.11.212
+194.180.11.213
+194.180.11.216
+194.180.11.217
+194.180.11.219
+194.180.11.225
+194.180.11.226
+194.180.11.229
+194.180.11.233
+194.180.11.236
+194.180.11.243
+194.180.11.254
+194.225.16.3
+194.225.24.20
+194.225.25.15
+194.225.25.16
+194.225.40.49
+194.225.40.114
+194.225.50.6
+194.225.62.66
+194.225.62.80
+194.225.62.98
+194.225.62.107
+194.225.73.141
+194.225.73.151
+194.225.90.4
+194.225.90.5
+194.225.92.15
+194.225.92.17
+194.225.100.42
+194.225.100.43
+194.225.106.21
+194.225.106.22
+194.225.115.9
+194.225.115.10
+194.225.117.10
+194.225.131.64
+194.225.133.40
+194.225.136.3
+194.225.136.4
+194.225.144.2
+194.225.144.3
+194.225.152.10
+194.225.152.12
+194.225.166.7
+194.225.166.8
+194.225.183.61
+194.225.183.62
+194.225.228.4
+194.225.228.5
+195.24.233.75
+195.28.11.3
+195.28.11.27
+195.28.11.35
+195.28.11.37
+195.28.11.47
+195.28.11.58
+195.28.11.60
+195.28.11.63
+195.28.11.64
+195.28.11.67
+195.28.11.68
+195.28.11.70
+195.28.11.99
+195.28.11.104
+195.28.11.109
+195.28.11.156
+195.28.11.179
+195.28.11.220
+195.28.11.236
+195.28.11.249
+195.28.11.250
+195.28.11.251
+195.28.11.253
+195.28.169.201
+195.28.169.248
+195.28.169.253
+195.62.4.20
+195.62.4.21
+195.62.4.22
+195.62.4.24
+195.62.4.25
+195.62.4.26
+195.88.189.70
+195.88.189.71
+195.88.189.74
+195.88.189.76
+195.88.189.77
+195.88.189.79
+195.88.189.81
+195.88.189.84
+195.88.189.86
+195.88.189.91
+195.88.189.98
+195.88.189.101
+195.88.189.110
+195.88.189.111
+195.88.189.112
+195.88.208.7
+195.88.208.9
+195.88.208.15
+195.88.208.17
+195.88.208.28
+195.88.208.49
+195.88.208.50
+195.88.208.53
+195.88.208.67
+195.88.208.82
+195.88.208.107
+195.88.208.111
+195.88.208.112
+195.88.208.115
+195.88.208.123
+195.88.208.125
+195.88.208.130
+195.88.208.134
+195.88.208.139
+195.88.208.141
+195.88.208.143
+195.88.208.147
+195.88.208.149
+195.88.208.157
+195.88.208.164
+195.88.208.167
+195.88.208.180
+195.88.208.181
+195.88.208.198
+195.88.208.204
+195.88.208.207
+195.88.208.210
+195.88.208.216
+195.88.208.236
+195.88.208.237
+195.88.208.241
+195.96.128.24
+195.96.128.130
+195.96.128.144
+195.96.128.148
+195.110.38.129
+195.110.38.141
+195.110.38.156
+195.110.38.190
+195.110.38.203
+195.110.38.205
+195.110.38.214
+195.110.38.217
+195.110.38.223
+195.110.38.230
+195.110.38.232
+195.110.38.234
+195.110.38.244
+195.110.38.245
+195.110.38.246
+195.110.38.248
+195.110.39.192
+195.110.39.194
+195.110.39.195
+195.110.39.198
+195.110.39.199
+195.110.39.220
+195.110.39.221
+195.110.39.222
+195.110.39.223
+195.114.4.16
+195.114.4.21
+195.114.4.23
+195.114.4.25
+195.114.4.117
+195.114.4.180
+195.114.4.182
+195.114.5.243
+195.114.8.10
+195.146.59.62
+195.146.59.249
+195.146.59.253
+195.146.60.2
+195.177.255.4
+195.177.255.15
+195.177.255.30
+195.177.255.47
+195.177.255.54
+195.177.255.60
+195.177.255.64
+195.177.255.74
+195.177.255.89
+195.177.255.90
+195.177.255.95
+195.177.255.103
+195.177.255.120
+195.177.255.125
+195.177.255.126
+195.177.255.132
+195.177.255.136
+195.177.255.141
+195.177.255.142
+195.177.255.164
+195.177.255.169
+195.177.255.170
+195.177.255.180
+195.177.255.184
+195.177.255.187
+195.177.255.201
+195.177.255.205
+195.177.255.208
+195.177.255.217
+195.177.255.226
+195.177.255.253
+195.181.12.184
+195.181.41.225
+195.181.41.229
+195.181.81.185
+195.181.84.14
+195.181.91.99
+195.191.74.141
+195.200.77.125
+195.200.77.134
+195.200.77.135
+195.200.77.136
+195.200.77.194
+195.200.77.227
+195.200.77.230
+195.200.77.242
+195.200.77.243
+195.200.77.244
+195.200.77.245
+195.200.77.251
+195.211.44.16
+195.211.44.17
+195.211.44.21
+195.211.44.24
+195.211.44.41
+195.211.44.69
+195.211.44.76
+195.211.44.96
+195.211.44.104
+195.211.44.107
+195.211.44.120
+195.211.44.136
+195.211.44.138
+195.211.44.160
+195.211.44.161
+195.211.44.162
+195.211.44.173
+195.211.44.211
+195.211.44.216
+195.211.44.218
+195.211.44.223
+195.211.44.227
+195.211.44.232
+195.211.44.235
+195.211.45.169
+195.211.45.184
+195.211.45.190
+195.211.45.230
+195.211.45.239
+195.211.45.240
+195.211.45.255
+195.211.46.64
+195.211.46.65
+195.211.46.111
+195.211.46.117
+195.211.46.211
+195.211.46.212
+195.211.46.242
+195.211.47.24
+195.211.47.27
+195.211.47.65
+195.211.47.199
+195.211.47.213
+195.211.47.220
+195.214.235.3
+195.214.235.4
+195.214.235.5
+195.214.235.11
+195.214.235.12
+195.214.235.13
+195.214.235.14
+195.214.235.19
+195.214.235.20
+195.214.235.21
+195.214.235.22
+195.214.235.46
+195.214.235.56
+195.214.235.57
+195.214.235.62
+195.214.235.92
+195.214.235.99
+195.214.235.100
+195.214.235.101
+195.214.235.102
+195.214.235.114
+195.214.235.116
+195.214.235.117
+195.214.235.118
+195.214.235.119
+195.214.235.121
+195.214.235.122
+195.214.235.123
+195.214.235.124
+195.214.235.141
+195.214.235.142
+195.214.235.147
+195.214.235.148
+195.214.235.163
+195.214.235.164
+195.214.235.171
+195.214.235.172
+195.214.235.179
+195.214.235.180
+195.214.235.181
+195.214.235.182
+195.214.235.206
+195.214.235.216
+195.226.223.3
+195.226.223.6
+195.226.223.11
+195.226.223.13
+195.226.223.14
+195.226.223.44
+195.226.223.70
+195.226.223.100
+195.226.223.131
+195.226.223.134
+195.226.223.135
+195.226.223.140
+195.226.223.147
+195.226.223.155
+195.226.223.157
+195.226.223.211
+195.226.223.213
+195.230.107.2
+195.230.107.49
+195.230.107.130
+195.234.191.130
+195.234.191.133
+195.234.191.137
+195.234.191.138
+195.234.191.141
+195.234.191.144
+195.234.191.197
+195.234.191.200
+195.238.231.8
+195.238.231.55
+195.238.231.56
+195.238.231.132
+195.238.231.133
+195.238.231.134
+195.238.231.146
+195.238.231.187
+195.238.231.234
+195.238.231.245
+195.238.240.2
+195.238.240.5
+195.238.240.19
+195.238.240.22
+195.238.240.91
+195.238.240.215
+195.245.70.210
+212.16.64.74
+212.16.68.4
+212.16.70.4
+212.16.70.8
+212.16.70.19
+212.16.76.19
+212.16.76.72
+212.16.76.117
+212.16.76.119
+212.16.76.120
+212.16.76.250
+212.16.82.16
+212.16.84.147
+212.16.84.148
+212.16.86.4
+212.16.86.15
+212.16.88.21
+212.16.88.22
+212.16.89.20
+212.16.89.25
+212.16.95.143
+212.18.108.115
+212.18.108.131
+212.18.108.132
+212.18.108.173
+212.18.108.174
+212.18.108.188
+212.18.108.189
+212.18.108.190
+212.18.108.203
+212.18.108.205
+212.18.108.211
+212.18.108.212
+212.18.108.214
+212.18.108.228
+212.18.108.237
+212.23.201.8
+212.23.201.10
+212.23.201.13
+212.23.201.15
+212.23.201.27
+212.23.201.29
+212.23.201.30
+212.23.201.36
+212.23.201.41
+212.23.201.44
+212.23.201.50
+212.23.201.53
+212.23.201.57
+212.23.201.58
+212.23.201.70
+212.23.201.72
+212.23.201.73
+212.23.201.74
+212.23.201.75
+212.23.201.76
+212.23.201.86
+212.23.201.91
+212.23.201.92
+212.23.201.93
+212.23.201.95
+212.23.201.98
+212.23.201.101
+212.23.201.103
+212.23.201.104
+212.23.201.107
+212.23.201.114
+212.23.201.116
+212.23.201.118
+212.23.201.122
+212.23.201.123
+212.23.201.133
+212.23.201.135
+212.23.201.143
+212.23.201.147
+212.23.201.151
+212.23.201.154
+212.23.201.158
+212.23.201.159
+212.23.201.162
+212.23.201.165
+212.23.201.168
+212.23.201.170
+212.23.201.172
+212.23.201.174
+212.23.201.176
+212.23.201.177
+212.23.201.182
+212.23.201.186
+212.23.201.192
+212.23.201.196
+212.23.201.203
+212.23.201.205
+212.23.201.208
+212.23.201.216
+212.23.201.218
+212.23.201.220
+212.23.201.225
+212.23.201.232
+212.23.201.248
+212.23.201.251
+212.23.216.25
+212.23.216.55
+212.23.216.56
+212.23.216.60
+212.23.216.100
+212.23.216.117
+212.23.216.121
+212.23.216.125
+212.23.216.150
+212.23.216.152
+212.33.194.26
+212.33.194.27
+212.33.194.28
+212.33.194.29
+212.33.194.30
+212.33.194.58
+212.33.194.60
+212.33.194.108
+212.33.194.148
+212.33.194.149
+212.33.195.66
+212.33.195.80
+212.33.195.85
+212.33.195.86
+212.33.195.88
+212.33.195.91
+212.33.195.92
+212.33.195.93
+212.33.195.94
+212.33.195.165
+212.33.195.166
+212.33.195.168
+212.33.195.252
+212.33.197.69
+212.33.197.71
+212.33.197.82
+212.33.197.85
+212.33.197.92
+212.33.197.94
+212.33.197.100
+212.33.197.124
+212.33.197.131
+212.33.198.15
+212.33.198.57
+212.33.198.60
+212.33.198.90
+212.33.198.227
+212.33.201.26
+212.33.201.27
+212.33.201.55
+212.33.201.133
+212.33.201.143
+212.33.201.167
+212.33.201.215
+212.33.201.220
+212.33.202.21
+212.33.202.24
+212.33.202.76
+212.33.202.97
+212.33.202.107
+212.33.202.113
+212.33.202.122
+212.33.202.153
+212.33.202.167
+212.33.202.192
+212.33.202.213
+212.33.202.214
+212.33.202.215
+212.33.202.216
+212.33.202.227
+212.33.203.10
+212.33.203.92
+212.33.203.186
+212.33.203.187
+212.33.203.188
+212.33.203.189
+212.33.203.190
+212.33.203.226
+212.33.204.93
+212.33.205.21
+212.33.205.55
+212.33.205.81
+212.33.205.82
+212.33.205.95
+212.33.205.96
+212.33.205.99
+212.33.205.110
+212.33.205.186
+212.33.205.223
+212.33.205.254
+212.33.206.11
+212.33.206.20
+212.33.206.46
+212.33.206.55
+212.33.206.93
+212.33.206.138
+212.33.206.140
+212.33.206.156
+212.33.206.168
+212.33.206.199
+212.33.206.205
+212.33.206.239
+212.33.217.224
+212.33.222.179
+212.80.5.205
+212.80.8.70
+212.80.8.84
+212.80.8.103
+212.80.8.105
+212.80.8.115
+212.80.8.212
+212.80.9.228
+212.80.9.229
+212.80.9.230
+212.80.9.231
+212.80.9.235
+212.80.10.252
+212.80.10.253
+212.80.16.72
+212.80.18.83
+212.80.18.182
+212.80.18.213
+212.80.19.2
+212.80.19.12
+212.80.19.244
+212.80.20.92
+212.80.20.93
+212.80.20.101
+212.80.20.132
+212.80.20.134
+212.80.20.165
+212.80.21.10
+212.80.21.68
+212.80.21.157
+212.80.21.179
+212.80.21.184
+212.80.22.18
+212.80.22.22
+212.80.25.138
+212.80.25.217
+212.80.27.250
+212.80.30.189
+212.80.30.190
+212.86.64.99
+212.86.64.100
+212.86.64.193
+212.86.66.11
+212.86.66.50
+212.86.66.90
+212.86.66.96
+212.86.67.138
+212.86.67.147
+212.86.67.149
+212.86.74.64
+212.86.74.148
+212.86.76.69
+212.86.77.54
+212.86.79.180
+212.86.79.184
+212.86.79.188
+212.86.79.189
+212.120.192.7
+212.120.192.10
+212.120.192.13
+212.120.192.21
+212.120.198.165
+212.120.200.58
+212.120.201.176
+212.120.205.150
+212.120.208.80
+212.120.211.206
+212.120.214.42
+212.120.214.61
+212.120.214.230
+212.120.223.248
+213.108.240.52
+213.108.240.53
+213.108.240.54
+213.108.240.67
+213.108.240.82
+213.108.240.86
+213.108.240.91
+213.108.240.131
+213.108.240.132
+213.108.240.134
+213.108.240.136
+213.108.240.141
+213.108.240.143
+213.108.240.144
+213.108.240.145
+213.108.240.151
+213.108.240.152
+213.108.240.155
+213.108.240.157
+213.108.240.158
+213.108.240.162
+213.108.240.167
+213.108.240.169
+213.108.240.170
+213.108.240.173
+213.108.240.180
+213.108.240.194
+213.108.240.204
+213.108.240.205
+213.108.241.73
+213.108.241.106
+213.108.241.110
+213.108.241.132
+213.108.241.133
+213.108.241.135
+213.108.241.140
+213.108.241.145
+213.108.241.146
+213.108.241.155
+213.108.241.196
+213.108.241.199
+213.108.241.200
+213.108.241.216
+213.108.241.235
+213.108.241.237
+213.108.241.243
+213.108.242.211
+213.108.242.215
+213.108.242.216
+213.108.242.217
+213.108.242.219
+213.108.242.250
+213.109.199.133
+213.176.1.165
+213.176.1.194
+213.176.5.20
+213.176.5.21
+213.176.6.146
+213.176.6.153
+213.176.6.198
+213.176.7.126
+213.176.7.151
+213.176.28.37
+213.176.28.45
+213.176.28.91
+213.176.28.143
+213.176.28.149
+213.176.28.151
+213.176.28.170
+213.176.28.199
+213.176.28.231
+213.176.28.245
+213.176.28.247
+213.176.29.6
+213.176.29.7
+213.176.29.8
+213.176.29.9
+213.176.29.26
+213.176.29.31
+213.176.29.32
+213.176.29.33
+213.176.29.34
+213.176.29.35
+213.176.29.58
+213.176.29.63
+213.176.29.66
+213.176.29.75
+213.176.29.78
+213.176.29.85
+213.176.29.87
+213.176.29.88
+213.176.29.89
+213.176.29.107
+213.176.29.108
+213.176.29.115
+213.176.29.121
+213.176.29.124
+213.176.29.125
+213.176.29.126
+213.176.29.128
+213.176.29.132
+213.176.29.133
+213.176.29.141
+213.176.29.142
+213.176.29.145
+213.176.29.151
+213.176.29.158
+213.176.29.159
+213.176.29.161
+213.176.29.162
+213.176.29.163
+213.176.29.189
+213.176.29.192
+213.176.29.201
+213.176.29.207
+213.176.29.208
+213.176.29.209
+213.176.29.212
+213.176.29.214
+213.176.29.219
+213.176.29.229
+213.176.29.236
+213.176.29.243
+213.176.29.244
+213.176.29.246
+213.176.31.7
+213.176.31.66
+213.176.31.74
+213.176.31.98
+213.176.31.99
+213.176.31.110
+213.176.31.122
+213.176.31.154
+213.176.31.214
+213.176.120.9
+213.176.120.34
+213.176.120.40
+213.176.120.114
+213.176.120.130
+213.176.121.78
+213.176.123.5
+213.195.22.3
+213.195.22.4
+213.195.22.106
+213.195.22.238
+213.195.56.113
+213.195.58.167
+213.207.192.19
+213.207.198.66
+213.207.203.90
+213.207.203.211
+213.207.204.10
+213.207.204.66
+213.207.209.21
+213.207.250.50
+213.207.250.59
+213.207.250.90
+213.232.124.4
+213.232.124.10
+213.232.124.34
+213.232.124.78
+213.232.124.154
+213.232.124.222
+213.232.125.115
+213.232.125.186
+213.232.126.49
+213.232.126.180
+213.232.126.235
+213.232.126.236
+213.232.126.237
+213.233.161.81
+213.233.161.190
+213.233.173.10
+213.233.176.155
+213.233.176.156
+213.233.177.172
+213.233.177.219
+213.233.177.221
+213.233.178.82
+213.233.178.102
+213.233.178.133
+213.233.178.226
+213.233.182.147
+213.233.182.236
+213.233.184.221
+217.11.18.100
+217.11.18.190
+217.11.19.10
+217.11.20.217
+217.11.20.227
+217.11.21.11
+217.11.23.6
+217.11.24.166
+217.11.27.116
+217.11.27.117
+217.11.28.51
+217.11.28.53
+217.11.29.178
+217.11.29.184
+217.11.29.186
+217.11.29.187
+217.11.29.188
+217.11.29.190
+217.11.29.191
+217.20.252.9
+217.20.252.12
+217.20.252.20
+217.20.252.24
+217.20.252.42
+217.20.252.68
+217.20.252.249
+217.24.147.254
+217.26.222.2
+217.26.222.234
+217.60.15.187
+217.60.236.60
+217.60.243.221
+217.60.243.244
+217.66.200.240
+217.66.215.114
+217.114.40.18
+217.114.40.19
+217.114.40.32
+217.114.40.34
+217.114.40.43
+217.114.40.49
+217.114.40.54
+217.114.40.75
+217.114.40.104
+217.114.40.107
+217.114.40.112
+217.114.40.203
+217.114.40.206
+217.114.40.215
+217.114.40.216
+217.114.40.246
+217.114.46.156
+217.114.46.157
+217.144.104.6
+217.144.104.7
+217.144.104.9
+217.144.104.11
+217.144.104.13
+217.144.104.14
+217.144.104.15
+217.144.104.16
+217.144.104.18
+217.144.104.19
+217.144.104.21
+217.144.104.22
+217.144.104.23
+217.144.104.25
+217.144.104.26
+217.144.104.27
+217.144.104.35
+217.144.104.37
+217.144.104.42
+217.144.104.44
+217.144.104.47
+217.144.104.49
+217.144.104.50
+217.144.104.54
+217.144.104.56
+217.144.104.58
+217.144.104.64
+217.144.104.65
+217.144.104.68
+217.144.104.69
+217.144.104.70
+217.144.104.74
+217.144.104.78
+217.144.104.80
+217.144.104.82
+217.144.104.83
+217.144.104.84
+217.144.104.87
+217.144.104.88
+217.144.104.92
+217.144.104.95
+217.144.104.97
+217.144.104.100
+217.144.104.101
+217.144.104.102
+217.144.104.106
+217.144.104.111
+217.144.104.112
+217.144.104.113
+217.144.104.119
+217.144.104.120
+217.144.104.122
+217.144.104.123
+217.144.104.127
+217.144.104.128
+217.144.104.129
+217.144.104.130
+217.144.104.131
+217.144.104.133
+217.144.104.134
+217.144.104.136
+217.144.104.139
+217.144.104.141
+217.144.104.142
+217.144.104.146
+217.144.104.155
+217.144.104.159
+217.144.104.160
+217.144.104.161
+217.144.104.162
+217.144.104.163
+217.144.104.166
+217.144.104.168
+217.144.104.170
+217.144.104.173
+217.144.104.174
+217.144.104.177
+217.144.104.178
+217.144.104.179
+217.144.104.180
+217.144.104.182
+217.144.104.184
+217.144.104.185
+217.144.104.189
+217.144.104.190
+217.144.104.191
+217.144.104.193
+217.144.104.197
+217.144.104.203
+217.144.104.205
+217.144.104.210
+217.144.104.212
+217.144.104.214
+217.144.104.217
+217.144.104.218
+217.144.104.222
+217.144.104.225
+217.144.104.226
+217.144.104.227
+217.144.104.234
+217.144.104.235
+217.144.104.242
+217.144.104.243
+217.144.104.249
+217.144.104.250
+217.144.104.254
+217.144.105.39
+217.144.105.42
+217.144.105.49
+217.144.105.52
+217.144.105.57
+217.144.105.58
+217.144.105.61
+217.144.105.63
+217.144.105.73
+217.144.105.77
+217.144.105.79
+217.144.105.80
+217.144.105.84
+217.144.105.90
+217.144.105.94
+217.144.105.101
+217.144.105.156
+217.144.105.163
+217.144.105.168
+217.144.105.169
+217.144.105.175
+217.144.105.176
+217.144.105.181
+217.144.105.195
+217.144.105.197
+217.144.105.198
+217.144.105.200
+217.144.105.205
+217.144.105.206
+217.144.105.207
+217.144.105.209
+217.144.105.210
+217.144.105.212
+217.144.105.217
+217.144.105.218
+217.144.105.221
+217.144.105.226
+217.144.105.230
+217.144.105.233
+217.144.105.252
+217.144.105.254
+217.144.106.7
+217.144.106.11
+217.144.106.16
+217.144.106.17
+217.144.106.18
+217.144.106.20
+217.144.106.21
+217.144.106.22
+217.144.106.26
+217.144.106.30
+217.144.106.31
+217.144.106.32
+217.144.106.36
+217.144.106.39
+217.144.106.40
+217.144.106.44
+217.144.106.48
+217.144.106.50
+217.144.106.54
+217.144.106.55
+217.144.106.59
+217.144.106.61
+217.144.106.62
+217.144.106.68
+217.144.106.93
+217.144.106.94
+217.144.106.100
+217.144.106.104
+217.144.106.110
+217.144.106.111
+217.144.106.113
+217.144.106.115
+217.144.106.116
+217.144.106.117
+217.144.106.118
+217.144.106.125
+217.144.106.126
+217.144.106.132
+217.144.106.138
+217.144.106.141
+217.144.106.143
+217.144.106.153
+217.144.106.155
+217.144.106.157
+217.144.106.201
+217.144.106.202
+217.144.106.203
+217.144.106.204
+217.144.106.205
+217.144.106.208
+217.144.106.212
+217.144.106.218
+217.144.106.222
+217.144.106.227
+217.144.106.236
+217.144.106.242
+217.144.106.252
+217.144.107.2
+217.144.107.4
+217.144.107.5
+217.144.107.6
+217.144.107.15
+217.144.107.20
+217.144.107.22
+217.144.107.52
+217.144.107.55
+217.144.107.61
+217.144.107.70
+217.144.107.83
+217.144.107.85
+217.144.107.94
+217.144.107.96
+217.144.107.98
+217.144.107.104
+217.144.107.111
+217.144.107.113
+217.144.107.119
+217.144.107.126
+217.144.107.127
+217.144.107.130
+217.144.107.132
+217.144.107.139
+217.144.107.147
+217.144.107.148
+217.144.107.149
+217.144.107.159
+217.144.107.160
+217.144.107.161
+217.144.107.162
+217.144.107.163
+217.144.107.166
+217.144.107.169
+217.144.107.171
+217.144.107.174
+217.144.107.176
+217.144.107.181
+217.144.107.182
+217.144.107.183
+217.144.107.184
+217.144.107.186
+217.144.107.194
+217.144.107.195
+217.144.107.197
+217.144.107.200
+217.144.107.203
+217.144.107.205
+217.144.107.208
+217.144.107.226
+217.144.107.228
+217.144.107.230
+217.144.107.235
+217.144.107.239
+217.144.107.241
+217.144.107.242
+217.144.107.246
+217.144.107.247
+217.146.209.50
+217.170.251.26
+217.170.252.10
+217.170.252.47
+217.170.252.155
+217.170.253.10
+217.172.98.71
+217.172.98.72
+217.172.98.74
+217.172.98.75
+217.172.98.77
+217.172.98.78
+217.172.98.79
+217.172.98.87
+217.172.98.90
+217.172.98.91
+217.172.98.92
+217.172.98.93
+217.172.98.95
+217.172.98.96
+217.172.98.97
+217.172.98.98
+217.172.98.102
+217.172.98.108
+217.172.98.109
+217.172.98.111
+217.172.98.116
+217.172.98.124
+217.172.98.132
+217.172.98.138
+217.172.98.147
+217.172.98.148
+217.172.98.149
+217.172.98.158
+217.172.98.160
+217.172.98.161
+217.172.98.162
+217.172.98.163
+217.172.98.169
+217.172.98.172
+217.172.98.175
+217.172.98.228
+217.172.98.231
+217.172.98.233
+217.172.98.234
+217.172.98.237
+217.172.98.241
+217.172.98.251
+217.172.126.251
+217.198.190.5
+217.198.190.56
+217.198.190.66
+217.198.190.100
+217.198.190.125
+217.198.190.132
+217.198.190.145
+217.198.190.146
+217.198.190.147
+217.198.190.150
+217.198.190.151
+217.198.190.153
+217.198.190.156
+217.198.190.162
+217.198.190.178
+217.198.190.209
+217.198.190.212
+217.198.190.214
+217.198.190.215
+217.198.190.225
+217.218.2.100
+217.218.6.5
+217.218.7.4
+217.218.7.5
+217.218.9.140
+217.218.9.141
+217.218.11.11
+217.218.11.12
+217.218.12.58
+217.218.13.168
+217.218.21.104
+217.218.21.122
+217.218.21.124
+217.218.26.220
+217.218.32.74
+217.218.40.5
+217.218.40.6
+217.218.46.11
+217.218.53.153
+217.218.54.16
+217.218.56.21
+217.218.56.210
+217.218.56.249
+217.218.60.101
+217.218.62.65
+217.218.62.66
+217.218.70.10
+217.218.71.153
+217.218.75.202
+217.218.82.85
+217.218.82.140
+217.218.85.234
+217.218.86.50
+217.218.98.56
+217.218.98.157
+217.218.102.174
+217.218.106.140
+217.218.106.141
+217.218.113.50
+217.218.114.8
+217.218.124.10
+217.218.126.162
+217.218.127.126
+217.218.127.127
+217.218.155.154
+217.218.155.155
+217.218.168.3
+217.218.171.210
+217.218.179.31
+217.218.179.39
+217.218.200.218
+217.218.204.123
+217.218.204.124
+217.218.204.125
+217.218.209.221
+217.218.212.140
+217.218.214.4
+217.218.214.16
+217.218.215.25
+217.218.215.78
+217.218.215.140
+217.218.227.241
+217.218.227.242
+217.218.227.243
+217.218.227.244
+217.218.227.247
+217.218.227.248
+217.218.227.249
+217.218.227.250
+217.218.227.251
+217.218.227.252
+217.218.227.253
+217.218.227.254
+217.218.230.194
+217.218.234.252
+217.218.242.66
+217.218.242.67
+217.218.251.178
+217.219.29.73
+217.219.29.107
+217.219.31.147
+217.219.33.33
+217.219.33.34
+217.219.33.35
+217.219.33.69
+217.219.34.30
+217.219.39.116
+217.219.42.18
+217.219.42.134
+217.219.66.2
+217.219.66.3
+217.219.66.8
+217.219.67.130
+217.219.68.45
+217.219.70.92
+217.219.70.197
+217.219.78.138
+217.219.78.144
+217.219.78.152
+217.219.78.153
+217.219.78.154
+217.219.78.156
+217.219.78.200
+217.219.79.82
+217.219.85.3
+217.219.85.4
+217.219.85.5
+217.219.87.100
+217.219.91.132
+217.219.91.135
+217.219.93.2
+217.219.120.82
+217.219.121.35
+217.219.121.36
+217.219.124.203
+217.219.129.246
+217.219.135.200
+217.219.136.95
+217.219.137.210
+217.219.138.140
+217.219.138.205
+217.219.139.219
+217.219.147.197
+217.219.148.251
+217.219.157.69
+217.219.157.78
+217.219.157.82
+217.219.157.112
+217.219.157.115
+217.219.157.122
+217.219.157.123
+217.219.157.124
+217.219.157.125
+217.219.157.126
+217.219.158.99
+217.219.162.163
+217.219.162.165
+217.219.165.2
+217.219.165.3
+217.219.168.164
+217.219.169.170
+217.219.173.3
+217.219.182.42
+217.219.187.3
+217.219.192.197
+217.219.199.52
+217.219.202.3
+217.219.204.10
+217.219.217.179
+217.219.223.3
+217.219.223.4
+217.219.223.195
+217.219.226.98
+217.219.226.103
+217.219.227.30
+217.219.244.3
+217.219.244.33
+217.219.251.131
+217.219.254.5
+193.134.100.123
+2.179.113.235
+2.179.114.71
+2.187.34.221
+2.179.162.163
+2.182.52.30
+2.179.162.72
+2.190.249.146
+2.176.245.137
+2.176.254.42
+2.177.48.37
+2.177.52.221
+2.177.95.39
+2.177.104.14
+2.177.105.80
+2.177.150.72
+2.177.168.52
+2.178.31.22
+2.182.152.219
+2.182.154.12
+2.190.33.197
+2.190.45.194
+2.190.87.30
+2.190.90.36
+2.190.227.52
+2.190.240.232
+2.191.7.159
+2.191.74.29
+2.191.78.44
+2.191.83.211
+2.191.181.170
+2.177.164.134
+2.180.26.106
+2.190.155.142
+2.176.238.212
+2.177.45.68
+2.177.54.23
+2.177.114.60
+2.178.137.218
+2.190.158.13
+2.190.176.218
+2.176.234.128
+2.176.247.54
+2.176.250.245
+2.177.45.25
+2.177.92.255
+2.177.109.58
+2.177.158.21
+2.177.219.23
+2.178.142.224
+2.178.215.98
+2.178.245.98
+2.178.253.51
+2.179.105.155
+2.179.164.199
+2.179.164.237
+2.184.156.151
+2.190.25.70
+2.190.96.211
+2.190.160.70
+2.190.188.156
+2.190.195.246
+2.191.5.173
+2.191.19.31
+2.191.116.58
+2.176.176.154
+2.176.244.30
+2.177.211.193
+2.180.33.238
+2.182.226.202
+2.183.9.23
+2.183.29.240
+2.190.201.38
+2.190.202.101
+2.191.1.229
+2.176.242.22
+2.177.51.166
+2.177.106.45
+2.177.150.38
+2.178.83.133
+2.180.43.33
+2.182.223.152
+2.186.115.37
+2.189.139.181
+2.189.139.227
+2.189.139.226
+2.189.164.30
+2.190.201.62
+2.191.79.18
+2.191.105.26
+2.191.115.143
+2.191.126.83
+2.191.187.230
+2.177.115.69
+2.178.245.83
+2.182.54.48
+2.191.65.217
+2.189.139.212
+2.191.13.49
+2.191.67.102
+2.176.235.174
+2.176.237.127
+2.176.242.7
+2.177.41.82
+2.177.98.70
+2.177.152.179
+2.178.16.146
+2.178.71.207
+2.179.64.79
+2.179.67.90
+2.179.229.254
+2.180.29.142
+2.180.30.167
+2.182.153.70
+2.190.194.227
+2.191.16.108
+2.176.198.213
+2.176.232.208
+2.176.238.75
+2.176.242.124
+2.177.92.52
+2.177.108.109
+2.177.153.8
+2.177.172.249
+2.177.175.40
+2.177.219.183
+2.177.223.28
+2.178.23.43
+2.178.80.11
+2.178.189.61
+2.179.109.19
+2.179.117.179
+2.182.154.9
+2.182.225.237
+2.189.139.231
+2.190.42.94
+2.190.138.115
+2.190.216.245
+2.191.5.137
+2.191.9.130
+2.177.106.125
+2.177.110.187
+2.177.158.155
+2.177.216.60
+2.178.13.244
+2.178.142.152
+2.178.186.226
+2.180.29.17
+2.189.148.130
+2.177.151.229
+2.177.152.199
+2.177.176.61
+2.178.74.99
+2.183.29.242
+2.184.237.51
+2.189.139.228
+2.191.73.34
+2.177.227.61
+2.178.30.208
+2.178.129.235
+2.178.140.0
+2.178.204.102
+2.180.26.19
+2.190.100.38
+2.190.131.48
+2.190.218.64
+2.190.225.30
+2.191.79.57
+2.191.114.208
+2.191.119.217
+2.191.123.60
+2.176.128.105
+2.176.174.251
+2.176.246.7
+2.177.41.184
+2.177.42.153
+2.177.47.149
+2.177.68.208
+2.177.111.71
+2.177.221.131
+2.178.17.165
+2.178.133.2
+2.179.124.171
+2.182.222.226
+2.189.139.146
+2.189.148.93
+2.189.148.149
+2.190.38.43
+2.190.38.168
+2.191.21.72
+2.191.66.80
+2.177.37.77
+2.177.108.126
+2.177.211.148
+2.177.231.29
+2.189.148.122
+2.189.148.121
+2.189.148.127
+2.189.148.128
+2.191.2.86
+2.191.127.125
+2.177.228.72
+2.179.113.178
+2.179.161.147
+2.177.169.30
+2.191.16.201
+2.191.73.58
+2.176.179.89
+2.177.43.209
+2.177.115.49
+2.177.159.38
+2.177.231.47
+2.182.214.198
+2.189.148.91
+2.189.148.89
+2.189.148.90
+2.189.148.132
+2.190.73.186
+2.190.93.129
+2.178.78.5
+2.190.38.244
+2.177.38.182
+2.177.165.101
+2.178.145.58
+2.180.202.254
+2.182.88.204
+2.186.122.108
+2.190.93.101
+2.190.151.62
+2.177.110.46
+2.182.152.182
+2.187.128.167
+2.180.218.207
+2.180.42.227
+2.181.236.27
+2.181.250.52
+2.183.201.25
+2.184.16.254
+2.185.102.157
+2.185.147.195
+2.186.12.123
+2.187.39.139
+2.187.147.65
+2.190.159.73
+2.191.63.230
+2.191.125.110
+2.182.215.189
+2.189.148.118
+2.189.148.254
+2.176.244.117
+2.189.122.179
+2.189.139.162
+2.189.139.184
+2.190.207.58
+2.191.47.177
+2.185.108.199
+2.190.93.162
+2.177.157.104
+2.181.85.90
+2.189.148.92
+2.189.148.119
+2.191.187.56
+2.188.226.244
+2.180.5.196
+2.189.10.143
+2.177.99.255
+2.180.19.106
+2.189.148.129
+2.190.153.37
+2.180.33.248
+2.182.214.99
+2.189.139.20
+2.180.165.148
+2.189.139.22
+2.190.203.58
+2.179.165.76
+2.191.81.12
+2.181.1.163
+2.178.10.185
+2.179.113.3
+2.190.153.144
+2.191.118.46
+2.179.108.17
+2.188.73.132
+2.184.60.90
+2.178.194.150
+2.191.69.61
+2.144.243.102
+2.176.77.239
+2.176.139.231
+2.176.155.226
+2.176.198.253
+2.176.199.97
+2.176.199.228
+2.176.202.231
+2.176.207.137
+2.176.207.237
+2.176.208.185
+2.176.212.136
+2.176.212.148
+2.176.213.17
+2.176.214.75
+2.176.214.67
+2.176.214.140
+2.176.215.74
+2.176.215.104
+2.176.215.116
+2.176.226.183
+2.176.255.109
+2.176.255.225
+2.177.18.194
+2.177.21.242
+2.177.29.172
+2.177.42.65
+2.177.64.236
+2.177.65.11
+2.177.73.173
+2.177.74.143
+2.177.78.163
+2.177.82.240
+2.177.84.65
+2.177.84.84
+2.177.86.86
+2.177.87.89
+2.177.88.150
+2.177.88.129
+2.177.88.183
+2.177.89.83
+2.177.94.139
+2.177.97.172
+2.177.118.29
+2.177.130.106
+2.177.140.113
+2.177.149.223
+2.177.151.13
+2.177.151.42
+2.177.151.74
+2.177.151.137
+2.177.154.57
+2.177.219.36
+2.177.220.103
+2.177.221.181
+2.177.229.250
+2.177.232.104
+2.177.233.99
+2.177.243.139
+2.177.244.82
+2.178.32.142
+2.178.35.0
+2.178.43.119
+2.178.56.53
+2.178.56.149
+2.178.79.195
+2.178.110.158
+2.178.110.133
+2.178.111.164
+2.178.111.252
+2.178.114.114
+2.178.115.36
+2.178.115.143
+2.178.122.163
+2.178.129.61
+2.178.156.168
+2.178.166.203
+2.178.169.72
+2.178.170.193
+2.178.176.212
+2.178.178.16
+2.178.178.217
+2.178.224.25
+2.179.43.185
+2.179.44.186
+2.179.46.75
+2.179.91.125
+2.179.100.200
+2.179.100.165
+2.179.102.161
+2.179.102.166
+2.179.110.20
+2.179.111.182
+2.179.124.77
+2.179.124.180
+2.180.155.152
+2.180.168.204
+2.181.34.56
+2.181.89.209
+2.181.90.137
+2.181.224.89
+2.181.231.135
+2.182.48.18
+2.182.48.64
+2.182.49.108
+2.182.50.207
+2.182.51.240
+2.182.109.74
+2.182.127.113
+2.182.181.171
+85.185.41.64
+85.185.62.143
+85.185.75.75
+85.185.166.18
+85.185.166.170
+85.185.210.194
+85.185.235.44
+85.185.241.82
+85.185.242.34
+85.185.247.208
+85.204.82.68
+86.104.111.7
+86.104.111.126
+86.105.44.162
+86.107.148.106
+86.107.149.130
+86.107.149.136
+87.107.48.137
+87.107.49.52
+87.107.55.204
+87.107.73.83
+87.107.73.82
+87.107.82.198
+87.107.139.210
+87.107.185.6
+87.251.147.166
+185.206.231.51
+188.121.146.34
+185.8.175.222
+185.192.113.13
+185.213.165.177
+188.136.174.82
+188.136.174.210
+185.110.231.1
+185.121.131.178
+188.0.240.4
+188.211.98.218
+46.100.12.247
+46.100.60.230
+46.100.134.33
+185.46.218.250
+185.46.219.53
+31.7.90.122
+188.75.65.182
+188.75.95.21
+188.211.55.158
+46.245.72.221
+46.245.118.148
+178.252.191.18
+185.111.83.55
+185.112.39.5
+185.112.36.217
+37.114.251.107
+185.172.0.242
+185.169.6.245
+185.206.95.135
+178.236.106.230
+185.46.217.124
+185.46.218.130
+185.44.36.5
+31.7.73.126
+37.255.149.138
+46.100.94.121
+46.245.122.21
+185.79.158.138
+185.112.38.182
+185.112.36.185
+46.34.166.162
+46.100.1.109
+185.140.4.30
+46.245.118.164
+46.245.118.163
+185.193.209.13
+185.175.79.173
+185.193.209.44
+185.214.37.82
+185.193.209.38
+188.211.125.25
+178.239.149.193
+37.153.128.137
+185.110.28.118
+37.255.222.132
+37.255.203.116
+185.162.41.202
+185.193.209.25
+185.186.240.233
+185.193.209.12
+185.175.79.140
+185.193.209.33
+188.210.154.132
+188.211.101.233
+188.211.68.59
+188.209.31.92
+46.245.118.162
+46.245.122.28
+178.131.30.4
+178.131.89.13
+178.131.95.154
+178.131.158.148
+178.131.165.9
+178.131.155.93
+178.173.144.210
+178.173.196.71
+178.239.149.225
+178.239.149.1
+178.239.156.19
+185.83.88.105
+185.110.30.64
+185.112.36.181
+185.112.38.56
+5.201.132.213
+5.201.133.136
+5.201.141.56
+5.201.145.207
+37.153.128.140
+37.255.198.6
+37.202.153.179
+46.38.132.238
+185.106.137.92
+188.75.65.179
+188.75.65.181
+188.211.73.133
+188.210.156.33
+188.213.154.236
+188.211.104.243
+188.213.147.34
+188.211.103.49
+46.245.78.85
+178.131.79.145
+178.131.31.79
+178.173.140.145
+178.173.217.221
+185.193.209.37
+185.193.209.24
+188.211.113.172
+178.131.95.2
+178.131.94.35
+45.142.191.36
+188.75.65.180
+188.75.65.178
+188.211.101.239
+188.211.73.123
+188.211.99.131
+188.209.66.119
+178.131.27.231
+178.131.165.97
+178.131.101.41
+178.131.147.208
+178.131.191.141
+178.173.138.218
+178.173.184.189
+178.173.215.59
+185.193.209.15
+185.193.209.3
+185.193.209.23
+185.175.78.199
+188.208.144.51
+188.209.79.123
+188.211.127.238
+46.235.76.161
+178.131.75.107
+178.131.91.5
+178.131.89.197
+178.131.93.191
+178.236.104.186
+37.153.130.202
+46.100.60.44
+46.245.4.4
+178.131.100.139
+178.131.153.91
+185.120.214.240
+178.173.185.216
+185.162.41.59
+188.211.101.127
+178.131.81.219
+178.131.76.141
+178.131.183.169
+178.173.215.53
+5.201.128.211
+5.201.129.159
+5.201.132.11
+37.143.146.56
+37.148.2.225
+188.211.104.216
+178.131.93.225
+45.8.160.217
+178.131.21.179
+178.131.111.182
+178.131.147.249
+178.131.111.183
+46.34.164.62
+185.175.78.97
+188.211.115.34
+37.202.188.182
+188.210.124.67
+178.131.132.168
+185.3.212.58
+188.209.65.12
+188.211.80.86
+188.211.122.188
+178.131.85.186
+178.131.181.76
+188.211.93.212
+188.211.113.28
+37.148.10.14
+178.131.91.185
+185.193.209.45
+37.148.5.188
+185.193.209.28
+178.131.89.60
+5.201.137.183
+185.162.40.190
+5.201.136.198
+185.176.34.216
+178.131.93.104
+178.131.190.233
+188.121.147.14
+2.144.6.75
+2.144.234.8
+2.176.0.149
+2.176.1.2
+2.176.3.199
+2.176.4.253
+2.176.5.147
+2.176.10.31
+2.176.13.185
+2.176.14.103
+2.176.14.183
+2.176.19.229
+2.176.21.116
+2.176.22.40
+2.176.23.196
+2.176.26.161
+2.176.28.124
+2.176.32.50
+2.176.32.152
+2.176.33.3
+2.176.33.49
+2.176.33.252
+2.176.37.116
+2.176.38.115
+2.176.40.17
+2.176.46.159
+2.176.48.151
+2.176.49.16
+2.176.51.21
+2.176.54.114
+2.176.57.203
+2.176.59.199
+2.176.63.26
+2.176.63.164
+2.176.64.13
+2.176.64.62
+2.176.67.195
+2.176.68.200
+2.176.69.30
+2.176.70.163
+2.176.70.194
+2.176.70.255
+2.176.72.122
+2.176.73.187
+2.176.75.51
+2.176.79.19
+2.176.79.205
+2.176.82.84
+2.176.89.185
+2.176.91.175
+2.176.96.244
+2.176.97.95
+2.176.110.198
+2.176.111.242
+2.176.112.190
+2.176.114.152
+2.176.115.171
+2.176.116.29
+2.176.118.141
+2.176.125.63
+2.176.125.180
+2.176.127.4
+2.176.128.63
+2.176.128.77
+2.176.128.112
+2.176.128.228
+2.176.129.91
+2.176.129.231
+2.176.130.105
+2.176.131.65
+2.176.131.77
+2.176.132.230
+2.176.137.87
+2.176.138.199
+2.176.139.170
+2.176.142.146
+2.176.144.136
+2.176.144.166
+2.176.144.243
+2.176.145.7
+2.176.146.150
+2.176.146.196
+2.176.148.38
+2.176.148.44
+2.176.150.91
+2.176.152.223
+2.176.153.246
+2.176.155.87
+2.176.157.202
+2.176.158.62
+2.176.158.249
+2.176.159.236
+2.176.164.204
+2.176.170.96
+2.176.172.196
+2.176.174.221
+2.176.180.253
+2.176.182.199
+2.176.186.237
+2.176.192.190
+2.176.194.95
+2.176.194.219
+2.176.194.252
+2.176.195.55
+2.176.195.166
+2.176.196.6
+2.176.198.119
+2.176.198.194
+2.176.199.32
+2.176.200.173
+2.176.200.224
+2.176.203.56
+2.176.203.132
+2.176.204.68
+2.176.207.44
+2.176.208.140
+2.176.210.13
+2.176.214.194
+2.176.217.128
+2.176.218.15
+2.176.218.38
+2.176.218.157
+2.176.219.106
+2.176.220.0
+2.176.220.41
+2.176.220.74
+2.176.220.159
+2.176.220.232
+2.176.223.22
+2.176.225.123
+2.176.228.243
+2.176.235.178
+2.176.236.18
+2.176.236.73
+2.176.237.101
+2.176.239.112
+2.176.239.166
+2.176.240.214
+2.176.241.29
+2.176.241.192
+2.176.243.199
+2.176.246.103
+2.176.246.118
+2.176.249.144
+2.176.250.140
+2.176.251.152
+2.176.252.239
+2.176.253.59
+2.177.0.4
+2.177.0.102
+2.177.1.27
+2.177.2.24
+2.177.2.191
+2.177.4.142
+2.177.4.190
+2.177.5.6
+2.177.5.226
+2.177.7.132
+2.177.8.24
+2.177.9.2
+2.177.9.92
+2.177.11.190
+2.177.13.184
+2.177.14.233
+2.177.16.78
+2.177.17.153
+2.177.20.69
+2.177.21.120
+2.177.21.132
+2.177.21.177
+2.177.22.81
+2.177.22.101
+2.177.23.57
+2.177.24.65
+2.177.24.180
+2.177.26.202
+2.177.28.36
+2.177.35.28
+2.177.35.203
+2.177.35.241
+2.177.37.57
+2.177.44.216
+2.177.45.132
+2.177.46.215
+2.177.48.88
+2.177.51.76
+2.177.51.229
+2.177.55.110
+2.177.56.122
+2.177.60.52
+2.177.60.86
+2.177.60.149
+2.177.65.54
+2.177.67.107
+2.177.67.109
+2.177.68.140
+2.177.69.213
+2.177.72.120
+2.177.72.160
+2.177.73.27
+2.177.73.194
+2.177.75.6
+2.177.77.139
+2.177.78.50
+2.177.79.209
+2.177.80.105
+2.177.81.171
+2.177.85.139
+2.177.86.104
+2.177.88.168
+2.177.89.205
+2.177.97.64
+2.177.100.34
+2.177.102.82
+2.177.104.97
+2.177.105.74
+2.177.109.182
+2.177.110.188
+2.177.112.34
+2.177.113.111
+2.177.115.30
+2.177.115.139
+2.177.116.83
+2.177.116.163
+2.177.117.151
+2.177.120.18
+2.177.121.15
+2.177.124.17
+2.177.125.26
+2.177.125.210
+2.177.126.89
+2.177.129.25
+2.177.130.99
+2.177.131.124
+2.177.132.3
+2.177.132.150
+2.177.133.146
+2.177.133.241
+2.177.137.23
+2.177.138.130
+2.177.138.241
+2.177.141.203
+2.177.142.59
+2.177.143.254
+2.177.144.14
+2.177.144.176
+2.177.145.91
+2.177.145.107
+2.177.146.124
+2.177.146.253
+2.177.147.104
+2.177.147.146
+2.177.148.14
+2.177.148.18
+2.177.150.204
+2.177.150.232
+2.177.153.97
+2.177.153.117
+2.177.154.117
+2.177.154.163
+2.177.155.114
+2.177.157.64
+2.177.160.50
+2.177.160.134
+2.177.162.103
+2.177.162.117
+2.177.163.247
+2.177.165.197
+2.177.166.204
+2.177.166.244
+2.177.171.61
+2.177.171.185
+2.177.172.140
+2.177.172.168
+2.177.174.32
+2.177.174.65
+2.177.174.80
+2.177.175.61
+2.177.176.87
+2.177.179.220
+2.177.180.217
+2.177.181.160
+2.177.181.248
+2.177.181.252
+2.177.182.225
+2.177.182.249
+2.177.185.220
+2.177.187.117
+2.177.187.218
+2.177.188.154
+2.177.190.97
+2.177.194.12
+2.177.194.227
+2.177.195.220
+2.177.196.18
+2.177.197.5
+2.177.198.140
+2.177.199.1
+2.177.199.219
+2.177.200.176
+2.177.202.44
+2.177.202.188
+2.177.205.239
+2.177.206.194
+2.177.208.38
+2.177.208.191
+2.177.209.17
+2.177.212.13
+2.177.212.85
+2.177.214.26
+2.177.214.42
+2.177.214.238
+2.177.217.0
+2.177.217.81
+2.177.218.70
+2.177.221.170
+2.177.221.178
+2.177.224.225
+2.177.225.4
+2.177.225.205
+2.177.226.0
+2.177.226.178
+2.177.230.72
+2.177.231.76
+2.177.231.200
+2.177.233.62
+2.177.236.2
+2.177.236.30
+2.177.236.221
+2.177.237.95
+2.177.240.71
+2.177.243.171
+2.177.244.185
+2.177.245.168
+2.177.245.206
+2.177.245.207
+2.177.246.141
+2.177.250.215
+2.177.250.239
+2.177.251.74
+2.178.0.88
+2.178.1.123
+2.178.2.120
+2.178.2.138
+2.178.12.135
+2.178.15.73
+2.178.17.73
+2.178.18.219
+2.178.20.173
+2.178.21.53
+2.178.25.0
+2.178.28.209
+2.178.28.241
+2.178.29.173
+2.178.34.223
+2.178.37.140
+2.178.41.120
+2.178.43.178
+2.178.44.137
+2.178.48.99
+2.178.48.207
+2.178.50.81
+2.178.53.39
+2.178.54.58
+2.178.58.202
+2.178.59.38
+2.178.67.118
+2.178.68.83
+2.178.70.36
+2.178.71.48
+2.178.72.192
+2.178.75.5
+2.178.79.202
+2.178.80.60
+2.178.80.166
+2.178.81.3
+2.178.87.134
+2.178.89.141
+2.178.92.217
+2.178.95.100
+2.178.98.24
+2.178.99.137
+2.178.99.171
+2.178.100.51
+2.178.101.158
+2.178.103.59
+2.178.104.72
+2.178.106.47
+2.178.111.162
+2.178.114.185
+2.178.116.7
+2.178.118.23
+2.178.118.113
+2.178.120.176
+2.178.121.69
+2.178.123.81
+2.178.125.192
+2.178.127.86
+2.178.131.81
+2.178.131.208
+2.178.134.227
+2.178.141.17
+2.178.147.116
+2.178.149.161
+2.178.150.176
+2.178.152.155
+2.178.162.109
+2.178.165.47
+2.178.167.203
+2.178.168.166
+2.178.176.44
+2.178.180.145
+2.178.183.88
+2.178.185.208
+2.178.188.32
+2.178.195.84
+2.178.195.119
+2.178.201.117
+2.178.203.141
+2.178.208.230
+2.178.214.202
+2.178.220.103
+2.178.229.49
+2.178.230.103
+2.178.232.133
+2.178.232.202
+2.178.232.209
+2.178.233.77
+2.178.234.139
+2.178.236.87
+2.178.241.103
+2.178.247.85
+2.179.20.77
+2.179.21.89
+2.179.21.253
+2.179.22.24
+2.179.46.173
+2.179.47.241
+2.179.67.96
+2.179.70.156
+2.179.71.6
+2.179.71.183
+2.179.78.139
+2.179.80.86
+2.179.83.31
+2.179.83.40
+2.179.84.26
+2.179.84.223
+2.179.86.198
+2.179.96.57
+2.179.96.164
+2.179.96.196
+2.179.100.5
+2.179.100.90
+2.179.101.193
+2.179.103.136
+2.179.103.247
+2.179.105.36
+2.179.106.42
+2.179.115.152
+2.179.115.171
+2.179.117.25
+2.179.117.157
+2.179.117.227
+2.179.118.254
+2.179.121.31
+2.179.124.214
+2.179.125.87
+2.179.126.163
+2.179.127.65
+2.179.162.144
+2.179.163.232
+2.179.167.231
+2.179.178.115
+2.179.186.238
+2.179.193.146
+2.179.194.45
+2.179.194.138
+2.179.211.167
+2.179.212.14
+2.179.217.132
+2.179.232.21
+2.179.252.135
+2.180.0.177
+2.180.1.91
+2.180.1.95
+2.180.3.207
+2.180.6.135
+2.180.8.54
+2.180.8.97
+2.180.15.75
+2.180.21.43
+2.180.21.218
+2.180.22.62
+2.180.22.233
+2.180.24.112
+2.180.25.192
+2.180.29.94
+2.180.31.174
+2.180.32.48
+2.180.32.211
+2.180.33.137
+2.180.35.195
+2.180.35.227
+2.180.36.43
+2.180.39.39
+2.180.41.242
+2.180.42.127
+2.180.43.95
+2.180.47.53
+2.181.1.61
+2.181.30.184
+2.181.31.165
+2.181.35.20
+2.181.35.134
+2.181.60.180
+2.181.80.158
+2.181.81.16
+2.181.85.245
+2.181.89.248
+2.181.93.51
+2.181.101.208
+2.181.102.4
+2.181.109.155
+2.181.177.81
+2.181.224.175
+2.181.224.244
+2.181.232.2
+2.181.232.233
+2.181.237.83
+2.181.238.104
+2.181.245.168
+2.181.247.131
+2.181.249.200
+2.181.251.228
+2.181.255.52
+2.182.51.83
+2.182.51.102
+2.182.51.211
+2.182.52.8
+2.182.53.4
+2.182.53.28
+2.182.54.16
+2.182.55.126
+2.182.59.207
+2.182.64.250
+2.182.65.3
+2.182.67.56
+2.182.67.151
+2.182.67.168
+2.182.67.197
+2.182.68.82
+2.182.68.142
+2.182.70.153
+2.182.73.35
+2.182.75.49
+2.182.75.133
+2.182.75.162
+2.182.75.254
+2.182.77.238
+2.182.84.145
+2.182.85.146
+2.182.86.49
+2.182.88.229
+2.182.90.64
+2.182.90.230
+2.182.93.10
+2.182.93.122
+2.182.93.241
+2.182.95.158
+2.182.95.239
+2.182.116.229
+2.182.118.163
+2.182.119.115
+2.182.127.44
+2.182.127.71
+2.182.166.5
+2.182.184.150
+2.182.190.134
+2.182.191.10
+2.182.192.22
+2.182.192.106
+2.182.196.132
+2.182.197.46
+2.182.201.6
+2.182.208.44
+2.182.215.172
+2.182.217.172
+2.182.217.217
+2.182.218.73
+2.182.221.90
+2.182.222.208
+2.182.226.35
+2.182.226.205
+2.182.227.83
+2.182.228.6
+2.182.228.77
+2.182.228.197
+2.182.229.125
+2.182.231.26
+2.182.234.126
+2.182.234.153
+2.182.234.201
+2.182.235.5
+2.182.235.216
+2.182.241.138
+2.182.249.72
+2.182.251.205
+2.183.8.116
+2.183.88.79
+2.183.89.135
+2.183.99.60
+2.183.99.80
+2.183.115.168
+2.183.123.1
+2.183.142.201
+2.183.143.93
+2.183.195.164
+2.183.198.32
+2.183.200.141
+2.183.202.66
+2.183.202.70
+2.183.202.71
+2.183.203.130
+2.183.203.186
+2.184.2.165
+2.184.2.184
+2.184.3.191
+2.184.15.56
+2.184.16.149
+2.184.16.208
+2.184.18.54
+2.184.18.130
+2.184.22.102
+2.184.29.224
+2.184.30.140
+2.184.31.224
+2.184.31.226
+2.184.53.203
+2.184.55.72
+2.184.57.76
+2.184.70.111
+2.184.156.10
+2.184.156.166
+2.184.157.37
+2.184.158.58
+2.184.158.225
+2.184.159.1
+2.184.159.172
+2.184.182.83
+2.184.204.101
+2.184.216.242
+2.184.238.105
+2.184.238.193
+2.184.239.43
+2.185.17.16
+2.185.17.227
+2.185.66.102
+2.185.97.114
+2.185.100.126
+2.185.102.55
+2.185.104.61
+2.185.109.51
+2.185.109.210
+2.185.110.156
+2.185.113.54
+2.185.116.135
+2.185.122.111
+2.185.141.99
+2.185.143.19
+2.185.143.54
+2.185.144.8
+2.185.144.53
+2.185.144.86
+2.185.146.24
+2.185.148.251
+2.185.175.77
+2.185.230.179
+2.185.232.154
+2.185.232.162
+2.185.233.7
+2.185.233.26
+2.185.237.103
+2.185.243.230
+2.185.244.248
+2.185.247.84
+2.185.251.200
+2.185.252.143
+2.186.13.114
+2.186.15.84
+2.186.112.159
+2.186.116.88
+2.186.116.124
+2.186.118.250
+2.186.120.77
+2.186.121.189
+2.186.122.128
+2.186.229.13
+2.187.2.155
+2.187.9.112
+2.187.20.133
+2.187.32.176
+2.187.34.93
+2.187.36.108
+2.187.56.151
+2.187.57.2
+2.187.59.40
+2.187.129.147
+2.187.138.186
+2.187.146.168
+2.187.148.114
+2.187.151.18
+2.187.188.92
+2.187.189.189
+2.187.249.102
+2.187.250.158
+2.188.72.139
+2.188.162.210
+2.188.167.197
+2.188.168.191
+2.188.174.129
+2.188.174.149
+2.188.174.154
+2.188.210.1
+2.188.210.9
+2.188.210.11
+2.188.210.60
+2.188.212.190
+2.188.218.178
+2.188.226.186
+2.188.226.249
+2.188.230.202
+2.188.236.66
+2.188.236.68
+2.188.236.69
+2.189.20.134
+2.189.20.221
+2.189.33.59
+2.189.89.26
+2.189.103.0
+2.189.103.1
+2.189.103.2
+2.189.103.3
+2.189.103.5
+2.189.103.6
+2.189.103.7
+2.189.103.8
+2.189.103.10
+2.189.103.11
+2.189.103.13
+2.189.103.16
+2.189.103.17
+2.189.103.18
+2.189.103.19
+2.189.103.20
+2.189.103.21
+2.189.103.22
+2.189.103.23
+2.189.103.24
+2.189.103.25
+2.189.103.26
+2.189.103.27
+2.189.103.28
+2.189.103.30
+2.189.103.32
+2.189.103.33
+2.189.103.34
+2.189.103.35
+2.189.103.36
+2.189.103.37
+2.189.103.39
+2.189.103.40
+2.189.103.41
+2.189.103.42
+2.189.103.43
+2.189.103.44
+2.189.103.45
+2.189.103.46
+2.189.103.47
+2.189.103.48
+2.189.103.49
+2.189.103.50
+2.189.103.51
+2.189.103.52
+2.189.103.53
+2.189.103.55
+2.189.103.56
+2.189.103.57
+2.189.103.59
+2.189.103.60
+2.189.103.61
+2.189.103.63
+2.189.103.64
+2.189.103.65
+2.189.103.67
+2.189.103.68
+2.189.103.69
+2.189.103.72
+2.189.103.73
+2.189.103.74
+2.189.103.75
+2.189.103.76
+2.189.103.78
+2.189.103.79
+2.189.103.80
+2.189.103.81
+2.189.103.82
+2.189.103.84
+2.189.103.85
+2.189.103.86
+2.189.103.87
+2.189.103.88
+2.189.103.89
+2.189.103.90
+2.189.103.91
+2.189.103.92
+2.189.103.93
+2.189.103.95
+2.189.103.96
+2.189.103.97
+2.189.103.98
+2.189.103.99
+2.189.103.100
+2.189.103.101
+2.189.103.102
+2.189.103.105
+2.189.103.106
+2.189.103.107
+2.189.103.108
+2.189.103.109
+2.189.103.110
+2.189.103.111
+2.189.103.112
+2.189.103.113
+2.189.103.114
+2.189.103.115
+2.189.103.116
+2.189.103.117
+2.189.103.118
+2.189.103.119
+2.189.103.120
+2.189.103.121
+2.189.103.122
+2.189.103.123
+2.189.103.124
+2.189.103.125
+2.189.103.128
+2.189.103.129
+2.189.103.130
+2.189.103.131
+2.189.103.132
+2.189.103.134
+2.189.103.135
+2.189.103.136
+2.189.103.138
+2.189.103.139
+2.189.103.140
+2.189.103.141
+2.189.103.142
+2.189.103.143
+2.189.103.144
+2.189.103.145
+2.189.103.146
+2.189.103.147
+2.189.103.148
+2.189.103.149
+2.189.103.150
+2.189.103.152
+2.189.103.153
+2.189.103.154
+2.189.103.155
+2.189.103.156
+2.189.103.158
+2.189.103.159
+2.189.103.160
+2.189.103.161
+2.189.103.162
+2.189.103.163
+2.189.103.164
+2.189.103.166
+2.189.103.167
+2.189.103.168
+2.189.103.169
+2.189.103.170
+2.189.103.171
+2.189.103.172
+2.189.103.173
+2.189.103.174
+2.189.103.176
+2.189.103.177
+2.189.103.178
+2.189.103.179
+2.189.103.180
+2.189.103.181
+2.189.103.182
+2.189.103.183
+2.189.103.184
+2.189.103.186
+2.189.103.187
+2.189.103.188
+2.189.103.189
+2.189.103.190
+2.189.103.192
+2.189.103.193
+2.189.103.194
+2.189.103.195
+2.189.103.196
+2.189.103.197
+2.189.103.198
+2.189.103.199
+2.189.103.200
+2.189.103.202
+2.189.103.203
+2.189.103.204
+2.189.103.205
+2.189.103.206
+2.189.103.208
+2.189.103.209
+2.189.103.210
+2.189.103.212
+2.189.103.213
+2.189.103.214
+2.189.103.215
+2.189.103.216
+2.189.103.217
+2.189.103.219
+2.189.103.220
+2.189.103.222
+2.189.103.223
+2.189.103.224
+2.189.103.225
+2.189.103.226
+2.189.103.227
+2.189.103.228
+2.189.103.229
+2.189.103.230
+2.189.103.232
+2.189.103.233
+2.189.103.234
+2.189.103.235
+2.189.103.236
+2.189.103.238
+2.189.103.239
+2.189.103.240
+2.189.103.241
+2.189.103.242
+2.189.103.244
+2.189.103.245
+2.189.103.246
+2.189.103.247
+2.189.103.248
+2.189.103.249
+2.189.103.250
+2.189.103.251
+2.189.103.252
+2.189.103.253
+2.189.103.254
+2.189.103.255
+2.189.142.24
+2.189.144.51
+2.189.146.0
+2.189.146.1
+2.189.146.2
+2.189.146.3
+2.189.146.4
+2.189.146.5
+2.189.146.6
+2.189.146.7
+2.189.146.8
+2.189.146.9
+2.189.146.10
+2.189.146.11
+2.189.146.12
+2.189.146.13
+2.189.146.14
+2.189.146.15
+2.189.146.16
+2.189.146.17
+2.189.146.19
+2.189.146.20
+2.189.146.21
+2.189.146.22
+2.189.146.24
+2.189.146.25
+2.189.146.26
+2.189.146.27
+2.189.146.28
+2.189.146.30
+2.189.146.31
+2.189.146.32
+2.189.146.33
+2.189.146.34
+2.189.146.35
+2.189.146.36
+2.189.146.37
+2.189.146.38
+2.189.146.39
+2.189.146.40
+2.189.146.41
+2.189.146.42
+2.189.146.43
+2.189.146.44
+2.189.146.45
+2.189.146.46
+2.189.146.47
+2.189.146.49
+2.189.146.50
+2.189.146.51
+2.189.146.52
+2.189.146.53
+2.189.146.54
+2.189.146.55
+2.189.146.57
+2.189.146.58
+2.189.146.59
+2.189.146.60
+2.189.146.61
+2.189.146.62
+2.189.146.63
+2.189.146.64
+2.189.146.65
+2.189.146.66
+2.189.146.68
+2.189.146.69
+2.189.146.70
+2.189.146.71
+2.189.146.72
+2.189.146.73
+2.189.146.74
+2.189.146.76
+2.189.146.77
+2.189.146.79
+2.189.146.80
+2.189.146.81
+2.189.146.82
+2.189.146.83
+2.189.146.84
+2.189.146.85
+2.189.146.86
+2.189.146.87
+2.189.146.88
+2.189.146.89
+2.189.146.90
+2.189.146.91
+2.189.146.92
+2.189.146.93
+2.189.146.95
+2.189.146.96
+2.189.146.98
+2.189.146.99
+2.189.146.100
+2.189.146.101
+2.189.146.103
+2.189.146.104
+2.189.146.105
+2.189.146.106
+2.189.146.109
+2.189.146.110
+2.189.146.111
+2.189.146.112
+2.189.146.114
+2.189.146.115
+2.189.146.116
+2.189.146.117
+2.189.146.119
+2.189.146.120
+2.189.146.121
+2.189.146.122
+2.189.146.123
+2.189.146.124
+2.189.146.125
+2.189.146.126
+2.189.146.127
+2.189.146.128
+2.189.146.130
+2.189.146.131
+2.189.146.134
+2.189.146.135
+2.189.146.136
+2.189.146.137
+2.189.146.138
+2.189.146.141
+2.189.146.142
+2.189.146.143
+2.189.146.144
+2.189.146.145
+2.189.146.146
+2.189.146.148
+2.189.146.150
+2.189.146.151
+2.189.146.153
+2.189.146.154
+2.189.146.155
+2.189.146.156
+2.189.146.157
+2.189.146.158
+2.189.146.159
+2.189.146.160
+2.189.146.161
+2.189.146.162
+2.189.146.163
+2.189.146.164
+2.189.146.165
+2.189.146.166
+2.189.146.169
+2.189.146.170
+2.189.146.171
+2.189.146.172
+2.189.146.173
+2.189.146.174
+2.189.146.176
+2.189.146.177
+2.189.146.178
+2.189.146.179
+2.189.146.180
+2.189.146.181
+2.189.146.183
+2.189.146.184
+2.189.146.185
+2.189.146.186
+2.189.146.188
+2.189.146.189
+2.189.146.190
+2.189.146.191
+2.189.146.192
+2.189.146.193
+2.189.146.194
+2.189.146.195
+2.189.146.196
+2.189.146.197
+2.189.146.198
+2.189.146.200
+2.189.146.201
+2.189.146.202
+2.189.146.203
+2.189.146.204
+2.189.146.205
+2.189.146.206
+2.189.146.207
+2.189.146.208
+2.189.146.209
+2.189.146.210
+2.189.146.211
+2.189.146.212
+2.189.146.213
+2.189.146.214
+2.189.146.215
+2.189.146.216
+2.189.146.217
+2.189.146.218
+2.189.146.219
+2.189.146.220
+2.189.146.221
+2.189.146.222
+2.189.146.223
+2.189.146.224
+2.189.146.225
+2.189.146.226
+2.189.146.227
+2.189.146.228
+2.189.146.229
+2.189.146.230
+2.189.146.231
+2.189.146.232
+2.189.146.233
+2.189.146.234
+2.189.146.235
+2.189.146.236
+2.189.146.238
+2.189.146.239
+2.189.146.240
+2.189.146.241
+2.189.146.243
+2.189.146.244
+2.189.146.245
+2.189.146.246
+2.189.146.247
+2.189.146.248
+2.189.146.249
+2.189.146.250
+2.189.146.251
+2.189.146.252
+2.189.146.254
+2.189.146.255
+2.189.147.203
+2.189.167.182
+2.189.248.85
+2.189.253.227
+2.190.0.219
+2.190.3.109
+2.190.4.52
+2.190.6.196
+2.190.7.228
+2.190.9.118
+2.190.11.141
+2.190.15.136
+2.190.19.245
+2.190.20.60
+2.190.23.236
+2.190.26.141
+2.190.27.169
+2.190.27.197
+2.190.37.39
+2.190.38.55
+2.190.38.87
+2.190.38.142
+2.190.38.211
+2.190.39.77
+2.190.39.130
+2.190.40.156
+2.190.42.21
+2.190.42.183
+2.190.45.166
+2.190.46.116
+2.190.51.254
+2.190.52.74
+2.190.53.198
+2.190.59.26
+2.190.59.204
+2.190.60.248
+2.190.63.200
+2.190.64.4
+2.190.64.131
+2.190.65.190
+2.190.76.222
+2.190.78.34
+2.190.78.187
+2.190.78.200
+2.190.80.240
+2.190.85.139
+2.190.87.233
+2.190.98.198
+2.190.99.4
+2.190.100.201
+2.190.101.82
+2.190.102.90
+2.190.102.135
+2.190.103.7
+2.190.104.114
+2.190.109.119
+2.190.110.193
+2.190.111.127
+2.190.113.4
+2.190.113.163
+2.190.119.48
+2.190.122.249
+2.190.124.53
+2.190.124.161
+2.190.125.194
+2.190.127.59
+2.190.128.73
+2.190.129.19
+2.190.130.21
+2.190.130.101
+2.190.131.105
+2.190.131.202
+2.190.136.56
+2.190.136.169
+2.190.137.45
+2.190.138.190
+2.190.139.44
+2.190.140.121
+2.190.141.59
+2.190.142.75
+2.190.144.94
+2.190.146.240
+2.190.148.66
+2.190.148.218
+2.190.149.244
+2.190.152.106
+2.190.154.170
+2.190.155.54
+2.190.155.103
+2.190.158.27
+2.190.160.83
+2.190.160.127
+2.190.162.121
+2.190.162.212
+2.190.163.198
+2.190.163.219
+2.190.164.173
+2.190.166.177
+2.190.168.116
+2.190.170.245
+2.190.172.131
+2.190.173.242
+2.190.175.7
+2.190.176.19
+2.190.176.114
+2.190.176.170
+2.190.177.8
+2.190.177.128
+2.190.178.171
+2.190.179.93
+2.190.180.3
+2.190.180.123
+2.190.183.211
+2.190.184.51
+2.190.184.94
+2.190.184.245
+2.190.187.101
+2.190.188.246
+2.190.190.162
+2.190.197.84
+2.190.200.30
+2.190.201.140
+2.190.202.90
+2.190.207.43
+2.190.211.126
+2.190.213.109
+2.190.221.31
+2.190.223.151
+2.190.224.23
+2.190.225.129
+2.190.227.220
+2.190.230.241
+2.190.233.13
+2.190.235.238
+2.190.238.96
+2.190.239.255
+2.190.240.70
+2.190.240.227
+2.190.245.242
+2.190.247.236
+2.190.249.207
+2.190.250.172
+2.190.251.210
+2.190.254.120
+2.190.254.154
+2.190.255.53
+2.191.0.6
+2.191.0.224
+2.191.1.50
+2.191.1.113
+2.191.1.242
+2.191.4.59
+2.191.5.65
+2.191.7.180
+2.191.10.52
+2.191.12.81
+2.191.16.31
+2.191.17.99
+2.191.18.29
+2.191.18.142
+2.191.18.180
+2.191.19.78
+2.191.20.194
+2.191.21.17
+2.191.22.179
+2.191.23.246
+2.191.24.148
+2.191.24.199
+2.191.24.212
+2.191.25.48
+2.191.25.243
+2.191.26.247
+2.191.31.63
+2.191.31.199
+2.191.31.237
+2.191.33.102
+2.191.33.218
+2.191.36.95
+2.191.38.0
+2.191.38.215
+2.191.39.12
+2.191.39.33
+2.191.44.159
+2.191.46.156
+2.191.47.193
+2.191.47.212
+2.191.48.80
+2.191.50.18
+2.191.50.221
+2.191.51.19
+2.191.51.147
+2.191.52.111
+2.191.53.176
+2.191.53.235
+2.191.55.88
+2.191.55.143
+2.191.57.193
+2.191.60.111
+2.191.60.174
+2.191.64.245
+2.191.65.114
+2.191.67.13
+2.191.67.122
+2.191.67.132
+2.191.68.132
+2.191.72.96
+2.191.75.140
+2.191.77.110
+2.191.79.203
+2.191.81.104
+2.191.83.222
+2.191.85.229
+2.191.88.158
+2.191.88.227
+2.191.89.5
+2.191.89.181
+2.191.90.111
+2.191.92.21
+2.191.93.51
+2.191.96.43
+2.191.98.55
+2.191.98.216
+2.191.102.103
+2.191.102.147
+2.191.102.197
+2.191.104.0
+2.191.109.200
+2.191.110.107
+2.191.111.70
+2.191.111.155
+2.191.111.206
+2.191.112.240
+2.191.117.110
+2.191.122.151
+2.191.123.43
+2.191.123.207
+2.191.123.233
+2.191.125.122
+2.191.126.113
+2.191.127.237
+2.191.128.179
+2.191.129.228
+2.191.130.41
+2.191.130.94
+2.191.136.130
+2.191.142.36
+2.191.147.12
+2.191.150.45
+2.191.152.160
+2.191.152.233
+2.191.153.212
+2.191.153.213
+2.191.155.105
+2.191.156.224
+2.191.158.7
+2.191.159.18
+2.191.161.238
+2.191.162.18
+2.191.165.91
+2.191.166.250
+2.191.167.59
+2.191.167.133
+2.191.167.183
+2.191.169.113
+2.191.173.112
+2.191.173.135
+2.191.174.192
+2.191.177.52
+2.191.180.74
+2.191.181.20
+2.191.181.136
+2.191.190.126
+2.191.196.245
+2.191.199.52
+2.191.203.66
+2.191.207.176
+2.191.212.121
+2.191.215.7
+2.191.221.159
+2.191.230.3
+2.191.231.150
+5.22.198.2
+5.22.199.225
+5.22.199.227
+5.22.199.233
+5.61.24.140
+5.61.25.140
+5.62.161.12
+5.62.164.234
+5.62.167.252
+5.62.168.205
+5.62.168.209
+5.62.169.32
+5.62.170.171
+5.62.171.239
+5.62.172.230
+5.62.177.52
+5.62.180.232
+5.62.184.217
+5.62.185.88
+5.62.185.142
+5.62.187.24
+5.62.190.208
+5.74.1.46
+5.74.2.235
+5.74.4.38
+5.74.4.133
+5.74.5.163
+5.74.8.73
+5.74.10.109
+5.74.10.150
+5.74.10.215
+5.74.11.204
+5.74.13.185
+5.74.14.152
+5.74.14.155
+5.74.15.104
+5.74.15.181
+5.74.15.246
+5.74.16.146
+5.74.17.89
+5.74.18.0
+5.74.21.244
+5.74.23.161
+5.74.25.63
+5.74.25.64
+5.74.26.88
+5.74.26.94
+5.74.31.226
+5.74.32.237
+5.74.33.49
+5.74.42.117
+5.74.44.120
+5.74.45.152
+5.74.46.132
+5.74.47.40
+5.74.48.79
+5.74.48.107
+5.74.48.243
+5.74.49.7
+5.74.49.68
+5.74.51.101
+5.74.51.243
+5.74.53.164
+5.74.56.24
+5.74.68.122
+5.74.69.14
+5.74.70.57
+5.74.70.206
+5.74.72.139
+5.74.72.153
+5.74.73.211
+5.74.81.76
+5.74.81.109
+5.74.81.245
+5.74.82.14
+5.74.83.74
+5.74.84.91
+5.74.85.195
+5.74.86.234
+5.74.87.26
+5.74.89.115
+5.74.90.185
+5.74.93.95
+5.74.94.194
+5.74.96.192
+5.74.101.232
+5.74.102.212
+5.74.103.201
+5.74.104.46
+5.74.104.251
+5.74.105.6
+5.74.105.160
+5.74.106.186
+5.74.107.255
+5.74.108.196
+5.74.111.225
+5.74.112.152
+5.74.114.57
+5.74.114.157
+5.74.119.110
+5.74.122.30
+5.74.122.185
+5.74.124.110
+5.74.124.128
+5.74.129.51
+5.74.137.139
+5.74.140.172
+5.74.141.173
+5.74.143.207
+5.74.144.104
+5.74.145.28
+5.74.146.231
+5.74.150.112
+5.74.151.182
+5.74.152.5
+5.74.153.178
+5.74.159.57
+5.74.167.27
+5.74.172.121
+5.74.172.152
+5.74.174.105
+5.74.176.41
+5.74.180.83
+5.74.180.115
+5.74.184.161
+5.74.184.196
+5.74.185.175
+5.74.185.189
+5.74.186.120
+5.74.187.88
+5.74.190.109
+5.74.191.121
+5.74.192.203
+5.74.197.119
+5.74.200.185
+5.74.210.56
+5.74.212.34
+5.74.213.219
+5.74.217.255
+5.74.218.230
+5.74.224.78
+5.74.227.206
+5.74.227.218
+5.74.229.87
+5.74.230.51
+5.74.232.30
+5.74.233.67
+5.74.234.125
+5.74.234.204
+5.74.239.116
+5.74.245.238
+5.74.249.28
+5.74.249.161
+5.74.250.248
+5.74.251.44
+5.74.255.5
+5.74.255.195
+5.106.18.195
+5.106.19.94
+5.106.19.219
+5.134.193.5
+5.134.196.186
+5.159.48.64
+5.159.48.65
+5.159.48.66
+5.159.48.67
+5.159.48.68
+5.159.48.69
+5.159.48.70
+5.159.48.71
+5.159.50.80
+5.159.50.81
+5.159.50.82
+5.159.50.83
+5.159.50.84
+5.159.50.85
+5.159.50.86
+5.159.50.87
+5.159.51.208
+5.159.51.209
+5.159.51.210
+5.159.51.211
+5.159.51.212
+5.159.51.213
+5.159.51.214
+5.159.52.128
+5.159.52.130
+5.159.52.131
+5.159.52.133
+5.159.52.134
+5.159.52.135
+5.159.52.240
+5.159.52.242
+5.159.52.243
+5.159.53.57
+5.159.53.59
+5.159.53.60
+5.159.53.61
+5.159.53.63
+5.159.55.32
+5.159.55.33
+5.159.55.34
+5.159.55.35
+5.159.55.36
+5.159.55.37
+5.159.55.38
+5.159.55.39
+5.160.4.2
+5.160.4.3
+5.160.4.4
+5.160.4.5
+5.160.4.7
+5.160.4.8
+5.160.4.9
+5.160.4.10
+5.160.4.11
+5.160.4.12
+5.160.12.122
+5.160.13.202
+5.160.24.22
+5.160.25.130
+5.160.36.9
+5.160.45.254
+5.160.56.246
+5.160.62.1
+5.160.65.254
+5.160.92.121
+5.160.92.226
+5.160.92.227
+5.160.92.228
+5.160.92.229
+5.160.92.230
+5.160.94.34
+5.160.96.225
+5.160.109.184
+5.160.123.194
+5.160.126.138
+5.160.136.10
+5.160.148.66
+5.160.148.67
+5.160.148.68
+5.160.148.69
+5.160.148.70
+5.160.148.71
+5.160.148.72
+5.160.148.74
+5.160.148.77
+5.160.163.134
+5.160.171.205
+5.160.178.11
+5.160.186.158
+5.160.224.230
+5.160.236.206
+5.190.6.209
+5.190.15.14
+5.190.15.24
+5.190.19.169
+5.190.31.223
+5.190.35.66
+5.190.35.97
+5.190.38.2
+5.190.38.49
+5.190.69.7
+5.190.112.72
+5.190.113.6
+5.190.113.140
+5.190.113.183
+5.190.128.8
+5.190.128.129
+5.190.160.53
+5.190.160.57
+5.190.220.34
+5.198.177.232
+5.200.65.62
+5.200.72.170
+5.200.72.171
+5.200.72.172
+5.200.72.173
+5.200.74.42
+5.200.74.50
+5.200.92.86
+5.200.92.244
+5.200.128.20
+5.200.132.3
+5.200.134.101
+5.200.146.99
+5.200.163.136
+5.200.164.247
+5.200.170.71
+5.200.171.36
+5.200.176.48
+5.200.184.32
+5.200.187.76
+5.200.194.128
+5.200.195.164
+5.200.197.185
+5.200.198.18
+5.200.201.89
+5.200.210.162
+5.200.215.15
+5.200.240.130
+5.200.242.159
+5.200.244.61
+5.201.137.96
+5.201.179.171
+5.201.188.29
+5.201.190.178
+5.202.7.227
+5.202.8.189
+5.202.18.102
+5.202.31.165
+5.202.31.223
+5.202.33.71
+5.202.37.55
+5.202.44.204
+5.202.45.176
+5.202.46.130
+5.202.50.117
+5.202.53.129
+5.202.56.141
+5.202.60.116
+5.202.67.98
+5.202.68.103
+5.202.84.189
+5.202.101.56
+5.202.101.146
+5.202.104.46
+5.202.105.105
+5.202.130.8
+5.202.130.15
+5.202.131.150
+5.202.133.117
+5.202.134.189
+5.202.134.199
+5.202.168.111
+5.202.168.119
+5.202.168.152
+5.202.169.223
+5.202.170.19
+5.202.171.163
+5.202.171.191
+5.202.172.103
+5.202.172.114
+5.202.172.183
+5.202.174.52
+5.202.176.249
+5.202.180.114
+5.202.192.33
+5.202.193.131
+5.202.195.45
+5.202.195.51
+5.202.195.180
+5.202.197.82
+5.202.198.47
+5.202.243.73
+5.202.244.49
+5.202.244.217
+5.202.248.100
+5.202.248.115
+5.202.251.74
+5.202.252.251
+5.232.193.40
+5.232.195.40
+5.232.199.145
+5.232.201.225
+5.232.208.59
+5.232.208.178
+5.232.210.50
+5.232.210.132
+5.232.210.222
+5.232.214.197
+5.233.44.62
+5.233.46.93
+5.233.48.136
+5.233.48.194
+5.233.52.86
+5.233.53.56
+5.233.55.148
+5.233.58.136
+5.233.58.144
+5.233.59.44
+5.233.59.230
+5.233.61.98
+5.233.64.200
+5.233.67.248
+5.233.69.125
+5.233.74.76
+5.233.75.240
+5.233.75.250
+5.233.77.37
+5.233.81.193
+5.233.85.66
+5.233.91.53
+5.233.93.115
+5.233.93.131
+5.233.94.60
+5.233.97.234
+5.233.106.189
+5.233.181.73
+5.233.250.11
+5.233.250.69
+5.234.0.79
+5.234.33.50
+5.234.34.57
+5.234.196.166
+5.234.199.241
+5.234.200.92
+5.234.200.137
+5.234.202.94
+5.234.202.190
+5.234.204.177
+5.234.204.253
+5.234.207.165
+5.234.208.89
+5.234.210.1
+5.234.219.151
+5.235.156.18
+5.235.158.237
+5.235.160.167
+5.235.163.89
+5.235.163.98
+5.235.165.39
+5.235.168.186
+5.235.183.5
+5.235.183.159
+5.235.184.199
+5.235.186.254
+5.235.204.78
+5.235.208.203
+5.235.225.63
+5.235.237.139
+5.236.27.202
+5.236.36.77
+5.236.37.103
+5.236.37.159
+5.236.52.142
+5.236.68.129
+5.236.73.237
+5.236.74.210
+5.236.84.190
+5.236.84.192
+5.236.85.62
+5.236.107.158
+5.236.118.91
+5.236.118.105
+5.236.119.175
+5.236.119.229
+5.236.120.190
+5.236.120.193
+5.236.120.235
+5.236.123.214
+5.236.124.167
+5.236.126.76
+5.236.126.227
+5.236.194.234
+5.236.195.148
+5.236.209.26
+5.236.229.2
+5.236.230.82
+5.236.231.10
+5.236.232.140
+5.236.232.215
+5.236.232.238
+5.236.234.18
+5.236.235.10
+5.236.235.199
+5.236.237.236
+5.236.239.22
+5.236.241.109
+5.236.241.133
+5.236.245.47
+5.236.245.86
+5.236.245.163
+5.236.246.226
+5.236.249.2
+5.236.250.105
+5.236.250.176
+5.236.251.135
+5.237.48.134
+5.237.51.190
+5.237.172.191
+5.237.174.161
+5.237.190.133
+5.237.206.248
+5.237.213.90
+5.237.245.132
+5.237.255.27
+5.238.0.89
+5.238.7.139
+5.238.24.206
+5.238.30.209
+5.238.31.104
+5.238.65.35
+5.238.78.40
+5.238.88.24
+5.238.89.91
+5.238.97.239
+5.238.110.3
+5.238.110.167
+5.238.110.213
+5.238.130.4
+5.238.133.19
+5.238.134.79
+5.238.135.96
+5.238.141.127
+5.238.143.185
+5.238.150.47
+5.238.150.53
+5.238.150.56
+5.238.151.220
+5.238.152.177
+5.238.152.198
+5.238.152.219
+5.238.154.229
+5.238.156.79
+5.238.156.165
+5.238.157.70
+5.238.157.199
+5.238.158.245
+5.238.159.131
+5.238.160.36
+5.238.165.192
+5.238.169.30
+5.238.171.5
+5.238.172.60
+5.238.173.41
+5.238.175.197
+5.238.177.107
+5.238.178.33
+5.238.179.239
+5.238.181.231
+5.238.181.255
+5.238.182.247
+5.238.185.124
+5.238.187.1
+5.238.187.140
+5.238.193.30
+5.238.193.244
+5.238.200.210
+5.238.201.203
+5.238.203.199
+5.238.204.198
+5.238.207.195
+5.238.212.93
+5.238.212.230
+5.238.215.18
+5.238.217.118
+5.238.219.142
+5.238.220.91
+5.238.220.102
+5.238.220.140
+5.238.220.186
+5.238.220.220
+5.238.220.248
+5.238.221.65
+5.238.223.141
+5.238.223.191
+5.238.224.243
+5.238.225.34
+5.238.229.124
+5.238.232.103
+5.238.232.177
+5.238.236.69
+5.238.238.240
+5.238.240.163
+5.238.241.173
+5.238.242.42
+5.238.242.208
+5.238.243.13
+5.238.245.212
+5.238.246.10
+5.238.246.172
+5.238.247.166
+5.238.248.237
+5.238.251.105
+5.238.253.179
+5.238.255.209
+5.239.1.48
+5.239.2.189
+5.239.7.66
+5.239.8.61
+5.239.8.91
+5.239.9.27
+5.239.9.95
+5.239.15.238
+5.239.16.146
+5.239.18.169
+5.239.19.59
+5.239.21.123
+5.239.21.243
+5.239.23.168
+5.239.28.79
+5.239.28.187
+5.239.28.190
+5.239.32.187
+5.239.33.153
+5.239.39.141
+5.239.43.186
+5.239.44.114
+5.239.45.55
+5.239.45.119
+5.239.46.122
+5.239.50.227
+5.239.52.92
+5.239.53.98
+5.239.56.200
+5.239.57.135
+5.239.58.62
+5.239.59.64
+5.239.59.107
+5.239.60.67
+5.239.62.104
+5.239.63.8
+5.239.64.243
+5.239.67.160
+5.239.67.218
+5.239.68.12
+5.239.72.145
+5.239.75.70
+5.239.77.124
+5.239.77.235
+5.239.78.153
+5.239.81.155
+5.239.82.24
+5.239.82.141
+5.239.84.50
+5.239.86.80
+5.239.86.114
+5.239.86.213
+5.239.86.250
+5.239.87.163
+5.239.88.27
+5.239.88.97
+5.239.89.181
+5.239.95.160
+5.239.97.128
+5.239.97.243
+5.239.106.96
+5.239.107.197
+5.239.114.119
+5.239.114.191
+5.239.115.200
+5.239.118.70
+5.239.120.171
+5.239.121.241
+5.239.122.71
+5.239.123.122
+5.239.146.31
+5.239.156.62
+5.239.160.78
+5.239.229.90
+5.239.229.93
+5.239.229.141
+5.239.230.163
+5.239.231.128
+5.239.232.233
+5.239.234.104
+5.239.234.118
+5.239.234.251
+5.239.237.197
+5.239.240.243
+5.239.241.88
+10.20.35.250
+10.59.1.1
+10.87.91.58
+10.87.96.166
+10.87.97.70
+10.88.67.214
+10.101.97.90
+10.114.50.150
+10.114.50.206
+10.114.61.26
+10.114.123.38
+10.114.123.62
+10.114.141.78
+10.114.141.214
+10.114.143.50
+10.140.39.98
+10.176.254.22
+10.233.240.106
+10.239.1.71
+31.7.65.42
+31.7.65.43
+31.7.65.44
+31.7.65.46
+31.7.89.106
+31.7.89.126
+31.7.90.115
+31.24.201.82
+31.25.92.29
+31.25.92.100
+31.25.92.161
+31.25.129.114
+31.25.132.114
+31.25.135.146
+31.47.51.23
+31.47.51.149
+31.171.222.82
+31.184.141.30
+31.184.188.88
+37.32.47.176
+37.32.121.210
+37.32.121.225
+37.32.125.194
+37.75.244.6
+37.75.244.51
+37.75.245.24
+37.75.245.59
+37.75.245.130
+37.75.245.132
+37.75.245.133
+37.75.246.1
+37.75.246.50
+37.75.246.52
+37.75.246.53
+37.143.147.31
+37.148.0.71
+37.148.17.66
+37.148.25.167
+37.148.58.95
+37.148.81.211
+37.148.86.227
+37.152.164.50
+37.153.128.176
+37.153.130.55
+37.156.8.33
+37.156.8.85
+37.156.9.190
+37.156.11.70
+37.156.12.28
+37.156.13.215
+37.156.15.184
+37.156.15.246
+37.156.30.206
+37.156.144.81
+37.191.78.213
+37.191.78.214
+37.202.156.75
+37.202.156.98
+37.202.157.22
+37.202.170.112
+37.202.171.204
+37.202.189.21
+37.228.139.163
+37.228.139.164
+37.228.139.165
+37.228.139.166
+37.255.128.218
+37.255.128.220
+37.255.129.56
+37.255.132.26
+37.255.134.87
+37.255.134.143
+37.255.149.128
+37.255.149.221
+37.255.173.50
+37.255.176.18
+37.255.192.204
+37.255.195.143
+37.255.196.74
+37.255.196.175
+37.255.208.116
+37.255.210.1
+37.255.211.212
+37.255.213.72
+37.255.213.226
+37.255.217.2
+37.255.220.2
+37.255.220.101
+37.255.222.28
+37.255.222.121
+37.255.223.74
+37.255.226.13
+37.255.231.150
+37.255.235.76
+37.255.236.74
+37.255.238.0
+37.255.238.113
+37.255.238.136
+37.255.238.156
+37.255.240.167
+37.255.241.74
+37.255.242.142
+37.255.242.252
+37.255.255.243
+45.9.253.179
+45.87.4.91
+45.87.4.130
+45.94.212.5
+45.132.175.121
+45.135.241.251
+45.138.135.75
+45.142.191.27
+45.142.191.196
+45.142.191.197
+45.142.191.202
+45.142.191.203
+45.159.150.79
+46.32.31.195
+46.34.161.193
+46.34.166.142
+46.34.166.236
+46.51.37.142
+46.100.2.195
+46.100.3.123
+46.100.8.118
+46.100.10.122
+46.100.10.123
+46.100.10.237
+46.100.11.36
+46.100.11.103
+46.100.11.168
+46.100.32.107
+46.100.32.206
+46.100.33.20
+46.100.40.43
+46.100.41.93
+46.100.42.58
+46.100.45.65
+46.100.45.228
+46.100.45.234
+46.100.47.174
+46.100.49.96
+46.100.50.129
+46.100.52.76
+46.100.53.30
+46.100.53.68
+46.100.55.77
+46.100.56.65
+46.100.57.133
+46.100.58.82
+46.100.58.238
+46.100.59.62
+46.100.59.121
+46.100.60.8
+46.100.60.29
+46.100.60.125
+46.100.60.151
+46.100.61.40
+46.100.61.74
+46.100.61.171
+46.100.61.247
+46.100.62.89
+46.100.75.205
+46.100.92.38
+46.100.92.64
+46.100.93.209
+46.100.94.175
+46.100.99.218
+46.100.106.113
+46.100.116.237
+46.100.132.82
+46.100.132.250
+46.100.146.123
+46.100.147.227
+46.100.148.51
+46.100.149.144
+46.100.164.204
+46.100.165.3
+46.100.165.41
+46.100.165.154
+46.100.167.151
+46.100.167.203
+46.100.168.233
+46.100.169.22
+46.100.169.38
+46.100.169.142
+46.100.171.14
+46.100.171.105
+46.100.187.239
+46.100.196.108
+46.100.216.23
+46.100.219.91
+46.100.220.219
+46.100.220.225
+46.100.221.40
+46.100.221.85
+46.100.231.142
+46.100.243.137
+46.100.248.35
+46.102.130.37
+46.143.245.4
+46.148.34.220
+46.148.38.10
+46.148.38.19
+46.148.38.43
+46.148.39.101
+46.148.40.49
+46.148.43.190
+46.148.44.204
+46.167.133.214
+46.167.136.35
+46.167.140.202
+46.167.144.122
+46.167.144.253
+46.167.145.195
+46.167.147.150
+46.167.151.122
+46.167.151.238
+46.167.159.23
+46.209.22.231
+46.209.30.46
+46.209.44.2
+46.209.51.158
+46.209.106.204
+46.209.223.243
+46.209.255.243
+46.235.76.19
+46.235.77.78
+46.245.2.181
+46.245.12.52
+46.245.13.243
+46.245.14.45
+46.245.14.119
+46.245.15.57
+46.245.23.49
+46.245.26.167
+46.245.27.5
+46.245.31.147
+46.245.40.26
+46.245.43.146
+46.245.43.156
+46.245.45.95
+46.245.45.132
+46.245.46.94
+46.245.76.247
+46.245.76.249
+46.245.78.84
+46.245.78.86
+46.245.87.3
+46.245.89.48
+46.245.89.51
+46.245.89.52
+46.245.89.53
+46.245.89.55
+46.245.89.56
+46.245.89.57
+46.245.91.72
+46.245.91.73
+46.245.91.74
+46.245.91.75
+46.245.91.78
+46.245.91.80
+46.245.94.190
+46.245.114.114
+46.249.120.224
+46.249.120.227
+46.249.120.228
+46.249.120.244
+46.249.121.42
+46.249.121.227
+46.249.122.28
+46.249.122.86
+46.249.122.87
+46.249.122.90
+46.249.122.91
+46.249.124.1
+46.249.126.177
+62.60.162.236
+62.60.163.244
+62.60.207.217
+62.60.223.196
+62.220.112.249
+66.79.99.200
+66.79.112.89
+66.79.113.200
+77.36.146.37
+77.36.243.5
+77.81.34.180
+77.81.34.221
+77.81.35.43
+77.81.37.184
+77.81.40.10
+77.81.41.69
+77.81.46.254
+77.81.146.230
+77.81.147.29
+77.81.148.90
+77.81.148.172
+77.81.148.187
+77.81.150.212
+77.81.153.245
+77.81.154.53
+77.81.156.52
+77.81.158.150
+77.81.158.173
+77.81.158.250
+77.104.90.154
+77.104.93.43
+77.104.115.152
+77.104.115.161
+77.104.126.13
+77.104.126.136
+77.238.106.88
+77.238.106.108
+77.238.106.154
+77.238.107.79
+77.238.109.90
+78.38.26.128
+78.38.26.132
+78.38.26.134
+78.38.26.135
+78.38.26.151
+78.38.26.155
+78.38.26.159
+78.38.26.164
+78.38.26.181
+78.38.26.183
+78.38.26.188
+78.38.26.210
+78.38.26.226
+78.38.27.3
+78.38.29.31
+78.38.30.118
+78.38.34.90
+78.38.88.75
+78.38.89.48
+78.38.90.169
+78.38.91.170
+78.38.105.11
+78.38.110.82
+78.38.123.58
+78.38.126.189
+78.38.152.39
+78.38.153.189
+78.38.166.50
+78.38.166.161
+78.38.168.165
+78.38.169.230
+78.38.183.35
+78.38.194.203
+78.38.195.162
+78.38.195.168
+78.38.210.89
+78.38.210.119
+78.38.210.206
+78.38.217.110
+78.38.243.235
+78.39.11.74
+78.39.26.103
+78.39.28.149
+78.39.29.203
+78.39.29.208
+78.39.31.90
+78.39.57.167
+78.39.81.36
+78.39.83.6
+78.39.83.21
+78.39.83.133
+78.39.88.109
+78.39.88.157
+78.39.88.243
+78.39.89.85
+78.39.89.162
+78.39.90.151
+78.39.91.177
+78.39.91.192
+78.39.92.139
+78.39.93.201
+78.39.94.33
+78.39.94.34
+78.39.95.51
+78.39.97.3
+78.39.99.16
+78.39.99.18
+78.39.99.19
+78.39.99.20
+78.39.99.21
+78.39.99.22
+78.39.99.23
+78.39.99.114
+78.39.99.118
+78.39.112.154
+78.39.119.115
+78.39.119.205
+78.39.120.28
+78.39.120.135
+78.39.120.208
+78.39.122.39
+78.39.123.99
+78.39.123.105
+78.39.126.216
+78.39.134.132
+78.39.139.32
+78.39.140.106
+78.39.140.166
+78.39.142.2
+78.39.145.18
+78.39.173.132
+78.39.201.210
+78.39.228.64
+78.39.228.77
+78.39.231.68
+78.39.233.249
+78.39.234.58
+78.39.235.85
+78.39.250.120
+78.110.122.102
+78.157.34.223
+78.157.35.16
+78.157.35.31
+78.157.35.40
+78.157.37.240
+78.157.38.175
+78.157.39.84
+78.157.39.112
+78.157.39.127
+78.157.41.112
+78.157.41.120
+78.157.43.176
+78.157.43.183
+78.157.45.48
+78.157.45.136
+78.157.45.224
+78.157.45.231
+78.157.45.240
+78.157.45.247
+78.157.46.80
+78.157.47.115
+78.157.48.23
+78.157.48.127
+78.157.48.128
+78.157.50.23
+78.157.57.32
+78.157.57.60
+78.157.57.67
+78.157.57.194
+78.157.57.227
+78.157.57.237
+78.157.58.31
+78.157.58.36
+78.157.58.40
+78.157.58.168
+78.157.61.40
+78.158.191.228
+79.127.2.107
+79.127.3.107
+79.127.3.122
+79.127.4.41
+79.127.4.154
+79.127.5.25
+79.127.5.209
+79.127.6.78
+79.127.6.134
+79.127.6.165
+79.127.7.120
+79.127.13.189
+79.127.14.88
+79.127.69.121
+79.127.69.125
+79.127.75.51
+79.127.75.52
+79.127.75.54
+79.127.77.51
+79.127.77.52
+79.127.77.53
+79.127.77.54
+79.127.101.13
+79.127.125.18
+79.127.126.91
+79.175.182.42
+79.175.186.60
+79.175.186.61
+80.75.5.26
+80.75.8.70
+80.191.16.186
+80.191.17.246
+80.191.38.128
+80.191.39.11
+80.191.39.185
+80.191.40.137
+80.191.40.152
+80.191.51.51
+80.191.52.19
+80.191.64.104
+80.191.71.89
+80.191.71.136
+80.191.77.163
+80.191.86.234
+80.191.87.143
+80.191.100.159
+80.191.102.86
+80.191.107.5
+80.191.189.166
+80.191.192.249
+80.191.194.187
+80.191.195.227
+80.191.203.4
+80.191.220.134
+80.191.221.10
+80.191.222.119
+80.191.230.86
+80.191.235.130
+80.191.240.70
+80.191.250.61
+80.191.253.225
+80.210.6.100
+80.210.7.254
+80.210.8.120
+80.210.9.170
+80.210.9.226
+80.210.12.253
+80.210.17.204
+80.210.18.80
+80.210.18.226
+80.210.21.43
+80.210.22.3
+80.210.22.27
+80.210.22.73
+80.210.22.115
+80.210.22.181
+80.210.22.219
+80.210.24.197
+80.210.25.137
+80.210.26.129
+80.210.27.23
+80.210.30.51
+80.210.30.117
+80.210.32.0
+80.210.32.240
+80.210.35.177
+80.210.35.231
+80.210.37.24
+80.210.41.3
+80.210.41.114
+80.210.42.127
+80.210.42.186
+80.210.44.69
+80.210.45.21
+80.210.45.71
+80.210.48.164
+80.210.48.185
+80.210.50.88
+80.210.50.152
+80.210.50.199
+80.210.51.52
+80.210.52.182
+80.210.54.72
+80.210.58.171
+80.210.59.165
+80.210.60.166
+80.210.63.101
+80.210.139.23
+80.210.141.56
+80.210.160.201
+80.210.164.153
+80.210.183.27
+80.210.193.176
+80.210.196.185
+80.210.242.220
+80.210.245.84
+80.210.246.86
+80.244.11.2
+80.253.152.178
+80.253.152.180
+81.12.1.28
+81.12.5.227
+81.12.47.52
+81.12.70.146
+81.12.72.234
+81.12.74.5
+81.12.76.64
+81.12.76.65
+81.12.76.66
+81.12.76.67
+81.12.76.68
+81.12.76.69
+81.12.76.70
+81.12.76.71
+81.12.76.73
+81.12.76.74
+81.12.76.75
+81.12.76.77
+81.12.76.79
+81.12.84.247
+81.12.87.101
+81.12.99.218
+81.12.118.214
+81.12.124.117
+81.12.124.158
+81.12.127.50
+81.16.112.49
+81.16.112.111
+81.16.113.186
+81.16.114.44
+81.16.114.199
+81.16.117.49
+81.16.121.150
+81.16.121.241
+81.16.124.53
+81.16.124.73
+81.16.124.165
+81.16.125.185
+81.16.125.235
+81.16.126.254
+81.28.32.40
+81.28.33.58
+81.28.52.31
+81.28.61.73
+81.29.248.99
+81.29.248.100
+81.29.248.101
+81.29.248.102
+81.29.248.103
+81.29.248.104
+81.29.248.105
+81.29.248.107
+81.90.146.46
+81.91.136.210
+81.91.144.18
+81.91.146.22
+81.91.151.30
+81.91.152.222
+81.91.153.9
+81.91.155.78
+81.91.156.186
+81.91.157.178
+81.91.159.58
+81.163.6.45
+82.99.232.78
+82.99.253.49
+84.47.236.218
+84.47.236.242
+84.241.1.127
+84.241.2.181
+84.241.2.187
+84.241.3.56
+84.241.3.94
+84.241.3.202
+84.241.4.78
+84.241.5.178
+84.241.6.65
+84.241.6.132
+84.241.6.191
+84.241.6.244
+84.241.8.128
+84.241.8.189
+84.241.9.10
+84.241.12.44
+84.241.12.173
+84.241.12.174
+84.241.14.53
+84.241.14.215
+84.241.14.220
+84.241.14.228
+84.241.15.29
+84.241.15.191
+84.241.16.37
+84.241.16.46
+84.241.16.203
+84.241.16.229
+84.241.18.174
+84.241.18.236
+84.241.18.254
+84.241.19.114
+84.241.22.145
+84.241.23.155
+84.241.24.107
+84.241.24.201
+84.241.24.246
+84.241.25.93
+84.241.25.250
+84.241.26.234
+84.241.27.32
+84.241.27.173
+84.241.28.126
+84.241.28.170
+84.241.28.209
+84.241.29.33
+84.241.29.55
+84.241.29.213
+84.241.30.49
+84.241.30.140
+84.241.36.194
+84.241.38.77
+84.241.38.166
+84.241.41.13
+84.241.42.191
+84.241.44.145
+84.241.44.198
+84.241.45.83
+84.241.45.218
+84.241.49.40
+84.241.52.13
+84.241.52.15
+84.241.56.122
+84.241.60.91
+85.9.87.50
+85.9.87.51
+85.9.94.3
+85.9.94.229
+85.9.105.38
+85.9.105.41
+85.9.115.105
+85.9.120.237
+85.9.121.104
+85.9.122.69
+85.133.133.206
+85.133.136.202
+85.133.137.98
+85.133.173.138
+85.133.173.139
+85.133.173.141
+85.133.173.142
+85.133.176.48
+85.133.184.233
+85.133.186.106
+85.133.187.69
+85.133.190.170
+85.133.221.190
+85.133.221.191
+85.133.228.178
+85.133.229.121
+85.133.229.202
+85.185.3.100
+85.185.12.173
+85.185.13.60
+85.185.13.148
+85.185.14.43
+85.185.43.176
+85.185.43.224
+85.185.49.27
+85.185.54.100
+85.185.62.32
+85.185.75.218
+85.185.78.181
+85.185.81.226
+85.185.81.227
+85.185.85.6
+85.185.87.105
+85.185.88.134
+85.185.98.57
+85.185.111.80
+85.185.123.177
+85.185.133.193
+85.185.138.250
+85.185.139.34
+85.185.139.42
+85.185.185.172
+85.185.187.2
+85.185.190.109
+85.185.201.197
+85.185.201.198
+85.185.201.227
+85.185.201.230
+85.185.206.161
+85.185.208.82
+85.185.212.150
+85.185.235.18
+85.185.238.111
+85.185.239.154
+85.185.239.155
+85.185.239.157
+85.198.26.3
+85.198.28.2
+85.198.29.80
+85.198.30.54
+85.198.30.223
+85.198.31.15
+85.198.31.107
+85.198.31.113
+85.204.88.255
+85.204.208.159
+86.104.38.94
+86.104.83.86
+86.104.88.202
+86.104.96.231
+86.104.98.191
+86.104.98.195
+86.104.98.239
+86.104.100.245
+86.104.101.72
+86.104.105.166
+86.104.106.34
+86.104.107.4
+86.104.109.105
+86.104.111.197
+86.105.43.13
+86.105.44.251
+86.105.45.105
+86.105.46.122
+86.105.47.176
+86.105.134.249
+86.105.138.65
+86.107.93.69
+86.107.145.246
+86.107.148.66
+86.107.149.221
+86.107.152.218
+86.107.155.195
+86.107.155.228
+86.107.156.242
+86.107.157.82
+87.107.17.22
+87.107.18.26
+87.107.18.178
+87.107.18.180
+87.107.48.10
+87.107.55.66
+87.107.87.8
+87.107.87.9
+87.107.87.10
+87.107.87.11
+87.107.105.43
+87.107.105.145
+87.107.136.130
+87.107.141.35
+87.107.141.136
+87.236.38.97
+87.236.38.99
+87.236.38.226
+87.236.214.214
+87.236.215.179
+87.248.145.213
+87.248.150.229
+87.248.151.36
+87.251.141.125
+88.218.16.4
+89.32.197.10
+89.33.129.156
+89.37.152.90
+89.37.153.30
+89.37.153.57
+89.37.155.10
+89.37.155.119
+89.37.219.25
+89.38.103.224
+89.38.244.110
+89.38.246.130
+89.39.9.15
+89.39.9.200
+89.39.11.125
+89.39.11.190
+89.40.78.167
+89.40.79.39
+89.40.79.93
+89.40.79.94
+89.40.246.181
+89.40.247.32
+89.41.40.219
+89.41.41.95
+89.42.69.188
+89.42.98.141
+89.43.7.182
+89.43.144.209
+89.43.220.123
+89.43.222.29
+89.43.224.58
+89.43.224.123
+89.43.226.208
+89.43.227.25
+89.43.227.182
+89.43.230.205
+89.43.231.153
+89.44.132.254
+89.44.176.90
+89.46.95.145
+89.46.216.48
+89.46.216.49
+89.46.216.50
+89.46.216.51
+89.46.216.53
+89.46.218.208
+89.46.218.209
+89.46.218.210
+89.46.218.211
+89.46.218.212
+89.46.218.213
+89.46.218.214
+89.46.218.215
+89.46.219.39
+89.46.219.200
+89.46.219.201
+89.46.219.202
+89.46.219.203
+89.46.219.204
+89.46.219.205
+89.46.219.206
+89.46.219.207
+89.144.136.152
+89.144.148.155
+89.144.157.144
+89.144.157.219
+89.144.167.45
+89.219.64.165
+89.219.66.125
+89.219.68.58
+89.219.69.122
+89.219.69.188
+89.219.71.91
+89.219.71.206
+89.219.74.95
+89.219.74.246
+89.219.76.55
+89.219.76.168
+89.219.76.250
+89.219.76.253
+89.219.77.179
+89.219.78.137
+89.219.78.248
+89.219.79.28
+89.219.79.34
+89.219.81.20
+89.219.82.36
+89.219.82.192
+89.219.84.16
+89.219.88.172
+89.219.92.79
+89.219.95.236
+89.219.98.186
+89.219.102.81
+89.219.102.145
+89.219.102.228
+89.219.104.103
+89.219.105.36
+89.219.105.147
+89.219.105.208
+89.219.106.180
+89.219.106.245
+89.219.107.242
+89.219.108.30
+89.219.108.87
+89.219.108.119
+89.219.108.162
+89.219.114.19
+89.219.114.67
+89.219.116.81
+89.219.117.55
+89.219.118.124
+89.219.120.196
+89.219.121.97
+89.219.121.202
+89.219.122.163
+89.219.124.77
+89.219.124.182
+89.219.124.190
+89.219.125.219
+89.219.125.241
+89.219.195.28
+89.219.197.140
+89.219.198.174
+89.219.200.215
+89.219.202.170
+89.219.204.225
+89.219.205.242
+89.219.206.64
+89.219.206.217
+89.219.208.93
+89.219.209.192
+89.219.210.23
+89.219.210.59
+89.219.210.101
+89.219.211.41
+89.219.211.114
+89.219.211.122
+89.219.213.9
+89.219.215.18
+89.219.216.120
+89.219.219.5
+89.219.220.133
+89.219.224.139
+89.219.224.145
+89.219.225.30
+89.219.226.171
+89.219.227.18
+89.219.227.30
+89.219.229.128
+89.219.230.93
+89.219.235.240
+89.219.238.107
+89.219.240.85
+89.219.240.218
+89.219.241.130
+89.219.241.141
+89.219.244.22
+89.219.244.236
+89.219.246.68
+89.219.246.152
+89.219.246.183
+89.219.249.214
+89.219.251.90
+89.219.251.219
+89.219.251.248
+89.219.253.157
+89.219.254.24
+89.219.254.58
+89.221.84.53
+89.221.84.111
+89.221.85.46
+89.221.85.61
+89.221.85.149
+89.221.85.194
+89.221.85.206
+89.221.85.225
+89.221.85.235
+89.221.85.241
+89.221.85.242
+89.221.85.253
+89.221.86.62
+89.221.86.159
+89.221.86.186
+89.235.70.70
+89.235.102.11
+89.235.109.20
+91.92.121.161
+91.92.121.180
+91.92.121.214
+91.92.122.157
+91.92.125.104
+91.92.125.118
+91.92.125.195
+91.92.129.240
+91.92.130.175
+91.92.131.18
+91.92.131.52
+91.92.131.133
+91.92.133.152
+91.92.149.40
+91.92.150.170
+91.92.157.114
+91.92.157.168
+91.92.164.143
+91.92.180.196
+91.92.181.171
+91.92.181.193
+91.92.182.158
+91.92.185.37
+91.92.186.76
+91.92.186.135
+91.92.188.251
+91.92.191.47
+91.92.191.125
+91.92.205.45
+91.92.207.143
+91.92.207.179
+91.92.209.91
+91.92.212.107
+91.92.212.182
+91.92.214.181
+91.92.215.243
+91.106.67.30
+91.106.80.65
+91.106.80.127
+91.106.83.24
+91.106.83.29
+91.106.90.177
+91.106.94.136
+91.108.138.179
+91.108.150.42
+91.185.129.168
+91.185.130.76
+91.185.140.53
+91.185.141.74
+91.185.144.212
+91.185.147.40
+91.186.193.26
+91.186.193.57
+91.199.18.60
+91.222.206.170
+91.222.206.206
+91.232.72.92
+91.232.72.108
+91.232.72.116
+91.232.72.118
+91.232.72.126
+91.232.74.194
+91.234.39.83
+91.242.44.34
+91.243.165.178
+91.243.172.186
+92.114.17.4
+92.119.58.85
+92.119.58.126
+92.242.193.66
+92.242.206.6
+92.242.219.186
+92.246.144.29
+93.114.111.108
+93.114.111.175
+93.115.121.162
+93.115.125.255
+93.115.127.45
+93.115.144.17
+93.115.144.80
+93.115.145.41
+93.115.145.221
+93.115.145.237
+93.115.146.70
+93.115.146.140
+93.115.146.168
+93.115.146.217
+93.115.147.35
+93.115.147.60
+93.115.147.79
+93.115.147.92
+93.115.147.105
+93.115.147.149
+93.115.147.162
+93.115.148.33
+93.115.148.245
+93.115.149.187
+93.115.149.243
+93.115.219.124
+93.117.1.197
+93.117.32.98
+93.117.38.186
+93.117.41.59
+93.117.42.205
+93.117.127.64
+93.117.127.230
+93.118.96.209
+93.118.107.27
+93.118.107.167
+93.118.108.1
+93.118.108.20
+93.118.108.97
+93.118.108.201
+93.118.110.78
+93.118.114.252
+93.118.115.17
+93.118.116.160
+93.118.119.64
+93.118.119.238
+93.118.120.51
+93.118.120.135
+93.118.123.87
+93.118.124.218
+93.118.126.1
+93.118.127.126
+93.118.127.147
+93.118.127.234
+93.118.128.93
+93.118.128.173
+93.118.132.228
+93.118.136.52
+93.118.139.177
+93.118.139.247
+93.118.140.25
+93.118.140.163
+93.118.141.13
+93.118.141.183
+93.118.142.99
+93.118.142.181
+93.118.143.242
+93.118.145.14
+93.118.145.65
+93.118.146.80
+93.118.146.143
+93.118.146.178
+93.118.147.1
+93.118.148.211
+93.118.148.214
+93.118.150.2
+93.118.151.69
+93.118.151.170
+93.118.152.54
+93.118.152.147
+93.118.152.220
+93.118.153.212
+93.118.154.127
+93.118.156.8
+93.118.159.179
+93.118.160.4
+93.118.160.31
+93.118.161.97
+93.118.161.126
+93.118.162.200
+93.118.163.83
+93.118.163.99
+93.118.163.126
+93.118.163.166
+93.118.164.241
+93.118.166.232
+93.118.180.65
+93.126.7.16
+93.126.9.38
+93.126.10.1
+93.126.11.129
+93.126.12.160
+93.126.18.28
+93.126.18.95
+93.126.18.133
+93.126.19.141
+93.126.19.239
+93.126.25.34
+93.126.56.30
+94.101.133.19
+94.139.183.164
+94.182.2.70
+94.182.2.132
+94.182.2.222
+94.182.4.172
+94.182.5.199
+94.182.18.14
+94.182.18.209
+94.182.18.226
+94.182.23.57
+94.182.24.206
+94.182.27.105
+94.182.31.70
+94.182.31.129
+94.182.34.88
+94.182.35.165
+94.182.35.190
+94.182.35.249
+94.182.39.166
+94.182.48.5
+94.182.50.48
+94.182.53.166
+94.182.53.245
+94.182.56.16
+94.182.63.24
+94.182.94.190
+94.182.110.250
+94.182.189.29
+94.182.189.246
+94.182.192.210
+94.182.192.239
+94.182.193.14
+94.182.193.62
+94.182.193.89
+94.182.193.142
+94.182.193.197
+94.182.193.211
+94.182.194.132
+94.182.196.113
+94.182.196.165
+94.182.197.49
+94.182.197.50
+94.182.200.10
+94.182.202.193
+94.182.211.97
+94.182.211.247
+94.182.214.205
+94.182.216.18
+94.182.216.205
+94.182.225.225
+94.183.0.137
+94.183.0.195
+94.183.1.160
+94.183.6.134
+94.183.7.152
+94.183.7.159
+94.183.19.200
+94.183.21.110
+94.183.23.251
+94.183.24.50
+94.183.27.70
+94.183.27.128
+94.183.27.173
+94.183.27.209
+94.183.28.216
+94.183.30.24
+94.183.30.72
+94.183.30.131
+94.183.30.132
+94.183.30.162
+94.183.30.197
+94.183.31.117
+94.183.32.24
+94.183.32.107
+94.183.46.99
+94.183.60.235
+94.183.62.94
+94.183.62.120
+94.183.67.63
+94.183.67.107
+94.183.71.93
+94.183.72.37
+94.183.72.133
+94.183.75.164
+94.183.83.164
+94.183.85.12
+94.183.89.83
+94.183.90.176
+94.183.91.88
+94.183.91.145
+94.183.92.218
+94.183.93.40
+94.183.97.3
+94.183.97.61
+94.183.99.183
+94.183.102.135
+94.183.103.185
+94.183.109.61
+94.183.116.21
+94.183.118.4
+94.183.118.45
+94.183.121.12
+94.183.123.138
+94.183.124.229
+94.183.126.175
+94.183.127.101
+94.183.127.111
+94.183.127.124
+94.183.131.36
+94.183.133.129
+94.183.145.252
+94.183.149.144
+94.183.160.229
+94.183.172.67
+94.184.21.255
+94.184.178.254
+94.232.173.145
+94.232.175.245
+95.38.11.5
+95.38.33.72
+95.38.33.190
+95.38.34.61
+95.38.46.178
+95.38.48.195
+95.38.48.247
+95.38.49.44
+95.38.49.132
+95.38.49.150
+95.38.49.158
+95.38.52.10
+95.38.52.44
+95.38.52.224
+95.38.66.32
+95.38.66.42
+95.38.67.74
+95.38.67.163
+95.38.78.14
+95.38.132.238
+95.38.135.134
+95.38.143.22
+95.38.148.64
+95.38.149.46
+95.38.149.51
+95.38.149.96
+95.38.169.186
+95.38.192.58
+95.38.192.133
+95.38.192.135
+95.38.192.178
+95.38.196.157
+95.38.196.169
+95.38.196.202
+95.38.196.243
+95.38.199.230
+95.80.141.50
+95.80.168.237
+95.80.171.57
+95.80.175.41
+95.130.56.177
+95.130.59.34
+95.130.225.119
+95.130.225.124
+95.130.225.186
+95.130.225.229
+95.130.225.239
+95.130.225.241
+95.156.252.19
+95.215.160.179
+103.215.220.90
+109.72.197.58
+109.95.71.36
+109.109.44.37
+109.109.44.172
+109.109.52.175
+109.122.235.120
+109.122.237.78
+109.125.129.234
+109.125.130.85
+109.125.132.133
+109.125.132.208
+109.125.132.231
+109.125.134.92
+109.125.135.16
+109.125.140.186
+109.125.147.46
+109.125.160.46
+109.125.168.20
+109.201.13.188
+109.201.15.9
+109.230.82.114
+109.230.83.233
+109.230.89.157
+109.230.90.106
+109.230.90.174
+109.230.93.162
+109.230.94.222
+109.230.94.246
+109.230.204.66
+109.230.204.91
+109.230.204.154
+109.230.204.174
+109.230.204.175
+109.232.2.63
+109.238.189.4
+109.238.189.50
+128.65.176.22
+128.65.179.91
+128.65.180.193
+128.65.183.63
+128.65.184.21
+128.65.184.26
+128.65.184.184
+128.65.188.19
+128.65.188.30
+128.65.189.79
+151.232.3.161
+151.232.48.49
+151.232.60.225
+151.232.101.57
+151.232.207.122
+151.233.2.157
+151.233.18.251
+151.233.47.165
+151.233.50.228
+151.233.53.38
+151.233.58.9
+151.234.0.199
+151.234.1.48
+151.234.2.254
+151.234.3.120
+151.234.23.25
+151.234.28.19
+151.234.31.125
+151.234.31.243
+151.234.72.243
+151.234.87.99
+151.234.125.227
+151.234.187.125
+151.234.211.218
+151.234.245.230
+151.235.1.157
+151.235.6.95
+151.235.7.132
+151.235.8.27
+151.235.8.47
+151.235.23.185
+151.235.32.61
+151.235.35.236
+151.235.38.166
+151.235.91.218
+151.235.95.23
+151.235.98.215
+151.235.99.142
+151.235.99.169
+151.235.101.1
+151.235.101.23
+151.235.102.98
+151.235.106.149
+151.235.106.162
+151.235.107.85
+151.235.108.124
+151.235.109.61
+151.235.109.246
+151.235.110.118
+151.235.110.157
+151.235.111.147
+151.235.112.216
+151.235.114.9
+151.235.115.208
+151.235.118.241
+151.235.120.110
+151.235.121.214
+151.235.123.9
+151.235.126.249
+151.235.129.206
+151.235.134.175
+151.235.185.215
+151.235.187.44
+151.235.190.76
+151.235.217.72
+151.235.240.128
+151.235.246.224
+151.235.250.125
+159.20.96.249
+159.20.103.83
+159.20.111.37
+171.22.25.51
+172.16.13.26
+172.17.0.6
+172.18.0.10
+172.18.10.2
+172.19.20.158
+172.19.190.190
+172.19.216.36
+172.20.1.206
+172.20.30.2
+172.21.113.129
+172.22.0.38
+172.22.11.2
+172.22.22.30
+172.24.206.228
+172.24.209.36
+172.30.7.170
+172.30.8.30
+172.31.100.245
+176.65.184.254
+176.65.224.62
+176.65.226.105
+176.65.226.111
+176.65.227.214
+176.65.228.94
+176.65.231.45
+176.65.241.43
+176.65.241.44
+176.65.241.45
+176.65.241.46
+176.65.252.69
+176.65.252.81
+176.65.252.227
+176.65.253.46
+176.65.253.55
+176.65.253.106
+176.65.253.200
+176.65.254.61
+176.65.254.112
+176.65.254.160
+176.122.210.113
+176.223.80.171
+176.223.83.46
+178.131.66.247
+178.131.72.214
+178.131.101.153
+178.131.113.81
+178.131.134.93
+178.131.135.230
+178.173.131.62
+178.173.131.163
+178.173.131.188
+178.173.137.44
+178.173.137.132
+178.173.137.249
+178.173.137.251
+178.173.138.33
+178.173.138.59
+178.173.138.157
+178.173.138.171
+178.173.138.255
+178.173.139.95
+178.173.140.171
+178.173.141.90
+178.173.143.103
+178.173.143.116
+178.173.143.161
+178.173.146.129
+178.173.147.73
+178.173.147.227
+178.173.161.10
+178.173.163.7
+178.173.163.158
+178.173.163.202
+178.173.169.16
+178.173.169.199
+178.173.169.228
+178.173.170.142
+178.173.173.88
+178.173.173.255
+178.173.174.48
+178.173.174.136
+178.173.174.229
+178.173.175.6
+178.173.175.56
+178.173.175.110
+178.173.175.152
+178.173.175.209
+178.173.182.45
+178.173.182.72
+178.173.182.87
+178.173.182.148
+178.173.182.177
+178.173.184.37
+178.173.184.112
+178.173.184.122
+178.173.185.11
+178.173.185.49
+178.173.185.86
+178.173.185.222
+178.173.185.241
+178.173.192.30
+178.173.193.32
+178.173.193.54
+178.173.193.77
+178.173.193.82
+178.173.195.75
+178.173.195.203
+178.173.196.39
+178.173.196.161
+178.173.197.84
+178.173.197.192
+178.173.197.228
+178.173.198.82
+178.173.198.112
+178.173.198.238
+178.173.199.32
+178.173.199.53
+178.173.199.105
+178.173.199.109
+178.173.199.113
+178.173.199.200
+178.173.200.68
+178.173.210.19
+178.173.210.29
+178.173.210.152
+178.173.210.176
+178.173.211.216
+178.173.212.43
+178.173.212.126
+178.173.212.209
+178.173.213.152
+178.173.213.211
+178.173.213.226
+178.173.214.151
+178.173.214.164
+178.173.215.117
+178.173.215.158
+178.173.215.208
+178.173.215.210
+178.173.216.5
+178.173.216.75
+178.173.216.112
+178.173.217.59
+178.173.218.46
+178.173.219.53
+178.173.219.114
+178.173.220.21
+178.173.220.47
+178.173.220.206
+178.173.221.227
+178.173.222.165
+178.236.98.110
+178.236.99.12
+178.236.99.239
+178.236.100.37
+178.236.103.15
+178.236.103.18
+178.236.103.127
+178.236.104.163
+178.236.105.85
+178.236.105.154
+178.236.106.237
+178.236.107.152
+178.236.108.124
+178.236.111.3
+178.236.111.114
+178.238.195.238
+178.239.144.40
+178.239.156.36
+178.239.156.113
+178.239.156.130
+178.239.156.133
+178.239.157.98
+178.239.157.100
+178.239.157.101
+178.239.157.102
+178.239.157.103
+178.239.157.104
+178.252.141.229
+178.252.147.125
+178.252.151.158
+178.252.152.72
+178.252.153.250
+178.252.171.227
+178.252.171.230
+178.252.177.32
+178.252.177.33
+178.252.177.35
+178.252.177.36
+178.252.177.37
+178.252.177.38
+178.252.177.39
+178.252.177.40
+178.252.177.42
+178.252.177.43
+178.252.177.44
+178.252.177.45
+185.3.201.0
+185.3.201.1
+185.3.201.2
+185.3.201.3
+185.3.201.4
+185.3.201.5
+185.3.201.6
+185.3.201.7
+185.3.201.8
+185.3.201.9
+185.3.201.10
+185.3.201.11
+185.3.201.12
+185.3.201.13
+185.3.201.14
+185.3.201.15
+185.3.201.16
+185.3.201.17
+185.3.201.18
+185.3.201.19
+185.3.201.20
+185.3.201.21
+185.3.201.22
+185.3.201.23
+185.3.201.24
+185.3.201.25
+185.3.201.26
+185.3.201.27
+185.3.201.28
+185.3.201.29
+185.3.201.31
+185.3.201.32
+185.3.201.33
+185.3.201.35
+185.3.201.36
+185.3.201.38
+185.3.201.40
+185.3.201.41
+185.3.201.42
+185.3.201.43
+185.3.201.44
+185.3.201.45
+185.3.201.46
+185.3.201.47
+185.3.201.48
+185.3.201.49
+185.3.201.51
+185.3.201.52
+185.3.201.53
+185.3.201.55
+185.3.201.56
+185.3.201.57
+185.3.201.58
+185.3.201.59
+185.3.201.60
+185.3.201.61
+185.3.201.62
+185.3.201.63
+185.3.201.64
+185.3.201.65
+185.3.201.66
+185.3.201.67
+185.3.201.68
+185.3.201.69
+185.3.201.70
+185.3.201.71
+185.3.201.72
+185.3.201.73
+185.3.201.74
+185.3.201.75
+185.3.201.76
+185.3.201.77
+185.3.201.78
+185.3.201.79
+185.3.201.80
+185.3.201.81
+185.3.201.82
+185.3.201.83
+185.3.201.84
+185.3.201.85
+185.3.201.86
+185.3.201.87
+185.3.201.88
+185.3.201.89
+185.3.201.90
+185.3.201.91
+185.3.201.92
+185.3.201.93
+185.3.201.94
+185.3.201.95
+185.3.201.96
+185.3.201.97
+185.3.201.98
+185.3.201.99
+185.3.201.100
+185.3.201.101
+185.3.201.102
+185.3.201.103
+185.3.201.104
+185.3.201.105
+185.3.201.106
+185.3.201.107
+185.3.201.109
+185.3.201.112
+185.3.201.114
+185.3.201.115
+185.3.201.116
+185.3.201.117
+185.3.201.118
+185.3.201.120
+185.3.201.121
+185.3.201.122
+185.3.201.123
+185.3.201.124
+185.3.201.125
+185.3.201.126
+185.3.201.127
+185.3.201.129
+185.3.201.130
+185.3.201.131
+185.3.201.132
+185.3.201.133
+185.3.201.134
+185.3.201.135
+185.3.202.0
+185.3.202.1
+185.3.202.2
+185.3.202.8
+185.3.202.10
+185.3.202.11
+185.3.202.12
+185.3.202.13
+185.3.202.15
+185.3.202.16
+185.3.202.17
+185.3.202.18
+185.3.202.19
+185.3.202.20
+185.3.202.21
+185.3.202.22
+185.3.202.23
+185.3.202.24
+185.3.202.27
+185.3.202.28
+185.3.202.29
+185.3.202.30
+185.3.202.31
+185.3.202.32
+185.3.202.33
+185.3.202.34
+185.3.202.35
+185.3.202.37
+185.3.202.38
+185.3.202.39
+185.3.202.40
+185.3.202.41
+185.3.202.43
+185.3.202.44
+185.3.202.45
+185.3.202.47
+185.3.202.48
+185.3.202.49
+185.3.202.50
+185.3.202.51
+185.3.202.52
+185.3.202.53
+185.3.202.54
+185.3.202.55
+185.3.202.56
+185.3.202.58
+185.3.202.60
+185.3.202.61
+185.3.202.62
+185.3.202.64
+185.3.202.65
+185.3.202.66
+185.3.202.67
+185.3.202.68
+185.3.202.69
+185.3.202.70
+185.3.202.71
+185.3.202.73
+185.3.202.75
+185.3.202.76
+185.3.202.77
+185.3.202.78
+185.3.202.79
+185.3.202.81
+185.3.202.82
+185.3.202.83
+185.3.202.84
+185.3.202.85
+185.3.202.86
+185.3.202.88
+185.3.202.89
+185.3.202.90
+185.3.202.91
+185.3.202.92
+185.3.202.93
+185.3.202.94
+185.3.202.95
+185.3.202.97
+185.3.202.98
+185.3.202.101
+185.3.202.102
+185.3.202.103
+185.3.202.104
+185.3.202.105
+185.3.202.106
+185.3.202.107
+185.3.202.109
+185.3.202.110
+185.3.202.111
+185.3.202.112
+185.3.202.113
+185.3.202.114
+185.3.202.117
+185.3.202.118
+185.3.202.119
+185.3.202.120
+185.3.202.121
+185.3.202.122
+185.3.202.123
+185.3.202.124
+185.3.202.126
+185.3.202.127
+185.3.202.128
+185.3.202.130
+185.3.202.131
+185.3.202.132
+185.3.202.133
+185.3.202.134
+185.3.202.135
+185.3.202.136
+185.3.202.137
+185.3.202.138
+185.3.202.139
+185.3.202.140
+185.3.202.141
+185.3.202.142
+185.3.202.145
+185.3.202.146
+185.3.202.147
+185.3.202.149
+185.3.202.150
+185.3.202.151
+185.3.202.152
+185.3.202.153
+185.3.202.155
+185.3.202.156
+185.3.202.157
+185.3.202.161
+185.3.202.163
+185.3.202.164
+185.3.202.165
+185.3.202.166
+185.3.202.167
+185.3.202.168
+185.3.202.169
+185.3.202.170
+185.3.202.171
+185.3.202.173
+185.3.202.175
+185.3.202.176
+185.3.202.177
+185.3.202.178
+185.3.202.179
+185.3.202.181
+185.3.202.182
+185.3.202.183
+185.3.202.185
+185.3.202.186
+185.3.202.189
+185.3.202.190
+185.3.202.191
+185.3.202.192
+185.3.202.194
+185.3.202.195
+185.3.202.196
+185.3.202.197
+185.3.202.198
+185.3.202.199
+185.3.202.200
+185.3.202.201
+185.3.202.202
+185.3.202.203
+185.3.202.204
+185.3.202.205
+185.3.202.206
+185.3.202.207
+185.3.202.208
+185.3.202.209
+185.3.202.210
+185.3.202.211
+185.3.202.212
+185.3.202.213
+185.3.202.214
+185.3.202.215
+185.3.202.217
+185.3.202.218
+185.3.202.219
+185.3.202.220
+185.3.202.222
+185.3.202.224
+185.3.202.225
+185.3.202.226
+185.3.202.227
+185.3.202.228
+185.3.202.229
+185.3.202.230
+185.3.202.231
+185.3.202.232
+185.3.202.233
+185.3.202.234
+185.3.202.235
+185.3.202.236
+185.3.202.237
+185.3.202.238
+185.3.202.239
+185.3.202.240
+185.3.202.241
+185.3.202.242
+185.3.202.243
+185.3.202.244
+185.3.202.245
+185.3.202.246
+185.3.202.247
+185.3.202.248
+185.3.202.249
+185.3.202.250
+185.3.202.252
+185.3.202.253
+185.3.202.254
+185.3.203.8
+185.3.203.9
+185.3.203.11
+185.3.203.13
+185.3.203.15
+185.3.203.36
+185.3.203.37
+185.3.203.38
+185.3.203.39
+185.3.203.40
+185.3.203.41
+185.3.203.42
+185.3.203.43
+185.3.203.44
+185.3.203.45
+185.3.203.46
+185.3.203.48
+185.3.203.50
+185.3.203.51
+185.3.203.52
+185.3.203.53
+185.3.203.54
+185.3.203.57
+185.3.203.60
+185.3.203.61
+185.3.203.62
+185.3.203.64
+185.3.203.65
+185.3.203.66
+185.3.203.67
+185.3.203.69
+185.3.203.70
+185.3.203.71
+185.3.203.72
+185.3.203.73
+185.3.203.74
+185.3.203.75
+185.3.203.76
+185.3.203.78
+185.3.203.79
+185.3.203.80
+185.3.203.81
+185.3.203.82
+185.3.203.83
+185.3.203.86
+185.3.203.87
+185.3.203.88
+185.3.203.89
+185.3.203.90
+185.3.203.94
+185.3.203.95
+185.3.203.96
+185.3.203.97
+185.3.203.98
+185.3.203.99
+185.3.203.101
+185.3.203.103
+185.3.203.104
+185.3.203.105
+185.3.203.106
+185.3.203.107
+185.3.203.108
+185.3.203.109
+185.3.203.110
+185.3.203.111
+185.3.203.113
+185.3.203.114
+185.3.203.115
+185.3.203.116
+185.3.203.119
+185.3.203.120
+185.3.203.121
+185.3.203.122
+185.3.203.123
+185.3.203.124
+185.3.203.125
+185.3.203.127
+185.14.80.238
+185.18.213.184
+185.20.163.2
+185.21.68.25
+185.22.31.186
+185.42.225.202
+185.42.225.203
+185.42.226.217
+185.44.113.194
+185.46.108.90
+185.46.108.100
+185.46.110.117
+185.46.218.30
+185.46.218.233
+185.49.96.145
+185.49.97.109
+185.49.97.238
+185.53.141.35
+185.53.143.185
+185.56.92.177
+185.56.93.73
+185.56.93.121
+185.66.226.12
+185.66.228.17
+185.71.195.160
+185.72.27.113
+185.72.27.114
+185.72.27.182
+185.72.80.60
+185.72.81.119
+185.83.88.119
+185.83.88.208
+185.83.182.89
+185.83.196.247
+185.86.183.33
+185.86.183.217
+185.92.41.251
+185.100.45.101
+185.100.47.205
+185.103.87.182
+185.103.129.198
+185.103.131.129
+185.106.137.91
+185.106.138.219
+185.106.146.146
+185.109.60.222
+185.109.63.58
+185.109.63.59
+185.109.63.60
+185.109.63.61
+185.109.63.146
+185.109.80.243
+185.109.251.165
+185.110.219.78
+185.110.219.88
+185.110.253.9
+185.111.81.2
+185.112.36.123
+185.112.36.172
+185.112.36.255
+185.112.37.174
+185.112.38.213
+185.112.39.14
+185.112.39.30
+185.112.39.181
+185.115.150.52
+185.115.169.71
+185.115.169.95
+185.115.169.101
+185.115.169.104
+185.115.169.193
+185.115.169.220
+185.117.139.165
+185.117.139.168
+185.117.139.169
+185.117.139.173
+185.119.164.1
+185.120.219.38
+185.120.230.33
+185.120.237.47
+185.120.238.5
+185.121.129.166
+185.126.2.134
+185.126.4.33
+185.126.6.3
+185.126.10.9
+185.126.10.33
+185.126.11.241
+185.128.138.138
+185.129.199.5
+185.129.199.129
+185.129.199.201
+185.129.216.1
+185.129.216.115
+185.129.216.151
+185.129.217.142
+185.131.30.5
+185.131.30.145
+185.131.30.163
+185.131.30.246
+185.131.103.238
+185.132.80.141
+185.132.80.188
+185.134.99.46
+185.136.174.247
+185.136.192.65
+185.136.194.35
+185.136.194.37
+185.136.194.40
+185.136.194.41
+185.136.194.234
+185.137.25.75
+185.137.25.208
+185.137.108.87
+185.141.36.130
+185.141.39.45
+185.142.95.10
+185.145.184.159
+185.147.40.12
+185.147.41.75
+185.147.41.88
+185.147.161.27
+185.147.161.30
+185.155.10.129
+185.155.10.178
+185.155.10.202
+185.155.11.23
+185.155.14.246
+185.155.15.164
+185.161.39.174
+185.161.112.1
+185.161.112.5
+185.161.112.8
+185.161.112.38
+185.161.112.41
+185.161.114.190
+185.162.42.113
+185.164.73.155
+185.169.20.113
+185.170.239.185
+185.172.2.162
+185.172.68.18
+185.172.68.66
+185.172.68.98
+185.172.68.100
+185.172.68.101
+185.172.68.103
+185.172.68.246
+185.172.71.115
+185.172.213.123
+185.174.132.180
+185.174.132.243
+185.176.59.227
+185.177.158.84
+185.177.159.231
+185.179.168.242
+185.179.171.216
+185.180.130.229
+185.180.131.223
+185.191.76.116
+185.191.76.119
+185.191.78.184
+185.193.209.34
+185.193.209.35
+185.193.209.36
+185.193.209.39
+185.193.209.40
+185.193.209.41
+185.193.209.42
+185.193.209.43
+185.193.209.46
+185.208.148.19
+185.213.165.116
+185.221.194.141
+185.221.194.214
+185.224.177.117
+185.224.179.59
+185.225.80.200
+185.225.83.200
+185.225.243.82
+185.225.243.85
+185.225.243.92
+185.225.243.93
+185.229.31.60
+185.235.197.122
+185.235.197.210
+185.235.197.218
+185.237.84.18
+185.237.87.97
+185.237.87.228
+185.255.208.31
+185.255.210.156
+185.255.210.160
+185.255.210.168
+185.255.210.194
+188.0.252.93
+188.75.64.118
+188.75.65.218
+188.75.65.219
+188.75.65.220
+188.75.65.221
+188.121.128.138
+188.121.129.219
+188.121.144.154
+188.121.145.94
+188.121.147.246
+188.121.150.39
+188.121.157.50
+188.121.159.178
+188.136.133.81
+188.136.133.82
+188.136.133.83
+188.136.142.185
+188.136.143.166
+188.136.144.98
+188.136.144.109
+188.136.152.9
+188.136.152.15
+188.136.152.100
+188.136.156.1
+188.136.156.2
+188.136.156.3
+188.136.156.4
+188.136.156.6
+188.136.156.9
+188.136.156.15
+188.136.156.18
+188.136.156.20
+188.136.156.21
+188.136.156.22
+188.136.156.23
+188.136.156.24
+188.136.156.26
+188.136.156.27
+188.136.156.28
+188.136.156.29
+188.136.162.118
+188.136.172.48
+188.136.174.223
+188.136.194.198
+188.136.208.249
+188.208.57.96
+188.208.57.189
+188.208.62.218
+188.209.9.21
+188.209.9.46
+188.209.14.56
+188.209.14.143
+188.209.14.176
+188.209.24.18
+188.209.24.179
+188.209.36.183
+188.209.39.46
+188.209.41.118
+188.209.43.141
+188.209.44.22
+188.209.44.25
+188.209.64.53
+188.209.64.97
+188.209.65.5
+188.209.65.16
+188.209.66.78
+188.209.70.28
+188.209.71.132
+188.209.75.85
+188.209.77.106
+188.209.79.35
+188.209.79.214
+188.210.80.12
+188.210.80.133
+188.210.82.71
+188.210.83.33
+188.210.85.91
+188.210.85.158
+188.210.85.198
+188.210.85.235
+188.210.86.7
+188.210.86.167
+188.210.87.171
+188.210.87.228
+188.210.97.73
+188.210.102.225
+188.210.103.74
+188.210.104.175
+188.210.110.19
+188.210.112.48
+188.210.112.62
+188.210.112.148
+188.210.113.85
+188.210.118.27
+188.210.120.214
+188.210.121.198
+188.210.123.34
+188.210.153.243
+188.210.160.92
+188.210.173.224
+188.211.32.154
+188.211.36.157
+188.211.48.173
+188.211.53.136
+188.211.53.150
+188.211.57.184
+188.211.59.63
+188.211.61.93
+188.211.61.110
+188.211.61.148
+188.211.62.19
+188.211.63.80
+188.211.66.239
+188.211.69.229
+188.211.74.122
+188.211.74.173
+188.211.74.230
+188.211.77.214
+188.211.78.196
+188.211.80.11
+188.211.81.41
+188.211.81.72
+188.211.82.229
+188.211.84.82
+188.211.84.110
+188.211.86.57
+188.211.86.140
+188.211.86.142
+188.211.87.47
+188.211.92.127
+188.211.95.111
+188.211.100.21
+188.211.100.255
+188.211.104.251
+188.211.106.164
+188.211.108.44
+188.211.109.83
+188.211.111.253
+188.211.114.45
+188.211.118.152
+188.211.119.147
+188.211.121.217
+188.211.123.8
+188.211.123.252
+188.211.124.104
+188.211.124.169
+188.211.124.189
+188.211.125.201
+188.211.127.59
+188.212.73.15
+188.212.81.13
+188.212.82.127
+188.212.85.27
+188.212.90.17
+188.212.144.128
+188.212.144.224
+188.212.145.97
+188.212.145.143
+188.212.148.5
+188.212.149.44
+188.212.245.103
+188.213.147.209
+188.213.148.89
+188.213.150.39
+188.213.155.38
+188.213.157.159
+188.213.158.155
+188.213.159.229
+188.213.177.216
+188.213.181.60
+188.213.183.209
+188.213.185.56
+188.213.188.237
+188.213.209.185
+188.214.187.38
+188.240.212.0
+188.240.212.1
+188.240.212.2
+188.240.212.3
+188.240.212.48
+188.240.212.49
+188.240.212.50
+188.240.212.51
+188.240.212.52
+188.240.212.53
+188.240.212.54
+188.240.212.55
+188.240.254.107
+192.168.100.2
+192.168.114.38
+192.168.160.66
+192.168.230.180
+193.24.120.212
+193.56.61.180
+193.134.100.5
+193.134.100.6
+193.134.100.7
+193.134.100.8
+193.134.100.9
+193.134.100.10
+193.134.100.11
+193.134.100.26
+193.134.100.27
+193.134.100.116
+193.134.100.117
+193.134.100.118
+193.151.157.201
+193.200.148.28
+193.200.148.79
+193.228.91.116
+193.228.168.209
+193.228.169.115
+193.228.169.116
+193.228.169.165
+194.9.56.64
+194.9.57.12
+194.9.57.139
+194.33.105.89
+194.36.174.129
+194.60.231.237
+194.147.164.139
+194.147.165.188
+194.150.68.122
+194.150.70.218
+194.150.70.219
+194.150.70.221
+194.150.71.157
+194.225.101.4
+194.225.101.8
+194.225.101.10
+194.225.101.23
+194.225.101.25
+194.225.101.28
+194.225.101.29
+194.225.101.33
+194.225.136.233
+194.225.149.241
+195.8.114.144
+195.88.189.60
+195.146.59.174
+195.146.59.175
+195.181.1.32
+195.181.3.10
+195.181.11.166
+195.181.11.227
+195.181.13.168
+195.181.26.210
+195.181.27.26
+195.181.27.67
+195.181.30.106
+195.181.30.206
+195.181.37.54
+195.181.39.210
+195.181.40.4
+195.181.40.5
+195.181.58.162
+195.181.86.242
+195.181.114.229
+212.16.64.129
+212.16.86.176
+212.33.210.119
+212.33.218.42
+212.80.19.122
+212.80.19.137
+212.86.73.128
+212.86.75.15
+212.86.94.173
+212.120.194.186
+212.120.196.162
+212.120.198.180
+212.120.199.78
+212.120.200.252
+212.120.215.52
+212.120.216.120
+212.120.220.62
+212.120.222.90
+212.120.223.134
+213.109.199.99
+213.109.248.89
+213.109.248.198
+213.109.250.70
+213.109.251.121
+213.109.251.128
+213.176.122.52
+213.176.122.93
+213.195.56.65
+213.207.204.105
+213.207.204.106
+217.11.27.141
+217.11.27.142
+217.11.29.254
+217.24.144.199
+217.24.148.89
+217.24.152.78
+217.24.155.243
+217.24.157.45
+217.60.241.77
+217.66.213.130
+217.146.222.230
+217.170.246.241
+217.170.251.124
+217.170.254.224
+217.170.254.225
+217.170.254.239
+217.170.255.2
+217.172.104.107
+217.172.104.155
+217.172.105.44
+217.172.105.112
+217.172.107.99
+217.172.110.58
+217.172.124.7
+217.218.33.138
+217.218.33.139
+217.218.44.62
+217.218.56.114
+217.218.60.89
+217.218.60.95
+217.218.65.22
+217.218.68.93
+217.218.72.159
+217.218.77.64
+217.218.87.32
+217.218.88.43
+217.218.118.210
+217.218.121.141
+217.218.121.183
+217.218.125.178
+217.218.126.239
+217.218.129.118
+217.218.137.200
+217.218.138.96
+217.218.164.81
+217.218.194.163
+217.218.195.27
+217.218.219.157
+217.218.223.149
+217.218.224.38
+217.218.224.212
+217.218.229.234
+217.218.229.236
+217.218.231.95
+217.218.235.107
+217.218.242.10
+217.218.248.213
+217.218.253.81
+217.219.27.59
+217.219.31.73
+217.219.34.42
+217.219.34.49
+217.219.35.99
+217.219.39.119
+217.219.45.4
+217.219.45.18
+217.219.45.19
+217.219.66.192
+217.219.66.194
+217.219.66.195
+217.219.66.196
+217.219.66.231
+217.219.66.233
+217.219.66.234
+217.219.66.235
+217.219.66.236
+217.219.66.237
+217.219.66.238
+217.219.66.239
+217.219.71.186
+217.219.71.190
+217.219.72.11
+217.219.75.225
+217.219.81.66
+217.219.82.195
+217.219.113.141
+217.219.131.139
+217.219.146.65
+217.219.146.71
+217.219.146.72
+217.219.146.74
+217.219.146.117
+217.219.156.146
+217.219.163.2
+217.219.163.12
+217.219.163.20
+217.219.163.22
+217.219.163.29
+217.219.163.58
+217.219.163.151
+217.219.163.162
+217.219.163.173
+217.219.173.237
+217.219.199.51
+217.219.213.28
+217.219.213.125
+217.219.221.147
+217.219.222.194
+217.219.224.130
+217.219.236.215
+217.219.237.17
+217.219.238.116
+217.219.239.69
+217.219.242.142
+217.219.242.195
+217.219.245.124
+217.219.245.171
\ No newline at end of file
diff --git a/cmd/internal/build_libbox/main.go b/cmd/internal/build_libbox/main.go
index c128216932..0f914499e0 100644
--- a/cmd/internal/build_libbox/main.go
+++ b/cmd/internal/build_libbox/main.go
@@ -204,6 +204,9 @@ func buildApple() {
"-target", bindTarget,
"-libname=box",
"-tags-not-macos=with_low_memory",
+ "-iosversion=15.0",
+ "-macosversion=13.0",
+ "-tvosversion=17.0",
}
//if !withTailscale {
// args = append(args, "-tags-macos="+strings.Join(memcTags, ","))
diff --git a/cmd/internal/update_certificates/main.go b/cmd/internal/update_certificates/main.go
index 03323c0661..d19eb7f1cb 100644
--- a/cmd/internal/update_certificates/main.go
+++ b/cmd/internal/update_certificates/main.go
@@ -43,11 +43,8 @@ func updateMozillaIncludedRootCAs() error {
package certificate
-import "crypto/x509"
-
-func newMozillaIncluded() *x509.CertPool {
- pool := x509.NewCertPool()
-`)
+func mozillaIncludedPEM() string {
+ return ` + "`")
for {
record, err := reader.Read()
if err == io.EOF {
@@ -58,17 +55,14 @@ func newMozillaIncluded() *x509.CertPool {
if record[geoIndex] == "China" {
continue
}
- generated.WriteString("\n // ")
+ cert := strings.Trim(record[certIndex], "'")
+ generated.WriteString("\n// ")
generated.WriteString(record[nameIndex])
generated.WriteString("\n")
- generated.WriteString(" pool.AppendCertsFromPEM([]byte(`")
- cert := record[certIndex]
- // Remove single quotes
- cert = cert[1 : len(cert)-1]
generated.WriteString(cert)
- generated.WriteString("`))\n")
+ generated.WriteString("\n")
}
- generated.WriteString("\treturn pool\n}\n")
+ generated.WriteString("`\n}\n")
return os.WriteFile("common/certificate/mozilla.go", []byte(generated.String()), 0o644)
}
@@ -127,11 +121,8 @@ func updateChromeIncludedRootCAs() error {
package certificate
-import "crypto/x509"
-
-func newChromeIncluded() *x509.CertPool {
- pool := x509.NewCertPool()
-`)
+func chromeIncludedPEM() string {
+ return ` + "`")
for {
record, err := reader.Read()
if err == io.EOF {
@@ -145,18 +136,13 @@ func newChromeIncluded() *x509.CertPool {
if chinaFingerprints[record[fingerprintIndex]] {
continue
}
- generated.WriteString("\n // ")
+ cert := strings.Trim(record[certIndex], "'")
+ generated.WriteString("\n// ")
generated.WriteString(record[subjectIndex])
generated.WriteString("\n")
- generated.WriteString(" pool.AppendCertsFromPEM([]byte(`")
- cert := record[certIndex]
- // Remove single quotes if present
- if len(cert) > 0 && cert[0] == '\'' {
- cert = cert[1 : len(cert)-1]
- }
generated.WriteString(cert)
- generated.WriteString("`))\n")
+ generated.WriteString("\n")
}
- generated.WriteString("\treturn pool\n}\n")
+ generated.WriteString("`\n}\n")
return os.WriteFile("common/certificate/chrome.go", []byte(generated.String()), 0o644)
}
diff --git a/cmd/sing-box/cmd_format.go b/cmd/sing-box/cmd_format.go
index ab59c9ae5d..a8ecb6ab72 100644
--- a/cmd/sing-box/cmd_format.go
+++ b/cmd/sing-box/cmd_format.go
@@ -38,10 +38,12 @@ func format() error {
return err
}
for _, optionsEntry := range optionsList {
+ comments := optionsEntry.options.Comments()
optionsEntry.options, err = badjson.Omitempty(globalCtx, optionsEntry.options)
if err != nil {
return err
}
+ optionsEntry.options.SetComments(comments)
buffer := new(bytes.Buffer)
encoder := json.NewEncoder(buffer)
encoder.SetIndent("", " ")
diff --git a/cmd/sing-box/cmd_rule_set_compile.go b/cmd/sing-box/cmd_rule_set_compile.go
index 73655b12ea..e2cbefc7bf 100644
--- a/cmd/sing-box/cmd_rule_set_compile.go
+++ b/cmd/sing-box/cmd_rule_set_compile.go
@@ -82,6 +82,11 @@ func compileRuleSet(sourcePath string) error {
}
func downgradeRuleSetVersion(version uint8, options option.PlainRuleSet) uint8 {
+ if version == C.RuleSetVersion5 && !rule.HasHeadlessRule(options.Rules, func(rule option.DefaultHeadlessRule) bool {
+ return len(rule.PackageNameRegex) > 0
+ }) {
+ version = C.RuleSetVersion4
+ }
if version == C.RuleSetVersion4 && !rule.HasHeadlessRule(options.Rules, func(rule option.DefaultHeadlessRule) bool {
return rule.NetworkInterfaceAddress != nil && rule.NetworkInterfaceAddress.Size() > 0 ||
len(rule.DefaultInterfaceAddress) > 0
diff --git a/cmd/sing-box/cmd_tools_networkquality.go b/cmd/sing-box/cmd_tools_networkquality.go
new file mode 100644
index 0000000000..5f63571de7
--- /dev/null
+++ b/cmd/sing-box/cmd_tools_networkquality.go
@@ -0,0 +1,121 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/sagernet/sing-box/common/networkquality"
+ "github.com/sagernet/sing-box/log"
+
+ "github.com/spf13/cobra"
+)
+
+var (
+ commandNetworkQualityFlagConfigURL string
+ commandNetworkQualityFlagSerial bool
+ commandNetworkQualityFlagMaxRuntime int
+ commandNetworkQualityFlagHTTP3 bool
+)
+
+var commandNetworkQuality = &cobra.Command{
+ Use: "networkquality",
+ Short: "Run a network quality test",
+ Run: func(cmd *cobra.Command, args []string) {
+ err := runNetworkQuality()
+ if err != nil {
+ log.Fatal(err)
+ }
+ },
+}
+
+func init() {
+ commandNetworkQuality.Flags().StringVar(
+ &commandNetworkQualityFlagConfigURL,
+ "config-url", "",
+ "Network quality test config URL (default: Apple mensura)",
+ )
+ commandNetworkQuality.Flags().BoolVar(
+ &commandNetworkQualityFlagSerial,
+ "serial", false,
+ "Run download and upload tests sequentially instead of in parallel",
+ )
+ commandNetworkQuality.Flags().IntVar(
+ &commandNetworkQualityFlagMaxRuntime,
+ "max-runtime", int(networkquality.DefaultMaxRuntime/time.Second),
+ "Network quality maximum runtime in seconds",
+ )
+ commandNetworkQuality.Flags().BoolVar(
+ &commandNetworkQualityFlagHTTP3,
+ "http3", false,
+ "Use HTTP/3 (QUIC) for measurement traffic",
+ )
+ commandTools.AddCommand(commandNetworkQuality)
+}
+
+func runNetworkQuality() error {
+ instance, err := createPreStartedClient()
+ if err != nil {
+ return err
+ }
+ defer instance.Close()
+
+ dialer, err := createDialer(instance, commandToolsFlagOutbound)
+ if err != nil {
+ return err
+ }
+
+ httpClient := networkquality.NewHTTPClient(dialer)
+ defer httpClient.CloseIdleConnections()
+
+ measurementClientFactory, err := networkquality.NewOptionalHTTP3Factory(dialer, commandNetworkQualityFlagHTTP3)
+ if err != nil {
+ return err
+ }
+
+ fmt.Fprintln(os.Stderr, "==== NETWORK QUALITY TEST ====")
+
+ result, err := networkquality.Run(networkquality.Options{
+ ConfigURL: commandNetworkQualityFlagConfigURL,
+ HTTPClient: httpClient,
+ NewMeasurementClient: measurementClientFactory,
+ Serial: commandNetworkQualityFlagSerial,
+ MaxRuntime: time.Duration(commandNetworkQualityFlagMaxRuntime) * time.Second,
+ Context: globalCtx,
+ OnProgress: func(p networkquality.Progress) {
+ if !commandNetworkQualityFlagSerial && p.Phase != networkquality.PhaseIdle {
+ fmt.Fprintf(os.Stderr, "\rDownload: %s RPM: %d Upload: %s RPM: %d",
+ networkquality.FormatBitrate(p.DownloadCapacity), p.DownloadRPM,
+ networkquality.FormatBitrate(p.UploadCapacity), p.UploadRPM)
+ return
+ }
+ switch networkquality.Phase(p.Phase) {
+ case networkquality.PhaseIdle:
+ if p.IdleLatencyMs > 0 {
+ fmt.Fprintf(os.Stderr, "\rIdle Latency: %d ms", p.IdleLatencyMs)
+ } else {
+ fmt.Fprint(os.Stderr, "\rMeasuring idle latency...")
+ }
+ case networkquality.PhaseDownload:
+ fmt.Fprintf(os.Stderr, "\rDownload: %s RPM: %d",
+ networkquality.FormatBitrate(p.DownloadCapacity), p.DownloadRPM)
+ case networkquality.PhaseUpload:
+ fmt.Fprintf(os.Stderr, "\rUpload: %s RPM: %d",
+ networkquality.FormatBitrate(p.UploadCapacity), p.UploadRPM)
+ }
+ },
+ })
+ if err != nil {
+ return err
+ }
+
+ fmt.Fprintln(os.Stderr)
+ fmt.Fprintln(os.Stderr, strings.Repeat("-", 40))
+ fmt.Fprintf(os.Stderr, "Idle Latency: %d ms\n", result.IdleLatencyMs)
+ fmt.Fprintf(os.Stderr, "Download Capacity: %-20s Accuracy: %s\n", networkquality.FormatBitrate(result.DownloadCapacity), result.DownloadCapacityAccuracy)
+ fmt.Fprintf(os.Stderr, "Upload Capacity: %-20s Accuracy: %s\n", networkquality.FormatBitrate(result.UploadCapacity), result.UploadCapacityAccuracy)
+ fmt.Fprintf(os.Stderr, "Download Responsiveness: %-20s Accuracy: %s\n", fmt.Sprintf("%d RPM", result.DownloadRPM), result.DownloadRPMAccuracy)
+ fmt.Fprintf(os.Stderr, "Upload Responsiveness: %-20s Accuracy: %s\n", fmt.Sprintf("%d RPM", result.UploadRPM), result.UploadRPMAccuracy)
+ return nil
+}
diff --git a/cmd/sing-box/cmd_tools_stun.go b/cmd/sing-box/cmd_tools_stun.go
new file mode 100644
index 0000000000..f13086caaa
--- /dev/null
+++ b/cmd/sing-box/cmd_tools_stun.go
@@ -0,0 +1,79 @@
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/sagernet/sing-box/common/stun"
+ "github.com/sagernet/sing-box/log"
+
+ "github.com/spf13/cobra"
+)
+
+var commandSTUNFlagServer string
+
+var commandSTUN = &cobra.Command{
+ Use: "stun",
+ Short: "Run a STUN test",
+ Args: cobra.NoArgs,
+ Run: func(cmd *cobra.Command, args []string) {
+ err := runSTUN()
+ if err != nil {
+ log.Fatal(err)
+ }
+ },
+}
+
+func init() {
+ commandSTUN.Flags().StringVarP(&commandSTUNFlagServer, "server", "s", stun.DefaultServer, "STUN server address")
+ commandTools.AddCommand(commandSTUN)
+}
+
+func runSTUN() error {
+ instance, err := createPreStartedClient()
+ if err != nil {
+ return err
+ }
+ defer instance.Close()
+
+ dialer, err := createDialer(instance, commandToolsFlagOutbound)
+ if err != nil {
+ return err
+ }
+
+ fmt.Fprintln(os.Stderr, "==== STUN TEST ====")
+
+ result, err := stun.Run(stun.Options{
+ Server: commandSTUNFlagServer,
+ Dialer: dialer,
+ Context: globalCtx,
+ OnProgress: func(p stun.Progress) {
+ switch p.Phase {
+ case stun.PhaseBinding:
+ if p.ExternalAddr != "" {
+ fmt.Fprintf(os.Stderr, "\rExternal Address: %s (%d ms)", p.ExternalAddr, p.LatencyMs)
+ } else {
+ fmt.Fprint(os.Stderr, "\rSending binding request...")
+ }
+ case stun.PhaseNATMapping:
+ fmt.Fprint(os.Stderr, "\rDetecting NAT mapping behavior...")
+ case stun.PhaseNATFiltering:
+ fmt.Fprint(os.Stderr, "\rDetecting NAT filtering behavior...")
+ }
+ },
+ })
+ if err != nil {
+ return err
+ }
+
+ fmt.Fprintln(os.Stderr)
+ fmt.Fprintf(os.Stderr, "External Address: %s\n", result.ExternalAddr)
+ fmt.Fprintf(os.Stderr, "Latency: %d ms\n", result.LatencyMs)
+ if result.NATTypeSupported {
+ fmt.Fprintf(os.Stderr, "NAT Mapping: %s\n", result.NATMapping)
+ fmt.Fprintf(os.Stderr, "NAT Filtering: %s\n", result.NATFiltering)
+ } else {
+ fmt.Fprintln(os.Stderr, "NAT Type Detection: not supported by server")
+ }
+ return nil
+}
diff --git a/cmd/sing-box/cmd_version.go b/cmd/sing-box/cmd_version.go
index ab5ada2ed8..3ef103b567 100644
--- a/cmd/sing-box/cmd_version.go
+++ b/cmd/sing-box/cmd_version.go
@@ -29,7 +29,7 @@ func printVersion(cmd *cobra.Command, args []string) {
os.Stdout.WriteString(C.Version + "\n")
return
}
- version := "sing-box version " + C.Version + "\n\n"
+ version := "hiddify-sing-box version " + C.Version + "\n\n"
version += "Environment: " + runtime.Version() + " " + runtime.GOOS + "/" + runtime.GOARCH + "\n"
var tags string
diff --git a/common/certificate/anchors_darwin.h b/common/certificate/anchors_darwin.h
new file mode 100644
index 0000000000..f535f5ca83
--- /dev/null
+++ b/common/certificate/anchors_darwin.h
@@ -0,0 +1,17 @@
+#ifndef BOX_CERTIFICATE_ANCHORS_DARWIN_H
+#define BOX_CERTIFICATE_ANCHORS_DARWIN_H
+
+#include
+#include
+
+// box_certificate_anchors_from_der wraps an array of DER-encoded certificate
+// blobs into a retained CFArrayRef of SecCertificateRef, returned as an opaque
+// pointer. The caller owns the returned reference and must call
+// box_certificate_release_anchors. Returns NULL when no blobs were accepted.
+void *box_certificate_anchors_from_der(const uint8_t *const *ders, const size_t *lens, size_t count);
+
+// box_certificate_release_anchors drops one reference from a CFArray handle
+// previously returned by box_certificate_anchors_from_der. No-op on NULL.
+void box_certificate_release_anchors(void *anchors);
+
+#endif
diff --git a/common/certificate/anchors_darwin.m b/common/certificate/anchors_darwin.m
new file mode 100644
index 0000000000..e9f471c67c
--- /dev/null
+++ b/common/certificate/anchors_darwin.m
@@ -0,0 +1,42 @@
+#import "anchors_darwin.h"
+
+#import
+#import
+
+void *box_certificate_anchors_from_der(const uint8_t *const *ders, const size_t *lens, size_t count) {
+ if (count == 0 || ders == NULL || lens == NULL) {
+ return NULL;
+ }
+ CFMutableArrayRef certificates = CFArrayCreateMutable(NULL, (CFIndex)count, &kCFTypeArrayCallBacks);
+ if (certificates == NULL) {
+ return NULL;
+ }
+ for (size_t index = 0; index < count; index++) {
+ if (ders[index] == NULL || lens[index] == 0) {
+ continue;
+ }
+ CFDataRef data = CFDataCreate(NULL, ders[index], (CFIndex)lens[index]);
+ if (data == NULL) {
+ continue;
+ }
+ SecCertificateRef certificate = SecCertificateCreateWithData(NULL, data);
+ CFRelease(data);
+ if (certificate == NULL) {
+ continue;
+ }
+ CFArrayAppendValue(certificates, certificate);
+ CFRelease(certificate);
+ }
+ if (CFArrayGetCount(certificates) == 0) {
+ CFRelease(certificates);
+ return NULL;
+ }
+ return certificates;
+}
+
+void box_certificate_release_anchors(void *anchors) {
+ if (anchors == NULL) {
+ return;
+ }
+ CFRelease((CFTypeRef)anchors);
+}
diff --git a/common/certificate/chrome.go b/common/certificate/chrome.go
index ea341b0c52..220462561b 100644
--- a/common/certificate/chrome.go
+++ b/common/certificate/chrome.go
@@ -2,13 +2,10 @@
package certificate
-import "crypto/x509"
-
-func newChromeIncluded() *x509.CertPool {
- pool := x509.NewCertPool()
-
- // CN=Actalis Authentication Root CA; O=Actalis S.p.A./03358520967; L=Milan; C=IT
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+func chromeIncludedPEM() string {
+ return `
+// CN=Actalis Authentication Root CA; O=Actalis S.p.A./03358520967; L=Milan; C=IT
+-----BEGIN CERTIFICATE-----
MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
@@ -40,10 +37,10 @@ K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=TunTrust Root CA; O=Agence Nationale de Certification Electronique; C=TN
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=TunTrust Root CA; O=Agence Nationale de Certification Electronique; C=TN
+-----BEGIN CERTIFICATE-----
MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
@@ -75,10 +72,43 @@ nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=Amazon Root CA 2; O=Amazon; C=US
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
- // CN=Amazon Root CA 4; O=Amazon; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Amazon Root CA 4; O=Amazon; C=US
+-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
@@ -90,10 +120,10 @@ M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Amazon Root CA 1; O=Amazon; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Amazon Root CA 1; O=Amazon; C=US
+-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
@@ -112,43 +142,10 @@ N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Amazon Root CA 2; O=Amazon; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
-ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
-b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
-MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
-b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
-gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
-W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
-1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
-8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
-2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
-z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
-8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
-mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
-7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
-+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
-0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
-Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
-UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
-LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
-+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
-k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
-7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
-btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
-urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
-fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
-n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
-76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
-9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
-4PsJYGw=
------END CERTIFICATE-----`))
-
- // CN=Amazon Root CA 3; O=Amazon; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Amazon Root CA 3; O=Amazon; C=US
+-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
@@ -159,10 +156,10 @@ QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certum Trusted Network CA; OU=Certum Certification Authority; O=Unizeto Technologies S.A.; C=PL
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certum Trusted Network CA; OU=Certum Certification Authority; O=Unizeto Technologies S.A.; C=PL
+-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
@@ -183,10 +180,10 @@ I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certum EC-384 CA; OU=Certum Certification Authority; O=Asseco Data Systems S.A.; C=PL
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certum EC-384 CA; OU=Certum Certification Authority; O=Asseco Data Systems S.A.; C=PL
+-----BEGIN CERTIFICATE-----
MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
@@ -200,10 +197,10 @@ QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certum Trusted Root CA; OU=Certum Certification Authority; O=Asseco Data Systems S.A.; C=PL
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certum Trusted Root CA; OU=Certum Certification Authority; O=Asseco Data Systems S.A.; C=PL
+-----BEGIN CERTIFICATE-----
MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
@@ -235,10 +232,10 @@ P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certum Trusted Network CA 2; OU=Certum Certification Authority; O=Unizeto Technologies S.A.; C=PL
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certum Trusted Network CA 2; OU=Certum Certification Authority; O=Unizeto Technologies S.A.; C=PL
+-----BEGIN CERTIFICATE-----
MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
@@ -271,10 +268,10 @@ b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
DrW5viSP
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Autoridad de Certificacion Firmaprofesional CIF A62634068; C=ES
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Autoridad de Certificacion Firmaprofesional CIF A62634068; C=ES
+-----BEGIN CERTIFICATE-----
MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
@@ -308,10 +305,10 @@ CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=ANF Secure Server Root CA; OU=ANF CA Raiz; O=ANF Autoridad de Certificacion; C=ES; SerialNumber=G63287510
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=ANF Secure Server Root CA; OU=ANF CA Raiz; O=ANF Autoridad de Certificacion; C=ES; SerialNumber=G63287510
+-----BEGIN CERTIFICATE-----
MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
@@ -344,10 +341,10 @@ OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Buypass Class 2 Root CA; O=Buypass AS-983163327; C=NO
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Buypass Class 2 Root CA; O=Buypass AS-983163327; C=NO
+-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
@@ -377,10 +374,10 @@ I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Buypass Class 3 Root CA; O=Buypass AS-983163327; C=NO
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Buypass Class 3 Root CA; O=Buypass AS-983163327; C=NO
+-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
@@ -410,10 +407,10 @@ kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certainly Root R1; O=Certainly; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certainly Root R1; O=Certainly; C=US
+-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
@@ -443,10 +440,10 @@ Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
OV+KmalBWQewLK8=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Certainly Root E1; O=Certainly; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Certainly Root E1; O=Certainly; C=US
+-----BEGIN CERTIFICATE-----
MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
@@ -458,34 +455,10 @@ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
------END CERTIFICATE-----`))
-
- // CN=Certigna; O=Dhimyotis; C=FR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
-DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
-BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
-QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
-gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
-zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
-130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
-JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
-ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
-AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
-AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
-9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
-bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
-fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
-HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
-t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
-WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
------END CERTIFICATE-----`))
-
- // CN=Certigna Root CA; OU=0002 48146308100036; O=Dhimyotis; C=FR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// CN=Certigna Root CA; OU=0002 48146308100036; O=Dhimyotis; C=FR
+-----BEGIN CERTIFICATE-----
MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
@@ -520,32 +493,10 @@ faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
------END CERTIFICATE-----`))
-
- // OU=certSIGN ROOT CA; O=certSIGN; C=RO
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
-AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
-QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
-MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
-0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
-UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
-RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
-OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
-JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
-AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
-BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
-LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
-MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
-44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
-Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
-i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
-9u6wWk5JRFRYX0KD
------END CERTIFICATE-----`))
-
- // OU=certSIGN ROOT CA G2; O=CERTSIGN SA; C=RO
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// OU=certSIGN ROOT CA G2; O=CERTSIGN SA; C=RO
+-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
@@ -575,10 +526,10 @@ pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
QRBdJ3NghVdJIgc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=HiPKI Root CA - G1; O=Chunghwa Telecom Co., Ltd.; C=TW
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=HiPKI Root CA - G1; O=Chunghwa Telecom Co., Ltd.; C=TW
+-----BEGIN CERTIFICATE-----
MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
@@ -608,10 +559,10 @@ Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OU=ePKI Root Certification Authority; O=Chunghwa Telecom Co., Ltd.; C=TW
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OU=ePKI Root Certification Authority; O=Chunghwa Telecom Co., Ltd.; C=TW
+-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
@@ -643,10 +594,99 @@ o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=D-TRUST BR Root CA 1 2020; O=D-Trust GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=D-TRUST Root Class 3 CA 2 2009; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+
+// CN=D-TRUST EV Root CA 2 2023; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw
+OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK
+F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE
+7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe
+EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6
+lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb
+RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV
+jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc
+jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx
+TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+
+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk
+hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF
+NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH
+kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14
+QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4
+pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q
+3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU
+t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX
+cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8
+ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT
+2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs
+7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP
+gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst
+Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh
+XBxvWHZks/wCuPWdCg==
+-----END CERTIFICATE-----
+
+// CN=D-TRUST Root Class 3 CA 2 EV 2009; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+
+// CN=D-TRUST BR Root CA 1 2020; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
@@ -663,10 +703,10 @@ c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
dWNbFJWcHwHP2NVypw87
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=D-TRUST EV Root CA 1 2020; O=D-Trust GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=D-TRUST EV Root CA 1 2020; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
@@ -683,89 +723,45 @@ c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
gfM0agPnIjhQW+0ZT0MW
------END CERTIFICATE-----`))
-
- // CN=D-TRUST Root Class 3 CA 2 EV 2009; O=D-Trust GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
-NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
-BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
-ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
-3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
-qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
-p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
-HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
-ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
-HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
-Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
-c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
-RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
-dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
-Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
-3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
-nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
-CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
-xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
-KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
------END CERTIFICATE-----`))
-
- // CN=D-TRUST Root Class 3 CA 2 2009; O=D-Trust GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
-ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
-HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
-UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
-tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
-ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
-lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
-/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
-A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
-A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
-dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
-MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
-cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
-L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
-BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
-acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
-o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
-zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
-PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
-Johw1+qRzT65ysCQblrGXnRl11z+o+I=
------END CERTIFICATE-----`))
-
- // CN=T-TeleSec GlobalRoot Class 3; OU=T-Systems Trust Center; O=T-Systems Enterprise Services GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
-8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
-RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
-hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
-ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
-EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
-A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
-WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
-1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
-6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
-91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
-e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
-TpPDpFQUWw==
------END CERTIFICATE-----`))
-
- // CN=T-TeleSec GlobalRoot Class 2; OU=T-Systems Trust Center; O=T-Systems Enterprise Services GmbH; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// CN=D-TRUST BR Root CA 2 2023; O=D-Trust GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw
+OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr
+i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE
+gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8
+k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT
+Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl
+2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U
+cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP
+/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS
+uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+
+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N
+DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+
+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61
+GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI
+FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n
+riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR
+VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc
+LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn
+4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD
+hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG
+koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46
+ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS
+Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80
+knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ
+hJ65bvspmZDogNOfJA==
+-----END CERTIFICATE-----
+
+// CN=T-TeleSec GlobalRoot Class 2; OU=T-Systems Trust Center; O=T-Systems Enterprise Services GmbH; C=DE
+-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
@@ -787,10 +783,87 @@ IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=Telekom Security TLS ECC Root 2020; O=Deutsche Telekom Security GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw
+CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
+bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw
+MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx
+JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE
+AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O
+tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP
+f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
+MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di
+z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn
+27iQ7t0l
+-----END CERTIFICATE-----
+
+// CN=Telekom Security TLS RSA Root 2023; O=Deutsche Telekom Security GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj
+MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
+eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy
+MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC
+REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG
+A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9
+cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV
+cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA
+U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6
+Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug
+BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy
+8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J
+co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg
+8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8
+rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12
+mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg
++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX
+gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
+p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ
+pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm
+9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw
+M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd
+GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+
+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t
+xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+
+w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK
+L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj
+X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q
+ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm
+dTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
+-----END CERTIFICATE-----
+
+// CN=T-TeleSec GlobalRoot Class 3; OU=T-Systems Trust Center; O=T-Systems Enterprise Services GmbH; C=DE
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
- // CN=DigiCert TLS RSA4096 Root G5; O=DigiCert, Inc.; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert TLS RSA4096 Root G5; O=DigiCert, Inc.; C=US
+-----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
@@ -820,10 +893,10 @@ p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert TLS ECC P384 Root G5; O=DigiCert, Inc.; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert TLS ECC P384 Root G5; O=DigiCert, Inc.; C=US
+-----BEGIN CERTIFICATE-----
MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
@@ -836,34 +909,76 @@ B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
DXZDjC5Ty3zfDBeWUA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert Assured ID Root CA; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
-JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
-mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
-wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
-VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
-AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
-AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
-pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
-dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
-fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
-NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
-H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
-+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----`))
-
- // CN=DigiCert Assured ID Root G2; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=QuoVadis Root CA 3 G3; O=QuoVadis Limited; C=BM
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+
+// CN=QuoVadis Root CA 2 G3; O=QuoVadis Limited; C=BM
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+
+// CN=DigiCert Assured ID Root G2; OU=www.digicert.com; O=DigiCert Inc; C=US
+-----BEGIN CERTIFICATE-----
MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
@@ -884,10 +999,10 @@ lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
IhNzbM8m9Yop5w==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert Assured ID Root G3; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert Assured ID Root G3; OU=www.digicert.com; O=DigiCert Inc; C=US
+-----BEGIN CERTIFICATE-----
MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
@@ -901,34 +1016,10 @@ BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
6pZjamVFkpUBtA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert Global Root CA; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
-CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
-nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
-43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
-T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
-gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
-TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
-DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
-hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
-06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
-PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
-YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----`))
-
- // CN=DigiCert Global Root G2; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert Global Root G2; OU=www.digicert.com; O=DigiCert Inc; C=US
+-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
@@ -949,10 +1040,10 @@ Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert Global Root G3; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert Global Root G3; OU=www.digicert.com; O=DigiCert Inc; C=US
+-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
@@ -966,35 +1057,10 @@ BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=DigiCert High Assurance EV Root CA; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----`))
-
- // CN=DigiCert Trusted Root G4; OU=www.digicert.com; O=DigiCert Inc; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=DigiCert Trusted Root G4; OU=www.digicert.com; O=DigiCert Inc; C=US
+-----BEGIN CERTIFICATE-----
MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
@@ -1025,111 +1091,10 @@ cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
------END CERTIFICATE-----`))
-
- // CN=QuoVadis Root CA 2; O=QuoVadis Limited; C=BM
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
-GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
-Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
-WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
-rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
-+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
-ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
-Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
-PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
-/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
-oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
-yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
-EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
-A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
-MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
-ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
-BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
-g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
-fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
-WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
-B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
-hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
-TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
-mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
-ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
-4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
-8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
------END CERTIFICATE-----`))
-
- // CN=QuoVadis Root CA 2 G3; O=QuoVadis Limited; C=BM
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
-BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
-BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
-MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
-qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
-n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
-c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
-O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
-o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
-IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
-IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
-8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
-vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
-7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
-cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
-ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
-AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
-roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
-W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
-lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
-+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
-csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
-dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
-KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
-HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
-WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=QuoVadis Root CA 3 G3; O=QuoVadis Limited; C=BM
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
-BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
-BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
-MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
-aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
-/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
-FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
-U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
-ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
-FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
-A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
-eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
-sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
-VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
-A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
-ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
-ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
-KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
-FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
-oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
-u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
-0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
-3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
-8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
-DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
-PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
-ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
------END CERTIFICATE-----`))
-
- // CN=CA Disig Root R2; O=Disig a.s.; L=Bratislava; C=SK
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=CA Disig Root R2; O=Disig a.s.; L=Bratislava; C=SK
+-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
@@ -1159,27 +1124,10 @@ gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=emSign ECC Root CA - G3; OU=emSign PKI; O=eMudhra Technologies Limited; C=IN
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
-EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
-bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
-RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
-TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
-b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
-djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
-WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
-fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
-zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
-hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
-CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
-+JbNR6iC8hZVdyR+EhCVBCyj
------END CERTIFICATE-----`))
-
- // CN=emSign Root CA - G1; OU=emSign PKI; O=eMudhra Technologies Limited; C=IN
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=emSign Root CA - G1; OU=emSign PKI; O=eMudhra Technologies Limited; C=IN
+-----BEGIN CERTIFICATE-----
MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
@@ -1200,32 +1148,43 @@ GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
iN66zB+Afko=
------END CERTIFICATE-----`))
-
- // CN=AffirmTrust Commercial; O=AffirmTrust; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
-Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
-ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
-MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
-yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
-VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
-nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
-XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
-vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
-Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
-N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
-nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
------END CERTIFICATE-----`))
-
- // CN=Atos TrustedRoot 2011; O=Atos; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// CN=emSign ECC Root CA - G3; OU=emSign PKI; O=eMudhra Technologies Limited; C=IN
+-----BEGIN CERTIFICATE-----
+MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
+EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
+bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
+RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
+TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
+b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
+WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
+fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
+zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
+hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
+CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
++JbNR6iC8hZVdyR+EhCVBCyj
+-----END CERTIFICATE-----
+
+// CN=Atos TrustedRoot Root CA ECC TLS 2021; O=Atos; C=DE
+-----BEGIN CERTIFICATE-----
+MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
+LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
+CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
+MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
+Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
+tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
+AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
+KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
+aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
+CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
+9H1/IISpQuQo
+-----END CERTIFICATE-----
+
+// CN=Atos TrustedRoot 2011; O=Atos; C=DE
+-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
@@ -1245,26 +1204,10 @@ DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
------END CERTIFICATE-----`))
-
- // CN=Atos TrustedRoot Root CA ECC TLS 2021; O=Atos; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
-LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
-CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
-MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
-Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
-zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
-tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
-AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
-KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
-aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
-CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
-9H1/IISpQuQo
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Atos TrustedRoot Root CA RSA TLS 2021; O=Atos; C=DE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Atos TrustedRoot Root CA RSA TLS 2021; O=Atos; C=DE
+-----BEGIN CERTIFICATE-----
MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
@@ -1294,59 +1237,10 @@ AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GlobalSign; OU=GlobalSign Root CA - R6; O=GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
-MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
-bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
-MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
-MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
-KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
-xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
-ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
-aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
-LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
-1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
-k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
-SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
-bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
-WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
-rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
-MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
-AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
-bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
-nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
-Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
-55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
-vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
-cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
-oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
-nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
-pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
-JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
-8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
-5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
------END CERTIFICATE-----`))
-
- // CN=GlobalSign Root E46; O=GlobalSign nv-sa; C=BE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
-CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
-ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
-MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
-HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
-IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
-R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
-yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
-DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
-7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
-+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
------END CERTIFICATE-----`))
-
- // CN=GlobalSign Root R46; O=GlobalSign nv-sa; C=BE
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GlobalSign Root R46; O=GlobalSign nv-sa; C=BE
+-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
@@ -1376,10 +1270,25 @@ u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GlobalSign; OU=GlobalSign ECC Root CA - R5; O=GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GlobalSign Root E46; O=GlobalSign nv-sa; C=BE
+-----BEGIN CERTIFICATE-----
+MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
+CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
+ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
+MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
+HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
+R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
+yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
+7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
+-----END CERTIFICATE-----
+
+// CN=GlobalSign; OU=GlobalSign ECC Root CA - R5; O=GlobalSign
+-----BEGIN CERTIFICATE-----
MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
@@ -1392,10 +1301,10 @@ VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
xwy8p2Fp8fc74SrL+SvzZpA3
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GlobalSign; OU=GlobalSign Root CA - R3; O=GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GlobalSign; OU=GlobalSign Root CA - R3; O=GlobalSign
+-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
@@ -1415,10 +1324,44 @@ jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Starfield Root Certificate Authority - G2; O=Starfield Technologies, Inc.; L=Scottsdale; ST=Arizona; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GlobalSign; OU=GlobalSign Root CA - R6; O=GlobalSign
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
+
+// CN=Starfield Root Certificate Authority - G2; O=Starfield Technologies, Inc.; L=Scottsdale; ST=Arizona; C=US
+-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
@@ -1440,10 +1383,10 @@ sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Go Daddy Root Certificate Authority - G2; O=GoDaddy.com, Inc.; L=Scottsdale; ST=Arizona; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Go Daddy Root Certificate Authority - G2; O=GoDaddy.com, Inc.; L=Scottsdale; ST=Arizona; C=US
+-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
@@ -1465,24 +1408,10 @@ gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
------END CERTIFICATE-----`))
-
- // CN=GlobalSign; OU=GlobalSign ECC Root CA - R4; O=GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
-VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
-bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
-MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
-UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
-BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
-uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
-HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
-+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
-bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GTS Root R4; O=Google Trust Services LLC; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GTS Root R4; O=Google Trust Services LLC; C=US
+-----BEGIN CERTIFICATE-----
MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
@@ -1494,10 +1423,10 @@ HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GTS Root R2; O=Google Trust Services LLC; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GTS Root R2; O=Google Trust Services LLC; C=US
+-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
@@ -1527,10 +1456,10 @@ TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GTS Root R1; O=Google Trust Services LLC; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GTS Root R1; O=Google Trust Services LLC; C=US
+-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
@@ -1560,10 +1489,10 @@ Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=GTS Root R3; O=Google Trust Services LLC; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GTS Root R3; O=Google Trust Services LLC; C=US
+-----BEGIN CERTIFICATE-----
MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
@@ -1575,10 +1504,24 @@ jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=ACCVRAIZ1; OU=PKIACCV; O=ACCV; C=ES
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=GlobalSign; OU=GlobalSign ECC Root CA - R4; O=GlobalSign
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
+VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
+UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
+BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
+uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
+HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
+bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
+-----END CERTIFICATE-----
+
+// CN=ACCVRAIZ1; OU=PKIACCV; O=ACCV; C=ES
+-----BEGIN CERTIFICATE-----
MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
@@ -1621,10 +1564,28 @@ I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS; OU=Ceres; O=FNMT-RCM; C=ES; OrganizationIdentifier=VATES-Q2826004J
+-----BEGIN CERTIFICATE-----
+MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
+CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
+FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
+Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
+MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
+DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
+QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
+sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
+Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
+SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
+MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
+v+c=
+-----END CERTIFICATE-----
- // OU=AC RAIZ FNMT-RCM; O=FNMT-RCM; C=ES
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OU=AC RAIZ FNMT-RCM; O=FNMT-RCM; C=ES
+-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
@@ -1655,28 +1616,10 @@ fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
------END CERTIFICATE-----`))
-
- // CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS; OU=Ceres; O=FNMT-RCM; C=ES; OrganizationIdentifier=VATES-Q2826004J
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
-CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
-FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
-Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
-MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
-DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
-QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
-BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
-sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
-Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
-SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
-MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
-v+c=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1; OU=Kamu Sertifikasyon Merkezi - Kamu SM; O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK; L=Gebze - Kocaeli; C=TR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1; OU=Kamu Sertifikasyon Merkezi - Kamu SM; O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK; L=Gebze - Kocaeli; C=TR
+-----BEGIN CERTIFICATE-----
MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
@@ -1701,10 +1644,10 @@ IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=HARICA TLS RSA Root CA 2021; O=Hellenic Academic and Research Institutions CA; C=GR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=HARICA TLS RSA Root CA 2021; O=Hellenic Academic and Research Institutions CA; C=GR
+-----BEGIN CERTIFICATE-----
MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
@@ -1736,10 +1679,10 @@ BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
63ZTGI0RmLo=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=HARICA TLS ECC Root CA 2021; O=Hellenic Academic and Research Institutions CA; C=GR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=HARICA TLS ECC Root CA 2021; O=Hellenic Academic and Research Institutions CA; C=GR
+-----BEGIN CERTIFICATE-----
MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
@@ -1753,10 +1696,10 @@ AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=IdenTrust Commercial Root CA 1; O=IdenTrust; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=IdenTrust Commercial Root CA 1; O=IdenTrust; C=US
+-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
@@ -1786,10 +1729,10 @@ l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=ISRG Root X1; O=Internet Security Research Group; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=ISRG Root X1; O=Internet Security Research Group; C=US
+-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
@@ -1819,10 +1762,10 @@ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=ISRG Root X2; O=Internet Security Research Group; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=ISRG Root X2; O=Internet Security Research Group; C=US
+-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
@@ -1835,10 +1778,10 @@ AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Izenpe.com; O=IZENPE S.A.; C=ES
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Izenpe.com; O=IZENPE S.A.; C=ES
+-----BEGIN CERTIFICATE-----
MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
@@ -1871,10 +1814,10 @@ UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=SZAFIR ROOT CA2; O=Krajowa Izba Rozliczeniowa S.A.; C=PL
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SZAFIR ROOT CA2; O=Krajowa Izba Rozliczeniowa S.A.; C=PL
+-----BEGIN CERTIFICATE-----
MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
@@ -1894,27 +1837,30 @@ nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
------END CERTIFICATE-----`))
-
- // CN=e-Szigno Root CA 2017; O=Microsec Ltd.; L=Budapest; C=HU; OrganizationIdentifier=VATHU-23584497
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
-BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
-LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
-b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
-BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
-THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
-IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
-xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
-Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
-eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
-jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
-+efcMQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Microsec e-Szigno Root CA 2009; O=Microsec Ltd.; L=Budapest; C=HU; EmailAddress=info@e-szigno.hu
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=e-Szigno TLS Root CA 2023; O=Microsec Ltd.; L=Budapest; C=HU; OrganizationIdentifier=VATHU-23584497
+-----BEGIN CERTIFICATE-----
+MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU
+TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow
+dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy
+b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T
+emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE
+AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS
+AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v
+SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K
+ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI
+zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt
+y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl
+C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6
+uWWL
+-----END CERTIFICATE-----
+
+// CN=Microsec e-Szigno Root CA 2009; O=Microsec Ltd.; L=Budapest; C=HU; EmailAddress=info@e-szigno.hu
+-----BEGIN CERTIFICATE-----
MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
@@ -1937,10 +1883,27 @@ ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=e-Szigno Root CA 2017; O=Microsec Ltd.; L=Budapest; C=HU; OrganizationIdentifier=VATHU-23584497
+-----BEGIN CERTIFICATE-----
+MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
+BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
+LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
+b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
+BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
+THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
+IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
+xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
+Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
+eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
+jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
++efcMQ==
+-----END CERTIFICATE-----
- // CN=Microsoft ECC Root Certificate Authority 2017; O=Microsoft Corporation; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Microsoft ECC Root Certificate Authority 2017; O=Microsoft Corporation; C=US
+-----BEGIN CERTIFICATE-----
MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
@@ -1954,10 +1917,10 @@ BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Microsoft RSA Root Certificate Authority 2017; O=Microsoft Corporation; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Microsoft RSA Root Certificate Authority 2017; O=Microsoft Corporation; C=US
+-----BEGIN CERTIFICATE-----
MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
@@ -1989,10 +1952,10 @@ GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
RA+GsCyRxj3qrg+E
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=NAVER Global Root Certification Authority; O=NAVER BUSINESS PLATFORM Corp.; C=KR
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=NAVER Global Root Certification Authority; O=NAVER BUSINESS PLATFORM Corp.; C=KR
+-----BEGIN CERTIFICATE-----
MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
@@ -2024,10 +1987,10 @@ LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
9XXeifdy
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=NetLock Arany (Class Gold) Főtanúsítvány; OU=Tanúsítványkiadók (Certification Services); O=NetLock Kft.; L=Budapest; C=HU
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=NetLock Arany (Class Gold) Főtanúsítvány; OU=Tanúsítványkiadók (Certification Services); O=NetLock Kft.; L=Budapest; C=HU
+-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
@@ -2050,10 +2013,10 @@ bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=OISTE WISeKey Global Root GC CA; OU=OISTE Foundation Endorsed; O=WISeKey; C=CH
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=OISTE WISeKey Global Root GC CA; OU=OISTE Foundation Endorsed; O=WISeKey; C=CH
+-----BEGIN CERTIFICATE-----
MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
@@ -2067,10 +2030,10 @@ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=OISTE WISeKey Global Root GB CA; OU=OISTE Foundation Endorsed; O=WISeKey; C=CH
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=OISTE WISeKey Global Root GB CA; OU=OISTE Foundation Endorsed; O=WISeKey; C=CH
+-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
@@ -2091,10 +2054,10 @@ gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=Security Communication ECC RootCA1; O=SECOM Trust Systems CO.,LTD.; C=JP
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Security Communication ECC RootCA1; O=SECOM Trust Systems CO.,LTD.; C=JP
+-----BEGIN CERTIFICATE-----
MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
@@ -2107,10 +2070,10 @@ ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OU=Security Communication RootCA2; O=SECOM Trust Systems CO.,LTD.; C=JP
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OU=Security Communication RootCA2; O=SECOM Trust Systems CO.,LTD.; C=JP
+-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
@@ -2130,73 +2093,10 @@ okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----`))
-
- // CN=Entrust Root Certification Authority; OU=www.entrust.net/CPS is incorporated by reference, (c) 2006 Entrust, Inc.; O=Entrust, Inc.; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
-NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
-NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
-ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
-BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
-Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
-4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
-KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
-rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
-94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
-sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
-gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
-kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
-vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
-O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
-AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
-9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
-eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
-0vdXcDazv/wor3ElhVsT/h5/WrQ8
------END CERTIFICATE-----`))
-
- // CN=Sectigo Public Server Authentication Root E46; O=Sectigo Limited; C=GB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
-CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
-ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
-MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
-A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
-ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
-IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
-WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
-6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
-Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
-qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
-4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
------END CERTIFICATE-----`))
-
- // CN=COMODO ECC Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
-IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
-MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
-ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
-T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
-biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
-FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
-cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
-BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
-fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
-GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=COMODO Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=COMODO Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
+-----BEGIN CERTIFICATE-----
MIID0DCCArigAwIBAgIQIKTEf93f4cdTYwcTiHdgEjANBgkqhkiG9w0BAQUFADCB
gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
@@ -2218,10 +2118,10 @@ HWLrp+cxEmbDD6ZLLkGC9/3JG6gbr+48zuOcrigHoSybJMIPIyaDMouGDx8rEkYl
Fo92kANr3ryqImhrjKGsKxE5pttwwn1y6TPn/CbxdFqR5p2ErPioBhlG5qfpqjQi
pKGfeq23sqSaM4hxAjwu1nqyH6LKwN0vEJT9s4yEIHlG1QXUEOTS22RPuFvuG8Ug
R1uUq27UlTMdphVx8fiUylQ5PsE=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=COMODO RSA Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=COMODO RSA Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
+-----BEGIN CERTIFICATE-----
MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
@@ -2254,10 +2154,10 @@ S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
NVOFBkpdn627G190
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=USERTrust RSA Certification Authority; O=The USERTRUST Network; L=Jersey City; ST=New Jersey; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=USERTrust RSA Certification Authority; O=The USERTRUST Network; L=Jersey City; ST=New Jersey; C=US
+-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
@@ -2290,10 +2190,10 @@ qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
jjxDah2nGN59PRbxYvnKkKj9
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=USERTrust ECC Certification Authority; O=The USERTRUST Network; L=Jersey City; ST=New Jersey; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=USERTrust ECC Certification Authority; O=The USERTRUST Network; L=Jersey City; ST=New Jersey; C=US
+-----BEGIN CERTIFICATE-----
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
@@ -2308,10 +2208,44 @@ A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=COMODO ECC Certification Authority; O=COMODO CA Limited; L=Salford; ST=Greater Manchester; C=GB
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+
+// CN=Sectigo Public Server Authentication Root E46; O=Sectigo Limited; C=GB
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
+ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
+MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
+A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
+ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
+WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
+Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
+qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
+4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
+-----END CERTIFICATE-----
- // CN=Sectigo Public Server Authentication Root R46; O=Sectigo Limited; C=GB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Sectigo Public Server Authentication Root R46; O=Sectigo Limited; C=GB
+-----BEGIN CERTIFICATE-----
MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
@@ -2342,93 +2276,10 @@ dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
------END CERTIFICATE-----`))
-
- // CN=Entrust Root Certification Authority - G2; OU=See www.entrust.net/legal-terms, (c) 2009 Entrust, Inc. - for authorized use only; O=Entrust, Inc.; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
-cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
-IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
-dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
-NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
-dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
-dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
-aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
-RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
-cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
-wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
-U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
-jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
-BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
-BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
-jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
-Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
-1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
-nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
-VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
------END CERTIFICATE-----`))
-
- // CN=Entrust Root Certification Authority - EC1; OU=See www.entrust.net/legal-terms, (c) 2012 Entrust, Inc. - for authorized use only; O=Entrust, Inc.; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
-A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
-d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
-dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
-RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
-MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
-VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
-L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
-Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
-A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
-ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
-Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
-R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
-hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
------END CERTIFICATE-----`))
-
- // CN=SSL.com Root Certification Authority RSA; O=SSL Corporation; L=Houston; ST=Texas; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
-BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
-DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
-OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
-dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
-bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
-AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
-xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
-qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
-C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
-6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
-/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
-YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
-JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
-US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
-ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
-+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
-M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
-HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
-A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
-cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
-Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
-PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
-q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
-cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
-a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
-H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
-K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
-nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
-oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
-Ic2wBlX7Jz9TkHCpBB5XJ7k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=SSL.com TLS ECC Root CA 2022; O=SSL Corporation; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SSL.com TLS ECC Root CA 2022; O=SSL Corporation; C=US
+-----BEGIN CERTIFICATE-----
MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
@@ -2441,10 +2292,28 @@ GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// CN=SSL.com EV Root Certification Authority ECC; O=SSL Corporation; L=Houston; ST=Texas; C=US
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
- // CN=SSL.com TLS RSA Root CA 2022; O=SSL Corporation; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SSL.com TLS RSA Root CA 2022; O=SSL Corporation; C=US
+-----BEGIN CERTIFICATE-----
MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
@@ -2475,10 +2344,10 @@ AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=SSL.com Root Certification Authority ECC; O=SSL Corporation; L=Houston; ST=Texas; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SSL.com Root Certification Authority ECC; O=SSL Corporation; L=Houston; ST=Texas; C=US
+-----BEGIN CERTIFICATE-----
MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
@@ -2493,10 +2362,10 @@ EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=SSL.com EV Root Certification Authority RSA R2; O=SSL Corporation; L=Houston; ST=Texas; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SSL.com EV Root Certification Authority RSA R2; O=SSL Corporation; L=Houston; ST=Texas; C=US
+-----BEGIN CERTIFICATE-----
MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
@@ -2529,63 +2398,113 @@ QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=SSL.com EV Root Certification Authority ECC; O=SSL Corporation; L=Houston; ST=Texas; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
-VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
-U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
-NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
-dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
-bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
-AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
-VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
-WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
-MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
-5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
-ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
-h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
------END CERTIFICATE-----`))
-
- // CN=SwissSign Gold CA - G2; O=SwissSign AG; C=CH
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
-BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
-biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
-MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
-d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
-76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
-bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
-6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
-emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
-MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
-MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
-MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
-FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
-aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
-gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
-qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
-lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
-8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
-L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
-45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
-UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
-O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
-bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
-GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
-77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
-hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
-92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
-Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
-ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
-Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
------END CERTIFICATE-----`))
-
- // CN=TWCA CYBER Root CA; OU=Root CA; O=TAIWAN-CA; C=TW
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=SSL.com Root Certification Authority RSA; O=SSL Corporation; L=Houston; ST=Texas; C=US
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+
+// CN=SwissSign RSA TLS Root CA 2022 - 1; O=SwissSign AG; C=CH
+-----BEGIN CERTIFICATE-----
+MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE
+AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx
+MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT
+d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg
+MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX
+vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7
+LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX
+5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE
+EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt
+/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x
+0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5
+KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM
+0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd
+OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta
+clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK
+wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4
+DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL
+BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3
+10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz
+Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ
+iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc
+gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM
+ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF
+LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp
+zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td
+Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0
+rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO
+gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ
+-----END CERTIFICATE-----
+
+// CN=TWCA Global Root CA; OU=Root CA; O=TAIWAN-CA; C=TW
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+
+// CN=TWCA CYBER Root CA; OU=Root CA; O=TAIWAN-CA; C=TW
+-----BEGIN CERTIFICATE-----
MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ
MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5
@@ -2616,75 +2535,10 @@ Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz
NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX
xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6
t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CN=TWCA Global Root CA; OU=Root CA; O=TAIWAN-CA; C=TW
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
-EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
-VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
-NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
-B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
-SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
-10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
-0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
-MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
-zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
-46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
-yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
-laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
-oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
-BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
-qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
-4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
-/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
-1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
-LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
-H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
-RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
-nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
-15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
-6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
-nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
-wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
-aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
-KwbQBM0=
------END CERTIFICATE-----`))
-
- // CN=TeliaSonera Root CA v1; O=TeliaSonera
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
-NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
-b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
-VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
-VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
-7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
-Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
-/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
-81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
-dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
-Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
-sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
-pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
-slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
-arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
-9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
-dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
-0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
-TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
-Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
-Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
-OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
-vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
-t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
-HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
-SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
------END CERTIFICATE-----`))
-
- // CN=Telia Root CA v2; O=Telia Finland Oyj; C=FI
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CN=Telia Root CA v2; O=Telia Finland Oyj; C=FI
+-----BEGIN CERTIFICATE-----
MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
@@ -2715,102 +2569,6 @@ Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
rBPuUBQemMc=
------END CERTIFICATE-----`))
-
- // CN=Trustwave Global ECC P384 Certification Authority; O=Trustwave Holdings, Inc.; L=Chicago; ST=Illinois; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
-BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
-YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
-A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
-d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
-Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
-BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
-j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
-1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
-A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
-AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
-MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
-Sw==
------END CERTIFICATE-----`))
-
- // CN=Trustwave Global ECC P256 Certification Authority; O=Trustwave Holdings, Inc.; L=Chicago; ST=Illinois; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
-BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
-YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
-A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
-d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
-Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
-SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
-FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
-DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
-CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
-DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
------END CERTIFICATE-----`))
-
- // CN=SecureTrust CA; O=SecureTrust Corporation; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
-MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
-cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
-Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
-0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
-wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
-7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
-8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
-BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
-JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
-NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
-6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
-3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
-D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
-CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
-3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
------END CERTIFICATE-----`))
-
- // CN=Trustwave Global Certification Authority; O=Trustwave Holdings, Inc.; L=Chicago; ST=Illinois; C=US
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
-CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
-ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
-c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
-OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
-SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
-b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
-swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
-7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
-1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
-80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
-JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
-RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
-hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
-coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
-BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
-twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
-EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
-DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
-0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
-uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
-lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
-aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
-sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
-MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
-qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
-VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
-h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
-EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
-yeC2nOnOcXHebD8WpHk=
------END CERTIFICATE-----`))
- return pool
+-----END CERTIFICATE-----
+`
}
diff --git a/common/certificate/chrome.pem b/common/certificate/chrome.pem
new file mode 100644
index 0000000000..0d6ac2370b
--- /dev/null
+++ b/common/certificate/chrome.pem
@@ -0,0 +1,2650 @@
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
+BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
+Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
+b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG
+EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u
+IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ
+n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd
+2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF
+VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ
+GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF
+li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU
+r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2
+eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb
+MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg
+jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB
+7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW
+5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE
+ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
+90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z
+xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu
+QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4
+FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH
+22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP
+xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn
+dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5
+Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b
+nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
+CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
+u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
+d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
+A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
+U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
+N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
+o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
+5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
+rqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
+9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
+M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
+MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
+CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
+1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
+ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
+ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
+BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
+YyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
+MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
+MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
+BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw
+MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg
+U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ
+n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q
+p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq
+NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF
+8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3
+HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa
+mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi
+7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF
+ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P
+qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ
+v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6
+Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1
+vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD
+ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4
+WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo
+zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR
+5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ
+GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf
+5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq
+0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D
+P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
+qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
+0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
+E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
+CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
+JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
+EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0
+WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT
+LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX
+BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE
+KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm
+Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
+EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
+UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
+nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
+gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
+A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
+OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
+VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
+b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
+DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
+0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
+OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
+fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
+Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
+o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
+sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
+OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
+Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
+adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
+3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
+F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
+CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
+XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
+djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
+WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
+AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
+P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
+b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
+XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
+5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
+DrW5viSP
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
+MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
+tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
+IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
+b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
+AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
+ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
+iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
+Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
+hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
+Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
+EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
+1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
+CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
+5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
+f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
+ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
+GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
+BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
+YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
+BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN
+MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF
+UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD
+VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v
+dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj
+cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q
+yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH
+2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX
+H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL
+zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR
+p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz
+W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/
+SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn
+LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3
+n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B
+u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj
+o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
+AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L
+9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej
+rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK
+pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0
+vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq
+OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
+/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9
+2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI
++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
+MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
+tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
+PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
+dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0
+YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2
+1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT
+vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed
+aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0
+1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5
+r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5
+cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ
+wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ
+6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA
+2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH
+Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR
+eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB
+/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u
+d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr
+PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
+8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi
+1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd
+rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di
+taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7
+lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj
+yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn
+Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
+yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
+wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
+OV+KmalBWQewLK8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
+bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s
+eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK
++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2
+QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
+hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
+ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
+BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
+WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
+MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
+MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
+VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
+BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
+ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
+CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
+I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
+TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
+C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
+ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
+IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
+Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
+JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
+hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
+GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
+1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
+L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
+dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
+aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
+hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
+6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
+HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
+0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
+lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
+o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
+gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
+faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
+Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
+jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
+3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
+Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
+BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ
+R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF
+dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw
+vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ
+uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp
+n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs
+cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW
+xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P
+rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF
+DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx
+DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy
+LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C
+eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ
+d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq
+kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
+b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl
+qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0
+OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c
+NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk
+ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO
+pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
+03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk
+PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
+1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
+QRBdJ3NghVdJIgc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
+Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3
+YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw
+qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv
+Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6
+lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz
+Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ
+KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK
+FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj
+HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr
+y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ
+/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM
+a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6
+fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG
+SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi
+7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc
+SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza
+ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc
+XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg
+iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho
+L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF
+Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
+kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
+vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
+YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw
+OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr
+i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE
+gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8
+k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT
+Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl
+2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U
+cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP
+/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS
+uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+
+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N
+DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+
+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61
+GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI
+FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n
+riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR
+VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc
+LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn
+4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD
+hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG
+koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46
+ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS
+Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80
+knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ
+hJ65bvspmZDogNOfJA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw
+OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK
+F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE
+7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe
+EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6
+lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb
+RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV
+jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc
+jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx
+TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+
+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk
+hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF
+NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH
+kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14
+QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4
+pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q
+3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU
+t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX
+cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8
+ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT
+2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs
+7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP
+gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst
+Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh
+XBxvWHZks/wCuPWdCg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
+NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS
+zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0
+QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/
+VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
+wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
+dWNbFJWcHwHP2NVypw87
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
+NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC
+/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD
+wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3
+OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
+y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
+gfM0agPnIjhQW+0ZT0MW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj
+MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
+eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy
+MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC
+REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG
+A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9
+cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV
+cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA
+U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6
+Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug
+BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy
+8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J
+co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg
+8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8
+rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12
+mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg
++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX
+gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
+p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ
+pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm
+9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw
+M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd
+GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+
+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t
+xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+
+w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK
+L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj
+X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q
+ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm
+dTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw
+CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
+bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw
+MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx
+JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE
+AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O
+tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP
+f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
+MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di
+z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn
+27iQ7t0l
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
+Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
+MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
+bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS
+7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp
+0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS
+B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
+BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
+LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
+DXZDjC5Ty3zfDBeWUA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
+HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
+NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
+IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+
+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0
+2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp
+wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM
+pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD
+nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po
+sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx
+Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd
+Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX
+KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe
+XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL
+tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv
+TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
+AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
+GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H
+PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF
+O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ
+REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik
+AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv
+/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+
+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
+MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
+qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
+ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
+EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
+bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
+RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
+TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
+b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
+WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
+fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
+zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
+hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
+CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
++JbNR6iC8hZVdyR+EhCVBCyj
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
+VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
+ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
+MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
+MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
+Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
+f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
+8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
+d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
+tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
+Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
+o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
+PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
+wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
+GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
+6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
+RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
+iN66zB+Afko=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
+LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
+CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
+MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
+Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
+tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
+AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
+KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
+aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
+CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
+9H1/IISpQuQo
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
+MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
+MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
+MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD
+QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z
+4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv
+Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ
+kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs
+GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln
+nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh
+3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD
+0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy
+geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8
+ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB
+c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI
+pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS
+4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs
+o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ
+qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw
+xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM
+rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4
+AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
+0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY
+o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
+dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
+oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
+CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
+ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
+MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
+HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
+R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
+yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
+7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
+MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
+VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
+MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
+c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ
+OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG
+vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud
+316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo
+0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE
+y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF
+zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE
++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN
+I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs
+x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa
+ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC
+4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4
+7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg
+JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti
+2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk
+pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF
+FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt
+rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk
+ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5
+u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
+4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
+N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
+vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G
+jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
+4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
+VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
+ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
+QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
+HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
+9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
+p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt
+nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY
+6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu
+MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k
+RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg
+f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV
++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo
+dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW
+Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa
+G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq
+gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H
+vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8
+0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC
+B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u
+NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg
+yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev
+HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6
+xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR
+TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
+JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
+7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
+6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
+VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
+UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
+BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
+uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
+HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
+bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
+CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
+WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
+BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
+Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
+yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
+BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
+WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
+tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
+374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
+IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
+mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
+wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
+MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
+ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
+UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
+YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
+LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
+RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
+LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
+77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
+JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
+fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
+6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
+1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
+9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
+RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
+uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
+CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
+FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
+Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
+MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
+DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
+QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
+sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
+Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
+SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
+MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
+v+c=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
+bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
+KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
+BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
+dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
+EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
+IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
+QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
+TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
+LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
+a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
+LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
+N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
+YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
+iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
+AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
+V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
+IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
+lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
+8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
+lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
+MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
+Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL
+MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
+YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv
+b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l
+mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE
+4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv
+a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M
+pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw
+Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b
+LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY
+AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB
+AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq
+E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr
+W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ
+CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
+AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU
+X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3
+f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja
+H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP
+JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P
+zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt
+jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0
+/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT
+BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
+aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
+xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
+63ZTGI0RmLo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
+CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
+cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
+dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG
+A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
+aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg
+Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7
+KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y
+STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
+AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
+SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
+nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
+CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
+R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
+MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
+ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
+EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
+ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
+zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
+tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
+/q4AaOeMSQ+2b1tbFfLn
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
+ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
+NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
+Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
+QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
+3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
+3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
+3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
+BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
+XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
+AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
+8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
+nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
+oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
+d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
+LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
+BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
+LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
+b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
+BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
+THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
+IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
+xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
+Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
+eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
+jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
++efcMQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
+VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
+MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV
+UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy
+b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR
+ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb
+hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
+FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
+L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
+iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
+MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
+NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG
+EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N
+aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ
+Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0
+ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1
+HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm
+gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ
+jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc
+aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG
+YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6
+W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K
+UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH
++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q
+W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC
+LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC
+gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6
+tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh
+SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2
+TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3
+pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR
+xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp
+GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
+dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
+AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
+RA+GsCyRxj3qrg+E
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
+BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
+T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx
+CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD
+b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA
+iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH
+38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE
+HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz
+kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP
+szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq
+vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf
+nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG
+YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo
+0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a
+CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K
+AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I
+36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN
+qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj
+cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm
++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL
+hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe
+lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7
+p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8
+piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR
+LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
+5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
+dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
+9XXeifdy
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
+CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
+bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
+Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ
+BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu
+ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS
+b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni
+eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W
+p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
+rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
+57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
+Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
+MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
+Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
+YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
+CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
+b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
+HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
+WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
+1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
+u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
+99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
+M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
+BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
+cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
+gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
+ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
+aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
+AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
+VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
+NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT
+HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5
+IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl
+dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK
+ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
+9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
+be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
+ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
+MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
+A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
+ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
+WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
+Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
+qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
+4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIQIKTEf93f4cdTYwcTiHdgEjANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMTAxMDEwMDAw
+MDBaFw0zMDEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo0IwQDAdBgNVHQ4EFgQUC1jli8ZMFTekQKkwqSG+RzZaVv8w
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBAC/JxBwHO89hAgCx2SFRdXIDMLDEFh9sAIsQrK/xR9SuEDwMGvjUk2ysEDd8
+t6aDZK3N3w6HM503sMZ7OHKx8xoOo/lVem0DZgMXlUrxsXrfViEGQo+x06iF3u6X
+HWLrp+cxEmbDD6ZLLkGC9/3JG6gbr+48zuOcrigHoSybJMIPIyaDMouGDx8rEkYl
+Fo92kANr3ryqImhrjKGsKxE5pttwwn1y6TPn/CbxdFqR5p2ErPioBhlG5qfpqjQi
+pKGfeq23sqSaM4hxAjwu1nqyH6LKwN0vEJT9s4yEIHlG1QXUEOTS22RPuFvuG8Ug
+R1uUq27UlTMdphVx8fiUylQ5PsE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
+Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
+HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
+MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
+YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
+ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
+SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
+iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
+ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
+IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
+VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
+SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
+8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
+HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
+zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
+AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
+mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
+YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
+gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
+Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
+JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
+DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
+TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
+dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
+LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
+0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
+QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
+FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
+DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
+CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
+DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
+MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
+DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
+DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
+b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP
+L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY
+t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins
+S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3
+PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO
+L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3
+R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w
+dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS
++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS
+d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG
+AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f
+gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
+BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z
+NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt
+hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM
+QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf
+R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ
+DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW
+P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy
+lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq
+bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w
+AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
+r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
+Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
+98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
+U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
+MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh
+dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm
+acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN
+SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
+GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
+uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
+15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
+b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
+ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
+c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
+OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
+SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
+b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
+swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
+7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
+1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
+80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
+JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
+RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
+hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
+coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
+BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
+twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
+DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
+0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
+uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
+lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
+aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
+sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
+MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
+qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
+VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
+h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
+EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
+yeC2nOnOcXHebD8WpHk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
+j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
+1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
+A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
+AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
+MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
+Sw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
+WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
+b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
+b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
+7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
+CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
+EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
+VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
+kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
+gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE
+AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx
+MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT
+d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg
+MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX
+vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7
+LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX
+5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE
+EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt
+/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x
+0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5
+KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM
+0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd
+OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta
+clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK
+wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4
+DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL
+BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3
+10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz
+Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ
+iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc
+gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM
+ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF
+LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp
+zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td
+Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0
+rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO
+gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ
+MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
+IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5
+WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO
+LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P
+40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF
+avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/
+34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i
+JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu
+j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf
+Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP
+2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA
+S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA
+oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC
+kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW
+5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd
+BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB
+AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t
+tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn
+68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn
+TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t
+RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx
+f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI
+Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz
+8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4
+NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX
+xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6
+t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
+CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
+AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
+NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ
+MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq
+AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9
+vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9
+lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD
+n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT
+7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o
+6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC
+TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6
+WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R
+DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI
+pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj
+YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy
+rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ
+8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi
+0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM
+A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS
+SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K
+TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF
+6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er
+3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt
+Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
+VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
+ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
+rBPuUBQemMc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
diff --git a/common/certificate/mozilla.go b/common/certificate/mozilla.go
index 178bcad46c..551b00c447 100644
--- a/common/certificate/mozilla.go
+++ b/common/certificate/mozilla.go
@@ -2,13 +2,10 @@
package certificate
-import "crypto/x509"
-
-func newMozillaIncluded() *x509.CertPool {
- pool := x509.NewCertPool()
-
- // Actalis Authentication Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+func mozillaIncludedPEM() string {
+ return `
+// Actalis Authentication Root CA
+-----BEGIN CERTIFICATE-----
MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
@@ -40,10 +37,10 @@ K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TunTrust Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TunTrust Root CA
+-----BEGIN CERTIFICATE-----
MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
@@ -75,10 +72,10 @@ nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Amazon Root CA 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Amazon Root CA 1
+-----BEGIN CERTIFICATE-----
MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
@@ -97,10 +94,10 @@ N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
rqXRfboQnoZsG4q5WTP468SQvvG5
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Amazon Root CA 2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Amazon Root CA 2
+-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
@@ -130,10 +127,10 @@ n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
4PsJYGw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Amazon Root CA 3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Amazon Root CA 3
+-----BEGIN CERTIFICATE-----
MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
@@ -144,10 +141,10 @@ QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
YyRIHN8wfdVoOw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Amazon Root CA 4
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Amazon Root CA 4
+-----BEGIN CERTIFICATE-----
MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
@@ -159,10 +156,10 @@ M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
1KyLa2tJElMzrdfkviT8tQp21KW8EA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Starfield Services Root Certificate Authority - G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Starfield Services Root Certificate Authority - G2
+-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
@@ -185,10 +182,10 @@ qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certum CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certum CA
+-----BEGIN CERTIFICATE-----
MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
@@ -206,10 +203,10 @@ xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certum EC-384 CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certum EC-384 CA
+-----BEGIN CERTIFICATE-----
MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
@@ -223,10 +220,10 @@ QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certum Trusted Network CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certum Trusted Network CA
+-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
@@ -247,10 +244,10 @@ I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certum Trusted Network CA 2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certum Trusted Network CA 2
+-----BEGIN CERTIFICATE-----
MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
@@ -283,10 +280,10 @@ b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
DrW5viSP
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certum Trusted Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certum Trusted Root CA
+-----BEGIN CERTIFICATE-----
MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
@@ -318,10 +315,10 @@ P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Autoridad de Certificacion Firmaprofesional CIF A62634068
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Autoridad de Certificacion Firmaprofesional CIF A62634068
+-----BEGIN CERTIFICATE-----
MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
@@ -355,28 +352,10 @@ CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
------END CERTIFICATE-----`))
-
- // FIRMAPROFESIONAL CA ROOT-A WEB
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQsw
-CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
-YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
-IFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQsw
-CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
-YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
-IFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zf
-e9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6C
-cyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB
-/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0O
-BBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
-PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw
-hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG
-XSaQpYXFuXqUPoeovQA=
------END CERTIFICATE-----`))
-
- // ANF Secure Server Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// ANF Secure Server Root CA
+-----BEGIN CERTIFICATE-----
MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
@@ -409,10 +388,10 @@ OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Buypass Class 2 Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Buypass Class 2 Root CA
+-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
@@ -442,10 +421,10 @@ I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Buypass Class 3 Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Buypass Class 3 Root CA
+-----BEGIN CERTIFICATE-----
MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
@@ -475,10 +454,10 @@ kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certainly Root E1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certainly Root E1
+-----BEGIN CERTIFICATE-----
MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
@@ -490,10 +469,10 @@ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certainly Root R1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certainly Root R1
+-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
@@ -523,10 +502,10 @@ Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
OV+KmalBWQewLK8=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certigna
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certigna
+-----BEGIN CERTIFICATE-----
MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
@@ -547,10 +526,10 @@ fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Certigna Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Certigna Root CA
+-----BEGIN CERTIFICATE-----
MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
@@ -585,32 +564,10 @@ faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
------END CERTIFICATE-----`))
-
- // certSIGN ROOT CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
-AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
-QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
-MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
-0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
-UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
-RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
-OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
-JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
-AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
-BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
-LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
-MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
-44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
-Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
-i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
-9u6wWk5JRFRYX0KD
------END CERTIFICATE-----`))
-
- // certSIGN ROOT CA G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// certSIGN ROOT CA G2
+-----BEGIN CERTIFICATE-----
MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
@@ -640,10 +597,10 @@ pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
QRBdJ3NghVdJIgc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // ePKI Root Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// ePKI Root Certification Authority
+-----BEGIN CERTIFICATE-----
MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
@@ -675,10 +632,10 @@ o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // HiPKI Root CA - G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// HiPKI Root CA - G1
+-----BEGIN CERTIFICATE-----
MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
@@ -708,10 +665,10 @@ Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SecureSign Root CA12
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SecureSign Root CA12
+-----BEGIN CERTIFICATE-----
MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL
BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u
LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw
@@ -731,10 +688,10 @@ mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA
8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV
55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/
yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SecureSign Root CA14
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SecureSign Root CA14
+-----BEGIN CERTIFICATE-----
MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM
BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u
LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw
@@ -765,10 +722,10 @@ dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl
Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB
365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c
JRNItX+S
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SecureSign Root CA15
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SecureSign Root CA15
+-----BEGIN CERTIFICATE-----
MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw
UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM
dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy
@@ -781,10 +738,10 @@ Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT
9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp
4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6
bkU6iYAZezKYVWOr62Nuk22rGwlgMU4=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST BR Root CA 1 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST BR Root CA 1 2020
+-----BEGIN CERTIFICATE-----
MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
@@ -801,10 +758,10 @@ c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
dWNbFJWcHwHP2NVypw87
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST BR Root CA 2 2023
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST BR Root CA 2 2023
+-----BEGIN CERTIFICATE-----
MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI
MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw
@@ -836,10 +793,10 @@ ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS
Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80
knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ
hJ65bvspmZDogNOfJA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST EV Root CA 1 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST EV Root CA 1 2020
+-----BEGIN CERTIFICATE-----
MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
@@ -856,10 +813,10 @@ c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
gfM0agPnIjhQW+0ZT0MW
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST EV Root CA 2 2023
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST EV Root CA 2 2023
+-----BEGIN CERTIFICATE-----
MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI
MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw
@@ -891,10 +848,10 @@ ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT
gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst
Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh
XBxvWHZks/wCuPWdCg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST Root CA 3 2013
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST Root CA 3 2013
+-----BEGIN CERTIFICATE-----
MIIEDjCCAvagAwIBAgIDD92sMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxHzAdBgNVBAMMFkQtVFJVU1QgUm9vdCBD
QSAzIDIwMTMwHhcNMTMwOTIwMDgyNTUxWhcNMjgwOTIwMDgyNTUxWjBFMQswCQYD
@@ -917,10 +874,10 @@ t4RVLFzI9XRKEBmLo8ftNdYJSNMOwLo5qLBGArDbxohZwr78e7Erz35ih1WWzAFv
m2chlTWL+BD8cRu3SzdppjvW7IvuwbDzJcmPkn2h6sPKRL8mpXSSnON065102ctN
h9j8tGlsi6BDB2B4l+nZk3zCRrybN1Kj7Yo8E6l7U0tJmhEFLAtuVqwfLoJs4Gln
tQ5tLdnkwBXxP/oYcuEVbSdbLTAoK59ImmQrme/ydUlfXA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST Root Class 3 CA 2 2009
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST Root Class 3 CA 2 2009
+-----BEGIN CERTIFICATE-----
MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
@@ -944,10 +901,10 @@ o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
Johw1+qRzT65ysCQblrGXnRl11z+o+I=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-TRUST Root Class 3 CA 2 EV 2009
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-TRUST Root Class 3 CA 2 EV 2009
+-----BEGIN CERTIFICATE-----
MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
@@ -971,10 +928,10 @@ nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-Trust SBR Root CA 1 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-Trust SBR Root CA 1 2022
+-----BEGIN CERTIFICATE-----
MIICXjCCAeOgAwIBAgIQUs/kjG2gSvc/gpcMgAmMlTAKBggqhkjOPQQDAzBJMQsw
CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSMwIQYDVQQDExpELVRy
dXN0IFNCUiBSb290IENBIDEgMjAyMjAeFw0yMjA3MDYxMTMwMDBaFw0zNzA3MDYx
@@ -988,10 +945,10 @@ hjlodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Nicl9yb290X2Nh
XzFfMjAyMi5jcmwwCgYIKoZIzj0EAwMDaQAwZgIxAJf53q5Lj5i1HkB/Mn1NVEPa
ic3CqpI80YIec8/6TJIg+2MnxfVzPQk996dhhozzagIxAOcvfLj1JYw7OR82q431
hqIu4Xpk2mc5Av7+Mz/Zc7ZYWzr8sqTZYHh3zHmnpq5VvQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // D-Trust SBR Root CA 2 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// D-Trust SBR Root CA 2 2022
+-----BEGIN CERTIFICATE-----
MIIFrDCCA5SgAwIBAgIQVNWjlR49lbpyG5rQMSFKujANBgkqhkiG9w0BAQ0FADBJ
MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSMwIQYDVQQDExpE
LVRydXN0IFNCUiBSb290IENBIDIgMjAyMjAeFw0yMjA3MDcwNzMwMDBaFw0zNzA3
@@ -1023,10 +980,10 @@ JpmgVDuhEm1wYs7T+bi9IvzUmtS74jgWL7d9OcKwqQPpnM9+GI123F8Ru+tC7FAJ
PlzskDHYGnK6P2kH7pg0wjSk1toT1qmE8gCGwFS6HhGw4rnEB7SR56rmMVZvsUTE
KmK8ybBlnDT8DBpT3yEXu8JtoQrm8bCqRAlQSTh6XXHiMS4ZsN+VQgR9hIjOCiNn
azidFt4G/ihwOKVarvyD7Q==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // T-TeleSec GlobalRoot Class 2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// T-TeleSec GlobalRoot Class 2
+-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
@@ -1048,10 +1005,10 @@ IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
BSeOE6Fuwg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // T-TeleSec GlobalRoot Class 3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// T-TeleSec GlobalRoot Class 3
+-----BEGIN CERTIFICATE-----
MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
@@ -1073,10 +1030,10 @@ WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
TpPDpFQUWw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Telekom Security SMIME ECC Root 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Telekom Security SMIME ECC Root 2021
+-----BEGIN CERTIFICATE-----
MIICRzCCAc2gAwIBAgIQFSrdFMkY0aRWQIamJa8HXzAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
bWJIMS0wKwYDVQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIEVDQyBSb290IDIw
@@ -1090,10 +1047,10 @@ vZA6SzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQD
AwNoADBlAjEA1rxIkodHA8dwOyW2H65GZ3N0ACdL5KUEogPfXiitbl4DyN1onLa/
lBBIlS8P/xiLAjABQDOel5dNBfJ0VAzNOf1qawnBJD9hjjiht+jXRBURYv8OYTdH
S0B/Sl+yZ1pzdcI=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Telekom Security SMIME RSA Root 2023
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Telekom Security SMIME RSA Root 2023
+-----BEGIN CERTIFICATE-----
MIIFtzCCA5+gAwIBAgIQDH5i9XlzO51Djotj7ZGVuDANBgkqhkiG9w0BAQwFADBl
MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
eSBHbWJIMS0wKwYDVQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIFJTQSBSb290
@@ -1125,10 +1082,10 @@ NDnPpZo2qsjtebzP9s4EUwvaslAjfLw+Jq3wDkO7JsuuwkDeNx8KoFHNY522T9jG
R3y82LTtnovzEeKotT7srnA+fiK7NUgXYGIUkTCjdj2mUTaLHw3dajEcpe3dlqNu
cg8TTaqnqVx4+QMSGJM3RRKJPfi+yr3ZvgzZGGSnyEE+dYIhOH1l9KDUE0sHeCn5
nX7Mhz/E2i6I3eML3FpRWunZEk+eAtv3BSVR
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Telekom Security TLS ECC Root 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Telekom Security TLS ECC Root 2020
+-----BEGIN CERTIFICATE-----
MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw
CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw
@@ -1142,10 +1099,10 @@ MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di
z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn
27iQ7t0l
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Telekom Security TLS RSA Root 2023
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Telekom Security TLS RSA Root 2023
+-----BEGIN CERTIFICATE-----
MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj
MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy
@@ -1177,10 +1134,10 @@ L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj
X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q
ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm
dTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Assured ID Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Assured ID Root CA
+-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
@@ -1201,10 +1158,10 @@ fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Assured ID Root G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Assured ID Root G2
+-----BEGIN CERTIFICATE-----
MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
@@ -1225,10 +1182,10 @@ lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
IhNzbM8m9Yop5w==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Assured ID Root G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Assured ID Root G3
+-----BEGIN CERTIFICATE-----
MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
@@ -1242,10 +1199,10 @@ BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
6pZjamVFkpUBtA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Global Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Global Root CA
+-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
@@ -1266,10 +1223,10 @@ hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Global Root G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Global Root G2
+-----BEGIN CERTIFICATE-----
MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
@@ -1290,10 +1247,10 @@ Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
MrY=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Global Root G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Global Root G3
+-----BEGIN CERTIFICATE-----
MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
@@ -1307,10 +1264,10 @@ BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
sycX
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert High Assurance EV Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert High Assurance EV Root CA
+-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
@@ -1332,10 +1289,10 @@ hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert SMIME ECC P384 Root G5
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert SMIME ECC P384 Root G5
+-----BEGIN CERTIFICATE-----
MIICHDCCAaOgAwIBAgIQBT9uoAYBcn3tP8OjtqPW7zAKBggqhkjOPQQDAzBQMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKDAmBgNVBAMTH0Rp
Z2lDZXJ0IFNNSU1FIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
@@ -1348,10 +1305,10 @@ wmQyF/7gZ5AurTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
hkjOPQQDAwNnADBkAjA3RPUygONx6/Rtz3zMkZrDbnHY0iNdkk2CQm1cYZX2kfWn
CPZql+mclC2YcP0ztgkCMAc8L7lYgl4Po2Kok2fwIMNpvwMsO1CnO69BOMlSSJHW
Dvu8YDB8ZD8SHkV/UT70pg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert SMIME RSA4096 Root G5
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert SMIME RSA4096 Root G5
+-----BEGIN CERTIFICATE-----
MIIFajCCA1KgAwIBAgIQBfa6BCODRst9XOa5W7ocVTANBgkqhkiG9w0BAQwFADBP
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJzAlBgNVBAMT
HkRpZ2lDZXJ0IFNNSU1FIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAxMTUwMDAwMDBa
@@ -1381,10 +1338,10 @@ CQxy5BMjYEyjyhcue2cA29DN6nofOSZXiTB3y07llUVPX/s2XD35ILU6ECVPkzJa
7sGW6OlWBLBJYU3seKidGMH/2OovVu+VK3sEXmfjVUDtOQT5C3n1aoxcD4makMfN
i97bJjWhbs2zQvKiDzsMjpP/FM/895P35EEIbhlSEQ9TGXN4DM/YhYH4rVXIsJ5G
Y6+cUu5cv/DAWzceCSDSPiPGoRVKDjZ+MMV5arwiiNkMUkAf3U4PZyYW0q0XHA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert TLS ECC P384 Root G5
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert TLS ECC P384 Root G5
+-----BEGIN CERTIFICATE-----
MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
@@ -1397,10 +1354,10 @@ B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
DXZDjC5Ty3zfDBeWUA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert TLS RSA4096 Root G5
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert TLS RSA4096 Root G5
+-----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
@@ -1430,10 +1387,10 @@ p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DigiCert Trusted Root G4
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DigiCert Trusted Root G4
+-----BEGIN CERTIFICATE-----
MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
@@ -1464,10 +1421,10 @@ cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // QuoVadis Root CA 1 G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// QuoVadis Root CA 1 G3
+-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
@@ -1497,10 +1454,10 @@ NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // QuoVadis Root CA 2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// QuoVadis Root CA 2
+-----BEGIN CERTIFICATE-----
MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
@@ -1532,10 +1489,10 @@ mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // QuoVadis Root CA 2 G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// QuoVadis Root CA 2 G3
+-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
@@ -1565,10 +1522,10 @@ dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // QuoVadis Root CA 3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// QuoVadis Root CA 3
+-----BEGIN CERTIFICATE-----
MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
@@ -1605,10 +1562,10 @@ zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
4SVhM7JZG+Ju1zdXtg2pEto=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // QuoVadis Root CA 3 G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// QuoVadis Root CA 3 G3
+-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
@@ -1638,10 +1595,10 @@ u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DIGITALSIGN GLOBAL ROOT ECDSA CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DIGITALSIGN GLOBAL ROOT ECDSA CA
+-----BEGIN CERTIFICATE-----
MIICajCCAfCgAwIBAgIUNi2PcoiiKCfkAP8kxi3k6/qdtuEwCgYIKoZIzj0EAwMw
ZDELMAkGA1UEBhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmljYWRv
cmEgRGlnaXRhbDEpMCcGA1UEAwwgRElHSVRBTFNJR04gR0xPQkFMIFJPT1QgRUNE
@@ -1655,10 +1612,10 @@ GDAWgBTOr0qLGnXi8TjnAvAWrV7qZNV7tDAdBgNVHQ4EFgQUzq9Kixp14vE45wLw
Fq1e6mTVe7QwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMAqIxHGc
RANNjbTHvKiu2TAnNWprFmPX/OdZ4aeJG0wxmiNVRObzQyHVRydvbVcBqgIxAPuy
6uKXf1G1n0jrvG81iahkcKtXds3AxhRgyn/iggBz98w16o4km+UIWccEjHN4/g==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // DIGITALSIGN GLOBAL ROOT RSA CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// DIGITALSIGN GLOBAL ROOT RSA CA
+-----BEGIN CERTIFICATE-----
MIIFtTCCA52gAwIBAgIUXVnIyqsJV/XmtdoplARq/8XUlYcwDQYJKoZIhvcNAQEN
BQAwYjELMAkGA1UEBhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmlj
YWRvcmEgRGlnaXRhbDEnMCUGA1UEAwweRElHSVRBTFNJR04gR0xPQkFMIFJPT1Qg
@@ -1690,10 +1647,10 @@ NrskGnkcUdH+E7v/eCzcpL4v9sVLU8+nTJlecKxZiASuZAS/e6Z6TdPod72hflAV
8+9JMIVNIVeq2yx1l62BAYeisXCdHgZaA2CxP6ZtgizUFLGBpeg9iB20cixYN4qO
OJS4c92p4Lj2d6KzfFjermk6tYulGrvy2HQGnP1icyAhdrF+cJ4Z1OsXYhk4mc02
K0f+McvfueSsCNPYpuvUnn5LZKRVXSsXyQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // CA Disig Root R2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// CA Disig Root R2
+-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
@@ -1723,44 +1680,10 @@ gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
------END CERTIFICATE-----`))
-
- // GLOBALTRUST 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG
-A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw
-FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx
-MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u
-aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b
-RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z
-YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3
-QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw
-yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+
-BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ
-SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH
-r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0
-4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me
-dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw
-q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2
-nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu
-H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
-VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC
-XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd
-6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf
-+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi
-kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7
-wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB
-TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C
-MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn
-4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I
-aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy
-qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
------END CERTIFICATE-----`))
-
- // emSign ECC Root CA - C3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// emSign ECC Root CA - C3
+-----BEGIN CERTIFICATE-----
MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG
EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx
IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw
@@ -1773,10 +1696,10 @@ BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c
3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J
0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // emSign ECC Root CA - G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// emSign ECC Root CA - G3
+-----BEGIN CERTIFICATE-----
MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
@@ -1790,10 +1713,10 @@ zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
+JbNR6iC8hZVdyR+EhCVBCyj
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // emSign Root CA - C1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// emSign Root CA - C1
+-----BEGIN CERTIFICATE-----
MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG
A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg
SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw
@@ -1813,10 +1736,10 @@ kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG
YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT
+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo
WXzhriKi4gp6D/piq1JM4fHfyr6DDUI=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // emSign Root CA - G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// emSign Root CA - G1
+-----BEGIN CERTIFICATE-----
MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
@@ -1837,102 +1760,10 @@ GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
iN66zB+Afko=
------END CERTIFICATE-----`))
-
- // AffirmTrust Commercial
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
-Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
-ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
-MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
-yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
-VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
-nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
-XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
-vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
-Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
-N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
-nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
------END CERTIFICATE-----`))
-
- // AffirmTrust Networking
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
-YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
-kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
-QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
-6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
-yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
-QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
-tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
-QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
-Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
-olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
-x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
------END CERTIFICATE-----`))
-
- // AffirmTrust Premium
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
-dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
-A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
-cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
-qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
-JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
-+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
-s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
-HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
-70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
-V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
-qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
-5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
-C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
-OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
-FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
-KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
-Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
-8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
-MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
-0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
-u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
-u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
-YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
-GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
-RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
-KeC2uAloGRwYQw==
------END CERTIFICATE-----`))
-
- // AffirmTrust Premium ECC
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
-VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
-cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
-BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
-VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
-0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
-ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
-A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
-aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
-flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
------END CERTIFICATE-----`))
-
- // Atos TrustedRoot 2011
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// Atos TrustedRoot 2011
+-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
@@ -1952,10 +1783,10 @@ DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Atos TrustedRoot Root CA ECC G2 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Atos TrustedRoot Root CA ECC G2 2020
+-----BEGIN CERTIFICATE-----
MIICMTCCAbagAwIBAgIMC3MoERh0MBzvbwiEMAoGCCqGSM49BAMDMEsxCzAJBgNV
BAYTAkRFMQ0wCwYDVQQKDARBdG9zMS0wKwYDVQQDDCRBdG9zIFRydXN0ZWRSb290
IFJvb3QgQ0EgRUNDIEcyIDIwMjAwHhcNMjAxMjE1MDgzOTEwWhcNNDAxMjEwMDgz
@@ -1968,10 +1799,10 @@ shufvlwfjP2ztvuzDgmHMB0GA1UdDgQWBBRbH8RxbLIbn75cH4z9s7b7sw4JhzAO
BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaQAwZgIxAOzgmf3d5FTByx/oPijX
FVlKgspTMOzrNqW5yM6TR1bIYabhbZJTlY/241VT8N165wIxALCH1RuzYPyRjYDK
ohtRSzhUy6oee9flRJUWLzxEeC4luuqQ5OxS7lfsA4TzXtsWDQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Atos TrustedRoot Root CA ECC TLS 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Atos TrustedRoot Root CA ECC TLS 2021
+-----BEGIN CERTIFICATE-----
MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
@@ -1984,10 +1815,10 @@ KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
9H1/IISpQuQo
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Atos TrustedRoot Root CA RSA G2 2020
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Atos TrustedRoot Root CA RSA G2 2020
+-----BEGIN CERTIFICATE-----
MIIFfzCCA2egAwIBAgIMR7opRlU+FpKXsKtAMA0GCSqGSIb3DQEBDAUAMEsxCzAJ
BgNVBAYTAkRFMQ0wCwYDVQQKDARBdG9zMS0wKwYDVQQDDCRBdG9zIFRydXN0ZWRS
b290IFJvb3QgQ0EgUlNBIEcyIDIwMjAwHhcNMjAxMjE1MDg0MTIzWhcNNDAxMjEw
@@ -2018,10 +1849,10 @@ VD190nZ12V4+MkinjPKecgz4uFi4FyOlFId1WHoAgQciOWpMlKC1otunLMGw8aOb
wEz3bXDqMZ/xrn0+cyjZod/6k/CbsPDizSUgde/ifTIFyZt27su9MR75lJhLJFhW
SMDeBky9pjRd7RZhY3P7GeL6W9iXddRtnmA5XpSLAizrmc5gKm4bjKdLvP025pgf
ZfJ/8eOPTIBGNli2oWXLzhxEdQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Atos TrustedRoot Root CA RSA TLS 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Atos TrustedRoot Root CA RSA TLS 2021
+-----BEGIN CERTIFICATE-----
MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
@@ -2051,10 +1882,10 @@ AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign
+-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
@@ -2085,10 +1916,26 @@ pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
+
+// GlobalSign
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
- // GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign
+-----BEGIN CERTIFICATE-----
MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
@@ -2108,26 +1955,10 @@ jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
-MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
-bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
-DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
-QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
-MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
-8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
-hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
-KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
-515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
-xwy8p2Fp8fc74SrL+SvzZpA3
------END CERTIFICATE-----`))
-
- // GlobalSign Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign Root CA
+-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
@@ -2147,10 +1978,10 @@ yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign Root E46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign Root E46
+-----BEGIN CERTIFICATE-----
MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
@@ -2162,10 +1993,10 @@ yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign Root R46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign Root R46
+-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
@@ -2195,10 +2026,10 @@ u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign Secure Mail Root E45
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign Secure Mail Root E45
+-----BEGIN CERTIFICATE-----
MIICITCCAaegAwIBAgIQdlP+qicdlUZd1vGe5biQCjAKBggqhkjOPQQDAzBSMQsw
CQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UEAxMf
R2xvYmFsU2lnbiBTZWN1cmUgTWFpbCBSb290IEU0NTAeFw0yMDAzMTgwMDAwMDBa
@@ -2211,10 +2042,10 @@ DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU3xNei1/CQAL9VreUTLYe1aaxFJYw
CgYIKoZIzj0EAwMDaAAwZQIwE7C+13EgPuSrnM42En1fTB8qtWlFM1/TLVqy5IjH
3go2QjJ5naZruuH5RCp7isMSAjEAoGYcToedh8ntmUwbCu4tYMM3xx3NtXKw2cbv
vPL/P/BS3QjnqmR5w+RpV5EvpMt8
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign Secure Mail Root R45
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign Secure Mail Root R45
+-----BEGIN CERTIFICATE-----
MIIFcDCCA1igAwIBAgIQdlP+qExQq5+NMrUdA49X3DANBgkqhkiG9w0BAQwFADBS
MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UE
AxMfR2xvYmFsU2lnbiBTZWN1cmUgTWFpbCBSb290IFI0NTAeFw0yMDAzMTgwMDAw
@@ -2245,10 +2076,10 @@ l+6NJllXu3jwelAwCbBgqp9O3Mk+HjrcYpMzsDpUdG8sMUXRaxEyamh29j32ahNe
JJjn6h2az3iCB2D3TRDTgZpFjZ6vm9yAx0OylWikww7oCkcVv1Qz3AHn1aYec9h6
sr8vreNVMJ7fDkG84BH1oQyoIuHjAKNOcHyS4wTRekKKdZBZ45vRTKJkvXN5m2/y
s8H2PA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Go Daddy Class 2 Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Go Daddy Class 2 Certification Authority
+-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
@@ -2271,10 +2102,10 @@ TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Go Daddy Root Certificate Authority - G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Go Daddy Root Certificate Authority - G2
+-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
@@ -2296,10 +2127,10 @@ gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
4uJEvlz36hz1
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Starfield Class 2 Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Starfield Class 2 Certification Authority
+-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
@@ -2322,10 +2153,10 @@ eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Starfield Root Certificate Authority - G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Starfield Root Certificate Authority - G2
+-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
@@ -2347,10 +2178,10 @@ sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GlobalSign
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GlobalSign
+-----BEGIN CERTIFICATE-----
MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
@@ -2361,10 +2192,10 @@ uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GTS Root R1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GTS Root R1
+-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
@@ -2394,10 +2225,10 @@ Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GTS Root R2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GTS Root R2
+-----BEGIN CERTIFICATE-----
MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
@@ -2427,10 +2258,10 @@ TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GTS Root R3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GTS Root R3
+-----BEGIN CERTIFICATE-----
MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
@@ -2442,10 +2273,10 @@ jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // GTS Root R4
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// GTS Root R4
+-----BEGIN CERTIFICATE-----
MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
@@ -2457,10 +2288,10 @@ HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Hongkong Post Root CA 3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Hongkong Post Root CA 3
+-----BEGIN CERTIFICATE-----
MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL
BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ
SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n
@@ -2493,10 +2324,10 @@ JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP
L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
mpv0
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // ACCVRAIZ1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// ACCVRAIZ1
+-----BEGIN CERTIFICATE-----
MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
@@ -2539,10 +2370,10 @@ I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // AC RAIZ FNMT-RCM
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// AC RAIZ FNMT-RCM
+-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
@@ -2573,10 +2404,10 @@ fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // AC RAIZ FNMT-RCM SERVIDORES SEGUROS
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// AC RAIZ FNMT-RCM SERVIDORES SEGUROS
+-----BEGIN CERTIFICATE-----
MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
@@ -2591,10 +2422,10 @@ VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
v+c=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Staat der Nederlanden Root CA - G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Staat der Nederlanden Root CA - G3
+-----BEGIN CERTIFICATE-----
MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
@@ -2625,10 +2456,10 @@ fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
94B7IWcnMFk=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
+-----BEGIN CERTIFICATE-----
MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
@@ -2653,10 +2484,10 @@ IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // HARICA Client ECC Root CA 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// HARICA Client ECC Root CA 2021
+-----BEGIN CERTIFICATE-----
MIICWjCCAeGgAwIBAgIQMWjZ2OFiVx7SGUSI5hB98DAKBggqhkjOPQQDAzBvMQsw
CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
cmNoIEluc3RpdHV0aW9ucyBDQTEnMCUGA1UEAwweSEFSSUNBIENsaWVudCBFQ0Mg
@@ -2670,10 +2501,10 @@ AQH/BAUwAwEB/zAdBgNVHQ4EFgQUUgjSvjKBJf31GpfsTl8au1PNkK0wDgYDVR0P
AQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMEwxRUZPqOa+w3eyGhhLLYh7WOar
lGtEA7AX/9+Cc0RRLP2THQZ7FNKJ7EAM7yEBLgIwL8kuWmwsHdmV4J6wuVxSfPb4
OMou8dQd8qJJopX4wVheT/5zCu8xsKsjWBOMi947
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // HARICA Client RSA Root CA 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// HARICA Client RSA Root CA 2021
+-----BEGIN CERTIFICATE-----
MIIFqjCCA5KgAwIBAgIQVVL4HtsbJCyeu5YYzQIoPjANBgkqhkiG9w0BAQsFADBv
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEnMCUGA1UEAwweSEFSSUNBIENsaWVudCBS
@@ -2705,10 +2536,10 @@ ndSV9ZmqRuqurL/0FBkk6Izs4/W8BmiKKgwFXwqXdafcfsD913oY3zDROEsfsJhw
v8x8c/BuxDGlpJcdrL/ObCFKvicjZ/MGVoEKkY624QMFMyzaNAhNTlAjrR+lxdR6
/uoJ7KcoYItGfLXqm91P+edrFcaIz0Pb5SfcBFZub0YV8VYt6FwMc8MjgTggy8kM
ac8sqzuEYDMZUv1pFDM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // HARICA TLS ECC Root CA 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// HARICA TLS ECC Root CA 2021
+-----BEGIN CERTIFICATE-----
MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
@@ -2722,10 +2553,10 @@ AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // HARICA TLS RSA Root CA 2021
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// HARICA TLS RSA Root CA 2021
+-----BEGIN CERTIFICATE-----
MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
@@ -2757,10 +2588,10 @@ BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
63ZTGI0RmLo=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Hellenic Academic and Research Institutions ECC RootCA 2015
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Hellenic Academic and Research Institutions ECC RootCA 2015
+-----BEGIN CERTIFICATE-----
MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
@@ -2776,10 +2607,10 @@ MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Hellenic Academic and Research Institutions RootCA 2015
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Hellenic Academic and Research Institutions RootCA 2015
+-----BEGIN CERTIFICATE-----
MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
@@ -2813,10 +2644,10 @@ bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
vm9qp/UsQu0yrbYhnr68
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // IdenTrust Commercial Root CA 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// IdenTrust Commercial Root CA 1
+-----BEGIN CERTIFICATE-----
MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
@@ -2846,10 +2677,10 @@ l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // IdenTrust Public Sector Root CA 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// IdenTrust Public Sector Root CA 1
+-----BEGIN CERTIFICATE-----
MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
@@ -2879,10 +2710,10 @@ WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // ISRG Root X1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// ISRG Root X1
+-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
@@ -2912,10 +2743,10 @@ oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // ISRG Root X2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// ISRG Root X2
+-----BEGIN CERTIFICATE-----
MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
@@ -2928,10 +2759,10 @@ AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
/q4AaOeMSQ+2b1tbFfLn
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Izenpe.com
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Izenpe.com
+-----BEGIN CERTIFICATE-----
MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
@@ -2964,10 +2795,10 @@ UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SZAFIR ROOT CA2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SZAFIR ROOT CA2
+-----BEGIN CERTIFICATE-----
MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
@@ -2987,10 +2818,10 @@ nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // LAWtrust Root CA2 (4096)
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// LAWtrust Root CA2 (4096)
+-----BEGIN CERTIFICATE-----
MIIFmDCCA4CgAwIBAgIEVRpusTANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJa
QTERMA8GA1UEChMITEFXdHJ1c3QxITAfBgNVBAMTGExBV3RydXN0IFJvb3QgQ0Ey
ICg0MDk2KTAgFw0yMzAyMTQwOTE5MzhaGA8yMDUzMDIxNDA5NDkzOFowQzELMAkG
@@ -3021,10 +2852,10 @@ NAdigkz0fseHdA6wIR4JIIDBsxU9Rm3T8QaSP++glYocbncxtut4KQx77oKlT36k
KV6eqi34jsDz/A0GhZtO3PfiCXzQFFEeerMjr/rRYSpltQHZuOMHyiR20vBKvu+G
BIBCFXARaH7Xx7v+506bnJWlHEqkydAJjKrOSNIekpfXEentZsw33PXXG3SbpupC
rF0y4Fj0gUf/0hLifhzcSXaWwx2fS8pcKjdbPYrROJsh2uO/RUPT4Fh3Hyg=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // e-Szigno Root CA 2017
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// e-Szigno Root CA 2017
+-----BEGIN CERTIFICATE-----
MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
@@ -3038,10 +2869,30 @@ A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
+efcMQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Microsec e-Szigno Root CA 2009
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// e-Szigno TLS Root CA 2023
+-----BEGIN CERTIFICATE-----
+MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU
+TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow
+dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy
+b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T
+emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE
+AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS
+AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v
+SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K
+ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI
+zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt
+y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl
+C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6
+uWWL
+-----END CERTIFICATE-----
+
+// Microsec e-Szigno Root CA 2009
+-----BEGIN CERTIFICATE-----
MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
@@ -3064,10 +2915,10 @@ ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Microsoft ECC Root Certificate Authority 2017
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Microsoft ECC Root Certificate Authority 2017
+-----BEGIN CERTIFICATE-----
MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
@@ -3081,10 +2932,10 @@ BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Microsoft RSA Root Certificate Authority 2017
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Microsoft RSA Root Certificate Authority 2017
+-----BEGIN CERTIFICATE-----
MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
@@ -3116,10 +2967,10 @@ GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
RA+GsCyRxj3qrg+E
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // NAVER Global Root Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// NAVER Global Root Certification Authority
+-----BEGIN CERTIFICATE-----
MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
@@ -3151,10 +3002,10 @@ LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
9XXeifdy
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // NetLock Arany (Class Gold) Főtanúsítvány
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// NetLock Arany (Class Gold) Főtanúsítvány
+-----BEGIN CERTIFICATE-----
MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
@@ -3177,10 +3028,10 @@ bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE Client Root ECC G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE Client Root ECC G1
+-----BEGIN CERTIFICATE-----
MIICNDCCAbqgAwIBAgIQVOyX1ou0xAshbg6y0FPIejAKBggqhkjOPQQDAzBLMQsw
CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY
T0lTVEUgQ2xpZW50IFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0MzE0MFoXDTQ4MDUy
@@ -3193,10 +3044,10 @@ Vzs5sS0AjCFmjJVpnG117Iw/+jAdBgNVHQ4EFgQUmVc7ObEtAIwhZoyVaZxtdeyM
P/owDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMQCW/+SCThYiW6CF
GDw9Oo8gBggl5/WRNhmte7TfW2YSN3Nw7c0FKAdeCM4NQl8ZkQICMGdJh64GQR0g
0zGmqiY38SeKYQ3+mgZDpy6eJkejMhiL6F5QBfGwekh23tuhYkq6dw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE Client Root RSA G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE Client Root RSA G1
+-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIQNBdvWQGIG6ql3chIu7Q7czANBgkqhkiG9w0BAQwFADBL
MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE
AwwYT0lTVEUgQ2xpZW50IFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MjMyOVoXDTQ4
@@ -3227,10 +3078,10 @@ keWTDnWRrqMjIElk1Lo5lldw7lU0KHzWr8qpnubJAckHwdBEsYC0UVCqj/ac5Wdz
ao6jC2rW/ZMMimHLvSjxX3H9uDM51krx9rJoUj5lj0OdgSQk9ihMNaf9MwqleMEE
H+xJasSu1UQWpqeNf9ohlj6ouhZn1Kmh58Ka+BDZO5ruaPYvAO7Lu2aNIjiG9L9f
eKnIoB1au3VQ+VILDx0CLBQa84dqd/M=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE Server Root ECC G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE Server Root ECC G1
+-----BEGIN CERTIFICATE-----
MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw
CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY
T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy
@@ -3243,10 +3094,10 @@ TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C
tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR
QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD
YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE Server Root RSA G1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE Server Root RSA G1
+-----BEGIN CERTIFICATE-----
MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL
MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE
AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4
@@ -3277,10 +3128,10 @@ YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1
J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2
wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy
BiElxky8j3C7DOReIoMt0r7+hVu05L0=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE WISeKey Global Root GA CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE WISeKey Global Root GA CA
+-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
@@ -3303,10 +3154,10 @@ vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
/L7fCg0=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE WISeKey Global Root GB CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE WISeKey Global Root GB CA
+-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
@@ -3327,10 +3178,10 @@ gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // OISTE WISeKey Global Root GC CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// OISTE WISeKey Global Root GC CA
+-----BEGIN CERTIFICATE-----
MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
@@ -3344,10 +3195,10 @@ BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Security Communication ECC RootCA1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Security Communication ECC RootCA1
+-----BEGIN CERTIFICATE-----
MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
@@ -3360,10 +3211,10 @@ ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Security Communication RootCA2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Security Communication RootCA2
+-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
@@ -3383,10 +3234,10 @@ okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // AAA Certificate Services
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// AAA Certificate Services
+-----BEGIN CERTIFICATE-----
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
@@ -3410,10 +3261,10 @@ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // COMODO Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// COMODO Certification Authority
+-----BEGIN CERTIFICATE-----
MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
@@ -3437,10 +3288,10 @@ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
ZQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // COMODO ECC Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// COMODO ECC Certification Authority
+-----BEGIN CERTIFICATE-----
MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
@@ -3455,10 +3306,10 @@ BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // COMODO RSA Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// COMODO RSA Certification Authority
+-----BEGIN CERTIFICATE-----
MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
@@ -3491,10 +3342,10 @@ S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
NVOFBkpdn627G190
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Entrust Root Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Entrust Root Certification Authority
+-----BEGIN CERTIFICATE-----
MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
@@ -3520,10 +3371,10 @@ AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
0vdXcDazv/wor3ElhVsT/h5/WrQ8
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Entrust Root Certification Authority - EC1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Entrust Root Certification Authority - EC1
+-----BEGIN CERTIFICATE-----
MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
@@ -3540,10 +3391,10 @@ Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Entrust Root Certification Authority - G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Entrust Root Certification Authority - G2
+-----BEGIN CERTIFICATE-----
MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
@@ -3567,10 +3418,10 @@ Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Entrust Root Certification Authority - G4
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Entrust Root Certification Authority - G4
+-----BEGIN CERTIFICATE-----
MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw
gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL
Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg
@@ -3605,10 +3456,10 @@ b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk
IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Entrust.net Certification Authority (2048)
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Entrust.net Certification Authority (2048)
+-----BEGIN CERTIFICATE-----
MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
@@ -3632,10 +3483,10 @@ zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
fF6adulZkMV8gzURZVE=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Sectigo Public Email Protection Root E46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Sectigo Public Email Protection Root E46
+-----BEGIN CERTIFICATE-----
MIICMTCCAbegAwIBAgIQbvXTp0GOoFlApzBr0kBlVjAKBggqhkjOPQQDAzBaMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTEwLwYDVQQDEyhT
ZWN0aWdvIFB1YmxpYyBFbWFpbCBQcm90ZWN0aW9uIFJvb3QgRTQ2MB4XDTIxMDMy
@@ -3648,10 +3499,10 @@ HQYDVR0OBBYEFC1OjKfCI7JXqQZrPmsrifPDXkfOMA4GA1UdDwEB/wQEAwIBhjAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCSnRpZY0VYjhsW5H16
bDZIMB8rcueQMzT9JKLGBoxvOzJXWvj+xkkSU5rZELKZUXICMAUlKjMh/JPmIqLM
cFUoNVaiB8QhhCMaTEyZUJmSFMtK3Fb79dOPaiz1cTr4izsDng==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Sectigo Public Email Protection Root R46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Sectigo Public Email Protection Root R46
+-----BEGIN CERTIFICATE-----
MIIFgDCCA2igAwIBAgIQHUSeuQ2DkXSu3fLriLemozANBgkqhkiG9w0BAQwFADBa
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTEwLwYDVQQD
EyhTZWN0aWdvIFB1YmxpYyBFbWFpbCBQcm90ZWN0aW9uIFJvb3QgUjQ2MB4XDTIx
@@ -3682,10 +3533,10 @@ IS+0AlmzLdBykLoLFHR4S8/BX1VyjlQrE876WAzTuyzZqZFh+PjxtnvevKnMkgTM
S2tfc4C2Ie1QT9d2h27O39K3vWKhfVhiaEVStj/eEtvtBGmedoiqAW3ahsdgG8NS
rDfsUHGAciohRQpTRzwZ643SWQTeJbDrHzVvYH3Xtca7CyeN4E1U5c8dJgFuOzXI
IBKJg/DS7Vg7NJ27MfUy/THzVho=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Sectigo Public Server Authentication Root E46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Sectigo Public Server Authentication Root E46
+-----BEGIN CERTIFICATE-----
MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
@@ -3698,10 +3549,10 @@ WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Sectigo Public Server Authentication Root R46
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Sectigo Public Server Authentication Root R46
+-----BEGIN CERTIFICATE-----
MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
@@ -3732,10 +3583,10 @@ dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // USERTrust ECC Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// USERTrust ECC Certification Authority
+-----BEGIN CERTIFICATE-----
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
@@ -3750,10 +3601,10 @@ A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // USERTrust RSA Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// USERTrust RSA Certification Authority
+-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
@@ -3786,10 +3637,10 @@ qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
jjxDah2nGN59PRbxYvnKkKj9
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com Client ECC Root CA 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com Client ECC Root CA 2022
+-----BEGIN CERTIFICATE-----
MIICQDCCAcagAwIBAgIQdvhIHq7wPHAf4D8lVAGD1TAKBggqhkjOPQQDAzBRMQsw
CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQDDB9T
U0wuY29tIENsaWVudCBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzAzMloX
@@ -3803,10 +3654,10 @@ U81SGi9dYKDDXfuyHBwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUC
ME0HES0R+7kmwyHdcuEX/MHPFOpJznGHjtZT3BHNXVSKr9kt9IxR6rxmR+J/lYNg
ZQIxAIwhTE+75bBQ35BiSebMkdv4P11xkQiOT5LJf6Zc6hN+7W3E6MMqb1wR4aXz
alqaTQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com Client RSA Root CA 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com Client RSA Root CA 2022
+-----BEGIN CERTIFICATE-----
MIIFjzCCA3egAwIBAgIQdq/uiJMVRbZQU5uAnKTfmjANBgkqhkiG9w0BAQsFADBR
MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQD
DB9TU0wuY29tIENsaWVudCBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzEw
@@ -3837,10 +3688,10 @@ miZPPiDPT0PzEIx/EGF6NsqqC33Mn0dEWa6llcaZU+MHaz1JELAY/10OhUMUS+dr
OdmsupJ13UPKugGVrRqBKzrw48UvDBhNEMauwO3+BVJ/GQXLqa81CAw4IuT+VuVT
Pr/k1rPZCMM91TMygSTFqeFlEbgyMzBxGEkdGkXGmhSKWDkobvPLUblJJmR4A8eR
EYOpuZA0tm+qBZ6FKFeZvn8nBkliTaH8CeErRglMFJtWj0U=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com EV Root Certification Authority ECC
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com EV Root Certification Authority ECC
+-----BEGIN CERTIFICATE-----
MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
@@ -3855,10 +3706,10 @@ MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com EV Root Certification Authority RSA R2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com EV Root Certification Authority RSA R2
+-----BEGIN CERTIFICATE-----
MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
@@ -3891,10 +3742,10 @@ QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com Root Certification Authority ECC
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com Root Certification Authority ECC
+-----BEGIN CERTIFICATE-----
MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
@@ -3909,10 +3760,10 @@ EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com Root Certification Authority RSA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com Root Certification Authority RSA
+-----BEGIN CERTIFICATE-----
MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
@@ -3945,10 +3796,10 @@ K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
Ic2wBlX7Jz9TkHCpBB5XJ7k=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com TLS ECC Root CA 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com TLS ECC Root CA 2022
+-----BEGIN CERTIFICATE-----
MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
@@ -3961,10 +3812,10 @@ GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SSL.com TLS RSA Root CA 2022
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SSL.com TLS RSA Root CA 2022
+-----BEGIN CERTIFICATE-----
MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
@@ -3995,10 +3846,10 @@ AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SwissSign Gold CA - G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SwissSign Gold CA - G2
+-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
@@ -4030,10 +3881,10 @@ hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SwissSign RSA SMIME Root CA 2022 - 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SwissSign RSA SMIME Root CA 2022 - 1
+-----BEGIN CERTIFICATE-----
MIIFlzCCA3+gAwIBAgIURg7UAXGQoBqDLEpCECgV0mEbrTIwDQYJKoZIhvcNAQEL
BQAwUzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEtMCsGA1UE
AxMkU3dpc3NTaWduIFJTQSBTTUlNRSBSb290IENBIDIwMjIgLSAxMB4XDTIyMDYw
@@ -4064,10 +3915,10 @@ PJPEP3ZOfmKiKcsWMN4saa+Rp+JX5TNMv9iOB6J/oTVGaUqoICn/694glVmxrk0w
a9iatAMfwjjkINUO1howTGicjODtoQ+OQl3rgCoSeaYXF7SVKo40kae90ayoGkMh
i97v4KxGJWUKxiuhmz4i6Bg4tSb2LMoIIN4w0a1U/dxIFZ/Np0HXNziFME8SiEM0
g9cqTdQAV1zlyvDd4ZIoKxh1vUekQhPpVlqNSl7ODnU1gHMZDywpi7uVuA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // SwissSign RSA TLS Root CA 2022 - 1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// SwissSign RSA TLS Root CA 2022 - 1
+-----BEGIN CERTIFICATE-----
MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL
BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE
AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx
@@ -4098,10 +3949,10 @@ zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td
Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0
rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO
gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TWCA CYBER Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TWCA CYBER Root CA
+-----BEGIN CERTIFICATE-----
MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ
MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5
@@ -4132,10 +3983,10 @@ Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz
NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX
xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6
t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TWCA Global Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TWCA Global Root CA
+-----BEGIN CERTIFICATE-----
MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
@@ -4165,10 +4016,10 @@ nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
KwbQBM0=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TWCA Global Root CA G2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TWCA Global Root CA G2
+-----BEGIN CERTIFICATE-----
MIIFlTCCA32gAwIBAgIQQAE0jMIAAAAAAAAAAZdY9DANBgkqhkiG9w0BAQwFADBU
MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
IENBMR8wHQYDVQQDExZUV0NBIEdsb2JhbCBSb290IENBIEcyMB4XDTIyMTEyMjA2
@@ -4199,10 +4050,10 @@ UamsVsAhTqMUdAU6vOO/bT1OP16lpG0pv4RRdVOOhhr1UXAqDRxOQOH9o+OlK2eQ
ksdsroW/OpsXFcqcKpPUTTkNvCAIo42IbAkNjK5EIU3JcezYJtcXni0RGDyjIn24
J1S/aMg7QsyPXk7n3MLF+mpED41WiHrfiYRsoLM+PfFlAAmI6irrQM6zXawyF67B
m+nQwfVJlN2nznxaB+uuIJwXMJJpk3Lzmltxm/5q33owaY6zLtsPLN0=
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TWCA Root Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TWCA Root Certification Authority
+-----BEGIN CERTIFICATE-----
MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
@@ -4222,10 +4073,10 @@ XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // Telia Root CA v2
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// Telia Root CA v2
+-----BEGIN CERTIFICATE-----
MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
@@ -4256,42 +4107,10 @@ Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
rBPuUBQemMc=
------END CERTIFICATE-----`))
-
- // TeliaSonera Root CA v1
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
-NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
-b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
-VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
-MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
-VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
-7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
-Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
-/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
-81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
-dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
-Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
-sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
-pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
-slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
-arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
-VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
-9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
-dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
-0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
-TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
-Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
-Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
-OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
-vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
-t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
-HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
-SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
------END CERTIFICATE-----`))
-
- // TrustAsia Global Root CA G3
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+-----END CERTIFICATE-----
+
+// TrustAsia Global Root CA G3
+-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM
BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp
ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe
@@ -4323,10 +4142,10 @@ AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d
gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV
+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo
FGWsJwt0ivKH
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TrustAsia Global Root CA G4
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TrustAsia Global Root CA G4
+-----BEGIN CERTIFICATE-----
MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw
WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y
@@ -4340,10 +4159,10 @@ pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE
AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR
UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj
/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TrustAsia SMIME ECC Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TrustAsia SMIME ECC Root CA
+-----BEGIN CERTIFICATE-----
MIICNjCCAbugAwIBAgIUWsL4KU/jfcVeHRhvO5MgH/97ui0wCgYIKoZIzj0EAwMw
WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xJDAiBgNVBAMTG1RydXN0QXNpYSBTTUlNRSBFQ0MgUm9vdCBDQTAeFw0y
@@ -4356,10 +4175,10 @@ QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFDFn5nKyDeYioKzPfiKnWTLj
ZiOlMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNpADBmAjEA3TpMjaTGf+29
pcZPPv0xSyjWilbfZRZ3h037ujIIgeCeM0iLn5SG7wErlOaM1tSOAjEAn4GcsCb9
K9by9XGEnqjHiozWWBFStbgEy8xxdWPixhk42W1sGXGkFhkhk7oGRChs
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TrustAsia SMIME RSA Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TrustAsia SMIME RSA Root CA
+-----BEGIN CERTIFICATE-----
MIIFhDCCA2ygAwIBAgIUWu5x394MV4W1uzYi17h2RgJzyv8wDQYJKoZIhvcNAQEM
BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp
ZXMsIEluYy4xJDAiBgNVBAMTG1RydXN0QXNpYSBTTUlNRSBSU0EgUm9vdCBDQTAe
@@ -4390,10 +4209,10 @@ fuF0t/aBauQjrI79jzUdmnEKTypVL/4YwQD3e0iKZa9vCB1D51q4H6ToA+v9TLW0
k6gx3kOdEr3n6aTS32/8b0aj7zFOjRerG6ng+Kk0VqEO53TsqIeF2Hc1S40+bnJ8
SMwfcrNxdNQkhrzIwON5FAHO2fqBxlyz+V0MOL7O8o6NXz0l4VE5I6jqAI4Es79y
oMK6g/vNpJd1IJq/p1Di3a0sH/Q/o8gx
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TrustAsia TLS ECC Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TrustAsia TLS ECC Root CA
+-----BEGIN CERTIFICATE-----
MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw
WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw
@@ -4406,10 +4225,10 @@ DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw
DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01
L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR
OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ==
------END CERTIFICATE-----`))
+-----END CERTIFICATE-----
- // TrustAsia TLS RSA Root CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
+// TrustAsia TLS RSA Root CA
+-----BEGIN CERTIFICATE-----
MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM
BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp
ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN
@@ -4440,153 +4259,6 @@ XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe
SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0
ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy
323imttUQ/hHWKNddBWcwauwxzQ=
------END CERTIFICATE-----`))
-
- // Secure Global CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
-MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
-Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
-iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
-/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
-jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
-HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
-sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
-gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
-KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
-AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
-URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
-H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
-I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
-iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
-f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
------END CERTIFICATE-----`))
-
- // SecureTrust CA
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
-MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
-cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
-Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
-0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
-wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
-7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
-8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
-BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
-JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
-NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
-6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
-3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
-D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
-CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
-3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
------END CERTIFICATE-----`))
-
- // Trustwave Global Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
-CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
-ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
-c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
-OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
-SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
-b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
-swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
-7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
-1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
-80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
-JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
-RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
-hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
-coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
-BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
-twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
-EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
-DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
-0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
-uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
-lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
-aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
-sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
-MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
-qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
-VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
-h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
-EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
-yeC2nOnOcXHebD8WpHk=
------END CERTIFICATE-----`))
-
- // Trustwave Global ECC P256 Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
-BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
-YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
-A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
-d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
-Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
-SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
-FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
-DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
-CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
-DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
------END CERTIFICATE-----`))
-
- // Trustwave Global ECC P384 Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
-VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
-BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
-YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
-NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
-A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
-d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
-Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
-BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
-j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
-1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
-A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
-AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
-MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
-Sw==
------END CERTIFICATE-----`))
-
- // XRamp Global Certification Authority
- pool.AppendCertsFromPEM([]byte(`-----BEGIN CERTIFICATE-----
-MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
-gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
-MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
-UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
-NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
-dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
-dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
-38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
-KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
-DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
-qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
-JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
-PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
-BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
-jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
-eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
-ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
-vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
-qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
-IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
-i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
-O+7ETPTsJ3xCwnR8gooJybQDJbw=
------END CERTIFICATE-----`))
- return pool
+-----END CERTIFICATE-----
+`
}
diff --git a/common/certificate/mozilla.pem b/common/certificate/mozilla.pem
new file mode 100644
index 0000000000..96f941b07e
--- /dev/null
+++ b/common/certificate/mozilla.pem
@@ -0,0 +1,4256 @@
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
+BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
+MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
+SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
+ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
+UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
+4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
+KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
+gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
+rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
+51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
+be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
+KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
+v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
+fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
+jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
+ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
+e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
+jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
+WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
+SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
+pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
+X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
+fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
+K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
+ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
+LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
+LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL
+BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg
+Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv
+b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG
+EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u
+IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ
+n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd
+2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF
+VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ
+GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF
+li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU
+r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2
+eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb
+MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg
+jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB
+7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW
+5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE
+ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0
+90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z
+xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu
+QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4
+FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH
+22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP
+xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn
+dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5
+Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b
+nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ
+CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH
+u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj
+d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
+ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
+9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
+IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
+VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
+93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
+jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
+A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
+U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
+N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
+o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
+5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
+rqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF
+ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
+b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL
+MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
+b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK
+gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ
+W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg
+1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K
+8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r
+2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me
+z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR
+8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj
+mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz
+7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6
++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI
+0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm
+UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2
+LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS
+k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl
+7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm
+btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl
+urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+
+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63
+n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE
+76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H
+9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT
+4PsJYGw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl
+ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr
+ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr
+BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM
+YyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5
+MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g
+Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG
+A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg
+Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi
+9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk
+M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB
+MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw
+CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW
+1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
+ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
+VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
+ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
+dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
+OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
+8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
+Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
+hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
+6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
+AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
+bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
+ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
+qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
+0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
+sSi6
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
+MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
+jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
+ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
+ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
+Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
+AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
+HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
+uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
+TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
+xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
+CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
+O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
+6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw
+CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw
+JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT
+EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0
+WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT
+LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX
+BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE
+KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm
+Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8
+EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J
+UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn
+nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
+MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
+ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
+cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
+WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
+Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
+IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
+UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
+TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
+BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
+kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
+AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
+HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
+sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
+I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
+J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
+VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB
+gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu
+QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG
+A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz
+OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ
+VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3
+b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA
+DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn
+0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB
+OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE
+fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E
+Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m
+o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i
+sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW
+OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez
+Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS
+adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n
+3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ
+F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf
+CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29
+XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm
+djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/
+WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb
+AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq
+P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko
+b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj
+XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P
+5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi
+DrW5viSP
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6
+MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu
+MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV
+BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw
+MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg
+U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ
+n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q
+p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq
+NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF
+8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3
+HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa
+mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi
+7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF
+ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P
+qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ
+v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6
+Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1
+vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD
+ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4
+WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo
+zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR
+5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ
+GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf
+5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq
+0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D
+P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM
+qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP
+0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf
+E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE
+BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
+cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1
+MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
+Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
+thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
+cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
+L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
+NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
+X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
+m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
+Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
+EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
+KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
+6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
+OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc
+tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd
+IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j
+b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC
+AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw
+ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m
+iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF
+Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ
+hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P
+Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE
+EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV
+1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t
+CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR
+5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw
+f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9
+ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK
+GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQsw
+CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
+YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
+IFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQsw
+CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE
+YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB
+IFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zf
+e9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6C
+cyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB
+/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0O
+BBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
+PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw
+hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG
+XSaQpYXFuXqUPoeovQA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV
+BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk
+YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV
+BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN
+MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF
+UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD
+VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v
+dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj
+cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q
+yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH
+2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX
+H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL
+zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR
+p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz
+W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/
+SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn
+LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3
+n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B
+u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj
+o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
+AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L
+9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej
+rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK
+pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0
+vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq
+OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ
+/zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9
+2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI
++PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2
+MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo
+tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
+6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
+L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
+1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
+MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
+QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
+arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
+Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
+FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
+P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
+9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
+uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
+9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
+OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
+KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
+DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
+H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
+I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
+5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
+3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
+Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
+MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
+Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
+TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
+HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
+ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
+N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
+tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
+0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
+/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
+KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
+zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
+O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
+34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
+K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
+AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
+Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
+QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
+IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
+HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
+O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
+033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
+dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
+kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
+3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
+u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
+4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
+bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s
+eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK
++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2
+QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
+hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
+ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
+BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
+PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
+dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0
+YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2
+1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT
+vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed
+aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0
+1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5
+r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5
+cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ
+wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ
+6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA
+2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH
+Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR
+eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB
+/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u
+d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr
+PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
+8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi
+1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd
+rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di
+taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7
+lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj
+yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn
+Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
+yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
+wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
+OV+KmalBWQewLK8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
+DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
+BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
+QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
+gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
+zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
+130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
+JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
+ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
+AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
+9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
+bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
+fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
+HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
+t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
+WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
+MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
+MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
+VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
+BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
+ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
+CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
+I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
+TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
+C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
+ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
+IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
+Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
+JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
+hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
+GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
+1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
+L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
+dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
+aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
+hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
+6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
+HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
+0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
+lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
+o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
+gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
+faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
+Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
+jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
+3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
+AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
+QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
+MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
+0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
+UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
+RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
+OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
+JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
+AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
+BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
+LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
+MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
+44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
+Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
+i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
+9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV
+BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g
+Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ
+BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ
+R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF
+dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw
+vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ
+uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp
+n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs
+cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW
+xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P
+rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF
+DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx
+DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy
+LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C
+eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ
+d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq
+kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC
+b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl
+qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0
+OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c
+NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk
+ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO
+pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj
+03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk
+PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE
+1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX
+QRBdJ3NghVdJIgc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
+Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
+IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
+SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
+SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
+ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
+DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
+TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
+fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
+sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
+WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
+nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
+dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
+NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
+AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
+MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
+uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
+PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
+JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
+gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
+j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
+5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
+o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
+/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
+Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
+W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
+hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP
+MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
+ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa
+Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3
+YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw
+qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv
+Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6
+lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz
+Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ
+KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK
+FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj
+HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr
+y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ
+/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM
+a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6
+fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG
+SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi
+7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc
+SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza
+ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc
+XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg
+iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho
+L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF
+Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr
+kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+
+vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU
+YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u
+LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw
+NTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD
+eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS
+b290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3emhF
+KxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mt
+p7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zd
+J1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur
+FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4J
+hscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+K
+h9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsF
+AAOCAQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6Ld
+mmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJ
+mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA
+8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV
+55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/
+yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM
+BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u
+LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw
+NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD
+eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS
+b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/
+FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg
+vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy
+6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo
+/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J
+kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ
+0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib
+y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac
+18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs
+0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB
+SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL
+ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk
+86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E
+rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib
+ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT
+zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS
+DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4
+2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo
+FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy
+K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6
+dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl
+Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB
+365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c
+JRNItX+S
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw
+UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM
+dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy
+NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl
+cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290
+IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4
+wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR
+ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB
+Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT
+9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp
+4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6
+bkU6iYAZezKYVWOr62Nuk22rGwlgMU4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5
+NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS
+zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0
+QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/
+VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW
+wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV
+dWNbFJWcHwHP2NVypw87
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEJSIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUw
+OTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCTcfKr
+i3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNE
+gXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8
+k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT
+Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl
+2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+U
+cSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP
+/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bS
+uREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+
+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4N
+DfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+
+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUZ5Dw1t61
+GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tI
+FoE9c+CeJyrrd6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67n
+riv6uvw8l5VAk1/DLQOj7aRvU9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTR
+VFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrc
+LmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdijYQ6qgYF/6FKC0ULn
+4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff/vtD
+hQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsG
+koHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46
+ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aS
+Ecr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80
+knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJ
+hJ65bvspmZDogNOfJA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS
+VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5
+NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG
+A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC
+/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD
+wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3
+OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g
+PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf
+Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l
+dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1
+c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO
+PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA
+y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb
+gfM0agPnIjhQW+0ZT0MW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBI
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlE
+LVRSVVNUIEVWIFJvb3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUw
+OTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEi
+MCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1sJkK
+F8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE
+7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFe
+EMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6
+lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIb
+RlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiV
+jTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgc
+jmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZx
+TnXonMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+
+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nk
+hbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knF
+NXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqvyREBuH
+kV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG
+OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y
+XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14
+QvBukEdHjqOSMo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4
+pZt+UPJ26oUFKidBK7GB0aL2QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q
+3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xDUmPBEcrCRbH0O1P1aa4846XerOhU
+t7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V4U/M5d40VxDJI3IX
+cI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuodNv8
+ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT
+2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs
+7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNP
+gofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAst
+Nl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phh
+XBxvWHZks/wCuPWdCg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDjCCAvagAwIBAgIDD92sMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxHzAdBgNVBAMMFkQtVFJVU1QgUm9vdCBD
+QSAzIDIwMTMwHhcNMTMwOTIwMDgyNTUxWhcNMjgwOTIwMDgyNTUxWjBFMQswCQYD
+VQQGEwJERTEVMBMGA1UECgwMRC1UcnVzdCBHbWJIMR8wHQYDVQQDDBZELVRSVVNU
+IFJvb3QgQ0EgMyAyMDEzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+xHtCkoIf7O1UmI4SwMoJ35NuOpNcG+QQd55OaYhs9uFp8vabomGxvQcgdJhl8Ywm
+CM2oNcqANtFjbehEeoLDbF7eu+g20sRoNoyfMr2EIuDcwu4QRjltr5M5rofmw7wJ
+ySxrZ1vZm3Z1TAvgu8XXvD558l++0ZBX+a72Zl8xv9Ntj6e6SvMjZbu376Ml1wrq
+WLbviPr6ebJSWNXwrIyhUXQplapRO5AyA58ccnSQ3j3tYdLl4/1kR+W5t0qp9x+u
+loYErC/jpIF3t1oW/9gPP/a3eMykr/pbPBJbqFKJcu+I89VEgYaVI5973bzZNO98
+lDyqwEHC451QGsDkGSL8swIDAQABo4IBBTCCAQEwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUP5DIfccVb/Mkj6nDL0uiDyGyL+cwDgYDVR0PAQH/BAQDAgEGMIG+
+BgNVHR8EgbYwgbMwdKByoHCGbmxkYXA6Ly9kaXJlY3RvcnkuZC10cnVzdC5uZXQv
+Q049RC1UUlVTVCUyMFJvb3QlMjBDQSUyMDMlMjAyMDEzLE89RC1UcnVzdCUyMEdt
+YkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MDugOaA3hjVodHRwOi8v
+Y3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2FfM18yMDEzLmNybDAN
+BgkqhkiG9w0BAQsFAAOCAQEADlkOWOR0SCNEzzQhtZwUGq2aS7eziG1cqRdw8Cqf
+jXv5e4X6xznoEAiwNStfzwLS05zICx7uBVSuN5MECX1sj8J0vPgclL4xAUAt8yQg
+t4RVLFzI9XRKEBmLo8ftNdYJSNMOwLo5qLBGArDbxohZwr78e7Erz35ih1WWzAFv
+m2chlTWL+BD8cRu3SzdppjvW7IvuwbDzJcmPkn2h6sPKRL8mpXSSnON065102ctN
+h9j8tGlsi6BDB2B4l+nZk3zCRrybN1Kj7Yo8E6l7U0tJmhEFLAtuVqwfLoJs4Gln
+tQ5tLdnkwBXxP/oYcuEVbSdbLTAoK59ImmQrme/ydUlfXA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
+ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
+HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
+UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
+tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
+ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
+lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
+/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
+A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
+A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
+dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
+MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
+cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
+L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
+BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
+acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
+zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
+PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
+Johw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
+MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
+bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
+NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
+BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
+ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
+3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
+qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
+p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
+HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
+ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
+HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
+Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
+c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
+RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
+dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
+Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
+3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
+CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
+xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
+KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICXjCCAeOgAwIBAgIQUs/kjG2gSvc/gpcMgAmMlTAKBggqhkjOPQQDAzBJMQsw
+CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSMwIQYDVQQDExpELVRy
+dXN0IFNCUiBSb290IENBIDEgMjAyMjAeFw0yMjA3MDYxMTMwMDBaFw0zNzA3MDYx
+MTI5NTlaMEkxCzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxELVRydXN0IEdtYkgxIzAh
+BgNVBAMTGkQtVHJ1c3QgU0JSIFJvb3QgQ0EgMSAyMDIyMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAEWZM59oxJZijXYQzIq38Moy3foqR8kito1S5+HkDLtGhJfxKhq39X
+nxkuYy5b/mZxDDMPud5rxIjDse/sOUDjlqvb5XuuH9z5r0aaakYGL8c3ZIsXYv6W
+w6LuhOCwlzm8o4GPMIGMMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPEpox4B
+Eh09dVZNx1B8xRmqDxi3MA4GA1UdDwEB/wQEAwIBBjBKBgNVHR8EQzBBMD+gPaA7
+hjlodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Nicl9yb290X2Nh
+XzFfMjAyMi5jcmwwCgYIKoZIzj0EAwMDaQAwZgIxAJf53q5Lj5i1HkB/Mn1NVEPa
+ic3CqpI80YIec8/6TJIg+2MnxfVzPQk996dhhozzagIxAOcvfLj1JYw7OR82q431
+hqIu4Xpk2mc5Av7+Mz/Zc7ZYWzr8sqTZYHh3zHmnpq5VvQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFrDCCA5SgAwIBAgIQVNWjlR49lbpyG5rQMSFKujANBgkqhkiG9w0BAQ0FADBJ
+MQswCQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSMwIQYDVQQDExpE
+LVRydXN0IFNCUiBSb290IENBIDIgMjAyMjAeFw0yMjA3MDcwNzMwMDBaFw0zNzA3
+MDcwNzI5NTlaMEkxCzAJBgNVBAYTAkRFMRUwEwYDVQQKEwxELVRydXN0IEdtYkgx
+IzAhBgNVBAMTGkQtVHJ1c3QgU0JSIFJvb3QgQ0EgMiAyMDIyMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAryy8jjaM62SvUWrWbjxekTrqmsPKbPuqJ55k
+IqlA37koRVrsU2EWKJjCiqR1eFCE3fogSJIHZUE1ZlESdGGdBwaFOTFXeyg/1Zyl
+7FrpHEsnn84nBvM39VLYETMWQTof9WN4ZWOGyb/IAQQfbu7i7KwM7oKS4vYaDT85
++Z1lk634uQXBPfg3gVbDoP4F7OCUFjojFgTapgqThXJtYTuhjUXW43++Fb02hAj2
+C4NrJqqiveCw56rgrmfE04KlDKmk8DN5DVA/8O+QPSS5f9IgbOqX87+c3EfeCWG9
+lHmVWgJ2NWDERyIN93ZjA9PG+4PGXaut7WklKwNbTSUAQeOMhxdSqOAFK0NNFBPK
+5z9DIrw3pHXx9r867zIeru5YhpByugSsQEjvXMR4p6mPJ1rLeuxY8sIIWJBtTQOF
+eXEVBQ5OPvnfDwX3XxRIViENM5KxrIzlGP6/D+7gBKq9IfJYtlyJCosYCSIaszXG
+ZsL1MxWZgOAI+ZYvE4zu2reIxOk3tddq1zqETatwjNNOFFWgohD8ZNpn6PHLM93J
+moqPli9Ygdn4mgBDzJD7VXb7huM3ASgMb/TpWU0Vd1FCSsw0uIBDUIHvV6UT26eU
+eQ9Lyn4Xfa+jIWTocVVWjwawR+xZD11wWywWQvCGnnXea01ImITiVxi2nIKZZTqL
+gHhXDEkCAwEAAaOBjzCBjDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRds4CU
+G+WGv2i6FDSk9u5t8t3f5zAOBgNVHQ8BAf8EBAMCAQYwSgYDVR0fBEMwQTA/oD2g
+O4Y5aHR0cDovL2NybC5kLXRydXN0Lm5ldC9jcmwvZC10cnVzdF9zYnJfcm9vdF9j
+YV8yXzIwMjIuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA0VC5YGFbNSr2X0/V9K9yv
+D1HhTbwhS5P0AEQTBxALJRg+SFmW96Hhk5B4Zho9I+siqwGmjgxRM+ZtjDHurKQB
+cDlI3sdmLGsNy3Ofh5LpPkcfuO8v7rdWjEiJ8DinFTmy7sA/F6RzAgicvAaKpMK3
+YWH5w9vE0Hp8Yd6xWJH13WVMLwv46z217Yq+dxy6WQISZnHlmCfODj2vUaJF+YL7
+WqWUcPeLhMNMZSWbe+IfMHCzQI467r3052jFnckpR3EOk8i1SE71ZrsHiHFpa3tI
+jm/wEcS0yXAUmCC97afqAdpupZsS/j5EMLPw63VSwPTD+ncmpHeCLW/zKB5OlfAw
+94n4LKJQW/K+Mn5sVNtyySpa4By2C9hSmlmh47ABJ8WgFlBm3OuubfSbWz2EbVuH
+56mJu2644JtTicD/LkAaiUQuGENnOOR8cl/ZoyklQUE9HHcbZKjDVe5jcWZig/R/
+JpmgVDuhEm1wYs7T+bi9IvzUmtS74jgWL7d9OcKwqQPpnM9+GI123F8Ru+tC7FAJ
+PlzskDHYGnK6P2kH7pg0wjSk1toT1qmE8gCGwFS6HhGw4rnEB7SR56rmMVZvsUTE
+KmK8ybBlnDT8DBpT3yEXu8JtoQrm8bCqRAlQSTh6XXHiMS4ZsN+VQgR9hIjOCiNn
+azidFt4G/ihwOKVarvyD7Q==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd
+AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC
+FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi
+1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq
+jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ
+wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/
+WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy
+NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC
+uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw
+IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6
+g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP
+BSeOE6Fuwg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
+KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
+BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
+YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
+OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
+aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
+ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
+8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
+RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
+hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
+ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
+EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
+A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
+WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
+1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
+6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
+91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
+TpPDpFQUWw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRzCCAc2gAwIBAgIQFSrdFMkY0aRWQIamJa8HXzAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
+bWJIMS0wKwYDVQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIEVDQyBSb290IDIw
+MjEwHhcNMjEwMzE4MTEwODMwWhcNNDYwMzE3MjM1OTU5WjBlMQswCQYDVQQGEwJE
+RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMS0wKwYD
+VQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIEVDQyBSb290IDIwMjEwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAASwGY+ia7XHzQ8wmTcMw2Bb8fEnIFU9wJKLq1ehb3OD
+IcJDEwxeiarHBTV5k2KQ1l0TH9F6oLyeEKdmfEYKsFdsv+ZUOTghbBJccczTWl9t
+t6eG37Pf7sLniUGWNfYvSrWjQjBAMB0GA1UdDgQWBBQrywEMY8NTEqWoV6/QnIP7
+vZA6SzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQD
+AwNoADBlAjEA1rxIkodHA8dwOyW2H65GZ3N0ACdL5KUEogPfXiitbl4DyN1onLa/
+lBBIlS8P/xiLAjABQDOel5dNBfJ0VAzNOf1qawnBJD9hjjiht+jXRBURYv8OYTdH
+S0B/Sl+yZ1pzdcI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgIQDH5i9XlzO51Djotj7ZGVuDANBgkqhkiG9w0BAQwFADBl
+MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
+eSBHbWJIMS0wKwYDVQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIFJTQSBSb290
+IDIwMjMwHhcNMjMwMzI4MTIwOTIyWhcNNDgwMzI3MjM1OTU5WjBlMQswCQYDVQQG
+EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMS0w
+KwYDVQQDDCRUZWxla29tIFNlY3VyaXR5IFNNSU1FIFJTQSBSb290IDIwMjMwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDvxQ6LvjLSZ0f/Ckxnsyq/yMPF
+keu1xx6R4WaoiItVIIAfUV53l54ZClzHazchfAM2AfSIJdmoLkGq/Ngm4JZAYnmu
+V54DOBocsncUPumhctDk4DfRF0btUFx6WMX4K/d1L8+BnlostzqsoFmYBFEM/0nF
+UP0e00eFSzNPoje1rwSaJzKdVtU/VWHji2+uUf6X/mkH+mJbJuYUeRWlEziuXze+
+lErWDYAWaaSRsjpJmHWdRhCKXHp/hKXorx7Hq7NaRrWjS/WmIzYARrHbBbYbzp56
+Mlya1XLDnYZNK4TTHrWI2hB4nCLDOyO16xMHvW9T7Jvsm9Nl9QcJ412nmbV+ho7V
+Av+3hQnjRxTdlmYYNN4I1d/LGJliCyvsAF1SRNPGlvwyViWRz80ZO5U5PgKHmWO2
+1T40eg8RdYG8fQTKYLQoddcCUd1SAC7H/YnxXPPLpCcSOI+7+4nw5MQ4LL6CoHFh
+YpGPSAwvK6mw8csQBOd0vzeQ708qQzWXEsYqcA3eLFVHeWMp9cofagZSHK4tJCKD
+Iq/QqjC3Kh//ZSNYZZPIjn1AEDGGeNlVyzww8N5RKgA20idFX9jooSE9fkZWOylF
+8R0FCc62QzDcRZAQMEyka4aLPz0vMZFx7ya59r6dsGzfEe5YP0N5hjmA8SYXB5jw
+maowLENZFM7t4kAThQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FJrOrCrsAfplcN6XnfHSAIylo2S7MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw
+FoAUms6sKuwB+mVw3ped8dIAjKWjZLswDQYJKoZIhvcNAQEMBQADggIBAONQ/fVA
+FiIJljoNqe+B5y4y8KHxSV57iA0Ecte+Z6i6He5Qu3JuetG7DHIwRsjV1wISFplO
+Ht9alu6Pkb6uhvgQd6XEbkdhwPIm2U9haAVIdQgVpaF71biziXnm7fHzYQCGey4x
+/qNc+Hk9tFuIe+Ajuw2hF/rLaA2Yd3EI4m1DdGvENsWUQaQA1lctmYqLIBIVAjIO
+0knsgUjFaidS17JzVVOWPJ5PTLWg0E9X0GcoSGS+xri67GTPyHvFaucq5llXttbU
+1sBnXNmeKAlAv/OpNTFlYAPLGWyClQMeXz/hvepJceVbtwtHFhsgiW2UmQx+iGwd
+DfS3IRpZl6zL6L4XH5V8U5uvUFKqjQsur1rXYPIqaSq57lRwGKq99aE/0t2hYxkA
++KcM66N58nBZo/iiEgPsE//kAoY218HDpLXUpMI3RbaUcD3FveujFR3jNnoVaSpW
+NDnPpZo2qsjtebzP9s4EUwvaslAjfLw+Jq3wDkO7JsuuwkDeNx8KoFHNY522T9jG
+R3y82LTtnovzEeKotT7srnA+fiK7NUgXYGIUkTCjdj2mUTaLHw3dajEcpe3dlqNu
+cg8TTaqnqVx4+QMSGJM3RRKJPfi+yr3ZvgzZGGSnyEE+dYIhOH1l9KDUE0sHeCn5
+nX7Mhz/E2i6I3eML3FpRWunZEk+eAtv3BSVR
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw
+CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH
+bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw
+MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx
+JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE
+AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O
+tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP
+f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA
+MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di
+z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn
+27iQ7t0l
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj
+MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0
+eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy
+MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC
+REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG
+A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9
+cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV
+cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA
+U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6
+Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug
+BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy
+8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J
+co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg
+8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8
+rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12
+mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg
++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX
+gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
+p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ
+pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm
+9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw
+M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd
+GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+
+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t
+xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+
+w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK
+L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj
+X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q
+ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm
+dTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
+JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
+mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
+VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
+AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
+AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
+pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
+dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
+fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
+NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
+H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
+b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
+cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA
+n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc
+biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp
+EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA
+bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu
+YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW
+BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI
+QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I
+0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni
+lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9
+B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv
+ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
+RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf
+Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q
+RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD
+AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY
+JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv
+6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
+QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
+CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
+nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
+43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
+T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
+gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
+BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
+TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
+DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
+hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
+06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
+PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
+YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
+MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT
+MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
+b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI
+2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx
+1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ
+q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz
+tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ
+vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV
+5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY
+1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4
+NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG
+Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91
+8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe
+pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw
+CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
+ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe
+Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw
+EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x
+IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG
+fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO
+Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd
+BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx
+AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/
+oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8
+sycX
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaOgAwIBAgIQBT9uoAYBcn3tP8OjtqPW7zAKBggqhkjOPQQDAzBQMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xKDAmBgNVBAMTH0Rp
+Z2lDZXJ0IFNNSU1FIEVDQyBQMzg0IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
+NDYwMTE0MjM1OTU5WjBQMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
+IEluYy4xKDAmBgNVBAMTH0RpZ2lDZXJ0IFNNSU1FIEVDQyBQMzg0IFJvb3QgRzUw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQWnVXlttT7+2drGtShqtJ3lT6I5QeftnBm
+ICikiOxwNa+zMv83E0qevAED3oTBuMbmZUeJ8hNVv82lHghgf61/6GGSKc8JR14L
+HMAfpL/yW7yY75lMzHBrtrrQKB2/vgSjQjBAMB0GA1UdDgQWBBRzemuW20IHi1Jm
+wmQyF/7gZ5AurTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
+hkjOPQQDAwNnADBkAjA3RPUygONx6/Rtz3zMkZrDbnHY0iNdkk2CQm1cYZX2kfWn
+CPZql+mclC2YcP0ztgkCMAc8L7lYgl4Po2Kok2fwIMNpvwMsO1CnO69BOMlSSJHW
+Dvu8YDB8ZD8SHkV/UT70pg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFajCCA1KgAwIBAgIQBfa6BCODRst9XOa5W7ocVTANBgkqhkiG9w0BAQwFADBP
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJzAlBgNVBAMT
+HkRpZ2lDZXJ0IFNNSU1FIFJTQTQwOTYgUm9vdCBHNTAeFw0yMTAxMTUwMDAwMDBa
+Fw00NjAxMTQyMzU5NTlaME8xCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy
+dCwgSW5jLjEnMCUGA1UEAxMeRGlnaUNlcnQgU01JTUUgUlNBNDA5NiBSb290IEc1
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4Gpb2fj5fey1e+9f3Vw0
+2Npd0ctldashfFsA1IJvRYVBiqkSAnIy8BT1A3W7Y5dJD0CZCxoeVqfS0OGr3eUE
+G+MfFBICiPWggAn2J5pQ8LrjouCsahSRtWs4EHqiMeGRG7e58CtbyHcJdrdRxDYK
+mVNURCW3CTWGFwVWkz1BtwLXYh+KkhGH6hFt6ggR3LF4SEmS9rRRgHgj2P7hVho6
+kBNWNInV4pWLX96yzPs/OLeF9+qevy6hLi9NfWoRLjag/xEIBJVV4Bs7Z5OplFXq
+Mu0GOn/Cf+OtEyfRNEGzMMO/tIj4A4Kk3z6reHegWZNx593rAAR7zEg5KOAeoxVp
+yDayoQuX31XW75GcpPYW91EK7gMjkdwE/+DdOPYiAwDCB3EaEsnXRiqUG83Wuxvu
+v75NUFiwC80wdin1z+W2ai92sLBpatBtZRg1fpO8chfBVULNL8Ilu/T9HaFkIlRd
+4p5yQYRucZbqRQe2XnpKhp1zZHc4A9IPU6VVIMRN/2hvVanq3XHkT9mFo3xOKQKe
+CwnyGlPMAKbd0TT2DcEwsZwCZKw17aWwKbHSlTMP0iAzvewjS/IZ+dqYZOQsMR8u
+4Y0cBJUoTYxYzUvlc4KGjOyo1nlc+2S73AxMKPYXr+Jo1haGmNv8AdwxuvicDvko
+Rkrh/ZYGRXkRaBdlXIsmh1sCAwEAAaNCMEAwHQYDVR0OBBYEFNGj1FcdT1XbdUxc
+Qp5jFs60xjsfMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
+SIb3DQEBDAUAA4ICAQAHpwreU7ua63C/sjaQzeSnuPEM5F1aHXhl/Mm4HiMRV3xp
+NW0B/1NQvwcOuscBP1gqlHUDqxwLI9wbih43PR1Yj3PZsypv3xCgWwynyrB/uSSi
+ATUy5V5GQevYf3PnQumkUSZ3gQqo6w8KUJ1+iiBn/AuOOhHTxYxgGNlLsfzU8bRJ
+Tq6H4dH7dqFf8wbPl5YM6Z51gVxTDSL8NuZJbnTbAIWNfCKgjvsQTNRiE1vvS3Im
+i/xOio/+lxBTxXiLQmQbX+CJ/bsJf1DgVIUmEWodZflJKdx8Nt/7PffSrO4yjW6m
+fTmcRcTKDfU7tHlTpS9Wx1HFikxkXZBDI45rTBd4zOi/9TvkqEjPrZsM3zJK09kS
+jiN4DS2vn6+ePAnClwDtOmkccT8539OPxGb17zaUD/PdkraWX5Cm3XOqpiCUlCVq
+CQxy5BMjYEyjyhcue2cA29DN6nofOSZXiTB3y07llUVPX/s2XD35ILU6ECVPkzJa
+7sGW6OlWBLBJYU3seKidGMH/2OovVu+VK3sEXmfjVUDtOQT5C3n1aoxcD4makMfN
+i97bJjWhbs2zQvKiDzsMjpP/FM/895P35EEIbhlSEQ9TGXN4DM/YhYH4rVXIsJ5G
+Y6+cUu5cv/DAWzceCSDSPiPGoRVKDjZ+MMV5arwiiNkMUkAf3U4PZyYW0q0XHA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp
+Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2
+MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
+bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS
+7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp
+0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS
+B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49
+BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ
+LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4
+DXZDjC5Ty3zfDBeWUA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN
+MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT
+HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN
+NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs
+IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+
+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0
+2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp
+wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM
+pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD
+nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po
+sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx
+Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd
+Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX
+KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe
+XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL
+tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv
+TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
+AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw
+GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H
+PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF
+O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ
+REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik
+AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv
+/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+
+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw
+MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF
+qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK
+ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg
+RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu
+Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y
+ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If
+xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV
+ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO
+DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ
+jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/
+CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi
+EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM
+fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY
+uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK
+chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t
+9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2
+SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd
++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc
+fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa
+sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N
+cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N
+0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie
+4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI
+r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
+/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm
+gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00
+MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV
+wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe
+rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341
+68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh
+4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp
+UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o
+abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc
+3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G
+KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt
+hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO
+Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt
+zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD
+ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2
+cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN
+qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5
+YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv
+b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2
+8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k
+NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj
+ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp
+q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt
+nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
+GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
+Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
+WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
+rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
+ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
+Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
+PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
+/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
+oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
+yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
+EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
+A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
+MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
+BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
+g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
+fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
+WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
+B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
+hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
+TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
+mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
+ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
+4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
+8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00
+MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf
+qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW
+n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym
+c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+
+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1
+o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j
+IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq
+IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz
+8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh
+vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l
+7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG
+cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD
+ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC
+roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga
+W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n
+lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE
++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV
+csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd
+dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg
+KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM
+HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4
+WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
+GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
+b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
+BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
+YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
+4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
+H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
+8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
+vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
+mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
+btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
+T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
+WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
+c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
+4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
+VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
+CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
+aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
+dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
+czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
+A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
+TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
+Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
+7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
+d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
+4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
+t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
+DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
+k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
+zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
+Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
+mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
+4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL
+BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc
+BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00
+MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR
+/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu
+FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR
+U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c
+ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR
+FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k
+A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw
+eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl
+sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp
+VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q
+A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+
+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD
+ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI
+FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv
+oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg
+u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP
+0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf
+3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl
+8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+
+DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN
+PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/
+ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICajCCAfCgAwIBAgIUNi2PcoiiKCfkAP8kxi3k6/qdtuEwCgYIKoZIzj0EAwMw
+ZDELMAkGA1UEBhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmljYWRv
+cmEgRGlnaXRhbDEpMCcGA1UEAwwgRElHSVRBTFNJR04gR0xPQkFMIFJPT1QgRUNE
+U0EgQ0EwHhcNMjEwMTIxMTEwNzUwWhcNNDYwMTE1MTEwNzUwWjBkMQswCQYDVQQG
+EwJQVDEqMCgGA1UECgwhRGlnaXRhbFNpZ24gQ2VydGlmaWNhZG9yYSBEaWdpdGFs
+MSkwJwYDVQQDDCBESUdJVEFMU0lHTiBHTE9CQUwgUk9PVCBFQ0RTQSBDQTB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABG4Lo6szTRzqSuj8BI0UoH3wCCxfg6uT0dJ7utdJ
+fY/sElBf1LnL5fD5M2MfyVfsQNgRC5foUhbMKY70BoYeONw9V8Tuqr3IVAQmWicT
+UUc9Hx8ajqiVpDPQzEfMbbj8SKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
+GDAWgBTOr0qLGnXi8TjnAvAWrV7qZNV7tDAdBgNVHQ4EFgQUzq9Kixp14vE45wLw
+Fq1e6mTVe7QwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMAqIxHGc
+RANNjbTHvKiu2TAnNWprFmPX/OdZ4aeJG0wxmiNVRObzQyHVRydvbVcBqgIxAPuy
+6uKXf1G1n0jrvG81iahkcKtXds3AxhRgyn/iggBz98w16o4km+UIWccEjHN4/g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFtTCCA52gAwIBAgIUXVnIyqsJV/XmtdoplARq/8XUlYcwDQYJKoZIhvcNAQEN
+BQAwYjELMAkGA1UEBhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmlj
+YWRvcmEgRGlnaXRhbDEnMCUGA1UEAwweRElHSVRBTFNJR04gR0xPQkFMIFJPT1Qg
+UlNBIENBMB4XDTIxMDEyMTEwNTAzNFoXDTQ2MDExNTEwNTAzNFowYjELMAkGA1UE
+BhMCUFQxKjAoBgNVBAoMIURpZ2l0YWxTaWduIENlcnRpZmljYWRvcmEgRGlnaXRh
+bDEnMCUGA1UEAwweRElHSVRBTFNJR04gR0xPQkFMIFJPT1QgUlNBIENBMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyIe2ONMc8N4S+IPHxIriibi0Inp4
++AxmUWh2NwrVT8JaCLgWXPdyAQk3hIEqVGvXktBs+qinQxI06w7bNw8p/ooxUULo
+S5yQqMgsEdP9oCl+zt6U9oLgWLRORSXxIvI90w97VBrcMrbWUU5+QbRXuCzGuQ4u
+ylfx1cjTWOel6UIRrtMgJZRp14/Kog3D058HaD8V0mcuU/12gpsLc6kpDZ4RkxQI
+mOyeVBJKVqIGFexrbC6SYC6GDa6CH1FN47IH1xAZVyL2qWlEhPPZPaAGv8yIfn/1
+zlulwipqdELqb6b/+Wix0F+9kdJVbzNXTB6d5OKLwYVloOBqnAAAiJLdWAgW8nAx
+qBzh3r1OcenWvn61oVrDTfe/m72UpP31qlOTRskmAQRwxKBxus4lZvuRflVw7kkK
+TWJ/wlCacvIYZ53pRag0hOj4gfbRWiIeB087s3/dEaVz3L6pGTppqW0bMuKJqqUn
+C1p+dOIPZDldfly5wRf8x41eyewk7dLyP3qERTcCvj5rWcTmWxZtwKqeqrVZLixw
+VZzMmZaYJFTRjtrKtBG0t3BDH2+QCyCgqHYTZdvbI1p1S6ELMXcK7n1oYRoTjOpR
+flxWo1dMXaHrE2W/VBTM8+7c1+w8l/J4Vrjfclxw/M4G3Z/SBzHv51KRns2618AY
+RAcxZUkyaRNK648CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAW
+gBS1Nrw8jBqrLPZZGS2DFNqTJRXWhjAdBgNVHQ4EFgQUtTa8PIwaqyz2WRktgxTa
+kyUV1oYwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQAU+zElODH4
+ygiyI3Y4rfjTWfXMtFcl4US+fvwW7K76Jp9PZxZKVvD97ccZATSOkFot1oBc7HHS
+gSWCHgBx35rR1R0iu9Gl82IPtOvcJHP+plbNmhTFBDUWMaIH66UA4rb4X3L9P2FJ
+jt5+TTjXeh50N2xR3L4ABLg4FPMgwe2bpyP9DUKEHX/yc8PQeGPxn+zXW+nxvmyg
+SwOejWnhFNqIEIEjU//aVCsLxrmWlQQYRvN7qJfYW2ik5DgcDkXlmNMJrppe7LN5
+DTly8vSUnQ6eYCLmqPZMhc0HgjpoOc09X+M49LavO2tKn2BRRaJAAuWqDOM+0XjU
+onScJroFmihwSj6mC9AdSfC6+K5BEH6kBxK9qM8pPVe7x/FDRwA+rnAYWiB7Ccs6
+OnCA5UxgmMEVwR1K98jwm+FyreddaFgLBLGMvJ+3+26LWwRV++sjVdd4UNoly74n
+NrskGnkcUdH+E7v/eCzcpL4v9sVLU8+nTJlecKxZiASuZAS/e6Z6TdPod72hflAV
+8+9JMIVNIVeq2yx1l62BAYeisXCdHgZaA2CxP6ZtgizUFLGBpeg9iB20cixYN4qO
+OJS4c92p4Lj2d6KzfFjermk6tYulGrvy2HQGnP1icyAhdrF+cJ4Z1OsXYhk4mc02
+K0f+McvfueSsCNPYpuvUnn5LZKRVXSsXyQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
+BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
+MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
+MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
+EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
+NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
+PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
+x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
+QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
+yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
+QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
+H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
+QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
+i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
+nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
+rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
+hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
+GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
+lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
+TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
+nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
+gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
+G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
+zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
+L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG
+A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw
+FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx
+MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u
+aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq
+hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b
+RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z
+YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3
+QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw
+yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+
+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ
+SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH
+r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0
+4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me
+dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw
+q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2
+nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu
+H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
+VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC
+XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd
+6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf
++I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi
+kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7
+wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB
+TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C
+MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn
+4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I
+aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy
+qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG
+EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx
+IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw
+MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
+biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND
+IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci
+MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti
+sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O
+BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
+Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c
+3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J
+0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG
+EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo
+bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g
+RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ
+TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s
+b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw
+djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0
+WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS
+fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB
+zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq
+hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB
+CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD
++JbNR6iC8hZVdyR+EhCVBCyj
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG
+A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg
+SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw
+MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln
+biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v
+dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ
+BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ
+HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH
+3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH
+GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c
+xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1
+aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq
+TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87
+/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4
+kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG
+YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT
++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo
+WXzhriKi4gp6D/piq1JM4fHfyr6DDUI=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD
+VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU
+ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH
+MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO
+MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv
+Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN
+BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz
+f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO
+8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq
+d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM
+tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt
+Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB
+o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x
+PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM
+wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d
+GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH
+6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby
+RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx
+iN66zB+Afko=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
+Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
+ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
+MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
+yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
+VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
+nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
+XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
+vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
+Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
+N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
+nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
+dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
+MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
+cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
+YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
+kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
+QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
+6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
+yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
+QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
+KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
+tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
+QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
+Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
+olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
+x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
+BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
+dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
+A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
+cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
+qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
+JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
+s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
+HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
+70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
+V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
+qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
+5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
+C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
+OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
+FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
+BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
+KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
+8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
+MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
+0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
+u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
+u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
+YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
+GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
+RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
+KeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
+VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
+cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
+BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
+VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
+0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
+ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
+A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
+A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
+aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
+flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE
+AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG
+EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM
+FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC
+REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp
+Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM
+VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+
+SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ
+4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L
+cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi
+eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG
+A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3
+DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j
+vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP
+DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc
+maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D
+lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv
+KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICMTCCAbagAwIBAgIMC3MoERh0MBzvbwiEMAoGCCqGSM49BAMDMEsxCzAJBgNV
+BAYTAkRFMQ0wCwYDVQQKDARBdG9zMS0wKwYDVQQDDCRBdG9zIFRydXN0ZWRSb290
+IFJvb3QgQ0EgRUNDIEcyIDIwMjAwHhcNMjAxMjE1MDgzOTEwWhcNNDAxMjEwMDgz
+OTA5WjBLMQswCQYDVQQGEwJERTENMAsGA1UECgwEQXRvczEtMCsGA1UEAwwkQXRv
+cyBUcnVzdGVkUm9vdCBSb290IENBIEVDQyBHMiAyMDIwMHYwEAYHKoZIzj0CAQYF
+K4EEACIDYgAEyFyAyk7CKB9XvzjmYSP80KlblhYWwwxeFaWQCf84KLR6HgrWUyrB
+u5BAdDfpgeiNL2gBNXxSLtj0WLMRHFvZhxiTkS3sndpsnm2ESPzCiQXrmBMCAWxT
+Hg5JY1hHsa/Co2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFFsfxHFs
+shufvlwfjP2ztvuzDgmHMB0GA1UdDgQWBBRbH8RxbLIbn75cH4z9s7b7sw4JhzAO
+BgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaQAwZgIxAOzgmf3d5FTByx/oPijX
+FVlKgspTMOzrNqW5yM6TR1bIYabhbZJTlY/241VT8N165wIxALCH1RuzYPyRjYDK
+ohtRSzhUy6oee9flRJUWLzxEeC4luuqQ5OxS7lfsA4TzXtsWDQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w
+LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w
+CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0
+MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF
+Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X
+tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4
+AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2
+KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD
+aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu
+CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo
+9H1/IISpQuQo
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFfzCCA2egAwIBAgIMR7opRlU+FpKXsKtAMA0GCSqGSIb3DQEBDAUAMEsxCzAJ
+BgNVBAYTAkRFMQ0wCwYDVQQKDARBdG9zMS0wKwYDVQQDDCRBdG9zIFRydXN0ZWRS
+b290IFJvb3QgQ0EgUlNBIEcyIDIwMjAwHhcNMjAxMjE1MDg0MTIzWhcNNDAxMjEw
+MDg0MTIyWjBLMQswCQYDVQQGEwJERTENMAsGA1UECgwEQXRvczEtMCsGA1UEAwwk
+QXRvcyBUcnVzdGVkUm9vdCBSb290IENBIFJTQSBHMiAyMDIwMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAljGFSqoPMv554UOHnPsjt45/DVS9x2KTd+Qc
+NQR2owOLIu7EhN2lk25uso4JA+tRFjEXqmkVGA5ndCNe6pp9tTk+PYKpa+H+qRyw
+rVpNTHiDQYvP8h1impgEnGPpq2X+SB0kZQdHPrmRLumdm38aNak0sLflcDPvSnJR
+tge/YD8qn51U3/PXlElRA1pAqWjdEVlc+HamvFBSEO2s7JXg1INrSdoKT5mD3jKD
+SINnlbJ+54GFPc2C98oC7W2IXQiNuDW/KmkwmbtL0UHbRaCTmVGBkDYIqoq26I+z
+y+7lRg1ydfVJbOGify+87YSmN+7ewk85Tvae8MnRmzCdSW3h2v8SEIzW5Zl7BbZ9
+sAnHpPiyHDmVOTP0Nc4lYnuwXyDzy234bFIUZESP08ipdgflr3GZLS0EJUh2r8Pn
+zEPyB7xKJCQ33fpulAlvTF4BtP5U7COWpV7dhv/pRirx6NzspT2vb6oOD7R1+j4I
+uSZFT2aGTLwZuOHVNe6ChMjTqxLnzXMzYnf0F8u9NHYqBc6V5Xh5S56wjfk8WDiR
+6l6HOMC3Qv2qTIcjrQQgsX52Qtq7tha6V8iOE/p11QhMrziRqu+P+p9JLlR8Clax
+evrETi/Uo/oWitCV5Zem/8P8fA5HWPN/B3sS3Fc/LeOhTVtSTDOHmagJe2x+DvLP
+VkKe6wUCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQgJfMH
+/adv8ZbukRBpzJrvfchoeDAdBgNVHQ4EFgQUICXzB/2nb/GW7pEQacya733IaHgw
+DgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBDAUAA4ICAQAkK06Y8h0X7dl2JrYw
+M+hpRaFRS1LYejowtuQS6r+fTOAEpPY1xv6hMPdThZKtVAVXX5LlKt42J557E0fJ
+anWv/PM35wz1PQFztWlR+L1Z0boL+Lq6ZCdDs3yDlYrnnhOW129KlkFJiw4grRbG
+96aHW4gSiYuJyhLSVq8iASFG6auYP6eI3uTLKpp1Gfo5XgkF1wMyGrgXUQjHAEB9
+9L74DFn0aXZu06RYW14mc+RCVQZeeEAP0zif7yZRcHSR8XdiAejZy+uh3zkyHbtr
+/XH+68+l5hT9AIATxpoASLCZBemugEj7CT9RFLW552BNTcovgSHuUgxletz1iUlM
+MJI0WIAyWbEN/yRhD+cKQtB7vPiOJ0c/cJ0n2bYGPaW7y16Prg5Tx5xqbztMD6NA
+cKiaB87UblsHotLiVLa9bzNyY61RmOGPdvFqBzgl/vZizl/bY8Jume8G3LneGRro
+VD190nZ12V4+MkinjPKecgz4uFi4FyOlFId1WHoAgQciOWpMlKC1otunLMGw8aOb
+wEz3bXDqMZ/xrn0+cyjZod/6k/CbsPDizSUgde/ifTIFyZt27su9MR75lJhLJFhW
+SMDeBky9pjRd7RZhY3P7GeL6W9iXddRtnmA5XpSLAizrmc5gKm4bjKdLvP025pgf
+ZfJ/8eOPTIBGNli2oWXLzhxEdQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM
+MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx
+MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00
+MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD
+QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z
+4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv
+Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ
+kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs
+GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln
+nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh
+3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD
+0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy
+geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8
+ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB
+c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI
+pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS
+4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs
+o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ
+qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw
+xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM
+rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4
+AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR
+0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY
+o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5
+dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE
+oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
+MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
+RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
+gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
+KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
+QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
+XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
+DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
+LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
+RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
+jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
+6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
+mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
+Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
+WD9f
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk
+MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH
+bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD
+QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu
+MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc
+8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke
+hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI
+KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg
+515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO
+xwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
+A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
+b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
+MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
+aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
+jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
+xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
+1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
+snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
+U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
+9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
+AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
+yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
+38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
+AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
+DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
+HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx
+CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD
+ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw
+MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex
+HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq
+R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd
+yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
+7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8
++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA
+MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD
+VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy
+MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
+c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ
+OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG
+vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud
+316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo
+0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE
+y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF
+zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE
++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN
+I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs
+x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa
+ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC
+4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4
+7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg
+JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti
+2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk
+pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF
+FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt
+rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk
+ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5
+u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP
+4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6
+N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
+vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICITCCAaegAwIBAgIQdlP+qicdlUZd1vGe5biQCjAKBggqhkjOPQQDAzBSMQsw
+CQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UEAxMf
+R2xvYmFsU2lnbiBTZWN1cmUgTWFpbCBSb290IEU0NTAeFw0yMDAzMTgwMDAwMDBa
+Fw00NTAzMTgwMDAwMDBaMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxT
+aWduIG52LXNhMSgwJgYDVQQDEx9HbG9iYWxTaWduIFNlY3VyZSBNYWlsIFJvb3Qg
+RTQ1MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE+XmLgUc3iZY/RUlQfxomC5Myfi7A
+wKcImsNuj5s+CyLsN1O3b4qwvCc3S22pRjvZH/+loUS7LXO/nkEHXFObUQg6Wrtv
+OMcWkXjCShNpHYLfWi8AiJaiLhx0+Z1+ZjeKo0IwQDAOBgNVHQ8BAf8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU3xNei1/CQAL9VreUTLYe1aaxFJYw
+CgYIKoZIzj0EAwMDaAAwZQIwE7C+13EgPuSrnM42En1fTB8qtWlFM1/TLVqy5IjH
+3go2QjJ5naZruuH5RCp7isMSAjEAoGYcToedh8ntmUwbCu4tYMM3xx3NtXKw2cbv
+vPL/P/BS3QjnqmR5w+RpV5EvpMt8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIQdlP+qExQq5+NMrUdA49X3DANBgkqhkiG9w0BAQwFADBS
+MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UE
+AxMfR2xvYmFsU2lnbiBTZWN1cmUgTWFpbCBSb290IFI0NTAeFw0yMDAzMTgwMDAw
+MDBaFw00NTAzMTgwMDAwMDBaMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
+YWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9iYWxTaWduIFNlY3VyZSBNYWlsIFJv
+b3QgUjQ1MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3HnMbQb5bbvg
+VgRsf+B1zC0FSehL3FTsW3eVcr9/Yp2FqYokUF9T5dt0b6QpWxMqCa2axS/C93Y7
+oUVGqkPmJP4rsG8ycBlGWnkmL/w9fV9ky1fMYWGo2ZVu45Wgbn9HEhjW7wPJ+4r6
+mr2CFalVd0sRT1nga8Nx8wzYVNWBaD4TuRUuh4o8RCc2YiRu+CwFcjBhvUKRI8Sd
+JafZVJoUozGtgHkMp2NsmKOsV0czH2WW4dDSNdr5cfehpiW1QV3fPmDY0fafpfK4
+zBOqj/mybuGDLZPdPoUa3eixXCYBy0mF/PzS1H+FYoZ0+cvsNSKiDDCPO6t561by
++kLz7fkfRYlAKa3qknTqUv1WtCvaou11wm6rzlKQS/be8EmPmkjUiBltRebMjLnd
+ZGBgAkD4uc+8WOs9hbnGCtOcB2aPxxg5I0bhPB6jL1Bhkgs9K2zxo0c4V5GrDY/G
+nU0E0iZSXOWl/SotFioBaeepfeE2t7Eqxdmxjb25i87Mi6E+C0jNUJU0xNgIWdhr
+JvS+9dQiFwBXya6bBDAznwv731aiyW5Udtqxl2InWQ8RiiIbZJY/qPG3JEqNPFN8
+bYN2PbImSHP1RBYBLQkqjhaWUNBzBl27IkiCTApGWj+A/1zy8pqsLAjg1urwEjiB
+T6YQ7UarzBacC89kppkChURnRq39TecCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgGG
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKCTFShu7o8IsjXGnmJ5dKexDit7
+MA0GCSqGSIb3DQEBDAUAA4ICAQBFCvjRXKxigdAE17b/V1GJCwzL3iRlN/urnu1m
+9OoMGWmJuBmxMFa02fb3vsaul8tF9hGMOjBkTMGfWcBGQggGR2QXeOCVBwbWjKKs
+qdk/03tWT/zEhyjftisWI8CfH1vj1kReIk8jBIw1FrV5B4ZcL5fi9ghkptzbqIrj
+pHt3DdEpkyggtFOjS05f3sH2dSP8Hzx4T3AxeC+iNVRxBKzIxG3D9pGx/s3uRG6B
+9kDFPioBv6tMsQM/DRHkD9Ik4yKIm59fRz1RSeAJN34XITF2t2dxSChLJdcQ6J9h
+WRbFPjJOHwzOo8wP5McRByIvOAjdW5frQmxZmpruetCd38XbCUMuCqoZPWvoajB6
+V+a/s2o5qY/j8U9laLa9nyiPoRZaCVA6Mi4dL0QRQqYA5jGY/y2hD+akYFbPedey
+Ttew+m4MVyPHzh+lsUxtGUmeDn9wj3E/WCifdd1h4Dq3Obbul9Q1UfuLSWDIPGau
+l+6NJllXu3jwelAwCbBgqp9O3Mk+HjrcYpMzsDpUdG8sMUXRaxEyamh29j32ahNe
+JJjn6h2az3iCB2D3TRDTgZpFjZ6vm9yAx0OylWikww7oCkcVv1Qz3AHn1aYec9h6
+sr8vreNVMJ7fDkG84BH1oQyoIuHjAKNOcHyS4wTRekKKdZBZ45vRTKJkvXN5m2/y
+s8H2PA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
+MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
+YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
+MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
+ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
+MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
+ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
+PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
+wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
+EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
+avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
+sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
+/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
+IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
+OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
+TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
+dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
+ReYNnyicsbkqWletNw+vHX/bvZ8=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
+EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
+ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
+NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
+EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
+AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
+E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
+/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
+DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
+GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
+tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
+AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
+WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
+9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
+gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
+2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
+4uJEvlz36hz1
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
+MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
+U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
+NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
+ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
+ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
+DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
+8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
+X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
+K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
+1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
+A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
+zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
+YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
+bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
+L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
+eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
+VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
+WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
+EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
+HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
+ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
+MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
+aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
+Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
+nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
+HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
+Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
+dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
+HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
+CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
+sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
+4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
+8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
+mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
+VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
+UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
+BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
+uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
+HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
+bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo
+27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w
+Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw
+TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl
+qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH
+szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8
+Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk
+MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92
+wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p
+aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN
+VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb
+C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe
+QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy
+h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4
+7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J
+ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef
+MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/
+Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT
+6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ
+0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm
+2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb
+bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt
+nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY
+6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu
+MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k
+RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg
+f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV
++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo
+dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW
+Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa
+G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq
+gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID
+AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H
+vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8
+0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC
+B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u
+NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg
+yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev
+HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6
+xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR
+TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg
+JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV
+7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl
+6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G
+jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2
+4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7
+VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm
+ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
+VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
+A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
+WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
+IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
+QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
+HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
+9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
+p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL
+BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ
+SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n
+a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5
+NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT
+CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u
+Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO
+dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI
+VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV
+9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY
+2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY
+vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt
+bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb
+x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+
+l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK
+TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj
+Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e
+i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw
+DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG
+7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk
+MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr
+gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk
+GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS
+3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm
+Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+
+l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c
+JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP
+L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
+LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
+mpv0
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
+AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
+CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ
+BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND
+VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb
+qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY
+HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo
+G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA
+lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr
+IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/
+0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH
+k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47
+4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO
+m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa
+cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl
+uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI
+KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls
+ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG
+AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT
+VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG
+CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA
+cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA
+QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA
+7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA
+cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA
+QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA
+czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu
+aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt
+aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud
+DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF
+BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp
+D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU
+JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m
+AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD
+vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms
+tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH
+7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA
+h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF
+d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H
+pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx
+CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ
+WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ
+BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG
+Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/
+yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf
+BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz
+WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF
+tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z
+374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC
+IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL
+mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7
+wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS
+MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2
+ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet
+UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H
+YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3
+LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1
+RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM
+LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf
+77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N
+JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm
+fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp
+6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp
+1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B
+9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok
+RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv
+uu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw
+CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw
+FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S
+Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5
+MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL
+DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS
+QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH
+sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK
+Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu
+SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC
+MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy
+v+c=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
+TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
+dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX
+DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
+ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
+b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP
+cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW
+IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX
+xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy
+KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR
+9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az
+5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8
+6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7
+Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP
+bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt
+BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt
+XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd
+INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp
+LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8
+Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp
+gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh
+/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw
+0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A
+fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq
+4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR
+1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/
+QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM
+94B7IWcnMFk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx
+GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp
+bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w
+KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0
+BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy
+dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG
+EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll
+IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU
+QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT
+TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg
+LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7
+a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr
+LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr
+N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X
+YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/
+iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f
+AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH
+V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf
+IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4
+lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
+8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
+lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWjCCAeGgAwIBAgIQMWjZ2OFiVx7SGUSI5hB98DAKBggqhkjOPQQDAzBvMQsw
+CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
+cmNoIEluc3RpdHV0aW9ucyBDQTEnMCUGA1UEAwweSEFSSUNBIENsaWVudCBFQ0Mg
+Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDMzNFoXDTQ1MDIxMzExMDMzM1owbzEL
+MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
+YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJzAlBgNVBAMMHkhBUklDQSBDbGllbnQgRUND
+IFJvb3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABAcYrZWWlNBcD4L3
+KkD6AsnJPTamowRqwW2VAYhgElRsXKIrbhM6iJUMHCaGNkqJGbcY3jvoqFAfyt9b
+v0mAFdvjMOEdWscqigEH/m0sNO8oKJe8wflXhpWLNc+eWtFolaNCMEAwDwYDVR0T
+AQH/BAUwAwEB/zAdBgNVHQ4EFgQUUgjSvjKBJf31GpfsTl8au1PNkK0wDgYDVR0P
+AQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMEwxRUZPqOa+w3eyGhhLLYh7WOar
+lGtEA7AX/9+Cc0RRLP2THQZ7FNKJ7EAM7yEBLgIwL8kuWmwsHdmV4J6wuVxSfPb4
+OMou8dQd8qJJopX4wVheT/5zCu8xsKsjWBOMi947
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqjCCA5KgAwIBAgIQVVL4HtsbJCyeu5YYzQIoPjANBgkqhkiG9w0BAQsFADBv
+MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEnMCUGA1UEAwweSEFSSUNBIENsaWVudCBS
+U0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTg0NloXDTQ1MDIxMzEwNTg0NVow
+bzELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBS
+ZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJzAlBgNVBAMMHkhBUklDQSBDbGllbnQg
+UlNBIFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AIHbV0KQLHQ19Pi4dBlNqwlad0WBc2KwNZ/40LczAIcTtparDlQSMAe8m7dI19EZ
+g66O2KnxqQCEsIxenugMj1Rpv/bUCE8mcP4YQWMaszKLQPgHq1cx8MYWdmeatN0v
+8tFrxdCShJFxbg8uY+kfU6TdUhPMCYMpgQzFU3VEsQ5nUxjQwx+IS5+UJLQpvLvo
+Tv1v0hUdSdyNcPIRGiBRVRG6iG/E91B51qox4oQ9XjLIdypQceULL+m26u+rCjM5
+Dv2PpWdDgo6YaQkJG0DNOGdH6snsl3ES3iT1cjzR90NMJveQsonpRUtVPTEFekHi
+lbpDwBfFtoU9GY1kcPNbrM2f0yl1h0uVZ2qm+NHdvJCGiUMpqTdb9V2wJlpTQnaQ
+K8+eVmwrVM9cmmXfW4tIYDh8+8ULz3YEYwIzKn31g2fn+sZD/SsP1CYvd6QywSTq
+ZJ2/szhxMUTyR7iiZkGh+5t7vMdGanW/WqKM6GpEwbiWtcAyCC17dDVzssrG/q8R
+chj258jCz6Uq6nvWWeh8oLJqQAlpDqWW29EAufGIbjbwiLKd8VLyw3y/MIk8Cmn5
+IqRl4ZvgdMaxhZeWLK6Uj1CmORIfvkfygXjTdTaefVogl+JSrpmfxnybZvP+2M/u
+vZcGHS2F3D42U5Z7ILroyOGtlmI+EXyzAISep0xxq0o3AgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFKDWBz1eJPd7oEQuJFINGaorBJGnMA4GA1Ud
+DwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEADUf5CWYxUux57sKo8mg+7ZZF
+yzqmmGM/6itNTgPQHILhy9Pl1qtbZyi8nf4MmQqAVafOGyNhDbBX8P7gyr7mkNuD
+LL6DjvR5tv7QDUKnWB9p6oH1BaX+RmjrbHjJ4Orn5t4xxdLVLIJjKJ1dqBp+iObn
+K/Es1dAFntwtvTdm1ASip62/OsKoO63/jZ0z4LmahKGHH3b0gnTXDvkwSD5biD6q
+XGvWLwzojnPCGJGDObZmWtAfYCddTeP2Og1mUJx4e6vzExCuDy+r6GSzGCCdRjVk
+JXPqmxBcWDWJsUZIp/Ss1B2eW8yppRoTTyRQqtkbbbFA+53dWHTEwm8UcuzbNZ+4
+VHVFw6bIGig1Oq5l8qmYzq9byTiMMTt/zNyW/eJb1tBZ9Ha6C8tPgxDHQNAdYOkq
+5UhYdwxFab4ZcQQk4uMkH0rIwT6Z9ZaYOEgloRWwG9fihBhb9nE1mmh7QMwYXAwk
+ndSV9ZmqRuqurL/0FBkk6Izs4/W8BmiKKgwFXwqXdafcfsD913oY3zDROEsfsJhw
+v8x8c/BuxDGlpJcdrL/ObCFKvicjZ/MGVoEKkY624QMFMyzaNAhNTlAjrR+lxdR6
+/uoJ7KcoYItGfLXqm91P+edrFcaIz0Pb5SfcBFZub0YV8VYt6FwMc8MjgTggy8kM
+ac8sqzuEYDMZUv1pFDM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw
+CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh
+cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v
+dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG
+A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
+aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg
+Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7
+KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y
+STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD
+AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw
+SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN
+nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs
+MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg
+Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL
+MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
+YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv
+b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l
+mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE
+4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv
+a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M
+pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw
+Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b
+LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY
+AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB
+AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq
+E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr
+W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ
+CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE
+AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU
+X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3
+f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja
+H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP
+JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P
+zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt
+jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0
+/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT
+BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79
+aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW
+xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU
+63ZTGI0RmLo=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN
+BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
+c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl
+bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv
+b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ
+BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj
+YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5
+MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0
+dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg
+QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa
+jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi
+C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep
+lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof
+TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix
+DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k
+IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT
+N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v
+dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG
+A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh
+ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx
+QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
+dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA
+4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0
+AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10
+4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C
+ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV
+9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD
+gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6
+Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq
+NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko
+LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
+Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd
+ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I
+XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI
+M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot
+9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V
+Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea
+j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh
+X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ
+l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf
+bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4
+pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK
+e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0
+vm9qp/UsQu0yrbYhnr68
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu
+VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw
+MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw
+JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT
+3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU
++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp
+S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1
+bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi
+T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL
+vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK
+Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK
+dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT
+c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv
+l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N
+iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD
+ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt
+LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93
+nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3
++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK
+W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT
+AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq
+l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG
+4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ
+mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A
+7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu
+VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN
+MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0
+MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7
+ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy
+RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS
+bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF
+/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R
+3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw
+EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy
+9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V
+GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ
+2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV
+WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD
+W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN
+AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV
+DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9
+TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G
+lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW
+mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df
+WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5
++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ
+tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA
+GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv
+8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
+WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
+ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
+h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
+0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
+A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
+T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
+B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
+B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
+KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
+OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
+jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
+qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
+rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
+hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
+3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
+NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
+ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
+TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
+jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
+oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
+4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
+mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
+emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw
+CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg
+R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00
+MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT
+ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw
+EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW
++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9
+ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T
+AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI
+zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW
+tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1
+/q4AaOeMSQ+2b1tbFfLn
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
+MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
+ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
+VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
+b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
+scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
+xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
+LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
+uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
+yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
+rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
+BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
+hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
+QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
+HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
+Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
+QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
+BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
+A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
+laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
+awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
+JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
+LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
+VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
+LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
+UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
+QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
+QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6
+ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw
+NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L
+cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg
+Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN
+QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT
+3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw
+3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6
+3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5
+BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN
+XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF
+AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw
+8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG
+nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP
+oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy
+d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg
+LvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFmDCCA4CgAwIBAgIEVRpusTANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJa
+QTERMA8GA1UEChMITEFXdHJ1c3QxITAfBgNVBAMTGExBV3RydXN0IFJvb3QgQ0Ey
+ICg0MDk2KTAgFw0yMzAyMTQwOTE5MzhaGA8yMDUzMDIxNDA5NDkzOFowQzELMAkG
+A1UEBhMCWkExETAPBgNVBAoTCExBV3RydXN0MSEwHwYDVQQDExhMQVd0cnVzdCBS
+b290IENBMiAoNDA5NikwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
+F8srQ7ps+cmTimUNEkzsJxS3E3ng1NUtGFbx+eoqEBZObETHamVG85qJNdGH+DOJ
+L4gJGpIQkZDBa58Obn8mihNdGKxoAQ0QeGVw2I6PhFqXMBjQEQ5KjVIQpYErUSj1
+Y8S27ECzAeWtd73lOO+8jbPdGaB7DY2022r7JTNa+pGvxHFFMPiIKXvLv9W6JwSO
+3bIA98pcmTUU6v11BhUIu8pXaPs/+7Q0c2PR1ePIOFppfWp6RAwNik7tkh0Qjzsi
+LLbf7cXG8Il5VGVeXxu9j33fubft6+TFB9FnPJU7kf5CelJAgATSOVdL9JJ9/5vv
+5Z3JCbKREjimKQg7ruvKzO1N504hAQf8bzLOaYyEUsZ36icwCt6lrzAraB+s1Owh
+rSJJds4PwvIHKvlqEoOaOwSuGXr+oYYk+kFeJXxArCe24yk2bzXiV9AZWN//ZPbD
+AUl22yu+vLlPFArVG1gh9hwuAHz4lLXLNxoU5DK5FtRg7AWqXzL6aiMSrNQQu9Ki
+grRLDotwJ6rWB8FniPqEwwjJioTI0jdygQ+NFkrk1zVRpTgPjIRLlTbA9ded4F2P
+q5HuAAi5nVIf7PiZu3lWsUna0uXYYYtbr/CrN8V7Go6Gvn7FexUeYWjoC4eLc0mh
+F3N+KXiOyuBBL3VzdKKXOn/3LnQJuExgi0Y2GRAtnQIDAQABo4GRMIGOMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMCsGA1UdEAQkMCKADzIwMjMwMjE0
+MDkxOTM4WoEPMjA1MzAyMTQwOTQ5MzhaMB8GA1UdIwQYMBaAFNfWVmJcPxeB5nNE
+KfVRBe8LYDesMB0GA1UdDgQWBBTX1lZiXD8XgeZzRCn1UQXvC2A3rDANBgkqhkiG
+9w0BAQsFAAOCAgEASZwp/j3snkV/qz48/iNvNz53p1P/eJ/8SUSAV2acbtp5/81F
+rUyTv7VZxukQt+X4jPuHxR6L2LM/ApYKu4qO79e0wIMgOJdZRWT89ncT8gnXocg4
+dAjq+UhM+h8EnLT/7G5WNnKTbJU+LF/eDwurycwVPhaPZvyyELih0bTewGMZzO9T
+qnU2IoslH7+byNfBX+ymNwmqe2K89iIt8dZY3Yy7UvQLp3apensajdytmoFiLoYF
+kHJHL6HJZ4SwDWywuJsWt9CZFC+cEpsjqI2mQx7p5S3leKcfZJRktneyqFz7Casp
+6x5tddH20MWlwx2fHvMaLbLIH+UoCm7zX/3a5iOhdpBcS5gBgizuRy0CGl9/NMVp
+tXKtPvPPnm34KegRJyvgWQsbYetKymmlpNXNURuUjnnN3/audF2xLBuGU/7RMAZB
+NAdigkz0fseHdA6wIR4JIIDBsxU9Rm3T8QaSP++glYocbncxtut4KQx77oKlT36k
+KV6eqi34jsDz/A0GhZtO3PfiCXzQFFEeerMjr/rRYSpltQHZuOMHyiR20vBKvu+G
+BIBCFXARaH7Xx7v+506bnJWlHEqkydAJjKrOSNIekpfXEentZsw33PXXG3SbpupC
+rF0y4Fj0gUf/0hLifhzcSXaWwx2fS8pcKjdbPYrROJsh2uO/RUPT4Fh3Hyg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV
+BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk
+LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv
+b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ
+BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg
+THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v
+IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv
+xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H
+Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB
+eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo
+jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ
++efcMQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICzzCCAjGgAwIBAgINAOhvGHvWOWuYSkmYCjAKBggqhkjOPQQDBDB1MQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xFzAVBgNVBGEMDlZBVEhVLTIzNTg0NDk3MSIwIAYDVQQDDBllLVN6aWdubyBU
+TFMgUm9vdCBDQSAyMDIzMB4XDTIzMDcxNzE0MDAwMFoXDTM4MDcxNzE0MDAwMFow
+dTELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRYwFAYDVQQKDA1NaWNy
+b3NlYyBMdGQuMRcwFQYDVQRhDA5WQVRIVS0yMzU4NDQ5NzEiMCAGA1UEAwwZZS1T
+emlnbm8gVExTIFJvb3QgQ0EgMjAyMzCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAE
+AGgP36J8PKp0iGEKjcJMpQEiFNT3YHdCnAo4YKGMZz6zY+n6kbCLS+Y53wLCMAFS
+AL/fjO1ZrTJlqwlZULUZwmgcAOAFX9pQJhzDrAQixTpN7+lXWDajwRlTEArRzT/v
+SzUaQ49CE0y5LBqcvjC2xN7cS53kpDzLLtmt3999Cd8ukv+ho2MwYTAPBgNVHRMB
+Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUWYQCYlpGePVd3I8K
+ECgj3NXW+0UwHwYDVR0jBBgwFoAUWYQCYlpGePVd3I8KECgj3NXW+0UwCgYIKoZI
+zj0EAwQDgYsAMIGHAkIBLdqu9S54tma4n7Zwf2Z0z+yOfP7AAXmazlIC58PRDHpt
+y7Ve7hekm9sEdu4pKeiv+62sUvTXK9Z3hBC9xdIoaDQCQTV2WnXzkoYI9bIeCvZl
+C9p2x1L/Cx6AcCIwwzPbGO2E14vs7dOoY4G1VnxHx1YwlGhza9IuqbnZLBwpvQy6
+uWWL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
+VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
+ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
+CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
+OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
+FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
+Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
+kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
+cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
+fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
+N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
+xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
+Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
+SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
+mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
+ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
+2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
+HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw
+CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD
+VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw
+MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV
+UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy
+b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq
+hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR
+ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb
+hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E
+BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3
+FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV
+L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB
+iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl
+MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw
+NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
+IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG
+EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N
+aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ
+Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0
+ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1
+HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm
+gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ
+jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc
+aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG
+YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6
+W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K
+UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH
++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q
+W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC
+LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC
+gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6
+tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh
+SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2
+TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3
+pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR
+xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp
+GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9
+dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN
+AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB
+RA+GsCyRxj3qrg+E
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM
+BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG
+T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx
+CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD
+b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA
+iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH
+38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE
+HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz
+kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP
+szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq
+vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf
+nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG
+YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo
+0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a
+CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K
+AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I
+36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
+Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN
+qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj
+cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm
++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL
+hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe
+lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7
+p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8
+piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR
+LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX
+5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO
+dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul
+9XXeifdy
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
+EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
+MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
+cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
+dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
+pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
+b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
+aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
+IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
+lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
+AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
+VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
+ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
+BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
+AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
+U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
+bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
+uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
+XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICNDCCAbqgAwIBAgIQVOyX1ou0xAshbg6y0FPIejAKBggqhkjOPQQDAzBLMQsw
+CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY
+T0lTVEUgQ2xpZW50IFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0MzE0MFoXDTQ4MDUy
+NDE0MzEzOVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp
+b24xITAfBgNVBAMMGE9JU1RFIENsaWVudCBSb290IEVDQyBHMTB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABIhOaB/Jnr46BFsVwzX0zFDFCK04bqg80gK6zKsl/XVA/WcZ
+nxsKXfbLFnv5XB6C3BVE1Jw8bWGTRfRPz2K53z5TjZrUSt6Iqgum8dRh1h501Riy
+xU1M74B77A3rgzlUlqNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSZ
+Vzs5sS0AjCFmjJVpnG117Iw/+jAdBgNVHQ4EFgQUmVc7ObEtAIwhZoyVaZxtdeyM
+P/owDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMQCW/+SCThYiW6CF
+GDw9Oo8gBggl5/WRNhmte7TfW2YSN3Nw7c0FKAdeCM4NQl8ZkQICMGdJh64GQR0g
+0zGmqiY38SeKYQ3+mgZDpy6eJkejMhiL6F5QBfGwekh23tuhYkq6dw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIQNBdvWQGIG6ql3chIu7Q7czANBgkqhkiG9w0BAQwFADBL
+MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE
+AwwYT0lTVEUgQ2xpZW50IFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MjMyOVoXDTQ4
+MDUyNDE0MjMyOFowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k
+YXRpb24xITAfBgNVBAMMGE9JU1RFIENsaWVudCBSb290IFJTQSBHMTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBALpP/v5UE7WEPLzg0zHxHW7cxFNx+uQ5
+UUN2fZIfgX8Aa0HC5trcGE1sF1lwCTNi7GmILbDdWflhYGBW8ba07+uH0BP+w89v
+j345WFGziQKOVJUeIl+rKAVDJ/hF9AlCJpT+vRN4u5HyEBCcDWd82mQg63owGrpI
+DXhUKpkxNKvLpmrnDGc5ZqQmqCco5/PmPHPkK8xvMS4TdGHLaObSM85SvH5lJFoh
+gTFDqrKc0RjnYTxSr4CJ6TRG3vlNmVptHb3GJdGTVY74J5JDOoyVRUDjiRinhsFZ
+mMrbJhwTwIyBuZiwrWmtbhjje2JB9a02/gu0eyBfn6lu+ZmCElLSisRUeLR890Gb
+A+cHXrPCuUlkZ5IWxGCQDrCCfTOt0Dbq0XZrfIhHmKwb+bRQjGGBadgx8436PvL1
+S6/Owx3vXygb6xjWoFhSMr5Cb81JlyLBcLnT42BP3oOCoE4wvXNTwr0X/aDAmI/q
+DhcH5kOVIE7bEaj549O4J0cMJ9sS64FVzHXbn9MXQ8T764oobemvRFBaQ/vxOeKT
+UM+Y/ESWWDilpe1Fw1JCBafv5TykrD3n1qlWBaqww6cZ5OU911dEbZQRH8pwyPy5
+TMxBWoN0U5B4z9bULk+xqk0u9dEIWzpk78inqHph7Oym1YhOtlTUWJHCJWSRvAoU
+PZIUmrULBukvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
+KYIlNQo6vpIr5AkD5OyPjThyOcswHQYDVR0OBBYEFCmCJTUKOr6SK+QJA+Tsj404
+cjnLMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEAbSOGwv/14MjA
+VYpgMcyXQ0dwQ9Pj7FL608Ke+4kyGspGk08Elyvb0JyEDZUHQlT+72kh35IDLo83
+ISN3qXc3bKDErpynWDlKFZdiRoNRIO0/wqPxw2In0KwTHv48Uh2Q1WPxqV7qf+fn
+65ZaUezUqRvjDJRmrMuIkkm+c1yK4Gq8poHNs1zUI5LITfkgjHCUS2ht8o8ebDX3
+6F/U170gN1Jm/yu7SWa3cagsX3MPB5LnTl+lBtvJijyXxULqfQ+BG1frngwP/6Mn
+IElTprM6TMttMDXa8vCa/lDfbVwkPU13an2GX0zQ4aa0rgQTAZDxgGiEB5SCB4Pr
+keWTDnWRrqMjIElk1Lo5lldw7lU0KHzWr8qpnubJAckHwdBEsYC0UVCqj/ac5Wdz
+0BvqgzUXL1DG3lbHu6MDy+KhGOj4zlEGo9IDQGEap2dXg/zRErkoqtpOa9Wc2IU3
+2r0i1zRZnBqmznjWlHgHBg+xkyGgSccQngquUXca+XGQw62YD4opamABqk+tIAMt
+ao6jC2rW/ZMMimHLvSjxX3H9uDM51krx9rJoUj5lj0OdgSQk9ihMNaf9MwqleMEE
+H+xJasSu1UQWpqeNf9ohlj6ouhZn1Kmh58Ka+BDZO5ruaPYvAO7Lu2aNIjiG9L9f
+eKnIoB1au3VQ+VILDx0CLBQa84dqd/M=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQsw
+CQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwY
+T0lTVEUgU2VydmVyIFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUy
+NDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRp
+b24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBHMTB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOujvqQy
+cvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N
+2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3
+TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C
+tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFR
+QD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKD
+YmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBL
+MQswCQYDVQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UE
+AwwYT0lTVEUgU2VydmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4
+MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5k
+YXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJTQSBHMTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxVYOPM
+vLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7b
+rEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzk
+ik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z
+O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8R
+tOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOS
+jswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUh
+sd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+Ho
+mnqT8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu
++zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYR
+i3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnT
+kCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
+8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2
+zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33
+I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG
+5D1rd9QhEOP28yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8
+qyiWXmFcuCIzGEgWUOrKL+mlSdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dP
+AGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l8PjaV8GUgeV6Vg27Rn9vkf195hfk
+gSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+FKrDgHGdPY3ofRRs
+YWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNqqYY1
+9tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome
+/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3
+J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2
+wq1yVAb+axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZy
+BiElxky8j3C7DOReIoMt0r7+hVu05L0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
+ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
+aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
+NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
+A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
+SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
+VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
+w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
+mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
+4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
+4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
+EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
+SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
+ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
+vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
+Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
+/L7fCg0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt
+MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg
+Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i
+YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x
+CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG
+b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh
+bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3
+HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx
+WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX
+1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk
+u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P
+99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r
+M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB
+BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh
+cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5
+gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO
+ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf
+aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
+CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
+bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
+Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ
+BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu
+ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS
+b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni
+eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W
+p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
+rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
+57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
+Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT
+AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD
+VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx
+NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT
+HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5
+IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
+AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl
+dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK
+ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu
+9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O
+be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
+MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
+U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
+DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
+dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
+YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
+OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
+zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
+VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
+hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
+ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
+awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
+OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
+DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
+coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
+okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
+t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
+1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
+SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
+MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
+GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
+YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
+GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
+BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
+3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
+YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
+rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
+ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
+oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
+QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
+b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
+AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
+GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
+G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
+l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
+smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
+gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
+BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
+MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
+YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
+RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
+UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
+2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
+Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
+nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
+/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
+PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
+QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
+SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
+IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
+zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
+BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
+ZQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
+MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
+BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
+IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
+MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
+ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
+T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
+FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
+cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
+BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
+fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
+GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB
+hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
+A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV
+BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT
+EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR
+6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X
+pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC
+9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV
+/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf
+Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z
++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w
+qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah
+SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC
+u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf
+Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq
+crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB
+/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl
+wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM
+4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV
+2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna
+FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ
+CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK
+boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke
+jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL
+S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb
+QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl
+0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB
+NVOFBkpdn627G190
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
+Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
+KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
+NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
+NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
+ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
+BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
+Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
+4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
+KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
+rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
+94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
+sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
+gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
+kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
+vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
+O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
+AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
+9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
+eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
+0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
+A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
+d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
+dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
+RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
+MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
+VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
+L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
+Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
+A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
+ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
+Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
+BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
+R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
+hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
+cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
+IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
+dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
+NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
+dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
+dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
+aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
+RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
+cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
+wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
+U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
+jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
+BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
+jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
+1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
+nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
+VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw
+gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL
+Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg
+MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw
+BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0
+MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT
+MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1
+c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ
+bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg
+Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ
+2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E
+T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j
+5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM
+C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T
+DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX
+wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A
+2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm
+nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
+dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl
+N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj
+c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS
+5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS
+Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr
+hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/
+B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI
+AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw
+H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+
+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk
+2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol
+IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
+5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
+n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
+RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
+bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
+IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
+MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
+LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
+YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
+A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
+K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
+sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
+MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
+XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
+HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
+4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
+j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
+U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
+u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
+bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
+fF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICMTCCAbegAwIBAgIQbvXTp0GOoFlApzBr0kBlVjAKBggqhkjOPQQDAzBaMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTEwLwYDVQQDEyhT
+ZWN0aWdvIFB1YmxpYyBFbWFpbCBQcm90ZWN0aW9uIFJvb3QgRTQ2MB4XDTIxMDMy
+MjAwMDAwMFoXDTQ2MDMyMTIzNTk1OVowWjELMAkGA1UEBhMCR0IxGDAWBgNVBAoT
+D1NlY3RpZ28gTGltaXRlZDExMC8GA1UEAxMoU2VjdGlnbyBQdWJsaWMgRW1haWwg
+UHJvdGVjdGlvbiBSb290IEU0NjB2MBAGByqGSM49AgEGBSuBBAAiA2IABLinUpT1
+PgWwG/YfsdN+ueQFZlSAzmylaH3kU1LbgvrEht9DePfIrRa8P3gyy2vTSdZE5bN+
+n3umxizy4rbTibCaPEvOiUvGxss6SWAPRrxtTnqcyZuFewq2sEfCiOPU0aNCMEAw
+HQYDVR0OBBYEFC1OjKfCI7JXqQZrPmsrifPDXkfOMA4GA1UdDwEB/wQEAwIBhjAP
+BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCSnRpZY0VYjhsW5H16
+bDZIMB8rcueQMzT9JKLGBoxvOzJXWvj+xkkSU5rZELKZUXICMAUlKjMh/JPmIqLM
+cFUoNVaiB8QhhCMaTEyZUJmSFMtK3Fb79dOPaiz1cTr4izsDng==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgDCCA2igAwIBAgIQHUSeuQ2DkXSu3fLriLemozANBgkqhkiG9w0BAQwFADBa
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTEwLwYDVQQD
+EyhTZWN0aWdvIFB1YmxpYyBFbWFpbCBQcm90ZWN0aW9uIFJvb3QgUjQ2MB4XDTIx
+MDMyMjAwMDAwMFoXDTQ2MDMyMTIzNTk1OVowWjELMAkGA1UEBhMCR0IxGDAWBgNV
+BAoTD1NlY3RpZ28gTGltaXRlZDExMC8GA1UEAxMoU2VjdGlnbyBQdWJsaWMgRW1h
+aWwgUHJvdGVjdGlvbiBSb290IFI0NjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
+AgoCggIBAJHlG/qqbTcrdccuXxSl2yyXtixGj2nZ7JYt8x1avtMdI+ZoCf9KEXMa
+rmefdprS5+y42V8r+SZWUa92nan8F+8yCtAjPLosT0eD7J0FaEJeBuDV6CtoSJey
++vOkcTV9NJsXi39NDdvcTwVMlGK/NfovyKccZtlxX+XmWlXKq/S4dxlFUEVOSqvb
+nmbBGbc3QshWpUAS+TPoOEU6xoSjAo4vJLDDQYUHSZzP3NHyJm/tMxwzZypFN9mF
+ZSIasbUQUglrA8YfcD2RxH2QPe1m+JD/JeDtkqKLMSmtnBJmeGOdV+z7C96O3IvL
+Oql39Lrl7DiMi+YTZqdpWMOCGhrN8Z/YU5JOSX2pRefxQyFatz5AzWOJz9m/x1AL
+4bzniJatntQX2l3P4JH9phDUuQOBm2ms+4SogTXrG+tobHxgPsPfybSudB1Ird1u
+EYbhKmo2Fq7IzrzbWPxAk0DYjlOXwqwiOOWIMbMuoe/s4EIN6v+TVkoGpJtMAmhk
+j1ZQwYEF/cvbxdcV8mu1dsOj+TLOyrVKqRt9Gdx/x2p+ley2uI39lUqcoytti/Fw
+5UcrAFzkuZ7U+NlYKdDL4ChibK6cYuLMvDaTQfXv/kZilbBXSnQsR1Ipnd2ioU9C
+wpLOLVBSXowKoffYncX4/TaHTlf9aKFfmYMc8LXd6JLTZUBVypaFAgMBAAGjQjBA
+MB0GA1UdDgQWBBSn15V360rDJ82TvjdMJoQhFH1dmDAOBgNVHQ8BAf8EBAMCAYYw
+DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAgEANNLxFfOTAdRyi/Cr
+CB8TPHO0sKvoeNlsupqvJuwQgOUNUzHd4/qMUSIkMze4GH46+ljoNOWM4KEfCUHS
+Nz/Mywk1Qojp/BHXz0KqpHC2ccFTvcV0r8QiJGPPYoJ9yctRwYiQbVtcvvuZqLq2
+hrDpZgvlG2uv6iuGp9+oI0yWP09XQhgVg0Pxhia3KgPOC53opWgejG+9heMbUY/n
+Fy8r0NZ4wi3dcojUZZ76mdR+55cKkgGapamEOgwqdD0zGMiH9+ik9YZCOf1rdSn8
+AAasoqUaVI7pUEkXZq9LBC2blIClVKuMVxdEnw/WaGRytEseAcfZm5TZg5mvEgUR
+o5gi0vJXyiT5ujgVEki6Yzv8i5V41nIHVszN/J0c0MVkO2M0zwSZircweXq28sbV
+2VR6hwt+TveE7BTziBYS8dWuChoJ7oat5av9rsMpeXTDAV8Rm991mcZK95uPbEns
+IS+0AlmzLdBykLoLFHR4S8/BX1VyjlQrE876WAzTuyzZqZFh+PjxtnvevKnMkgTM
+S2tfc4C2Ie1QT9d2h27O39K3vWKhfVhiaEVStj/eEtvtBGmedoiqAW3ahsdgG8NS
+rDfsUHGAciohRQpTRzwZ643SWQTeJbDrHzVvYH3Xtca7CyeN4E1U5c8dJgFuOzXI
+IBKJg/DS7Vg7NJ27MfUy/THzVho=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw
+CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T
+ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN
+MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG
+A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT
+ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC
+WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+
+6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B
+Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa
+qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q
+4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf
+MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD
+Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw
+HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY
+MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp
+YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa
+ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz
+SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf
+iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X
+ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3
+IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS
+VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE
+SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu
++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt
+8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L
+HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt
+zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P
+AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c
+mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ
+YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52
+gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA
+Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB
+JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX
+DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui
+TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5
+dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65
+LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp
+0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY
+QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
+MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl
+eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT
+JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx
+MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg
+VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo
+I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng
+o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G
+A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB
+zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW
+RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
+MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
+Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
+iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
+/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
+jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
+HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
+sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
+gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
+KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
+AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
+URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
+H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
+I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
+iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
+MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
+FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
+MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
+cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
+Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
+0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
+wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
+7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
+8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
+BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
+JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
+NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
+6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
+3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
+D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
+CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICQDCCAcagAwIBAgIQdvhIHq7wPHAf4D8lVAGD1TAKBggqhkjOPQQDAzBRMQsw
+CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQDDB9T
+U0wuY29tIENsaWVudCBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzAzMloX
+DTQ2MDgxOTE2MzAzMVowUTELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
+b3JhdGlvbjEoMCYGA1UEAwwfU1NMLmNvbSBDbGllbnQgRUNDIFJvb3QgQ0EgMjAy
+MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABC1Tfp+LPrM2ulDizOvcuiaK04wGP2cP
+7/UX5dSumkYqQQEHaedncfHCAzbG8CtSjs8UkmikPnBREmmNeKKCyikUwOSUIrJE
+kmBvyASkZ9Wi0PPQ1+qOPA+60kBHkDTufaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAf
+BgNVHSMEGDAWgBS3/i1ixYFTzVIaL11goMNd+7IcHDAdBgNVHQ4EFgQUt/4tYsWB
+U81SGi9dYKDDXfuyHBwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUC
+ME0HES0R+7kmwyHdcuEX/MHPFOpJznGHjtZT3BHNXVSKr9kt9IxR6rxmR+J/lYNg
+ZQIxAIwhTE+75bBQ35BiSebMkdv4P11xkQiOT5LJf6Zc6hN+7W3E6MMqb1wR4aXz
+alqaTQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjzCCA3egAwIBAgIQdq/uiJMVRbZQU5uAnKTfmjANBgkqhkiG9w0BAQsFADBR
+MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSgwJgYDVQQD
+DB9TU0wuY29tIENsaWVudCBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzEw
+N1oXDTQ2MDgxOTE2MzEwNlowUTELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBD
+b3Jwb3JhdGlvbjEoMCYGA1UEAwwfU1NMLmNvbSBDbGllbnQgUlNBIFJvb3QgQ0Eg
+MjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALhY20Yw+8k/48jw
+ATM04tpIqBjpIG6a1wHh1SmPMLQjauTLYrC+4p8gvT5UoDlox4Y3ZnQGBu90K9rc
+n4SpUi+Q0u5+fPulIq1vcEZnlj0p1KO7VnsUBFnBIWNEHrIfElyQh2UNiPYeiCLi
+Y1S78zb41n/c2v8pNanGbg5pWz/YvoKHFXBdsMdcEg9jpjjNz3O5ww6JJjcbP2Ic
+MmnRm9n/VZAx3rFj3c/FdHf874ghU78AMRomLAAwpV9s4+T2AIrKmIecdAN6i2bs
+fv2jjzUlXHils6T7PW2pivBsiIKL/UrQb+TXo7SONEk4vs5F5dIcyl7CNxSLzWZW
+Mzed5WvsQ5JkoELadW/AFez5ab00uYp7+hb7Vf5SIOgEBFZWZfU3RJjIikbpt6y4
+6L5ijlQ2W/c7cL9d7i26X95CGYbwf4vrCMvYvuoOQkKgNnNXF+0y6tCN6Acbm5no
+xJpiBA5I9zwSuvdYwZqM6cewIzZWNB3LbNq6B4Qd/dGsn+bCie/DuWwYs2mHV1+1
+DDhbpyEkKjunNJGetFTqKE/TwaOL5OYr1fKdv5thACLd1ktEHz9dVv7enHjMmVuq
+5L2620NLrUwmTKNNNIpsdDYT22L8m7IFgf+uPwzN9hui9DnnyvVMXPtUdzWAWsAS
+oRMBM2c9nYGhqfWFJFiIeOf042hVAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8w
+HwYDVR0jBBgwFoAU8DhClDSpPAB/Uu45pfdLDbxqfSMwHQYDVR0OBBYEFPA4QpQ0
+qTwAf1LuOaX3Sw28an0jMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC
+AgEAmU/b8OrWEfoq/cirbeQOc2LSQp8V/nxwUj9kh4IxP0VALuEinwZmKfyW0y2N
+tjjH2fMnwVkpoIz2cyQPKCLXTmHdE93bnzJSk/tPzOo4PJhqA6sWryHRQq59RSvq
+xM+KWZ+CcHY6+GImyRCXWEAkpC25LymAJ+GJa3LKSQhxN1MF8YDO00IC0vzC0ZQG
+7gfi9oPif5/nu1bDW7/dlZMJHiTBzybNraSuwrRp56q17TeU6d3RY4VrmnpKVnbc
+GYUo1OTGpNi4lkF30LRZ8UYFh4cCH2m5ghjQQ9km2hpnqNZ1durybQ5C/4gmom6E
+/n5iG/DGPe3AHGrHkda4ADdJm7mEBaHNbjHWROpTi7pTmB2hkIrphfgb8pNYw8jc
+miZPPiDPT0PzEIx/EGF6NsqqC33Mn0dEWa6llcaZU+MHaz1JELAY/10OhUMUS+dr
+00q1smBh3GlJAiNd6JJxw5yfRWd5HtwyhrqqVTxkbzK1EEAV3nJAeOBucLtu6wno
+OdmsupJ13UPKugGVrRqBKzrw48UvDBhNEMauwO3+BVJ/GQXLqa81CAw4IuT+VuVT
+Pr/k1rPZCMM91TMygSTFqeFlEbgyMzBxGEkdGkXGmhSKWDkobvPLUblJJmR4A8eR
+EYOpuZA0tm+qBZ6FKFeZvn8nBkliTaH8CeErRglMFJtWj0U=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
+WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
+b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
+b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
+7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
+CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
+EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
+VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
+kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
+gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw
+CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT
+U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2
+MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh
+dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG
+ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm
+acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN
+SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME
+GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW
+uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp
+15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN
+b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO
+MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD
+DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX
+DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw
+b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP
+L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY
+t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins
+S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3
+PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO
+L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3
+R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w
+dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS
++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS
+d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG
+AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f
+gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
+BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z
+NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt
+hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM
+QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf
+R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ
+DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW
+P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy
+lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq
+bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w
+AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q
+r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji
+Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU
+98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x
+ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1
+c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx
+OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI
+SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI
+b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn
+swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu
+7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8
+1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW
+80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP
+JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l
+RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw
+hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10
+coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc
+BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n
+twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud
+DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W
+0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe
+uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q
+lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB
+aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE
+sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT
+MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe
+qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh
+VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8
+h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9
+EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK
+yeC2nOnOcXHebD8WpHk=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN
+FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w
+DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw
+CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh
+DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD
+VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf
+BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3
+YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x
+NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G
+A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0
+d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF
+Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ
+j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF
+1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G
+A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3
+AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC
+MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu
+Sw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
+gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
+MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
+UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
+NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
+dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
+dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
+38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
+KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
+DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
+qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
+JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
+PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
+BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
+jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
+eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
+vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
+IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
+i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
+O+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
+biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
+76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
+bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
+6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
+emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
+MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
+MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
+MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
+FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
+aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
+gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
+qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
+lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
+8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
+45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
+UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
+O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
+bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
+GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
+77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
+hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
+92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
+Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
+ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
+Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFlzCCA3+gAwIBAgIURg7UAXGQoBqDLEpCECgV0mEbrTIwDQYJKoZIhvcNAQEL
+BQAwUzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEtMCsGA1UE
+AxMkU3dpc3NTaWduIFJTQSBTTUlNRSBSb290IENBIDIwMjIgLSAxMB4XDTIyMDYw
+ODEwNTMxM1oXDTQ3MDYwODEwNTMxM1owUzELMAkGA1UEBhMCQ0gxFTATBgNVBAoT
+DFN3aXNzU2lnbiBBRzEtMCsGA1UEAxMkU3dpc3NTaWduIFJTQSBTTUlNRSBSb290
+IENBIDIwMjIgLSAxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1Pv6
+P4aimXAJOsnWoU4Bzka1LSRIDUXprMka1zKApObTytbyKTfsmizWgc7mG52xD0Hf
+WNNfqqB5WQuMrfnF+Rz7w+k1QHTDwQzLZ/ucXgwj+dAv+kyCRRy19R/4GW7ak7dO
+aIN+Yi0djJUfcNnOWowhXai+CKlWbdn3uZCZxzvXvZ4uyWdXLiHO8DKD+wQB+beC
+RA2yy3oJoUg+T8ALahsb7M8dnn8GkKwoBQuo5lQ7oqcsOROZqPs06/XwvQHYiBHI
+rroZAkkC3IostL1hYOydeFxqiy8Xhl7yT5MAa13FsqmlGOrmbX5XBfsH/Lx8oUOx
+ZhyoZ/urN/aqqrh6Qfc51YyfrnI2J+RixkOZ8aFB6f+Jnw9Jr8kUBhcnZDkNpbQq
+W+w8+5/FX8Y7XSYZ8oQpuJVECVL9bDDQYo8opYGWK5QvJnXkCYwK3zjzfl04joKa
+jNyers4SQjoi8jWNT9IayEkzC/o2P/8sa2ogcUzNrRA/aTKEjlzuU4hE4t3MAzCS
+hnmQKkt1+1JixPRvTffbI6EY3UVTF5pjJEiJIs1+mwEcgCgDj1sr+h/jfBm95o+x
+QHag8sc3sjKUEDLNpxOX8TssejQie3Q6QOKvgvjBwXj8X+Q1f8D0TPBMsuqHA3Il
+WYMqCKRR3s/uqOfoQD+I8DarCU7YoKh/8+EJ27kCAwEAAaNjMGEwDwYDVR0TAQH/
+BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHwYDVR0jBBgwFoAUzC6tiYyD40CjJWml
+6pJ90jc6x8YwHQYDVR0OBBYEFMwurYmMg+NAoyVppeqSfdI3OsfGMA0GCSqGSIb3
+DQEBCwUAA4ICAQAAB2YWpe3Hub+8yJGtWO1eEgWz9kabe+SEEC8HsVpeMm5tAPBe
+x5piOYdN5Dzzvva6alNshG0H1GHKZ2a+mz5FMJ1R0tdaQq6dkg4jq9AVlD6omsqb
+7cHCXyGjmYD8uaZhDlCAgCfH6H2g1JR6mAPn7kKL81JQXO++sHZaHAmhv4PAHnZl
+0CVBW2mRk3f5jEvwLNubBgAXg/palLSGie+8CgsS+AZN0nPikThduWpLT6ev2iYl
+kiMafB8nDZGE7xdy9kbrazs3qdTVmmO6XnmMKrWbojS1zJYn+XkIPH9t4P983MUm
+r8OhemkW3Yc1c8ZrMWtWAS1PmdnuyuHQg962hecW+NGuM0j7Gs9dX4qEYXQHbxmw
+USGyoQSxe1OP76JFrR+Y3flqBGyqNsWvjOopSUrn/1ezxjwRSRgX5maF4egj8osO
+PJPEP3ZOfmKiKcsWMN4saa+Rp+JX5TNMv9iOB6J/oTVGaUqoICn/694glVmxrk0w
+a9iatAMfwjjkINUO1howTGicjODtoQ+OQl3rgCoSeaYXF7SVKo40kae90ayoGkMh
+i97v4KxGJWUKxiuhmz4i6Bg4tSb2LMoIIN4w0a1U/dxIFZ/Np0HXNziFME8SiEM0
+g9cqTdQAV1zlyvDd4ZIoKxh1vUekQhPpVlqNSl7ODnU1gHMZDywpi7uVuA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQEL
+BQAwUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UE
+AxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgx
+MTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxT
+d2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0EgVExTIFJvb3QgQ0Eg
+MjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmjiC8NX
+vDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7
+LCTLf5ImgKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX
+5XH8irCRIFucdFJtrhUnWXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyE
+EPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlfGUEGjw5NBuBwQCMBauTLE5tzrE0USJIt
+/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36qOTw7D59Ke4LKa2/KIj4x
+0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLOEGrOyvi5
+KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM
+0ZPlEuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shd
+OxtYk8EXlFXIC+OCeYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrta
+clXvyFu1cvh43zcgTFeRc5JzrBh3Q4IgaezprClG5QtO+DdziZaKHG29777YtvTK
+wP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQABo2MwYTAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow4UD2p8P98Q+4
+DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL
+BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO3
+10aewCoSPY6WlkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgz
+Hqp41eZUBDqyggmNzhYzWUUo8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQ
+iJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zpy1FVCypM9fJkT6lc/2cyjlUtMoIc
+gC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3CjlvrzG4ngRhZi0Rjn9UM
+ZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6MOuhF
+LhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJp
+zv1/THfQwUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/Td
+Ao9QAwKxuDdollDruF/UKIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0
+rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EO
+gLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ
+MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
+IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5
+WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO
+LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P
+40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF
+avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/
+34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i
+JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu
+j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf
+Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP
+2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA
+S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA
+oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC
+kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW
+5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd
+BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB
+AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t
+tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn
+68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn
+TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t
+RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx
+f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI
+Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz
+8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4
+NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX
+xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6
+t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx
+EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT
+VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5
+NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT
+B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG
+SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF
+10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz
+0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh
+MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH
+zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc
+46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2
+yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi
+laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP
+oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA
+BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE
+qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm
+4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL
+1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF
+H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo
+RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+
+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh
+15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW
+6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW
+nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j
+wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz
+aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy
+KwbQBM0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFlTCCA32gAwIBAgIQQAE0jMIAAAAAAAAAAZdY9DANBgkqhkiG9w0BAQwFADBU
+MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290
+IENBMR8wHQYDVQQDExZUV0NBIEdsb2JhbCBSb290IENBIEcyMB4XDTIyMTEyMjA2
+NDIyMVoXDTQ3MTEyMjE1NTk1OVowVDELMAkGA1UEBhMCVFcxEjAQBgNVBAoTCVRB
+SVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEfMB0GA1UEAxMWVFdDQSBHbG9iYWwg
+Um9vdCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKoO1SCS
+Aa2C+QwIkTRrihbQRhb/A7jYjeqTNPv/K739bqrcm/KGgVX1iRzEjXVqWHiREx4C
+E3A9774K5wCPuDHldMUwvv991pnlwkKjzyHWswh/kdVh5qKVEA3vXpcLSTjVIrDX
+i1lvnzWbf9KRzHp/u6Cf3lUz9kuNCup9CcB53L1E4v4c52QhKM8ESuK0v4Z5KrsO
+k8mPXqwwOVKQB7nqnCZCFMRnRv7RGmihPlAZoyYKJymQwva063OaeB7hmPRlDDUh
+BvgL3mLlTcGzXdm5+mGXKuPqx0RVJJL+Eqc/xHfgLQKBB9X7feYQnjq0qO/s+1Dq
+Nc/MfrtCuURsUum/KnIfP96bcOncWsU7u7/wWYWvL8GwFHkFrHWfJfURJwZgIcdt
+Zb6oiZzlrEbf+F1EA41gvfexDcwv70FUL+5rlblOfDTfO/l3nX3NBz0cBjMSgOxy
+nPItgtrVO8TH+QTDZAJ89TVgp7RGKS4b76VYgC56iVE4Njz9oXe4gDDQit6NpzQm
+7CO7GFUYNkXu7QEGqk2/ZAzKmJcaMQJm+HhoW4jfCajnm/o0bXAcIa0Ii/Khtqx2
+ar/xgCUAvjweTa65PLaVY71rfkcSkFVFEY3sFx/BvieBk1djaQAmd4vDWeV70Q1E
+8qjw94WaBffCLnCak4XYlZAxkFSm7AufN0UPAgMBAAGjYzBhMA4GA1UdDwEB/wQE
+AwIBBjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFJKM1DbRW0dTxHENhN1k
+KvU2ZEDnMB0GA1UdDgQWBBSSjNQ20VtHU8RxDYTdZCr1NmRA5zANBgkqhkiG9w0B
+AQwFAAOCAgEAJfxL2pC02nXnQTqB0ab+oGrzGHFiaiQIi6l6TclVzs8QKC4EGZYF
+z10CICo7s1U/Ac1CzbJ37f9183x325alz4xnBvSkm3L2IUkJmKMyXndaYwnvYkOX
+Aji16jwYUGj8WVvZedTx5FZIE1bY03ELXniUOBFF+gUX9Q51HmJSYUa6LhmthrSI
+D7FQ5kAANBqVnZPgUfnUVUbplTwlhi6X1wExGETsHGDpfWmvMviXQCUkto0aVTzF
+t/e8BlI7cTBwPnEXfvFmBF5dvIoxQ6aSHXtU0qU2i2+N1l7a1MMuHd85VWCCMJ4n
+/46A3WNMplU12NAzqYBtPl6dzKhngGb6mVcMUsoZdbA4NVUqgcWMHlbXX5DyINja
+4GZx6bJ4q2e5JG5rNnL8b439f3I5KGdSkQUfV2XSo6cNYfqh59U1RpXJBof2MOwy
+UamsVsAhTqMUdAU6vOO/bT1OP16lpG0pv4RRdVOOhhr1UXAqDRxOQOH9o+OlK2eQ
+ksdsroW/OpsXFcqcKpPUTTkNvCAIo42IbAkNjK5EIU3JcezYJtcXni0RGDyjIn24
+J1S/aMg7QsyPXk7n3MLF+mpED41WiHrfiYRsoLM+PfFlAAmI6irrQM6zXawyF67B
+m+nQwfVJlN2nznxaB+uuIJwXMJJpk3Lzmltxm/5q33owaY6zLtsPLN0=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
+MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
+V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
+WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
+LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
+AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
+K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
+RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
+rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
+3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
+hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
+MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
+XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
+lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
+aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
+YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx
+CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE
+AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1
+NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ
+MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq
+AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9
+vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9
+lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD
+n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT
+7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o
+6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC
+TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6
+WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R
+DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI
+pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj
+YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy
+rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ
+8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi
+0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM
+A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS
+SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K
+TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF
+6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er
+3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt
+Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT
+VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW
+ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA
+rBPuUBQemMc=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw
+NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv
+b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD
+VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2
+MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F
+VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1
+7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X
+Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+
+/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs
+81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm
+dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe
+Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu
+sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4
+pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs
+slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ
+arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD
+VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG
+9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl
+dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj
+TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed
+Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7
+Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI
+OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7
+vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW
+t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn
+HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx
+SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM
+BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp
+ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe
+Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw
+IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU
+cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS
+T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK
+AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1
+nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep
+qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA
+yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs
+hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX
+zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv
+kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT
+f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA
+uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB
+o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih
+MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E
+BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4
+wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2
+XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1
+JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j
+ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV
+VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx
+xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on
+AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d
+7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj
+gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV
++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo
+FGWsJwt0ivKH
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw
+WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
+IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y
+MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD
+VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz
+dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx
+s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw
+LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij
+YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD
+pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE
+AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR
+UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj
+/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICNjCCAbugAwIBAgIUWsL4KU/jfcVeHRhvO5MgH/97ui0wCgYIKoZIzj0EAwMw
+WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
+IEluYy4xJDAiBgNVBAMTG1RydXN0QXNpYSBTTUlNRSBFQ0MgUm9vdCBDQTAeFw0y
+NDA1MTUwNTQxNTlaFw00NDA1MTUwNTQxNThaMFoxCzAJBgNVBAYTAkNOMSUwIwYD
+VQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDExtUcnVz
+dEFzaWEgU01JTUUgRUNDIFJvb3QgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATN
+2fsnvWnshsmQQ7FwF5SnyXcjOj8jZdMcox0eQlQg69BCu1m5i6zyho1Ljh2qliIj
+OXZtkpvrIst6Q6Jz/XNLwiUPKrFpxv9F36k8lYC7qR5Kky/sHB2I9BGSN583mHKj
+QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFDFn5nKyDeYioKzPfiKnWTLj
+ZiOlMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNpADBmAjEA3TpMjaTGf+29
+pcZPPv0xSyjWilbfZRZ3h037ujIIgeCeM0iLn5SG7wErlOaM1tSOAjEAn4GcsCb9
+K9by9XGEnqjHiozWWBFStbgEy8xxdWPixhk42W1sGXGkFhkhk7oGRChs
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFhDCCA2ygAwIBAgIUWu5x394MV4W1uzYi17h2RgJzyv8wDQYJKoZIhvcNAQEM
+BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp
+ZXMsIEluYy4xJDAiBgNVBAMTG1RydXN0QXNpYSBTTUlNRSBSU0EgUm9vdCBDQTAe
+Fw0yNDA1MTUwNTQyMDFaFw00NDA1MTUwNTQyMDBaMFoxCzAJBgNVBAYTAkNOMSUw
+IwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDExtU
+cnVzdEFzaWEgU01JTUUgUlNBIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQCYlZytPFlz05N2pkhUphyIckxN4YL/GhMfUN6M2ZBC0byZ0zej
+13E6yt1eG5BhQm6PQAFzfR8xutQdbgTSqpCESjMKRJ9aGR+0bi1o/K/An0oQEr8+
+gsKCsC/nkG+QZBCD7Ow2lAx8T+ACDT2HeUJNAOUwrnAfFf36z1IlNk15ILvxEJjg
+YIfJ9XgMIu0C5hFs8ZtakRF0htD+eJKWBMOY78Zwr6mQqhb2Iu3Y+kYoceLJCMBQ
+vHajui2W8hH5pL0QVvgnbStLZIjcF13PAAiKkq4azBLX3/AQKPPNOuo6Eowb52EJ
+Q2rkOOn+dDnbzQo7w09T1q5x1TiDhx/O50zzEVWH37ev9+sahhBtqO1I3TLQ26oq
+C3J3KXf9eug/eCAqaL7ebwjmtYVHgDf5cZaLpZhWl3wRZRaO1M7YJ9T5WsWnjbvR
+Nw2lq2Vd2nSTiF7bdfZ/m8KasW0IAgyYSrvNMK92NQKFViNRCUAJBffwPR7CyHoa
+usVBFbkNdrS0pLhF/Y2jOz0DKs2zlX80e92hT9k6/yf1DcIBnP9ZdVoayefS/X9P
+D7X+DTzmoNb7tXZctDBNED/+4utaDrFPT1B+CDMCkVcySYmnQBBQF2ufY7qyslaY
+dvT/cukEnNSnTE/2Oh9aVDFvy7oyrfhtr0XHe2NE38L9eOhKirB0dRbejwIDAQAB
+o0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSAGqpDwcl/ixqWRbw9u2tI
+UmxbqzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACp1gaGCIOp/
+Vq4JMJcQePTZQBRSpO5qf/AJKNYQY+BOe8kxxwilF+uvhuKXB0+pDqKFzO2kgIEd
+WlMGPEwaqbeEhs989YUKcJnQ7TaRjed3Ls6EnCiGLSU1jEwB5n3bYV3id4TTAdFi
+3QyiCmSk/PDtOkjyOew11qF6F3Hs09LsuCb7rRVwVkrPZMC5YFv35s2gwgMr+bLl
+2rqlNxzYjdp5dCpn5KJ6xyyNpcFqgWzM9ak5aiJ9ouIIzemT27rLH3V3nveYrxTk
+O6BMp3LntV5TScz/klfxWSsJuulSk8APRQth1mxZcwvY+QEv2gNPNxz034NeC0Gg
+sXw5AKFs0Ni0kXIrGz+imtHE3yvVyJV9hM12G9zkJMY/FSI9hadCK+1+cVlhSMI9
+kWNAfCmzgBYKJfwYYA5TrQ4qzvxBOs2x5GprzDltyE1luKqTiHhuDwKL4JaOdB/Q
+fuF0t/aBauQjrI79jzUdmnEKTypVL/4YwQD3e0iKZa9vCB1D51q4H6ToA+v9TLW0
+k6gx3kOdEr3n6aTS32/8b0aj7zFOjRerG6ng+Kk0VqEO53TsqIeF2Hc1S40+bnJ8
+SMwfcrNxdNQkhrzIwON5FAHO2fqBxlyz+V0MOL7O8o6NXz0l4VE5I6jqAI4Es79y
+oMK6g/vNpJd1IJq/p1Di3a0sH/Q/o8gx
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMw
+WDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs
+IEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQw
+NTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBYMQswCQYDVQQGEwJDTjElMCMGA1UE
+ChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1c3RB
+c2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/pVs/
+AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDp
+guMqWzJ8S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAw
+DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAw
+DgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01
+L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15KeAIxAKORh/IRM4PDwYqR
+OkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEM
+BQAwWDELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dp
+ZXMsIEluYy4xIjAgBgNVBAMTGVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcN
+MjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2WjBYMQswCQYDVQQGEwJDTjElMCMG
+A1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAGA1UEAxMZVHJ1
+c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
+AgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+
+NmDQDIPNlOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJ
+Q1DNDX3eRA5gEk9bNb2/mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561
+HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fkzv93uMltrOXVmPGZLmzjyUT5tUMnCE32
+ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYozza/+lcK7Fs/6TAWe8Tb
+xNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyrz2I8sMeX
+i9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQ
+UNoyIBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+j
+TnhMmCWr8n4uIF6CFabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DT
+bE3txci3OE9kxJRMT6DNrqXGJyV1J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8
+S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnTq1mt1tve1CuBAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZylomkadFK/hT
+MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3
+Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4
+iqME3mmL5Dw8veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt
+7DlK9RME7I10nYEKqG/odv6LTytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp
+2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHxtlotJnMnlvm5P1vQiJ3koP26TpUJ
+g3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp27RIGAAtvKLEiUUj
+pQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87qqA8M
+pugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongP
+XvPKnbwbPKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIwe
+SsCI3zWQzj8C9GRh3sfIB5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0
+ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNzFrwFuHnYWa8G5z9nODmxfKuU4CkUpijy
+323imttUQ/hHWKNddBWcwauwxzQ=
+-----END CERTIFICATE-----
diff --git a/common/certificate/store.go b/common/certificate/store.go
index 353bc8182c..f489267d34 100644
--- a/common/certificate/store.go
+++ b/common/certificate/store.go
@@ -1,6 +1,7 @@
package certificate
import (
+ "bytes"
"context"
"crypto/x509"
"io/fs"
@@ -29,6 +30,8 @@ type Store struct {
certificatePaths []string
certificateDirectoryPaths []string
watcher *fswatch.Watcher
+ //nolint:unused // populated only on darwin && cgo via the storePlatform embed.
+ platform storePlatform
}
func NewStore(ctx context.Context, logger logger.Logger, options option.CertificateOptions) (*Store, error) {
@@ -113,10 +116,18 @@ func (s *Store) Start(stage adapter.StartStage) error {
}
func (s *Store) Close() error {
- if s.watcher != nil {
- return s.watcher.Close()
+ watcher := s.watcher
+ s.watcher = nil
+
+ var closeErr error
+ if watcher != nil {
+ closeErr = watcher.Close()
}
- return nil
+ platformErr := s.closePlatform()
+ if platformErr != nil {
+ closeErr = platformErr
+ }
+ return closeErr
}
func (s *Store) Pool() *x509.CertPool {
@@ -125,15 +136,39 @@ func (s *Store) Pool() *x509.CertPool {
return s.currentPool
}
+func (s *Store) StoreKind() string {
+ return s.storeType
+}
+
+func (s *Store) ExclusiveAnchors() bool {
+ return s.storeType != C.CertificateStoreSystem
+}
+
func (s *Store) update() error {
currentPool, err := s.newBasePool()
if err != nil {
return err
}
+ pemBuffer := new(bytes.Buffer)
+ switch s.storeType {
+ case C.CertificateStoreMozilla:
+ pemContent := mozillaIncludedPEM()
+ if !currentPool.AppendCertsFromPEM([]byte(pemContent)) {
+ return E.New("invalid Mozilla included certificate PEM")
+ }
+ appendPEMBlock(pemBuffer, string(pemContent))
+ case C.CertificateStoreChrome:
+ pemContent := chromeIncludedPEM()
+ if !currentPool.AppendCertsFromPEM([]byte(pemContent)) {
+ return E.New("invalid Chrome included certificate PEM")
+ }
+ appendPEMBlock(pemBuffer, string(pemContent))
+ }
if s.certificate != "" {
if !currentPool.AppendCertsFromPEM([]byte(s.certificate)) {
return E.New("invalid certificate PEM strings")
}
+ appendPEMBlock(pemBuffer, s.certificate)
}
for _, path := range s.certificatePaths {
pemContent, err := os.ReadFile(path)
@@ -143,6 +178,7 @@ func (s *Store) update() error {
if !currentPool.AppendCertsFromPEM(pemContent) {
return E.New("invalid certificate PEM file: ", path)
}
+ appendPEMBlock(pemBuffer, string(pemContent))
}
var firstErr error
for _, directoryPath := range s.certificateDirectoryPaths {
@@ -155,8 +191,8 @@ func (s *Store) update() error {
}
for _, directoryEntry := range directoryEntries {
pemContent, err := os.ReadFile(filepath.Join(directoryPath, directoryEntry.Name()))
- if err == nil {
- currentPool.AppendCertsFromPEM(pemContent)
+ if err == nil && currentPool.AppendCertsFromPEM(pemContent) {
+ appendPEMBlock(pemBuffer, string(pemContent))
}
}
}
@@ -166,7 +202,15 @@ func (s *Store) update() error {
s.access.Lock()
defer s.access.Unlock()
s.currentPool = currentPool
- return nil
+ return s.updatePlatformLocked(pemBuffer.Bytes())
+}
+
+func appendPEMBlock(buffer *bytes.Buffer, block string) {
+ existing := buffer.Bytes()
+ if len(existing) > 0 && existing[len(existing)-1] != '\n' {
+ buffer.WriteByte('\n')
+ }
+ buffer.WriteString(block)
}
func (s *Store) newBasePool() (*x509.CertPool, error) {
@@ -176,10 +220,8 @@ func (s *Store) newBasePool() (*x509.CertPool, error) {
return x509.NewCertPool(), nil
}
return s.systemPool.Clone(), nil
- case C.CertificateStoreMozilla:
- return newMozillaIncluded(), nil
- case C.CertificateStoreChrome:
- return newChromeIncluded(), nil
+ case C.CertificateStoreMozilla, C.CertificateStoreChrome:
+ return x509.NewCertPool(), nil
case C.CertificateStoreNone:
return x509.NewCertPool(), nil
default:
diff --git a/common/certificate/store_darwin.go b/common/certificate/store_darwin.go
new file mode 100644
index 0000000000..bbc8d4ba84
--- /dev/null
+++ b/common/certificate/store_darwin.go
@@ -0,0 +1,167 @@
+//go:build darwin && cgo
+
+package certificate
+
+/*
+#cgo CFLAGS: -x objective-c -fobjc-arc
+#cgo LDFLAGS: -framework Foundation -framework Security
+
+#include
+#include "anchors_darwin.h"
+*/
+import "C"
+
+import (
+ "crypto/sha256"
+ "encoding/pem"
+ "runtime"
+ "sync/atomic"
+ "unsafe"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+var (
+ _ adapter.AppleCertificateStore = (*Store)(nil)
+ _ adapter.AppleAnchors = (*appleAnchors)(nil)
+)
+
+type storePlatform struct {
+ anchors *appleAnchors
+ hash [sha256.Size]byte
+}
+
+type appleAnchors struct {
+ cfArray unsafe.Pointer
+ refs atomic.Int32
+}
+
+func newAppleAnchors(pemBytes []byte) (*appleAnchors, error) {
+ anchors := &appleAnchors{}
+ anchors.refs.Store(1)
+ if len(pemBytes) == 0 {
+ return anchors, nil
+ }
+ derBlocks := decodeCertificatePEM(pemBytes)
+ if len(derBlocks) == 0 {
+ return nil, E.New("parse certificate PEM")
+ }
+ pointerSize := C.size_t(unsafe.Sizeof((*C.uint8_t)(nil)))
+ lenSize := C.size_t(unsafe.Sizeof(C.size_t(0)))
+ pointersC := (**C.uint8_t)(C.malloc(pointerSize * C.size_t(len(derBlocks))))
+ defer C.free(unsafe.Pointer(pointersC))
+ lensC := (*C.size_t)(C.malloc(lenSize * C.size_t(len(derBlocks))))
+ defer C.free(unsafe.Pointer(lensC))
+ pointersSlice := unsafe.Slice(pointersC, len(derBlocks))
+ lensSlice := unsafe.Slice(lensC, len(derBlocks))
+ var pinner runtime.Pinner
+ defer pinner.Unpin()
+ for index, der := range derBlocks {
+ pinner.Pin(&der[0])
+ pointersSlice[index] = (*C.uint8_t)(unsafe.Pointer(&der[0]))
+ lensSlice[index] = C.size_t(len(der))
+ }
+ cfArray := C.box_certificate_anchors_from_der(pointersC, lensC, C.size_t(len(derBlocks)))
+ if cfArray == nil {
+ return nil, E.New("parse certificate PEM")
+ }
+ anchors.cfArray = cfArray
+ return anchors, nil
+}
+
+// NewAppleAnchors parses the given PEM and returns a ref-counted handle
+// wrapping a CFArray of SecCertificateRef. The caller owns the returned
+// reference and must call Release when finished. Returns an error when
+// pemBytes is non-empty but contains no usable CERTIFICATE blocks.
+func NewAppleAnchors(pemBytes []byte) (adapter.AppleAnchors, error) {
+ return newAppleAnchors(pemBytes)
+}
+
+// AcquireAnchors returns a retained AppleAnchors handle, preferring the
+// per-config userAnchors over the process-wide certificate store. Returns
+// nil when neither source is available. Callers must Release the handle.
+func AcquireAnchors(userAnchors adapter.AppleAnchors, store adapter.CertificateStore) adapter.AppleAnchors {
+ if userAnchors != nil {
+ return userAnchors.Retain()
+ }
+ if store == nil {
+ return nil
+ }
+ apple, loaded := store.(adapter.AppleCertificateStore)
+ if !loaded {
+ return nil
+ }
+ return apple.AppleAnchors()
+}
+
+func (a *appleAnchors) Retain() adapter.AppleAnchors {
+ a.refs.Add(1)
+ return a
+}
+
+func (a *appleAnchors) Release() {
+ if a.refs.Add(-1) != 0 {
+ return
+ }
+ if a.cfArray != nil {
+ C.box_certificate_release_anchors(a.cfArray)
+ }
+}
+
+func (a *appleAnchors) Ref() unsafe.Pointer {
+ return a.cfArray
+}
+
+func (s *Store) AppleAnchors() adapter.AppleAnchors {
+ s.access.RLock()
+ defer s.access.RUnlock()
+ if s.platform.anchors == nil {
+ return nil
+ }
+ return s.platform.anchors.Retain()
+}
+
+func (s *Store) updatePlatformLocked(pemBytes []byte) error {
+ hash := sha256.Sum256(pemBytes)
+ if s.platform.anchors != nil && s.platform.hash == hash {
+ return nil
+ }
+ newAnchors, err := newAppleAnchors(pemBytes)
+ if err != nil {
+ return err
+ }
+ old := s.platform.anchors
+ s.platform.anchors = newAnchors
+ s.platform.hash = hash
+ if old != nil {
+ old.Release()
+ }
+ return nil
+}
+
+func (s *Store) closePlatform() error {
+ s.access.Lock()
+ defer s.access.Unlock()
+ if s.platform.anchors != nil {
+ s.platform.anchors.Release()
+ s.platform.anchors = nil
+ }
+ return nil
+}
+
+func decodeCertificatePEM(pemBytes []byte) [][]byte {
+ var blocks [][]byte
+ rest := pemBytes
+ for {
+ block, next := pem.Decode(rest)
+ if block == nil {
+ break
+ }
+ if block.Type == "CERTIFICATE" && len(block.Bytes) > 0 {
+ blocks = append(blocks, block.Bytes)
+ }
+ rest = next
+ }
+ return blocks
+}
diff --git a/common/certificate/store_other.go b/common/certificate/store_other.go
new file mode 100644
index 0000000000..746520d141
--- /dev/null
+++ b/common/certificate/store_other.go
@@ -0,0 +1,14 @@
+//go:build !(darwin && cgo)
+
+package certificate
+
+//nolint:unused // referenced by Store.platform; populated only in store_darwin.go.
+type storePlatform struct{}
+
+func (s *Store) updatePlatformLocked(_ []byte) error {
+ return nil
+}
+
+func (s *Store) closePlatform() error {
+ return nil
+}
diff --git a/common/cloudflare/api.go b/common/cloudflare/api.go
new file mode 100644
index 0000000000..d86f811c53
--- /dev/null
+++ b/common/cloudflare/api.go
@@ -0,0 +1,224 @@
+package cloudflare
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "strings"
+ "time"
+
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/tidwall/gjson"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+)
+
+type CloudflareApi struct {
+ client http.Client
+}
+
+const baseUrl = "https://api.cloudflareclient.com/v0i1909051800/"
+
+func NewCloudflareApiDetour(detour N.Dialer) *CloudflareApi {
+ opts := make([]CloudflareApiOption, 0, 1)
+ if detour != nil {
+ opts = append(opts, WithDialContext(func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return detour.DialContext(ctx, network, M.ParseSocksaddr(addr))
+ }))
+ }
+ return NewCloudflareApi(opts...)
+}
+func NewCloudflareApi(opts ...CloudflareApiOption) *CloudflareApi {
+ api := &CloudflareApi{http.Client{Timeout: 30 * time.Second}}
+ for _, opt := range opts {
+ opt(api)
+ }
+ return api
+}
+
+func (api *CloudflareApi) CreateProfile(ctx context.Context, publicKey string) (*CloudflareProfile, error) {
+ request, err := http.NewRequest("POST", baseUrl+"reg", strings.NewReader(
+ fmt.Sprintf(
+ "{\"install_id\":\"\",\"tos\":\"%s\",\"key\":\"%s\",\"fcm_token\":\"\",\"type\":\"ios\",\"locale\":\"en_US\"}",
+ time.Now().Format("2006-01-02T15:04:05.000Z"),
+ publicKey,
+ ),
+ ))
+ if err != nil {
+ return nil, err
+ }
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != 200 {
+ return nil, fmt.Errorf("status code is not 200")
+ }
+ content, err := io.ReadAll(response.Body)
+ if err != nil {
+ return nil, err
+ }
+ profile := new(CloudflareProfile)
+ return profile, json.NewDecoder(strings.NewReader(gjson.Get(string(content), "result").Raw)).Decode(profile)
+}
+
+func (api *CloudflareApi) GetProfile(ctx context.Context, authToken string, id string) (*CloudflareProfile, error) {
+ request, err := http.NewRequest("GET", baseUrl+"reg/"+id, nil)
+ if err != nil {
+ return nil, err
+ }
+ request.Header.Set("Authorization", "Bearer "+authToken)
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != 200 {
+ return nil, fmt.Errorf("status code is not 200")
+ }
+ content, err := io.ReadAll(response.Body)
+ if err != nil {
+ return nil, err
+ }
+ profile := new(CloudflareProfile)
+ return profile, json.NewDecoder(strings.NewReader(gjson.Get(string(content), "result").Raw)).Decode(profile)
+}
+
+func (api *CloudflareApi) UpdateAccount(ctx context.Context, profile *CloudflareProfile, license string) (*CloudflareProfile, error) {
+ deviceId := profile.ID
+ authToken := profile.Token
+ request, err := http.NewRequest("POST", fmt.Sprint(baseUrl, "reg/", deviceId, "/account"), strings.NewReader(
+ fmt.Sprintf("{\"license\":\"%s\"}", license),
+ ))
+ request.Header.Set("Authorization", "Bearer "+authToken)
+ if err != nil {
+ return nil, err
+ }
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != 200 {
+ return nil, fmt.Errorf("status code is not 200")
+ }
+ content, err := io.ReadAll(response.Body)
+ if err != nil {
+ return nil, err
+ }
+ ia := new(IdentityAccount)
+ if err := json.Unmarshal([]byte(content), ia); err != nil {
+ return nil, err
+ }
+
+ profile.Account = *ia
+ return profile, nil
+}
+
+func (api *CloudflareApi) CreateProfileLicense(ctx context.Context, privateKey string, license string) (*CloudflareProfile, error) {
+ var wgKey wgtypes.Key
+ var err error
+ if privateKey != "" {
+ wgKey, err = wgtypes.ParseKey(privateKey)
+ if err != nil {
+
+ return nil, err
+ }
+ } else {
+ wgKey, err = wgtypes.GeneratePrivateKey()
+ if err != nil {
+
+ return nil, err
+ }
+ }
+ profile, err := api.CreateProfile(ctx, wgKey.PublicKey().String())
+ if err != nil {
+ return nil, err
+ }
+ profile.Config.PrivateKey = wgKey.String()
+ if license == "" {
+ return profile, nil
+ }
+ return api.UpdateAccount(ctx, profile, license)
+}
+
+func (api *CloudflareApi) DeleteProfile(ctx context.Context, profile *CloudflareProfile) error {
+ request, err := http.NewRequest("DELETE", fmt.Sprint(baseUrl, "reg/", profile.ID), nil)
+ if err != nil {
+ return err
+ }
+ request.Header.Set("Authorization", "Bearer "+profile.Token)
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != 200 {
+ return fmt.Errorf("status code is not 200")
+ }
+ return nil
+}
+
+type DeviceUpdate struct {
+ Name string `json:"name"`
+ Key string `json:"key"`
+ KeyType string `json:"key_type"`
+ TunType string `json:"tunnel_type"`
+}
+
+func (api *CloudflareApi) GetProfile4471(ctx context.Context, authToken string, id string) (*CloudflareProfile, error) {
+ request, err := http.NewRequest("GET", ApiUrl+"/"+ApiVersion+"/reg/"+id, nil)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range Headers {
+ request.Header.Set(k, v)
+ }
+ request.Header.Set("Authorization", "Bearer "+authToken)
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != http.StatusOK {
+ return nil, fmt.Errorf("status code is not 200")
+ }
+ profile := new(CloudflareProfile)
+ return profile, json.NewDecoder(response.Body).Decode(profile)
+}
+
+func (api *CloudflareApi) EnrollKey(ctx context.Context, authToken string, id string, keyType, tunType, publicKey string) (*CloudflareProfile, error) {
+ deviceUpdate := DeviceUpdate{
+ Name: "PC",
+ Key: publicKey,
+ KeyType: keyType,
+ TunType: tunType,
+ }
+ jsonData, err := json.Marshal(deviceUpdate)
+ if err != nil {
+ return nil, fmt.Errorf("failed to marshal json: %v", err)
+ }
+ request, err := http.NewRequest("PATCH", ApiUrl+"/"+ApiVersion+"/reg/"+id, bytes.NewBuffer(jsonData))
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range Headers {
+ request.Header.Set(k, v)
+ }
+ request.Header.Set("Authorization", "Bearer "+authToken)
+ response, err := api.client.Do(request.WithContext(ctx))
+ if err != nil {
+ return nil, err
+ }
+ defer response.Body.Close()
+ if response.StatusCode != http.StatusOK {
+ return nil, fmt.Errorf("failed to enroll key: %v", response.StatusCode)
+ }
+ profile := new(CloudflareProfile)
+ return profile, json.NewDecoder(response.Body).Decode(profile)
+}
diff --git a/common/cloudflare/constant.go b/common/cloudflare/constant.go
new file mode 100644
index 0000000000..47bd5cb982
--- /dev/null
+++ b/common/cloudflare/constant.go
@@ -0,0 +1,24 @@
+package cloudflare
+
+const (
+ ApiUrl = "https://api.cloudflareclient.com"
+ ApiVersion = "v0a4471"
+ ConnectSNI = "consumer-masque.cloudflareclient.com"
+ ZeroTierSNI = "zt-masque.cloudflareclient.com"
+ ConnectURI = "https://cloudflareaccess.com"
+ DefaultModel = "PC"
+ KeyTypeWg = "curve25519"
+ TunTypeWg = "wireguard"
+ KeyTypeMasque = "secp256r1"
+ TunTypeMasque = "masque"
+ DefaultLocale = "en_US"
+ DefaultEndpointH2V4 = "162.159.198.2"
+ DefaultEndpointH2V6 = ""
+)
+
+var Headers = map[string]string{
+ "User-Agent": "WARP for Android",
+ "CF-Client-Version": "a-6.35-4471",
+ "Content-Type": "application/json; charset=UTF-8",
+ "Connection": "Keep-Alive",
+}
diff --git a/common/cloudflare/option.go b/common/cloudflare/option.go
new file mode 100644
index 0000000000..929e91b7ea
--- /dev/null
+++ b/common/cloudflare/option.go
@@ -0,0 +1,17 @@
+package cloudflare
+
+import (
+ "context"
+ "net"
+ "net/http"
+)
+
+type CloudflareApiOption func(api *CloudflareApi)
+
+func WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) CloudflareApiOption {
+ return func(api *CloudflareApi) {
+ api.client.Transport = &http.Transport{
+ DialContext: dialContext,
+ }
+ }
+}
diff --git a/common/cloudflare/profile.go b/common/cloudflare/profile.go
new file mode 100644
index 0000000000..9528774052
--- /dev/null
+++ b/common/cloudflare/profile.go
@@ -0,0 +1,45 @@
+package cloudflare
+
+import (
+ "time"
+
+ C "github.com/sagernet/sing-box/constant"
+)
+
+type IdentityAccount struct {
+ Created time.Time `json:"created"`
+ Updated time.Time `json:"updated"`
+ License string `json:"license"`
+ PremiumData int64 `json:"premium_data"`
+ WarpPlus bool `json:"warp_plus"`
+ AccountType string `json:"account_type"`
+ ReferralRenewalCountdown int64 `json:"referral_renewal_countdown"`
+ Role string `json:"role"`
+ ID string `json:"id"`
+ Quota int64 `json:"quota"`
+ Usage int64 `json:"usage"`
+ ReferralCount int64 `json:"referral_count"`
+ TTL time.Time `json:"ttl"`
+}
+type CloudflareProfile struct {
+ ID string `json:"id"`
+ Type string `json:"type"`
+ Name string `json:"name"`
+ Key string `json:"key"`
+ Account IdentityAccount `json:"account"`
+ Config C.WARPConfig `json:"config"`
+ Token string `json:"token"`
+ WARPEnabled bool `json:"warp_enabled"`
+ WaitlistEnabled bool `json:"waitlist_enabled"`
+ Created time.Time `json:"created"`
+ Updated time.Time `json:"updated"`
+ Tos time.Time `json:"tos"`
+ Place int `json:"place"`
+ Locale string `json:"locale"`
+ Enabled bool `json:"enabled"`
+ InstallID string `json:"install_id"`
+ FcmToken string `json:"fcm_token"`
+ Policy struct {
+ TunnelProtocol string `json:"tunnel_protocol"`
+ } `json:"policy"`
+}
diff --git a/common/dialer/detour.go b/common/dialer/detour.go
index 5c0b552ba8..b2fc3efa0b 100644
--- a/common/dialer/detour.go
+++ b/common/dialer/detour.go
@@ -17,19 +17,27 @@ type DirectDialer interface {
}
type DetourDialer struct {
- outboundManager adapter.OutboundManager
- detour string
- legacyDNSDialer bool
- dialer N.Dialer
- initOnce sync.Once
- initErr error
+ outboundManager adapter.OutboundManager
+ detour string
+ defaultOutbound bool
+ disableEmptyDirectCheck bool
+ dialer N.Dialer
+ initOnce sync.Once
+ initErr error
}
-func NewDetour(outboundManager adapter.OutboundManager, detour string, legacyDNSDialer bool) N.Dialer {
+func NewDetour(outboundManager adapter.OutboundManager, detour string, disableEmptyDirectCheck bool) N.Dialer {
+ return &DetourDialer{
+ outboundManager: outboundManager,
+ detour: detour,
+ disableEmptyDirectCheck: disableEmptyDirectCheck,
+ }
+}
+
+func NewDefaultOutboundDetour(outboundManager adapter.OutboundManager) N.Dialer {
return &DetourDialer{
outboundManager: outboundManager,
- detour: detour,
- legacyDNSDialer: legacyDNSDialer,
+ defaultOutbound: true,
}
}
@@ -47,12 +55,18 @@ func (d *DetourDialer) Dialer() (N.Dialer, error) {
}
func (d *DetourDialer) init() {
- dialer, loaded := d.outboundManager.Outbound(d.detour)
- if !loaded {
- d.initErr = E.New("outbound detour not found: ", d.detour)
- return
+ var dialer adapter.Outbound
+ if d.detour != "" {
+ var loaded bool
+ dialer, loaded = d.outboundManager.Outbound(d.detour)
+ if !loaded {
+ d.initErr = E.New("outbound detour not found: ", d.detour)
+ return
+ }
+ } else {
+ dialer = d.outboundManager.Default()
}
- if !d.legacyDNSDialer {
+ if !d.defaultOutbound && !d.disableEmptyDirectCheck {
if directDialer, isDirect := dialer.(DirectDialer); isDirect {
if directDialer.IsEmpty() {
d.initErr = E.New("detour to an empty direct outbound makes no sense")
diff --git a/common/dialer/dialer.go b/common/dialer/dialer.go
index 2ba559f9e0..f0e8043093 100644
--- a/common/dialer/dialer.go
+++ b/common/dialer/dialer.go
@@ -17,14 +17,15 @@ import (
)
type Options struct {
- Context context.Context
- Options option.DialerOptions
- RemoteIsDomain bool
- DirectResolver bool
- ResolverOnDetour bool
- NewDialer bool
- LegacyDNSDialer bool
- DirectOutbound bool
+ Context context.Context
+ Options option.DialerOptions
+ RemoteIsDomain bool
+ DirectResolver bool
+ ResolverOnDetour bool
+ NewDialer bool
+ DisableEmptyDirectCheck bool
+ DirectOutbound bool
+ DefaultOutbound bool
}
// TODO: merge with NewWithOptions
@@ -42,19 +43,26 @@ func NewWithOptions(options Options) (N.Dialer, error) {
dialer N.Dialer
err error
)
+ hasDetour := dialOptions.Detour != "" || options.DefaultOutbound
if dialOptions.Detour != "" {
outboundManager := service.FromContext[adapter.OutboundManager](options.Context)
if outboundManager == nil {
return nil, E.New("missing outbound manager")
}
- dialer = NewDetour(outboundManager, dialOptions.Detour, options.LegacyDNSDialer)
+ dialer = NewDetour(outboundManager, dialOptions.Detour, options.DisableEmptyDirectCheck)
+ } else if options.DefaultOutbound {
+ outboundManager := service.FromContext[adapter.OutboundManager](options.Context)
+ if outboundManager == nil {
+ return nil, E.New("missing outbound manager")
+ }
+ dialer = NewDefaultOutboundDetour(outboundManager)
} else {
dialer, err = NewDefault(options.Context, dialOptions)
if err != nil {
return nil, err
}
}
- if options.RemoteIsDomain && (dialOptions.Detour == "" || options.ResolverOnDetour || dialOptions.DomainResolver != nil && dialOptions.DomainResolver.Server != "") {
+ if options.RemoteIsDomain && (!hasDetour || options.ResolverOnDetour || dialOptions.DomainResolver != nil && dialOptions.DomainResolver.Server != "") {
networkManager := service.FromContext[adapter.NetworkManager](options.Context)
dnsTransport := service.FromContext[adapter.DNSTransportManager](options.Context)
var defaultOptions adapter.NetworkOptions
@@ -87,11 +95,13 @@ func NewWithOptions(options Options) (N.Dialer, error) {
}
server = dialOptions.DomainResolver.Server
dnsQueryOptions = adapter.DNSQueryOptions{
- Transport: transport,
- Strategy: strategy,
- DisableCache: dialOptions.DomainResolver.DisableCache,
- RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
- ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
+ Transport: transport,
+ Strategy: strategy,
+ Timeout: time.Duration(dialOptions.DomainResolver.Timeout),
+ DisableCache: dialOptions.DomainResolver.DisableCache,
+ DisableOptimisticCache: dialOptions.DomainResolver.DisableOptimisticCache,
+ RewriteTTL: dialOptions.DomainResolver.RewriteTTL,
+ ClientSubnet: dialOptions.DomainResolver.ClientSubnet.Build(netip.Prefix{}),
}
resolveFallbackDelay = time.Duration(dialOptions.FallbackDelay)
} else if options.DirectResolver {
diff --git a/common/geosite/reader.go b/common/geosite/reader.go
index ecd63a7e2e..6cccee9ee3 100644
--- a/common/geosite/reader.go
+++ b/common/geosite/reader.go
@@ -9,6 +9,7 @@ import (
"sync/atomic"
E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/varbin"
)
type Reader struct {
@@ -71,7 +72,7 @@ func (r *Reader) readMetadata() error {
codeIndex uint64
codeLength uint64
)
- code, err = readString(reader)
+ code, err = varbin.ReadValue[string](reader, binary.BigEndian)
if err != nil {
return err
}
@@ -108,16 +109,9 @@ func (r *Reader) Read(code string) ([]Item, error) {
}
r.bufferedReader.Reset(r.reader)
itemList := make([]Item, r.domainLength[code])
- for i := range itemList {
- typeByte, err := r.bufferedReader.ReadByte()
- if err != nil {
- return nil, err
- }
- itemList[i].Type = ItemType(typeByte)
- itemList[i].Value, err = readString(r.bufferedReader)
- if err != nil {
- return nil, err
- }
+ err = varbin.Read(r.bufferedReader, binary.BigEndian, &itemList)
+ if err != nil {
+ return nil, err
}
return itemList, nil
}
@@ -138,18 +132,3 @@ func (r *readCounter) Read(p []byte) (n int, err error) {
}
return
}
-
-func readString(reader io.ByteReader) (string, error) {
- length, err := binary.ReadUvarint(reader)
- if err != nil {
- return "", err
- }
- bytes := make([]byte, length)
- for i := range bytes {
- bytes[i], err = reader.ReadByte()
- if err != nil {
- return "", err
- }
- }
- return string(bytes), nil
-}
diff --git a/common/geosite/writer.go b/common/geosite/writer.go
index 52f2f7b9b4..1615fa3480 100644
--- a/common/geosite/writer.go
+++ b/common/geosite/writer.go
@@ -2,6 +2,7 @@ package geosite
import (
"bytes"
+ "encoding/binary"
"sort"
"github.com/sagernet/sing/common/varbin"
@@ -19,11 +20,7 @@ func Write(writer varbin.Writer, domains map[string][]Item) error {
for _, code := range keys {
index[code] = content.Len()
for _, item := range domains[code] {
- err := content.WriteByte(byte(item.Type))
- if err != nil {
- return err
- }
- err = writeString(content, item.Value)
+ err := varbin.Write(content, binary.BigEndian, item)
if err != nil {
return err
}
@@ -41,7 +38,7 @@ func Write(writer varbin.Writer, domains map[string][]Item) error {
}
for _, code := range keys {
- err = writeString(writer, code)
+ err = varbin.Write(writer, binary.BigEndian, code)
if err != nil {
return err
}
@@ -62,12 +59,3 @@ func Write(writer varbin.Writer, domains map[string][]Item) error {
return nil
}
-
-func writeString(writer varbin.Writer, value string) error {
- _, err := varbin.WriteUvarint(writer, uint64(len(value)))
- if err != nil {
- return err
- }
- _, err = writer.Write([]byte(value))
- return err
-}
diff --git a/common/httpclient/apple_transport_darwin.go b/common/httpclient/apple_transport_darwin.go
new file mode 100644
index 0000000000..4619dc58de
--- /dev/null
+++ b/common/httpclient/apple_transport_darwin.go
@@ -0,0 +1,461 @@
+//go:build darwin && cgo
+
+package httpclient
+
+/*
+#cgo CFLAGS: -x objective-c -fobjc-arc
+#cgo LDFLAGS: -framework Foundation -framework Security
+
+#include
+#include "apple_transport_darwin.h"
+*/
+import "C"
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+ "unsafe"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/certificate"
+ "github.com/sagernet/sing-box/common/proxybridge"
+ boxTLS "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/ntp"
+)
+
+const applePinnedHashSize = sha256.Size
+
+var (
+ newAppleUserAnchors = certificate.NewAppleAnchors
+ newAppleProxyBridge = proxybridge.New
+ newAppleTransportSession = func(shared *appleTransportShared) (unsafe.Pointer, error) {
+ session, err := shared.newSession()
+ return unsafe.Pointer(session), err
+ }
+)
+
+func verifyApplePinnedPublicKeySHA256(flatHashes []byte, leafCertificate []byte) error {
+ if len(flatHashes)%applePinnedHashSize != 0 {
+ return E.New("invalid pinned public key list")
+ }
+ knownHashes := make([][]byte, 0, len(flatHashes)/applePinnedHashSize)
+ for offset := 0; offset < len(flatHashes); offset += applePinnedHashSize {
+ knownHashes = append(knownHashes, append([]byte(nil), flatHashes[offset:offset+applePinnedHashSize]...))
+ }
+ return boxTLS.VerifyPublicKeySHA256(knownHashes, [][]byte{leafCertificate})
+}
+
+//export box_apple_http_verify_public_key_sha256
+func box_apple_http_verify_public_key_sha256(knownHashValues *C.uint8_t, knownHashValuesLen C.size_t, leafCert *C.uint8_t, leafCertLen C.size_t) *C.char {
+ flatHashes := C.GoBytes(unsafe.Pointer(knownHashValues), C.int(knownHashValuesLen))
+ leafCertificate := C.GoBytes(unsafe.Pointer(leafCert), C.int(leafCertLen))
+ err := verifyApplePinnedPublicKeySHA256(flatHashes, leafCertificate)
+ if err == nil {
+ return nil
+ }
+ return C.CString(err.Error())
+}
+
+type appleSessionConfig struct {
+ serverName string
+ minVersion uint16
+ maxVersion uint16
+ insecure bool
+ anchorOnly bool
+ userAnchors adapter.AppleAnchors
+ store adapter.CertificateStore
+ pinnedPublicKeySHA256s []byte
+}
+
+type appleTransportShared struct {
+ logger logger.ContextLogger
+ bridge *proxybridge.Bridge
+ config appleSessionConfig
+ timeFunc func() time.Time
+ refs atomic.Int32
+}
+
+type appleTransport struct {
+ shared *appleTransportShared
+ access sync.Mutex
+ session *C.box_apple_http_session_t
+ closed bool
+}
+
+func newAppleTransport(ctx context.Context, logger logger.ContextLogger, rawDialer N.Dialer, options option.HTTPClientOptions) (innerTransport, error) {
+ sessionConfig, err := newAppleSessionConfig(ctx, options)
+ if err != nil {
+ return nil, err
+ }
+ releaseConfig := true
+ defer func() {
+ if releaseConfig {
+ sessionConfig.close()
+ }
+ }()
+ bridge, err := newAppleProxyBridge(ctx, logger, "apple http proxy", rawDialer)
+ if err != nil {
+ return nil, err
+ }
+ shared := &appleTransportShared{
+ logger: logger,
+ bridge: bridge,
+ config: sessionConfig,
+ timeFunc: ntp.TimeFuncFromContext(ctx),
+ }
+ shared.refs.Store(1)
+ sessionRef, err := newAppleTransportSession(shared)
+ if err != nil {
+ bridge.Close()
+ return nil, err
+ }
+ session := (*C.box_apple_http_session_t)(sessionRef)
+ releaseConfig = false
+ return &appleTransport{
+ shared: shared,
+ session: session,
+ }, nil
+}
+
+func newAppleSessionConfig(ctx context.Context, options option.HTTPClientOptions) (appleSessionConfig, error) {
+ version := options.Version
+ if version == 0 {
+ version = 2
+ }
+ switch version {
+ case 2:
+ case 1:
+ return appleSessionConfig{}, E.New("HTTP/1.1 is unsupported in Apple HTTP engine")
+ case 3:
+ return appleSessionConfig{}, E.New("HTTP/3 is unsupported in Apple HTTP engine")
+ default:
+ return appleSessionConfig{}, E.New("unknown HTTP version: ", version)
+ }
+ if options.DisableVersionFallback {
+ return appleSessionConfig{}, E.New("disable_version_fallback is unsupported in Apple HTTP engine")
+ }
+ if options.HTTP2Options != (option.HTTP2Options{}) {
+ return appleSessionConfig{}, E.New("HTTP/2 options are unsupported in Apple HTTP engine")
+ }
+ if options.HTTP3Options != (option.QUICOptions{}) {
+ return appleSessionConfig{}, E.New("QUIC options are unsupported in Apple HTTP engine")
+ }
+
+ tlsOptions := common.PtrValueOrDefault(options.TLS)
+ if tlsOptions.Engine != "" {
+ return appleSessionConfig{}, E.New("tls.engine is unsupported in Apple HTTP engine")
+ }
+ if len(tlsOptions.ALPN) > 0 {
+ return appleSessionConfig{}, E.New("tls.alpn is unsupported in Apple HTTP engine")
+ }
+ validated, err := boxTLS.ValidateSystemTLSOptions(ctx, tlsOptions, "Apple HTTP engine")
+ if err != nil {
+ return appleSessionConfig{}, err
+ }
+
+ config := appleSessionConfig{
+ serverName: tlsOptions.ServerName,
+ minVersion: validated.MinVersion,
+ maxVersion: validated.MaxVersion,
+ insecure: tlsOptions.Insecure || len(tlsOptions.CertificatePublicKeySHA256) > 0,
+ anchorOnly: validated.Exclusive,
+ store: validated.Store,
+ }
+ if len(validated.UserPEM) > 0 {
+ userAnchors, anchorsErr := newAppleUserAnchors(validated.UserPEM)
+ if anchorsErr != nil {
+ return appleSessionConfig{}, anchorsErr
+ }
+ config.userAnchors = userAnchors
+ }
+ if len(tlsOptions.CertificatePublicKeySHA256) > 0 {
+ config.pinnedPublicKeySHA256s = make([]byte, 0, len(tlsOptions.CertificatePublicKeySHA256)*applePinnedHashSize)
+ for _, hashValue := range tlsOptions.CertificatePublicKeySHA256 {
+ if len(hashValue) != applePinnedHashSize {
+ if config.userAnchors != nil {
+ config.userAnchors.Release()
+ }
+ return appleSessionConfig{}, E.New("invalid certificate_public_key_sha256 length: ", len(hashValue))
+ }
+ config.pinnedPublicKeySHA256s = append(config.pinnedPublicKeySHA256s, hashValue...)
+ }
+ }
+ return config, nil
+}
+
+func (c *appleSessionConfig) close() {
+ if c.userAnchors != nil {
+ c.userAnchors.Release()
+ c.userAnchors = nil
+ }
+}
+
+func (s *appleTransportShared) retain() {
+ s.refs.Add(1)
+}
+
+func (s *appleTransportShared) release() error {
+ if s.refs.Add(-1) == 0 {
+ s.config.close()
+ return s.bridge.Close()
+ }
+ return nil
+}
+
+func (s *appleTransportShared) newSession() (*C.box_apple_http_session_t, error) {
+ cProxyHost := C.CString("127.0.0.1")
+ defer C.free(unsafe.Pointer(cProxyHost))
+ cProxyUsername := C.CString(s.bridge.Username())
+ defer C.free(unsafe.Pointer(cProxyUsername))
+ cProxyPassword := C.CString(s.bridge.Password())
+ defer C.free(unsafe.Pointer(cProxyPassword))
+ var pinnedPointer *C.uint8_t
+ if len(s.config.pinnedPublicKeySHA256s) > 0 {
+ pinnedPointer = (*C.uint8_t)(C.CBytes(s.config.pinnedPublicKeySHA256s))
+ defer C.free(unsafe.Pointer(pinnedPointer))
+ }
+ anchors := certificate.AcquireAnchors(s.config.userAnchors, s.config.store)
+ var anchorsRef unsafe.Pointer
+ if anchors != nil {
+ anchorsRef = anchors.Ref()
+ defer anchors.Release()
+ }
+ cConfig := C.box_apple_http_session_config_t{
+ proxy_host: cProxyHost,
+ proxy_port: C.int(s.bridge.Port()),
+ proxy_username: cProxyUsername,
+ proxy_password: cProxyPassword,
+ min_tls_version: C.uint16_t(s.config.minVersion),
+ max_tls_version: C.uint16_t(s.config.maxVersion),
+ insecure: C.bool(s.config.insecure),
+ anchors_cf: anchorsRef,
+ anchor_only: C.bool(s.config.anchorOnly),
+ pinned_public_key_sha256: pinnedPointer,
+ pinned_public_key_sha256_len: C.size_t(len(s.config.pinnedPublicKeySHA256s)),
+ }
+ var cErr *C.char
+ session := C.box_apple_http_session_create(&cConfig, &cErr)
+ if session != nil {
+ return session, nil
+ }
+ return nil, appleCStringError(cErr, "create Apple HTTP session")
+}
+
+func (t *appleTransport) RoundTrip(request *http.Request) (*http.Response, error) {
+ if requestRequiresHTTP1(request) {
+ return nil, E.New("HTTP upgrade requests are unsupported in Apple HTTP engine")
+ }
+ if request.URL == nil {
+ return nil, E.New("missing request URL")
+ }
+ switch request.URL.Scheme {
+ case "http", "https":
+ default:
+ return nil, E.New("unsupported URL scheme: ", request.URL.Scheme)
+ }
+ if request.URL.Scheme == "https" && t.shared.config.serverName != "" && !strings.EqualFold(t.shared.config.serverName, request.URL.Hostname()) {
+ return nil, E.New("tls.server_name is unsupported in Apple HTTP engine unless it matches request host")
+ }
+ var body []byte
+ if request.Body != nil && request.Body != http.NoBody {
+ defer request.Body.Close()
+ var err error
+ body, err = io.ReadAll(request.Body)
+ if err != nil {
+ return nil, err
+ }
+ }
+ headerKeys, headerValues := flattenRequestHeaders(request)
+ cMethod := C.CString(request.Method)
+ defer C.free(unsafe.Pointer(cMethod))
+ cURL := C.CString(request.URL.String())
+ defer C.free(unsafe.Pointer(cURL))
+ cHeaderKeys := make([]*C.char, len(headerKeys))
+ cHeaderValues := make([]*C.char, len(headerValues))
+ defer func() {
+ for _, ptr := range cHeaderKeys {
+ C.free(unsafe.Pointer(ptr))
+ }
+ for _, ptr := range cHeaderValues {
+ C.free(unsafe.Pointer(ptr))
+ }
+ }()
+ for index, value := range headerKeys {
+ cHeaderKeys[index] = C.CString(value)
+ }
+ for index, value := range headerValues {
+ cHeaderValues[index] = C.CString(value)
+ }
+ var headerKeysPointer **C.char
+ var headerValuesPointer **C.char
+ if len(cHeaderKeys) > 0 {
+ pointerArraySize := C.size_t(len(cHeaderKeys)) * C.size_t(unsafe.Sizeof((*C.char)(nil)))
+ headerKeysPointer = (**C.char)(C.malloc(pointerArraySize))
+ defer C.free(unsafe.Pointer(headerKeysPointer))
+ headerValuesPointer = (**C.char)(C.malloc(pointerArraySize))
+ defer C.free(unsafe.Pointer(headerValuesPointer))
+ copy(unsafe.Slice(headerKeysPointer, len(cHeaderKeys)), cHeaderKeys)
+ copy(unsafe.Slice(headerValuesPointer, len(cHeaderValues)), cHeaderValues)
+ }
+ var bodyPointer *C.uint8_t
+ if len(body) > 0 {
+ bodyPointer = (*C.uint8_t)(C.CBytes(body))
+ defer C.free(unsafe.Pointer(bodyPointer))
+ }
+ var (
+ hasVerifyTime bool
+ verifyTimeUnixMilli int64
+ )
+ if t.shared.timeFunc != nil {
+ hasVerifyTime = true
+ verifyTimeUnixMilli = t.shared.timeFunc().UnixMilli()
+ }
+ cRequest := C.box_apple_http_request_t{
+ method: cMethod,
+ url: cURL,
+ header_keys: (**C.char)(headerKeysPointer),
+ header_values: (**C.char)(headerValuesPointer),
+ header_count: C.size_t(len(cHeaderKeys)),
+ body: bodyPointer,
+ body_len: C.size_t(len(body)),
+ has_verify_time: C.bool(hasVerifyTime),
+ verify_time_unix_millis: C.int64_t(verifyTimeUnixMilli),
+ }
+ var cErr *C.char
+ var task *C.box_apple_http_task_t
+ t.access.Lock()
+ if t.session == nil {
+ t.access.Unlock()
+ return nil, net.ErrClosed
+ }
+ // Keep the session attached until NSURLSession has created the task.
+ task = C.box_apple_http_session_send_async(t.session, &cRequest, &cErr)
+ t.access.Unlock()
+ if task == nil {
+ return nil, appleCStringError(cErr, "create Apple HTTP request")
+ }
+ cancelDone := make(chan struct{})
+ cancelExit := make(chan struct{})
+ go func() {
+ defer close(cancelExit)
+ select {
+ case <-request.Context().Done():
+ C.box_apple_http_task_cancel(task)
+ case <-cancelDone:
+ }
+ }()
+ cResponse := C.box_apple_http_task_wait(task, &cErr)
+ close(cancelDone)
+ <-cancelExit
+ C.box_apple_http_task_close(task)
+ if cResponse == nil {
+ err := appleCStringError(cErr, "Apple HTTP request failed")
+ if request.Context().Err() != nil {
+ return nil, request.Context().Err()
+ }
+ return nil, err
+ }
+ defer C.box_apple_http_response_free(cResponse)
+ return parseAppleHTTPResponse(request, cResponse), nil
+}
+
+func (t *appleTransport) CloseIdleConnections() {
+ t.access.Lock()
+ if t.closed {
+ t.access.Unlock()
+ return
+ }
+ t.access.Unlock()
+ newSession, err := t.shared.newSession()
+ if err != nil {
+ t.shared.logger.Error(E.Cause(err, "reset Apple HTTP session"))
+ return
+ }
+ t.access.Lock()
+ if t.closed {
+ t.access.Unlock()
+ C.box_apple_http_session_close(newSession)
+ return
+ }
+ oldSession := t.session
+ t.session = newSession
+ t.access.Unlock()
+ C.box_apple_http_session_retire(oldSession)
+}
+
+func (t *appleTransport) Close() error {
+ t.access.Lock()
+ if t.closed {
+ t.access.Unlock()
+ return nil
+ }
+ t.closed = true
+ session := t.session
+ t.session = nil
+ t.access.Unlock()
+ C.box_apple_http_session_close(session)
+ return t.shared.release()
+}
+
+func flattenRequestHeaders(request *http.Request) ([]string, []string) {
+ var (
+ keys []string
+ values []string
+ )
+ for key, headerValues := range request.Header {
+ for _, value := range headerValues {
+ keys = append(keys, key)
+ values = append(values, value)
+ }
+ }
+ if request.Host != "" {
+ keys = append(keys, "Host")
+ values = append(values, request.Host)
+ }
+ return keys, values
+}
+
+func parseAppleHTTPResponse(request *http.Request, response *C.box_apple_http_response_t) *http.Response {
+ headers := make(http.Header)
+ headerKeys := unsafe.Slice(response.header_keys, int(response.header_count))
+ headerValues := unsafe.Slice(response.header_values, int(response.header_count))
+ for index := range headerKeys {
+ headers.Add(C.GoString(headerKeys[index]), C.GoString(headerValues[index]))
+ }
+ body := bytes.NewReader(C.GoBytes(unsafe.Pointer(response.body), C.int(response.body_len)))
+ // NSURLSession's completion-handler API does not expose the negotiated protocol;
+ // callers that read Response.Proto will see HTTP/1.1 even when the wire was HTTP/2.
+ return &http.Response{
+ StatusCode: int(response.status_code),
+ Status: fmt.Sprintf("%d %s", int(response.status_code), http.StatusText(int(response.status_code))),
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: headers,
+ Body: io.NopCloser(body),
+ ContentLength: int64(body.Len()),
+ Request: request,
+ }
+}
+
+func appleCStringError(cErr *C.char, message string) error {
+ if cErr == nil {
+ return E.New(message)
+ }
+ defer C.free(unsafe.Pointer(cErr))
+ return E.New(message, ": ", C.GoString(cErr))
+}
diff --git a/common/httpclient/apple_transport_darwin.h b/common/httpclient/apple_transport_darwin.h
new file mode 100644
index 0000000000..4774a6b4de
--- /dev/null
+++ b/common/httpclient/apple_transport_darwin.h
@@ -0,0 +1,70 @@
+#include
+#include
+#include
+
+typedef struct box_apple_http_session box_apple_http_session_t;
+typedef struct box_apple_http_task box_apple_http_task_t;
+
+typedef struct box_apple_http_session_config {
+ const char *proxy_host;
+ int proxy_port;
+ const char *proxy_username;
+ const char *proxy_password;
+ uint16_t min_tls_version;
+ uint16_t max_tls_version;
+ bool insecure;
+ void *anchors_cf;
+ bool anchor_only;
+ const uint8_t *pinned_public_key_sha256;
+ size_t pinned_public_key_sha256_len;
+} box_apple_http_session_config_t;
+
+typedef struct box_apple_http_request {
+ const char *method;
+ const char *url;
+ const char **header_keys;
+ const char **header_values;
+ size_t header_count;
+ const uint8_t *body;
+ size_t body_len;
+ bool has_verify_time;
+ int64_t verify_time_unix_millis;
+} box_apple_http_request_t;
+
+typedef struct box_apple_http_response {
+ int status_code;
+ char **header_keys;
+ char **header_values;
+ size_t header_count;
+ uint8_t *body;
+ size_t body_len;
+ char *error;
+} box_apple_http_response_t;
+
+box_apple_http_session_t *box_apple_http_session_create(
+ const box_apple_http_session_config_t *config,
+ char **error_out
+);
+void box_apple_http_session_retire(box_apple_http_session_t *session);
+void box_apple_http_session_close(box_apple_http_session_t *session);
+
+box_apple_http_task_t *box_apple_http_session_send_async(
+ box_apple_http_session_t *session,
+ const box_apple_http_request_t *request,
+ char **error_out
+);
+box_apple_http_response_t *box_apple_http_task_wait(
+ box_apple_http_task_t *task,
+ char **error_out
+);
+void box_apple_http_task_cancel(box_apple_http_task_t *task);
+void box_apple_http_task_close(box_apple_http_task_t *task);
+
+void box_apple_http_response_free(box_apple_http_response_t *response);
+
+char *box_apple_http_verify_public_key_sha256(
+ uint8_t *known_hash_values,
+ size_t known_hash_values_len,
+ uint8_t *leaf_cert,
+ size_t leaf_cert_len
+);
diff --git a/common/httpclient/apple_transport_darwin.m b/common/httpclient/apple_transport_darwin.m
new file mode 100644
index 0000000000..1e72a3e0ab
--- /dev/null
+++ b/common/httpclient/apple_transport_darwin.m
@@ -0,0 +1,364 @@
+#import "apple_transport_darwin.h"
+
+#import
+#import
+#import
+#import
+#import
+#import
+
+typedef struct box_apple_http_session {
+ void *handle;
+} box_apple_http_session_t;
+
+typedef struct box_apple_http_task {
+ void *task;
+ void *done_semaphore;
+ box_apple_http_response_t *response;
+ char *error;
+} box_apple_http_task_t;
+
+static NSString *const box_apple_http_verify_time_key = @"sing-box.verify-time";
+
+static void box_set_error_string(char **error_out, NSString *message) {
+ if (error_out == NULL || *error_out != NULL) {
+ return;
+ }
+ const char *utf8 = [message UTF8String];
+ *error_out = strdup(utf8 != NULL ? utf8 : "unknown error");
+}
+
+static void box_set_error_from_nserror(char **error_out, NSError *error) {
+ if (error == nil) {
+ box_set_error_string(error_out, @"unknown error");
+ return;
+ }
+ box_set_error_string(error_out, error.localizedDescription ?: error.description);
+}
+
+static bool box_evaluate_trust(SecTrustRef trustRef, NSArray *anchors, bool anchor_only, NSDate *verifyDate) {
+ if (trustRef == NULL) {
+ return false;
+ }
+ if (verifyDate != nil && SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)verifyDate) != errSecSuccess) {
+ return false;
+ }
+ if (anchors.count > 0 || anchor_only) {
+ CFMutableArrayRef anchorArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ for (id certificate in anchors) {
+ CFArrayAppendValue(anchorArray, (__bridge const void *)certificate);
+ }
+ SecTrustSetAnchorCertificates(trustRef, anchorArray);
+ SecTrustSetAnchorCertificatesOnly(trustRef, anchor_only);
+ CFRelease(anchorArray);
+ }
+ CFErrorRef error = NULL;
+ bool result = SecTrustEvaluateWithError(trustRef, &error);
+ if (error != NULL) {
+ CFRelease(error);
+ }
+ return result;
+}
+
+static NSDate *box_apple_http_verify_date_for_request(NSURLRequest *request) {
+ if (request == nil) {
+ return nil;
+ }
+ id value = [NSURLProtocol propertyForKey:box_apple_http_verify_time_key inRequest:request];
+ if (![value isKindOfClass:[NSNumber class]]) {
+ return nil;
+ }
+ return [NSDate dateWithTimeIntervalSince1970:[(NSNumber *)value longLongValue] / 1000.0];
+}
+
+static box_apple_http_response_t *box_create_response(NSHTTPURLResponse *httpResponse, NSData *data) {
+ box_apple_http_response_t *response = calloc(1, sizeof(box_apple_http_response_t));
+ response->status_code = (int)httpResponse.statusCode;
+ NSDictionary *headers = httpResponse.allHeaderFields;
+ response->header_count = headers.count;
+ if (response->header_count > 0) {
+ response->header_keys = calloc(response->header_count, sizeof(char *));
+ response->header_values = calloc(response->header_count, sizeof(char *));
+ NSUInteger index = 0;
+ for (id key in headers) {
+ NSString *keyString = [[key description] copy];
+ NSString *valueString = [[headers[key] description] copy];
+ response->header_keys[index] = strdup(keyString.UTF8String ?: "");
+ response->header_values[index] = strdup(valueString.UTF8String ?: "");
+ index++;
+ }
+ }
+ if (data.length > 0) {
+ response->body_len = data.length;
+ response->body = malloc(data.length);
+ memcpy(response->body, data.bytes, data.length);
+ }
+ return response;
+}
+
+@interface BoxAppleHTTPSessionDelegate : NSObject
+@property(nonatomic, assign) BOOL insecure;
+@property(nonatomic, assign) BOOL anchorOnly;
+@property(nonatomic, strong) NSArray *anchors;
+@property(nonatomic, strong) NSData *pinnedPublicKeyHashes;
+@end
+
+@implementation BoxAppleHTTPSessionDelegate
+
+- (void)URLSession:(NSURLSession *)session
+ task:(NSURLSessionTask *)task
+willPerformHTTPRedirection:(NSHTTPURLResponse *)response
+ newRequest:(NSURLRequest *)request
+ completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
+ completionHandler(nil);
+}
+
+- (void)URLSession:(NSURLSession *)session
+ task:(NSURLSessionTask *)task
+didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+ completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
+ if (![challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
+ completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
+ return;
+ }
+ SecTrustRef trustRef = challenge.protectionSpace.serverTrust;
+ if (trustRef == NULL) {
+ completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
+ return;
+ }
+ NSDate *verifyDate = box_apple_http_verify_date_for_request(task.currentRequest ?: task.originalRequest);
+ BOOL needsCustomHandling = self.insecure || self.anchorOnly || self.anchors.count > 0 || self.pinnedPublicKeyHashes.length > 0 || verifyDate != nil;
+ if (!needsCustomHandling) {
+ completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
+ return;
+ }
+ BOOL ok = YES;
+ if (!self.insecure) {
+ ok = box_evaluate_trust(trustRef, self.anchors, self.anchorOnly, verifyDate);
+ }
+ if (ok && self.pinnedPublicKeyHashes.length > 0) {
+ CFArrayRef certificateChain = SecTrustCopyCertificateChain(trustRef);
+ SecCertificateRef leafCertificate = NULL;
+ if (certificateChain != NULL && CFArrayGetCount(certificateChain) > 0) {
+ leafCertificate = (SecCertificateRef)CFArrayGetValueAtIndex(certificateChain, 0);
+ }
+ if (leafCertificate == NULL) {
+ ok = NO;
+ } else {
+ NSData *leafData = CFBridgingRelease(SecCertificateCopyData(leafCertificate));
+ char *pinError = box_apple_http_verify_public_key_sha256(
+ (uint8_t *)self.pinnedPublicKeyHashes.bytes,
+ self.pinnedPublicKeyHashes.length,
+ (uint8_t *)leafData.bytes,
+ leafData.length
+ );
+ if (pinError != NULL) {
+ free(pinError);
+ ok = NO;
+ }
+ }
+ if (certificateChain != NULL) {
+ CFRelease(certificateChain);
+ }
+ }
+ if (!ok) {
+ completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
+ return;
+ }
+ completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:trustRef]);
+}
+
+@end
+
+@interface BoxAppleHTTPSessionHandle : NSObject
+@property(nonatomic, strong) NSURLSession *session;
+@property(nonatomic, strong) BoxAppleHTTPSessionDelegate *delegate;
+@end
+
+@implementation BoxAppleHTTPSessionHandle
+@end
+
+box_apple_http_session_t *box_apple_http_session_create(
+ const box_apple_http_session_config_t *config,
+ char **error_out
+) {
+ @autoreleasepool {
+ NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
+ sessionConfig.URLCache = nil;
+ sessionConfig.HTTPCookieStorage = nil;
+ sessionConfig.URLCredentialStorage = nil;
+ sessionConfig.HTTPShouldSetCookies = NO;
+ if (config != NULL && config->proxy_host != NULL && config->proxy_port > 0) {
+ NSMutableDictionary *proxyDictionary = [NSMutableDictionary dictionary];
+ proxyDictionary[(__bridge NSString *)kCFStreamPropertySOCKSProxyHost] = [NSString stringWithUTF8String:config->proxy_host];
+ proxyDictionary[(__bridge NSString *)kCFStreamPropertySOCKSProxyPort] = @(config->proxy_port);
+ proxyDictionary[(__bridge NSString *)kCFStreamPropertySOCKSVersion] = (__bridge NSString *)kCFStreamSocketSOCKSVersion5;
+ if (config->proxy_username != NULL) {
+ proxyDictionary[(__bridge NSString *)kCFStreamPropertySOCKSUser] = [NSString stringWithUTF8String:config->proxy_username];
+ }
+ if (config->proxy_password != NULL) {
+ proxyDictionary[(__bridge NSString *)kCFStreamPropertySOCKSPassword] = [NSString stringWithUTF8String:config->proxy_password];
+ }
+ sessionConfig.connectionProxyDictionary = proxyDictionary;
+ }
+ if (config != NULL && config->min_tls_version != 0) {
+ sessionConfig.TLSMinimumSupportedProtocolVersion = (tls_protocol_version_t)config->min_tls_version;
+ }
+ if (config != NULL && config->max_tls_version != 0) {
+ sessionConfig.TLSMaximumSupportedProtocolVersion = (tls_protocol_version_t)config->max_tls_version;
+ }
+ BoxAppleHTTPSessionDelegate *delegate = [[BoxAppleHTTPSessionDelegate alloc] init];
+ if (config != NULL) {
+ delegate.insecure = config->insecure;
+ delegate.anchorOnly = config->anchor_only;
+ if (config->anchors_cf != NULL) {
+ delegate.anchors = (__bridge NSArray *)config->anchors_cf;
+ } else {
+ delegate.anchors = @[];
+ }
+ if (config->pinned_public_key_sha256 != NULL && config->pinned_public_key_sha256_len > 0) {
+ delegate.pinnedPublicKeyHashes = [NSData dataWithBytes:config->pinned_public_key_sha256 length:config->pinned_public_key_sha256_len];
+ }
+ }
+ NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:delegate delegateQueue:nil];
+ if (session == nil) {
+ box_set_error_string(error_out, @"create URLSession");
+ return NULL;
+ }
+ BoxAppleHTTPSessionHandle *handle = [[BoxAppleHTTPSessionHandle alloc] init];
+ handle.session = session;
+ handle.delegate = delegate;
+ box_apple_http_session_t *sessionHandle = calloc(1, sizeof(box_apple_http_session_t));
+ sessionHandle->handle = (__bridge_retained void *)handle;
+ return sessionHandle;
+ }
+}
+
+void box_apple_http_session_retire(box_apple_http_session_t *session) {
+ if (session == NULL || session->handle == NULL) {
+ return;
+ }
+ BoxAppleHTTPSessionHandle *handle = (__bridge_transfer BoxAppleHTTPSessionHandle *)session->handle;
+ [handle.session finishTasksAndInvalidate];
+ free(session);
+}
+
+void box_apple_http_session_close(box_apple_http_session_t *session) {
+ if (session == NULL || session->handle == NULL) {
+ return;
+ }
+ BoxAppleHTTPSessionHandle *handle = (__bridge_transfer BoxAppleHTTPSessionHandle *)session->handle;
+ [handle.session invalidateAndCancel];
+ free(session);
+}
+
+box_apple_http_task_t *box_apple_http_session_send_async(
+ box_apple_http_session_t *session,
+ const box_apple_http_request_t *request,
+ char **error_out
+) {
+ @autoreleasepool {
+ if (session == NULL || session->handle == NULL || request == NULL || request->method == NULL || request->url == NULL) {
+ box_set_error_string(error_out, @"invalid apple HTTP request");
+ return NULL;
+ }
+ BoxAppleHTTPSessionHandle *handle = (__bridge BoxAppleHTTPSessionHandle *)session->handle;
+ NSURL *requestURL = [NSURL URLWithString:[NSString stringWithUTF8String:request->url]];
+ if (requestURL == nil) {
+ box_set_error_string(error_out, @"invalid request URL");
+ return NULL;
+ }
+ NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:requestURL];
+ urlRequest.HTTPMethod = [NSString stringWithUTF8String:request->method];
+ for (size_t index = 0; index < request->header_count; index++) {
+ const char *key = request->header_keys[index];
+ const char *value = request->header_values[index];
+ if (key == NULL || value == NULL) {
+ continue;
+ }
+ [urlRequest addValue:[NSString stringWithUTF8String:value] forHTTPHeaderField:[NSString stringWithUTF8String:key]];
+ }
+ if (request->body != NULL && request->body_len > 0) {
+ urlRequest.HTTPBody = [NSData dataWithBytes:request->body length:request->body_len];
+ }
+ if (request->has_verify_time) {
+ [NSURLProtocol setProperty:@(request->verify_time_unix_millis) forKey:box_apple_http_verify_time_key inRequest:urlRequest];
+ }
+ box_apple_http_task_t *task = calloc(1, sizeof(box_apple_http_task_t));
+ dispatch_semaphore_t doneSemaphore = dispatch_semaphore_create(0);
+ task->done_semaphore = (__bridge_retained void *)doneSemaphore;
+ NSURLSessionDataTask *dataTask = [handle.session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
+ if (error != nil) {
+ box_set_error_from_nserror(&task->error, error);
+ } else if (![response isKindOfClass:[NSHTTPURLResponse class]]) {
+ box_set_error_string(&task->error, @"unexpected HTTP response type");
+ } else {
+ task->response = box_create_response((NSHTTPURLResponse *)response, data ?: [NSData data]);
+ }
+ dispatch_semaphore_signal((__bridge dispatch_semaphore_t)task->done_semaphore);
+ }];
+ if (dataTask == nil) {
+ box_set_error_string(error_out, @"create data task");
+ box_apple_http_task_close(task);
+ return NULL;
+ }
+ task->task = (__bridge_retained void *)dataTask;
+ [dataTask resume];
+ return task;
+ }
+}
+
+box_apple_http_response_t *box_apple_http_task_wait(
+ box_apple_http_task_t *task,
+ char **error_out
+) {
+ if (task == NULL || task->done_semaphore == NULL) {
+ box_set_error_string(error_out, @"invalid apple HTTP task");
+ return NULL;
+ }
+ dispatch_semaphore_wait((__bridge dispatch_semaphore_t)task->done_semaphore, DISPATCH_TIME_FOREVER);
+ if (task->error != NULL) {
+ box_set_error_string(error_out, [NSString stringWithUTF8String:task->error]);
+ return NULL;
+ }
+ return task->response;
+}
+
+void box_apple_http_task_cancel(box_apple_http_task_t *task) {
+ if (task == NULL || task->task == NULL) {
+ return;
+ }
+ NSURLSessionTask *nsTask = (__bridge NSURLSessionTask *)task->task;
+ [nsTask cancel];
+}
+
+void box_apple_http_task_close(box_apple_http_task_t *task) {
+ if (task == NULL) {
+ return;
+ }
+ if (task->task != NULL) {
+ __unused NSURLSessionTask *nsTask = (__bridge_transfer NSURLSessionTask *)task->task;
+ task->task = NULL;
+ }
+ if (task->done_semaphore != NULL) {
+ __unused dispatch_semaphore_t doneSemaphore = (__bridge_transfer dispatch_semaphore_t)task->done_semaphore;
+ task->done_semaphore = NULL;
+ }
+ free(task->error);
+ free(task);
+}
+
+void box_apple_http_response_free(box_apple_http_response_t *response) {
+ if (response == NULL) {
+ return;
+ }
+ for (size_t index = 0; index < response->header_count; index++) {
+ free(response->header_keys[index]);
+ free(response->header_values[index]);
+ }
+ free(response->header_keys);
+ free(response->header_values);
+ free(response->body);
+ free(response->error);
+ free(response);
+}
diff --git a/common/httpclient/apple_transport_darwin_test.go b/common/httpclient/apple_transport_darwin_test.go
new file mode 100644
index 0000000000..3055c25f25
--- /dev/null
+++ b/common/httpclient/apple_transport_darwin_test.go
@@ -0,0 +1,952 @@
+//go:build darwin && cgo
+
+package httpclient
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ stdtls "crypto/tls"
+ "crypto/x509"
+ "errors"
+ "io"
+ "net"
+ "net/http"
+ "net/http/httptest"
+ "net/url"
+ "slices"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+ "unsafe"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/proxybridge"
+ boxTLS "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/route"
+ "github.com/sagernet/sing/common/json/badoption"
+ commonLogger "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+const appleHTTPTestTimeout = 5 * time.Second
+
+const appleHTTPRecoveryLoops = 5
+
+type appleHTTPTestDialer struct {
+ dialer net.Dialer
+ listener net.ListenConfig
+ hostMap map[string]string
+}
+
+type appleHTTPObservedRequest struct {
+ method string
+ body string
+ host string
+ values []string
+ protoMajor int
+}
+
+type appleHTTPTestServer struct {
+ server *httptest.Server
+ baseURL string
+ dialHost string
+ certificate stdtls.Certificate
+ certificatePEM string
+ publicKeyHash []byte
+}
+
+type appleTestAnchors struct {
+ ref unsafe.Pointer
+ releases int
+}
+
+func (a *appleTestAnchors) Retain() adapter.AppleAnchors {
+ return a
+}
+
+func (a *appleTestAnchors) Release() {
+ a.releases++
+}
+
+func (a *appleTestAnchors) Ref() unsafe.Pointer {
+ return a.ref
+}
+
+func TestNewAppleSessionConfig(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleHTTPTestCertificate(t, "localhost")
+ serverHash := certificatePublicKeySHA256(t, serverCertificate.Certificate[0])
+ otherHash := bytes.Repeat([]byte{0x7f}, applePinnedHashSize)
+
+ testCases := []struct {
+ name string
+ options option.HTTPClientOptions
+ check func(t *testing.T, config appleSessionConfig)
+ wantErr string
+ }{
+ {
+ name: "success with certificate anchors",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ DialerOptions: option.DialerOptions{
+ ConnectTimeout: badoption.Duration(2 * time.Second),
+ },
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.3",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ },
+ },
+ check: func(t *testing.T, config appleSessionConfig) {
+ t.Helper()
+ if config.serverName != "localhost" {
+ t.Fatalf("unexpected server name: %q", config.serverName)
+ }
+ if config.minVersion != stdtls.VersionTLS12 {
+ t.Fatalf("unexpected min version: %x", config.minVersion)
+ }
+ if config.maxVersion != stdtls.VersionTLS13 {
+ t.Fatalf("unexpected max version: %x", config.maxVersion)
+ }
+ if config.insecure {
+ t.Fatal("unexpected insecure flag")
+ }
+ if !config.anchorOnly {
+ t.Fatal("expected anchor_only")
+ }
+ if config.userAnchors == nil {
+ t.Fatal("expected user anchors")
+ }
+ if config.userAnchors.Ref() == nil {
+ t.Fatal("expected non-empty user anchors")
+ }
+ if config.store != nil {
+ t.Fatal("unexpected store reference")
+ }
+ if len(config.pinnedPublicKeySHA256s) != 0 {
+ t.Fatalf("unexpected pinned hashes: %d", len(config.pinnedPublicKeySHA256s))
+ }
+ },
+ },
+ {
+ name: "success with flattened pins",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ Insecure: true,
+ CertificatePublicKeySHA256: badoption.Listable[[]byte]{serverHash, otherHash},
+ },
+ },
+ },
+ check: func(t *testing.T, config appleSessionConfig) {
+ t.Helper()
+ if !config.insecure {
+ t.Fatal("expected insecure flag")
+ }
+ if len(config.pinnedPublicKeySHA256s) != 2*applePinnedHashSize {
+ t.Fatalf("unexpected flattened pin length: %d", len(config.pinnedPublicKeySHA256s))
+ }
+ if !bytes.Equal(config.pinnedPublicKeySHA256s[:applePinnedHashSize], serverHash) {
+ t.Fatal("unexpected first pin")
+ }
+ if !bytes.Equal(config.pinnedPublicKeySHA256s[applePinnedHashSize:], otherHash) {
+ t.Fatal("unexpected second pin")
+ }
+ if config.userAnchors != nil {
+ t.Fatal("unexpected user anchors")
+ }
+ if config.anchorOnly {
+ t.Fatal("unexpected anchor_only")
+ }
+ },
+ },
+ {
+ name: "http11 unsupported",
+ options: option.HTTPClientOptions{Version: 1},
+ wantErr: "HTTP/1.1 is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "http3 unsupported",
+ options: option.HTTPClientOptions{Version: 3},
+ wantErr: "HTTP/3 is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "unknown version",
+ options: option.HTTPClientOptions{Version: 9},
+ wantErr: "unknown HTTP version: 9",
+ },
+ {
+ name: "disable version fallback unsupported",
+ options: option.HTTPClientOptions{
+ DisableVersionFallback: true,
+ },
+ wantErr: "disable_version_fallback is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "http2 options unsupported",
+ options: option.HTTPClientOptions{
+ HTTP2Options: option.HTTP2Options{
+ IdleTimeout: badoption.Duration(time.Second),
+ },
+ },
+ wantErr: "HTTP/2 options are unsupported in Apple HTTP engine",
+ },
+ {
+ name: "quic options unsupported",
+ options: option.HTTPClientOptions{
+ HTTP3Options: option.QUICOptions{
+ InitialPacketSize: 1200,
+ },
+ },
+ wantErr: "QUIC options are unsupported in Apple HTTP engine",
+ },
+ {
+ name: "tls engine unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{Engine: "go"},
+ },
+ },
+ wantErr: "tls.engine is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "disable sni unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{DisableSNI: true},
+ },
+ },
+ wantErr: "disable_sni is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "alpn unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ ALPN: badoption.Listable[string]{"h2"},
+ },
+ },
+ },
+ wantErr: "tls.alpn is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "cipher suites unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ CipherSuites: badoption.Listable[string]{"TLS_AES_128_GCM_SHA256"},
+ },
+ },
+ },
+ wantErr: "cipher_suites is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "curve preferences unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ CurvePreferences: badoption.Listable[option.CurvePreference]{option.CurvePreference(option.X25519)},
+ },
+ },
+ },
+ wantErr: "curve_preferences is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "client certificate unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ ClientCertificate: badoption.Listable[string]{"client-certificate"},
+ ClientKey: badoption.Listable[string]{"client-key"},
+ },
+ },
+ },
+ wantErr: "client certificate is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "tls fragment unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{Fragment: true},
+ },
+ },
+ wantErr: "tls fragment is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "ktls unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{KernelTx: true},
+ },
+ },
+ wantErr: "ktls is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "ech unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ ECH: &option.OutboundECHOptions{Enabled: true},
+ },
+ },
+ },
+ wantErr: "ech is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "utls unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ UTLS: &option.OutboundUTLSOptions{Enabled: true},
+ },
+ },
+ },
+ wantErr: "utls is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "reality unsupported",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Reality: &option.OutboundRealityOptions{Enabled: true},
+ },
+ },
+ },
+ wantErr: "reality is unsupported in Apple HTTP engine",
+ },
+ {
+ name: "pin and certificate conflict",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ CertificatePublicKeySHA256: badoption.Listable[[]byte]{serverHash},
+ },
+ },
+ },
+ wantErr: "certificate_public_key_sha256 is conflict with certificate or certificate_path",
+ },
+ {
+ name: "invalid min version",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{MinVersion: "bogus"},
+ },
+ },
+ wantErr: "parse min_version",
+ },
+ {
+ name: "invalid max version",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{MaxVersion: "bogus"},
+ },
+ },
+ wantErr: "parse max_version",
+ },
+ {
+ name: "invalid pin length",
+ options: option.HTTPClientOptions{
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ CertificatePublicKeySHA256: badoption.Listable[[]byte]{{0x01, 0x02}},
+ },
+ },
+ },
+ wantErr: "invalid certificate_public_key_sha256 length: 2",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ config, err := newAppleSessionConfig(context.Background(), testCase.options)
+ if testCase.wantErr != "" {
+ if err == nil {
+ t.Fatal("expected error")
+ }
+ if !strings.Contains(err.Error(), testCase.wantErr) {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ return
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ if testCase.check != nil {
+ testCase.check(t, config)
+ }
+ })
+ }
+}
+
+func TestAppleTransportVerifyPublicKeySHA256(t *testing.T) {
+ serverCertificate, _ := newAppleHTTPTestCertificate(t, "localhost")
+ goodHash := certificatePublicKeySHA256(t, serverCertificate.Certificate[0])
+ badHash := append([]byte(nil), goodHash...)
+ badHash[0] ^= 0xff
+
+ err := verifyApplePinnedPublicKeySHA256(goodHash, serverCertificate.Certificate[0])
+ if err != nil {
+ t.Fatalf("expected correct pin to succeed: %v", err)
+ }
+
+ err = verifyApplePinnedPublicKeySHA256(badHash, serverCertificate.Certificate[0])
+ if err == nil {
+ t.Fatal("expected incorrect pin to fail")
+ }
+ if !strings.Contains(err.Error(), "unrecognized remote public key") {
+ t.Fatalf("unexpected pin mismatch error: %v", err)
+ }
+
+ err = verifyApplePinnedPublicKeySHA256(goodHash[:applePinnedHashSize-1], serverCertificate.Certificate[0])
+ if err == nil {
+ t.Fatal("expected malformed pin list to fail")
+ }
+ if !strings.Contains(err.Error(), "invalid pinned public key list") {
+ t.Fatalf("unexpected malformed pin error: %v", err)
+ }
+}
+
+func TestNewAppleTransportClosesSessionConfigOnBridgeFailure(t *testing.T) {
+ _, serverCertificatePEM := newAppleHTTPTestCertificate(t, "localhost")
+ restoreAppleTransportFactories(t)
+ testAnchors := &appleTestAnchors{ref: unsafe.Pointer(new(int))}
+ newAppleUserAnchors = func([]byte) (adapter.AppleAnchors, error) {
+ return testAnchors, nil
+ }
+ newAppleProxyBridge = func(context.Context, commonLogger.ContextLogger, string, N.Dialer) (*proxybridge.Bridge, error) {
+ return nil, errors.New("bridge boom")
+ }
+
+ _, err := newAppleTransport(newAppleHTTPTestContext(), log.NewNOPFactory().NewLogger("httpclient"), &appleHTTPTestDialer{}, appleTransportAnchorOptions(serverCertificatePEM))
+ if err == nil || !strings.Contains(err.Error(), "bridge boom") {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if testAnchors.releases != 1 {
+ t.Fatalf("expected 1 anchor release, got %d", testAnchors.releases)
+ }
+}
+
+func TestNewAppleTransportClosesSessionConfigOnSessionFailure(t *testing.T) {
+ _, serverCertificatePEM := newAppleHTTPTestCertificate(t, "localhost")
+ restoreAppleTransportFactories(t)
+ testAnchors := &appleTestAnchors{ref: unsafe.Pointer(new(int))}
+ newAppleUserAnchors = func([]byte) (adapter.AppleAnchors, error) {
+ return testAnchors, nil
+ }
+ newAppleTransportSession = func(*appleTransportShared) (unsafe.Pointer, error) {
+ return nil, errors.New("session boom")
+ }
+
+ _, err := newAppleTransport(newAppleHTTPTestContext(), log.NewNOPFactory().NewLogger("httpclient"), &appleHTTPTestDialer{}, appleTransportAnchorOptions(serverCertificatePEM))
+ if err == nil || !strings.Contains(err.Error(), "session boom") {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if testAnchors.releases != 1 {
+ t.Fatalf("expected 1 anchor release, got %d", testAnchors.releases)
+ }
+}
+
+func TestAppleTransportRoundTripHTTPS(t *testing.T) {
+ requests := make(chan appleHTTPObservedRequest, 1)
+ server := startAppleHTTPTestServer(t, func(w http.ResponseWriter, r *http.Request) {
+ body, err := io.ReadAll(r.Body)
+ if err != nil {
+ t.Error(err)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ requests <- appleHTTPObservedRequest{
+ method: r.Method,
+ body: string(body),
+ host: r.Host,
+ values: append([]string(nil), r.Header.Values("X-Test")...),
+ protoMajor: r.ProtoMajor,
+ }
+ w.Header().Set("X-Reply", "apple")
+ w.WriteHeader(http.StatusCreated)
+ _, _ = w.Write([]byte("response body"))
+ })
+
+ transport := newAppleHTTPTestTransport(t, server, option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: appleHTTPServerTLSOptions(server),
+ },
+ })
+
+ request, err := http.NewRequest(http.MethodPost, server.URL("/roundtrip"), bytes.NewReader([]byte("request body")))
+ if err != nil {
+ t.Fatal(err)
+ }
+ request.Header.Add("X-Test", "one")
+ request.Header.Add("X-Test", "two")
+ request.Host = "custom.example"
+
+ response, err := transport.RoundTrip(request)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer response.Body.Close()
+
+ responseBody := readResponseBody(t, response)
+ if response.StatusCode != http.StatusCreated {
+ t.Fatalf("unexpected status code: %d", response.StatusCode)
+ }
+ if response.Status != "201 Created" {
+ t.Fatalf("unexpected status: %q", response.Status)
+ }
+ if response.Header.Get("X-Reply") != "apple" {
+ t.Fatalf("unexpected response header: %q", response.Header.Get("X-Reply"))
+ }
+ if responseBody != "response body" {
+ t.Fatalf("unexpected response body: %q", responseBody)
+ }
+ if response.ContentLength != int64(len(responseBody)) {
+ t.Fatalf("unexpected content length: %d", response.ContentLength)
+ }
+
+ observed := waitObservedRequest(t, requests)
+ if observed.method != http.MethodPost {
+ t.Fatalf("unexpected method: %q", observed.method)
+ }
+ if observed.body != "request body" {
+ t.Fatalf("unexpected request body: %q", observed.body)
+ }
+ if observed.host != "custom.example" {
+ t.Fatalf("unexpected host: %q", observed.host)
+ }
+ if observed.protoMajor != 2 {
+ t.Fatalf("expected HTTP/2 request, got HTTP/%d", observed.protoMajor)
+ }
+ var normalizedValues []string
+ for _, value := range observed.values {
+ for part := range strings.SplitSeq(value, ",") {
+ normalizedValues = append(normalizedValues, strings.TrimSpace(part))
+ }
+ }
+ slices.Sort(normalizedValues)
+ if !slices.Equal(normalizedValues, []string{"one", "two"}) {
+ t.Fatalf("unexpected header values: %#v", observed.values)
+ }
+}
+
+func TestAppleTransportPinnedPublicKey(t *testing.T) {
+ server := startAppleHTTPTestServer(t, func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte("pinned"))
+ })
+
+ goodTransport := newAppleHTTPTestTransport(t, server, option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "localhost",
+ Insecure: true,
+ CertificatePublicKeySHA256: badoption.Listable[[]byte]{server.publicKeyHash},
+ },
+ },
+ })
+
+ response, err := goodTransport.RoundTrip(newAppleHTTPRequest(t, http.MethodGet, server.URL("/good"), nil))
+ if err != nil {
+ t.Fatalf("expected pinned request to succeed: %v", err)
+ }
+ response.Body.Close()
+
+ badHash := append([]byte(nil), server.publicKeyHash...)
+ badHash[0] ^= 0xff
+ badTransport := newAppleHTTPTestTransport(t, server, option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "localhost",
+ Insecure: true,
+ CertificatePublicKeySHA256: badoption.Listable[[]byte]{badHash},
+ },
+ },
+ })
+
+ response, err = badTransport.RoundTrip(newAppleHTTPRequest(t, http.MethodGet, server.URL("/bad"), nil))
+ if err == nil {
+ response.Body.Close()
+ t.Fatal("expected incorrect pinned public key to fail")
+ }
+}
+
+func TestAppleTransportGuardrails(t *testing.T) {
+ testCases := []struct {
+ name string
+ options option.HTTPClientOptions
+ buildRequest func(t *testing.T) *http.Request
+ wantErrSubstr string
+ }{
+ {
+ name: "websocket upgrade rejected",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ },
+ buildRequest: func(t *testing.T) *http.Request {
+ t.Helper()
+ request := newAppleHTTPRequest(t, http.MethodGet, "https://localhost/socket", nil)
+ request.Header.Set("Connection", "Upgrade")
+ request.Header.Set("Upgrade", "websocket")
+ return request
+ },
+ wantErrSubstr: "HTTP upgrade requests are unsupported in Apple HTTP engine",
+ },
+ {
+ name: "missing url rejected",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ },
+ buildRequest: func(t *testing.T) *http.Request {
+ t.Helper()
+ return &http.Request{Method: http.MethodGet}
+ },
+ wantErrSubstr: "missing request URL",
+ },
+ {
+ name: "unsupported scheme rejected",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ },
+ buildRequest: func(t *testing.T) *http.Request {
+ t.Helper()
+ return newAppleHTTPRequest(t, http.MethodGet, "ftp://localhost/file", nil)
+ },
+ wantErrSubstr: "unsupported URL scheme: ftp",
+ },
+ {
+ name: "server name mismatch rejected",
+ options: option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "example.com",
+ },
+ },
+ },
+ buildRequest: func(t *testing.T) *http.Request {
+ t.Helper()
+ return newAppleHTTPRequest(t, http.MethodGet, "https://localhost/path", nil)
+ },
+ wantErrSubstr: "tls.server_name is unsupported in Apple HTTP engine unless it matches request host",
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ transport := newAppleHTTPTestTransport(t, nil, testCase.options)
+ response, err := transport.RoundTrip(testCase.buildRequest(t))
+ if err == nil {
+ response.Body.Close()
+ t.Fatal("expected error")
+ }
+ if !strings.Contains(err.Error(), testCase.wantErrSubstr) {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ })
+ }
+}
+
+func TestAppleTransportCancellationRecovery(t *testing.T) {
+ server := startAppleHTTPTestServer(t, func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.Path {
+ case "/block":
+ select {
+ case <-r.Context().Done():
+ return
+ case <-time.After(appleHTTPTestTimeout):
+ http.Error(w, "request was not canceled", http.StatusGatewayTimeout)
+ }
+ default:
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte("ok"))
+ }
+ })
+
+ transport := newAppleHTTPTestTransport(t, server, option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: appleHTTPServerTLSOptions(server),
+ },
+ })
+
+ for index := range appleHTTPRecoveryLoops {
+ ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
+ request := newAppleHTTPRequestWithContext(t, ctx, http.MethodGet, server.URL("/block"), nil)
+ response, err := transport.RoundTrip(request)
+ cancel()
+ if err == nil {
+ response.Body.Close()
+ t.Fatalf("iteration %d: expected cancellation error", index)
+ }
+ if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) {
+ t.Fatalf("iteration %d: unexpected cancellation error: %v", index, err)
+ }
+
+ response, err = transport.RoundTrip(newAppleHTTPRequest(t, http.MethodGet, server.URL("/ok"), nil))
+ if err != nil {
+ t.Fatalf("iteration %d: follow-up request failed: %v", index, err)
+ }
+ if body := readResponseBody(t, response); body != "ok" {
+ response.Body.Close()
+ t.Fatalf("iteration %d: unexpected follow-up body: %q", index, body)
+ }
+ response.Body.Close()
+ }
+}
+
+func TestAppleTransportLifecycle(t *testing.T) {
+ server := startAppleHTTPTestServer(t, func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ _, _ = w.Write([]byte("ok"))
+ })
+
+ transport := newAppleHTTPTestTransport(t, server, option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: appleHTTPServerTLSOptions(server),
+ },
+ })
+
+ assertAppleHTTPSucceeds(t, transport, server.URL("/original"))
+
+ transport.CloseIdleConnections()
+ assertAppleHTTPSucceeds(t, transport, server.URL("/reset"))
+
+ innerTransport := transport.(*appleTransport)
+ err := innerTransport.Close()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ response, err := innerTransport.RoundTrip(newAppleHTTPRequest(t, http.MethodGet, server.URL("/closed"), nil))
+ if err == nil {
+ response.Body.Close()
+ t.Fatal("expected closed transport to fail")
+ }
+ if !errors.Is(err, net.ErrClosed) {
+ t.Fatalf("unexpected closed transport error: %v", err)
+ }
+}
+
+func startAppleHTTPTestServer(t *testing.T, handler http.HandlerFunc) *appleHTTPTestServer {
+ t.Helper()
+
+ serverCertificate, serverCertificatePEM := newAppleHTTPTestCertificate(t, "localhost")
+ server := httptest.NewUnstartedServer(handler)
+ server.EnableHTTP2 = true
+ server.TLS = &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ }
+ server.StartTLS()
+ t.Cleanup(server.Close)
+
+ parsedURL, err := url.Parse(server.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ baseURL := *parsedURL
+ baseURL.Host = net.JoinHostPort("localhost", parsedURL.Port())
+
+ return &appleHTTPTestServer{
+ server: server,
+ baseURL: baseURL.String(),
+ dialHost: parsedURL.Hostname(),
+ certificate: serverCertificate,
+ certificatePEM: serverCertificatePEM,
+ publicKeyHash: certificatePublicKeySHA256(t, serverCertificate.Certificate[0]),
+ }
+}
+
+func (s *appleHTTPTestServer) URL(path string) string {
+ if path == "" {
+ return s.baseURL
+ }
+ if strings.HasPrefix(path, "/") {
+ return s.baseURL + path
+ }
+ return s.baseURL + "/" + path
+}
+
+func newAppleHTTPTestTransport(t *testing.T, server *appleHTTPTestServer, options option.HTTPClientOptions) innerTransport {
+ t.Helper()
+
+ ctx := newAppleHTTPTestContext()
+ dialer := &appleHTTPTestDialer{
+ hostMap: make(map[string]string),
+ }
+ if server != nil {
+ dialer.hostMap["localhost"] = server.dialHost
+ }
+
+ transport, err := newAppleTransport(ctx, log.NewNOPFactory().NewLogger("httpclient"), dialer, options)
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ _ = transport.Close()
+ })
+ return transport
+}
+
+func newAppleHTTPTestContext() context.Context {
+ return service.ContextWith[adapter.ConnectionManager](
+ context.Background(),
+ route.NewConnectionManager(log.NewNOPFactory().NewLogger("connection")),
+ )
+}
+
+func appleTransportAnchorOptions(certificatePEM string) option.HTTPClientOptions {
+ return option.HTTPClientOptions{
+ Version: 2,
+ OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
+ TLS: &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{certificatePEM},
+ },
+ },
+ }
+}
+
+func restoreAppleTransportFactories(t *testing.T) {
+ t.Helper()
+ oldAnchors := newAppleUserAnchors
+ oldBridge := newAppleProxyBridge
+ oldSession := newAppleTransportSession
+ t.Cleanup(func() {
+ newAppleUserAnchors = oldAnchors
+ newAppleProxyBridge = oldBridge
+ newAppleTransportSession = oldSession
+ })
+}
+
+func (d *appleHTTPTestDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ host := destination.AddrString()
+ if destination.IsDomain() {
+ host = destination.Fqdn
+ if mappedHost, loaded := d.hostMap[host]; loaded {
+ host = mappedHost
+ }
+ }
+ return d.dialer.DialContext(ctx, network, net.JoinHostPort(host, strconv.Itoa(int(destination.Port))))
+}
+
+func (d *appleHTTPTestDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ host := destination.AddrString()
+ if destination.IsDomain() {
+ host = destination.Fqdn
+ if mappedHost, loaded := d.hostMap[host]; loaded {
+ host = mappedHost
+ }
+ }
+ if host == "" {
+ host = "127.0.0.1"
+ }
+ return d.listener.ListenPacket(ctx, N.NetworkUDP, net.JoinHostPort(host, strconv.Itoa(int(destination.Port))))
+}
+
+func newAppleHTTPTestCertificate(t *testing.T, serverName string) (stdtls.Certificate, string) {
+ t.Helper()
+
+ privateKeyPEM, certificatePEM, err := boxTLS.GenerateCertificate(nil, nil, time.Now, serverName, time.Now().Add(time.Hour))
+ if err != nil {
+ t.Fatal(err)
+ }
+ certificate, err := stdtls.X509KeyPair(certificatePEM, privateKeyPEM)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return certificate, string(certificatePEM)
+}
+
+func certificatePublicKeySHA256(t *testing.T, certificateDER []byte) []byte {
+ t.Helper()
+
+ certificate, err := x509.ParseCertificate(certificateDER)
+ if err != nil {
+ t.Fatal(err)
+ }
+ publicKeyDER, err := x509.MarshalPKIXPublicKey(certificate.PublicKey)
+ if err != nil {
+ t.Fatal(err)
+ }
+ hashValue := sha256.Sum256(publicKeyDER)
+ return append([]byte(nil), hashValue[:]...)
+}
+
+func appleHTTPServerTLSOptions(server *appleHTTPTestServer) *option.OutboundTLSOptions {
+ return &option.OutboundTLSOptions{
+ Enabled: true,
+ ServerName: "localhost",
+ Certificate: badoption.Listable[string]{server.certificatePEM},
+ }
+}
+
+func newAppleHTTPRequest(t *testing.T, method string, rawURL string, body []byte) *http.Request {
+ t.Helper()
+ return newAppleHTTPRequestWithContext(t, context.Background(), method, rawURL, body)
+}
+
+func newAppleHTTPRequestWithContext(t *testing.T, ctx context.Context, method string, rawURL string, body []byte) *http.Request {
+ t.Helper()
+ request, err := http.NewRequestWithContext(ctx, method, rawURL, bytes.NewReader(body))
+ if err != nil {
+ t.Fatal(err)
+ }
+ return request
+}
+
+func waitObservedRequest(t *testing.T, requests <-chan appleHTTPObservedRequest) appleHTTPObservedRequest {
+ t.Helper()
+
+ select {
+ case request := <-requests:
+ return request
+ case <-time.After(appleHTTPTestTimeout):
+ t.Fatal("timed out waiting for observed request")
+ return appleHTTPObservedRequest{}
+ }
+}
+
+func readResponseBody(t *testing.T, response *http.Response) string {
+ t.Helper()
+
+ body, err := io.ReadAll(response.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return string(body)
+}
+
+func assertAppleHTTPSucceeds(t *testing.T, transport http.RoundTripper, rawURL string) {
+ t.Helper()
+
+ response, err := transport.RoundTrip(newAppleHTTPRequest(t, http.MethodGet, rawURL, nil))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer response.Body.Close()
+ if body := readResponseBody(t, response); body != "ok" {
+ t.Fatalf("unexpected response body: %q", body)
+ }
+}
diff --git a/common/httpclient/apple_transport_stub.go b/common/httpclient/apple_transport_stub.go
new file mode 100644
index 0000000000..9735998f4e
--- /dev/null
+++ b/common/httpclient/apple_transport_stub.go
@@ -0,0 +1,16 @@
+//go:build !darwin || !cgo
+
+package httpclient
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func newAppleTransport(ctx context.Context, logger logger.ContextLogger, rawDialer N.Dialer, options option.HTTPClientOptions) (innerTransport, error) {
+ return nil, E.New("Apple HTTP engine is not available on non-Apple platforms")
+}
diff --git a/common/httpclient/client.go b/common/httpclient/client.go
new file mode 100644
index 0000000000..9dbb8cc1d5
--- /dev/null
+++ b/common/httpclient/client.go
@@ -0,0 +1,131 @@
+package httpclient
+
+import (
+ "context"
+ "time"
+
+ "github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func NewTransport(ctx context.Context, logger logger.ContextLogger, tag string, options option.HTTPClientOptions) (*ManagedTransport, error) {
+ rawDialer, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: true,
+ DirectResolver: options.DirectResolver,
+ ResolverOnDetour: options.ResolveOnDetour,
+ NewDialer: options.ResolveOnDetour,
+ DisableEmptyDirectCheck: options.DisableEmptyDirectCheck,
+ DefaultOutbound: options.DefaultOutbound,
+ })
+ if err != nil {
+ return nil, err
+ }
+ headers := options.Headers.Build()
+ host := headers.Get("Host")
+ headers.Del("Host")
+
+ var cheapRebuild bool
+ switch options.Engine {
+ case C.TLSEngineApple:
+ inner, transportErr := newAppleTransport(ctx, logger, rawDialer, options)
+ if transportErr != nil {
+ return nil, transportErr
+ }
+ managedTransport := &ManagedTransport{
+ dialer: rawDialer,
+ headers: headers,
+ host: host,
+ tag: tag,
+ factory: func() (innerTransport, error) {
+ return newAppleTransport(ctx, logger, rawDialer, options)
+ },
+ }
+ managedTransport.epoch.Store(&transportEpoch{transport: inner})
+ return managedTransport, nil
+ case "", C.TLSEngineGo:
+ cheapRebuild = true
+ default:
+ return nil, E.New("unknown HTTP engine: ", options.Engine)
+ }
+ tlsOptions := common.PtrValueOrDefault(options.TLS)
+ tlsOptions.Enabled = true
+ baseTLSConfig, err := tls.NewClientWithOptions(tls.ClientOptions{
+ Context: ctx,
+ Logger: logger,
+ Options: tlsOptions,
+ AllowEmptyServerName: true,
+ })
+ if err != nil {
+ return nil, err
+ }
+ inner, err := newTransport(rawDialer, baseTLSConfig, options)
+ if err != nil {
+ return nil, err
+ }
+ managedTransport := &ManagedTransport{
+ cheapRebuild: cheapRebuild,
+ dialer: rawDialer,
+ headers: headers,
+ host: host,
+ tag: tag,
+ factory: func() (innerTransport, error) {
+ return newTransport(rawDialer, baseTLSConfig, options)
+ },
+ }
+ managedTransport.epoch.Store(&transportEpoch{transport: inner})
+ return managedTransport, nil
+}
+
+func newTransport(rawDialer N.Dialer, baseTLSConfig tls.Config, options option.HTTPClientOptions) (innerTransport, error) {
+ version := options.Version
+ if version == 0 {
+ version = 2
+ }
+ fallbackDelay := time.Duration(options.DialerOptions.FallbackDelay)
+ if fallbackDelay == 0 {
+ fallbackDelay = 300 * time.Millisecond
+ }
+ var transport innerTransport
+ var err error
+ switch version {
+ case 1:
+ transport = newHTTP1Transport(rawDialer, baseTLSConfig)
+ case 2:
+ if options.DisableVersionFallback {
+ transport, err = newHTTP2Transport(rawDialer, baseTLSConfig, options.HTTP2Options)
+ } else {
+ transport, err = newHTTP2FallbackTransport(rawDialer, baseTLSConfig, options.HTTP2Options)
+ }
+ case 3:
+ if baseTLSConfig != nil {
+ _, err = baseTLSConfig.STDConfig()
+ if err != nil {
+ return nil, err
+ }
+ }
+ if options.DisableVersionFallback {
+ transport, err = newHTTP3Transport(rawDialer, baseTLSConfig, options.HTTP3Options)
+ } else {
+ var h2Fallback innerTransport
+ h2Fallback, err = newHTTP2FallbackTransport(rawDialer, baseTLSConfig, options.HTTP2Options)
+ if err != nil {
+ return nil, err
+ }
+ transport, err = newHTTP3FallbackTransport(rawDialer, baseTLSConfig, h2Fallback, options.HTTP3Options, fallbackDelay)
+ }
+ default:
+ return nil, E.New("unknown HTTP version: ", version)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return transport, nil
+}
diff --git a/common/httpclient/context.go b/common/httpclient/context.go
new file mode 100644
index 0000000000..883a25e20c
--- /dev/null
+++ b/common/httpclient/context.go
@@ -0,0 +1,14 @@
+package httpclient
+
+import "context"
+
+type transportKey struct{}
+
+func contextWithTransportTag(ctx context.Context, transportTag string) context.Context {
+ return context.WithValue(ctx, transportKey{}, transportTag)
+}
+
+func transportTagFromContext(ctx context.Context) (string, bool) {
+ value, loaded := ctx.Value(transportKey{}).(string)
+ return value, loaded
+}
diff --git a/common/httpclient/helpers.go b/common/httpclient/helpers.go
new file mode 100644
index 0000000000..7cc78cc6e1
--- /dev/null
+++ b/common/httpclient/helpers.go
@@ -0,0 +1,116 @@
+package httpclient
+
+import (
+ "context"
+ stdTLS "crypto/tls"
+ "io"
+ "net"
+ "net/http"
+ "strings"
+
+ "github.com/sagernet/sing-box/common/tls"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ "golang.org/x/net/idna"
+)
+
+func dialTLS(ctx context.Context, rawDialer N.Dialer, baseTLSConfig tls.Config, destination M.Socksaddr, nextProtos []string, expectProto string) (net.Conn, error) {
+ if baseTLSConfig == nil {
+ return nil, E.New("TLS transport unavailable")
+ }
+ tlsConfig := baseTLSConfig.Clone()
+ if tlsConfig.ServerName() == "" && destination.IsValid() {
+ tlsConfig.SetServerName(destination.AddrString())
+ }
+ tlsConfig.SetNextProtos(nextProtos)
+ conn, err := rawDialer.DialContext(ctx, N.NetworkTCP, destination)
+ if err != nil {
+ return nil, err
+ }
+ tlsConn, err := tls.ClientHandshake(ctx, conn, tlsConfig)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ if expectProto != "" && tlsConn.ConnectionState().NegotiatedProtocol != expectProto {
+ tlsConn.Close()
+ return nil, errHTTP2Fallback
+ }
+ return tlsConn, nil
+}
+
+func applyHeaders(request *http.Request, headers http.Header, host string) {
+ for header, values := range headers {
+ request.Header[header] = append([]string(nil), values...)
+ }
+ if host != "" {
+ request.Host = host
+ }
+}
+
+func requestRequiresHTTP1(request *http.Request) bool {
+ return strings.Contains(strings.ToLower(request.Header.Get("Connection")), "upgrade") &&
+ strings.EqualFold(request.Header.Get("Upgrade"), "websocket")
+}
+
+func requestReplayable(request *http.Request) bool {
+ return request.Body == nil || request.Body == http.NoBody || request.GetBody != nil
+}
+
+func cloneRequestForRetry(request *http.Request) *http.Request {
+ cloned := request.Clone(request.Context())
+ if request.Body != nil && request.Body != http.NoBody && request.GetBody != nil {
+ cloned.Body = mustGetBody(request)
+ }
+ return cloned
+}
+
+func mustGetBody(request *http.Request) io.ReadCloser {
+ body, err := request.GetBody()
+ if err != nil {
+ panic(err)
+ }
+ return body
+}
+
+func requestAuthority(request *http.Request) string {
+ if request == nil || request.URL == nil || request.URL.Host == "" {
+ return ""
+ }
+ host, port, err := net.SplitHostPort(request.URL.Host)
+ if err != nil {
+ host = request.URL.Host
+ port = ""
+ }
+ if port == "" {
+ if request.URL.Scheme == "http" {
+ port = "80"
+ } else {
+ port = "443"
+ }
+ }
+ if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
+ return host + ":" + port
+ }
+ ascii, idnaErr := idna.Lookup.ToASCII(host)
+ if idnaErr == nil {
+ host = ascii
+ } else {
+ host = strings.ToLower(host)
+ }
+ return net.JoinHostPort(host, port)
+}
+
+func buildSTDTLSConfig(baseTLSConfig tls.Config, destination M.Socksaddr, nextProtos []string) (*stdTLS.Config, error) {
+ if baseTLSConfig == nil {
+ return nil, nil
+ }
+ tlsConfig := baseTLSConfig.Clone()
+ if tlsConfig.ServerName() == "" && destination.IsValid() {
+ tlsConfig.SetServerName(destination.AddrString())
+ }
+ tlsConfig.SetNextProtos(nextProtos)
+ return tlsConfig.STDConfig()
+}
diff --git a/common/httpclient/helpers_test.go b/common/httpclient/helpers_test.go
new file mode 100644
index 0000000000..2c451e0a58
--- /dev/null
+++ b/common/httpclient/helpers_test.go
@@ -0,0 +1,51 @@
+package httpclient
+
+import (
+ "net/http"
+ "net/url"
+ "testing"
+)
+
+func TestRequestAuthority(t *testing.T) {
+ testCases := []struct {
+ name string
+ url string
+ expect string
+ }{
+ {name: "https default port", url: "https://example.com/foo", expect: "example.com:443"},
+ {name: "http default port", url: "http://example.com/foo", expect: "example.com:80"},
+ {name: "https explicit port", url: "https://example.com:8443/foo", expect: "example.com:8443"},
+ {name: "https uppercase host", url: "https://EXAMPLE.COM/foo", expect: "example.com:443"},
+ {name: "https ipv6 default port", url: "https://[2001:db8::1]/foo", expect: "[2001:db8::1]:443"},
+ {name: "https ipv6 explicit port", url: "https://[2001:db8::1]:8443/foo", expect: "[2001:db8::1]:8443"},
+ {name: "https ipv4", url: "https://192.0.2.1/foo", expect: "192.0.2.1:443"},
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ parsed, err := url.Parse(testCase.url)
+ if err != nil {
+ t.Fatalf("parse url: %v", err)
+ }
+ got := requestAuthority(&http.Request{URL: parsed})
+ if got != testCase.expect {
+ t.Fatalf("got %q, want %q", got, testCase.expect)
+ }
+ })
+ }
+
+ t.Run("nil request", func(t *testing.T) {
+ if got := requestAuthority(nil); got != "" {
+ t.Fatalf("got %q, want empty", got)
+ }
+ })
+ t.Run("nil URL", func(t *testing.T) {
+ if got := requestAuthority(&http.Request{}); got != "" {
+ t.Fatalf("got %q, want empty", got)
+ }
+ })
+ t.Run("empty host", func(t *testing.T) {
+ if got := requestAuthority(&http.Request{URL: &url.URL{Scheme: "https"}}); got != "" {
+ t.Fatalf("got %q, want empty", got)
+ }
+ })
+}
diff --git a/common/httpclient/http1_transport.go b/common/httpclient/http1_transport.go
new file mode 100644
index 0000000000..ad2ccedb8f
--- /dev/null
+++ b/common/httpclient/http1_transport.go
@@ -0,0 +1,42 @@
+package httpclient
+
+import (
+ "context"
+ "net"
+ "net/http"
+
+ "github.com/sagernet/sing-box/common/tls"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+type http1Transport struct {
+ transport *http.Transport
+}
+
+func newHTTP1Transport(rawDialer N.Dialer, baseTLSConfig tls.Config) *http1Transport {
+ transport := &http.Transport{
+ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return rawDialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
+ },
+ }
+ if baseTLSConfig != nil {
+ transport.DialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return dialTLS(ctx, rawDialer, baseTLSConfig, M.ParseSocksaddr(addr), []string{"http/1.1"}, "")
+ }
+ }
+ return &http1Transport{transport: transport}
+}
+
+func (t *http1Transport) RoundTrip(request *http.Request) (*http.Response, error) {
+ return t.transport.RoundTrip(request)
+}
+
+func (t *http1Transport) CloseIdleConnections() {
+ t.transport.CloseIdleConnections()
+}
+
+func (t *http1Transport) Close() error {
+ t.CloseIdleConnections()
+ return nil
+}
diff --git a/common/httpclient/http2_config.go b/common/httpclient/http2_config.go
new file mode 100644
index 0000000000..9e1d871fdc
--- /dev/null
+++ b/common/httpclient/http2_config.go
@@ -0,0 +1,42 @@
+package httpclient
+
+import (
+ stdTLS "crypto/tls"
+ "net/http"
+ "time"
+
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/net/http2"
+)
+
+func CloneHTTP2Transport(transport *http2.Transport) *http2.Transport {
+ return &http2.Transport{
+ ReadIdleTimeout: transport.ReadIdleTimeout,
+ PingTimeout: transport.PingTimeout,
+ DialTLSContext: transport.DialTLSContext,
+ }
+}
+
+func ConfigureHTTP2Transport(options option.HTTP2Options) (*http2.Transport, error) {
+ stdTransport := &http.Transport{
+ TLSClientConfig: &stdTLS.Config{},
+ HTTP2: &http.HTTP2Config{
+ MaxReceiveBufferPerStream: int(options.StreamReceiveWindow.Value()),
+ MaxReceiveBufferPerConnection: int(options.ConnectionReceiveWindow.Value()),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ SendPingTimeout: time.Duration(options.KeepAlivePeriod),
+ PingTimeout: time.Duration(options.IdleTimeout),
+ },
+ }
+ h2Transport, err := http2.ConfigureTransports(stdTransport)
+ if err != nil {
+ return nil, E.Cause(err, "configure HTTP/2 transport")
+ }
+ // ConfigureTransports binds ConnPool to the throwaway http.Transport; sever it so DialTLSContext is used directly.
+ h2Transport.ConnPool = nil
+ h2Transport.ReadIdleTimeout = time.Duration(options.KeepAlivePeriod)
+ h2Transport.PingTimeout = time.Duration(options.IdleTimeout)
+ return h2Transport, nil
+}
diff --git a/common/httpclient/http2_fallback_transport.go b/common/httpclient/http2_fallback_transport.go
new file mode 100644
index 0000000000..682b1ebadf
--- /dev/null
+++ b/common/httpclient/http2_fallback_transport.go
@@ -0,0 +1,98 @@
+package httpclient
+
+import (
+ "context"
+ stdTLS "crypto/tls"
+ "errors"
+ "net"
+ "net/http"
+ "sync"
+
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ "golang.org/x/net/http2"
+)
+
+var errHTTP2Fallback = E.New("fallback to HTTP/1.1")
+
+type http2FallbackTransport struct {
+ h2Transport *http2.Transport
+ h1Transport *http1Transport
+ fallbackAccess sync.RWMutex
+ fallbackAuthority map[string]struct{}
+}
+
+func newHTTP2FallbackTransport(rawDialer N.Dialer, baseTLSConfig tls.Config, options option.HTTP2Options) (*http2FallbackTransport, error) {
+ h1 := newHTTP1Transport(rawDialer, baseTLSConfig)
+ h2Transport, err := ConfigureHTTP2Transport(options)
+ if err != nil {
+ return nil, err
+ }
+ h2Transport.DialTLSContext = func(ctx context.Context, network, addr string, _ *stdTLS.Config) (net.Conn, error) {
+ return dialTLS(ctx, rawDialer, baseTLSConfig, M.ParseSocksaddr(addr), []string{http2.NextProtoTLS, "http/1.1"}, http2.NextProtoTLS)
+ }
+ return &http2FallbackTransport{
+ h2Transport: h2Transport,
+ h1Transport: h1,
+ fallbackAuthority: make(map[string]struct{}),
+ }, nil
+}
+
+func (t *http2FallbackTransport) isH2Fallback(authority string) bool {
+ if authority == "" {
+ return false
+ }
+ t.fallbackAccess.RLock()
+ _, found := t.fallbackAuthority[authority]
+ t.fallbackAccess.RUnlock()
+ return found
+}
+
+func (t *http2FallbackTransport) markH2Fallback(authority string) {
+ if authority == "" {
+ return
+ }
+ t.fallbackAccess.Lock()
+ t.fallbackAuthority[authority] = struct{}{}
+ t.fallbackAccess.Unlock()
+}
+
+func (t *http2FallbackTransport) RoundTrip(request *http.Request) (*http.Response, error) {
+ return t.roundTrip(request, true)
+}
+
+func (t *http2FallbackTransport) roundTrip(request *http.Request, allowHTTP1Fallback bool) (*http.Response, error) {
+ if request.URL.Scheme != "https" || requestRequiresHTTP1(request) {
+ return t.h1Transport.RoundTrip(request)
+ }
+ authority := requestAuthority(request)
+ if t.isH2Fallback(authority) {
+ if !allowHTTP1Fallback {
+ return nil, errHTTP2Fallback
+ }
+ return t.h1Transport.RoundTrip(request)
+ }
+ response, err := t.h2Transport.RoundTrip(request)
+ if err == nil {
+ return response, nil
+ }
+ if !errors.Is(err, errHTTP2Fallback) || !allowHTTP1Fallback {
+ return nil, err
+ }
+ t.markH2Fallback(authority)
+ return t.h1Transport.RoundTrip(cloneRequestForRetry(request))
+}
+
+func (t *http2FallbackTransport) CloseIdleConnections() {
+ t.h1Transport.CloseIdleConnections()
+ t.h2Transport.CloseIdleConnections()
+}
+
+func (t *http2FallbackTransport) Close() error {
+ t.CloseIdleConnections()
+ return nil
+}
diff --git a/common/httpclient/http2_fallback_transport_test.go b/common/httpclient/http2_fallback_transport_test.go
new file mode 100644
index 0000000000..2c2085c863
--- /dev/null
+++ b/common/httpclient/http2_fallback_transport_test.go
@@ -0,0 +1,37 @@
+package httpclient
+
+import (
+ "testing"
+)
+
+func TestHTTP2FallbackAuthorityIsolation(t *testing.T) {
+ transport := &http2FallbackTransport{fallbackAuthority: make(map[string]struct{})}
+
+ transport.markH2Fallback("a.example:443")
+ if !transport.isH2Fallback("a.example:443") {
+ t.Fatal("a.example:443 should be marked")
+ }
+ if transport.isH2Fallback("b.example:443") {
+ t.Fatal("b.example:443 must remain unmarked after marking a.example")
+ }
+
+ transport.markH2Fallback("b.example:443")
+ if !transport.isH2Fallback("b.example:443") {
+ t.Fatal("b.example:443 should be marked after explicit mark")
+ }
+ if !transport.isH2Fallback("a.example:443") {
+ t.Fatal("a.example:443 mark must survive marking another authority")
+ }
+}
+
+func TestHTTP2FallbackEmptyAuthorityNoOp(t *testing.T) {
+ transport := &http2FallbackTransport{fallbackAuthority: make(map[string]struct{})}
+
+ transport.markH2Fallback("")
+ if len(transport.fallbackAuthority) != 0 {
+ t.Fatalf("empty authority must not be stored, got %d entries", len(transport.fallbackAuthority))
+ }
+ if transport.isH2Fallback("") {
+ t.Fatal("isH2Fallback must be false for empty authority")
+ }
+}
diff --git a/common/httpclient/http2_transport.go b/common/httpclient/http2_transport.go
new file mode 100644
index 0000000000..78e7ae6824
--- /dev/null
+++ b/common/httpclient/http2_transport.go
@@ -0,0 +1,52 @@
+package httpclient
+
+import (
+ "context"
+ stdTLS "crypto/tls"
+ "net"
+ "net/http"
+
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/option"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ "golang.org/x/net/http2"
+)
+
+type http2Transport struct {
+ h2Transport *http2.Transport
+ h1Transport *http1Transport
+}
+
+func newHTTP2Transport(rawDialer N.Dialer, baseTLSConfig tls.Config, options option.HTTP2Options) (*http2Transport, error) {
+ h1 := newHTTP1Transport(rawDialer, baseTLSConfig)
+ h2Transport, err := ConfigureHTTP2Transport(options)
+ if err != nil {
+ return nil, err
+ }
+ h2Transport.DialTLSContext = func(ctx context.Context, network, addr string, _ *stdTLS.Config) (net.Conn, error) {
+ return dialTLS(ctx, rawDialer, baseTLSConfig, M.ParseSocksaddr(addr), []string{http2.NextProtoTLS}, http2.NextProtoTLS)
+ }
+ return &http2Transport{
+ h2Transport: h2Transport,
+ h1Transport: h1,
+ }, nil
+}
+
+func (t *http2Transport) RoundTrip(request *http.Request) (*http.Response, error) {
+ if request.URL.Scheme != "https" || requestRequiresHTTP1(request) {
+ return t.h1Transport.RoundTrip(request)
+ }
+ return t.h2Transport.RoundTrip(request)
+}
+
+func (t *http2Transport) CloseIdleConnections() {
+ t.h1Transport.CloseIdleConnections()
+ t.h2Transport.CloseIdleConnections()
+}
+
+func (t *http2Transport) Close() error {
+ t.CloseIdleConnections()
+ return nil
+}
diff --git a/common/httpclient/http3_transport.go b/common/httpclient/http3_transport.go
new file mode 100644
index 0000000000..d3eb5bc155
--- /dev/null
+++ b/common/httpclient/http3_transport.go
@@ -0,0 +1,321 @@
+//go:build with_quic
+
+package httpclient
+
+import (
+ "context"
+ stdTLS "crypto/tls"
+ "errors"
+ "net/http"
+ "sync"
+ "time"
+
+ "github.com/sagernet/quic-go"
+ "github.com/sagernet/quic-go/http3"
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+type http3Transport struct {
+ h3Transport *http3.Transport
+}
+
+type http3BrokenEntry struct {
+ until time.Time
+ backoff time.Duration
+}
+
+type http3FallbackTransport struct {
+ h3Transport *http3.Transport
+ h2Fallback innerTransport
+ fallbackDelay time.Duration
+ brokenAccess sync.Mutex
+ broken map[string]http3BrokenEntry
+}
+
+func newHTTP3RoundTripper(
+ rawDialer N.Dialer,
+ baseTLSConfig tls.Config,
+ options option.QUICOptions,
+) *http3.Transport {
+ var handshakeTimeout time.Duration
+ if baseTLSConfig != nil {
+ handshakeTimeout = baseTLSConfig.HandshakeTimeout()
+ }
+ quicConfig := &quic.Config{
+ InitialStreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ MaxStreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ InitialConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ KeepAlivePeriod: time.Duration(options.KeepAlivePeriod),
+ MaxIdleTimeout: time.Duration(options.IdleTimeout),
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ }
+ if options.InitialPacketSize > 0 {
+ quicConfig.InitialPacketSize = uint16(options.InitialPacketSize)
+ }
+ if options.MaxConcurrentStreams > 0 {
+ quicConfig.MaxIncomingStreams = int64(options.MaxConcurrentStreams)
+ }
+ if handshakeTimeout > 0 {
+ quicConfig.HandshakeIdleTimeout = handshakeTimeout
+ }
+ h3Transport := &http3.Transport{
+ TLSClientConfig: &stdTLS.Config{},
+ QUICConfig: quicConfig,
+ Dial: func(ctx context.Context, addr string, tlsConfig *stdTLS.Config, quicConfig *quic.Config) (*quic.Conn, error) {
+ if handshakeTimeout > 0 && quicConfig.HandshakeIdleTimeout == 0 {
+ quicConfig = quicConfig.Clone()
+ quicConfig.HandshakeIdleTimeout = handshakeTimeout
+ }
+ if baseTLSConfig != nil {
+ var err error
+ tlsConfig, err = buildSTDTLSConfig(baseTLSConfig, M.ParseSocksaddr(addr), []string{http3.NextProtoH3})
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ tlsConfig = tlsConfig.Clone()
+ tlsConfig.NextProtos = []string{http3.NextProtoH3}
+ }
+ conn, err := rawDialer.DialContext(ctx, N.NetworkUDP, M.ParseSocksaddr(addr))
+ if err != nil {
+ return nil, err
+ }
+ quicConn, err := quic.DialEarly(ctx, bufio.NewUnbindPacketConn(conn), conn.RemoteAddr(), tlsConfig, quicConfig)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return quicConn, nil
+ },
+ }
+ return h3Transport
+}
+
+func newHTTP3Transport(
+ rawDialer N.Dialer,
+ baseTLSConfig tls.Config,
+ options option.QUICOptions,
+) (innerTransport, error) {
+ return &http3Transport{
+ h3Transport: newHTTP3RoundTripper(rawDialer, baseTLSConfig, options),
+ }, nil
+}
+
+func newHTTP3FallbackTransport(
+ rawDialer N.Dialer,
+ baseTLSConfig tls.Config,
+ h2Fallback innerTransport,
+ options option.QUICOptions,
+ fallbackDelay time.Duration,
+) (innerTransport, error) {
+ return &http3FallbackTransport{
+ h3Transport: newHTTP3RoundTripper(rawDialer, baseTLSConfig, options),
+ h2Fallback: h2Fallback,
+ fallbackDelay: fallbackDelay,
+ broken: make(map[string]http3BrokenEntry),
+ }, nil
+}
+
+func (t *http3Transport) RoundTrip(request *http.Request) (*http.Response, error) {
+ return t.h3Transport.RoundTrip(request)
+}
+
+func (t *http3Transport) CloseIdleConnections() {
+ t.h3Transport.CloseIdleConnections()
+}
+
+func (t *http3Transport) Close() error {
+ t.CloseIdleConnections()
+ return t.h3Transport.Close()
+}
+
+func (t *http3FallbackTransport) RoundTrip(request *http.Request) (*http.Response, error) {
+ if request.URL.Scheme != "https" || requestRequiresHTTP1(request) {
+ return t.h2Fallback.RoundTrip(request)
+ }
+ return t.roundTripHTTP3(request)
+}
+
+func (t *http3FallbackTransport) roundTripHTTP3(request *http.Request) (*http.Response, error) {
+ authority := requestAuthority(request)
+ if t.h3Broken(authority) {
+ return t.h2FallbackRoundTrip(request)
+ }
+ response, err := t.h3Transport.RoundTripOpt(request, http3.RoundTripOpt{OnlyCachedConn: true})
+ if err == nil {
+ t.clearH3Broken(authority)
+ return response, nil
+ }
+ if !errors.Is(err, http3.ErrNoCachedConn) {
+ t.markH3Broken(authority)
+ return t.h2FallbackRoundTrip(cloneRequestForRetry(request))
+ }
+ if !requestReplayable(request) {
+ response, err = t.h3Transport.RoundTrip(request)
+ if err == nil {
+ t.clearH3Broken(authority)
+ return response, nil
+ }
+ t.markH3Broken(authority)
+ return nil, err
+ }
+ return t.roundTripHTTP3Race(request, authority)
+}
+
+func (t *http3FallbackTransport) roundTripHTTP3Race(request *http.Request, authority string) (*http.Response, error) {
+ ctx, cancel := context.WithCancel(request.Context())
+ defer cancel()
+ type result struct {
+ response *http.Response
+ err error
+ h3 bool
+ }
+ results := make(chan result, 2)
+ startRoundTrip := func(request *http.Request, useH3 bool) {
+ request = request.WithContext(ctx)
+ var (
+ response *http.Response
+ err error
+ )
+ if useH3 {
+ response, err = t.h3Transport.RoundTrip(request)
+ } else {
+ response, err = t.h2FallbackRoundTrip(request)
+ }
+ results <- result{response: response, err: err, h3: useH3}
+ }
+ goroutines := 1
+ received := 0
+ drainRemaining := func() {
+ cancel()
+ for range goroutines - received {
+ go func() {
+ loser := <-results
+ if loser.response != nil && loser.response.Body != nil {
+ loser.response.Body.Close()
+ }
+ }()
+ }
+ }
+ go startRoundTrip(cloneRequestForRetry(request), true)
+ timer := time.NewTimer(t.fallbackDelay)
+ defer timer.Stop()
+ var (
+ h3Err error
+ fallbackErr error
+ )
+ for {
+ select {
+ case <-timer.C:
+ if goroutines == 1 {
+ goroutines++
+ go startRoundTrip(cloneRequestForRetry(request), false)
+ }
+ case raceResult := <-results:
+ received++
+ if raceResult.err == nil {
+ if raceResult.h3 {
+ t.clearH3Broken(authority)
+ }
+ drainRemaining()
+ return raceResult.response, nil
+ }
+ if raceResult.h3 {
+ t.markH3Broken(authority)
+ h3Err = raceResult.err
+ if goroutines == 1 {
+ goroutines++
+ if !timer.Stop() {
+ select {
+ case <-timer.C:
+ default:
+ }
+ }
+ go startRoundTrip(cloneRequestForRetry(request), false)
+ }
+ } else {
+ fallbackErr = raceResult.err
+ }
+ if received < goroutines {
+ continue
+ }
+ drainRemaining()
+ switch {
+ case h3Err != nil && fallbackErr != nil:
+ return nil, E.Errors(h3Err, fallbackErr)
+ case fallbackErr != nil:
+ return nil, fallbackErr
+ default:
+ return nil, h3Err
+ }
+ }
+ }
+}
+
+func (t *http3FallbackTransport) h2FallbackRoundTrip(request *http.Request) (*http.Response, error) {
+ if fallback, isFallback := t.h2Fallback.(*http2FallbackTransport); isFallback {
+ return fallback.roundTrip(request, true)
+ }
+ return t.h2Fallback.RoundTrip(request)
+}
+
+func (t *http3FallbackTransport) CloseIdleConnections() {
+ t.h3Transport.CloseIdleConnections()
+ t.h2Fallback.CloseIdleConnections()
+}
+
+func (t *http3FallbackTransport) Close() error {
+ t.CloseIdleConnections()
+ return t.h3Transport.Close()
+}
+
+func (t *http3FallbackTransport) h3Broken(authority string) bool {
+ if authority == "" {
+ return false
+ }
+ t.brokenAccess.Lock()
+ defer t.brokenAccess.Unlock()
+ entry, found := t.broken[authority]
+ if !found {
+ return false
+ }
+ if entry.until.IsZero() || !time.Now().Before(entry.until) {
+ delete(t.broken, authority)
+ return false
+ }
+ return true
+}
+
+func (t *http3FallbackTransport) clearH3Broken(authority string) {
+ if authority == "" {
+ return
+ }
+ t.brokenAccess.Lock()
+ delete(t.broken, authority)
+ t.brokenAccess.Unlock()
+}
+
+func (t *http3FallbackTransport) markH3Broken(authority string) {
+ if authority == "" {
+ return
+ }
+ t.brokenAccess.Lock()
+ defer t.brokenAccess.Unlock()
+ entry := t.broken[authority]
+ if entry.backoff == 0 {
+ entry.backoff = 5 * time.Minute
+ } else {
+ entry.backoff *= 2
+ if entry.backoff > 48*time.Hour {
+ entry.backoff = 48 * time.Hour
+ }
+ }
+ entry.until = time.Now().Add(entry.backoff)
+ t.broken[authority] = entry
+}
diff --git a/common/httpclient/http3_transport_stub.go b/common/httpclient/http3_transport_stub.go
new file mode 100644
index 0000000000..f86a9f3653
--- /dev/null
+++ b/common/httpclient/http3_transport_stub.go
@@ -0,0 +1,30 @@
+//go:build !with_quic
+
+package httpclient
+
+import (
+ "time"
+
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func newHTTP3FallbackTransport(
+ rawDialer N.Dialer,
+ baseTLSConfig tls.Config,
+ h2Fallback innerTransport,
+ options option.QUICOptions,
+ fallbackDelay time.Duration,
+) (innerTransport, error) {
+ return nil, E.New("HTTP/3 requires building with the with_quic tag")
+}
+
+func newHTTP3Transport(
+ rawDialer N.Dialer,
+ baseTLSConfig tls.Config,
+ options option.QUICOptions,
+) (innerTransport, error) {
+ return nil, E.New("HTTP/3 requires building with the with_quic tag")
+}
diff --git a/common/httpclient/http3_transport_test.go b/common/httpclient/http3_transport_test.go
new file mode 100644
index 0000000000..600e88db06
--- /dev/null
+++ b/common/httpclient/http3_transport_test.go
@@ -0,0 +1,99 @@
+//go:build with_quic
+
+package httpclient
+
+import (
+ "testing"
+ "time"
+)
+
+func TestHTTP3BrokenAuthorityIsolation(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.markH3Broken("a.example:443")
+ if !transport.h3Broken("a.example:443") {
+ t.Fatal("a.example:443 should be broken after mark")
+ }
+ if transport.h3Broken("b.example:443") {
+ t.Fatal("b.example:443 must not be affected by marking a.example")
+ }
+}
+
+func TestHTTP3BrokenBackoffPerAuthority(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.markH3Broken("a.example:443")
+ if transport.broken["a.example:443"].backoff != 5*time.Minute {
+ t.Fatalf("first mark should set backoff to 5m, got %v", transport.broken["a.example:443"].backoff)
+ }
+ transport.markH3Broken("a.example:443")
+ if transport.broken["a.example:443"].backoff != 10*time.Minute {
+ t.Fatalf("second mark should double backoff to 10m, got %v", transport.broken["a.example:443"].backoff)
+ }
+ transport.markH3Broken("a.example:443")
+ if transport.broken["a.example:443"].backoff != 20*time.Minute {
+ t.Fatalf("third mark should double to 20m, got %v", transport.broken["a.example:443"].backoff)
+ }
+
+ if _, found := transport.broken["b.example:443"]; found {
+ t.Fatal("marking a.example must not leak into b.example backoff state")
+ }
+
+ transport.markH3Broken("b.example:443")
+ if transport.broken["b.example:443"].backoff != 5*time.Minute {
+ t.Fatalf("b.example first mark should start at 5m independent of a.example, got %v", transport.broken["b.example:443"].backoff)
+ }
+}
+
+func TestHTTP3BrokenBackoffCap(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.broken["a.example:443"] = http3BrokenEntry{backoff: 48 * time.Hour, until: time.Now().Add(48 * time.Hour)}
+ transport.markH3Broken("a.example:443")
+ if transport.broken["a.example:443"].backoff != 48*time.Hour {
+ t.Fatalf("backoff must cap at 48h, got %v", transport.broken["a.example:443"].backoff)
+ }
+}
+
+func TestHTTP3BrokenClearDeletesEntry(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.markH3Broken("a.example:443")
+ transport.markH3Broken("b.example:443")
+ transport.clearH3Broken("a.example:443")
+
+ if _, found := transport.broken["a.example:443"]; found {
+ t.Fatal("clearH3Broken must delete the entry")
+ }
+ if !transport.h3Broken("b.example:443") {
+ t.Fatal("clearing a.example must not affect b.example")
+ }
+}
+
+func TestHTTP3BrokenExpiredEntryGarbageCollected(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.broken["a.example:443"] = http3BrokenEntry{
+ backoff: 5 * time.Minute,
+ until: time.Now().Add(-time.Second),
+ }
+ if transport.h3Broken("a.example:443") {
+ t.Fatal("expired entry must report not broken")
+ }
+ if _, found := transport.broken["a.example:443"]; found {
+ t.Fatal("expired entry must be garbage-collected on read")
+ }
+}
+
+func TestHTTP3BrokenEmptyAuthorityNoOp(t *testing.T) {
+ transport := &http3FallbackTransport{broken: make(map[string]http3BrokenEntry)}
+
+ transport.markH3Broken("")
+ if len(transport.broken) != 0 {
+ t.Fatalf("markH3Broken must ignore empty authority, got %d entries", len(transport.broken))
+ }
+ if transport.h3Broken("") {
+ t.Fatal("h3Broken must return false for empty authority")
+ }
+ transport.clearH3Broken("")
+}
diff --git a/common/httpclient/managed_transport.go b/common/httpclient/managed_transport.go
new file mode 100644
index 0000000000..779eccda8f
--- /dev/null
+++ b/common/httpclient/managed_transport.go
@@ -0,0 +1,209 @@
+package httpclient
+
+import (
+ "io"
+ "net/http"
+ "sync"
+ "sync/atomic"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+ N "github.com/sagernet/sing/common/network"
+)
+
+type innerTransport interface {
+ http.RoundTripper
+ CloseIdleConnections()
+ Close() error
+}
+
+var _ adapter.HTTPTransport = (*ManagedTransport)(nil)
+
+type ManagedTransport struct {
+ epoch atomic.Pointer[transportEpoch]
+ rebuildAccess sync.Mutex
+ factory func() (innerTransport, error)
+ cheapRebuild bool
+
+ dialer N.Dialer
+ headers http.Header
+ host string
+ tag string
+}
+
+type transportEpoch struct {
+ transport innerTransport
+ active atomic.Int64
+ marked atomic.Bool
+ closeOnce sync.Once
+}
+
+type managedResponseBody struct {
+ body io.ReadCloser
+ release func()
+ once sync.Once
+}
+
+func (e *transportEpoch) tryClose() {
+ e.closeOnce.Do(func() {
+ e.transport.Close()
+ })
+}
+
+func (b *managedResponseBody) Read(p []byte) (int, error) {
+ return b.body.Read(p)
+}
+
+func (b *managedResponseBody) Close() error {
+ err := b.body.Close()
+ b.once.Do(b.release)
+ return err
+}
+
+func (t *ManagedTransport) getEpoch() (*transportEpoch, error) {
+ epoch := t.epoch.Load()
+ if epoch != nil {
+ return epoch, nil
+ }
+ t.rebuildAccess.Lock()
+ defer t.rebuildAccess.Unlock()
+ epoch = t.epoch.Load()
+ if epoch != nil {
+ return epoch, nil
+ }
+ inner, err := t.factory()
+ if err != nil {
+ return nil, err
+ }
+ epoch = &transportEpoch{transport: inner}
+ t.epoch.Store(epoch)
+ return epoch, nil
+}
+
+func (t *ManagedTransport) acquireEpoch() (*transportEpoch, error) {
+ for {
+ epoch, err := t.getEpoch()
+ if err != nil {
+ return nil, err
+ }
+ epoch.active.Add(1)
+ if epoch == t.epoch.Load() {
+ return epoch, nil
+ }
+ t.releaseEpoch(epoch)
+ }
+}
+
+func (t *ManagedTransport) releaseEpoch(epoch *transportEpoch) {
+ if epoch.active.Add(-1) == 0 && epoch.marked.Load() {
+ epoch.tryClose()
+ }
+}
+
+func (t *ManagedTransport) retireEpoch(epoch *transportEpoch) {
+ if epoch == nil {
+ return
+ }
+ epoch.marked.Store(true)
+ if epoch.active.Load() == 0 {
+ epoch.tryClose()
+ }
+}
+
+func (t *ManagedTransport) RoundTrip(request *http.Request) (*http.Response, error) {
+ epoch, err := t.acquireEpoch()
+ if err != nil {
+ return nil, E.Cause(err, "rebuild http transport")
+ }
+ if t.tag != "" {
+ if transportTag, loaded := transportTagFromContext(request.Context()); loaded && transportTag == t.tag {
+ t.releaseEpoch(epoch)
+ return nil, E.New("HTTP request loopback in transport[", t.tag, "]")
+ }
+ request = request.Clone(contextWithTransportTag(request.Context(), t.tag))
+ } else if len(t.headers) > 0 || t.host != "" {
+ request = request.Clone(request.Context())
+ }
+ applyHeaders(request, t.headers, t.host)
+ response, roundTripErr := epoch.transport.RoundTrip(request)
+ if roundTripErr != nil || response == nil || response.Body == nil {
+ t.releaseEpoch(epoch)
+ return response, roundTripErr
+ }
+ response.Body = &managedResponseBody{
+ body: response.Body,
+ release: func() { t.releaseEpoch(epoch) },
+ }
+ return response, roundTripErr
+}
+
+func (t *ManagedTransport) CloseIdleConnections() {
+ oldEpoch := t.epoch.Swap(nil)
+ if oldEpoch == nil {
+ return
+ }
+ oldEpoch.transport.CloseIdleConnections()
+ t.retireEpoch(oldEpoch)
+}
+
+func (t *ManagedTransport) Reset() {
+ oldEpoch := t.epoch.Swap(nil)
+ if t.cheapRebuild {
+ t.rebuildAccess.Lock()
+ if t.epoch.Load() == nil {
+ inner, err := t.factory()
+ if err == nil {
+ t.epoch.Store(&transportEpoch{transport: inner})
+ }
+ }
+ t.rebuildAccess.Unlock()
+ }
+ t.retireEpoch(oldEpoch)
+}
+
+func (t *ManagedTransport) close() error {
+ epoch := t.epoch.Swap(nil)
+ if epoch != nil {
+ return epoch.transport.Close()
+ }
+ return nil
+}
+
+var _ adapter.HTTPTransport = (*sharedRef)(nil)
+
+type sharedRef struct {
+ managed *ManagedTransport
+ shared *sharedState
+ idle atomic.Bool
+}
+
+type sharedState struct {
+ activeRefs atomic.Int32
+}
+
+func newSharedRef(managed *ManagedTransport, shared *sharedState) *sharedRef {
+ shared.activeRefs.Add(1)
+ return &sharedRef{
+ managed: managed,
+ shared: shared,
+ }
+}
+
+func (r *sharedRef) RoundTrip(request *http.Request) (*http.Response, error) {
+ if r.idle.CompareAndSwap(true, false) {
+ r.shared.activeRefs.Add(1)
+ }
+ return r.managed.RoundTrip(request)
+}
+
+func (r *sharedRef) CloseIdleConnections() {
+ if r.idle.CompareAndSwap(false, true) {
+ if r.shared.activeRefs.Add(-1) == 0 {
+ r.managed.CloseIdleConnections()
+ }
+ }
+}
+
+func (r *sharedRef) Reset() {
+ r.managed.Reset()
+}
diff --git a/common/httpclient/manager.go b/common/httpclient/manager.go
new file mode 100644
index 0000000000..614e4f83bd
--- /dev/null
+++ b/common/httpclient/manager.go
@@ -0,0 +1,179 @@
+package httpclient
+
+import (
+ "context"
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+)
+
+var (
+ _ adapter.HTTPClientManager = (*Manager)(nil)
+ _ adapter.LifecycleService = (*Manager)(nil)
+)
+
+type Manager struct {
+ ctx context.Context
+ logger log.ContextLogger
+ access sync.Mutex
+ defines map[string]option.HTTPClient
+ sharedTransports map[string]*sharedManagedTransport
+ managedTransports []*ManagedTransport
+ defaultTag string
+ defaultTransport *sharedManagedTransport
+ defaultTransportFallback func() (*ManagedTransport, error)
+}
+
+type sharedManagedTransport struct {
+ managed *ManagedTransport
+ shared *sharedState
+}
+
+func NewManager(ctx context.Context, logger log.ContextLogger, clients []option.HTTPClient, defaultHTTPClient string) *Manager {
+ defines := make(map[string]option.HTTPClient, len(clients))
+ for _, client := range clients {
+ defines[client.Tag] = client
+ }
+ defaultTag := defaultHTTPClient
+ if defaultTag == "" && len(clients) > 0 {
+ defaultTag = clients[0].Tag
+ }
+ return &Manager{
+ ctx: ctx,
+ logger: logger,
+ defines: defines,
+ sharedTransports: make(map[string]*sharedManagedTransport),
+ defaultTag: defaultTag,
+ }
+}
+
+func (m *Manager) Initialize(defaultTransportFallback func() (*ManagedTransport, error)) {
+ m.defaultTransportFallback = defaultTransportFallback
+}
+
+func (m *Manager) Name() string {
+ return "http-client"
+}
+
+func (m *Manager) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ if m.defaultTag != "" {
+ sharedTransport, err := m.resolveShared(m.defaultTag)
+ if err != nil {
+ return E.Cause(err, "resolve default http client")
+ }
+ m.defaultTransport = sharedTransport
+ }
+ return nil
+}
+
+func (m *Manager) DefaultTransport() adapter.HTTPTransport {
+ m.access.Lock()
+ defer m.access.Unlock()
+ if m.defaultTransport == nil && m.defaultTransportFallback != nil {
+ transport, err := m.defaultTransportFallback()
+ if err != nil {
+ m.logger.Error(E.Cause(err, "create default http client"))
+ return nil
+ }
+ m.managedTransports = append(m.managedTransports, transport)
+ m.defaultTransport = &sharedManagedTransport{
+ managed: transport,
+ shared: &sharedState{},
+ }
+ }
+ if m.defaultTransport == nil {
+ return nil
+ }
+ return newSharedRef(m.defaultTransport.managed, m.defaultTransport.shared)
+}
+
+func (m *Manager) ResolveTransport(ctx context.Context, logger logger.ContextLogger, options option.HTTPClientOptions) (adapter.HTTPTransport, error) {
+ if options.Tag != "" {
+ if options.ResolveOnDetour {
+ define, loaded := m.defines[options.Tag]
+ if !loaded {
+ return nil, E.New("http_client not found: ", options.Tag)
+ }
+ resolvedOptions := define.Options()
+ resolvedOptions.ResolveOnDetour = true
+ transport, err := NewTransport(ctx, logger, options.Tag, resolvedOptions)
+ if err != nil {
+ return nil, err
+ }
+ m.trackTransport(transport)
+ return transport, nil
+ }
+ sharedTransport, err := m.resolveShared(options.Tag)
+ if err != nil {
+ return nil, err
+ }
+ return newSharedRef(sharedTransport.managed, sharedTransport.shared), nil
+ }
+ transport, err := NewTransport(ctx, logger, "", options)
+ if err != nil {
+ return nil, err
+ }
+ m.trackTransport(transport)
+ return transport, nil
+}
+
+func (m *Manager) trackTransport(transport *ManagedTransport) {
+ m.access.Lock()
+ defer m.access.Unlock()
+ m.managedTransports = append(m.managedTransports, transport)
+}
+
+func (m *Manager) resolveShared(tag string) (*sharedManagedTransport, error) {
+ m.access.Lock()
+ defer m.access.Unlock()
+ if sharedTransport, loaded := m.sharedTransports[tag]; loaded {
+ return sharedTransport, nil
+ }
+ define, loaded := m.defines[tag]
+ if !loaded {
+ return nil, E.New("http_client not found: ", tag)
+ }
+ transport, err := NewTransport(m.ctx, m.logger, tag, define.Options())
+ if err != nil {
+ return nil, E.Cause(err, "create shared http_client[", tag, "]")
+ }
+ sharedTransport := &sharedManagedTransport{
+ managed: transport,
+ shared: &sharedState{},
+ }
+ m.sharedTransports[tag] = sharedTransport
+ m.managedTransports = append(m.managedTransports, transport)
+ return sharedTransport, nil
+}
+
+func (m *Manager) ResetNetwork() {
+ m.access.Lock()
+ defer m.access.Unlock()
+ for _, transport := range m.managedTransports {
+ transport.Reset()
+ }
+}
+
+func (m *Manager) Close() error {
+ m.access.Lock()
+ defer m.access.Unlock()
+ if m.managedTransports == nil {
+ return nil
+ }
+ var err error
+ for _, transport := range m.managedTransports {
+ err = E.Append(err, transport.close(), func(err error) error {
+ return E.Cause(err, "close http client")
+ })
+ }
+ m.managedTransports = nil
+ m.sharedTransports = nil
+ return err
+}
diff --git a/common/interrupt/conn.go b/common/interrupt/conn.go
index 6a6d31c68b..5ebbff8a9e 100644
--- a/common/interrupt/conn.go
+++ b/common/interrupt/conn.go
@@ -3,6 +3,7 @@ package interrupt
import (
"net"
+ N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/x/list"
)
@@ -30,7 +31,8 @@ func (c *Conn) Close() error {
c.group.access.Lock()
defer c.group.access.Unlock()
c.group.connections.Remove(c.element)
- return c.Conn.Close()
+ go c.Conn.Close()
+ return nil
}
func (c *Conn) ReaderReplaceable() bool {
@@ -73,3 +75,32 @@ func (c *PacketConn) WriterReplaceable() bool {
func (c *PacketConn) Upstream() any {
return c.PacketConn
}
+
+type SingPacketConn struct {
+ N.PacketConn
+ group *Group
+ element *list.Element[*groupConnItem]
+}
+
+/*func (c *SingPacketConn) MarkAsInternal() {
+ c.element.Value.internal = true
+}*/
+
+func (c *SingPacketConn) Close() error {
+ c.group.access.Lock()
+ defer c.group.access.Unlock()
+ c.group.connections.Remove(c.element)
+ return c.PacketConn.Close()
+}
+
+func (c *SingPacketConn) ReaderReplaceable() bool {
+ return true
+}
+
+func (c *SingPacketConn) WriterReplaceable() bool {
+ return true
+}
+
+func (c *SingPacketConn) Upstream() any {
+ return c.PacketConn
+}
diff --git a/common/interrupt/group.go b/common/interrupt/group.go
index ba2e7f739b..bd3fbb0a2a 100644
--- a/common/interrupt/group.go
+++ b/common/interrupt/group.go
@@ -5,6 +5,7 @@ import (
"net"
"sync"
+ N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/x/list"
)
@@ -36,6 +37,13 @@ func (g *Group) NewPacketConn(conn net.PacketConn, isExternal bool) net.PacketCo
return &PacketConn{PacketConn: conn, group: g, element: item}
}
+func (g *Group) NewSingPacketConn(conn N.PacketConn, isExternal bool) N.PacketConn {
+ g.access.Lock()
+ defer g.access.Unlock()
+ item := g.connections.PushBack(&groupConnItem{conn, isExternal})
+ return &SingPacketConn{PacketConn: conn, group: g, element: item}
+}
+
func (g *Group) Interrupt(interruptExternalConnections bool) {
g.access.Lock()
defer g.access.Unlock()
diff --git a/common/listener/listener.go b/common/listener/listener.go
index cc27a62e18..4ca82b6203 100644
--- a/common/listener/listener.go
+++ b/common/listener/listener.go
@@ -25,9 +25,9 @@ type Listener struct {
logger logger.ContextLogger
network []string
listenOptions option.ListenOptions
- connHandler adapter.ConnectionHandlerEx
- packetHandler adapter.PacketHandlerEx
- oobPacketHandler adapter.OOBPacketHandlerEx
+ connHandler adapter.ConnectionHandler
+ packetHandler adapter.PacketHandler
+ oobPacketHandler adapter.OOBPacketHandler
threadUnsafePacketWriter bool
disablePacketOutput bool
setSystemProxy bool
@@ -48,9 +48,9 @@ type Options struct {
Logger logger.ContextLogger
Network []string
Listen option.ListenOptions
- ConnectionHandler adapter.ConnectionHandlerEx
- PacketHandler adapter.PacketHandlerEx
- OOBPacketHandler adapter.OOBPacketHandlerEx
+ ConnectionHandler adapter.ConnectionHandler
+ PacketHandler adapter.PacketHandler
+ OOBPacketHandler adapter.OOBPacketHandler
ThreadUnsafePacketWriter bool
DisablePacketOutput bool
SetSystemProxy bool
diff --git a/common/listener/listener_tcp.go b/common/listener/listener_tcp.go
index 54d84a6b7b..8cfdd6e6c3 100644
--- a/common/listener/listener_tcp.go
+++ b/common/listener/listener_tcp.go
@@ -106,6 +106,6 @@ func (l *Listener) loopTCPIn() {
metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
ctx := log.ContextWithNewID(l.ctx)
l.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
- go l.connHandler.NewConnectionEx(ctx, conn, metadata, nil)
+ go l.connHandler.NewConnection(ctx, conn, metadata, nil)
}
}
diff --git a/common/listener/listener_udp.go b/common/listener/listener_udp.go
index e689c8bb67..ed48a75553 100644
--- a/common/listener/listener_udp.go
+++ b/common/listener/listener_udp.go
@@ -11,6 +11,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/redir"
"github.com/sagernet/sing/common/buf"
+ sBufio "github.com/sagernet/sing/common/bufio"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
@@ -18,6 +19,8 @@ import (
"github.com/sagernet/sing/service"
)
+const udpOutputBatchSize = 128
+
func (l *Listener) ListenUDP() (net.PacketConn, error) {
bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort)
var listenConfig net.ListenConfig
@@ -98,6 +101,15 @@ func (l *Listener) PacketWriter() N.PacketWriter {
func (l *Listener) loopUDPIn() {
defer close(l.packetOutboundClosed)
+ if l.oobPacketHandler == nil {
+ if batchHandler, isBatchHandler := l.packetHandler.(adapter.PacketBatchHandler); isBatchHandler {
+ packetConn := sBufio.NewPacketConn(l.udpConn)
+ if readWaiter, created := sBufio.CreatePacketBatchReadWaiter(packetConn); created {
+ l.loopUDPInBatch(batchHandler, readWaiter)
+ return
+ }
+ }
+ }
var buffer *buf.Buffer
if !l.threadUnsafePacketWriter {
buffer = buf.NewPacket()
@@ -126,7 +138,7 @@ func (l *Listener) loopUDPIn() {
return
}
buffer.Truncate(n)
- l.oobPacketHandler.NewPacketEx(buffer, oob[:oobN], M.SocksaddrFromNetIP(addr).Unwrap())
+ l.oobPacketHandler.NewPacket(buffer, oob[:oobN], M.SocksaddrFromNetIP(addr).Unwrap())
}
} else {
for {
@@ -148,37 +160,82 @@ func (l *Listener) loopUDPIn() {
return
}
buffer.Truncate(n)
- l.packetHandler.NewPacketEx(buffer, M.SocksaddrFromNetIP(addr).Unwrap())
+ l.packetHandler.NewPacket(buffer, M.SocksaddrFromNetIP(addr).Unwrap())
+ }
+ }
+}
+
+func (l *Listener) loopUDPInBatch(handler adapter.PacketBatchHandler, readWaiter N.PacketBatchReadWaiter) {
+ readWaitOptions := N.ReadWaitOptions{
+ BatchSize: sBufio.DefaultPacketReadBatchSize,
+ }
+ readWaiter.InitializeReadWaiter(readWaitOptions)
+ for {
+ buffers, sources, err := readWaiter.WaitReadPackets()
+ if err != nil {
+ buf.ReleaseMulti(buffers)
+ if l.shutdown.Load() && E.IsClosed(err) {
+ return
+ }
+ l.udpConn.Close()
+ l.logger.Error("udp listener closed: ", err)
+ return
}
+ handler.NewPacketBatch(buffers, sources)
}
}
func (l *Listener) loopUDPOut() {
+ packetConn := sBufio.NewPacketConn(l.udpConn)
+ batchWriter := sBufio.NewPacketBatchWriter(packetConn)
+ packets := make([]*N.PacketBuffer, 0, udpOutputBatchSize)
+ buffers := make([]*buf.Buffer, 0, udpOutputBatchSize)
+ destinations := make([]M.Socksaddr, 0, udpOutputBatchSize)
for {
select {
case packet := <-l.packetOutbound:
- destination := packet.Destination.AddrPort()
- _, err := l.udpConn.WriteToUDPAddrPort(packet.Buffer.Bytes(), destination)
- packet.Buffer.Release()
- N.PutPacketBuffer(packet)
- if err != nil {
- if l.shutdown.Load() && E.IsClosed(err) {
- return
- }
- l.logger.Error("udp listener write back: ", destination, ": ", err)
- continue
- }
- continue
+ packets = append(packets, packet)
case <-l.packetOutboundClosed:
+ l.releasePacketOutbound()
+ return
}
- for {
+ drain:
+ for len(packets) < udpOutputBatchSize {
select {
case packet := <-l.packetOutbound:
- packet.Buffer.Release()
- N.PutPacketBuffer(packet)
+ packets = append(packets, packet)
default:
+ break drain
+ }
+ }
+ for _, packet := range packets {
+ buffers = append(buffers, packet.Buffer)
+ destinations = append(destinations, packet.Destination)
+ }
+ err := batchWriter.WritePacketBatch(buffers, destinations)
+ for _, packet := range packets {
+ N.PutPacketBuffer(packet)
+ }
+ packets = packets[:0]
+ buffers = buffers[:0]
+ destinations = destinations[:0]
+ if err != nil {
+ if l.shutdown.Load() && E.IsClosed(err) {
return
}
+ l.logger.Error("udp listener write back: ", err)
+ }
+ }
+}
+
+func (l *Listener) releasePacketOutbound() {
+ for {
+ select {
+ case packet := <-l.packetOutbound:
+ packet.Buffer.Release()
+ N.PutPacketBuffer(packet)
+ default:
+ return
}
}
}
@@ -203,5 +260,30 @@ func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr)
}
}
+func (w *packetWriter) WritePacketBatch(buffers []*buf.Buffer, destinations []M.Socksaddr) error {
+ if len(buffers) == 0 || len(buffers) != len(destinations) {
+ buf.ReleaseMulti(buffers)
+ return os.ErrInvalid
+ }
+ for index, buffer := range buffers {
+ packet := N.NewPacketBuffer()
+ packet.Buffer = buffer
+ packet.Destination = destinations[index]
+ select {
+ case w.packetOutbound <- packet:
+ default:
+ buffer.Release()
+ N.PutPacketBuffer(packet)
+ buf.ReleaseMulti(buffers[index+1:])
+ if w.shutdown.Load() {
+ return os.ErrClosed
+ }
+ w.logger.Trace("dropped packet batch to ", destinations[index])
+ return nil
+ }
+ }
+ return nil
+}
+
func (w *packetWriter) WriteIsThreadUnsafe() {
}
diff --git a/common/monitoring/brodcaster.go b/common/monitoring/brodcaster.go
new file mode 100644
index 0000000000..b7cf4f0bb3
--- /dev/null
+++ b/common/monitoring/brodcaster.go
@@ -0,0 +1,92 @@
+package monitoring
+
+import (
+ "context"
+ "sync"
+)
+
+type Broadcaster[T any] struct {
+ ctx context.Context
+ cancel context.CancelFunc
+
+ mu sync.RWMutex
+ subs map[chan T]struct{}
+ once sync.Once
+}
+
+func NewBroadcaster[T any](parent context.Context) *Broadcaster[T] {
+ ctx, cancel := context.WithCancel(parent)
+ b := &Broadcaster[T]{
+ ctx: ctx,
+ cancel: cancel,
+ subs: make(map[chan T]struct{}),
+ }
+
+ go b.watchContext()
+ return b
+}
+
+func (b *Broadcaster[T]) watchContext() {
+ <-b.ctx.Done()
+ b.closeAll()
+}
+
+func (b *Broadcaster[T]) Subscribe(buffer int) <-chan T {
+ ch := make(chan T, buffer)
+
+ b.mu.Lock()
+ defer b.mu.Unlock()
+
+ select {
+ case <-b.ctx.Done():
+ close(ch)
+ default:
+ b.subs[ch] = struct{}{}
+ }
+
+ return ch
+}
+
+func (b *Broadcaster[T]) Unsubscribe(ch <-chan T) {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+
+ for sub := range b.subs {
+ if sub == ch {
+ delete(b.subs, sub)
+ close(sub)
+ return
+ }
+ }
+}
+
+func (b *Broadcaster[T]) Publish(event T) {
+ b.mu.RLock()
+ defer b.mu.RUnlock()
+
+ for ch := range b.subs {
+ select {
+ case ch <- event:
+ case <-b.ctx.Done():
+ return
+ default:
+ // slow subscriber → drop event
+ }
+ }
+}
+
+func (b *Broadcaster[T]) Close() {
+ b.once.Do(func() {
+ b.cancel()
+ })
+}
+
+func (b *Broadcaster[T]) closeAll() {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+
+ for ch := range b.subs {
+ close(ch)
+ }
+ b.subs = nil
+}
diff --git a/common/monitoring/outbound_monitoring.go b/common/monitoring/outbound_monitoring.go
new file mode 100644
index 0000000000..75ed268078
--- /dev/null
+++ b/common/monitoring/outbound_monitoring.go
@@ -0,0 +1,1067 @@
+package monitoring
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net"
+ "sort"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/urltest"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/service"
+
+ "github.com/sagernet/sing-box/hiddify/ipinfo"
+ "github.com/sagernet/sing/common/x/list"
+
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/json/badoption"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service/pause"
+)
+
+const TimeoutDelay uint16 = 65535
+
+var _ adapter.ConnectionTracker = (*OutboundMonitoring)(nil)
+var _ adapter.LifecycleService = (*OutboundMonitoring)(nil)
+var _ adapter.InterfaceUpdateListener = (*OutboundMonitoring)(nil)
+
+const (
+ defaultWorkerCount = 10
+ defaultDebounceWindow = 500 * time.Millisecond
+ defaultURLTestTimeout = 5 * time.Second
+ defaultIdleTimeout = 10 * time.Minute
+ defaultInterval = 5 * time.Minute
+ defaultURLTest = "https://www.gstatic.com/generate_204"
+)
+
+// func RegisterService(registry *boxService.Registry) {
+// boxService.Register[option.MonitoringOptions](registry, C.TypeOutboundMonitor, func(ctx context.Context, logger log.ContextLogger, tag string, options option.MonitoringOptions) (adapter.Service, error) {
+// return NewOutboundMonitoring(ctx, logger, tag, options)
+// })
+// }
+
+func Get(ctx context.Context) *OutboundMonitoring {
+ return service.PtrFromContext[OutboundMonitoring](ctx)
+}
+
+// OutboundMonitoring orchestrates URL testing and traffic sampling for outbounds.
+type OutboundMonitoring struct {
+ endpointManager adapter.EndpointManager
+ outboundManager adapter.OutboundManager
+ logger log.ContextLogger
+ cache adapter.CacheFile
+ ctx context.Context
+ cancel context.CancelFunc
+ tag string
+ pause pause.Manager
+ pauseCallback *list.Element[pause.Callback]
+ started bool
+ urls []string
+ currentLinkIndex atomic.Uint32
+ access sync.Mutex
+ idleTimeout time.Duration
+ lastActive common.TypedValue[time.Time]
+ workersRunning atomic.Bool
+ mainInterval time.Duration
+ debounceWindow time.Duration
+ urlTestTimeout time.Duration
+ workersCount int
+ history adapter.URLTestHistoryStorage
+
+ mainTicker *time.Ticker
+
+ priorityQueue chan *testTask
+ normalQueue chan *testTask
+
+ outbounds map[string]*outboundState
+ groups map[string]*groupState
+
+ cacheDirty atomic.Bool
+
+ cycleSeq uint64
+ cycleRunning atomic.Bool
+
+ workerWG sync.WaitGroup
+ schedulerWG sync.WaitGroup
+ closerOnce sync.Once
+}
+
+// InterfaceUpdated implements [adapter.InterfaceUpdateListener].
+func (m *OutboundMonitoring) InterfaceUpdated() {
+ m.startCycleOnce()
+}
+
+// Name implements [adapter.LifecycleService].
+func (m *OutboundMonitoring) Name() string {
+ return "outbound-monitoring"
+}
+
+func (m *OutboundMonitoring) OutboundsHistory(groupTag string) map[string]*adapter.URLTestHistory {
+
+ histories := make(map[string]*adapter.URLTestHistory)
+
+ grp, ok := m.groups[groupTag]
+ if !ok {
+ return histories
+ }
+ //m.logger.Debug("collecting history for group ", groupTag, " with ", len(grp.outbounds), " outbounds")
+ for outboundTag := range grp.outbounds {
+ histories[outboundTag] = m.getUrlTest(outboundTag)
+ // m.logger.Error("checking history for outbound ", outboundTag)
+
+ }
+ return histories
+}
+
+func (m *OutboundMonitoring) getUrlTest(outboundTag string) *adapter.URLTestHistory {
+ state, ok := m.outbounds[outboundTag]
+ if !ok {
+ return nil
+ }
+
+ if grp, ok := m.groups[outboundTag]; ok {
+ realtag := RealTag(state.outbound)
+ //m.logger.Debug("outbound ", outboundTag, " is a group, checking group ", grp.tag, " with real tag ", realtag)
+ if realtag != "" && realtag != outboundTag {
+ return m.getUrlTest(realtag)
+ }
+
+ return m.getMinGroupOutboundHistory(grp.tag)
+
+ }
+ state.mu.Lock()
+ his := state.history
+ his.IsFromCache = state.from_cache
+ state.mu.Unlock()
+ return &his
+
+}
+
+func (m *OutboundMonitoring) getMinGroupOutboundHistory(groupTag string) *adapter.URLTestHistory {
+ grp, ok := m.groups[groupTag]
+ if !ok {
+ return nil
+ }
+ var minHis *adapter.URLTestHistory
+ var minHisFromCache *adapter.URLTestHistory
+ for outboundTag := range grp.outbounds {
+ his := m.getUrlTest(outboundTag)
+ if his == nil || his.Delay == 0 {
+ continue
+ }
+ if !his.IsFromCache {
+ if minHis == nil {
+ minHis = his
+ } else if his.Delay < minHis.Delay {
+ minHis.Delay = his.Delay
+ minHis.IpInfo = his.IpInfo
+ } else if minHis.IpInfo == nil {
+ minHis.IpInfo = his.IpInfo
+ }
+ } else {
+ if minHisFromCache == nil {
+ minHisFromCache = his
+ } else if his.Delay < minHisFromCache.Delay {
+ minHisFromCache.Delay = his.Delay
+ minHisFromCache.IpInfo = his.IpInfo
+ } else if minHisFromCache.IpInfo == nil {
+ minHisFromCache.IpInfo = his.IpInfo
+ }
+ }
+ }
+
+ final := minHis
+ if minHis == nil || minHis.Delay >= TimeoutDelay {
+ final = minHisFromCache
+ } else if minHisFromCache != nil && minHis.IpInfo == nil {
+ final.IpInfo = minHisFromCache.IpInfo
+ }
+
+ return final
+
+}
+
+func (m *OutboundMonitoring) RoutedConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) net.Conn {
+ m.Touch()
+ return conn
+}
+func (m *OutboundMonitoring) RoutedPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, matchedRule adapter.Rule, matchOutbound adapter.Outbound) N.PacketConn {
+ m.Touch()
+ return conn
+}
+
+// NewOutboundMonitoring creates and starts a monitoring instance.
+func NewOutboundMonitoring(ctx context.Context, logger log.ContextLogger, options option.MonitoringOptions) (*OutboundMonitoring, error) {
+ if options.Interval <= 0 {
+ options.Interval = badoption.Duration(defaultInterval)
+ }
+ if options.Workers <= 0 {
+ options.Workers = defaultWorkerCount
+ }
+ if options.URLTestTimeout <= 0 {
+ options.URLTestTimeout = badoption.Duration(defaultURLTestTimeout)
+ }
+ if options.IdleTimeout <= 0 {
+ options.IdleTimeout = badoption.Duration(defaultIdleTimeout)
+ }
+ if options.DebounceWindow <= 0 {
+ options.DebounceWindow = badoption.Duration(defaultDebounceWindow)
+ }
+
+ cloned := append([]string(nil), options.URLs...)
+ if len(cloned) == 0 {
+ cloned = []string{defaultURLTest}
+ }
+
+ var history adapter.URLTestHistoryStorage
+ if historyFromCtx := service.PtrFromContext[urltest.HistoryStorage](ctx); historyFromCtx != nil {
+ history = historyFromCtx
+ } else if clashServer := service.FromContext[adapter.ClashServer](ctx); clashServer != nil {
+ history = clashServer.HistoryStorage()
+ } else {
+ history = urltest.NewHistoryStorage()
+ }
+
+ ctx, cancel := context.WithCancel(ctx)
+ m := &OutboundMonitoring{
+ ctx: ctx,
+ cancel: cancel,
+ urls: cloned,
+ pause: service.FromContext[pause.Manager](ctx),
+ started: false,
+ logger: logger,
+ outboundManager: service.FromContext[adapter.OutboundManager](ctx),
+ endpointManager: service.FromContext[adapter.EndpointManager](ctx),
+
+ history: history,
+
+ mainInterval: options.Interval.Build(),
+ idleTimeout: options.IdleTimeout.Build(),
+ workersCount: options.Workers,
+ urlTestTimeout: options.URLTestTimeout.Build(),
+ debounceWindow: options.DebounceWindow.Build(),
+
+ priorityQueue: make(chan *testTask, 1000),
+ normalQueue: make(chan *testTask, 10000),
+ outbounds: make(map[string]*outboundState),
+ groups: make(map[string]*groupState),
+ }
+
+ return m, nil
+}
+
+func (m *OutboundMonitoring) Start(stage adapter.StartStage) error {
+ m.logger.Info("starting outbound monitoring ", stage)
+ switch stage {
+ case adapter.StartStateInitialize:
+ m.cache = service.FromContext[adapter.CacheFile](m.ctx)
+
+ for _, outbound := range m.outboundManager.Outbounds() {
+ // if _, ok := outbound.(adapter.OutboundGroup); !ok {
+ m.outbounds[outbound.Tag()] = &outboundState{groupTags: []string{}, invalid: true, outbound: outbound, dependencies: outbound.Dependencies()}
+ // }
+ //m.logger.Info("registered outbound for monitoring: ", outbound.Tag())
+ }
+ for _, outbound := range m.endpointManager.Endpoints() {
+ // if _, ok := outbound.(adapter.OutboundGroup); !ok {
+ m.outbounds[outbound.Tag()] = &outboundState{groupTags: []string{}, invalid: true, outbound: outbound, dependencies: outbound.Dependencies()}
+ // }
+ //m.logger.Info("registered outbound for monitoring: ", outbound.Tag())
+ }
+ for tag, outbound := range m.outbounds {
+ for _, dep := range outbound.dependencies {
+ m.outbounds[dep].dependenciesInverse = append(m.outbounds[dep].dependenciesInverse, tag)
+ }
+ }
+
+ m.logger.Info("registered ", len(m.outbounds), " outbounds for monitoring")
+ grp := m.makeGroup("")
+ for tag := range m.outbounds {
+ grp.outbounds[tag] = struct{}{}
+ m.outbounds[tag].groupTags = append(m.outbounds[tag].groupTags, "")
+ }
+ for _, outbound := range m.outboundManager.Outbounds() {
+ if og, ok := outbound.(adapter.OutboundGroup); ok {
+ groupTag := og.Tag()
+ grp := m.makeGroup(groupTag)
+ for _, tag := range og.All() {
+ if _, exists := m.outbounds[tag]; !exists {
+ return errors.New("outbound monitoring: outbound not found: " + tag + " in group " + groupTag)
+ }
+ grp.outbounds[tag] = struct{}{}
+ m.outbounds[tag].groupTags = append(m.outbounds[tag].groupTags, groupTag)
+ }
+
+ //m.logger.Info("registered outbound group for monitoring: ", groupTag, " with ", len(og.All()), " outbounds")
+
+ }
+ }
+ m.logger.Info("registered ", len(m.groups), " outbound groups for monitoring")
+ m.loadHistory()
+ case adapter.StartStatePostStart:
+ for i := 0; i < m.workersCount; i++ {
+ m.workerWG.Add(1)
+ go m.workerLoop()
+ }
+ for groupTag := range m.groups {
+ m.schedulerWG.Add(1)
+ go m.groupNotifierLoop(m.groups[groupTag])
+ }
+
+ m.started = true
+ m.Touch()
+ }
+
+ return nil
+}
+
+func (m *OutboundMonitoring) startTimerWorkers() {
+ if !m.workersRunning.CompareAndSwap(false, true) {
+ return
+ }
+ m.mainTicker = time.NewTicker(m.mainInterval)
+
+ m.pauseCallback = pause.RegisterTicker(m.pause, m.mainTicker, m.mainInterval, nil)
+ m.schedulerWG.Add(1)
+ go m.scheduleLoop()
+}
+func (m *OutboundMonitoring) stopTimerWorkers() {
+ if !m.workersRunning.CompareAndSwap(true, false) {
+ return
+ }
+ m.mainTicker.Stop()
+ m.mainTicker = nil
+ if m.cacheDirty.Load() {
+ m.saveHistory()
+ }
+
+ m.pause.UnregisterCallback(m.pauseCallback)
+}
+
+func (m *OutboundMonitoring) SignalChange(outboundTag string) error {
+ if grp, ok := m.groups[outboundTag]; ok {
+ grp.notifyCh <- struct{}{}
+ return nil
+ }
+ state := m.getState(outboundTag)
+ if state == nil {
+ return errors.New("outbound not registered")
+ }
+ for _, groupTag := range state.groupTags {
+ if grp, ok := m.groups[groupTag]; ok {
+ grp.notifyCh <- struct{}{}
+ }
+ }
+ return nil
+
+}
+func (m *OutboundMonitoring) TestNow(outboundTag string) error {
+ m.testParents(outboundTag, true)
+ return m.testNow(outboundTag, true)
+}
+func (m *OutboundMonitoring) testNow(outboundTag string, priority bool) error {
+ m.logger.Info("testing outbound ", outboundTag, " with priority: ", priority)
+ if grp, ok := m.groups[outboundTag]; ok {
+ for tag := range grp.outbounds {
+ m.testNow(tag, false)
+ }
+ } else {
+ state := m.getState(outboundTag)
+ if state == nil {
+ return errors.New("outbound not registered")
+ }
+
+ task := &testTask{
+ outboundTag: outboundTag,
+ cycleID: m.cycleSeq,
+ priority: priority,
+ }
+
+ if !m.enqueueTask(task) {
+ // return errors.New("test already queued")
+ }
+ }
+ return nil
+}
+
+func (m *OutboundMonitoring) testParents(outboundTag string, first bool) {
+ state := m.getState(outboundTag)
+ if state == nil {
+ return
+ }
+ if _, ok := m.groups[outboundTag]; !ok && !first {
+ m.logger.Info("testing outbound ", outboundTag)
+ m.testNow(outboundTag, true)
+ }
+ for _, dep := range state.dependenciesInverse {
+ m.logger.Info("testing parent outbound ", dep, " of ", outboundTag)
+ m.testParents(dep, false)
+ }
+}
+
+// InvalidateTest marks the cached test result as invalid so it will be retested.
+func (m *OutboundMonitoring) InvalidateTest(outboundTag string) error {
+ state := m.getState(outboundTag)
+ if state == nil {
+ return errors.New("outbound not registered")
+ }
+ state.mu.Lock()
+ state.invalid = true
+ state.mu.Unlock()
+
+ m.enqueueTask(&testTask{
+ outboundTag: outboundTag,
+ cycleID: m.cycleSeq,
+ priority: true,
+ })
+
+ return nil
+}
+
+func (m *OutboundMonitoring) SubscribeGroup(groupTag string) (observer <-chan GroupEvent, err error) {
+
+ if g, ok := m.groups[groupTag]; ok {
+ return g.observer.Subscribe(1), nil
+ }
+ return nil, E.New("group not found ", groupTag)
+}
+func (m *OutboundMonitoring) UnsubscribeGroup(groupTag string, observer <-chan GroupEvent) (err error) {
+ if g, ok := m.groups[groupTag]; ok {
+ g.observer.Unsubscribe(observer)
+ return nil
+ }
+ return E.New("group not found ", groupTag)
+}
+
+func (m *OutboundMonitoring) Close() error {
+ m.closerOnce.Do(func() {
+ m.stopTimerWorkers()
+
+ // close(m.priorityQueue)
+ // close(m.normalQueue)
+ for _, g := range m.groups {
+ if g.observer != nil {
+ g.observer.Close()
+ }
+ }
+ m.cancel()
+ m.workerWG.Wait()
+ m.schedulerWG.Wait()
+
+ })
+ return nil
+}
+
+func (m *OutboundMonitoring) scheduleLoop() {
+ m.logger.Info("outbound monitoring schedule loop started")
+ m.startCycleOnce()
+ ticker := m.mainTicker
+ for {
+ select {
+ case <-m.ctx.Done():
+ m.schedulerWG.Done()
+ return
+ case <-ticker.C:
+ if time.Since(m.lastActive.Load()) > m.idleTimeout {
+ m.schedulerWG.Done()
+ m.stopTimerWorkers()
+ return
+ }
+ m.startCycleOnce()
+ }
+ }
+}
+
+func (m *OutboundMonitoring) workerLoop() {
+
+ defer m.workerWG.Done()
+ for {
+
+ select {
+ case <-m.ctx.Done():
+ return
+ case task := <-m.priorityQueue:
+ m.executeTask(task) //for prioritising tasks, we execute them immediately
+ default:
+ select {
+ case <-m.ctx.Done():
+ return
+ case task := <-m.priorityQueue:
+ m.executeTask(task)
+ case task := <-m.normalQueue:
+ m.executeTask(task)
+ }
+ }
+ }
+}
+
+func (m *OutboundMonitoring) executeTask(task *testTask) {
+ select {
+ case <-m.ctx.Done():
+ return
+ default:
+ }
+
+ state := m.outbounds[task.outboundTag]
+ if state == nil {
+ return
+ }
+
+ state.mu.Lock()
+ state.testing = true
+ state.mu.Unlock()
+ defer func() {
+ state.mu.Lock()
+ state.testing = false
+ state.mu.Unlock()
+ }()
+ state.mu.Lock()
+ cycle := task.cycleID
+ state.mu.Unlock()
+
+ if cycle < 10 && !state.outbound.IsReady() {
+ m.logger.Info("outbound ", task.outboundTag, " is not ready, skipping test")
+ go func() {
+ select {
+ case <-m.ctx.Done():
+ return
+ case <-time.After(3 * time.Second):
+ }
+ state.mu.Lock()
+ task.cycleID++
+ state.mu.Unlock()
+ m.enqueueTask(task)
+ }()
+ return
+ }
+ done := make(chan struct{})
+ go func() {
+ defer close(done)
+ delay, err := m.tester(m.ctx, task.outboundTag)
+
+ outcome := testOutcome{
+ outboundTag: task.outboundTag,
+ history: delay,
+ err: err,
+ cycleID: task.cycleID,
+ priority: task.priority,
+ }
+
+ m.applyResult(outcome)
+ if task.resultCh != nil {
+ select {
+ case task.resultCh <- outcome:
+ case <-m.ctx.Done():
+ default:
+ }
+
+ }
+ }()
+ select {
+ case <-m.ctx.Done():
+ return
+ case <-done:
+ }
+
+}
+
+func (m *OutboundMonitoring) tester(parent context.Context, tag string) (adapter.URLTestHistory, error) {
+ out, ok := m.outbounds[tag]
+ if !ok {
+ return adapter.URLTestHistory{Delay: 0}, errors.New("outbound not registered")
+ }
+
+ idx := m.currentLinkIndex.Load()
+
+ ctx, cancel := context.WithTimeout(parent, m.urlTestTimeout)
+ defer cancel()
+
+ delay, err := urltest.URLTest(ctx, m.urls[idx], out.outbound)
+
+ his := adapter.URLTestHistory{
+ Time: time.Now(),
+ Delay: delay,
+ }
+ if err != nil || delay >= TimeoutDelay {
+ his.Delay = TimeoutDelay
+ m.logger.Warn("outbound ", tag, " URL test failed: ", err)
+ return his, err
+ }
+ select {
+ case <-parent.Done():
+ return his, parent.Err()
+ default:
+ }
+ if out.history.IpInfo == nil || out.from_cache {
+
+ ctx, cancel2 := context.WithTimeout(parent, m.urlTestTimeout)
+ defer cancel2()
+
+ newip, t, err := ipinfo.GetIpInfo(m.logger, ctx, out.outbound)
+ if err == nil {
+ his.IpInfo = mergeIpInfo(out.history.IpInfo, newip)
+ if t < his.Delay {
+ his.Delay = t
+ }
+ }
+ }
+ if his.IpInfo != nil {
+ m.logger.Info("outbound ", tag, " IP ", fmt.Sprint(his.IpInfo), " (", his.Delay, "ms): ", err)
+ } else {
+ m.logger.Info("outbound ", tag, " , IP: - (", his.Delay, "ms)")
+ }
+ return his, nil
+}
+
+func (m *OutboundMonitoring) startCycleOnce() bool {
+ if !m.cycleRunning.CompareAndSwap(false, true) {
+ return false
+ }
+ go func() {
+ defer m.cycleRunning.Store(false)
+ m.logger.Info("starting regular outbound monitoring cycle")
+ m.runCycle()
+ }()
+ return true
+}
+
+func (m *OutboundMonitoring) runCycle() {
+ cycleID := atomic.AddUint64(&m.cycleSeq, 1)
+ tags := m.collectCycleTargets()
+
+ if len(tags) == 0 {
+ return
+ }
+ defer func() {
+ if m.cacheDirty.Swap(false) {
+ m.saveHistory()
+ }
+ }()
+
+ for idx, _ := range m.urls {
+ outcomes := m.runStage(cycleID, tags)
+ success := 0
+ for _, result := range outcomes {
+ if result.err == nil {
+ success++
+ }
+ }
+ if success > 0 || idx == len(m.urls)-1 {
+ return
+ }
+ m.currentLinkIndex.Store((m.currentLinkIndex.Load() + 1) % uint32(len(m.urls)))
+ }
+}
+
+func (m *OutboundMonitoring) runStage(cycleID uint64, tags []string) []testOutcome {
+ resultCh := make(chan testOutcome, len(tags))
+
+ expected := 0
+ for _, tag := range tags {
+ state := m.getState(tag)
+ if state == nil {
+ continue
+ }
+
+ task := &testTask{
+ outboundTag: tag,
+ cycleID: cycleID,
+ priority: false,
+ resultCh: resultCh,
+ }
+ if m.enqueueTask(task) {
+ expected++
+ }
+
+ }
+
+ results := make([]testOutcome, 0, expected)
+
+ for expected > 0 {
+ select {
+ case <-m.ctx.Done():
+ return results
+ case r := <-resultCh:
+ results = append(results, r)
+ expected--
+ }
+ }
+
+ return results
+}
+
+func (m *OutboundMonitoring) enqueueTask(task *testTask) bool {
+
+ select {
+ case <-m.ctx.Done():
+ return false
+ default:
+ }
+ state, ok := m.outbounds[task.outboundTag]
+ if !ok {
+ return false
+ }
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ if task.priority {
+ if state.priorityQueued {
+ return false
+ }
+ state.priorityQueued = true
+ } else {
+ if state.enqueuedCycle == task.cycleID {
+ return false
+ }
+ state.enqueuedCycle = task.cycleID
+ state.queued = true
+ }
+ if task.priority {
+ select {
+ case m.priorityQueue <- task:
+ return true
+ default:
+ return false
+ }
+
+ } else {
+ select {
+ case m.normalQueue <- task:
+ return true
+ default:
+ return false
+ }
+ }
+
+}
+
+func (m *OutboundMonitoring) applyResult(outcome testOutcome) *adapter.URLTestHistory {
+ select {
+ case <-m.ctx.Done():
+ return nil
+ default:
+ }
+ state, ok := m.outbounds[outcome.outboundTag]
+ if !ok {
+ return nil
+ }
+ state.mu.Lock()
+ defer state.mu.Unlock()
+
+ state.queued = false
+ state.priorityQueued = false
+ state.enqueuedCycle = 0
+ state.invalid = outcome.err != nil
+ state.lastURL = outcome.url
+ if (outcome.history.Delay != state.history.Delay) || state.history.IpInfo == nil || (outcome.history.IpInfo != nil) {
+ m.cacheDirty.Store(true)
+ }
+ state.history.Delay = outcome.history.Delay
+ state.history.Time = outcome.history.Time
+ state.from_cache = false
+ if outcome.history.IpInfo != nil {
+ state.history.IpInfo = outcome.history.IpInfo
+ }
+ m.history.StoreURLTestHistory(outcome.outboundTag, &state.history)
+
+ m.emitGroupEvent(state.groupTags)
+ return &state.history
+}
+
+func mergeIpInfo(old, new *ipinfo.IpInfo) *ipinfo.IpInfo {
+ if old == nil {
+ return new
+ }
+ if new == nil {
+ return old
+ }
+ new2 := *new // copy
+ if new2.CountryCode == "" {
+ new2.CountryCode = old.CountryCode
+ }
+ if new2.Org == "" {
+ new2.Org = old.Org
+ }
+ return &new2
+}
+
+func (m *OutboundMonitoring) collectCycleTargets() []string {
+
+ tags := make([]string, 0, len(m.outbounds))
+
+ delays := make(map[string]uint16, len(tags))
+
+ for tag, state := range m.outbounds {
+ if _, ok := m.groups[tag]; ok {
+ continue
+ }
+ state.mu.Lock()
+ if state.testing || state.queued || state.priorityQueued {
+ state.mu.Unlock()
+ continue
+ }
+ if state.invalid || time.Since(state.history.Time) >= m.mainInterval {
+ tags = append(tags, tag)
+ delays[tag] = state.history.Delay
+ }
+ state.mu.Unlock()
+ }
+
+ sort.SliceStable(tags, func(i, j int) bool {
+ return delays[tags[i]] < delays[tags[j]]
+ })
+ return tags
+}
+
+func (m *OutboundMonitoring) makeGroup(tag string) *groupState {
+ grp, ok := m.groups[tag]
+ if ok {
+ return grp
+ }
+
+ grp = &groupState{
+ tag: tag,
+ outbounds: make(map[string]struct{}),
+ observer: NewBroadcaster[GroupEvent](m.ctx),
+ notifyCh: make(chan struct{}, 1),
+ }
+ m.groups[tag] = grp
+ return grp
+}
+
+func (m *OutboundMonitoring) Touch() {
+ if !m.started {
+ return
+ }
+ m.access.Lock()
+ defer m.access.Unlock()
+ if m.mainTicker != nil {
+ m.lastActive.Store(time.Now())
+ return
+ }
+ m.startTimerWorkers()
+
+}
+
+func (m *OutboundMonitoring) emitGroupEvent(groupTags []string) {
+ for _, groupTag := range groupTags {
+ grp, ok := m.groups[groupTag]
+ if !ok || grp.observer == nil {
+ continue
+ }
+
+ select {
+ case grp.notifyCh <- struct{}{}:
+ default:
+ }
+ }
+}
+
+func (m *OutboundMonitoring) emitGroupEventThrottled(groupTag string, since time.Time) {
+
+ grp, ok := m.groups[groupTag]
+ if !ok || grp.observer == nil {
+ return
+ }
+ tags := make([]string, 0, len(grp.outbounds))
+ for tag := range grp.outbounds {
+ state := m.outbounds[tag]
+ if state == nil {
+ continue
+ }
+ state.mu.Lock()
+ if !state.history.Time.Before(since) {
+ tags = append(tags, tag)
+ }
+ state.mu.Unlock()
+ }
+ grp.observer.Publish(GroupEvent{
+ GroupTag: groupTag,
+ From: since,
+ To: time.Now(),
+ tags: tags,
+ })
+}
+
+// func (m *OutboundMonitoring) OutboundsHistories() map[string]adapter.URLTestHistory {
+
+// histories := make(map[string]adapter.URLTestHistory)
+// outbounds := m.outbounds
+// for outboundTag, state := range outbounds {
+// state.mu.Lock()
+// histories[outboundTag] = state.history
+// state.mu.Unlock()
+// }
+// return histories
+// }
+func RealTag(detour adapter.Outbound) string {
+ if group, isGroup := detour.(adapter.OutboundGroup); isGroup {
+ tag := group.Now()
+ if tag != "" {
+ return tag
+ }
+ }
+ return detour.Tag()
+}
+
+func (m *OutboundMonitoring) groupNotifierLoop(grp *groupState) {
+
+ defer m.schedulerWG.Done()
+
+ var (
+ timer *time.Timer
+ timerCh <-chan time.Time
+ since time.Time
+ )
+
+ for {
+ select {
+ case <-m.ctx.Done():
+ if timer != nil {
+ timer.Stop()
+ }
+ return
+ case <-grp.notifyCh:
+ // if !m.cacheDirty.Load() {
+ // continue
+ // }
+ if timer == nil {
+ timer = time.NewTimer(m.debounceWindow)
+ timerCh = timer.C
+ }
+ case <-timerCh:
+ m.emitGroupEventThrottled(grp.tag, since)
+ since = time.Now()
+ if !timer.Stop() {
+ select {
+ case <-timer.C:
+ default:
+ }
+ }
+ timer = nil
+ timerCh = nil
+ }
+ }
+}
+
+func (m *OutboundMonitoring) getState(tag string) *outboundState {
+ return m.outbounds[tag]
+}
+
+type testTask struct {
+ outboundTag string
+ cycleID uint64
+ priority bool
+ resultCh chan<- testOutcome
+}
+
+type testOutcome struct {
+ outboundTag string
+ url string
+ history adapter.URLTestHistory
+ err error
+ cycleID uint64
+ priority bool
+}
+
+type outboundState struct {
+ mu sync.Mutex
+
+ outbound adapter.Outbound
+ groupTags []string
+ dependenciesInverse []string
+ dependencies []string
+ lastURL string
+
+ invalid bool
+ queued bool
+ priorityQueued bool
+ testing bool
+ enqueuedCycle uint64
+ from_cache bool
+
+ history adapter.URLTestHistory
+}
+
+type GroupEvent struct {
+ GroupTag string
+ From time.Time
+ To time.Time
+ tags []string
+}
+
+type groupState struct {
+ tag string
+ outbounds map[string]struct{}
+
+ observer *Broadcaster[GroupEvent]
+ notifyCh chan struct{}
+ bestDelay uint16
+}
+
+type History struct {
+ OutboundData map[string]*adapter.URLTestHistory `json:"outbound_data"`
+}
+
+func (m *OutboundMonitoring) saveHistory() error {
+ if m.cache == nil {
+ return nil
+ }
+ history := &History{
+ OutboundData: make(map[string]*adapter.URLTestHistory),
+ }
+ for tag, state := range m.outbounds {
+ state.mu.Lock()
+ h := state.history
+ state.mu.Unlock()
+ history.OutboundData[tag] = &h
+ }
+ content, err := json.Marshal(history)
+ if err != nil {
+ m.logger.Error("failed to marshal outbound monitoring history: ", err)
+ return err
+ }
+ m.cache.SaveBinary("outbound_monitoring_history", &adapter.SavedBinary{
+ LastUpdated: time.Now(),
+ Content: content,
+ })
+ return nil
+}
+func (m *OutboundMonitoring) loadHistory() *History {
+ history := &History{}
+ if m.cache == nil {
+ return history
+ }
+ saved := m.cache.LoadBinary("outbound_monitoring_history")
+ if saved == nil {
+ return history
+ }
+ err := json.Unmarshal(saved.Content, history)
+ if err != nil {
+ m.logger.Error("failed to unmarshal outbound monitoring history: ", err)
+ return history
+ }
+ for tag, his := range history.OutboundData {
+ if state, ok := m.outbounds[tag]; ok && his != nil {
+ if _, ok := m.groups[tag]; ok {
+ continue
+ }
+ if his.Delay >= TimeoutDelay {
+ his.Delay = 0
+ }
+ state.mu.Lock()
+ state.history = *his
+ state.from_cache = true
+ state.mu.Unlock()
+ }
+ }
+ return history
+}
diff --git a/common/mux/router.go b/common/mux/router.go
index ec78808600..6de6c4d6c7 100644
--- a/common/mux/router.go
+++ b/common/mux/router.go
@@ -42,7 +42,7 @@ func NewRouterWithOptions(router adapter.ConnectionRouterEx, logger logger.Conte
return log.ContextWithNewID(ctx)
},
Logger: logger,
- HandlerEx: adapter.NewRouteContextHandlerEx(router),
+ HandlerEx: adapter.NewRouteContextHandler(router),
Padding: options.Padding,
Brutal: brutalOptions,
})
diff --git a/common/networkquality/http.go b/common/networkquality/http.go
new file mode 100644
index 0000000000..f9ff2a4a5b
--- /dev/null
+++ b/common/networkquality/http.go
@@ -0,0 +1,142 @@
+package networkquality
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/http"
+ "strings"
+
+ C "github.com/sagernet/sing-box/constant"
+ sBufio "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func FormatBitrate(bps int64) string {
+ switch {
+ case bps >= 1_000_000_000:
+ return fmt.Sprintf("%.1f Gbps", float64(bps)/1_000_000_000)
+ case bps >= 1_000_000:
+ return fmt.Sprintf("%.1f Mbps", float64(bps)/1_000_000)
+ case bps >= 1_000:
+ return fmt.Sprintf("%.1f Kbps", float64(bps)/1_000)
+ default:
+ return fmt.Sprintf("%d bps", bps)
+ }
+}
+
+func NewHTTPClient(dialer N.Dialer) *http.Client {
+ transport := &http.Transport{
+ ForceAttemptHTTP2: true,
+ TLSHandshakeTimeout: C.TCPTimeout,
+ }
+ if dialer != nil {
+ transport.DialContext = func(ctx context.Context, network string, addr string) (net.Conn, error) {
+ return dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
+ }
+ }
+ return &http.Client{Transport: transport}
+}
+
+func baseTransportFromClient(client *http.Client) (*http.Transport, error) {
+ if client == nil {
+ return nil, E.New("http client is nil")
+ }
+ if client.Transport == nil {
+ return http.DefaultTransport.(*http.Transport).Clone(), nil
+ }
+ transport, ok := client.Transport.(*http.Transport)
+ if !ok {
+ return nil, E.New("http client transport must be *http.Transport")
+ }
+ return transport.Clone(), nil
+}
+
+func newMeasurementClient(
+ baseClient *http.Client,
+ connectEndpoint string,
+ singleConnection bool,
+ disableKeepAlives bool,
+ readCounters []N.CountFunc,
+ writeCounters []N.CountFunc,
+) (*http.Client, error) {
+ transport, err := baseTransportFromClient(baseClient)
+ if err != nil {
+ return nil, err
+ }
+ transport.DisableCompression = true
+ transport.DisableKeepAlives = disableKeepAlives
+ if singleConnection {
+ transport.MaxConnsPerHost = 1
+ transport.MaxIdleConnsPerHost = 1
+ transport.MaxIdleConns = 1
+ }
+
+ baseDialContext := transport.DialContext
+ if baseDialContext == nil {
+ dialer := &net.Dialer{}
+ baseDialContext = dialer.DialContext
+ }
+ transport.DialContext = func(ctx context.Context, network string, addr string) (net.Conn, error) {
+ dialAddr := addr
+ if connectEndpoint != "" {
+ dialAddr = rewriteDialAddress(addr, connectEndpoint)
+ }
+ conn, dialErr := baseDialContext(ctx, network, dialAddr)
+ if dialErr != nil {
+ return nil, dialErr
+ }
+ if len(readCounters) > 0 || len(writeCounters) > 0 {
+ return sBufio.NewCounterConn(conn, readCounters, writeCounters), nil
+ }
+ return conn, nil
+ }
+
+ return &http.Client{
+ Transport: transport,
+ CheckRedirect: baseClient.CheckRedirect,
+ Jar: baseClient.Jar,
+ Timeout: baseClient.Timeout,
+ }, nil
+}
+
+type MeasurementClientFactory func(
+ connectEndpoint string,
+ singleConnection bool,
+ disableKeepAlives bool,
+ readCounters []N.CountFunc,
+ writeCounters []N.CountFunc,
+) (*http.Client, error)
+
+func defaultMeasurementClientFactory(baseClient *http.Client) MeasurementClientFactory {
+ return func(connectEndpoint string, singleConnection, disableKeepAlives bool, readCounters, writeCounters []N.CountFunc) (*http.Client, error) {
+ return newMeasurementClient(baseClient, connectEndpoint, singleConnection, disableKeepAlives, readCounters, writeCounters)
+ }
+}
+
+func NewOptionalHTTP3Factory(dialer N.Dialer, useHTTP3 bool) (MeasurementClientFactory, error) {
+ if !useHTTP3 {
+ return nil, nil
+ }
+ return NewHTTP3MeasurementClientFactory(dialer)
+}
+
+func rewriteDialAddress(addr string, connectEndpoint string) string {
+ connectEndpoint = strings.TrimSpace(connectEndpoint)
+ host, port, err := net.SplitHostPort(addr)
+ if err != nil {
+ return addr
+ }
+ endpointHost, endpointPort, err := net.SplitHostPort(connectEndpoint)
+ if err == nil {
+ host = endpointHost
+ if endpointPort != "" {
+ port = endpointPort
+ }
+ } else if connectEndpoint != "" {
+ host = connectEndpoint
+ }
+ return net.JoinHostPort(host, port)
+}
diff --git a/common/networkquality/http3.go b/common/networkquality/http3.go
new file mode 100644
index 0000000000..0e907821d2
--- /dev/null
+++ b/common/networkquality/http3.go
@@ -0,0 +1,55 @@
+//go:build with_quic
+
+package networkquality
+
+import (
+ "context"
+ "crypto/tls"
+ "net"
+ "net/http"
+
+ "github.com/sagernet/quic-go"
+ "github.com/sagernet/quic-go/http3"
+ sBufio "github.com/sagernet/sing/common/bufio"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClientFactory, error) {
+ // singleConnection and disableKeepAlives are not applied:
+ // HTTP/3 multiplexes streams over a single QUIC connection by default.
+ return func(connectEndpoint string, _, _ bool, readCounters, writeCounters []N.CountFunc) (*http.Client, error) {
+ transport := &http3.Transport{
+ Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (*quic.Conn, error) {
+ dialAddr := addr
+ if connectEndpoint != "" {
+ dialAddr = rewriteDialAddress(addr, connectEndpoint)
+ }
+ destination := M.ParseSocksaddr(dialAddr)
+ var udpConn net.Conn
+ var dialErr error
+ if dialer != nil {
+ udpConn, dialErr = dialer.DialContext(ctx, N.NetworkUDP, destination)
+ } else {
+ var netDialer net.Dialer
+ udpConn, dialErr = netDialer.DialContext(ctx, N.NetworkUDP, destination.String())
+ }
+ if dialErr != nil {
+ return nil, dialErr
+ }
+ wrappedConn := udpConn
+ if len(readCounters) > 0 || len(writeCounters) > 0 {
+ wrappedConn = sBufio.NewCounterConn(udpConn, readCounters, writeCounters)
+ }
+ packetConn := sBufio.NewUnbindPacketConn(wrappedConn)
+ quicConn, dialErr := quic.DialEarly(ctx, packetConn, udpConn.RemoteAddr(), tlsCfg, cfg)
+ if dialErr != nil {
+ udpConn.Close()
+ return nil, dialErr
+ }
+ return quicConn, nil
+ },
+ }
+ return &http.Client{Transport: transport}, nil
+ }, nil
+}
diff --git a/common/networkquality/http3_stub.go b/common/networkquality/http3_stub.go
new file mode 100644
index 0000000000..632837e68d
--- /dev/null
+++ b/common/networkquality/http3_stub.go
@@ -0,0 +1,12 @@
+//go:build !with_quic
+
+package networkquality
+
+import (
+ C "github.com/sagernet/sing-box/constant"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func NewHTTP3MeasurementClientFactory(dialer N.Dialer) (MeasurementClientFactory, error) {
+ return nil, C.ErrQUICNotIncluded
+}
diff --git a/common/networkquality/networkquality.go b/common/networkquality/networkquality.go
new file mode 100644
index 0000000000..3247705d9e
--- /dev/null
+++ b/common/networkquality/networkquality.go
@@ -0,0 +1,1420 @@
+package networkquality
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "io"
+ "math"
+ "math/rand"
+ "net/http"
+ "net/http/httptrace"
+ "net/url"
+ "slices"
+ "sort"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ sBufio "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const DefaultConfigURL = "https://mensura.cdn-apple.com/api/v1/gm/config"
+
+type Config struct {
+ Version int `json:"version"`
+ TestEndpoint string `json:"test_endpoint"`
+ URLs URLs `json:"urls"`
+}
+
+type URLs struct {
+ SmallHTTPSDownloadURL string `json:"small_https_download_url"`
+ LargeHTTPSDownloadURL string `json:"large_https_download_url"`
+ HTTPSUploadURL string `json:"https_upload_url"`
+ SmallDownloadURL string `json:"small_download_url"`
+ LargeDownloadURL string `json:"large_download_url"`
+ UploadURL string `json:"upload_url"`
+}
+
+func (u *URLs) smallDownloadURL() string {
+ if u.SmallHTTPSDownloadURL != "" {
+ return u.SmallHTTPSDownloadURL
+ }
+ return u.SmallDownloadURL
+}
+
+func (u *URLs) largeDownloadURL() string {
+ if u.LargeHTTPSDownloadURL != "" {
+ return u.LargeHTTPSDownloadURL
+ }
+ return u.LargeDownloadURL
+}
+
+func (u *URLs) uploadURL() string {
+ if u.HTTPSUploadURL != "" {
+ return u.HTTPSUploadURL
+ }
+ return u.UploadURL
+}
+
+type Accuracy int32
+
+const (
+ AccuracyLow Accuracy = 0
+ AccuracyMedium Accuracy = 1
+ AccuracyHigh Accuracy = 2
+)
+
+func (a Accuracy) String() string {
+ switch a {
+ case AccuracyHigh:
+ return "High"
+ case AccuracyMedium:
+ return "Medium"
+ default:
+ return "Low"
+ }
+}
+
+type Result struct {
+ DownloadCapacity int64
+ UploadCapacity int64
+ DownloadRPM int32
+ UploadRPM int32
+ IdleLatencyMs int32
+ DownloadCapacityAccuracy Accuracy
+ UploadCapacityAccuracy Accuracy
+ DownloadRPMAccuracy Accuracy
+ UploadRPMAccuracy Accuracy
+}
+
+type Progress struct {
+ Phase Phase
+ DownloadCapacity int64
+ UploadCapacity int64
+ DownloadRPM int32
+ UploadRPM int32
+ IdleLatencyMs int32
+ ElapsedMs int64
+ DownloadCapacityAccuracy Accuracy
+ UploadCapacityAccuracy Accuracy
+ DownloadRPMAccuracy Accuracy
+ UploadRPMAccuracy Accuracy
+}
+
+type Phase int32
+
+const (
+ PhaseIdle Phase = 0
+ PhaseDownload Phase = 1
+ PhaseUpload Phase = 2
+ PhaseDone Phase = 3
+)
+
+type Options struct {
+ ConfigURL string
+ HTTPClient *http.Client
+ NewMeasurementClient MeasurementClientFactory
+ Serial bool
+ MaxRuntime time.Duration
+ OnProgress func(Progress)
+ Context context.Context
+}
+
+const DefaultMaxRuntime = 20 * time.Second
+
+type measurementSettings struct {
+ idleProbeCount int
+ testTimeout time.Duration
+ stabilityInterval time.Duration
+ sampleInterval time.Duration
+ progressInterval time.Duration
+ maxProbesPerSecond int
+ initialConnections int
+ maxConnections int
+ movingAvgDistance int
+ trimPercent int
+ stdDevTolerancePct float64
+ maxProbeCapacityPct float64
+}
+
+var settings = measurementSettings{
+ idleProbeCount: 5,
+ testTimeout: DefaultMaxRuntime,
+ stabilityInterval: time.Second,
+ sampleInterval: 250 * time.Millisecond,
+ progressInterval: 500 * time.Millisecond,
+ maxProbesPerSecond: 100,
+ initialConnections: 1,
+ maxConnections: 16,
+ movingAvgDistance: 4,
+ trimPercent: 5,
+ stdDevTolerancePct: 5,
+ maxProbeCapacityPct: 0.05,
+}
+
+type resolvedConfig struct {
+ smallURL *url.URL
+ largeURL *url.URL
+ uploadURL *url.URL
+ connectEndpoint string
+}
+
+type directionPlan struct {
+ dataURL *url.URL
+ probeURL *url.URL
+ connectEndpoint string
+ isUpload bool
+}
+
+type probeTrace struct {
+ reused bool
+ connectStart time.Time
+ connectDone time.Time
+ tlsStart time.Time
+ tlsDone time.Time
+ tlsVersion uint16
+ gotConn time.Time
+ wroteRequest time.Time
+ firstResponseByte time.Time
+}
+
+type probeMeasurement struct {
+ total time.Duration
+ tcp time.Duration
+ tls time.Duration
+ httpFirst time.Duration
+ httpLoaded time.Duration
+ bytes int64
+ reused bool
+}
+
+type probeRound struct {
+ interval int
+ tcp time.Duration
+ tls time.Duration
+ httpFirst time.Duration
+ httpLoaded time.Duration
+}
+
+func (p probeRound) responsivenessLatency() float64 {
+ var foreignSamples []float64
+ if p.tcp > 0 {
+ foreignSamples = append(foreignSamples, durationMillis(p.tcp))
+ }
+ if p.tls > 0 {
+ foreignSamples = append(foreignSamples, durationMillis(p.tls))
+ }
+ if p.httpFirst > 0 {
+ foreignSamples = append(foreignSamples, durationMillis(p.httpFirst))
+ }
+ if len(foreignSamples) == 0 || p.httpLoaded <= 0 {
+ return 0
+ }
+ return (meanFloat64s(foreignSamples) + durationMillis(p.httpLoaded)) / 2
+}
+
+const maxConsecutiveErrors = 3
+
+type loadConnection struct {
+ client *http.Client
+ dataURL *url.URL
+ isUpload bool
+ active atomic.Bool
+ ready atomic.Bool
+}
+
+func (c *loadConnection) run(ctx context.Context, onError func(error)) {
+ defer closeMeasurementClient(c.client)
+ markActive := func() {
+ c.ready.Store(true)
+ c.active.Store(true)
+ }
+ var consecutiveErrors int
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ }
+ var err error
+ if c.isUpload {
+ err = runUploadRequest(ctx, c.client, c.dataURL.String(), markActive)
+ } else {
+ err = runDownloadRequest(ctx, c.client, c.dataURL.String(), markActive)
+ }
+ c.active.Store(false)
+ if err != nil {
+ if ctx.Err() != nil {
+ return
+ }
+ consecutiveErrors++
+ if consecutiveErrors > maxConsecutiveErrors {
+ onError(err)
+ return
+ }
+ c.client.CloseIdleConnections()
+ continue
+ }
+ consecutiveErrors = 0
+ }
+}
+
+type intervalThroughput struct {
+ interval int
+ bps float64
+}
+
+type intervalWindow struct {
+ lower int
+ upper int
+}
+
+type stabilityTracker struct {
+ window int
+ stdDevTolerancePct float64
+ instantaneous []float64
+ movingAverages []float64
+}
+
+func (s *stabilityTracker) add(value float64) bool {
+ if value <= 0 || math.IsNaN(value) || math.IsInf(value, 0) {
+ return false
+ }
+ s.instantaneous = append(s.instantaneous, value)
+ if len(s.instantaneous) > s.window {
+ s.instantaneous = s.instantaneous[len(s.instantaneous)-s.window:]
+ }
+ s.movingAverages = append(s.movingAverages, meanFloat64s(s.instantaneous))
+ if len(s.movingAverages) > s.window {
+ s.movingAverages = s.movingAverages[len(s.movingAverages)-s.window:]
+ }
+ return s.stable()
+}
+
+func (s *stabilityTracker) ready() bool {
+ return len(s.movingAverages) >= s.window
+}
+
+func (s *stabilityTracker) accuracy() Accuracy {
+ if s.stable() {
+ return AccuracyHigh
+ }
+ if s.ready() {
+ return AccuracyMedium
+ }
+ return AccuracyLow
+}
+
+func (s *stabilityTracker) stable() bool {
+ if len(s.movingAverages) < s.window {
+ return false
+ }
+ currentAverage := s.movingAverages[len(s.movingAverages)-1]
+ if currentAverage <= 0 {
+ return false
+ }
+ return stdDevFloat64s(s.movingAverages) <= currentAverage*(s.stdDevTolerancePct/100)
+}
+
+type directionMeasurement struct {
+ capacity int64
+ rpm int32
+ capacityAccuracy Accuracy
+ rpmAccuracy Accuracy
+}
+
+type directionRunner struct {
+ factory MeasurementClientFactory
+ plan directionPlan
+ probeBytes int64
+
+ errCh chan error
+ errOnce sync.Once
+ wg sync.WaitGroup
+
+ totalBytes atomic.Int64
+ currentCapacity atomic.Int64
+ currentRPM atomic.Int32
+ currentInterval atomic.Int64
+
+ connMu sync.Mutex
+ connections []*loadConnection
+
+ probeMu sync.Mutex
+ probeRounds []probeRound
+ intervalProbeValues []float64
+ responsivenessWindow *intervalWindow
+ throughputs []intervalThroughput
+ throughputWindow *intervalWindow
+}
+
+func newDirectionRunner(factory MeasurementClientFactory, plan directionPlan, probeBytes int64) *directionRunner {
+ return &directionRunner{
+ factory: factory,
+ plan: plan,
+ probeBytes: probeBytes,
+ errCh: make(chan error, 1),
+ }
+}
+
+func (r *directionRunner) fail(err error) {
+ if err == nil {
+ return
+ }
+ r.errOnce.Do(func() {
+ select {
+ case r.errCh <- err:
+ default:
+ }
+ })
+}
+
+func (r *directionRunner) onConnectionFailed(err error) {
+ r.connMu.Lock()
+ activeCount := 0
+ for _, conn := range r.connections {
+ if conn.active.Load() {
+ activeCount++
+ }
+ }
+ r.connMu.Unlock()
+ if activeCount == 0 {
+ r.fail(err)
+ }
+}
+
+func (r *directionRunner) addConnection(ctx context.Context) error {
+ counter := N.CountFunc(func(n int64) { r.totalBytes.Add(n) })
+ var readCounters, writeCounters []N.CountFunc
+ if r.plan.isUpload {
+ writeCounters = []N.CountFunc{counter}
+ } else {
+ readCounters = []N.CountFunc{counter}
+ }
+ client, err := r.factory(r.plan.connectEndpoint, true, false, readCounters, writeCounters)
+ if err != nil {
+ return err
+ }
+ conn := &loadConnection{
+ client: client,
+ dataURL: r.plan.dataURL,
+ isUpload: r.plan.isUpload,
+ }
+ r.connMu.Lock()
+ r.connections = append(r.connections, conn)
+ r.connMu.Unlock()
+ r.wg.Add(1)
+ go func() {
+ defer r.wg.Done()
+ conn.run(ctx, r.onConnectionFailed)
+ }()
+ return nil
+}
+
+func (r *directionRunner) connectionCount() int {
+ r.connMu.Lock()
+ defer r.connMu.Unlock()
+ return len(r.connections)
+}
+
+func (r *directionRunner) pickReadyConnection() *loadConnection {
+ r.connMu.Lock()
+ defer r.connMu.Unlock()
+ var ready []*loadConnection
+ for _, conn := range r.connections {
+ if conn.ready.Load() && conn.active.Load() {
+ ready = append(ready, conn)
+ }
+ }
+ if len(ready) == 0 {
+ return nil
+ }
+ return ready[rand.Intn(len(ready))]
+}
+
+func (r *directionRunner) startProber(ctx context.Context) {
+ r.wg.Add(1)
+ go func() {
+ defer r.wg.Done()
+ ticker := time.NewTicker(r.probeInterval())
+ defer ticker.Stop()
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-ticker.C:
+ }
+ conn := r.pickReadyConnection()
+ if conn == nil {
+ continue
+ }
+ r.runProbeRound(ctx, conn.client)
+ ticker.Reset(r.probeInterval())
+ }
+ }()
+}
+
+func (r *directionRunner) runProbeRound(ctx context.Context, selfClient *http.Client) {
+ foreignClient, err := r.factory(r.plan.connectEndpoint, true, true, nil, nil)
+ if err != nil {
+ return
+ }
+ defer closeMeasurementClient(foreignClient)
+ round, err := collectProbeRound(ctx, foreignClient, selfClient, r.plan.probeURL.String())
+ if err != nil {
+ return
+ }
+ r.recordProbeRound(probeRound{
+ interval: int(r.currentInterval.Load()),
+ tcp: round.tcp,
+ tls: round.tls,
+ httpFirst: round.httpFirst,
+ httpLoaded: round.httpLoaded,
+ })
+}
+
+func (r *directionRunner) probeInterval() time.Duration {
+ interval := time.Second / time.Duration(settings.maxProbesPerSecond)
+ capacity := r.currentCapacity.Load()
+ if capacity <= 0 || r.probeBytes <= 0 || settings.maxProbeCapacityPct <= 0 {
+ return interval
+ }
+ bitsPerRound := float64(r.probeBytes*2) * 8
+ minSeconds := bitsPerRound / (float64(capacity) * settings.maxProbeCapacityPct)
+ if minSeconds <= 0 {
+ return interval
+ }
+ capacityInterval := time.Duration(minSeconds * float64(time.Second))
+ if capacityInterval > interval {
+ interval = capacityInterval
+ }
+ return interval
+}
+
+func (r *directionRunner) recordProbeRound(round probeRound) {
+ r.probeMu.Lock()
+ r.probeRounds = append(r.probeRounds, round)
+ if latency := round.responsivenessLatency(); latency > 0 {
+ r.intervalProbeValues = append(r.intervalProbeValues, latency)
+ }
+ r.currentRPM.Store(calculateRPM(r.probeRounds))
+ r.probeMu.Unlock()
+}
+
+func (r *directionRunner) swapIntervalProbeValues() []float64 {
+ r.probeMu.Lock()
+ defer r.probeMu.Unlock()
+ values := append([]float64(nil), r.intervalProbeValues...)
+ r.intervalProbeValues = nil
+ return values
+}
+
+func (r *directionRunner) setResponsivenessWindow(currentInterval int) {
+ lower := max(currentInterval-settings.movingAvgDistance+1, 0)
+ r.probeMu.Lock()
+ r.responsivenessWindow = &intervalWindow{lower: lower, upper: currentInterval}
+ r.probeMu.Unlock()
+}
+
+func (r *directionRunner) recordThroughput(interval int, bps float64) {
+ r.probeMu.Lock()
+ r.throughputs = append(r.throughputs, intervalThroughput{interval: interval, bps: bps})
+ r.probeMu.Unlock()
+}
+
+func (r *directionRunner) setThroughputWindow(currentInterval int) {
+ lower := max(currentInterval-settings.movingAvgDistance+1, 0)
+ r.probeMu.Lock()
+ r.throughputWindow = &intervalWindow{lower: lower, upper: currentInterval}
+ r.probeMu.Unlock()
+}
+
+func (r *directionRunner) finalRPM() int32 {
+ r.probeMu.Lock()
+ defer r.probeMu.Unlock()
+ if r.responsivenessWindow == nil {
+ return calculateRPM(r.probeRounds)
+ }
+ var rounds []probeRound
+ for _, round := range r.probeRounds {
+ if round.interval >= r.responsivenessWindow.lower && round.interval <= r.responsivenessWindow.upper {
+ rounds = append(rounds, round)
+ }
+ }
+ if len(rounds) == 0 {
+ rounds = r.probeRounds
+ }
+ return calculateRPM(rounds)
+}
+
+func (r *directionRunner) finalCapacity(totalDuration time.Duration) int64 {
+ r.probeMu.Lock()
+ defer r.probeMu.Unlock()
+ var samples []float64
+ if r.throughputWindow != nil {
+ for _, sample := range r.throughputs {
+ if sample.interval >= r.throughputWindow.lower && sample.interval <= r.throughputWindow.upper {
+ samples = append(samples, sample.bps)
+ }
+ }
+ }
+ if len(samples) == 0 {
+ for _, sample := range r.throughputs {
+ samples = append(samples, sample.bps)
+ }
+ }
+ if len(samples) > 0 {
+ return int64(math.Round(upperTrimmedMean(samples, settings.trimPercent)))
+ }
+ if totalDuration > 0 {
+ return int64(float64(r.totalBytes.Load()) * 8 / totalDuration.Seconds())
+ }
+ return 0
+}
+
+func (r *directionRunner) wait() {
+ r.wg.Wait()
+}
+
+func Run(options Options) (*Result, error) {
+ ctx := options.Context
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ if options.HTTPClient == nil {
+ return nil, E.New("http client is required")
+ }
+ maxRuntime, err := normalizeMaxRuntime(options.MaxRuntime)
+ if err != nil {
+ return nil, err
+ }
+ configURL := resolveConfigURL(options.ConfigURL)
+ config, err := fetchConfig(ctx, options.HTTPClient, configURL)
+ if err != nil {
+ return nil, E.Cause(err, "fetch config")
+ }
+ resolved, err := validateConfig(config)
+ if err != nil {
+ return nil, E.Cause(err, "validate config")
+ }
+
+ start := time.Now()
+ report := func(progress Progress) {
+ if options.OnProgress == nil {
+ return
+ }
+ progress.ElapsedMs = time.Since(start).Milliseconds()
+ options.OnProgress(progress)
+ }
+
+ factory := options.NewMeasurementClient
+ if factory == nil {
+ factory = defaultMeasurementClientFactory(options.HTTPClient)
+ }
+
+ report(Progress{Phase: PhaseIdle})
+ idleLatency, probeBytes, err := measureIdleLatency(ctx, factory, resolved)
+ if err != nil {
+ return nil, E.Cause(err, "measure idle latency")
+ }
+ report(Progress{Phase: PhaseIdle, IdleLatencyMs: idleLatency})
+
+ start = time.Now()
+
+ var download, upload *directionMeasurement
+ if options.Serial {
+ download, upload, err = measureSerial(
+ ctx,
+ factory,
+ resolved,
+ idleLatency,
+ probeBytes,
+ maxRuntime,
+ report,
+ )
+ } else {
+ download, upload, err = measureParallel(
+ ctx,
+ factory,
+ resolved,
+ idleLatency,
+ probeBytes,
+ maxRuntime,
+ report,
+ )
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ result := &Result{
+ DownloadCapacity: download.capacity,
+ UploadCapacity: upload.capacity,
+ DownloadRPM: download.rpm,
+ UploadRPM: upload.rpm,
+ IdleLatencyMs: idleLatency,
+ DownloadCapacityAccuracy: download.capacityAccuracy,
+ UploadCapacityAccuracy: upload.capacityAccuracy,
+ DownloadRPMAccuracy: download.rpmAccuracy,
+ UploadRPMAccuracy: upload.rpmAccuracy,
+ }
+ report(Progress{
+ Phase: PhaseDone,
+ DownloadCapacity: result.DownloadCapacity,
+ UploadCapacity: result.UploadCapacity,
+ DownloadRPM: result.DownloadRPM,
+ UploadRPM: result.UploadRPM,
+ IdleLatencyMs: result.IdleLatencyMs,
+ DownloadCapacityAccuracy: result.DownloadCapacityAccuracy,
+ UploadCapacityAccuracy: result.UploadCapacityAccuracy,
+ DownloadRPMAccuracy: result.DownloadRPMAccuracy,
+ UploadRPMAccuracy: result.UploadRPMAccuracy,
+ })
+ return result, nil
+}
+
+func normalizeMaxRuntime(maxRuntime time.Duration) (time.Duration, error) {
+ if maxRuntime == 0 {
+ return settings.testTimeout, nil
+ }
+ if maxRuntime < 0 {
+ return 0, E.New("max runtime must be positive")
+ }
+ return maxRuntime, nil
+}
+
+func measureSerial(
+ ctx context.Context,
+ factory MeasurementClientFactory,
+ resolved *resolvedConfig,
+ idleLatency int32,
+ probeBytes int64,
+ maxRuntime time.Duration,
+ report func(Progress),
+) (*directionMeasurement, *directionMeasurement, error) {
+ downloadRuntime, uploadRuntime := splitRuntimeBudget(maxRuntime, 2)
+ report(Progress{Phase: PhaseDownload, IdleLatencyMs: idleLatency})
+ download, err := measureDirection(ctx, factory, directionPlan{
+ dataURL: resolved.largeURL,
+ probeURL: resolved.smallURL,
+ connectEndpoint: resolved.connectEndpoint,
+ }, probeBytes, downloadRuntime, func(capacity int64, rpm int32) {
+ report(Progress{
+ Phase: PhaseDownload,
+ DownloadCapacity: capacity,
+ DownloadRPM: rpm,
+ IdleLatencyMs: idleLatency,
+ })
+ })
+ if err != nil {
+ return nil, nil, E.Cause(err, "measure download")
+ }
+
+ report(Progress{
+ Phase: PhaseUpload,
+ DownloadCapacity: download.capacity,
+ DownloadRPM: download.rpm,
+ IdleLatencyMs: idleLatency,
+ })
+ upload, err := measureDirection(ctx, factory, directionPlan{
+ dataURL: resolved.uploadURL,
+ probeURL: resolved.smallURL,
+ connectEndpoint: resolved.connectEndpoint,
+ isUpload: true,
+ }, probeBytes, uploadRuntime, func(capacity int64, rpm int32) {
+ report(Progress{
+ Phase: PhaseUpload,
+ DownloadCapacity: download.capacity,
+ UploadCapacity: capacity,
+ DownloadRPM: download.rpm,
+ UploadRPM: rpm,
+ IdleLatencyMs: idleLatency,
+ })
+ })
+ if err != nil {
+ return nil, nil, E.Cause(err, "measure upload")
+ }
+ return download, upload, nil
+}
+
+func measureParallel(
+ ctx context.Context,
+ factory MeasurementClientFactory,
+ resolved *resolvedConfig,
+ idleLatency int32,
+ probeBytes int64,
+ maxRuntime time.Duration,
+ report func(Progress),
+) (*directionMeasurement, *directionMeasurement, error) {
+ type parallelResult struct {
+ measurement *directionMeasurement
+ err error
+ }
+ type progressState struct {
+ sync.Mutex
+ downloadCapacity int64
+ uploadCapacity int64
+ downloadRPM int32
+ uploadRPM int32
+ }
+
+ parallelCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ report(Progress{Phase: PhaseDownload, IdleLatencyMs: idleLatency})
+ report(Progress{Phase: PhaseUpload, IdleLatencyMs: idleLatency})
+
+ var state progressState
+ sendProgress := func(phase Phase, capacity int64, rpm int32) {
+ state.Lock()
+ if phase == PhaseDownload {
+ state.downloadCapacity = capacity
+ state.downloadRPM = rpm
+ } else {
+ state.uploadCapacity = capacity
+ state.uploadRPM = rpm
+ }
+ snapshot := Progress{
+ Phase: phase,
+ DownloadCapacity: state.downloadCapacity,
+ UploadCapacity: state.uploadCapacity,
+ DownloadRPM: state.downloadRPM,
+ UploadRPM: state.uploadRPM,
+ IdleLatencyMs: idleLatency,
+ }
+ state.Unlock()
+ report(snapshot)
+ }
+
+ var wg sync.WaitGroup
+ downloadCh := make(chan parallelResult, 1)
+ uploadCh := make(chan parallelResult, 1)
+ wg.Add(2)
+ go func() {
+ defer wg.Done()
+ measurement, err := measureDirection(parallelCtx, factory, directionPlan{
+ dataURL: resolved.largeURL,
+ probeURL: resolved.smallURL,
+ connectEndpoint: resolved.connectEndpoint,
+ }, probeBytes, maxRuntime, func(capacity int64, rpm int32) {
+ sendProgress(PhaseDownload, capacity, rpm)
+ })
+ if err != nil {
+ cancel()
+ downloadCh <- parallelResult{err: E.Cause(err, "measure download")}
+ return
+ }
+ downloadCh <- parallelResult{measurement: measurement}
+ }()
+ go func() {
+ defer wg.Done()
+ measurement, err := measureDirection(parallelCtx, factory, directionPlan{
+ dataURL: resolved.uploadURL,
+ probeURL: resolved.smallURL,
+ connectEndpoint: resolved.connectEndpoint,
+ isUpload: true,
+ }, probeBytes, maxRuntime, func(capacity int64, rpm int32) {
+ sendProgress(PhaseUpload, capacity, rpm)
+ })
+ if err != nil {
+ cancel()
+ uploadCh <- parallelResult{err: E.Cause(err, "measure upload")}
+ return
+ }
+ uploadCh <- parallelResult{measurement: measurement}
+ }()
+
+ download := <-downloadCh
+ upload := <-uploadCh
+ wg.Wait()
+ if download.err != nil {
+ return nil, nil, download.err
+ }
+ if upload.err != nil {
+ return nil, nil, upload.err
+ }
+ return download.measurement, upload.measurement, nil
+}
+
+func resolveConfigURL(rawURL string) string {
+ rawURL = strings.TrimSpace(rawURL)
+ if rawURL == "" {
+ return DefaultConfigURL
+ }
+ if !strings.Contains(rawURL, "://") && !strings.Contains(rawURL, "/") {
+ return "https://" + rawURL + "/.well-known/nq"
+ }
+ parsedURL, err := url.Parse(rawURL)
+ if err != nil {
+ return rawURL
+ }
+ if parsedURL.Scheme != "" && parsedURL.Host != "" && (parsedURL.Path == "" || parsedURL.Path == "/") {
+ parsedURL.Path = "/.well-known/nq"
+ return parsedURL.String()
+ }
+ return rawURL
+}
+
+func fetchConfig(ctx context.Context, client *http.Client, configURL string) (*Config, error) {
+ req, err := newRequest(ctx, http.MethodGet, configURL, nil)
+ if err != nil {
+ return nil, err
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+ if err = validateResponse(resp); err != nil {
+ return nil, err
+ }
+ var config Config
+ if err = json.NewDecoder(resp.Body).Decode(&config); err != nil {
+ return nil, E.Cause(err, "decode config")
+ }
+ return &config, nil
+}
+
+func validateConfig(config *Config) (*resolvedConfig, error) {
+ if config == nil {
+ return nil, E.New("config is nil")
+ }
+ if config.Version != 1 {
+ return nil, E.New("unsupported config version: ", config.Version)
+ }
+ parseURL := func(name string, rawURL string) (*url.URL, error) {
+ if rawURL == "" {
+ return nil, E.New("config missing required URL: ", name)
+ }
+ parsedURL, err := url.Parse(rawURL)
+ if err != nil {
+ return nil, E.Cause(err, "parse "+name)
+ }
+ if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
+ return nil, E.New("unsupported URL scheme in ", name, ": ", parsedURL.Scheme)
+ }
+ if parsedURL.Host == "" {
+ return nil, E.New("config missing host in ", name)
+ }
+ return parsedURL, nil
+ }
+
+ smallURL, err := parseURL("small_download_url", config.URLs.smallDownloadURL())
+ if err != nil {
+ return nil, err
+ }
+ largeURL, err := parseURL("large_download_url", config.URLs.largeDownloadURL())
+ if err != nil {
+ return nil, err
+ }
+ uploadURL, err := parseURL("upload_url", config.URLs.uploadURL())
+ if err != nil {
+ return nil, err
+ }
+
+ if smallURL.Host != largeURL.Host || smallURL.Host != uploadURL.Host {
+ return nil, E.New("config URLs must use the same host")
+ }
+
+ return &resolvedConfig{
+ smallURL: smallURL,
+ largeURL: largeURL,
+ uploadURL: uploadURL,
+ connectEndpoint: strings.TrimSpace(config.TestEndpoint),
+ }, nil
+}
+
+func measureIdleLatency(ctx context.Context, factory MeasurementClientFactory, config *resolvedConfig) (int32, int64, error) {
+ var latencies []int64
+ var maxProbeBytes int64
+ for i := 0; i < settings.idleProbeCount; i++ {
+ select {
+ case <-ctx.Done():
+ return 0, 0, ctx.Err()
+ default:
+ }
+ client, err := factory(config.connectEndpoint, true, true, nil, nil)
+ if err != nil {
+ return 0, 0, err
+ }
+ measurement, err := runProbe(ctx, client, config.smallURL.String(), false)
+ closeMeasurementClient(client)
+ if err != nil {
+ return 0, 0, err
+ }
+ latencies = append(latencies, measurement.total.Milliseconds())
+ if measurement.bytes > maxProbeBytes {
+ maxProbeBytes = measurement.bytes
+ }
+ }
+ slices.Sort(latencies)
+ return int32(latencies[len(latencies)/2]), maxProbeBytes, nil
+}
+
+func measureDirection(
+ ctx context.Context,
+ factory MeasurementClientFactory,
+ plan directionPlan,
+ probeBytes int64,
+ maxRuntime time.Duration,
+ onProgress func(capacity int64, rpm int32),
+) (*directionMeasurement, error) {
+ phaseCtx, phaseCancel := context.WithTimeout(ctx, maxRuntime)
+ defer phaseCancel()
+
+ runner := newDirectionRunner(factory, plan, probeBytes)
+ defer runner.wait()
+
+ for i := 0; i < settings.initialConnections; i++ {
+ err := runner.addConnection(phaseCtx)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ runner.startProber(phaseCtx)
+
+ throughputTracker := stabilityTracker{
+ window: settings.movingAvgDistance,
+ stdDevTolerancePct: settings.stdDevTolerancePct,
+ }
+ responsivenessTracker := stabilityTracker{
+ window: settings.movingAvgDistance,
+ stdDevTolerancePct: settings.stdDevTolerancePct,
+ }
+
+ start := time.Now()
+ sampleTicker := time.NewTicker(settings.sampleInterval)
+ defer sampleTicker.Stop()
+ intervalTicker := time.NewTicker(settings.stabilityInterval)
+ defer intervalTicker.Stop()
+ progressTicker := time.NewTicker(settings.progressInterval)
+ defer progressTicker.Stop()
+
+ prevSampleBytes := int64(0)
+ prevSampleTime := start
+ prevIntervalBytes := int64(0)
+ prevIntervalTime := start
+ var ewmaCapacity float64
+ var goodputSaturated bool
+ var intervalIndex int
+
+ for {
+ select {
+ case err := <-runner.errCh:
+ return nil, err
+ case now := <-sampleTicker.C:
+ currentBytes := runner.totalBytes.Load()
+ elapsed := now.Sub(prevSampleTime).Seconds()
+ if elapsed > 0 {
+ instantaneousBps := float64(currentBytes-prevSampleBytes) * 8 / elapsed
+ if ewmaCapacity == 0 {
+ ewmaCapacity = instantaneousBps
+ } else {
+ ewmaCapacity = 0.3*instantaneousBps + 0.7*ewmaCapacity
+ }
+ runner.currentCapacity.Store(int64(ewmaCapacity))
+ }
+ prevSampleBytes = currentBytes
+ prevSampleTime = now
+ case <-intervalTicker.C:
+ now := time.Now()
+ currentBytes := runner.totalBytes.Load()
+ elapsed := now.Sub(prevIntervalTime).Seconds()
+ if elapsed > 0 {
+ intervalBps := float64(currentBytes-prevIntervalBytes) * 8 / elapsed
+ runner.recordThroughput(intervalIndex, intervalBps)
+ throughputStable := throughputTracker.add(intervalBps)
+ if throughputStable && runner.throughputWindow == nil {
+ runner.setThroughputWindow(intervalIndex)
+ }
+ if !goodputSaturated && (throughputStable || (runner.connectionCount() >= settings.maxConnections && throughputTracker.ready())) {
+ goodputSaturated = true
+ }
+ if runner.connectionCount() < settings.maxConnections {
+ err := runner.addConnection(phaseCtx)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ if goodputSaturated {
+ if values := runner.swapIntervalProbeValues(); len(values) > 0 {
+ if responsivenessTracker.add(upperTrimmedMean(values, settings.trimPercent)) && runner.responsivenessWindow == nil {
+ runner.setResponsivenessWindow(intervalIndex)
+ phaseCancel()
+ }
+ }
+ }
+ prevIntervalBytes = currentBytes
+ prevIntervalTime = now
+ intervalIndex++
+ runner.currentInterval.Store(int64(intervalIndex))
+ case <-progressTicker.C:
+ if onProgress != nil {
+ onProgress(int64(ewmaCapacity), runner.currentRPM.Load())
+ }
+ case <-phaseCtx.Done():
+ if ctx.Err() != nil {
+ return nil, ctx.Err()
+ }
+ totalDuration := time.Since(start)
+ return &directionMeasurement{
+ capacity: runner.finalCapacity(totalDuration),
+ rpm: runner.finalRPM(),
+ capacityAccuracy: throughputTracker.accuracy(),
+ rpmAccuracy: responsivenessTracker.accuracy(),
+ }, nil
+ }
+ }
+}
+
+func splitRuntimeBudget(total time.Duration, directions int) (time.Duration, time.Duration) {
+ if directions <= 1 {
+ return total, total
+ }
+ first := total / time.Duration(directions)
+ second := total - first
+ return first, second
+}
+
+func collectProbeRound(ctx context.Context, foreignClient *http.Client, selfClient *http.Client, rawURL string) (probeMeasurement, error) {
+ var foreignResult probeMeasurement
+ var selfResult probeMeasurement
+ var foreignErr error
+ var selfErr error
+
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go func() {
+ defer wg.Done()
+ foreignResult, foreignErr = runProbe(ctx, foreignClient, rawURL, false)
+ }()
+ go func() {
+ defer wg.Done()
+ selfResult, selfErr = runProbe(ctx, selfClient, rawURL, true)
+ }()
+ wg.Wait()
+
+ if foreignErr != nil {
+ return probeMeasurement{}, E.Cause(foreignErr, "foreign probe")
+ }
+ if selfErr != nil {
+ return probeMeasurement{}, E.Cause(selfErr, "self probe")
+ }
+ return probeMeasurement{
+ tcp: foreignResult.tcp,
+ tls: foreignResult.tls,
+ httpFirst: foreignResult.httpFirst,
+ httpLoaded: selfResult.httpLoaded,
+ }, nil
+}
+
+func runProbe(ctx context.Context, client *http.Client, rawURL string, expectReuse bool) (probeMeasurement, error) {
+ var trace probeTrace
+ start := time.Now()
+ req, err := newRequest(httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
+ ConnectStart: func(string, string) {
+ if trace.connectStart.IsZero() {
+ trace.connectStart = time.Now()
+ }
+ },
+ ConnectDone: func(string, string, error) {
+ if trace.connectDone.IsZero() {
+ trace.connectDone = time.Now()
+ }
+ },
+ TLSHandshakeStart: func() {
+ if trace.tlsStart.IsZero() {
+ trace.tlsStart = time.Now()
+ }
+ },
+ TLSHandshakeDone: func(state tls.ConnectionState, _ error) {
+ if trace.tlsDone.IsZero() {
+ trace.tlsDone = time.Now()
+ trace.tlsVersion = state.Version
+ }
+ },
+ GotConn: func(info httptrace.GotConnInfo) {
+ trace.reused = info.Reused
+ trace.gotConn = time.Now()
+ },
+ WroteRequest: func(httptrace.WroteRequestInfo) {
+ trace.wroteRequest = time.Now()
+ },
+ GotFirstResponseByte: func() {
+ trace.firstResponseByte = time.Now()
+ },
+ }), http.MethodGet, rawURL, nil)
+ if err != nil {
+ return probeMeasurement{}, err
+ }
+ if !expectReuse {
+ req.Close = true
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ return probeMeasurement{}, err
+ }
+ defer resp.Body.Close()
+ if err = validateResponse(resp); err != nil {
+ return probeMeasurement{}, err
+ }
+ n, err := io.Copy(io.Discard, resp.Body)
+ end := time.Now()
+ if err != nil {
+ return probeMeasurement{}, err
+ }
+ if expectReuse && !trace.reused {
+ return probeMeasurement{}, E.New("self probe did not reuse an existing connection")
+ }
+
+ httpStart := trace.wroteRequest
+ if httpStart.IsZero() {
+ switch {
+ case !trace.tlsDone.IsZero():
+ httpStart = trace.tlsDone
+ case !trace.connectDone.IsZero():
+ httpStart = trace.connectDone
+ case !trace.gotConn.IsZero():
+ httpStart = trace.gotConn
+ default:
+ httpStart = start
+ }
+ }
+
+ measurement := probeMeasurement{
+ total: end.Sub(start),
+ bytes: n,
+ reused: trace.reused,
+ }
+ if !trace.connectStart.IsZero() && !trace.connectDone.IsZero() && trace.connectDone.After(trace.connectStart) {
+ measurement.tcp = trace.connectDone.Sub(trace.connectStart)
+ }
+ if !trace.tlsStart.IsZero() && !trace.tlsDone.IsZero() && trace.tlsDone.After(trace.tlsStart) {
+ measurement.tls = trace.tlsDone.Sub(trace.tlsStart)
+ if roundTrips := tlsHandshakeRoundTrips(trace.tlsVersion); roundTrips > 1 {
+ measurement.tls /= time.Duration(roundTrips)
+ }
+ }
+ if !trace.firstResponseByte.IsZero() && trace.firstResponseByte.After(httpStart) {
+ measurement.httpFirst = trace.firstResponseByte.Sub(httpStart)
+ }
+ if end.After(httpStart) {
+ measurement.httpLoaded = end.Sub(httpStart)
+ }
+ return measurement, nil
+}
+
+func runDownloadRequest(ctx context.Context, client *http.Client, rawURL string, onActive func()) error {
+ req, err := newRequest(ctx, http.MethodGet, rawURL, nil)
+ if err != nil {
+ return err
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ err = validateResponse(resp)
+ if err != nil {
+ return err
+ }
+ if onActive != nil {
+ onActive()
+ }
+ _, err = sBufio.Copy(io.Discard, resp.Body)
+ if ctx.Err() != nil {
+ return nil
+ }
+ return err
+}
+
+func runUploadRequest(ctx context.Context, client *http.Client, rawURL string, onActive func()) error {
+ body := &uploadBody{
+ ctx: ctx,
+ onActive: onActive,
+ }
+ req, err := newRequest(ctx, http.MethodPost, rawURL, body)
+ if err != nil {
+ return err
+ }
+ req.ContentLength = -1
+ req.Header.Set("Content-Type", "application/octet-stream")
+ resp, err := client.Do(req)
+ if err != nil {
+ if ctx.Err() != nil {
+ return nil
+ }
+ return err
+ }
+ defer resp.Body.Close()
+ err = validateResponse(resp)
+ if err != nil {
+ return err
+ }
+ _, _ = io.Copy(io.Discard, resp.Body)
+ <-ctx.Done()
+ return nil
+}
+
+func newRequest(ctx context.Context, method string, rawURL string, body io.Reader) (*http.Request, error) {
+ req, err := http.NewRequestWithContext(ctx, method, rawURL, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("Accept-Encoding", "identity")
+ return req, nil
+}
+
+func closeMeasurementClient(client *http.Client) {
+ if client == nil {
+ return
+ }
+ client.CloseIdleConnections()
+ if closer, ok := client.Transport.(interface{ Close() error }); ok {
+ _ = closer.Close()
+ }
+}
+
+func validateResponse(resp *http.Response) error {
+ if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+ return E.New("unexpected status: ", resp.Status)
+ }
+ if encoding := resp.Header.Get("Content-Encoding"); encoding != "" {
+ return E.New("unexpected content encoding: ", encoding)
+ }
+ return nil
+}
+
+func calculateRPM(rounds []probeRound) int32 {
+ if len(rounds) == 0 {
+ return 0
+ }
+ var tcpSamples []float64
+ var tlsSamples []float64
+ var httpFirstSamples []float64
+ var httpLoadedSamples []float64
+ for _, round := range rounds {
+ if round.tcp > 0 {
+ tcpSamples = append(tcpSamples, durationMillis(round.tcp))
+ }
+ if round.tls > 0 {
+ tlsSamples = append(tlsSamples, durationMillis(round.tls))
+ }
+ if round.httpFirst > 0 {
+ httpFirstSamples = append(httpFirstSamples, durationMillis(round.httpFirst))
+ }
+ if round.httpLoaded > 0 {
+ httpLoadedSamples = append(httpLoadedSamples, durationMillis(round.httpLoaded))
+ }
+ }
+ httpLoaded := upperTrimmedMean(httpLoadedSamples, settings.trimPercent)
+ if httpLoaded <= 0 {
+ return 0
+ }
+ var foreignComponents []float64
+ if tcp := upperTrimmedMean(tcpSamples, settings.trimPercent); tcp > 0 {
+ foreignComponents = append(foreignComponents, tcp)
+ }
+ if tls := upperTrimmedMean(tlsSamples, settings.trimPercent); tls > 0 {
+ foreignComponents = append(foreignComponents, tls)
+ }
+ if httpFirst := upperTrimmedMean(httpFirstSamples, settings.trimPercent); httpFirst > 0 {
+ foreignComponents = append(foreignComponents, httpFirst)
+ }
+ if len(foreignComponents) == 0 {
+ return 0
+ }
+ foreignLatency := meanFloat64s(foreignComponents)
+ foreignRPM := 60000.0 / foreignLatency
+ loadedRPM := 60000.0 / httpLoaded
+ return int32(math.Round((foreignRPM + loadedRPM) / 2))
+}
+
+func tlsHandshakeRoundTrips(version uint16) int {
+ switch version {
+ case tls.VersionTLS12, tls.VersionTLS11, tls.VersionTLS10:
+ return 2
+ default:
+ return 1
+ }
+}
+
+func durationMillis(value time.Duration) float64 {
+ return float64(value) / float64(time.Millisecond)
+}
+
+func upperTrimmedMean(values []float64, trimPercent int) float64 {
+ trimmed := upperTrimFloat64s(values, trimPercent)
+ if len(trimmed) == 0 {
+ return 0
+ }
+ return meanFloat64s(trimmed)
+}
+
+func upperTrimFloat64s(values []float64, trimPercent int) []float64 {
+ if len(values) == 0 {
+ return nil
+ }
+ trimmed := append([]float64(nil), values...)
+ sort.Float64s(trimmed)
+ if trimPercent <= 0 {
+ return trimmed
+ }
+ trimCount := int(math.Floor(float64(len(trimmed)) * float64(trimPercent) / 100))
+ if trimCount <= 0 || trimCount >= len(trimmed) {
+ return trimmed
+ }
+ return trimmed[:len(trimmed)-trimCount]
+}
+
+func meanFloat64s(values []float64) float64 {
+ if len(values) == 0 {
+ return 0
+ }
+ var total float64
+ for _, value := range values {
+ total += value
+ }
+ return total / float64(len(values))
+}
+
+func stdDevFloat64s(values []float64) float64 {
+ if len(values) == 0 {
+ return 0
+ }
+ mean := meanFloat64s(values)
+ var total float64
+ for _, value := range values {
+ delta := value - mean
+ total += delta * delta
+ }
+ return math.Sqrt(total / float64(len(values)))
+}
+
+type uploadBody struct {
+ ctx context.Context
+ activated atomic.Bool
+ onActive func()
+}
+
+func (u *uploadBody) Read(p []byte) (int, error) {
+ if err := u.ctx.Err(); err != nil {
+ return 0, err
+ }
+ clear(p)
+ n := len(p)
+ if n > 0 && u.onActive != nil && u.activated.CompareAndSwap(false, true) {
+ u.onActive()
+ }
+ return n, nil
+}
+
+func (u *uploadBody) Close() error {
+ return nil
+}
diff --git a/common/process/searcher_android.go b/common/process/searcher_android.go
index 287c72190b..e634774488 100644
--- a/common/process/searcher_android.go
+++ b/common/process/searcher_android.go
@@ -7,6 +7,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
)
var _ Searcher = (*androidSearcher)(nil)
@@ -16,6 +17,9 @@ type androidSearcher struct {
}
func NewSearcher(config Config) (Searcher, error) {
+ if config.PackageManager == nil {
+ return nil, E.New("missing package manager")
+ }
return &androidSearcher{config.PackageManager}, nil
}
diff --git a/common/proxybridge/bridge.go b/common/proxybridge/bridge.go
new file mode 100644
index 0000000000..3380cae447
--- /dev/null
+++ b/common/proxybridge/bridge.go
@@ -0,0 +1,115 @@
+package proxybridge
+
+import (
+ std_bufio "bufio"
+ "context"
+ "crypto/rand"
+ "encoding/hex"
+ "net"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/auth"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/protocol/socks"
+ "github.com/sagernet/sing/service"
+)
+
+type Bridge struct {
+ ctx context.Context
+ logger logger.ContextLogger
+ tag string
+ dialer N.Dialer
+ connection adapter.ConnectionManager
+ tcpListener *net.TCPListener
+ username string
+ password string
+ authenticator *auth.Authenticator
+}
+
+func New(ctx context.Context, logger logger.ContextLogger, tag string, dialer N.Dialer) (*Bridge, error) {
+ username := randomHex(16)
+ password := randomHex(16)
+ tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)})
+ if err != nil {
+ return nil, err
+ }
+ bridge := &Bridge{
+ ctx: ctx,
+ logger: logger,
+ tag: tag,
+ dialer: dialer,
+ connection: service.FromContext[adapter.ConnectionManager](ctx),
+ tcpListener: tcpListener,
+ username: username,
+ password: password,
+ authenticator: auth.NewAuthenticator([]auth.User{{Username: username, Password: password}}),
+ }
+ go bridge.acceptLoop()
+ return bridge, nil
+}
+
+func randomHex(size int) string {
+ raw := make([]byte, size)
+ rand.Read(raw)
+ return hex.EncodeToString(raw)
+}
+
+func (b *Bridge) Port() uint16 {
+ return M.SocksaddrFromNet(b.tcpListener.Addr()).Port
+}
+
+func (b *Bridge) Username() string {
+ return b.username
+}
+
+func (b *Bridge) Password() string {
+ return b.password
+}
+
+func (b *Bridge) Close() error {
+ return common.Close(b.tcpListener)
+}
+
+func (b *Bridge) acceptLoop() {
+ for {
+ tcpConn, err := b.tcpListener.AcceptTCP()
+ if err != nil {
+ return
+ }
+ ctx := log.ContextWithNewID(b.ctx)
+ go func() {
+ hErr := socks.HandleConnectionEx(ctx, tcpConn, std_bufio.NewReader(tcpConn), b.authenticator, b, nil, 0, M.SocksaddrFromNet(tcpConn.RemoteAddr()), nil)
+ if hErr == nil {
+ return
+ }
+ if E.IsClosedOrCanceled(hErr) {
+ b.logger.DebugContext(ctx, E.Cause(hErr, b.tag, " connection closed"))
+ return
+ }
+ b.logger.ErrorContext(ctx, E.Cause(hErr, b.tag))
+ }()
+ }
+}
+
+func (b *Bridge) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Source = source
+ metadata.Destination = destination
+ metadata.Network = N.NetworkTCP
+ b.logger.InfoContext(ctx, b.tag, " connection to ", metadata.Destination)
+ b.connection.NewConnection(ctx, b.dialer, conn, metadata, onClose)
+}
+
+func (b *Bridge) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Source = source
+ metadata.Destination = destination
+ metadata.Network = N.NetworkUDP
+ b.logger.InfoContext(ctx, b.tag, " packet connection to ", metadata.Destination)
+ b.connection.NewPacketConnection(ctx, b.dialer, conn, metadata, onClose)
+}
diff --git a/common/proxyproto/dialer.go b/common/proxyproto/dialer.go
new file mode 100644
index 0000000000..f3fba6f4da
--- /dev/null
+++ b/common/proxyproto/dialer.go
@@ -0,0 +1,50 @@
+package proxyproto
+
+import (
+ "context"
+ "net"
+ "net/netip"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ "github.com/pires/go-proxyproto"
+)
+
+var _ N.Dialer = (*Dialer)(nil)
+
+type Dialer struct {
+ N.Dialer
+}
+
+func (d *Dialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ conn, err := d.Dialer.DialContext(ctx, network, destination)
+ if err != nil {
+ return nil, err
+ }
+ var source M.Socksaddr
+ metadata := adapter.ContextFrom(ctx)
+ if metadata != nil {
+ source = metadata.Source
+ }
+ if !source.IsValid() {
+ source = M.SocksaddrFromNet(conn.LocalAddr())
+ }
+ if destination.Addr.Is6() {
+ source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port)
+ }
+ h := proxyproto.HeaderProxyFromAddrs(1, source.TCPAddr(), destination.TCPAddr())
+ _, err = h.WriteTo(conn)
+ if err != nil {
+ conn.Close()
+ return nil, E.Cause(err, "write proxy protocol header")
+ }
+ return conn, nil
+ default:
+ return d.Dialer.DialContext(ctx, network, destination)
+ }
+}
diff --git a/common/proxyproto/listener.go b/common/proxyproto/listener.go
new file mode 100644
index 0000000000..23a839d719
--- /dev/null
+++ b/common/proxyproto/listener.go
@@ -0,0 +1,62 @@
+package proxyproto
+
+import (
+ std_bufio "bufio"
+ "net"
+
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/bufio"
+ M "github.com/sagernet/sing/common/metadata"
+
+ "github.com/pires/go-proxyproto"
+)
+
+type Listener struct {
+ net.Listener
+ AcceptNoHeader bool
+}
+
+func (l *Listener) Accept() (net.Conn, error) {
+ conn, err := l.Listener.Accept()
+ if err != nil {
+ return nil, err
+ }
+ bufReader := std_bufio.NewReader(conn)
+ header, err := proxyproto.Read(bufReader)
+ if err != nil && !(l.AcceptNoHeader && err == proxyproto.ErrNoProxyProtocol) {
+ return nil, &Error{err}
+ }
+ if bufReader.Buffered() > 0 {
+ cache := buf.NewSize(bufReader.Buffered())
+ _, err = cache.ReadFullFrom(bufReader, cache.FreeLen())
+ if err != nil {
+ return nil, &Error{err}
+ }
+ conn = bufio.NewCachedConn(conn, cache)
+ }
+ if header != nil {
+ return &bufio.AddrConn{Conn: conn,
+ Source: M.SocksaddrFromNet(header.SourceAddr).Unwrap(),
+ Destination: M.SocksaddrFromNet(header.DestinationAddr).Unwrap(),
+ }, nil
+ }
+ return conn, nil
+}
+
+var _ net.Error = (*Error)(nil)
+
+type Error struct {
+ error
+}
+
+func (e *Error) Unwrap() error {
+ return e.error
+}
+
+func (e *Error) Timeout() bool {
+ return false
+}
+
+func (e *Error) Temporary() bool {
+ return true
+}
diff --git a/common/schannel/doc.go b/common/schannel/doc.go
new file mode 100644
index 0000000000..bdcb2f1a36
--- /dev/null
+++ b/common/schannel/doc.go
@@ -0,0 +1,5 @@
+// Package schannel wraps the Windows Schannel security provider (SSPI) for
+// client-side TLS. The public API is implemented on Windows only; on other
+// platforms the package is empty and intended for transitive imports from
+// build-tagged callers.
+package schannel
diff --git a/common/schannel/schannel_windows.go b/common/schannel/schannel_windows.go
new file mode 100644
index 0000000000..d912ca2315
--- /dev/null
+++ b/common/schannel/schannel_windows.go
@@ -0,0 +1,719 @@
+package schannel
+
+import (
+ "bytes"
+ "crypto/tls"
+ "encoding/binary"
+ "os"
+ "sync"
+ "syscall"
+ "unsafe"
+
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/windows"
+)
+
+const clientCredentialFlags = schCredManualCredValidation | schCredNoDefaultCreds | schUseStrongCrypto
+
+var versionCheck = sync.OnceValue(func() error {
+ major, _, build := windows.RtlGetNtVersionNumbers()
+ build &= 0xffff
+ if major < 10 || (major == 10 && build < 17763) {
+ return E.New("Windows TLS engine requires Windows build 17763 or later (Windows 10 version 1809, Windows Server 2019, or newer)")
+ }
+ return nil
+})
+
+// CheckPlatform returns an error when the running Windows version does not
+// support the SCH_CREDENTIALS structure used by this package.
+func CheckPlatform() error {
+ return versionCheck()
+}
+
+type clientCredentialKey struct {
+ disabledProtocols uint32
+ flags uint32
+}
+
+type clientCredential struct {
+ key clientCredentialKey
+ once sync.Once
+ handle secHandle
+ tlsParams tlsParameters
+ err error
+}
+
+var clientCredentialCache sync.Map
+
+func cachedClientCredential(minVersion, maxVersion uint16) (*clientCredential, error) {
+ key := clientCredentialKey{
+ disabledProtocols: disabledProtocolsMask(minVersion, maxVersion),
+ flags: clientCredentialFlags,
+ }
+ actual, _ := clientCredentialCache.LoadOrStore(key, &clientCredential{key: key})
+ credential := actual.(*clientCredential)
+ credential.once.Do(func() {
+ credential.err = credential.acquire()
+ })
+ if credential.err != nil {
+ clientCredentialCache.Delete(key)
+ return nil, credential.err
+ }
+ return credential, nil
+}
+
+func (c *clientCredential) acquire() error {
+ c.tlsParams.grbitDisabledProtocols = c.key.disabledProtocols
+ sch := schCredentials{
+ dwVersion: schCredentialsVersion,
+ dwFlags: c.key.flags,
+ cTlsParameters: 1,
+ pTlsParameters: &c.tlsParams,
+ }
+ pkg, err := windows.UTF16PtrFromString(unispNameW)
+ if err != nil {
+ return err
+ }
+ var expiry windows.Filetime
+ status := sspiAcquireCredentialsHandle(
+ nil,
+ pkg,
+ secPkgCredOutbound,
+ nil,
+ unsafe.Pointer(&sch),
+ 0,
+ 0,
+ &c.handle,
+ &expiry,
+ )
+ if status != secEOK {
+ return sspiError("AcquireCredentialsHandle", status)
+ }
+ return nil
+}
+
+// ClientContext owns the per-connection Schannel security context and drives
+// it through handshake and application-data phases.
+type ClientContext struct {
+ credential *clientCredential
+ handle secHandle
+ targetName *uint16
+
+ // alpnBuffer is the SEC_APPLICATION_PROTOCOLS blob; kept alive for the
+ // duration of the first handshake call.
+ alpnBuffer []byte
+
+ firstCall bool
+ valid bool
+}
+
+// NewClientContext allocates a new client context, reuses the Schannel
+// credential handle for the supplied TLS version bounds, and advertises ALPN
+// protocols through an SECBUFFER_APPLICATION_PROTOCOLS buffer on the first
+// handshake call.
+func NewClientContext(minVersion, maxVersion uint16, serverName string, alpn []string) (*ClientContext, error) {
+ if minVersion != 0 && maxVersion != 0 && minVersion > maxVersion {
+ return nil, os.ErrInvalid
+ }
+ err := CheckPlatform()
+ if err != nil {
+ return nil, err
+ }
+ targetName, err := windows.UTF16PtrFromString(serverName)
+ if err != nil {
+ return nil, err
+ }
+ credential, err := cachedClientCredential(minVersion, maxVersion)
+ if err != nil {
+ return nil, err
+ }
+ c := &ClientContext{
+ credential: credential,
+ targetName: targetName,
+ firstCall: true,
+ }
+ if len(alpn) > 0 {
+ c.alpnBuffer, err = encodeAlpnBuffer(alpn)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return c, nil
+}
+
+// Close releases the per-connection security context. Safe to call multiple
+// times.
+func (c *ClientContext) Close() {
+ if c == nil {
+ return
+ }
+ if c.valid {
+ sspiDeleteSecurityContext(&c.handle)
+ c.valid = false
+ c.handle = secHandle{}
+ }
+}
+
+type StepResult struct {
+ // Output must be written to the peer verbatim before the next Step call.
+ // When Done is true, leftover input[Consumed:] is the first application
+ // ciphertext — not more handshake bytes.
+ Output []byte
+ Consumed int
+ Done bool
+ Incomplete bool
+}
+
+// Step drives one handshake iteration. Input may be nil on the first call.
+// Callers must write Output to the peer, append more peer bytes when
+// Incomplete is true, and loop until Done is true.
+func (c *ClientContext) Step(input []byte) (StepResult, error) {
+ var inputDesc *secBufferDesc
+ var inputBufs [2]secBuffer
+ if c.firstCall {
+ if len(c.alpnBuffer) > 0 {
+ inputBufs[0].bufferType = secbufferApplicationProtocols
+ inputBufs[0].cbBuffer = uint32(len(c.alpnBuffer))
+ inputBufs[0].pvBuffer = &c.alpnBuffer[0]
+ inputDesc = &secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 1,
+ pBuffers: &inputBufs[0],
+ }
+ }
+ } else {
+ if len(input) == 0 {
+ return StepResult{}, E.New("schannel: empty handshake input after first step")
+ }
+ inputBufs[0].bufferType = secbufferToken
+ inputBufs[0].cbBuffer = uint32(len(input))
+ inputBufs[0].pvBuffer = &input[0]
+ inputBufs[1].bufferType = secbufferEmpty
+ inputDesc = &secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 2,
+ pBuffers: &inputBufs[0],
+ }
+ }
+
+ result, terminal, err := c.runInitializeSecurityContext(inputDesc, "InitializeSecurityContext")
+ if err != nil || terminal {
+ return result, err
+ }
+
+ switch {
+ case c.firstCall:
+ result.Consumed = 0
+ case inputBufs[1].bufferType == secbufferExtra && inputBufs[1].cbBuffer > 0:
+ consumed, extraErr := consumedFromExtra(&inputBufs[1], len(input))
+ if extraErr != nil {
+ return result, extraErr
+ }
+ result.Consumed = consumed
+ default:
+ result.Consumed = len(input)
+ }
+
+ c.firstCall = false
+ c.alpnBuffer = nil
+ return result, nil
+}
+
+// StreamSizes must be called after Step returns Done=true.
+func (c *ClientContext) StreamSizes() (header, trailer, maxMessage uint32, err error) {
+ var sizes secPkgContextStreamSizes
+ status := sspiQueryContextAttributes(&c.handle, secpkgAttrStreamSizes, unsafe.Pointer(&sizes))
+ if status != secEOK {
+ return 0, 0, 0, sspiError("QueryContextAttributes(stream sizes)", status)
+ }
+ return sizes.cbHeader, sizes.cbTrailer, sizes.cbMaximumMessage, nil
+}
+
+// Encrypt wraps a plaintext chunk into a TLS record using the supplied
+// backing buffer which must have room for header + plaintext + trailer bytes.
+// Plaintext is copied into buffer starting at `header` offset before calling
+// EncryptMessage. Returns the encrypted record as a slice into buffer.
+func (c *ClientContext) Encrypt(header, trailer uint32, plaintext []byte, buffer []byte) ([]byte, error) {
+ if len(buffer) < int(header)+len(plaintext)+int(trailer) {
+ return nil, E.New("schannel: encrypt buffer too small")
+ }
+ copy(buffer[header:], plaintext)
+ headerPtr := &buffer[0]
+ dataPtr := &buffer[header]
+ trailerPtr := &buffer[int(header)+len(plaintext)]
+
+ bufs := [4]secBuffer{
+ {cbBuffer: header, bufferType: secbufferStreamHeader, pvBuffer: headerPtr},
+ {cbBuffer: uint32(len(plaintext)), bufferType: secbufferData, pvBuffer: dataPtr},
+ {cbBuffer: trailer, bufferType: secbufferStreamTrailer, pvBuffer: trailerPtr},
+ {bufferType: secbufferEmpty},
+ }
+ desc := secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 4,
+ pBuffers: &bufs[0],
+ }
+ status := sspiEncryptMessage(&c.handle, 0, &desc, 0)
+ if status != secEOK {
+ return nil, sspiError("EncryptMessage", status)
+ }
+ total := int(bufs[0].cbBuffer + bufs[1].cbBuffer + bufs[2].cbBuffer)
+ return buffer[:total], nil
+}
+
+type DecryptResult struct {
+ // Plaintext aliases memory inside the input buffer passed to Decrypt;
+ // callers must copy before the next Decrypt call reuses that buffer.
+ Plaintext []byte
+ // ConsumedTotal is the number of input bytes Schannel consumed, i.e.
+ // input[ConsumedTotal:] are unprocessed leftover ciphertext.
+ ConsumedTotal int
+ // RenegotiateToken aliases the post-handshake token that must be fed back
+ // through InitializeSecurityContext after SEC_I_RENEGOTIATE.
+ RenegotiateToken []byte
+ Incomplete bool
+ Renegotiate bool
+ Expired bool
+}
+
+// Decrypt processes a chunk of TLS ciphertext in-place. The returned Plaintext
+// aliases memory inside input until the next Decrypt call; callers must copy
+// the bytes they want to keep.
+func (c *ClientContext) Decrypt(input []byte) (DecryptResult, error) {
+ var result DecryptResult
+ if len(input) == 0 {
+ result.Incomplete = true
+ return result, nil
+ }
+ bufs := [4]secBuffer{
+ {cbBuffer: uint32(len(input)), bufferType: secbufferData, pvBuffer: &input[0]},
+ {bufferType: secbufferEmpty},
+ {bufferType: secbufferEmpty},
+ {bufferType: secbufferEmpty},
+ }
+ desc := secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 4,
+ pBuffers: &bufs[0],
+ }
+ status := sspiDecryptMessage(&c.handle, &desc, 0, nil)
+ switch status {
+ case secEOK:
+ case secEIncompleteMessage:
+ result.Incomplete = true
+ return result, nil
+ case secIContextExpired:
+ result.Expired = true
+ return result, nil
+ case secIRenegotiate:
+ result.Renegotiate = true
+ default:
+ return result, sspiError("DecryptMessage", status)
+ }
+ return parseDecryptResult(input, bufs[:], result.Renegotiate)
+}
+
+// PostHandshake processes a TLS 1.3 post-handshake message
+// (NewSessionTicket, KeyUpdate) after DecryptMessage returned
+// SEC_I_RENEGOTIATE. Pass the token preserved from Decrypt on the first call;
+// pass more peer bytes on subsequent calls when Incomplete.
+func (c *ClientContext) PostHandshake(input []byte) (StepResult, error) {
+ var inputDesc *secBufferDesc
+ var inputBufs [2]secBuffer
+ if len(input) > 0 {
+ inputBufs[0].bufferType = secbufferToken
+ inputBufs[0].cbBuffer = uint32(len(input))
+ inputBufs[0].pvBuffer = &input[0]
+ inputBufs[1].bufferType = secbufferEmpty
+ inputDesc = &secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 2,
+ pBuffers: &inputBufs[0],
+ }
+ }
+
+ result, terminal, err := c.runInitializeSecurityContext(inputDesc, "InitializeSecurityContext(post-handshake)")
+ if err != nil || terminal {
+ return result, err
+ }
+
+ if len(input) > 0 && inputBufs[1].bufferType == secbufferExtra && inputBufs[1].cbBuffer > 0 {
+ consumed, extraErr := consumedFromExtra(&inputBufs[1], len(input))
+ if extraErr != nil {
+ return result, extraErr
+ }
+ result.Consumed = consumed
+ } else {
+ result.Consumed = len(input)
+ }
+ return result, nil
+}
+
+func parseDecryptResult(input []byte, bufs []secBuffer, renegotiate bool) (DecryptResult, error) {
+ var result DecryptResult
+ var dataBuffer, extraBuffer *secBuffer
+ for index := range bufs {
+ switch bufs[index].bufferType {
+ case secbufferData:
+ dataBuffer = &bufs[index]
+ case secbufferExtra:
+ extraBuffer = &bufs[index]
+ }
+ }
+ if dataBuffer != nil && dataBuffer.cbBuffer > 0 && dataBuffer.pvBuffer != nil {
+ result.Plaintext = unsafe.Slice(dataBuffer.pvBuffer, int(dataBuffer.cbBuffer))
+ }
+ if extraBuffer != nil && extraBuffer.cbBuffer > 0 {
+ consumed, err := consumedFromExtra(extraBuffer, len(input))
+ if err != nil {
+ return result, err
+ }
+ result.ConsumedTotal = consumed
+ } else {
+ result.ConsumedTotal = len(input)
+ }
+ if renegotiate {
+ result.Renegotiate = true
+ if extraBuffer != nil && extraBuffer.cbBuffer > 0 {
+ result.RenegotiateToken = input[result.ConsumedTotal:]
+ } else {
+ result.RenegotiateToken = input
+ }
+ }
+ return result, nil
+}
+
+// ApplicationProtocol returns the empty string when ALPN was not negotiated.
+func (c *ClientContext) ApplicationProtocol() (string, error) {
+ var info secPkgContextApplicationProtocol
+ status := sspiQueryContextAttributes(&c.handle, secpkgAttrApplicationProtocol, unsafe.Pointer(&info))
+ if status != secEOK {
+ return "", sspiError("QueryContextAttributes(application protocol)", status)
+ }
+ if info.protoNegoStatus != secApplicationProtocolNegotiationStatusSuccess {
+ return "", nil
+ }
+ size := int(info.protocolIDSize)
+ if size > len(info.protocolID) {
+ return "", E.New("schannel: invalid ALPN protocol size")
+ }
+ return string(info.protocolID[:size]), nil
+}
+
+// ConnectionInfo reports the negotiated TLS version and cipher suite.
+// cipherSuite may be zero when the Windows build does not return a
+// mappable cipher name.
+func (c *ClientContext) ConnectionInfo() (version, cipherSuite uint16, err error) {
+ var info secPkgContextConnectionInfo
+ status := sspiQueryContextAttributes(&c.handle, secpkgAttrConnectionInfo, unsafe.Pointer(&info))
+ if status != secEOK {
+ return 0, 0, sspiError("QueryContextAttributes(connection info)", status)
+ }
+ version = sspProtocolToTLSVersion(info.dwProtocol)
+
+ var cipherInfo secPkgContextCipherInfo
+ cipherInfo.dwVersion = 1
+ status = sspiQueryContextAttributes(&c.handle, secpkgAttrCipherInfo, unsafe.Pointer(&cipherInfo))
+ if status == secEOK {
+ cipherSuite = cipherSuiteID(windows.UTF16ToString(cipherInfo.szCipherSuite[:]))
+ }
+ return version, cipherSuite, nil
+}
+
+func cipherSuiteID(name string) uint16 {
+ for _, suite := range tls.CipherSuites() {
+ if suite.Name == name {
+ return suite.ID
+ }
+ }
+ for _, suite := range tls.InsecureCipherSuites() {
+ if suite.Name == name {
+ return suite.ID
+ }
+ }
+ return 0
+}
+
+// RemoteCertificateChain returns freshly allocated DER bytes ordered
+// leaf → intermediates.
+func (c *ClientContext) RemoteCertificateChain() ([][]byte, error) {
+ var leaf *windows.CertContext
+ status := sspiQueryContextAttributes(&c.handle, secpkgAttrRemoteCertContext, unsafe.Pointer(&leaf))
+ if status != secEOK {
+ return nil, sspiError("QueryContextAttributes(remote cert context)", status)
+ }
+ if leaf == nil {
+ return nil, nil
+ }
+ defer windows.CertFreeCertificateContext(leaf)
+
+ chain, err := buildCertChainDER(leaf)
+ if err != nil {
+ return [][]byte{certContextDER(leaf)}, nil
+ }
+ return chain, nil
+}
+
+const handshakeContextReq = iscReqSequenceDetect |
+ iscReqReplayDetect |
+ iscReqConfidentiality |
+ iscReqAllocateMemory |
+ iscReqStream |
+ iscReqUseSuppliedCreds |
+ iscReqManualCredValidation |
+ iscReqExtendedError
+
+// runInitializeSecurityContext returns terminal=true when the result is
+// final (error or more-data-needed), signalling that the caller must skip
+// extra-buffer post-processing.
+func (c *ClientContext) runInitializeSecurityContext(inputDesc *secBufferDesc, opLabel string) (StepResult, bool, error) {
+ var outputBufs [1]secBuffer
+ outputBufs[0].bufferType = secbufferToken
+ outputDesc := secBufferDesc{
+ ulVersion: secbufferVersion,
+ cBuffers: 1,
+ pBuffers: &outputBufs[0],
+ }
+ var ctxIn *secHandle
+ if c.valid {
+ ctxIn = &c.handle
+ }
+ var contextAttr uint32
+ var expiry windows.Filetime
+ status := sspiInitializeSecurityContext(
+ &c.credential.handle,
+ ctxIn,
+ c.targetName,
+ handshakeContextReq,
+ 0,
+ 0,
+ inputDesc,
+ 0,
+ &c.handle,
+ &outputDesc,
+ &contextAttr,
+ &expiry,
+ )
+
+ switch status {
+ case secEOK, secICompleteNeeded, secICompleteAndContinue, secIContinueNeeded:
+ c.valid = true
+ }
+ if status == secICompleteNeeded || status == secICompleteAndContinue {
+ completeStatus := sspiCompleteAuthToken(&c.handle, &outputDesc)
+ if completeStatus != secEOK {
+ if outputBufs[0].pvBuffer != nil {
+ sspiFreeContextBuffer(outputBufs[0].pvBuffer)
+ }
+ return StepResult{}, true, sspiError("CompleteAuthToken", completeStatus)
+ }
+ }
+
+ var result StepResult
+ if outputBufs[0].cbBuffer > 0 && outputBufs[0].pvBuffer != nil {
+ result.Output = unsafeSliceCopy(outputBufs[0].pvBuffer, int(outputBufs[0].cbBuffer))
+ sspiFreeContextBuffer(outputBufs[0].pvBuffer)
+ }
+
+ switch status {
+ case secEOK, secICompleteNeeded:
+ result.Done = true
+ return result, false, nil
+ case secIContinueNeeded, secICompleteAndContinue:
+ return result, false, nil
+ case secEIncompleteMessage:
+ c.valid = true
+ result.Incomplete = true
+ return result, true, nil
+ default:
+ return result, true, sspiError(opLabel, status)
+ }
+}
+
+func consumedFromExtra(extraBuf *secBuffer, inputLen int) (int, error) {
+ extraLen := int(extraBuf.cbBuffer)
+ if extraLen > inputLen {
+ return 0, E.New("schannel: SECBUFFER_EXTRA exceeds input length")
+ }
+ return inputLen - extraLen, nil
+}
+
+func disabledProtocolsMask(minVersion, maxVersion uint16) uint32 {
+ allowed := uint32(0)
+ versions := []struct {
+ id uint16
+ mask uint32
+ }{
+ {tls.VersionTLS10, spProtTLS10Client},
+ {tls.VersionTLS11, spProtTLS11Client},
+ {tls.VersionTLS12, spProtTLS12Client},
+ {tls.VersionTLS13, spProtTLS13Client},
+ }
+ effectiveMin := minVersion
+ if effectiveMin == 0 {
+ effectiveMin = tls.VersionTLS12
+ if maxVersion != 0 && maxVersion < tls.VersionTLS12 {
+ effectiveMin = versions[0].id
+ }
+ }
+ effectiveMax := maxVersion
+ if effectiveMax == 0 {
+ effectiveMax = tls.VersionTLS13
+ }
+ for _, v := range versions {
+ if v.id >= effectiveMin && v.id <= effectiveMax {
+ allowed |= v.mask
+ }
+ }
+ if allowed == 0 {
+ return 0
+ }
+ return spProtAllTLSClients &^ allowed
+}
+
+func sspProtocolToTLSVersion(sp uint32) uint16 {
+ switch {
+ case sp&spProtTLS13Client != 0:
+ return tls.VersionTLS13
+ case sp&spProtTLS12Client != 0:
+ return tls.VersionTLS12
+ case sp&spProtTLS11Client != 0:
+ return tls.VersionTLS11
+ case sp&spProtTLS10Client != 0:
+ return tls.VersionTLS10
+ }
+ return 0
+}
+
+func encodeAlpnBuffer(protocols []string) ([]byte, error) {
+ var protoList []byte
+ for _, proto := range protocols {
+ if len(proto) == 0 || len(proto) > 255 {
+ return nil, E.New("schannel: invalid ALPN protocol: ", proto)
+ }
+ protoList = append(protoList, byte(len(proto)))
+ protoList = append(protoList, []byte(proto)...)
+ }
+ if len(protoList) > 0xFFFF {
+ return nil, E.New("schannel: ALPN list too long")
+ }
+ // Layout:
+ // uint32 ProtocolListsSize
+ // uint32 ProtoNegoExt
+ // uint16 ProtocolListSize
+ // bytes ProtocolList
+ inner := 4 + 2 + len(protoList)
+ buffer := make([]byte, 4+inner)
+ binary.LittleEndian.PutUint32(buffer[0:4], uint32(inner))
+ binary.LittleEndian.PutUint32(buffer[4:8], secApplicationProtocolNegotiationExtALPN)
+ binary.LittleEndian.PutUint16(buffer[8:10], uint16(len(protoList)))
+ copy(buffer[10:], protoList)
+ return buffer, nil
+}
+
+func unsafeSliceCopy(ptr *byte, size int) []byte {
+ if ptr == nil || size <= 0 {
+ return nil
+ }
+ out := make([]byte, size)
+ copy(out, unsafe.Slice(ptr, size))
+ return out
+}
+
+func certContextDER(ctx *windows.CertContext) []byte {
+ if ctx == nil || ctx.EncodedCert == nil || ctx.Length == 0 {
+ return nil
+ }
+ out := make([]byte, ctx.Length)
+ copy(out, unsafe.Slice(ctx.EncodedCert, int(ctx.Length)))
+ return out
+}
+
+func buildCertChainDER(leaf *windows.CertContext) ([][]byte, error) {
+ var chainPara windows.CertChainPara
+ chainPara.Size = uint32(unsafe.Sizeof(chainPara))
+ var chainCtx *windows.CertChainContext
+ err := windows.CertGetCertificateChain(0, leaf, nil, leaf.Store, &chainPara, 0, 0, &chainCtx)
+ if err != nil {
+ return nil, err
+ }
+ defer windows.CertFreeCertificateChain(chainCtx)
+ return extractCertChainDER(chainCtx)
+}
+
+func extractCertChainDER(chainCtx *windows.CertChainContext) ([][]byte, error) {
+ if chainCtx == nil || chainCtx.ChainCount == 0 || chainCtx.Chains == nil {
+ return nil, E.New("schannel: empty certificate chain")
+ }
+ chains := unsafe.Slice(chainCtx.Chains, int(chainCtx.ChainCount))
+ chain := chains[0]
+ if chain == nil || chain.NumElements == 0 || chain.Elements == nil {
+ return nil, E.New("schannel: empty certificate chain")
+ }
+ elements := unsafe.Slice(chain.Elements, int(chain.NumElements))
+ if len(elements) > 1 &&
+ chain.TrustStatus.ErrorStatus&windows.CERT_TRUST_IS_PARTIAL_CHAIN == 0 &&
+ isSelfSignedCertContext(elements[len(elements)-1].CertContext) {
+ elements = elements[:len(elements)-1]
+ }
+ derChain := make([][]byte, 0, len(elements))
+ for index, element := range elements {
+ if element == nil || element.CertContext == nil {
+ return nil, E.New("schannel: missing certificate chain element ", index)
+ }
+ der := certContextDER(element.CertContext)
+ if len(der) == 0 {
+ return nil, E.New("schannel: empty certificate chain element ", index)
+ }
+ derChain = append(derChain, der)
+ }
+ return derChain, nil
+}
+
+func isSelfSignedCertContext(ctx *windows.CertContext) bool {
+ if ctx == nil || ctx.CertInfo == nil {
+ return false
+ }
+ return bytes.Equal(
+ certNameBlobBytes(ctx.CertInfo.Issuer),
+ certNameBlobBytes(ctx.CertInfo.Subject),
+ )
+}
+
+func certNameBlobBytes(blob windows.CertNameBlob) []byte {
+ if blob.Size == 0 || blob.Data == nil {
+ return nil
+ }
+ return unsafe.Slice(blob.Data, int(blob.Size))
+}
+
+func sspiError(where string, status syscall.Errno) error {
+ return E.New("schannel: ", where, ": ", formatStatus(status))
+}
+
+var statusNames = map[syscall.Errno]string{
+ secEUnsupportedFunc: "SEC_E_UNSUPPORTED_FUNCTION",
+ secEInternalError: "SEC_E_INTERNAL_ERROR",
+ secEInvalidToken: "SEC_E_INVALID_TOKEN",
+ secELogonDenied: "SEC_E_LOGON_DENIED",
+ secEMessageAltered: "SEC_E_MESSAGE_ALTERED",
+ secENoAuthenticatingAuthority: "SEC_E_NO_AUTHENTICATING_AUTHORITY",
+ secEContextExpired: "SEC_E_CONTEXT_EXPIRED",
+ secEIncompleteMessage: "SEC_E_INCOMPLETE_MESSAGE",
+ secEIncompleteCreds: "SEC_E_INCOMPLETE_CREDENTIALS",
+ secEBufferTooSmall: "SEC_E_BUFFER_TOO_SMALL",
+ secEWrongPrincipal: "SEC_E_WRONG_PRINCIPAL",
+ secEIllegalMessage: "SEC_E_ILLEGAL_MESSAGE",
+ secECertUnknown: "SEC_E_CERT_UNKNOWN",
+ secECertExpired: "SEC_E_CERT_EXPIRED",
+ secEAlgorithmMismatch: "SEC_E_ALGORITHM_MISMATCH",
+}
+
+func formatStatus(status syscall.Errno) string {
+ name, loaded := statusNames[status]
+ if !loaded {
+ return status.Error()
+ }
+ return name + ": " + status.Error()
+}
diff --git a/common/schannel/schannel_windows_test.go b/common/schannel/schannel_windows_test.go
new file mode 100644
index 0000000000..35bcaabb21
--- /dev/null
+++ b/common/schannel/schannel_windows_test.go
@@ -0,0 +1,188 @@
+//go:build windows
+
+package schannel
+
+import (
+ "bytes"
+ "crypto/tls"
+ "testing"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+func TestExtractCertChainDERExcludesSelfSignedRoot(t *testing.T) {
+ leaf := certContextForTest([]byte("leaf"), []byte("intermediate"), []byte("leaf"))
+ intermediate := certContextForTest([]byte("intermediate"), []byte("root"), []byte("intermediate"))
+ root := certContextForTest([]byte("root"), []byte("root"), []byte("root"))
+
+ chainCtx := certChainContextForTest(leaf, intermediate, root)
+ derChain, err := extractCertChainDER(chainCtx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(derChain) != 2 {
+ t.Fatalf("expected 2 certificates, got %d", len(derChain))
+ }
+ if !bytes.Equal(derChain[0], []byte("leaf")) {
+ t.Fatalf("unexpected leaf certificate: %q", string(derChain[0]))
+ }
+ if !bytes.Equal(derChain[1], []byte("intermediate")) {
+ t.Fatalf("unexpected intermediate certificate: %q", string(derChain[1]))
+ }
+}
+
+func TestExtractCertChainDERKeepsLastIntermediateWithoutRoot(t *testing.T) {
+ leaf := certContextForTest([]byte("leaf"), []byte("intermediate"), []byte("leaf"))
+ intermediate := certContextForTest([]byte("intermediate"), []byte("root"), []byte("intermediate"))
+
+ chainCtx := certChainContextForTest(leaf, intermediate)
+ derChain, err := extractCertChainDER(chainCtx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(derChain) != 2 {
+ t.Fatalf("expected 2 certificates, got %d", len(derChain))
+ }
+ if !bytes.Equal(derChain[1], []byte("intermediate")) {
+ t.Fatalf("unexpected last certificate: %q", string(derChain[1]))
+ }
+}
+
+func TestDisabledProtocolsMask(t *testing.T) {
+ testCases := []struct {
+ name string
+ minVersion uint16
+ maxVersion uint16
+ want uint32
+ }{
+ {
+ name: "default range",
+ want: spProtAllTLSClients &^ (spProtTLS12Client | spProtTLS13Client),
+ },
+ {
+ name: "default minimum with explicit max",
+ maxVersion: tls.VersionTLS12,
+ want: spProtAllTLSClients &^ spProtTLS12Client,
+ },
+ {
+ name: "explicit tls10 range",
+ minVersion: tls.VersionTLS10,
+ maxVersion: tls.VersionTLS13,
+ want: 0,
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ got := disabledProtocolsMask(testCase.minVersion, testCase.maxVersion)
+ if got != testCase.want {
+ t.Fatalf("disabledProtocolsMask(%#x, %#x) = %#x, want %#x", testCase.minVersion, testCase.maxVersion, got, testCase.want)
+ }
+ })
+ }
+}
+
+func TestClientCredentialCacheReusesVersionRange(t *testing.T) {
+ if err := CheckPlatform(); err != nil {
+ t.Skip(err)
+ }
+ first, err := NewClientContext(tls.VersionTLS12, tls.VersionTLS13, "localhost", []string{"h2"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer first.Close()
+ second, err := NewClientContext(tls.VersionTLS12, tls.VersionTLS13, "example.com", []string{"http/1.1"})
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer second.Close()
+ if first.credential != second.credential {
+ t.Fatal("expected same TLS version range to reuse credential")
+ }
+
+ tls12Only, err := NewClientContext(tls.VersionTLS12, tls.VersionTLS12, "localhost", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer tls12Only.Close()
+ if first.credential == tls12Only.credential {
+ t.Fatal("expected distinct TLS version range to use a distinct credential")
+ }
+ if first.credential.key.disabledProtocols != disabledProtocolsMask(tls.VersionTLS12, tls.VersionTLS13) {
+ t.Fatalf("unexpected cached disabled protocol mask: %#x", first.credential.key.disabledProtocols)
+ }
+}
+
+func TestParseDecryptResultKeepsRenegotiateExtraToken(t *testing.T) {
+ input := []byte("plain-ticket")
+ result, err := parseDecryptResult(input, []secBuffer{
+ {bufferType: secbufferExtra, cbBuffer: 6},
+ }, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !result.Renegotiate {
+ t.Fatal("expected Renegotiate to be true")
+ }
+ if result.ConsumedTotal != len(input)-6 {
+ t.Fatalf("unexpected consumed total: %d", result.ConsumedTotal)
+ }
+ if !bytes.Equal(result.RenegotiateToken, []byte("ticket")) {
+ t.Fatalf("unexpected renegotiate token: %q", string(result.RenegotiateToken))
+ }
+}
+
+func TestParseDecryptResultKeepsRenegotiateWholeBufferWithoutExtra(t *testing.T) {
+ input := []byte("ticket")
+ result, err := parseDecryptResult(input, []secBuffer{
+ {bufferType: secbufferData, cbBuffer: uint32(len(input)), pvBuffer: &input[0]},
+ }, true)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !result.Renegotiate {
+ t.Fatal("expected Renegotiate to be true")
+ }
+ if result.ConsumedTotal != len(input) {
+ t.Fatalf("unexpected consumed total: %d", result.ConsumedTotal)
+ }
+ if !bytes.Equal(result.RenegotiateToken, input) {
+ t.Fatalf("unexpected renegotiate token: %q", string(result.RenegotiateToken))
+ }
+}
+
+func certChainContextForTest(certs ...*windows.CertContext) *windows.CertChainContext {
+ elements := make([]*windows.CertChainElement, 0, len(certs))
+ for _, cert := range certs {
+ elements = append(elements, &windows.CertChainElement{CertContext: cert})
+ }
+ simpleChain := &windows.CertSimpleChain{
+ NumElements: uint32(len(elements)),
+ Elements: &elements[0],
+ }
+ chains := []*windows.CertSimpleChain{simpleChain}
+ return &windows.CertChainContext{
+ ChainCount: 1,
+ Chains: &chains[0],
+ }
+}
+
+func certContextForTest(der, issuer, subject []byte) *windows.CertContext {
+ certInfo := &windows.CertInfo{
+ Issuer: certNameBlobForTest(issuer),
+ Subject: certNameBlobForTest(subject),
+ }
+ return &windows.CertContext{
+ EncodedCert: &der[0],
+ Length: uint32(len(der)),
+ CertInfo: certInfo,
+ }
+}
+
+func certNameBlobForTest(value []byte) windows.CertNameBlob {
+ return windows.CertNameBlob{
+ Size: uint32(len(value)),
+ Data: (*byte)(unsafe.Pointer(&value[0])),
+ }
+}
diff --git a/common/schannel/syscall_windows.go b/common/schannel/syscall_windows.go
new file mode 100644
index 0000000000..654869b664
--- /dev/null
+++ b/common/schannel/syscall_windows.go
@@ -0,0 +1,28 @@
+package schannel
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go syscall_windows.go
+
+// secur32.dll — SSPI / Schannel interface
+
+//sys sspiAcquireCredentialsHandle(principal *uint16, pkgname *uint16, credentialUse uint32, logonID *uint64, authData unsafe.Pointer, getKeyFn uintptr, getKeyArg uintptr, credential *secHandle, expiry *windows.Filetime) (ret syscall.Errno) = secur32.AcquireCredentialsHandleW
+//sys sspiFreeCredentialsHandle(credential *secHandle) (ret syscall.Errno) = secur32.FreeCredentialsHandle
+//sys sspiInitializeSecurityContext(credential *secHandle, context *secHandle, targetName *uint16, contextReq uint32, reserved1 uint32, targetDataRep uint32, input *secBufferDesc, reserved2 uint32, newContext *secHandle, output *secBufferDesc, contextAttr *uint32, expiry *windows.Filetime) (ret syscall.Errno) = secur32.InitializeSecurityContextW
+//sys sspiDeleteSecurityContext(context *secHandle) (ret syscall.Errno) = secur32.DeleteSecurityContext
+//sys sspiQueryContextAttributes(context *secHandle, attribute uint32, buffer unsafe.Pointer) (ret syscall.Errno) = secur32.QueryContextAttributesW
+//sys sspiEncryptMessage(context *secHandle, qop uint32, message *secBufferDesc, sequenceNumber uint32) (ret syscall.Errno) = secur32.EncryptMessage
+//sys sspiDecryptMessage(context *secHandle, message *secBufferDesc, sequenceNumber uint32, qop *uint32) (ret syscall.Errno) = secur32.DecryptMessage
+//sys sspiFreeContextBuffer(buffer *byte) (ret syscall.Errno) = secur32.FreeContextBuffer
+
+// mkwinsyscall does not emit CompleteAuthToken for this package, so bind it manually.
+var procCompleteAuthToken = modsecur32.NewProc("CompleteAuthToken")
+
+func sspiCompleteAuthToken(context *secHandle, token *secBufferDesc) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procCompleteAuthToken.Addr(), uintptr(unsafe.Pointer(context)), uintptr(unsafe.Pointer(token)))
+ ret = syscall.Errno(r0)
+ return
+}
diff --git a/common/schannel/types_windows.go b/common/schannel/types_windows.go
new file mode 100644
index 0000000000..fd4f8b5439
--- /dev/null
+++ b/common/schannel/types_windows.go
@@ -0,0 +1,161 @@
+package schannel
+
+import (
+ "syscall"
+
+ "golang.org/x/sys/windows"
+)
+
+const (
+ unispNameW = "Microsoft Unified Security Protocol Provider"
+
+ schCredentialsVersion = 5
+
+ secPkgCredOutbound = 2
+
+ iscReqSequenceDetect = 0x00000008
+ iscReqReplayDetect = 0x00000004
+ iscReqConfidentiality = 0x00000010
+ iscReqAllocateMemory = 0x00000100
+ iscReqStream = 0x00008000
+ iscReqUseSuppliedCreds = 0x00000080
+ iscReqManualCredValidation = 0x00080000
+ iscReqExtendedError = 0x00004000
+
+ secbufferEmpty = 0
+ secbufferData = 1
+ secbufferToken = 2
+ secbufferExtra = 5
+ secbufferStreamTrailer = 6
+ secbufferStreamHeader = 7
+ secbufferApplicationProtocols = 18
+ secbufferVersion = 0
+
+ secApplicationProtocolNegotiationExtALPN = 2
+
+ secApplicationProtocolNegotiationStatusSuccess = 1
+
+ schCredManualCredValidation = 0x00000008
+ schCredNoDefaultCreds = 0x00000010
+ schUseStrongCrypto = 0x00400000
+
+ spProtTLS10Client = 0x00000080
+ spProtTLS11Client = 0x00000200
+ spProtTLS12Client = 0x00000800
+ spProtTLS13Client = 0x00002000
+
+ spProtAllTLSClients = spProtTLS10Client | spProtTLS11Client | spProtTLS12Client | spProtTLS13Client
+
+ secpkgAttrStreamSizes = 4
+ secpkgAttrConnectionInfo = 0x5A
+ secpkgAttrApplicationProtocol = 0x23
+ secpkgAttrCipherInfo = 0x64
+ secpkgAttrRemoteCertContext = 0x53
+)
+
+const (
+ secEOK = syscall.Errno(windows.SEC_E_OK)
+ secICompleteNeeded = syscall.Errno(windows.SEC_I_COMPLETE_NEEDED)
+ secICompleteAndContinue = syscall.Errno(windows.SEC_I_COMPLETE_AND_CONTINUE)
+ secIContinueNeeded = syscall.Errno(windows.SEC_I_CONTINUE_NEEDED)
+ secIContextExpired = syscall.Errno(windows.SEC_I_CONTEXT_EXPIRED)
+ secIRenegotiate = syscall.Errno(windows.SEC_I_RENEGOTIATE)
+ secEIncompleteMessage = syscall.Errno(windows.SEC_E_INCOMPLETE_MESSAGE)
+ secEIncompleteCreds = syscall.Errno(windows.SEC_E_INCOMPLETE_CREDENTIALS)
+ secEBufferTooSmall = syscall.Errno(windows.SEC_E_BUFFER_TOO_SMALL)
+ secEMessageAltered = syscall.Errno(windows.SEC_E_MESSAGE_ALTERED)
+ secEContextExpired = syscall.Errno(windows.SEC_E_CONTEXT_EXPIRED)
+ secEUnsupportedFunc = syscall.Errno(windows.SEC_E_UNSUPPORTED_FUNCTION)
+ secEInvalidToken = syscall.Errno(windows.SEC_E_INVALID_TOKEN)
+ secELogonDenied = syscall.Errno(windows.SEC_E_LOGON_DENIED)
+ secEIllegalMessage = syscall.Errno(windows.SEC_E_ILLEGAL_MESSAGE)
+ secEWrongPrincipal = syscall.Errno(windows.SEC_E_WRONG_PRINCIPAL)
+ secECertUnknown = syscall.Errno(windows.SEC_E_CERT_UNKNOWN)
+ secECertExpired = syscall.Errno(windows.SEC_E_CERT_EXPIRED)
+ secEAlgorithmMismatch = syscall.Errno(windows.SEC_E_ALGORITHM_MISMATCH)
+ secEInternalError = syscall.Errno(windows.SEC_E_INTERNAL_ERROR)
+ secENoAuthenticatingAuthority = syscall.Errno(windows.SEC_E_NO_AUTHENTICATING_AUTHORITY)
+)
+
+type secHandle struct {
+ lower uintptr
+ upper uintptr
+}
+
+type secBuffer struct {
+ cbBuffer uint32
+ bufferType uint32
+ pvBuffer *byte
+}
+
+type secBufferDesc struct {
+ ulVersion uint32
+ cBuffers uint32
+ pBuffers *secBuffer
+}
+
+type schCredentials struct {
+ dwVersion uint32
+ dwCredFormat uint32
+ cCreds uint32
+ paCred uintptr
+ hRootStore windows.Handle
+ cMappers uint32
+ aphMappers uintptr
+ dwSessionLifespan uint32
+ dwFlags uint32
+ cTlsParameters uint32
+ pTlsParameters *tlsParameters
+}
+
+type tlsParameters struct {
+ _ uint32 // cAlpnIds
+ _ uintptr // rgstrAlpnIds
+ grbitDisabledProtocols uint32
+ _ uint32 // cDisabledCrypto
+ _ uintptr // pDisabledCrypto
+ _ uint32 // dwFlags
+}
+
+type secPkgContextStreamSizes struct {
+ cbHeader uint32
+ cbTrailer uint32
+ cbMaximumMessage uint32
+ cBuffers uint32
+ cbBlockSize uint32
+}
+
+type secPkgContextConnectionInfo struct {
+ dwProtocol uint32
+ aiCipher uint32
+ dwCipherStrength uint32
+ aiHash uint32
+ dwHashStrength uint32
+ aiExch uint32
+ dwExchStrength uint32
+}
+
+type secPkgContextApplicationProtocol struct {
+ protoNegoStatus uint32
+ protoNegoExt uint32
+ protocolIDSize byte
+ protocolID [255]byte
+}
+
+type secPkgContextCipherInfo struct {
+ dwVersion uint32
+ dwProtocol uint32
+ dwCipherSuite uint32
+ dwBaseCipherSuite uint32
+ szCipherSuite [64]uint16
+ szCipher [64]uint16
+ dwCipherLen uint32
+ dwCipherBlockLen uint32
+ szHash [64]uint16
+ dwHashLen uint32
+ szExchange [64]uint16
+ dwMinExchangeLen uint32
+ dwMaxExchangeLen uint32
+ szCertificate [64]uint16
+ dwKeyType uint32
+}
diff --git a/common/schannel/zsyscall_windows.go b/common/schannel/zsyscall_windows.go
new file mode 100644
index 0000000000..85a7bc8087
--- /dev/null
+++ b/common/schannel/zsyscall_windows.go
@@ -0,0 +1,99 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package schannel
+
+import (
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modsecur32 = windows.NewLazySystemDLL("secur32.dll")
+
+ procAcquireCredentialsHandleW = modsecur32.NewProc("AcquireCredentialsHandleW")
+ procDecryptMessage = modsecur32.NewProc("DecryptMessage")
+ procDeleteSecurityContext = modsecur32.NewProc("DeleteSecurityContext")
+ procEncryptMessage = modsecur32.NewProc("EncryptMessage")
+ procFreeContextBuffer = modsecur32.NewProc("FreeContextBuffer")
+ procFreeCredentialsHandle = modsecur32.NewProc("FreeCredentialsHandle")
+ procInitializeSecurityContextW = modsecur32.NewProc("InitializeSecurityContextW")
+ procQueryContextAttributesW = modsecur32.NewProc("QueryContextAttributesW")
+)
+
+func sspiAcquireCredentialsHandle(principal *uint16, pkgname *uint16, credentialUse uint32, logonID *uint64, authData unsafe.Pointer, getKeyFn uintptr, getKeyArg uintptr, credential *secHandle, expiry *windows.Filetime) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procAcquireCredentialsHandleW.Addr(), uintptr(unsafe.Pointer(principal)), uintptr(unsafe.Pointer(pkgname)), uintptr(credentialUse), uintptr(unsafe.Pointer(logonID)), uintptr(authData), uintptr(getKeyFn), uintptr(getKeyArg), uintptr(unsafe.Pointer(credential)), uintptr(unsafe.Pointer(expiry)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiDecryptMessage(context *secHandle, message *secBufferDesc, sequenceNumber uint32, qop *uint32) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procDecryptMessage.Addr(), uintptr(unsafe.Pointer(context)), uintptr(unsafe.Pointer(message)), uintptr(sequenceNumber), uintptr(unsafe.Pointer(qop)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiDeleteSecurityContext(context *secHandle) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procDeleteSecurityContext.Addr(), uintptr(unsafe.Pointer(context)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiEncryptMessage(context *secHandle, qop uint32, message *secBufferDesc, sequenceNumber uint32) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procEncryptMessage.Addr(), uintptr(unsafe.Pointer(context)), uintptr(qop), uintptr(unsafe.Pointer(message)), uintptr(sequenceNumber))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiFreeContextBuffer(buffer *byte) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procFreeContextBuffer.Addr(), uintptr(unsafe.Pointer(buffer)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiFreeCredentialsHandle(credential *secHandle) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procFreeCredentialsHandle.Addr(), uintptr(unsafe.Pointer(credential)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiInitializeSecurityContext(credential *secHandle, context *secHandle, targetName *uint16, contextReq uint32, reserved1 uint32, targetDataRep uint32, input *secBufferDesc, reserved2 uint32, newContext *secHandle, output *secBufferDesc, contextAttr *uint32, expiry *windows.Filetime) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procInitializeSecurityContextW.Addr(), uintptr(unsafe.Pointer(credential)), uintptr(unsafe.Pointer(context)), uintptr(unsafe.Pointer(targetName)), uintptr(contextReq), uintptr(reserved1), uintptr(targetDataRep), uintptr(unsafe.Pointer(input)), uintptr(reserved2), uintptr(unsafe.Pointer(newContext)), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(contextAttr)), uintptr(unsafe.Pointer(expiry)))
+ ret = syscall.Errno(r0)
+ return
+}
+
+func sspiQueryContextAttributes(context *secHandle, attribute uint32, buffer unsafe.Pointer) (ret syscall.Errno) {
+ r0, _, _ := syscall.SyscallN(procQueryContextAttributesW.Addr(), uintptr(unsafe.Pointer(context)), uintptr(attribute), uintptr(buffer))
+ ret = syscall.Errno(r0)
+ return
+}
diff --git a/common/srs/binary.go b/common/srs/binary.go
index d2c865e177..e625ac89c8 100644
--- a/common/srs/binary.go
+++ b/common/srs/binary.go
@@ -6,7 +6,6 @@ import (
"encoding/binary"
"io"
"net/netip"
- "unsafe"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
@@ -46,6 +45,7 @@ const (
ruleItemNetworkIsConstrained
ruleItemNetworkInterfaceAddress
ruleItemDefaultInterfaceAddress
+ ruleItemPackageNameRegex
ruleItemFinal uint8 = 0xFF
)
@@ -215,6 +215,8 @@ func readDefaultRule(reader varbin.Reader, recover bool) (rule option.DefaultHea
rule.ProcessPathRegex, err = readRuleItemString(reader)
case ruleItemPackageName:
rule.PackageName, err = readRuleItemString(reader)
+ case ruleItemPackageNameRegex:
+ rule.PackageNameRegex, err = readRuleItemString(reader)
case ruleItemWIFISSID:
rule.WIFISSID, err = readRuleItemString(reader)
case ruleItemWIFIBSSID:
@@ -394,6 +396,15 @@ func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessRule, gen
return err
}
}
+ if len(rule.PackageNameRegex) > 0 {
+ if generateVersion < C.RuleSetVersion5 {
+ return E.New("`package_name_regex` rule item is only supported in version 5 or later")
+ }
+ err = writeRuleItemString(writer, ruleItemPackageNameRegex, rule.PackageNameRegex)
+ if err != nil {
+ return err
+ }
+ }
if len(rule.NetworkType) > 0 {
if generateVersion < C.RuleSetVersion3 {
return E.New("`network_type` rule item is only supported in version 3 or later")
@@ -506,24 +517,7 @@ func writeDefaultRule(writer varbin.Writer, rule option.DefaultHeadlessRule, gen
}
func readRuleItemString(reader varbin.Reader) ([]string, error) {
- length, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- result := make([]string, length)
- for i := range result {
- strLen, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- buf := make([]byte, strLen)
- _, err = io.ReadFull(reader, buf)
- if err != nil {
- return nil, err
- }
- result[i] = string(buf)
- }
- return result, nil
+ return varbin.ReadValue[[]string](reader, binary.BigEndian)
}
func writeRuleItemString(writer varbin.Writer, itemType uint8, value []string) error {
@@ -531,34 +525,11 @@ func writeRuleItemString(writer varbin.Writer, itemType uint8, value []string) e
if err != nil {
return err
}
- _, err = varbin.WriteUvarint(writer, uint64(len(value)))
- if err != nil {
- return err
- }
- for _, s := range value {
- _, err = varbin.WriteUvarint(writer, uint64(len(s)))
- if err != nil {
- return err
- }
- _, err = writer.Write([]byte(s))
- if err != nil {
- return err
- }
- }
- return nil
+ return varbin.Write(writer, binary.BigEndian, value)
}
func readRuleItemUint8[E ~uint8](reader varbin.Reader) ([]E, error) {
- length, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- result := make([]E, length)
- _, err = io.ReadFull(reader, *(*[]byte)(unsafe.Pointer(&result)))
- if err != nil {
- return nil, err
- }
- return result, nil
+ return varbin.ReadValue[[]E](reader, binary.BigEndian)
}
func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, value []E) error {
@@ -566,25 +537,11 @@ func writeRuleItemUint8[E ~uint8](writer varbin.Writer, itemType uint8, value []
if err != nil {
return err
}
- _, err = varbin.WriteUvarint(writer, uint64(len(value)))
- if err != nil {
- return err
- }
- _, err = writer.Write(*(*[]byte)(unsafe.Pointer(&value)))
- return err
+ return varbin.Write(writer, binary.BigEndian, value)
}
func readRuleItemUint16(reader varbin.Reader) ([]uint16, error) {
- length, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- result := make([]uint16, length)
- err = binary.Read(reader, binary.BigEndian, result)
- if err != nil {
- return nil, err
- }
- return result, nil
+ return varbin.ReadValue[[]uint16](reader, binary.BigEndian)
}
func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []uint16) error {
@@ -592,11 +549,7 @@ func writeRuleItemUint16(writer varbin.Writer, itemType uint8, value []uint16) e
if err != nil {
return err
}
- _, err = varbin.WriteUvarint(writer, uint64(len(value)))
- if err != nil {
- return err
- }
- return binary.Write(writer, binary.BigEndian, value)
+ return varbin.Write(writer, binary.BigEndian, value)
}
func writeRuleItemCIDR(writer varbin.Writer, itemType uint8, value []string) error {
diff --git a/common/srs/ip_cidr.go b/common/srs/ip_cidr.go
index 7c81abda2b..93ae84ad32 100644
--- a/common/srs/ip_cidr.go
+++ b/common/srs/ip_cidr.go
@@ -2,7 +2,6 @@ package srs
import (
"encoding/binary"
- "io"
"net/netip"
M "github.com/sagernet/sing/common/metadata"
@@ -10,16 +9,11 @@ import (
)
func readPrefix(reader varbin.Reader) (netip.Prefix, error) {
- addrLen, err := binary.ReadUvarint(reader)
+ addrSlice, err := varbin.ReadValue[[]byte](reader, binary.BigEndian)
if err != nil {
return netip.Prefix{}, err
}
- addrSlice := make([]byte, addrLen)
- _, err = io.ReadFull(reader, addrSlice)
- if err != nil {
- return netip.Prefix{}, err
- }
- prefixBits, err := reader.ReadByte()
+ prefixBits, err := varbin.ReadValue[uint8](reader, binary.BigEndian)
if err != nil {
return netip.Prefix{}, err
}
@@ -27,16 +21,11 @@ func readPrefix(reader varbin.Reader) (netip.Prefix, error) {
}
func writePrefix(writer varbin.Writer, prefix netip.Prefix) error {
- addrSlice := prefix.Addr().AsSlice()
- _, err := varbin.WriteUvarint(writer, uint64(len(addrSlice)))
- if err != nil {
- return err
- }
- _, err = writer.Write(addrSlice)
+ err := varbin.Write(writer, binary.BigEndian, prefix.Addr().AsSlice())
if err != nil {
return err
}
- err = writer.WriteByte(uint8(prefix.Bits()))
+ err = binary.Write(writer, binary.BigEndian, uint8(prefix.Bits()))
if err != nil {
return err
}
diff --git a/common/srs/ip_set.go b/common/srs/ip_set.go
index a10ac08c0f..044dc823b3 100644
--- a/common/srs/ip_set.go
+++ b/common/srs/ip_set.go
@@ -2,11 +2,11 @@ package srs
import (
"encoding/binary"
- "io"
"net/netip"
"os"
"unsafe"
+ "github.com/sagernet/sing/common"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/varbin"
@@ -22,6 +22,11 @@ type myIPRange struct {
to netip.Addr
}
+type myIPRangeData struct {
+ From []byte
+ To []byte
+}
+
func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
version, err := reader.ReadByte()
if err != nil {
@@ -36,30 +41,17 @@ func readIPSet(reader varbin.Reader) (*netipx.IPSet, error) {
if err != nil {
return nil, err
}
+ ranges := make([]myIPRangeData, length)
+ err = varbin.Read(reader, binary.BigEndian, &ranges)
+ if err != nil {
+ return nil, err
+ }
mySet := &myIPSet{
- rr: make([]myIPRange, length),
+ rr: make([]myIPRange, len(ranges)),
}
- for i := range mySet.rr {
- fromLen, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- fromBytes := make([]byte, fromLen)
- _, err = io.ReadFull(reader, fromBytes)
- if err != nil {
- return nil, err
- }
- toLen, err := binary.ReadUvarint(reader)
- if err != nil {
- return nil, err
- }
- toBytes := make([]byte, toLen)
- _, err = io.ReadFull(reader, toBytes)
- if err != nil {
- return nil, err
- }
- mySet.rr[i].from = M.AddrFromIP(fromBytes)
- mySet.rr[i].to = M.AddrFromIP(toBytes)
+ for i, rangeData := range ranges {
+ mySet.rr[i].from = M.AddrFromIP(rangeData.From)
+ mySet.rr[i].to = M.AddrFromIP(rangeData.To)
}
return (*netipx.IPSet)(unsafe.Pointer(mySet)), nil
}
@@ -69,27 +61,18 @@ func writeIPSet(writer varbin.Writer, set *netipx.IPSet) error {
if err != nil {
return err
}
- mySet := (*myIPSet)(unsafe.Pointer(set))
- err = binary.Write(writer, binary.BigEndian, uint64(len(mySet.rr)))
+ dataList := common.Map((*myIPSet)(unsafe.Pointer(set)).rr, func(rr myIPRange) myIPRangeData {
+ return myIPRangeData{
+ From: rr.from.AsSlice(),
+ To: rr.to.AsSlice(),
+ }
+ })
+ err = binary.Write(writer, binary.BigEndian, uint64(len(dataList)))
if err != nil {
return err
}
- for _, rr := range mySet.rr {
- fromBytes := rr.from.AsSlice()
- _, err = varbin.WriteUvarint(writer, uint64(len(fromBytes)))
- if err != nil {
- return err
- }
- _, err = writer.Write(fromBytes)
- if err != nil {
- return err
- }
- toBytes := rr.to.AsSlice()
- _, err = varbin.WriteUvarint(writer, uint64(len(toBytes)))
- if err != nil {
- return err
- }
- _, err = writer.Write(toBytes)
+ for _, data := range dataList {
+ err = varbin.Write(writer, binary.BigEndian, data)
if err != nil {
return err
}
diff --git a/common/stun/stun.go b/common/stun/stun.go
new file mode 100644
index 0000000000..a4bb9d5cc8
--- /dev/null
+++ b/common/stun/stun.go
@@ -0,0 +1,612 @@
+package stun
+
+import (
+ "context"
+ "crypto/rand"
+ "encoding/binary"
+ "fmt"
+ "net"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing/common/bufio"
+ "github.com/sagernet/sing/common/bufio/deadline"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const (
+ DefaultServer = "stun.voipgate.com:3478"
+
+ magicCookie = 0x2112A442
+ headerSize = 20
+
+ bindingRequest = 0x0001
+ bindingSuccessResponse = 0x0101
+ bindingErrorResponse = 0x0111
+
+ attrMappedAddress = 0x0001
+ attrChangeRequest = 0x0003
+ attrErrorCode = 0x0009
+ attrXORMappedAddress = 0x0020
+ attrOtherAddress = 0x802c
+
+ familyIPv4 = 0x01
+ familyIPv6 = 0x02
+
+ changeIP = 0x04
+ changePort = 0x02
+
+ defaultRTO = 500 * time.Millisecond
+ minRTO = 250 * time.Millisecond
+ maxRetransmit = 2
+)
+
+type Phase int32
+
+const (
+ PhaseBinding Phase = iota
+ PhaseNATMapping
+ PhaseNATFiltering
+ PhaseDone
+)
+
+type NATMapping int32
+
+const (
+ NATMappingUnknown NATMapping = iota
+ _ // reserved
+ NATMappingEndpointIndependent
+ NATMappingAddressDependent
+ NATMappingAddressAndPortDependent
+)
+
+func (m NATMapping) String() string {
+ switch m {
+ case NATMappingEndpointIndependent:
+ return "Endpoint Independent"
+ case NATMappingAddressDependent:
+ return "Address Dependent"
+ case NATMappingAddressAndPortDependent:
+ return "Address and Port Dependent"
+ default:
+ return "Unknown"
+ }
+}
+
+type NATFiltering int32
+
+const (
+ NATFilteringUnknown NATFiltering = iota
+ NATFilteringEndpointIndependent
+ NATFilteringAddressDependent
+ NATFilteringAddressAndPortDependent
+)
+
+func (f NATFiltering) String() string {
+ switch f {
+ case NATFilteringEndpointIndependent:
+ return "Endpoint Independent"
+ case NATFilteringAddressDependent:
+ return "Address Dependent"
+ case NATFilteringAddressAndPortDependent:
+ return "Address and Port Dependent"
+ default:
+ return "Unknown"
+ }
+}
+
+type TransactionID [12]byte
+
+type Options struct {
+ Server string
+ Dialer N.Dialer
+ Context context.Context
+ OnProgress func(Progress)
+}
+
+type Progress struct {
+ Phase Phase
+ ExternalAddr string
+ LatencyMs int32
+ NATMapping NATMapping
+ NATFiltering NATFiltering
+}
+
+type Result struct {
+ ExternalAddr string
+ LatencyMs int32
+ NATMapping NATMapping
+ NATFiltering NATFiltering
+ NATTypeSupported bool
+}
+
+type parsedResponse struct {
+ xorMappedAddr netip.AddrPort
+ mappedAddr netip.AddrPort
+ otherAddr netip.AddrPort
+}
+
+func (r *parsedResponse) externalAddr() (netip.AddrPort, bool) {
+ if r.xorMappedAddr.IsValid() {
+ return r.xorMappedAddr, true
+ }
+ if r.mappedAddr.IsValid() {
+ return r.mappedAddr, true
+ }
+ return netip.AddrPort{}, false
+}
+
+type stunAttribute struct {
+ typ uint16
+ value []byte
+}
+
+func newTransactionID() TransactionID {
+ var id TransactionID
+ _, _ = rand.Read(id[:])
+ return id
+}
+
+func buildBindingRequest(txID TransactionID, attrs ...stunAttribute) []byte {
+ attrLen := 0
+ for _, attr := range attrs {
+ attrLen += 4 + len(attr.value) + paddingLen(len(attr.value))
+ }
+
+ buf := make([]byte, headerSize+attrLen)
+ binary.BigEndian.PutUint16(buf[0:2], bindingRequest)
+ binary.BigEndian.PutUint16(buf[2:4], uint16(attrLen))
+ binary.BigEndian.PutUint32(buf[4:8], magicCookie)
+ copy(buf[8:20], txID[:])
+
+ offset := headerSize
+ for _, attr := range attrs {
+ binary.BigEndian.PutUint16(buf[offset:offset+2], attr.typ)
+ binary.BigEndian.PutUint16(buf[offset+2:offset+4], uint16(len(attr.value)))
+ copy(buf[offset+4:offset+4+len(attr.value)], attr.value)
+ offset += 4 + len(attr.value) + paddingLen(len(attr.value))
+ }
+
+ return buf
+}
+
+func changeRequestAttr(flags byte) stunAttribute {
+ return stunAttribute{
+ typ: attrChangeRequest,
+ value: []byte{0, 0, 0, flags},
+ }
+}
+
+func parseResponse(data []byte, expectedTxID TransactionID) (*parsedResponse, error) {
+ if len(data) < headerSize {
+ return nil, E.New("response too short")
+ }
+
+ msgType := binary.BigEndian.Uint16(data[0:2])
+ if msgType&0xC000 != 0 {
+ return nil, E.New("invalid STUN message: top 2 bits not zero")
+ }
+
+ cookie := binary.BigEndian.Uint32(data[4:8])
+ if cookie != magicCookie {
+ return nil, E.New("invalid magic cookie")
+ }
+
+ var txID TransactionID
+ copy(txID[:], data[8:20])
+ if txID != expectedTxID {
+ return nil, E.New("transaction ID mismatch")
+ }
+
+ msgLen := int(binary.BigEndian.Uint16(data[2:4]))
+ if msgLen > len(data)-headerSize {
+ return nil, E.New("message length exceeds data")
+ }
+
+ attrData := data[headerSize : headerSize+msgLen]
+
+ if msgType == bindingErrorResponse {
+ return nil, parseErrorResponse(attrData)
+ }
+ if msgType != bindingSuccessResponse {
+ return nil, E.New("unexpected message type: ", fmt.Sprintf("0x%04x", msgType))
+ }
+
+ resp := &parsedResponse{}
+ offset := 0
+ for offset+4 <= len(attrData) {
+ attrType := binary.BigEndian.Uint16(attrData[offset : offset+2])
+ attrLen := int(binary.BigEndian.Uint16(attrData[offset+2 : offset+4]))
+ if offset+4+attrLen > len(attrData) {
+ break
+ }
+ attrValue := attrData[offset+4 : offset+4+attrLen]
+
+ switch attrType {
+ case attrXORMappedAddress:
+ addr, err := parseXORMappedAddress(attrValue, txID)
+ if err == nil {
+ resp.xorMappedAddr = addr
+ }
+ case attrMappedAddress:
+ addr, err := parseMappedAddress(attrValue)
+ if err == nil {
+ resp.mappedAddr = addr
+ }
+ case attrOtherAddress:
+ addr, err := parseMappedAddress(attrValue)
+ if err == nil {
+ resp.otherAddr = addr
+ }
+ }
+
+ offset += 4 + attrLen + paddingLen(attrLen)
+ }
+
+ return resp, nil
+}
+
+func parseErrorResponse(data []byte) error {
+ offset := 0
+ for offset+4 <= len(data) {
+ attrType := binary.BigEndian.Uint16(data[offset : offset+2])
+ attrLen := int(binary.BigEndian.Uint16(data[offset+2 : offset+4]))
+ if offset+4+attrLen > len(data) {
+ break
+ }
+ if attrType == attrErrorCode && attrLen >= 4 {
+ attrValue := data[offset+4 : offset+4+attrLen]
+ class := int(attrValue[2] & 0x07)
+ number := int(attrValue[3])
+ code := class*100 + number
+ if attrLen > 4 {
+ return E.New("STUN error ", code, ": ", string(attrValue[4:]))
+ }
+ return E.New("STUN error ", code)
+ }
+ offset += 4 + attrLen + paddingLen(attrLen)
+ }
+ return E.New("STUN error response")
+}
+
+func parseXORMappedAddress(data []byte, txID TransactionID) (netip.AddrPort, error) {
+ if len(data) < 4 {
+ return netip.AddrPort{}, E.New("XOR-MAPPED-ADDRESS too short")
+ }
+
+ family := data[1]
+ xPort := binary.BigEndian.Uint16(data[2:4])
+ port := xPort ^ uint16(magicCookie>>16)
+
+ switch family {
+ case familyIPv4:
+ if len(data) < 8 {
+ return netip.AddrPort{}, E.New("XOR-MAPPED-ADDRESS IPv4 too short")
+ }
+ var ip [4]byte
+ binary.BigEndian.PutUint32(ip[:], binary.BigEndian.Uint32(data[4:8])^magicCookie)
+ return netip.AddrPortFrom(netip.AddrFrom4(ip), port), nil
+ case familyIPv6:
+ if len(data) < 20 {
+ return netip.AddrPort{}, E.New("XOR-MAPPED-ADDRESS IPv6 too short")
+ }
+ var ip [16]byte
+ var xorKey [16]byte
+ binary.BigEndian.PutUint32(xorKey[0:4], magicCookie)
+ copy(xorKey[4:16], txID[:])
+ for i := range 16 {
+ ip[i] = data[4+i] ^ xorKey[i]
+ }
+ return netip.AddrPortFrom(netip.AddrFrom16(ip), port), nil
+ default:
+ return netip.AddrPort{}, E.New("unknown address family: ", family)
+ }
+}
+
+func parseMappedAddress(data []byte) (netip.AddrPort, error) {
+ if len(data) < 4 {
+ return netip.AddrPort{}, E.New("MAPPED-ADDRESS too short")
+ }
+
+ family := data[1]
+ port := binary.BigEndian.Uint16(data[2:4])
+
+ switch family {
+ case familyIPv4:
+ if len(data) < 8 {
+ return netip.AddrPort{}, E.New("MAPPED-ADDRESS IPv4 too short")
+ }
+ return netip.AddrPortFrom(
+ netip.AddrFrom4([4]byte{data[4], data[5], data[6], data[7]}), port,
+ ), nil
+ case familyIPv6:
+ if len(data) < 20 {
+ return netip.AddrPort{}, E.New("MAPPED-ADDRESS IPv6 too short")
+ }
+ var ip [16]byte
+ copy(ip[:], data[4:20])
+ return netip.AddrPortFrom(netip.AddrFrom16(ip), port), nil
+ default:
+ return netip.AddrPort{}, E.New("unknown address family: ", family)
+ }
+}
+
+func roundTrip(conn net.PacketConn, addr net.Addr, txID TransactionID, attrs []stunAttribute, rto time.Duration) (*parsedResponse, time.Duration, error) {
+ request := buildBindingRequest(txID, attrs...)
+ currentRTO := rto
+ retransmitCount := 0
+
+ sendTime := time.Now()
+ _, err := conn.WriteTo(request, addr)
+ if err != nil {
+ return nil, 0, E.Cause(err, "send STUN request")
+ }
+
+ buf := make([]byte, 1024)
+ for {
+ err = conn.SetReadDeadline(sendTime.Add(currentRTO))
+ if err != nil {
+ return nil, 0, E.Cause(err, "set read deadline")
+ }
+
+ n, _, readErr := conn.ReadFrom(buf)
+ if readErr != nil {
+ if E.IsTimeout(readErr) && retransmitCount < maxRetransmit {
+ retransmitCount++
+ currentRTO *= 2
+ sendTime = time.Now()
+ _, err = conn.WriteTo(request, addr)
+ if err != nil {
+ return nil, 0, E.Cause(err, "retransmit STUN request")
+ }
+ continue
+ }
+ return nil, 0, E.Cause(readErr, "read STUN response")
+ }
+
+ if n < headerSize || buf[0]&0xC0 != 0 ||
+ binary.BigEndian.Uint32(buf[4:8]) != magicCookie {
+ continue
+ }
+ var receivedTxID TransactionID
+ copy(receivedTxID[:], buf[8:20])
+ if receivedTxID != txID {
+ continue
+ }
+
+ latency := time.Since(sendTime)
+
+ resp, parseErr := parseResponse(buf[:n], txID)
+ if parseErr != nil {
+ return nil, 0, parseErr
+ }
+
+ return resp, latency, nil
+ }
+}
+
+func Run(options Options) (*Result, error) {
+ ctx := options.Context
+ if ctx == nil {
+ ctx = context.Background()
+ }
+
+ server := options.Server
+ if server == "" {
+ server = DefaultServer
+ }
+ serverSocksaddr := M.ParseSocksaddr(server)
+ if serverSocksaddr.Port == 0 {
+ serverSocksaddr.Port = 3478
+ }
+
+ reportProgress := options.OnProgress
+ if reportProgress == nil {
+ reportProgress = func(Progress) {}
+ }
+
+ var (
+ packetConn net.PacketConn
+ serverAddr net.Addr
+ err error
+ )
+
+ if options.Dialer != nil {
+ packetConn, err = options.Dialer.ListenPacket(ctx, serverSocksaddr)
+ if err != nil {
+ return nil, E.Cause(err, "create UDP socket")
+ }
+ serverAddr = serverSocksaddr
+ } else {
+ serverUDPAddr, resolveErr := net.ResolveUDPAddr("udp", serverSocksaddr.String())
+ if resolveErr != nil {
+ return nil, E.Cause(resolveErr, "resolve STUN server")
+ }
+ packetConn, err = net.ListenPacket("udp", "")
+ if err != nil {
+ return nil, E.Cause(err, "create UDP socket")
+ }
+ serverAddr = serverUDPAddr
+ }
+ defer func() {
+ _ = packetConn.Close()
+ }()
+ if deadline.NeedAdditionalReadDeadline(packetConn) {
+ packetConn = deadline.NewPacketConn(bufio.NewPacketConn(packetConn))
+ }
+
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+
+ rto := defaultRTO
+
+ // Phase 1: Binding
+ reportProgress(Progress{Phase: PhaseBinding})
+
+ txID := newTransactionID()
+ resp, latency, err := roundTrip(packetConn, serverAddr, txID, nil, rto)
+ if err != nil {
+ return nil, E.Cause(err, "binding request")
+ }
+
+ rto = max(minRTO, 3*latency)
+
+ externalAddr, ok := resp.externalAddr()
+ if !ok {
+ return nil, E.New("no mapped address in response")
+ }
+
+ result := &Result{
+ ExternalAddr: externalAddr.String(),
+ LatencyMs: int32(latency.Milliseconds()),
+ }
+
+ reportProgress(Progress{
+ Phase: PhaseBinding,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ })
+
+ otherAddr := resp.otherAddr
+ if !otherAddr.IsValid() {
+ result.NATTypeSupported = false
+ reportProgress(Progress{
+ Phase: PhaseDone,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ })
+ return result, nil
+ }
+ result.NATTypeSupported = true
+
+ select {
+ case <-ctx.Done():
+ return result, nil
+ default:
+ }
+
+ // Phase 2: NAT Mapping Detection (RFC 5780 Section 4.3)
+ reportProgress(Progress{
+ Phase: PhaseNATMapping,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ })
+
+ result.NATMapping = detectNATMapping(
+ packetConn, serverSocksaddr.Port, externalAddr, otherAddr, rto,
+ )
+
+ reportProgress(Progress{
+ Phase: PhaseNATMapping,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ NATMapping: result.NATMapping,
+ })
+
+ select {
+ case <-ctx.Done():
+ return result, nil
+ default:
+ }
+
+ // Phase 3: NAT Filtering Detection (RFC 5780 Section 4.4)
+ reportProgress(Progress{
+ Phase: PhaseNATFiltering,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ NATMapping: result.NATMapping,
+ })
+
+ result.NATFiltering = detectNATFiltering(packetConn, serverAddr, rto)
+
+ reportProgress(Progress{
+ Phase: PhaseDone,
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ NATMapping: result.NATMapping,
+ NATFiltering: result.NATFiltering,
+ })
+
+ return result, nil
+}
+
+func detectNATMapping(
+ conn net.PacketConn,
+ serverPort uint16,
+ externalAddr netip.AddrPort,
+ otherAddr netip.AddrPort,
+ rto time.Duration,
+) NATMapping {
+ // Mapping Test II: Send to other_ip:server_port
+ testIIAddr := net.UDPAddrFromAddrPort(
+ netip.AddrPortFrom(otherAddr.Addr(), serverPort),
+ )
+ txID2 := newTransactionID()
+ resp2, _, err := roundTrip(conn, testIIAddr, txID2, nil, rto)
+ if err != nil {
+ return NATMappingUnknown
+ }
+
+ externalAddr2, ok := resp2.externalAddr()
+ if !ok {
+ return NATMappingUnknown
+ }
+
+ if externalAddr == externalAddr2 {
+ return NATMappingEndpointIndependent
+ }
+
+ // Mapping Test III: Send to other_ip:other_port
+ testIIIAddr := net.UDPAddrFromAddrPort(otherAddr)
+ txID3 := newTransactionID()
+ resp3, _, err := roundTrip(conn, testIIIAddr, txID3, nil, rto)
+ if err != nil {
+ return NATMappingUnknown
+ }
+
+ externalAddr3, ok := resp3.externalAddr()
+ if !ok {
+ return NATMappingUnknown
+ }
+
+ if externalAddr2 == externalAddr3 {
+ return NATMappingAddressDependent
+ }
+ return NATMappingAddressAndPortDependent
+}
+
+func detectNATFiltering(
+ conn net.PacketConn,
+ serverAddr net.Addr,
+ rto time.Duration,
+) NATFiltering {
+ // Filtering Test II: Request response from different IP and port
+ txID := newTransactionID()
+ _, _, err := roundTrip(conn, serverAddr, txID,
+ []stunAttribute{changeRequestAttr(changeIP | changePort)}, rto)
+ if err == nil {
+ return NATFilteringEndpointIndependent
+ }
+
+ // Filtering Test III: Request response from different port only
+ txID = newTransactionID()
+ _, _, err = roundTrip(conn, serverAddr, txID,
+ []stunAttribute{changeRequestAttr(changePort)}, rto)
+ if err == nil {
+ return NATFilteringAddressDependent
+ }
+
+ return NATFilteringAddressAndPortDependent
+}
+
+func paddingLen(n int) int {
+ if n%4 == 0 {
+ return 0
+ }
+ return 4 - n%4
+}
diff --git a/common/tls/acme.go b/common/tls/acme.go
index c96e002c8a..93f293f6f2 100644
--- a/common/tls/acme.go
+++ b/common/tls/acme.go
@@ -5,6 +5,7 @@ package tls
import (
"context"
"crypto/tls"
+ "slices"
"strings"
"github.com/sagernet/sing-box/adapter"
@@ -38,37 +39,6 @@ func (w *acmeWrapper) Close() error {
return nil
}
-type acmeLogWriter struct {
- logger logger.Logger
-}
-
-func (w *acmeLogWriter) Write(p []byte) (n int, err error) {
- logLine := strings.ReplaceAll(string(p), " ", ": ")
- switch {
- case strings.HasPrefix(logLine, "error: "):
- w.logger.Error(logLine[7:])
- case strings.HasPrefix(logLine, "warn: "):
- w.logger.Warn(logLine[6:])
- case strings.HasPrefix(logLine, "info: "):
- w.logger.Info(logLine[6:])
- case strings.HasPrefix(logLine, "debug: "):
- w.logger.Debug(logLine[7:])
- default:
- w.logger.Debug(logLine)
- }
- return len(p), nil
-}
-
-func (w *acmeLogWriter) Sync() error {
- return nil
-}
-
-func encoderConfig() zapcore.EncoderConfig {
- config := zap.NewProductionEncoderConfig()
- config.TimeKey = zapcore.OmitKey
- return config
-}
-
func startACME(ctx context.Context, logger logger.Logger, options option.InboundACMEOptions) (*tls.Config, adapter.SimpleLifecycle, error) {
var acmeServer string
switch options.Provider {
@@ -91,8 +61,8 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
storage = certmagic.Default.Storage
}
zapLogger := zap.New(zapcore.NewCore(
- zapcore.NewConsoleEncoder(encoderConfig()),
- &acmeLogWriter{logger: logger},
+ zapcore.NewConsoleEncoder(ACMEEncoderConfig()),
+ &ACMELogWriter{Logger: logger},
zap.DebugLevel,
))
config := &certmagic.Config{
@@ -100,10 +70,16 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
Storage: storage,
Logger: zapLogger,
}
+ profile := options.Profile
+ if profile == "" && acmeServer == certmagic.LetsEncryptProductionCA && slices.ContainsFunc(options.Domain, certmagic.SubjectIsIP) {
+ profile = "shortlived"
+ }
+
acmeConfig := certmagic.ACMEIssuer{
CA: acmeServer,
Email: options.Email,
Agreed: true,
+ Profile: profile,
DisableHTTPChallenge: options.DisableHTTPChallenge,
DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
AltHTTPPort: int(options.AlternativeHTTPPort),
@@ -158,7 +134,7 @@ func startACME(ctx context.Context, logger logger.Logger, options option.Inbound
} else {
tlsConfig = &tls.Config{
GetCertificate: config.GetCertificate,
- NextProtos: []string{ACMETLS1Protocol},
+ NextProtos: []string{C.ACMETLS1Protocol},
}
}
return tlsConfig, &acmeWrapper{ctx: ctx, cfg: config, cache: cache, domain: options.Domain}, nil
diff --git a/common/tls/acme_contstant.go b/common/tls/acme_contstant.go
deleted file mode 100644
index c5cd2ff164..0000000000
--- a/common/tls/acme_contstant.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package tls
-
-const ACMETLS1Protocol = "acme-tls/1"
diff --git a/common/tls/acme_logger.go b/common/tls/acme_logger.go
new file mode 100644
index 0000000000..cb3a1e3ce3
--- /dev/null
+++ b/common/tls/acme_logger.go
@@ -0,0 +1,41 @@
+package tls
+
+import (
+ "strings"
+
+ "github.com/sagernet/sing/common/logger"
+
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+type ACMELogWriter struct {
+ Logger logger.Logger
+}
+
+func (w *ACMELogWriter) Write(p []byte) (n int, err error) {
+ logLine := strings.ReplaceAll(string(p), " ", ": ")
+ switch {
+ case strings.HasPrefix(logLine, "error: "):
+ w.Logger.Error(logLine[7:])
+ case strings.HasPrefix(logLine, "warn: "):
+ w.Logger.Warn(logLine[6:])
+ case strings.HasPrefix(logLine, "info: "):
+ w.Logger.Info(logLine[6:])
+ case strings.HasPrefix(logLine, "debug: "):
+ w.Logger.Debug(logLine[7:])
+ default:
+ w.Logger.Debug(logLine)
+ }
+ return len(p), nil
+}
+
+func (w *ACMELogWriter) Sync() error {
+ return nil
+}
+
+func ACMEEncoderConfig() zapcore.EncoderConfig {
+ config := zap.NewProductionEncoderConfig()
+ config.TimeKey = zapcore.OmitKey
+ return config
+}
diff --git a/common/tls/apple_client.go b/common/tls/apple_client.go
new file mode 100644
index 0000000000..441c29b34b
--- /dev/null
+++ b/common/tls/apple_client.go
@@ -0,0 +1,44 @@
+//go:build darwin && cgo
+
+package tls
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/certificate"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/logger"
+)
+
+const appleTLSEngineName = "Apple TLS engine"
+
+type appleClientConfig struct {
+ systemTLSConfig
+ userPEM []byte
+}
+
+func (c *appleClientConfig) Clone() Config {
+ return &appleClientConfig{
+ systemTLSConfig: c.systemTLSConfig.clone(),
+ userPEM: append([]byte(nil), c.userPEM...),
+ }
+}
+
+func (c *appleClientConfig) resolveAnchors() (adapter.AppleAnchors, error) {
+ if len(c.userPEM) > 0 {
+ return certificate.NewAppleAnchors(c.userPEM)
+ }
+ return certificate.AcquireAnchors(nil, c.store), nil
+}
+
+func newAppleClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
+ base, validated, err := newSystemTLSConfig(ctx, serverAddress, options, allowEmptyServerName, appleTLSEngineName)
+ if err != nil {
+ return nil, err
+ }
+ return &appleClientConfig{
+ systemTLSConfig: base,
+ userPEM: append([]byte(nil), validated.UserPEM...),
+ }, nil
+}
diff --git a/common/tls/apple_client_platform.go b/common/tls/apple_client_platform.go
new file mode 100644
index 0000000000..9e2b7b53e0
--- /dev/null
+++ b/common/tls/apple_client_platform.go
@@ -0,0 +1,713 @@
+//go:build darwin && cgo
+
+package tls
+
+/*
+#cgo CFLAGS: -x objective-c -fobjc-arc
+#cgo LDFLAGS: -framework Foundation -framework Network -framework Security
+
+#include
+#include "apple_client_platform_darwin.h"
+*/
+import "C"
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/binary"
+ "io"
+ "math"
+ "net"
+ "os"
+ "runtime/cgo"
+ "strings"
+ "sync"
+ "time"
+ "unsafe"
+
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ N "github.com/sagernet/sing/common/network"
+
+ "golang.org/x/sys/unix"
+)
+
+func (c *appleClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) (Conn, error) {
+ tcpConn, ok := N.UnwrapReader(conn).(*net.TCPConn)
+ if !ok {
+ return nil, E.New("apple TLS: requires fd-backed TCP connection")
+ }
+ syscallConn, err := tcpConn.SyscallConn()
+ if err != nil {
+ return nil, E.Cause(err, "access raw connection")
+ }
+
+ var dupFD int
+ controlErr := syscallConn.Control(func(fd uintptr) {
+ dupFD, err = unix.Dup(int(fd))
+ })
+ if controlErr != nil {
+ return nil, E.Cause(controlErr, "access raw connection")
+ }
+ if err != nil {
+ return nil, E.Cause(err, "duplicate raw connection")
+ }
+
+ serverName := c.serverName
+ serverNamePtr := cStringOrNil(serverName)
+ defer cFree(serverNamePtr)
+
+ alpn := strings.Join(c.nextProtos, "\n")
+ alpnPtr := cStringOrNil(alpn)
+ defer cFree(alpnPtr)
+
+ anchors, err := c.resolveAnchors()
+ if err != nil {
+ return nil, err
+ }
+ var anchorsRef unsafe.Pointer
+ if anchors != nil {
+ anchorsRef = anchors.Ref()
+ }
+
+ var (
+ hasVerifyTime bool
+ verifyTimeUnixMilli int64
+ )
+ if c.timeFunc != nil {
+ hasVerifyTime = true
+ verifyTimeUnixMilli = c.timeFunc().UnixMilli()
+ }
+
+ var errorPtr *C.char
+ client := C.box_apple_tls_client_create(
+ C.int(dupFD),
+ serverNamePtr,
+ alpnPtr,
+ C.size_t(len(alpn)),
+ C.uint16_t(c.minVersion),
+ C.uint16_t(c.maxVersion),
+ C.bool(c.insecure),
+ anchorsRef,
+ C.bool(c.anchorOnly),
+ C.bool(hasVerifyTime),
+ C.int64_t(verifyTimeUnixMilli),
+ &errorPtr,
+ )
+ if anchors != nil {
+ anchors.Release()
+ }
+ if client == nil {
+ if errorPtr != nil {
+ defer C.free(unsafe.Pointer(errorPtr))
+ return nil, E.New(C.GoString(errorPtr))
+ }
+ return nil, E.New("apple TLS: create connection")
+ }
+ if err = waitAppleTLSClientReady(ctx, client); err != nil {
+ C.box_apple_tls_client_cancel(client)
+ C.box_apple_tls_client_free(client)
+ return nil, err
+ }
+
+ var state C.box_apple_tls_state_t
+ stateOK := C.box_apple_tls_client_copy_state(client, &state, &errorPtr)
+ if !bool(stateOK) {
+ C.box_apple_tls_client_cancel(client)
+ C.box_apple_tls_client_free(client)
+ if errorPtr != nil {
+ defer C.free(unsafe.Pointer(errorPtr))
+ return nil, E.New(C.GoString(errorPtr))
+ }
+ return nil, E.New("apple TLS: read metadata")
+ }
+ defer C.box_apple_tls_state_free(&state)
+
+ connectionState, rawCerts, err := parseAppleTLSState(&state)
+ if err != nil {
+ C.box_apple_tls_client_cancel(client)
+ C.box_apple_tls_client_free(client)
+ return nil, err
+ }
+ if len(c.certificatePublicKeySHA256) > 0 {
+ err = VerifyPublicKeySHA256(c.certificatePublicKeySHA256, rawCerts)
+ if err != nil {
+ C.box_apple_tls_client_cancel(client)
+ C.box_apple_tls_client_free(client)
+ return nil, err
+ }
+ }
+
+ return &appleTLSConn{
+ rawConn: conn,
+ client: client,
+ state: connectionState,
+ closed: make(chan struct{}),
+ }, nil
+}
+
+const (
+ appleTLSHandshakePollInterval = 100 * time.Millisecond
+ appleTLSWriteChunkSize = 32 * 1024
+)
+
+func waitAppleTLSClientReady(ctx context.Context, client *C.box_apple_tls_client_t) error {
+ for {
+ err := ctx.Err()
+ if err != nil {
+ C.box_apple_tls_client_cancel(client)
+ return err
+ }
+
+ waitTimeout := appleTLSHandshakePollInterval
+ deadline, loaded := ctx.Deadline()
+ if loaded {
+ remaining := time.Until(deadline)
+ if remaining <= 0 {
+ C.box_apple_tls_client_cancel(client)
+ err = ctx.Err()
+ if err != nil {
+ return err
+ }
+ return context.DeadlineExceeded
+ }
+ if remaining < waitTimeout {
+ waitTimeout = remaining
+ }
+ }
+
+ var errorPtr *C.char
+ waitResult := C.box_apple_tls_client_wait_ready(client, C.int(timeoutFromDuration(waitTimeout)), &errorPtr)
+ switch waitResult {
+ case 1:
+ return nil
+ case -2:
+ continue
+ case 0:
+ if errorPtr != nil {
+ defer C.free(unsafe.Pointer(errorPtr))
+ return E.New(C.GoString(errorPtr))
+ }
+ return E.New("apple TLS: handshake failed")
+ default:
+ return E.New("apple TLS: invalid handshake state")
+ }
+ }
+}
+
+type appleTLSConn struct {
+ rawConn net.Conn
+ client *C.box_apple_tls_client_t
+ state tls.ConnectionState
+
+ readAccess sync.Mutex
+ writeAccess sync.Mutex
+ stateAccess sync.RWMutex
+ closeOnce sync.Once
+ ioAccess sync.Mutex
+ ioGroup sync.WaitGroup
+ closed chan struct{}
+ readEOF bool
+ deadlineAccess sync.Mutex
+ readDeadline time.Time
+ writeDeadline time.Time
+ readTimedOut bool
+ writeTimedOut bool
+}
+
+var (
+ _ N.ExtendedConn = (*appleTLSConn)(nil)
+ _ N.ReadWaitCreator = (*appleTLSConn)(nil)
+)
+
+func (c *appleTLSConn) Read(p []byte) (int, error) {
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if c.readEOF {
+ return 0, io.EOF
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+
+ return c.readIntoLocked(p)
+}
+
+func (c *appleTLSConn) ReadBuffer(buffer *buf.Buffer) error {
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if buffer.IsFull() {
+ return io.ErrShortBuffer
+ }
+ startLen := buffer.Len()
+ n, err := c.readIntoLocked(buffer.FreeBytes())
+ buffer.Truncate(startLen + n)
+ return err
+}
+
+func (c *appleTLSConn) readIntoLocked(p []byte) (int, error) {
+ if c.readEOF {
+ return 0, io.EOF
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+
+ timeoutMs, err := c.prepareReadTimeout()
+ if err != nil {
+ return 0, err
+ }
+
+ client, err := c.acquireClient()
+ if err != nil {
+ return 0, err
+ }
+ defer c.releaseClient()
+
+ var eof C.bool
+ var errorPtr *C.char
+ n := C.box_apple_tls_client_read(client, unsafe.Pointer(&p[0]), C.size_t(len(p)), C.int(timeoutMs), &eof, &errorPtr)
+ switch {
+ case n == -2:
+ c.markReadTimedOut()
+ return 0, os.ErrDeadlineExceeded
+ case n >= 0:
+ if bool(eof) {
+ c.readEOF = true
+ if n == 0 {
+ return 0, io.EOF
+ }
+ }
+ return int(n), nil
+ default:
+ if errorPtr != nil {
+ defer C.free(unsafe.Pointer(errorPtr))
+ if c.isClosed() {
+ return 0, net.ErrClosed
+ }
+ return 0, E.New(C.GoString(errorPtr))
+ }
+ return 0, net.ErrClosed
+ }
+}
+
+func (c *appleTLSConn) Write(p []byte) (int, error) {
+ c.writeAccess.Lock()
+ defer c.writeAccess.Unlock()
+ if len(p) == 0 {
+ return 0, nil
+ }
+
+ client, err := c.acquireClient()
+ if err != nil {
+ return 0, err
+ }
+ defer c.releaseClient()
+
+ deadline, err := c.prepareWriteDeadline()
+ if err != nil {
+ return 0, err
+ }
+ var written int
+ for written < len(p) {
+ timeoutMs, expired := deadlineTimeoutMs(deadline)
+ if expired {
+ C.box_apple_tls_client_cancel(client)
+ c.markWriteTimedOut()
+ return written, os.ErrDeadlineExceeded
+ }
+ chunkSize := min(len(p)-written, appleTLSWriteChunkSize)
+ chunk := p[written : written+chunkSize]
+ var errorPtr *C.char
+ n := C.box_apple_tls_client_write(client, unsafe.Pointer(&chunk[0]), C.size_t(len(chunk)), C.int(timeoutMs), &errorPtr)
+ switch {
+ case n == -2:
+ c.markWriteTimedOut()
+ return written, os.ErrDeadlineExceeded
+ case n >= 0:
+ written += int(n)
+ if int(n) != len(chunk) {
+ return written, io.ErrShortWrite
+ }
+ continue
+ }
+ return written, c.errorFromPointer(errorPtr)
+ }
+ return written, nil
+}
+
+func (c *appleTLSConn) WriteBuffer(buffer *buf.Buffer) error {
+ defer buffer.Release()
+ _, err := c.Write(buffer.Bytes())
+ return err
+}
+
+func (c *appleTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
+ return &appleTLSReadWaiter{
+ conn: c,
+ results: make(chan *C.box_apple_tls_read_result_t, 1),
+ }, true
+}
+
+func (c *appleTLSConn) Close() error {
+ var closeErr error
+ c.closeOnce.Do(func() {
+ close(c.closed)
+ C.box_apple_tls_client_cancel(c.client)
+ closeErr = c.rawConn.Close()
+ c.ioAccess.Lock()
+ c.ioGroup.Wait()
+ C.box_apple_tls_client_free(c.client)
+ c.client = nil
+ c.ioAccess.Unlock()
+ })
+ return closeErr
+}
+
+func (c *appleTLSConn) LocalAddr() net.Addr {
+ return c.rawConn.LocalAddr()
+}
+
+func (c *appleTLSConn) RemoteAddr() net.Addr {
+ return c.rawConn.RemoteAddr()
+}
+
+// SetDeadline installs deadlines for subsequent Read and Write calls.
+//
+// Deadlines only apply to subsequent Read or Write calls; an in-flight call
+// does not observe later updates to its deadline. Callers that need to cancel
+// an in-flight I/O must Close the connection instead.
+//
+// Once an active Read or Write trips its deadline, the underlying
+// nw_connection is cancelled and the conn is no longer usable — callers must
+// Close after a deadline error.
+func (c *appleTLSConn) SetDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ c.readDeadline = t
+ c.writeDeadline = t
+ c.readTimedOut = false
+ c.writeTimedOut = false
+ c.deadlineAccess.Unlock()
+ return nil
+}
+
+func (c *appleTLSConn) SetReadDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ c.readDeadline = t
+ c.readTimedOut = false
+ c.deadlineAccess.Unlock()
+ return nil
+}
+
+func (c *appleTLSConn) SetWriteDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ c.writeDeadline = t
+ c.writeTimedOut = false
+ c.deadlineAccess.Unlock()
+ return nil
+}
+
+func (c *appleTLSConn) prepareReadTimeout() (int, error) {
+ c.deadlineAccess.Lock()
+ defer c.deadlineAccess.Unlock()
+ if c.readTimedOut {
+ return 0, os.ErrDeadlineExceeded
+ }
+ timeoutMs, expired := deadlineTimeoutMs(c.readDeadline)
+ if expired {
+ c.readTimedOut = true
+ return 0, os.ErrDeadlineExceeded
+ }
+ return timeoutMs, nil
+}
+
+func (c *appleTLSConn) prepareWriteDeadline() (time.Time, error) {
+ c.deadlineAccess.Lock()
+ defer c.deadlineAccess.Unlock()
+ if c.writeTimedOut {
+ return time.Time{}, os.ErrDeadlineExceeded
+ }
+ _, expired := deadlineTimeoutMs(c.writeDeadline)
+ if expired {
+ c.writeTimedOut = true
+ return time.Time{}, os.ErrDeadlineExceeded
+ }
+ return c.writeDeadline, nil
+}
+
+func (c *appleTLSConn) markReadTimedOut() {
+ c.deadlineAccess.Lock()
+ c.readTimedOut = true
+ c.deadlineAccess.Unlock()
+}
+
+func (c *appleTLSConn) markWriteTimedOut() {
+ c.deadlineAccess.Lock()
+ c.writeTimedOut = true
+ c.deadlineAccess.Unlock()
+}
+
+func deadlineTimeoutMs(deadline time.Time) (int, bool) {
+ if deadline.IsZero() {
+ return -1, false
+ }
+ remaining := time.Until(deadline)
+ if remaining <= 0 {
+ return 0, true
+ }
+ return timeoutFromDuration(remaining), false
+}
+
+func (c *appleTLSConn) isClosed() bool {
+ select {
+ case <-c.closed:
+ return true
+ default:
+ return false
+ }
+}
+
+func (c *appleTLSConn) acquireClient() (*C.box_apple_tls_client_t, error) {
+ c.ioAccess.Lock()
+ defer c.ioAccess.Unlock()
+ if c.isClosed() {
+ return nil, net.ErrClosed
+ }
+ client := c.client
+ if client == nil {
+ return nil, net.ErrClosed
+ }
+ c.ioGroup.Add(1)
+ return client, nil
+}
+
+func (c *appleTLSConn) releaseClient() {
+ c.ioGroup.Done()
+}
+
+func (c *appleTLSConn) errorFromPointer(errorPtr *C.char) error {
+ if errorPtr != nil {
+ defer C.free(unsafe.Pointer(errorPtr))
+ if c.isClosed() {
+ return net.ErrClosed
+ }
+ return E.New(C.GoString(errorPtr))
+ }
+ return net.ErrClosed
+}
+
+type appleTLSReadWaiter struct {
+ conn *appleTLSConn
+ options N.ReadWaitOptions
+ results chan *C.box_apple_tls_read_result_t
+}
+
+var _ N.ReadWaiter = (*appleTLSReadWaiter)(nil)
+
+func (w *appleTLSReadWaiter) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
+ w.options = options
+ if w.results == nil {
+ w.results = make(chan *C.box_apple_tls_read_result_t, 1)
+ }
+ return false
+}
+
+func (w *appleTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
+ c := w.conn
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if c.readEOF {
+ return nil, io.EOF
+ }
+ maximumLen := readWaitFreeLen(w.options)
+ if maximumLen <= 0 {
+ return nil, io.ErrShortBuffer
+ }
+ timeoutMs, err := c.prepareReadTimeout()
+ if err != nil {
+ return nil, err
+ }
+ client, err := c.acquireClient()
+ if err != nil {
+ return nil, err
+ }
+ defer c.releaseClient()
+
+ handle := cgo.NewHandle(w)
+ defer handle.Delete()
+ var errorPtr *C.char
+ if !bool(C.box_apple_tls_client_read_async(client, C.size_t(maximumLen), C.uintptr_t(handle), &errorPtr)) {
+ return nil, c.errorFromPointer(errorPtr)
+ }
+
+ var result *C.box_apple_tls_read_result_t
+ if timeoutMs >= 0 {
+ timer := time.NewTimer(time.Duration(timeoutMs) * time.Millisecond)
+ defer timer.Stop()
+ select {
+ case result = <-w.results:
+ case <-timer.C:
+ C.box_apple_tls_client_cancel(client)
+ result = <-w.results
+ if result != nil {
+ C.box_apple_tls_read_result_free(result)
+ }
+ c.markReadTimedOut()
+ return nil, os.ErrDeadlineExceeded
+ }
+ } else {
+ result = <-w.results
+ }
+ return c.readWaitResultToBuffer(result, w.options)
+}
+
+func (c *appleTLSConn) readWaitResultToBuffer(result *C.box_apple_tls_read_result_t, options N.ReadWaitOptions) (*buf.Buffer, error) {
+ defer C.box_apple_tls_read_result_free(result)
+ buffer := options.NewBuffer()
+ if buffer.IsFull() {
+ buffer.Release()
+ return nil, io.ErrShortBuffer
+ }
+ startLen := buffer.Len()
+ var eof C.bool
+ var errorPtr *C.char
+ n := C.box_apple_tls_read_result_copy(result, unsafe.Pointer(&buffer.FreeBytes()[0]), C.size_t(buffer.FreeLen()), &eof, &errorPtr)
+ if n < 0 {
+ buffer.Release()
+ return nil, c.errorFromPointer(errorPtr)
+ }
+ if bool(eof) {
+ c.readEOF = true
+ if n == 0 {
+ buffer.Release()
+ return nil, io.EOF
+ }
+ }
+ if n == 0 {
+ buffer.Release()
+ return nil, io.ErrNoProgress
+ }
+ buffer.Truncate(startLen + int(n))
+ options.PostReturn(buffer)
+ return buffer, nil
+}
+
+func readWaitFreeLen(options N.ReadWaitOptions) int {
+ if options.IncreaseBuffer {
+ return 65535 - options.FrontHeadroom - options.RearHeadroom
+ }
+ if options.MTU > 0 {
+ return options.MTU
+ }
+ return buf.BufferSize - options.FrontHeadroom - options.RearHeadroom
+}
+
+//export box_apple_tls_read_callback
+func box_apple_tls_read_callback(callbackHandle C.uintptr_t, result *C.box_apple_tls_read_result_t) {
+ handle := cgo.Handle(callbackHandle)
+ waiter, ok := handle.Value().(*appleTLSReadWaiter)
+ if !ok {
+ C.box_apple_tls_read_result_free(result)
+ return
+ }
+ select {
+ case waiter.results <- result:
+ default:
+ C.box_apple_tls_read_result_free(result)
+ }
+}
+
+func (c *appleTLSConn) NetConn() net.Conn {
+ return c.rawConn
+}
+
+func (c *appleTLSConn) HandshakeContext(ctx context.Context) error {
+ return nil
+}
+
+func (c *appleTLSConn) ConnectionState() ConnectionState {
+ c.stateAccess.RLock()
+ defer c.stateAccess.RUnlock()
+ return c.state
+}
+
+func parseAppleTLSState(state *C.box_apple_tls_state_t) (tls.ConnectionState, [][]byte, error) {
+ rawCerts, peerCertificates, err := parseAppleCertChain(state.peer_cert_chain, state.peer_cert_chain_len)
+ if err != nil {
+ return tls.ConnectionState{}, nil, err
+ }
+ var negotiatedProtocol string
+ if state.alpn != nil {
+ negotiatedProtocol = C.GoString(state.alpn)
+ }
+ var serverName string
+ if state.server_name != nil {
+ serverName = C.GoString(state.server_name)
+ }
+ return tls.ConnectionState{
+ Version: uint16(state.version),
+ HandshakeComplete: true,
+ CipherSuite: uint16(state.cipher_suite),
+ NegotiatedProtocol: negotiatedProtocol,
+ ServerName: serverName,
+ PeerCertificates: peerCertificates,
+ }, rawCerts, nil
+}
+
+func parseAppleCertChain(chain *C.uint8_t, chainLen C.size_t) ([][]byte, []*x509.Certificate, error) {
+ if chain == nil || chainLen == 0 {
+ return nil, nil, nil
+ }
+ chainBytes := C.GoBytes(unsafe.Pointer(chain), C.int(chainLen))
+ var (
+ rawCerts [][]byte
+ peerCertificates []*x509.Certificate
+ )
+ for len(chainBytes) >= 4 {
+ certificateLen := binary.BigEndian.Uint32(chainBytes[:4])
+ chainBytes = chainBytes[4:]
+ if len(chainBytes) < int(certificateLen) {
+ return nil, nil, E.New("apple TLS: invalid certificate chain")
+ }
+ certificateData := append([]byte(nil), chainBytes[:certificateLen]...)
+ certificate, err := x509.ParseCertificate(certificateData)
+ if err != nil {
+ return nil, nil, E.Cause(err, "parse peer certificate")
+ }
+ rawCerts = append(rawCerts, certificateData)
+ peerCertificates = append(peerCertificates, certificate)
+ chainBytes = chainBytes[certificateLen:]
+ }
+ if len(chainBytes) != 0 {
+ return nil, nil, E.New("apple TLS: invalid certificate chain")
+ }
+ return rawCerts, peerCertificates, nil
+}
+
+func timeoutFromDuration(timeout time.Duration) int {
+ if timeout <= 0 {
+ return 0
+ }
+ timeoutMilliseconds := int64(timeout / time.Millisecond)
+ if timeout%time.Millisecond != 0 {
+ timeoutMilliseconds++
+ }
+ if timeoutMilliseconds > math.MaxInt32 {
+ return math.MaxInt32
+ }
+ return int(timeoutMilliseconds)
+}
+
+func cStringOrNil(value string) *C.char {
+ if value == "" {
+ return nil
+ }
+ return C.CString(value)
+}
+
+func cFree(pointer *C.char) {
+ if pointer != nil {
+ C.free(unsafe.Pointer(pointer))
+ }
+}
diff --git a/common/tls/apple_client_platform_benchmark_test.go b/common/tls/apple_client_platform_benchmark_test.go
new file mode 100644
index 0000000000..27fcf1532c
--- /dev/null
+++ b/common/tls/apple_client_platform_benchmark_test.go
@@ -0,0 +1,278 @@
+//go:build darwin && cgo
+
+package tls
+
+import (
+ "bytes"
+ stdtls "crypto/tls"
+ "crypto/x509"
+ "errors"
+ "io"
+ "net"
+ "testing"
+
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/json/badoption"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const (
+ appleTLSBenchmarkReadPayloadSize = 16 * 1024
+ appleTLSBenchmarkWritePayloadSize = 48 * 1024
+)
+
+func BenchmarkAppleClientReadBuffer(b *testing.B) {
+ payload := bytes.Repeat([]byte{'r'}, appleTLSBenchmarkReadPayloadSize)
+ start := make(chan struct{})
+ clientConn, serverResult := newAppleBenchmarkClientConn(b, func(conn *stdtls.Conn) error {
+ <-start
+ for range b.N {
+ if err := writeBenchmarkPayload(conn, payload); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ defer clientConn.Close()
+
+ extendedConn := clientConn.(N.ExtendedConn)
+ b.ReportAllocs()
+ b.SetBytes(int64(len(payload)))
+ b.ReportMetric(float64(len(payload)), "payload_B")
+ b.ResetTimer()
+ close(start)
+ target := b.N * len(payload)
+ var received int
+ for received < target {
+ buffer := buf.NewSize(len(payload))
+ err := extendedConn.ReadBuffer(buffer)
+ if err != nil {
+ buffer.Release()
+ b.Fatal(err)
+ }
+ received += buffer.Len()
+ buffer.Release()
+ }
+ b.StopTimer()
+ if err := <-serverResult; err != nil {
+ b.Fatal(err)
+ }
+}
+
+func BenchmarkAppleClientReadWaiter(b *testing.B) {
+ payload := bytes.Repeat([]byte{'w'}, appleTLSBenchmarkReadPayloadSize)
+ start := make(chan struct{})
+ clientConn, serverResult := newAppleBenchmarkClientConn(b, func(conn *stdtls.Conn) error {
+ <-start
+ for range b.N {
+ if err := writeBenchmarkPayload(conn, payload); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ defer clientConn.Close()
+
+ readWaiter, ok := clientConn.(N.ReadWaitCreator).CreateReadWaiter()
+ if !ok {
+ b.Fatal("expected read waiter")
+ }
+ readWaiter.InitializeReadWaiter(N.ReadWaitOptions{
+ MTU: appleTLSBenchmarkReadPayloadSize,
+ })
+ b.ReportAllocs()
+ b.SetBytes(int64(len(payload)))
+ b.ReportMetric(float64(len(payload)), "payload_B")
+ b.ResetTimer()
+ close(start)
+ target := b.N * len(payload)
+ var received int
+ for received < target {
+ buffer, err := readWaiter.WaitReadBuffer()
+ if err != nil {
+ if errors.Is(err, io.ErrNoProgress) {
+ continue
+ }
+ b.Fatal(err)
+ }
+ received += buffer.Len()
+ buffer.Release()
+ }
+ b.StopTimer()
+ if err := <-serverResult; err != nil {
+ b.Fatal(err)
+ }
+}
+
+func BenchmarkAppleClientWriteBuffer(b *testing.B) {
+ payload := bytes.Repeat([]byte{'x'}, appleTLSBenchmarkWritePayloadSize)
+ start := make(chan struct{})
+ clientConn, serverResult := newAppleBenchmarkClientConn(b, func(conn *stdtls.Conn) error {
+ <-start
+ _, err := io.CopyN(io.Discard, conn, int64(b.N*len(payload)))
+ return err
+ })
+ defer clientConn.Close()
+
+ extendedConn := clientConn.(N.ExtendedConn)
+ b.ReportAllocs()
+ b.SetBytes(int64(len(payload)))
+ b.ReportMetric(float64(len(payload)), "payload_B")
+ b.ReportMetric(float64(appleTLSWriteChunkSize), "write_chunk_B")
+ b.ResetTimer()
+ close(start)
+ for range b.N {
+ buffer := buf.NewSize(len(payload))
+ _, err := buffer.Write(payload)
+ if err != nil {
+ buffer.Release()
+ b.Fatal(err)
+ }
+ err = extendedConn.WriteBuffer(buffer)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ b.StopTimer()
+ if err := <-serverResult; err != nil {
+ b.Fatal(err)
+ }
+}
+
+func BenchmarkStdlibClientReadBuffer(b *testing.B) {
+ payload := bytes.Repeat([]byte{'r'}, appleTLSBenchmarkReadPayloadSize)
+ start := make(chan struct{})
+ clientConn, serverResult := newStdlibBenchmarkClientConn(b, func(conn *stdtls.Conn) error {
+ <-start
+ for range b.N {
+ if err := writeBenchmarkPayload(conn, payload); err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ defer clientConn.Close()
+
+ b.ReportAllocs()
+ b.SetBytes(int64(len(payload)))
+ b.ReportMetric(float64(len(payload)), "payload_B")
+ b.ResetTimer()
+ close(start)
+ target := b.N * len(payload)
+ var received int
+ for received < target {
+ buffer := buf.NewSize(len(payload))
+ n, err := clientConn.Read(buffer.FreeBytes())
+ if n > 0 {
+ buffer.Truncate(buffer.Len() + n)
+ }
+ received += buffer.Len()
+ buffer.Release()
+ if err != nil && received < target {
+ b.Fatal(err)
+ }
+ }
+ b.StopTimer()
+ if err := <-serverResult; err != nil {
+ b.Fatal(err)
+ }
+}
+
+func BenchmarkStdlibClientWriteBuffer(b *testing.B) {
+ payload := bytes.Repeat([]byte{'x'}, appleTLSBenchmarkWritePayloadSize)
+ start := make(chan struct{})
+ clientConn, serverResult := newStdlibBenchmarkClientConn(b, func(conn *stdtls.Conn) error {
+ <-start
+ _, err := io.CopyN(io.Discard, conn, int64(b.N*len(payload)))
+ return err
+ })
+ defer clientConn.Close()
+
+ b.ReportAllocs()
+ b.SetBytes(int64(len(payload)))
+ b.ReportMetric(float64(len(payload)), "payload_B")
+ b.ResetTimer()
+ close(start)
+ for range b.N {
+ buffer := buf.NewSize(len(payload))
+ _, err := buffer.Write(payload)
+ if err != nil {
+ buffer.Release()
+ b.Fatal(err)
+ }
+ _, err = clientConn.Write(buffer.Bytes())
+ buffer.Release()
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ b.StopTimer()
+ if err := <-serverResult; err != nil {
+ b.Fatal(err)
+ }
+}
+
+func newAppleBenchmarkClientConn(b *testing.B, handler func(*stdtls.Conn) error) (Conn, <-chan error) {
+ b.Helper()
+
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(b, "localhost")
+ serverResult, serverAddress := startAppleTLSIOTestServer(b, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ }, handler)
+
+ clientConn, err := newAppleTestClientConn(b, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ b.Fatal(err)
+ }
+ return clientConn, serverResult
+}
+
+func newStdlibBenchmarkClientConn(b *testing.B, handler func(*stdtls.Conn) error) (*stdtls.Conn, <-chan error) {
+ b.Helper()
+
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(b, "localhost")
+ serverResult, serverAddress := startAppleTLSIOTestServer(b, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ }, handler)
+
+ roots := x509.NewCertPool()
+ if !roots.AppendCertsFromPEM([]byte(serverCertificatePEM)) {
+ b.Fatal("parse benchmark certificate")
+ }
+ dialer := &net.Dialer{
+ Timeout: appleTLSTestTimeout,
+ }
+ clientConn, err := stdtls.DialWithDialer(dialer, "tcp", serverAddress, &stdtls.Config{
+ ServerName: "localhost",
+ RootCAs: roots,
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ if err != nil {
+ b.Fatal(err)
+ }
+ return clientConn, serverResult
+}
+
+func writeBenchmarkPayload(writer io.Writer, payload []byte) error {
+ for len(payload) > 0 {
+ n, err := writer.Write(payload)
+ if err != nil {
+ return err
+ }
+ payload = payload[n:]
+ }
+ return nil
+}
diff --git a/common/tls/apple_client_platform_darwin.h b/common/tls/apple_client_platform_darwin.h
new file mode 100644
index 0000000000..43b3e031d8
--- /dev/null
+++ b/common/tls/apple_client_platform_darwin.h
@@ -0,0 +1,43 @@
+#include
+#include
+#include
+#include
+
+typedef struct box_apple_tls_client box_apple_tls_client_t;
+typedef struct box_apple_tls_read_result box_apple_tls_read_result_t;
+
+typedef struct box_apple_tls_state {
+ uint16_t version;
+ uint16_t cipher_suite;
+ char *alpn;
+ char *server_name;
+ uint8_t *peer_cert_chain;
+ size_t peer_cert_chain_len;
+} box_apple_tls_state_t;
+
+box_apple_tls_client_t *box_apple_tls_client_create(
+ int connected_socket,
+ const char *server_name,
+ const char *alpn,
+ size_t alpn_len,
+ uint16_t min_version,
+ uint16_t max_version,
+ bool insecure,
+ void *anchors_cf,
+ bool anchor_only,
+ bool has_verify_time,
+ int64_t verify_time_unix_millis,
+ char **error_out
+);
+
+int box_apple_tls_client_wait_ready(box_apple_tls_client_t *client, int timeout_msec, char **error_out);
+void box_apple_tls_client_cancel(box_apple_tls_client_t *client);
+void box_apple_tls_client_free(box_apple_tls_client_t *client);
+ssize_t box_apple_tls_client_read(box_apple_tls_client_t *client, void *buffer, size_t buffer_len, int timeout_msec, bool *eof_out, char **error_out);
+ssize_t box_apple_tls_client_write(box_apple_tls_client_t *client, const void *buffer, size_t buffer_len, int timeout_msec, char **error_out);
+bool box_apple_tls_client_read_async(box_apple_tls_client_t *client, size_t maximum_len, uintptr_t callback_handle, char **error_out);
+ssize_t box_apple_tls_read_result_copy(box_apple_tls_read_result_t *result, void *buffer, size_t buffer_len, bool *eof_out, char **error_out);
+void box_apple_tls_read_result_free(box_apple_tls_read_result_t *result);
+bool box_apple_tls_client_copy_state(box_apple_tls_client_t *client, box_apple_tls_state_t *state, char **error_out);
+void box_apple_tls_state_free(box_apple_tls_state_t *state);
+ssize_t box_apple_tls_copy_dispatch_data_for_test(const void *first, size_t first_len, const void *second, size_t second_len, void *buffer, size_t buffer_len, char **error_out);
diff --git a/common/tls/apple_client_platform_darwin.m b/common/tls/apple_client_platform_darwin.m
new file mode 100644
index 0000000000..f4d0eb6793
--- /dev/null
+++ b/common/tls/apple_client_platform_darwin.m
@@ -0,0 +1,759 @@
+#import "apple_client_platform_darwin.h"
+
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+#import
+
+typedef nw_connection_t _Nullable (*box_nw_connection_create_with_connected_socket_and_parameters_f)(int connected_socket, nw_parameters_t parameters);
+typedef const char * _Nullable (*box_sec_protocol_metadata_string_accessor_f)(sec_protocol_metadata_t metadata);
+
+typedef struct box_apple_tls_client {
+ void *connection;
+ void *queue;
+ void *ready_semaphore;
+ void *anchors;
+ atomic_int ref_count;
+ atomic_bool ready;
+ atomic_bool ready_done;
+ char *ready_error;
+ box_apple_tls_state_t state;
+} box_apple_tls_client_t;
+
+struct box_apple_tls_read_result {
+ void *content;
+ bool eof;
+ char *error;
+};
+
+extern void box_apple_tls_read_callback(uintptr_t callback_handle, box_apple_tls_read_result_t *result);
+
+static nw_connection_t box_apple_tls_connection(box_apple_tls_client_t *client) {
+ if (client == NULL || client->connection == NULL) {
+ return nil;
+ }
+ return (__bridge nw_connection_t)client->connection;
+}
+
+static dispatch_queue_t box_apple_tls_client_queue(box_apple_tls_client_t *client) {
+ if (client == NULL || client->queue == NULL) {
+ return nil;
+ }
+ return (__bridge dispatch_queue_t)client->queue;
+}
+
+static dispatch_semaphore_t box_apple_tls_ready_semaphore(box_apple_tls_client_t *client) {
+ if (client == NULL || client->ready_semaphore == NULL) {
+ return nil;
+ }
+ return (__bridge dispatch_semaphore_t)client->ready_semaphore;
+}
+
+static NSArray *box_apple_tls_client_anchors(box_apple_tls_client_t *client) {
+ if (client == NULL || client->anchors == NULL) {
+ return nil;
+ }
+ return (__bridge NSArray *)client->anchors;
+}
+
+static dispatch_data_t box_apple_tls_read_result_content(box_apple_tls_read_result_t *result) {
+ if (result == NULL || result->content == NULL) {
+ return nil;
+ }
+ return (__bridge dispatch_data_t)result->content;
+}
+
+static void box_apple_tls_state_reset(box_apple_tls_state_t *state) {
+ if (state == NULL) {
+ return;
+ }
+ free(state->alpn);
+ free(state->server_name);
+ free(state->peer_cert_chain);
+ memset(state, 0, sizeof(box_apple_tls_state_t));
+}
+
+static void box_apple_tls_client_destroy(box_apple_tls_client_t *client) {
+ free(client->ready_error);
+ box_apple_tls_state_reset(&client->state);
+ if (client->anchors != NULL) {
+ CFRelease((CFTypeRef)client->anchors);
+ }
+ if (client->ready_semaphore != NULL) {
+ CFBridgingRelease(client->ready_semaphore);
+ }
+ if (client->connection != NULL) {
+ CFBridgingRelease(client->connection);
+ }
+ if (client->queue != NULL) {
+ CFBridgingRelease(client->queue);
+ }
+ free(client);
+}
+
+static void box_apple_tls_client_release(box_apple_tls_client_t *client) {
+ if (client == NULL) {
+ return;
+ }
+ if (atomic_fetch_sub(&client->ref_count, 1) == 1) {
+ box_apple_tls_client_destroy(client);
+ }
+}
+
+static void box_set_error_string(char **error_out, NSString *message) {
+ if (error_out == NULL || *error_out != NULL) {
+ return;
+ }
+ const char *utf8 = [message UTF8String];
+ *error_out = strdup(utf8 != NULL ? utf8 : "unknown error");
+}
+
+static void box_set_error_message(char **error_out, const char *message) {
+ if (error_out == NULL || *error_out != NULL) {
+ return;
+ }
+ *error_out = strdup(message != NULL ? message : "unknown error");
+}
+
+static void box_set_error_from_nw_error(char **error_out, nw_error_t error) {
+ if (error == NULL) {
+ box_set_error_message(error_out, "unknown network error");
+ return;
+ }
+ CFErrorRef cfError = nw_error_copy_cf_error(error);
+ if (cfError == NULL) {
+ box_set_error_message(error_out, "unknown network error");
+ return;
+ }
+ NSString *description = [(__bridge NSError *)cfError description];
+ box_set_error_string(error_out, description);
+ CFRelease(cfError);
+}
+
+static ssize_t box_apple_tls_dispatch_data_copy(dispatch_data_t content, void *buffer, size_t buffer_len, char **error_out) {
+ if (content == nil) {
+ return 0;
+ }
+ size_t content_size = dispatch_data_get_size(content);
+ if (content_size == 0) {
+ return 0;
+ }
+ if (buffer == NULL) {
+ box_set_error_message(error_out, "apple TLS: read buffer unavailable");
+ return -1;
+ }
+ __block size_t copied = 0;
+ __block bool overflow = false;
+ bool complete = dispatch_data_apply(content, ^bool(dispatch_data_t region, size_t offset, const void *region_buffer, size_t region_size) {
+ (void)region;
+ (void)offset;
+ if (region_size == 0) {
+ return true;
+ }
+ if (region_buffer == NULL || region_size > buffer_len - copied) {
+ overflow = true;
+ return false;
+ }
+ memcpy((uint8_t *)buffer + copied, region_buffer, region_size);
+ copied += region_size;
+ return true;
+ });
+ if (!complete || overflow) {
+ box_set_error_message(error_out, "apple TLS: read buffer too small");
+ return -1;
+ }
+ return (ssize_t)copied;
+}
+
+ssize_t box_apple_tls_copy_dispatch_data_for_test(const void *first, size_t first_len, const void *second, size_t second_len, void *buffer, size_t buffer_len, char **error_out) {
+ @autoreleasepool {
+ dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
+ dispatch_data_t first_data = first_len > 0 ? dispatch_data_create(first, first_len, queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT) : dispatch_data_empty;
+ dispatch_data_t second_data = second_len > 0 ? dispatch_data_create(second, second_len, queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT) : dispatch_data_empty;
+ dispatch_data_t content = dispatch_data_create_concat(first_data, second_data);
+ return box_apple_tls_dispatch_data_copy(content, buffer, buffer_len, error_out);
+ }
+}
+
+static char *box_apple_tls_metadata_copy_negotiated_protocol(sec_protocol_metadata_t metadata) {
+ static box_sec_protocol_metadata_string_accessor_f copy_fn;
+ static box_sec_protocol_metadata_string_accessor_f get_fn;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ copy_fn = (box_sec_protocol_metadata_string_accessor_f)dlsym(RTLD_DEFAULT, "sec_protocol_metadata_copy_negotiated_protocol");
+ get_fn = (box_sec_protocol_metadata_string_accessor_f)dlsym(RTLD_DEFAULT, "sec_protocol_metadata_get_negotiated_protocol");
+ });
+ if (copy_fn != NULL) {
+ return (char *)copy_fn(metadata);
+ }
+ if (get_fn != NULL) {
+ const char *protocol = get_fn(metadata);
+ if (protocol != NULL) {
+ return strdup(protocol);
+ }
+ }
+ return NULL;
+}
+
+static char *box_apple_tls_metadata_copy_server_name(sec_protocol_metadata_t metadata) {
+ static box_sec_protocol_metadata_string_accessor_f copy_fn;
+ static box_sec_protocol_metadata_string_accessor_f get_fn;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ copy_fn = (box_sec_protocol_metadata_string_accessor_f)dlsym(RTLD_DEFAULT, "sec_protocol_metadata_copy_server_name");
+ get_fn = (box_sec_protocol_metadata_string_accessor_f)dlsym(RTLD_DEFAULT, "sec_protocol_metadata_get_server_name");
+ });
+ if (copy_fn != NULL) {
+ return (char *)copy_fn(metadata);
+ }
+ if (get_fn != NULL) {
+ const char *server_name = get_fn(metadata);
+ if (server_name != NULL) {
+ return strdup(server_name);
+ }
+ }
+ return NULL;
+}
+
+static NSArray *box_split_lines(const char *content, size_t content_len) {
+ if (content == NULL || content_len == 0) {
+ return @[];
+ }
+ NSString *string = [[NSString alloc] initWithBytes:content length:content_len encoding:NSUTF8StringEncoding];
+ if (string == nil) {
+ return @[];
+ }
+ NSMutableArray *lines = [NSMutableArray array];
+ [string enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {
+ if (line.length > 0) {
+ [lines addObject:line];
+ }
+ }];
+ return lines;
+}
+
+static bool box_evaluate_trust(sec_trust_t trust, NSArray *anchors, bool anchor_only, NSDate *verify_date) {
+ bool result = false;
+ SecTrustRef trustRef = sec_trust_copy_ref(trust);
+ if (trustRef == NULL) {
+ return false;
+ }
+ if (verify_date != nil && SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)verify_date) != errSecSuccess) {
+ CFRelease(trustRef);
+ return false;
+ }
+ if (anchors.count > 0 || anchor_only) {
+ CFMutableArrayRef anchorArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ for (id certificate in anchors) {
+ CFArrayAppendValue(anchorArray, (__bridge const void *)certificate);
+ }
+ SecTrustSetAnchorCertificates(trustRef, anchorArray);
+ SecTrustSetAnchorCertificatesOnly(trustRef, anchor_only);
+ CFRelease(anchorArray);
+ }
+ CFErrorRef error = NULL;
+ result = SecTrustEvaluateWithError(trustRef, &error);
+ if (error != NULL) {
+ CFRelease(error);
+ }
+ CFRelease(trustRef);
+ return result;
+}
+
+static nw_connection_t box_apple_tls_create_connection(int connected_socket, nw_parameters_t parameters) {
+ static box_nw_connection_create_with_connected_socket_and_parameters_f create_fn;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ char name[] = "sretemarap_dna_tekcos_detcennoc_htiw_etaerc_noitcennoc_wn";
+ for (size_t i = 0, j = sizeof(name) - 2; i < j; i++, j--) {
+ char t = name[i];
+ name[i] = name[j];
+ name[j] = t;
+ }
+ create_fn = (box_nw_connection_create_with_connected_socket_and_parameters_f)dlsym(RTLD_DEFAULT, name);
+ });
+ if (create_fn == NULL) {
+ return nil;
+ }
+ return create_fn(connected_socket, parameters);
+}
+
+static bool box_apple_tls_state_copy(const box_apple_tls_state_t *source, box_apple_tls_state_t *destination) {
+ memset(destination, 0, sizeof(box_apple_tls_state_t));
+ destination->version = source->version;
+ destination->cipher_suite = source->cipher_suite;
+ if (source->alpn != NULL) {
+ destination->alpn = strdup(source->alpn);
+ if (destination->alpn == NULL) {
+ goto oom;
+ }
+ }
+ if (source->server_name != NULL) {
+ destination->server_name = strdup(source->server_name);
+ if (destination->server_name == NULL) {
+ goto oom;
+ }
+ }
+ if (source->peer_cert_chain_len > 0) {
+ destination->peer_cert_chain = malloc(source->peer_cert_chain_len);
+ if (destination->peer_cert_chain == NULL) {
+ goto oom;
+ }
+ memcpy(destination->peer_cert_chain, source->peer_cert_chain, source->peer_cert_chain_len);
+ destination->peer_cert_chain_len = source->peer_cert_chain_len;
+ }
+ return true;
+
+oom:
+ box_apple_tls_state_reset(destination);
+ return false;
+}
+
+// Captures TLS negotiation results from the verify block. The sec_metadata
+// exposed here is live for the duration of the handshake; the one retrieved
+// after nw_connection_state_ready may return stale ALPN/server_name buffers.
+static void box_apple_tls_state_load(sec_protocol_metadata_t sec_metadata, box_apple_tls_state_t *state) {
+ state->version = (uint16_t)sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_metadata);
+ state->cipher_suite = (uint16_t)sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_metadata);
+ state->alpn = box_apple_tls_metadata_copy_negotiated_protocol(sec_metadata);
+ state->server_name = box_apple_tls_metadata_copy_server_name(sec_metadata);
+
+ NSMutableData *chain_data = [NSMutableData data];
+ sec_protocol_metadata_access_peer_certificate_chain(sec_metadata, ^(sec_certificate_t certificate) {
+ SecCertificateRef certificate_ref = sec_certificate_copy_ref(certificate);
+ if (certificate_ref == NULL) {
+ return;
+ }
+ CFDataRef certificate_data = SecCertificateCopyData(certificate_ref);
+ CFRelease(certificate_ref);
+ if (certificate_data == NULL) {
+ return;
+ }
+ uint32_t certificate_len = (uint32_t)CFDataGetLength(certificate_data);
+ uint32_t network_len = htonl(certificate_len);
+ [chain_data appendBytes:&network_len length:sizeof(network_len)];
+ [chain_data appendBytes:CFDataGetBytePtr(certificate_data) length:certificate_len];
+ CFRelease(certificate_data);
+ });
+ if (chain_data.length > 0) {
+ state->peer_cert_chain = malloc(chain_data.length);
+ if (state->peer_cert_chain != NULL) {
+ memcpy(state->peer_cert_chain, chain_data.bytes, chain_data.length);
+ state->peer_cert_chain_len = chain_data.length;
+ }
+ }
+}
+
+box_apple_tls_client_t *box_apple_tls_client_create(
+ int connected_socket,
+ const char *server_name,
+ const char *alpn,
+ size_t alpn_len,
+ uint16_t min_version,
+ uint16_t max_version,
+ bool insecure,
+ void *anchors_cf,
+ bool anchor_only,
+ bool has_verify_time,
+ int64_t verify_time_unix_millis,
+ char **error_out
+) {
+ box_apple_tls_client_t *client = calloc(1, sizeof(box_apple_tls_client_t));
+ if (client == NULL) {
+ close(connected_socket);
+ box_set_error_message(error_out, "apple TLS: out of memory");
+ return NULL;
+ }
+ client->queue = (__bridge_retained void *)dispatch_queue_create("sing-box.apple-private-tls", DISPATCH_QUEUE_SERIAL);
+ client->ready_semaphore = (__bridge_retained void *)dispatch_semaphore_create(0);
+ atomic_init(&client->ref_count, 1);
+ atomic_init(&client->ready, false);
+ atomic_init(&client->ready_done, false);
+ if (anchors_cf != NULL) {
+ client->anchors = (void *)CFRetain(anchors_cf);
+ }
+
+ NSArray *alpnList = box_split_lines(alpn, alpn_len);
+ NSDate *verifyDate = nil;
+ if (has_verify_time) {
+ verifyDate = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)verify_time_unix_millis / 1000.0];
+ }
+ nw_parameters_t parameters = nw_parameters_create_secure_tcp(^(nw_protocol_options_t tls_options) {
+ sec_protocol_options_t sec_options = nw_tls_copy_sec_protocol_options(tls_options);
+ if (min_version != 0) {
+ sec_protocol_options_set_min_tls_protocol_version(sec_options, (tls_protocol_version_t)min_version);
+ }
+ if (max_version != 0) {
+ sec_protocol_options_set_max_tls_protocol_version(sec_options, (tls_protocol_version_t)max_version);
+ }
+ if (server_name != NULL && server_name[0] != '\0') {
+ sec_protocol_options_set_tls_server_name(sec_options, server_name);
+ }
+ for (NSString *protocol in alpnList) {
+ sec_protocol_options_add_tls_application_protocol(sec_options, protocol.UTF8String);
+ }
+ sec_protocol_options_set_peer_authentication_required(sec_options, !insecure);
+ sec_protocol_options_set_verify_block(sec_options, ^(sec_protocol_metadata_t metadata, sec_trust_t trust, sec_protocol_verify_complete_t complete) {
+ if (client->state.version == 0) {
+ box_apple_tls_state_load(metadata, &client->state);
+ }
+ complete(insecure || box_evaluate_trust(trust, box_apple_tls_client_anchors(client), anchor_only, verifyDate));
+ }, box_apple_tls_client_queue(client));
+ }, NW_PARAMETERS_DEFAULT_CONFIGURATION);
+
+ nw_connection_t connection = box_apple_tls_create_connection(connected_socket, parameters);
+ if (connection == NULL) {
+ close(connected_socket);
+ if (client->anchors != NULL) {
+ CFRelease((CFTypeRef)client->anchors);
+ }
+ if (client->ready_semaphore != NULL) {
+ CFBridgingRelease(client->ready_semaphore);
+ }
+ if (client->queue != NULL) {
+ CFBridgingRelease(client->queue);
+ }
+ free(client);
+ box_set_error_message(error_out, "apple TLS: failed to create connection");
+ return NULL;
+ }
+
+ client->connection = (__bridge_retained void *)connection;
+ atomic_fetch_add(&client->ref_count, 1);
+
+ nw_connection_set_state_changed_handler(connection, ^(nw_connection_state_t state, nw_error_t error) {
+ switch (state) {
+ case nw_connection_state_ready:
+ if (!atomic_load(&client->ready_done)) {
+ if (client->state.version == 0) {
+ box_set_error_message(&client->ready_error, "apple TLS: metadata unavailable");
+ } else {
+ atomic_store(&client->ready, true);
+ }
+ atomic_store(&client->ready_done, true);
+ dispatch_semaphore_signal(box_apple_tls_ready_semaphore(client));
+ }
+ break;
+ case nw_connection_state_failed:
+ if (!atomic_load(&client->ready_done)) {
+ box_set_error_from_nw_error(&client->ready_error, error);
+ atomic_store(&client->ready_done, true);
+ dispatch_semaphore_signal(box_apple_tls_ready_semaphore(client));
+ }
+ break;
+ case nw_connection_state_cancelled:
+ if (!atomic_load(&client->ready_done)) {
+ box_set_error_from_nw_error(&client->ready_error, error);
+ atomic_store(&client->ready_done, true);
+ dispatch_semaphore_signal(box_apple_tls_ready_semaphore(client));
+ }
+ box_apple_tls_client_release(client);
+ break;
+ default:
+ break;
+ }
+ });
+ nw_connection_set_queue(connection, box_apple_tls_client_queue(client));
+ nw_connection_start(connection);
+ return client;
+}
+
+int box_apple_tls_client_wait_ready(box_apple_tls_client_t *client, int timeout_msec, char **error_out) {
+ dispatch_semaphore_t ready_semaphore = box_apple_tls_ready_semaphore(client);
+ if (ready_semaphore == nil) {
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return 0;
+ }
+ if (!atomic_load(&client->ready_done)) {
+ dispatch_time_t timeout = DISPATCH_TIME_FOREVER;
+ if (timeout_msec >= 0) {
+ timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeout_msec * NSEC_PER_MSEC);
+ }
+ long wait_result = dispatch_semaphore_wait(ready_semaphore, timeout);
+ if (wait_result != 0) {
+ return -2;
+ }
+ }
+ if (atomic_load(&client->ready)) {
+ return 1;
+ }
+ if (client->ready_error != NULL) {
+ if (error_out != NULL) {
+ *error_out = client->ready_error;
+ client->ready_error = NULL;
+ } else {
+ free(client->ready_error);
+ client->ready_error = NULL;
+ }
+ } else {
+ box_set_error_message(error_out, "apple TLS: handshake failed");
+ }
+ return 0;
+}
+
+void box_apple_tls_client_cancel(box_apple_tls_client_t *client) {
+ if (client == NULL) {
+ return;
+ }
+ nw_connection_t connection = box_apple_tls_connection(client);
+ if (connection != nil) {
+ nw_connection_cancel(connection);
+ }
+}
+
+void box_apple_tls_client_free(box_apple_tls_client_t *client) {
+ if (client == NULL) {
+ return;
+ }
+ nw_connection_t connection = box_apple_tls_connection(client);
+ if (connection != nil) {
+ nw_connection_cancel(connection);
+ }
+ box_apple_tls_client_release(client);
+}
+
+ssize_t box_apple_tls_client_read(box_apple_tls_client_t *client, void *buffer, size_t buffer_len, int timeout_msec, bool *eof_out, char **error_out) {
+ @autoreleasepool {
+ nw_connection_t connection = box_apple_tls_connection(client);
+ if (connection == nil) {
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return -1;
+ }
+
+ dispatch_semaphore_t read_semaphore = dispatch_semaphore_create(0);
+ __block size_t content_len = 0;
+ __block bool read_eof = false;
+ __block char *local_error = NULL;
+
+ nw_connection_receive(connection, 1, (uint32_t)buffer_len, ^(dispatch_data_t content, nw_content_context_t context, bool is_complete, nw_error_t error) {
+ @autoreleasepool {
+ if (content != NULL) {
+ ssize_t copied = box_apple_tls_dispatch_data_copy(content, buffer, buffer_len, &local_error);
+ if (copied >= 0) {
+ content_len = (size_t)copied;
+ }
+ }
+ if (error != NULL && content_len == 0 && local_error == NULL) {
+ box_set_error_from_nw_error(&local_error, error);
+ }
+ if (is_complete && (context == NULL || nw_content_context_get_is_final(context))) {
+ read_eof = true;
+ }
+ dispatch_semaphore_signal(read_semaphore);
+ }
+ });
+
+ dispatch_time_t wait_deadline = DISPATCH_TIME_FOREVER;
+ if (timeout_msec >= 0) {
+ wait_deadline = dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeout_msec * NSEC_PER_MSEC);
+ }
+ long wait_result = dispatch_semaphore_wait(read_semaphore, wait_deadline);
+ if (wait_result != 0) {
+ nw_connection_cancel(connection);
+ dispatch_semaphore_wait(read_semaphore, DISPATCH_TIME_FOREVER);
+ if (local_error != NULL) {
+ free(local_error);
+ local_error = NULL;
+ }
+ return -2;
+ }
+ if (local_error != NULL) {
+ if (error_out != NULL) {
+ *error_out = local_error;
+ } else {
+ free(local_error);
+ }
+ return -1;
+ }
+ if (eof_out != NULL) {
+ *eof_out = read_eof;
+ }
+ return (ssize_t)content_len;
+ }
+}
+
+ssize_t box_apple_tls_client_write(box_apple_tls_client_t *client, const void *buffer, size_t buffer_len, int timeout_msec, char **error_out) {
+ @autoreleasepool {
+ nw_connection_t connection = box_apple_tls_connection(client);
+ if (connection == nil) {
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return -1;
+ }
+ if (buffer_len == 0) {
+ return 0;
+ }
+
+ void *content_copy = malloc(buffer_len);
+ if (content_copy == NULL) {
+ box_set_error_message(error_out, "apple TLS: out of memory");
+ return -1;
+ }
+ dispatch_queue_t queue = box_apple_tls_client_queue(client);
+ if (queue == nil) {
+ free(content_copy);
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return -1;
+ }
+ memcpy(content_copy, buffer, buffer_len);
+ dispatch_data_t content = dispatch_data_create(content_copy, buffer_len, queue, ^{
+ free(content_copy);
+ });
+
+ dispatch_semaphore_t write_semaphore = dispatch_semaphore_create(0);
+ __block char *local_error = NULL;
+
+ nw_connection_send(connection, content, NW_CONNECTION_DEFAULT_STREAM_CONTEXT, false, ^(nw_error_t error) {
+ @autoreleasepool {
+ if (error != NULL) {
+ box_set_error_from_nw_error(&local_error, error);
+ }
+ dispatch_semaphore_signal(write_semaphore);
+ }
+ });
+
+ dispatch_time_t wait_deadline = DISPATCH_TIME_FOREVER;
+ if (timeout_msec >= 0) {
+ wait_deadline = dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeout_msec * NSEC_PER_MSEC);
+ }
+ long wait_result = dispatch_semaphore_wait(write_semaphore, wait_deadline);
+ if (wait_result != 0) {
+ nw_connection_cancel(connection);
+ dispatch_semaphore_wait(write_semaphore, DISPATCH_TIME_FOREVER);
+ if (local_error != NULL) {
+ free(local_error);
+ local_error = NULL;
+ }
+ return -2;
+ }
+ if (local_error != NULL) {
+ if (error_out != NULL) {
+ *error_out = local_error;
+ } else {
+ free(local_error);
+ }
+ return -1;
+ }
+ return (ssize_t)buffer_len;
+ }
+}
+
+bool box_apple_tls_client_read_async(box_apple_tls_client_t *client, size_t maximum_len, uintptr_t callback_handle, char **error_out) {
+ @autoreleasepool {
+ nw_connection_t connection = box_apple_tls_connection(client);
+ if (connection == nil) {
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return false;
+ }
+ if (maximum_len == 0) {
+ box_set_error_message(error_out, "apple TLS: empty read buffer");
+ return false;
+ }
+ uint32_t receive_len = maximum_len > UINT32_MAX ? UINT32_MAX : (uint32_t)maximum_len;
+ nw_connection_receive(connection, 1, receive_len, ^(dispatch_data_t content, nw_content_context_t context, bool is_complete, nw_error_t error) {
+ @autoreleasepool {
+ box_apple_tls_read_result_t *result = calloc(1, sizeof(box_apple_tls_read_result_t));
+ if (result == NULL) {
+ box_apple_tls_read_callback(callback_handle, NULL);
+ return;
+ }
+ size_t content_size = content != NULL ? dispatch_data_get_size(content) : 0;
+ if (content_size > 0) {
+ result->content = (__bridge_retained void *)content;
+ }
+ if (error != NULL && content_size == 0) {
+ box_set_error_from_nw_error(&result->error, error);
+ }
+ if (is_complete && (context == NULL || nw_content_context_get_is_final(context))) {
+ result->eof = true;
+ }
+ box_apple_tls_read_callback(callback_handle, result);
+ }
+ });
+ return true;
+ }
+}
+
+ssize_t box_apple_tls_read_result_copy(box_apple_tls_read_result_t *result, void *buffer, size_t buffer_len, bool *eof_out, char **error_out) {
+ @autoreleasepool {
+ if (result == NULL) {
+ box_set_error_message(error_out, "apple TLS: read result unavailable");
+ return -1;
+ }
+ if (result->error != NULL) {
+ if (error_out != NULL) {
+ *error_out = result->error;
+ result->error = NULL;
+ } else {
+ free(result->error);
+ result->error = NULL;
+ }
+ return -1;
+ }
+ if (eof_out != NULL) {
+ *eof_out = result->eof;
+ }
+ dispatch_data_t content = box_apple_tls_read_result_content(result);
+ if (content == nil) {
+ return 0;
+ }
+ return box_apple_tls_dispatch_data_copy(content, buffer, buffer_len, error_out);
+ }
+}
+
+void box_apple_tls_read_result_free(box_apple_tls_read_result_t *result) {
+ if (result == NULL) {
+ return;
+ }
+ free(result->error);
+ if (result->content != NULL) {
+ CFBridgingRelease(result->content);
+ }
+ free(result);
+}
+
+bool box_apple_tls_client_copy_state(box_apple_tls_client_t *client, box_apple_tls_state_t *state, char **error_out) {
+ dispatch_queue_t queue = box_apple_tls_client_queue(client);
+ if (queue == nil || state == NULL) {
+ box_set_error_message(error_out, "apple TLS: invalid client");
+ return false;
+ }
+ memset(state, 0, sizeof(box_apple_tls_state_t));
+ __block bool copied = false;
+ __block char *local_error = NULL;
+ dispatch_sync(queue, ^{
+ if (!atomic_load(&client->ready)) {
+ box_set_error_message(&local_error, "apple TLS: metadata unavailable");
+ return;
+ }
+ if (!box_apple_tls_state_copy(&client->state, state)) {
+ box_set_error_message(&local_error, "apple TLS: out of memory");
+ return;
+ }
+ copied = true;
+ });
+ if (copied) {
+ return true;
+ }
+ if (local_error != NULL) {
+ if (error_out != NULL) {
+ *error_out = local_error;
+ } else {
+ free(local_error);
+ }
+ }
+ box_apple_tls_state_reset(state);
+ return false;
+}
+
+void box_apple_tls_state_free(box_apple_tls_state_t *state) {
+ box_apple_tls_state_reset(state);
+}
diff --git a/common/tls/apple_client_platform_dispatch_test.go b/common/tls/apple_client_platform_dispatch_test.go
new file mode 100644
index 0000000000..65261a925e
--- /dev/null
+++ b/common/tls/apple_client_platform_dispatch_test.go
@@ -0,0 +1,50 @@
+//go:build darwin && cgo
+
+package tls
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+)
+
+func TestAppleTLSDispatchDataCopySegments(t *testing.T) {
+ first := []byte("hello ")
+ second := []byte("world")
+
+ buffer := make([]byte, len(first)+len(second))
+ n, errorMessage := appleTLSCopyDispatchDataForTest(first, second, buffer)
+ if n < 0 {
+ t.Fatalf("copy failed: %s", errorMessage)
+ }
+ if int(n) != len(buffer) {
+ t.Fatalf("copied %d bytes, want %d", n, len(buffer))
+ }
+ if !bytes.Equal(buffer, []byte("hello world")) {
+ t.Fatalf("unexpected copy result: %q", string(buffer))
+ }
+}
+
+func TestAppleTLSDispatchDataCopyRejectsSmallBuffer(t *testing.T) {
+ first := []byte("hello")
+ second := []byte("world")
+
+ buffer := make([]byte, len(first)+len(second)-1)
+ n, errorMessage := appleTLSCopyDispatchDataForTest(first, second, buffer)
+ if n != -1 {
+ t.Fatalf("copied %d bytes, want error", n)
+ }
+ if !strings.Contains(errorMessage, "read buffer too small") {
+ t.Fatalf("unexpected error: %q", errorMessage)
+ }
+}
+
+func TestAppleTLSDispatchDataCopyEmpty(t *testing.T) {
+ n, errorMessage := appleTLSCopyDispatchDataForTest(nil, nil, nil)
+ if n != 0 {
+ t.Fatalf("copied %d bytes, want 0", n)
+ }
+ if errorMessage != "" {
+ t.Fatalf("unexpected error: %q", errorMessage)
+ }
+}
diff --git a/common/tls/apple_client_platform_dispatch_testhelper_darwin.go b/common/tls/apple_client_platform_dispatch_testhelper_darwin.go
new file mode 100644
index 0000000000..0d80d429d9
--- /dev/null
+++ b/common/tls/apple_client_platform_dispatch_testhelper_darwin.go
@@ -0,0 +1,44 @@
+//go:build darwin && cgo
+
+package tls
+
+/*
+#include
+#include "apple_client_platform_darwin.h"
+*/
+import "C"
+
+import "unsafe"
+
+func appleTLSCopyDispatchDataForTest(first, second []byte, buffer []byte) (int, string) {
+ var firstPtr unsafe.Pointer
+ if len(first) > 0 {
+ firstPtr = C.CBytes(first)
+ defer C.free(firstPtr)
+ }
+ var secondPtr unsafe.Pointer
+ if len(second) > 0 {
+ secondPtr = C.CBytes(second)
+ defer C.free(secondPtr)
+ }
+ var bufferPtr unsafe.Pointer
+ if len(buffer) > 0 {
+ bufferPtr = unsafe.Pointer(&buffer[0])
+ }
+ var errPtr *C.char
+ n := C.box_apple_tls_copy_dispatch_data_for_test(
+ firstPtr,
+ C.size_t(len(first)),
+ secondPtr,
+ C.size_t(len(second)),
+ bufferPtr,
+ C.size_t(len(buffer)),
+ &errPtr,
+ )
+ if errPtr == nil {
+ return int(n), ""
+ }
+ errorMessage := C.GoString(errPtr)
+ C.free(unsafe.Pointer(errPtr))
+ return int(n), errorMessage
+}
diff --git a/common/tls/apple_client_platform_test.go b/common/tls/apple_client_platform_test.go
new file mode 100644
index 0000000000..c7b93a1ba1
--- /dev/null
+++ b/common/tls/apple_client_platform_test.go
@@ -0,0 +1,766 @@
+//go:build darwin && cgo
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ stdtls "crypto/tls"
+ "errors"
+ "io"
+ "net"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/json/badoption"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const appleTLSTestTimeout = 5 * time.Second
+
+const (
+ appleTLSSuccessHandshakeLoops = 20
+ appleTLSFailureRecoveryLoops = 10
+)
+
+type appleTLSServerResult struct {
+ state stdtls.ConnectionState
+ err error
+}
+
+var (
+ _ N.ExtendedConn = (*appleTLSConn)(nil)
+ _ N.ReadWaitCreator = (*appleTLSConn)(nil)
+)
+
+func TestAppleClientHandshakeAppliesALPNAndVersion(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ for index := range appleTLSSuccessHandshakeLoops {
+ serverResult, serverAddress := startAppleTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2"},
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatalf("iteration %d: %v", index, err)
+ }
+
+ clientState := clientConn.ConnectionState()
+ if clientState.Version != stdtls.VersionTLS12 {
+ _ = clientConn.Close()
+ t.Fatalf("iteration %d: unexpected negotiated version: %x", index, clientState.Version)
+ }
+ if clientState.NegotiatedProtocol != "h2" {
+ _ = clientConn.Close()
+ t.Fatalf("iteration %d: unexpected negotiated protocol: %q", index, clientState.NegotiatedProtocol)
+ }
+ _ = clientConn.Close()
+
+ result := <-serverResult
+ if result.err != nil {
+ t.Fatalf("iteration %d: %v", index, result.err)
+ }
+ if result.state.Version != stdtls.VersionTLS12 {
+ t.Fatalf("iteration %d: server negotiated unexpected version: %x", index, result.state.Version)
+ }
+ if result.state.NegotiatedProtocol != "h2" {
+ t.Fatalf("iteration %d: server negotiated unexpected protocol: %q", index, result.state.NegotiatedProtocol)
+ }
+ }
+}
+
+func TestAppleClientHandshakeRejectsOpaqueConn(t *testing.T) {
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ Insecure: true,
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ clientConn, serverConn := net.Pipe()
+ defer clientConn.Close()
+ defer serverConn.Close()
+ _, err = ClientHandshake(context.Background(), clientConn, clientConfig)
+ if err == nil {
+ t.Fatal("expected handshake to reject non-TCP connection")
+ }
+}
+
+func TestAppleClientHandshakeRejectsVersionMismatch(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ serverResult, serverAddress := startAppleTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS13,
+ MaxVersion: stdtls.VersionTLS13,
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected version mismatch handshake to fail")
+ }
+
+ if result := <-serverResult; result.err == nil {
+ t.Fatal("expected server handshake to fail on version mismatch")
+ }
+}
+
+func TestAppleClientHandshakeRejectsServerNameMismatch(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ serverResult, serverAddress := startAppleTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "example.com",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected server name mismatch handshake to fail")
+ }
+
+ if result := <-serverResult; result.err == nil {
+ t.Fatal("expected server handshake to fail on server name mismatch")
+ }
+}
+
+func TestAppleClientHandshakeRecoversAfterFailure(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ testCases := []struct {
+ name string
+ serverConfig *stdtls.Config
+ clientOptions option.OutboundTLSOptions
+ }{
+ {
+ name: "version mismatch",
+ serverConfig: &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS13,
+ MaxVersion: stdtls.VersionTLS13,
+ },
+ clientOptions: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ },
+ {
+ name: "server name mismatch",
+ serverConfig: &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ },
+ clientOptions: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "example.com",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ },
+ }
+ successClientOptions := option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ for index := range appleTLSFailureRecoveryLoops {
+ failedResult, failedAddress := startAppleTLSTestServer(t, testCase.serverConfig)
+ failedConn, err := newAppleTestClientConn(t, failedAddress, testCase.clientOptions)
+ if err == nil {
+ _ = failedConn.Close()
+ t.Fatalf("iteration %d: expected handshake failure", index)
+ }
+ if result := <-failedResult; result.err == nil {
+ t.Fatalf("iteration %d: expected server handshake failure", index)
+ }
+
+ successResult, successAddress := startAppleTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2"},
+ })
+ successConn, err := newAppleTestClientConn(t, successAddress, successClientOptions)
+ if err != nil {
+ t.Fatalf("iteration %d: follow-up handshake failed: %v", index, err)
+ }
+ clientState := successConn.ConnectionState()
+ if clientState.NegotiatedProtocol != "h2" {
+ _ = successConn.Close()
+ t.Fatalf("iteration %d: unexpected negotiated protocol after failure: %q", index, clientState.NegotiatedProtocol)
+ }
+ _ = successConn.Close()
+
+ result := <-successResult
+ if result.err != nil {
+ t.Fatalf("iteration %d: follow-up server handshake failed: %v", index, result.err)
+ }
+ if result.state.NegotiatedProtocol != "h2" {
+ t.Fatalf("iteration %d: follow-up server negotiated unexpected protocol: %q", index, result.state.NegotiatedProtocol)
+ }
+ }
+ })
+ }
+}
+
+func TestAppleClientConfigCloneWithInlineCertificate(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2", "http/1.1"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ clone := clientConfig.Clone()
+ clone.SetServerName("other")
+ clone.SetNextProtos([]string{"http/1.1"})
+ if clientConfig.ServerName() == "other" {
+ t.Fatal("Clone shares server name with original")
+ }
+ nextProtos := clientConfig.NextProtos()
+ if len(nextProtos) != 2 || nextProtos[0] != "h2" || nextProtos[1] != "http/1.1" {
+ t.Fatalf("Clone shares ALPN slice with original: %v", nextProtos)
+ }
+
+ for index := range appleTLSFailureRecoveryLoops {
+ serverResult, serverAddress := startAppleTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2"},
+ })
+
+ handshakeConfig := clientConfig.Clone()
+ handshakeConfig.SetNextProtos([]string{"h2"})
+ clientConn, err := dialAppleTestClientConn(t, serverAddress, handshakeConfig)
+ if err != nil {
+ t.Fatalf("iteration %d: %v", index, err)
+ }
+
+ clientState := clientConn.ConnectionState()
+ if clientState.NegotiatedProtocol != "h2" {
+ _ = clientConn.Close()
+ t.Fatalf("iteration %d: unexpected negotiated protocol: %q", index, clientState.NegotiatedProtocol)
+ }
+ _ = clientConn.Close()
+
+ result := <-serverResult
+ if result.err != nil {
+ t.Fatalf("iteration %d: %v", index, result.err)
+ }
+ }
+}
+
+func TestAppleClientReadBuffer(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ payload := []byte("apple tls read buffer payload")
+ serverResult, serverAddress := startAppleTLSIOTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ }, func(conn *stdtls.Conn) error {
+ _, err := conn.Write(payload)
+ return err
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ extendedConn := clientConn.(N.ExtendedConn)
+ const (
+ frontHeadroom = 17
+ rearHeadroom = 19
+ )
+ buffer := buf.NewSize(frontHeadroom + len(payload) + rearHeadroom)
+ defer buffer.Release()
+ buffer.Resize(frontHeadroom, 0)
+ buffer.Reserve(rearHeadroom)
+ err = extendedConn.ReadBuffer(buffer)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(buffer.Bytes(), payload) {
+ t.Fatalf("unexpected payload: %q", buffer.Bytes())
+ }
+ if buffer.Start() != frontHeadroom {
+ t.Fatalf("unexpected front headroom: %d", buffer.Start())
+ }
+ if buffer.FreeLen() != 0 {
+ t.Fatalf("unexpected reserved free length before PostReturn: %d", buffer.FreeLen())
+ }
+ buffer.OverCap(rearHeadroom)
+ if buffer.FreeLen() != rearHeadroom {
+ t.Fatalf("unexpected rear headroom after PostReturn: %d", buffer.FreeLen())
+ }
+
+ if err = <-serverResult; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestAppleClientWriteBuffer(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ payload := bytes.Repeat([]byte("apple-write-buffer-"), 3000)
+ serverResult, serverAddress := startAppleTLSIOTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ }, func(conn *stdtls.Conn) error {
+ received := make([]byte, len(payload))
+ _, err := io.ReadFull(conn, received)
+ if err != nil {
+ return err
+ }
+ if !bytes.Equal(received, payload) {
+ return errors.New("payload mismatch")
+ }
+ return nil
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ extendedConn := clientConn.(N.ExtendedConn)
+ buffer := buf.NewSize(len(payload))
+ _, err = buffer.Write(payload)
+ if err != nil {
+ t.Fatal(err)
+ }
+ err = extendedConn.WriteBuffer(buffer)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if buffer.RawCap() != 0 {
+ t.Fatalf("buffer was not released: raw cap %d", buffer.RawCap())
+ }
+ if err = <-serverResult; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestAppleClientCreateReadWaiter(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ payload := []byte("apple tls read waiter payload")
+ serverResult, serverAddress := startAppleTLSIOTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ }, func(conn *stdtls.Conn) error {
+ _, err := conn.Write(payload)
+ return err
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ readWaitCreator := clientConn.(N.ReadWaitCreator)
+ readWaiter, ok := readWaitCreator.CreateReadWaiter()
+ if !ok {
+ t.Fatal("expected read waiter")
+ }
+ const (
+ frontHeadroom = 11
+ rearHeadroom = 13
+ )
+ needCopy := readWaiter.InitializeReadWaiter(N.ReadWaitOptions{
+ FrontHeadroom: frontHeadroom,
+ RearHeadroom: rearHeadroom,
+ MTU: len(payload),
+ })
+ if needCopy {
+ t.Fatal("expected owned read waiter buffer")
+ }
+ buffer, err := readWaiter.WaitReadBuffer()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer buffer.Release()
+ if !bytes.Equal(buffer.Bytes(), payload) {
+ t.Fatalf("unexpected payload: %q", buffer.Bytes())
+ }
+ if buffer.Start() != frontHeadroom {
+ t.Fatalf("unexpected front headroom: %d", buffer.Start())
+ }
+ if buffer.FreeLen() != rearHeadroom {
+ t.Fatalf("unexpected rear headroom: %d", buffer.FreeLen())
+ }
+ if buffer.Cap() != buffer.RawCap() {
+ t.Fatalf("capacity was not restored: cap=%d raw=%d", buffer.Cap(), buffer.RawCap())
+ }
+
+ if err = <-serverResult; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestAppleClientReadDeadline(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ serverDone, serverAddress := startAppleTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+ defer close(serverDone)
+
+ err = clientConn.SetReadDeadline(time.Now().Add(200 * time.Millisecond))
+ if err != nil {
+ t.Fatalf("SetReadDeadline: %v", err)
+ }
+
+ readDone := make(chan error, 1)
+ buffer := make([]byte, 64)
+ go func() {
+ _, readErr := clientConn.Read(buffer)
+ readDone <- readErr
+ }()
+
+ select {
+ case readErr := <-readDone:
+ if !errors.Is(readErr, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", readErr)
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("Read did not return within 2s after deadline")
+ }
+
+ _, err = clientConn.Read(buffer)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("sticky deadline: expected os.ErrDeadlineExceeded, got %v", err)
+ }
+}
+
+func TestAppleClientSetDeadlineClearsPreExpiredSticky(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newAppleTestCertificate(t, "localhost")
+ serverDone, serverAddress := startAppleTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+
+ clientConn, err := newAppleTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: "apple",
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+ defer close(serverDone)
+
+ err = clientConn.SetReadDeadline(time.Now().Add(-time.Second))
+ if err != nil {
+ t.Fatalf("SetReadDeadline past: %v", err)
+ }
+
+ // Pre-expired deadline trips sticky flag without cancelling nw_connection
+ // (prepareReadTimeout short-circuits before the C read is issued).
+ buffer := make([]byte, 64)
+ _, err = clientConn.Read(buffer)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("pre-expired: expected os.ErrDeadlineExceeded, got %v", err)
+ }
+
+ err = clientConn.SetReadDeadline(time.Time{})
+ if err != nil {
+ t.Fatalf("SetReadDeadline zero: %v", err)
+ }
+
+ newDeadline := 300 * time.Millisecond
+ err = clientConn.SetReadDeadline(time.Now().Add(newDeadline))
+ if err != nil {
+ t.Fatalf("SetReadDeadline future: %v", err)
+ }
+
+ readStart := time.Now()
+ _, err = clientConn.Read(buffer)
+ readElapsed := time.Since(readStart)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("after clear: expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ if readElapsed < newDeadline-50*time.Millisecond {
+ t.Fatalf("sticky flag was not cleared: Read returned after %v, expected ~%v", readElapsed, newDeadline)
+ }
+}
+
+func startAppleTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config) (chan<- struct{}, string) {
+ t.Helper()
+
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ listener.Close()
+ })
+
+ if tcpListener, isTCP := listener.(*net.TCPListener); isTCP {
+ err = tcpListener.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ done := make(chan struct{})
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+ handshakeErr := conn.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if handshakeErr != nil {
+ return
+ }
+ tlsConn := stdtls.Server(conn, tlsConfig)
+ defer tlsConn.Close()
+ handshakeErr = tlsConn.Handshake()
+ if handshakeErr != nil {
+ return
+ }
+ handshakeErr = conn.SetDeadline(time.Time{})
+ if handshakeErr != nil {
+ return
+ }
+ <-done
+ }()
+ return done, listener.Addr().String()
+}
+
+func startAppleTLSIOTestServer(t testing.TB, tlsConfig *stdtls.Config, handler func(*stdtls.Conn) error) (<-chan error, string) {
+ t.Helper()
+
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ listener.Close()
+ })
+
+ if tcpListener, isTCP := listener.(*net.TCPListener); isTCP {
+ err = tcpListener.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ result := make(chan error, 1)
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ result <- err
+ return
+ }
+ defer conn.Close()
+
+ err = conn.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if err != nil {
+ result <- err
+ return
+ }
+
+ tlsConn := stdtls.Server(conn, tlsConfig)
+ defer tlsConn.Close()
+ err = tlsConn.Handshake()
+ if err != nil {
+ result <- err
+ return
+ }
+ result <- handler(tlsConn)
+ }()
+ return result, listener.Addr().String()
+}
+
+func newAppleTestCertificate(t testing.TB, serverName string) (stdtls.Certificate, string) {
+ t.Helper()
+
+ privateKeyPEM, certificatePEM, err := GenerateCertificate(nil, nil, time.Now, serverName, time.Now().Add(time.Hour))
+ if err != nil {
+ t.Fatal(err)
+ }
+ certificate, err := stdtls.X509KeyPair(certificatePEM, privateKeyPEM)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return certificate, string(certificatePEM)
+}
+
+func startAppleTLSTestServer(t *testing.T, tlsConfig *stdtls.Config) (<-chan appleTLSServerResult, string) {
+ t.Helper()
+
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() {
+ listener.Close()
+ })
+
+ if tcpListener, isTCP := listener.(*net.TCPListener); isTCP {
+ err = tcpListener.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ result := make(chan appleTLSServerResult, 1)
+ go func() {
+ defer close(result)
+
+ conn, err := listener.Accept()
+ if err != nil {
+ result <- appleTLSServerResult{err: err}
+ return
+ }
+ defer conn.Close()
+
+ err = conn.SetDeadline(time.Now().Add(appleTLSTestTimeout))
+ if err != nil {
+ result <- appleTLSServerResult{err: err}
+ return
+ }
+
+ tlsConn := stdtls.Server(conn, tlsConfig)
+ defer tlsConn.Close()
+
+ err = tlsConn.Handshake()
+ if err != nil {
+ result <- appleTLSServerResult{err: err}
+ return
+ }
+
+ result <- appleTLSServerResult{state: tlsConn.ConnectionState()}
+ }()
+
+ return result, listener.Addr().String()
+}
+
+func newAppleTestClientConn(t testing.TB, serverAddress string, options option.OutboundTLSOptions) (Conn, error) {
+ t.Helper()
+
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ ServerAddress: "",
+ Options: options,
+ })
+ if err != nil {
+ return nil, err
+ }
+ return dialAppleTestClientConn(t, serverAddress, clientConfig)
+}
+
+func dialAppleTestClientConn(t testing.TB, serverAddress string, clientConfig Config) (Conn, error) {
+ t.Helper()
+
+ ctx, cancel := context.WithTimeout(context.Background(), appleTLSTestTimeout)
+ t.Cleanup(cancel)
+
+ conn, err := net.DialTimeout("tcp", serverAddress, appleTLSTestTimeout)
+ if err != nil {
+ return nil, err
+ }
+
+ tlsConn, err := ClientHandshake(ctx, conn, clientConfig)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return tlsConn, nil
+}
diff --git a/common/tls/apple_client_stub.go b/common/tls/apple_client_stub.go
new file mode 100644
index 0000000000..33b7df47c5
--- /dev/null
+++ b/common/tls/apple_client_stub.go
@@ -0,0 +1,15 @@
+//go:build !darwin || !cgo
+
+package tls
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+)
+
+func newAppleClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
+ return nil, E.New("Apple TLS engine is not available on non-Apple platforms")
+}
diff --git a/common/tls/client.go b/common/tls/client.go
index 839699547c..7b303687ca 100644
--- a/common/tls/client.go
+++ b/common/tls/client.go
@@ -6,16 +6,45 @@ import (
"errors"
"net"
"os"
+ "strings"
"github.com/sagernet/sing-box/common/badtls"
+ "github.com/sagernet/sing-box/common/tlsspoof"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
aTLS "github.com/sagernet/sing/common/tls"
)
+var errMissingServerName = E.New("missing server_name or insecure=true")
+
+func parseTLSSpoofOptions(serverName string, options option.OutboundTLSOptions) (string, tlsspoof.Method, error) {
+ spoof, method, err := tlsspoof.ParseOptions(options.Spoof, options.SpoofMethod)
+ if err != nil {
+ return "", 0, err
+ }
+ if spoof == "" {
+ return "", 0, nil
+ }
+ if options.DisableSNI || serverName == "" || M.ParseAddr(serverName).IsValid() {
+ return "", 0, E.New("`spoof` requires TLS ClientHello with SNI")
+ }
+ if strings.EqualFold(spoof, serverName) {
+ return "", 0, E.New("`spoof` must differ from `server_name`")
+ }
+ return spoof, method, nil
+}
+
+func applyTLSSpoof(conn net.Conn, spoof string, method tlsspoof.Method) (net.Conn, error) {
+ if spoof == "" {
+ return conn, nil
+ }
+ return tlsspoof.NewConn(conn, method, spoof)
+}
+
func NewDialerFromOptions(ctx context.Context, logger logger.ContextLogger, dialer N.Dialer, serverAddress string, options option.OutboundTLSOptions) (N.Dialer, error) {
if !options.Enabled {
return dialer, nil
@@ -42,11 +71,12 @@ func NewClient(ctx context.Context, logger logger.ContextLogger, serverAddress s
}
type ClientOptions struct {
- Context context.Context
- Logger logger.ContextLogger
- ServerAddress string
- Options option.OutboundTLSOptions
- KTLSCompatible bool
+ Context context.Context
+ Logger logger.ContextLogger
+ ServerAddress string
+ Options option.OutboundTLSOptions
+ AllowEmptyServerName bool
+ KTLSCompatible bool
}
func NewClientWithOptions(options ClientOptions) (Config, error) {
@@ -61,17 +91,24 @@ func NewClientWithOptions(options ClientOptions) (Config, error) {
if options.Options.KernelRx {
options.Logger.Warn("enabling kTLS RX will definitely reduce performance, please checkout https://sing-box.sagernet.org/configuration/shared/tls/#kernel_rx")
}
+ switch options.Options.Engine {
+ case "", C.TLSEngineGo:
+ case C.TLSEngineApple:
+ return newAppleClient(options.Context, options.Logger, options.ServerAddress, options.Options, options.AllowEmptyServerName)
+ case C.TLSEngineWindows:
+ return newWindowsClient(options.Context, options.Logger, options.ServerAddress, options.Options, options.AllowEmptyServerName)
+ default:
+ return nil, E.New("unknown tls engine: ", options.Options.Engine)
+ }
if options.Options.Reality != nil && options.Options.Reality.Enabled {
- return NewRealityClient(options.Context, options.Logger, options.ServerAddress, options.Options)
+ return newRealityClient(options.Context, options.Logger, options.ServerAddress, options.Options, options.AllowEmptyServerName)
} else if options.Options.UTLS != nil && options.Options.UTLS.Enabled {
- return NewUTLSClient(options.Context, options.Logger, options.ServerAddress, options.Options)
+ return newUTLSClient(options.Context, options.Logger, options.ServerAddress, options.Options, options.AllowEmptyServerName)
}
- return NewSTDClient(options.Context, options.Logger, options.ServerAddress, options.Options)
+ return newSTDClient(options.Context, options.Logger, options.ServerAddress, options.Options, options.AllowEmptyServerName)
}
func ClientHandshake(ctx context.Context, conn net.Conn, config Config) (Conn, error) {
- ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
- defer cancel()
tlsConn, err := aTLS.ClientHandshake(ctx, conn, config)
if err != nil {
return nil, err
diff --git a/common/tls/client_test.go b/common/tls/client_test.go
new file mode 100644
index 0000000000..5bc939e29e
--- /dev/null
+++ b/common/tls/client_test.go
@@ -0,0 +1,154 @@
+package tls
+
+import (
+ "context"
+ "crypto/tls"
+ "net"
+ "testing"
+
+ tf "github.com/sagernet/sing-box/common/tlsfragment"
+ "github.com/sagernet/sing-box/common/tlsspoof"
+ "github.com/sagernet/sing-box/option"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestParseTLSSpoofOptions_Disabled(t *testing.T) {
+ t.Parallel()
+ spoof, method, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{})
+ require.NoError(t, err)
+ require.Empty(t, spoof)
+ require.Equal(t, tlsspoof.MethodWrongSequence, method)
+}
+
+func TestParseTLSSpoofOptions_MethodWithoutSpoof(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ SpoofMethod: tlsspoof.MethodNameWrongChecksum,
+ })
+ require.Error(t, err)
+}
+
+func TestParseTLSSpoofOptions_IPLiteralRejected(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("1.2.3.4", option.OutboundTLSOptions{
+ Spoof: "example.com",
+ })
+ require.Error(t, err)
+}
+
+func TestParseTLSSpoofOptions_EmptyServerNameRejected(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("", option.OutboundTLSOptions{
+ Spoof: "example.com",
+ })
+ require.Error(t, err)
+}
+
+func TestParseTLSSpoofOptions_DisableSNIRejected(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ Spoof: "decoy.com",
+ DisableSNI: true,
+ })
+ require.Error(t, err)
+}
+
+// TestParseTLSSpoofOptions_RejectsSameSNI is the primary regression test for
+// the "spoofed packet contains the original SNI" bug report: when a user
+// configures spoof equal to server_name, the rewriter produces a byte-identical
+// record, so the fake and real ClientHellos on the wire look the same. Reject
+// at parse time.
+func TestParseTLSSpoofOptions_RejectsSameSNI(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ Spoof: "example.com",
+ })
+ require.Error(t, err)
+
+ _, _, err = parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ Spoof: "EXAMPLE.com",
+ })
+ require.Error(t, err, "comparison must be case-insensitive")
+}
+
+func TestParseTLSSpoofOptions_UnknownMethodRejected(t *testing.T) {
+ t.Parallel()
+ _, _, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ Spoof: "decoy.com",
+ SpoofMethod: "nonsense",
+ })
+ require.Error(t, err)
+}
+
+func TestParseTLSSpoofOptions_DistinctSNIAccepted(t *testing.T) {
+ t.Parallel()
+ if !tlsspoof.PlatformSupported {
+ t.Skip("tlsspoof not supported on this platform")
+ }
+ spoof, method, err := parseTLSSpoofOptions("example.com", option.OutboundTLSOptions{
+ Spoof: "decoy.com",
+ SpoofMethod: tlsspoof.MethodNameWrongSequence,
+ })
+ require.NoError(t, err)
+ require.Equal(t, "decoy.com", spoof)
+ require.Equal(t, tlsspoof.MethodWrongSequence, method)
+}
+
+// The following tests guard the wrap gate in STDClientConfig.Client():
+// tf.Conn must wrap the underlying connection whenever either `fragment` or
+// `record_fragment` is set, so that TLS fragmentation coexists with features
+// like tls_spoof that layer on top of tf.Conn.
+
+func newSTDClientConfigForGateTest(fragment, recordFragment bool) *STDClientConfig {
+ return &STDClientConfig{
+ ctx: context.Background(),
+ config: &tls.Config{ServerName: "example.com", InsecureSkipVerify: true},
+ fragment: fragment,
+ recordFragment: recordFragment,
+ }
+}
+
+func TestSTDClient_Client_NoFragment_DoesNotWrap(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newSTDClientConfigForGateTest(false, false).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.False(t, isTF, "no fragment flags: must not wrap with tf.Conn")
+}
+
+func TestSTDClient_Client_FragmentOnly_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newSTDClientConfigForGateTest(true, false).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "fragment=true: must wrap with tf.Conn")
+}
+
+func TestSTDClient_Client_RecordFragmentOnly_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newSTDClientConfigForGateTest(false, true).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "record_fragment=true: must wrap with tf.Conn")
+}
+
+func TestSTDClient_Client_BothFragment_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newSTDClientConfigForGateTest(true, true).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "both fragment flags: must wrap with tf.Conn")
+}
diff --git a/common/tls/masque_client.go b/common/tls/masque_client.go
new file mode 100644
index 0000000000..e9e4028995
--- /dev/null
+++ b/common/tls/masque_client.go
@@ -0,0 +1,81 @@
+package tls
+
+import (
+ "context"
+ "crypto/ecdsa"
+ "crypto/tls"
+ "crypto/x509"
+ "time"
+
+ "github.com/sagernet/quic-go/http3"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+)
+
+func NewMASQUEClient(ctx context.Context, logger logger.ContextLogger, serverName string, cert [][]byte, privateKey *ecdsa.PrivateKey, peerPublicKey *ecdsa.PublicKey, options option.MASQUEOutboundTLSOptions) (Config, error) {
+ var tlsConfig tls.Config
+ tlsConfig.ServerName = serverName
+ tlsConfig.InsecureSkipVerify = true
+ tlsConfig.NextProtos = []string{http3.NextProtoH3}
+ tlsConfig.Certificates = []tls.Certificate{
+ {
+ Certificate: cert,
+ PrivateKey: privateKey,
+ },
+ }
+ if options.CipherSuites != nil {
+ find:
+ for _, cipherSuite := range options.CipherSuites {
+ for _, tlsCipherSuite := range tls.CipherSuites() {
+ if cipherSuite == tlsCipherSuite.Name {
+ tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, tlsCipherSuite.ID)
+ continue find
+ }
+ }
+ return nil, E.New("unknown cipher_suite: ", cipherSuite)
+ }
+ }
+ for _, curve := range options.CurvePreferences {
+ tlsConfig.CurvePreferences = append(tlsConfig.CurvePreferences, tls.CurveID(curve))
+ }
+ if !options.Insecure {
+ tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ if len(rawCerts) == 0 {
+ return nil
+ }
+ cert, err := x509.ParseCertificate(rawCerts[0])
+ if err != nil {
+ return err
+ }
+ if _, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
+ return x509.ErrUnsupportedAlgorithm
+ }
+ if !cert.PublicKey.(*ecdsa.PublicKey).Equal(peerPublicKey) {
+ return x509.CertificateInvalidError{Cert: cert, Reason: 10, Detail: "remote endpoint has a different public key than what we trust in config.json"}
+ }
+ return nil
+ }
+ }
+ var config Config = &STDClientConfig{
+ ctx: ctx,
+ config: &tlsConfig,
+ serverName: serverName,
+ fragment: options.Fragment,
+ fragmentFallbackDelay: time.Duration(options.FragmentFallbackDelay),
+ recordFragment: options.RecordFragment,
+ }
+ if options.KernelRx || options.KernelTx {
+ if !C.IsLinux {
+ return nil, E.New("kTLS is only supported on Linux")
+ }
+ config = &KTLSClientConfig{
+ Config: config,
+ logger: logger,
+ kernelTx: options.KernelTx,
+ kernelRx: options.KernelRx,
+ }
+ }
+ return config, nil
+}
diff --git a/common/tls/reality_client.go b/common/tls/reality_client.go
index d8328770df..af64ef6f29 100644
--- a/common/tls/reality_client.go
+++ b/common/tls/reality_client.go
@@ -52,11 +52,18 @@ type RealityClientConfig struct {
}
func NewRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
+ return newRealityClient(ctx, logger, serverAddress, options, false)
+}
+
+func newRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
if options.UTLS == nil || !options.UTLS.Enabled {
return nil, E.New("uTLS is required by reality client")
}
+ if options.Spoof != "" || options.SpoofMethod != "" {
+ return nil, E.New("spoof is unsupported in reality")
+ }
- uClient, err := NewUTLSClient(ctx, logger, serverAddress, options)
+ uClient, err := newUTLSClient(ctx, logger, serverAddress, options, allowEmptyServerName)
if err != nil {
return nil, err
}
@@ -108,6 +115,14 @@ func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
e.uClient.SetNextProtos(nextProto)
}
+func (e *RealityClientConfig) HandshakeTimeout() time.Duration {
+ return e.uClient.HandshakeTimeout()
+}
+
+func (e *RealityClientConfig) SetHandshakeTimeout(timeout time.Duration) {
+ e.uClient.SetHandshakeTimeout(timeout)
+}
+
func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
return nil, E.New("unsupported usage for reality")
}
diff --git a/common/tls/reality_server.go b/common/tls/reality_server.go
index 5fc684756b..10d6061870 100644
--- a/common/tls/reality_server.go
+++ b/common/tls/reality_server.go
@@ -26,12 +26,17 @@ import (
var _ ServerConfigCompat = (*RealityServerConfig)(nil)
type RealityServerConfig struct {
- config *utls.RealityConfig
+ config *utls.RealityConfig
+ handshakeTimeout time.Duration
}
func NewRealityServer(ctx context.Context, logger log.ContextLogger, options option.InboundTLSOptions) (ServerConfig, error) {
var tlsConfig utls.RealityConfig
+ if options.CertificateProvider != nil {
+ return nil, E.New("certificate_provider is unavailable in reality")
+ }
+ //nolint:staticcheck
if options.ACME != nil && len(options.ACME.Domain) > 0 {
return nil, E.New("acme is unavailable in reality")
}
@@ -126,7 +131,16 @@ func NewRealityServer(ctx context.Context, logger log.ContextLogger, options opt
if options.ECH != nil && options.ECH.Enabled {
return nil, E.New("Reality is conflict with ECH")
}
- var config ServerConfig = &RealityServerConfig{&tlsConfig}
+ var handshakeTimeout time.Duration
+ if options.HandshakeTimeout > 0 {
+ handshakeTimeout = options.HandshakeTimeout.Build()
+ } else {
+ handshakeTimeout = C.TCPTimeout
+ }
+ var config ServerConfig = &RealityServerConfig{
+ config: &tlsConfig,
+ handshakeTimeout: handshakeTimeout,
+ }
if options.KernelTx || options.KernelRx {
if !C.IsLinux {
return nil, E.New("kTLS is only supported on Linux")
@@ -157,6 +171,14 @@ func (c *RealityServerConfig) SetNextProtos(nextProto []string) {
c.config.NextProtos = nextProto
}
+func (c *RealityServerConfig) HandshakeTimeout() time.Duration {
+ return c.handshakeTimeout
+}
+
+func (c *RealityServerConfig) SetHandshakeTimeout(timeout time.Duration) {
+ c.handshakeTimeout = timeout
+}
+
func (c *RealityServerConfig) STDConfig() (*tls.Config, error) {
return nil, E.New("unsupported usage for reality")
}
@@ -187,7 +209,8 @@ func (c *RealityServerConfig) ServerHandshake(ctx context.Context, conn net.Conn
func (c *RealityServerConfig) Clone() Config {
return &RealityServerConfig{
- config: c.config.Clone(),
+ config: c.config.Clone(),
+ handshakeTimeout: c.handshakeTimeout,
}
}
diff --git a/common/tls/server.go b/common/tls/server.go
index 74b240fc75..8f4b3c38d0 100644
--- a/common/tls/server.go
+++ b/common/tls/server.go
@@ -46,8 +46,11 @@ func NewServerWithOptions(options ServerOptions) (ServerConfig, error) {
}
func ServerHandshake(ctx context.Context, conn net.Conn, config ServerConfig) (Conn, error) {
- ctx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
- defer cancel()
+ if config.HandshakeTimeout() == 0 {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, C.TCPTimeout)
+ defer cancel()
+ }
tlsConn, err := aTLS.ServerHandshake(ctx, conn, config)
if err != nil {
return nil, err
diff --git a/common/tls/std_client.go b/common/tls/std_client.go
index 1611c83e7c..6531039604 100644
--- a/common/tls/std_client.go
+++ b/common/tls/std_client.go
@@ -14,6 +14,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tlsfragment"
+ "github.com/sagernet/sing-box/common/tlsspoof"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
@@ -24,16 +25,32 @@ import (
type STDClientConfig struct {
ctx context.Context
config *tls.Config
+ serverName string
+ disableSNI bool
+ verifyServerName bool
+ handshakeTimeout time.Duration
fragment bool
fragmentFallbackDelay time.Duration
recordFragment bool
+ spoof string
+ spoofMethod tlsspoof.Method
}
func (c *STDClientConfig) ServerName() string {
- return c.config.ServerName
+ return c.serverName
}
func (c *STDClientConfig) SetServerName(serverName string) {
+ c.serverName = serverName
+ if c.disableSNI {
+ c.config.ServerName = ""
+ if c.verifyServerName {
+ c.config.VerifyConnection = verifyConnection(c.config.RootCAs, c.config.Time, serverName)
+ } else {
+ c.config.VerifyConnection = nil
+ }
+ return
+ }
c.config.ServerName = serverName
}
@@ -45,25 +62,45 @@ func (c *STDClientConfig) SetNextProtos(nextProto []string) {
c.config.NextProtos = nextProto
}
+func (c *STDClientConfig) HandshakeTimeout() time.Duration {
+ return c.handshakeTimeout
+}
+
+func (c *STDClientConfig) SetHandshakeTimeout(timeout time.Duration) {
+ c.handshakeTimeout = timeout
+}
+
func (c *STDClientConfig) STDConfig() (*STDConfig, error) {
return c.config, nil
}
func (c *STDClientConfig) Client(conn net.Conn) (Conn, error) {
- if c.recordFragment {
+ if c.fragment || c.recordFragment {
conn = tf.NewConn(conn, c.ctx, c.fragment, c.recordFragment, c.fragmentFallbackDelay)
}
+ conn, err := applyTLSSpoof(conn, c.spoof, c.spoofMethod)
+ if err != nil {
+ return nil, err
+ }
return tls.Client(conn, c.config), nil
}
func (c *STDClientConfig) Clone() Config {
- return &STDClientConfig{
+ cloned := &STDClientConfig{
ctx: c.ctx,
config: c.config.Clone(),
+ serverName: c.serverName,
+ disableSNI: c.disableSNI,
+ verifyServerName: c.verifyServerName,
+ handshakeTimeout: c.handshakeTimeout,
fragment: c.fragment,
fragmentFallbackDelay: c.fragmentFallbackDelay,
recordFragment: c.recordFragment,
+ spoof: c.spoof,
+ spoofMethod: c.spoofMethod,
}
+ cloned.SetServerName(cloned.serverName)
+ return cloned
}
func (c *STDClientConfig) ECHConfigList() []byte {
@@ -75,41 +112,27 @@ func (c *STDClientConfig) SetECHConfigList(EncryptedClientHelloConfigList []byte
}
func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
+ return newSTDClient(ctx, logger, serverAddress, options, false)
+}
+
+func newSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
var serverName string
if options.ServerName != "" {
serverName = options.ServerName
} else if serverAddress != "" {
serverName = serverAddress
}
- if serverName == "" && !options.Insecure {
- return nil, E.New("missing server_name or insecure=true")
+ if serverName == "" && !options.Insecure && !allowEmptyServerName {
+ return nil, errMissingServerName
}
var tlsConfig tls.Config
tlsConfig.Time = ntp.TimeFuncFromContext(ctx)
tlsConfig.RootCAs = adapter.RootPoolFromContext(ctx)
- if !options.DisableSNI {
- tlsConfig.ServerName = serverName
- }
if options.Insecure {
tlsConfig.InsecureSkipVerify = options.Insecure
} else if options.DisableSNI {
tlsConfig.InsecureSkipVerify = true
- tlsConfig.VerifyConnection = func(state tls.ConnectionState) error {
- verifyOptions := x509.VerifyOptions{
- Roots: tlsConfig.RootCAs,
- DNSName: serverName,
- Intermediates: x509.NewCertPool(),
- }
- for _, cert := range state.PeerCertificates[1:] {
- verifyOptions.Intermediates.AddCert(cert)
- }
- if tlsConfig.Time != nil {
- verifyOptions.CurrentTime = tlsConfig.Time()
- }
- _, err := state.PeerCertificates[0].Verify(verifyOptions)
- return err
- }
}
if len(options.CertificatePublicKeySHA256) > 0 {
if len(options.Certificate) > 0 || options.CertificatePath != "" {
@@ -117,7 +140,7 @@ func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddres
}
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
- return verifyPublicKeySHA256(options.CertificatePublicKeySHA256, rawCerts, tlsConfig.Time)
+ return VerifyPublicKeySHA256(options.CertificatePublicKeySHA256, rawCerts)
}
}
if len(options.ALPN) > 0 {
@@ -198,7 +221,30 @@ func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddres
} else if len(clientCertificate) > 0 || len(clientKey) > 0 {
return nil, E.New("client certificate and client key must be provided together")
}
- var config Config = &STDClientConfig{ctx, &tlsConfig, options.Fragment, time.Duration(options.FragmentFallbackDelay), options.RecordFragment}
+ var handshakeTimeout time.Duration
+ if options.HandshakeTimeout > 0 {
+ handshakeTimeout = options.HandshakeTimeout.Build()
+ } else {
+ handshakeTimeout = C.TCPTimeout
+ }
+ spoof, spoofMethod, err := parseTLSSpoofOptions(serverName, options)
+ if err != nil {
+ return nil, err
+ }
+ var config Config = &STDClientConfig{
+ ctx: ctx,
+ config: &tlsConfig,
+ serverName: serverName,
+ disableSNI: options.DisableSNI,
+ verifyServerName: options.DisableSNI && !options.Insecure,
+ handshakeTimeout: handshakeTimeout,
+ fragment: options.Fragment,
+ fragmentFallbackDelay: time.Duration(options.FragmentFallbackDelay),
+ recordFragment: options.RecordFragment,
+ spoof: spoof,
+ spoofMethod: spoofMethod,
+ }
+ config.SetServerName(serverName)
if options.ECH != nil && options.ECH.Enabled {
var err error
config, err = parseECHClientConfig(ctx, config.(ECHCapableConfig), options)
@@ -220,7 +266,16 @@ func NewSTDClient(ctx context.Context, logger logger.ContextLogger, serverAddres
return config, nil
}
-func verifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte, timeFunc func() time.Time) error {
+func verifyConnection(rootCAs *x509.CertPool, timeFunc func() time.Time, serverName string) func(state tls.ConnectionState) error {
+ return func(state tls.ConnectionState) error {
+ if serverName == "" {
+ return errMissingServerName
+ }
+ return verifySystemTLSPeer(rootCAs, serverName, timeFunc, state.PeerCertificates)
+ }
+}
+
+func VerifyPublicKeySHA256(knownHashValues [][]byte, rawCerts [][]byte) error {
leafCertificate, err := x509.ParseCertificate(rawCerts[0])
if err != nil {
return E.Cause(err, "failed to parse leaf certificate")
diff --git a/common/tls/std_server.go b/common/tls/std_server.go
index a1a2a611de..a99b327579 100644
--- a/common/tls/std_server.go
+++ b/common/tls/std_server.go
@@ -13,19 +13,88 @@ import (
"github.com/sagernet/fswatch"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/ntp"
+ "github.com/sagernet/sing/service"
)
var errInsecureUnused = E.New("tls: insecure unused")
+type managedCertificateProvider interface {
+ adapter.CertificateProvider
+ adapter.SimpleLifecycle
+}
+
+type sharedCertificateProvider struct {
+ tag string
+ manager adapter.CertificateProviderManager
+ provider adapter.CertificateProviderService
+}
+
+func (p *sharedCertificateProvider) Start() error {
+ provider, found := p.manager.Get(p.tag)
+ if !found {
+ return E.New("certificate provider not found: ", p.tag)
+ }
+ p.provider = provider
+ return nil
+}
+
+func (p *sharedCertificateProvider) Close() error {
+ return nil
+}
+
+func (p *sharedCertificateProvider) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ return p.provider.GetCertificate(hello)
+}
+
+func (p *sharedCertificateProvider) GetACMENextProtos() []string {
+ return getACMENextProtos(p.provider)
+}
+
+type inlineCertificateProvider struct {
+ provider adapter.CertificateProviderService
+}
+
+func (p *inlineCertificateProvider) Start() error {
+ for _, stage := range adapter.ListStartStages {
+ err := adapter.LegacyStart(p.provider, stage)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (p *inlineCertificateProvider) Close() error {
+ return p.provider.Close()
+}
+
+func (p *inlineCertificateProvider) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ return p.provider.GetCertificate(hello)
+}
+
+func (p *inlineCertificateProvider) GetACMENextProtos() []string {
+ return getACMENextProtos(p.provider)
+}
+
+func getACMENextProtos(provider adapter.CertificateProvider) []string {
+ if acmeProvider, isACME := provider.(adapter.ACMECertificateProvider); isACME {
+ return acmeProvider.GetACMENextProtos()
+ }
+ return nil
+}
+
type STDServerConfig struct {
access sync.RWMutex
config *tls.Config
+ handshakeTimeout time.Duration
logger log.Logger
+ certificateProvider managedCertificateProvider
acmeService adapter.SimpleLifecycle
certificate []byte
key []byte
@@ -53,18 +122,17 @@ func (c *STDServerConfig) SetServerName(serverName string) {
func (c *STDServerConfig) NextProtos() []string {
c.access.RLock()
defer c.access.RUnlock()
- if c.acmeService != nil && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == ACMETLS1Protocol {
+ if c.hasACMEALPN() && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == C.ACMETLS1Protocol {
return c.config.NextProtos[1:]
- } else {
- return c.config.NextProtos
}
+ return c.config.NextProtos
}
func (c *STDServerConfig) SetNextProtos(nextProto []string) {
c.access.Lock()
defer c.access.Unlock()
config := c.config.Clone()
- if c.acmeService != nil && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == ACMETLS1Protocol {
+ if c.hasACMEALPN() && len(c.config.NextProtos) > 1 && c.config.NextProtos[0] == C.ACMETLS1Protocol {
config.NextProtos = append(c.config.NextProtos[:1], nextProto...)
} else {
config.NextProtos = nextProto
@@ -72,6 +140,30 @@ func (c *STDServerConfig) SetNextProtos(nextProto []string) {
c.config = config
}
+func (c *STDServerConfig) HandshakeTimeout() time.Duration {
+ c.access.RLock()
+ defer c.access.RUnlock()
+ return c.handshakeTimeout
+}
+
+func (c *STDServerConfig) SetHandshakeTimeout(timeout time.Duration) {
+ c.access.Lock()
+ defer c.access.Unlock()
+ c.handshakeTimeout = timeout
+}
+
+func (c *STDServerConfig) hasACMEALPN() bool {
+ if c.acmeService != nil {
+ return true
+ }
+ if c.certificateProvider != nil {
+ if acmeProvider, isACME := c.certificateProvider.(adapter.ACMECertificateProvider); isACME {
+ return len(acmeProvider.GetACMENextProtos()) > 0
+ }
+ }
+ return false
+}
+
func (c *STDServerConfig) STDConfig() (*STDConfig, error) {
return c.config, nil
}
@@ -86,20 +178,45 @@ func (c *STDServerConfig) Server(conn net.Conn) (Conn, error) {
func (c *STDServerConfig) Clone() Config {
return &STDServerConfig{
- config: c.config.Clone(),
+ config: c.config.Clone(),
+ handshakeTimeout: c.handshakeTimeout,
}
}
func (c *STDServerConfig) Start() error {
+ if c.certificateProvider != nil {
+ err := c.certificateProvider.Start()
+ if err != nil {
+ return err
+ }
+ if acmeProvider, isACME := c.certificateProvider.(adapter.ACMECertificateProvider); isACME {
+ nextProtos := acmeProvider.GetACMENextProtos()
+ if len(nextProtos) > 0 {
+ c.access.Lock()
+ config := c.config.Clone()
+ mergedNextProtos := append([]string{}, nextProtos...)
+ for _, nextProto := range config.NextProtos {
+ if !common.Contains(mergedNextProtos, nextProto) {
+ mergedNextProtos = append(mergedNextProtos, nextProto)
+ }
+ }
+ config.NextProtos = mergedNextProtos
+ c.config = config
+ c.access.Unlock()
+ }
+ }
+ }
if c.acmeService != nil {
- return c.acmeService.Start()
- } else {
- err := c.startWatcher()
+ err := c.acmeService.Start()
if err != nil {
- c.logger.Warn("create fsnotify watcher: ", err)
+ return err
}
- return nil
}
+ err := c.startWatcher()
+ if err != nil {
+ c.logger.Warn("create fsnotify watcher: ", err)
+ }
+ return nil
}
func (c *STDServerConfig) startWatcher() error {
@@ -204,23 +321,34 @@ func (c *STDServerConfig) certificateUpdated(path string) error {
}
func (c *STDServerConfig) Close() error {
- if c.acmeService != nil {
- return c.acmeService.Close()
- }
- if c.watcher != nil {
- return c.watcher.Close()
- }
- return nil
+ return common.Close(c.certificateProvider, c.acmeService, common.PtrOrNil(c.watcher))
}
func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.InboundTLSOptions) (ServerConfig, error) {
if !options.Enabled {
return nil, nil
}
+ //nolint:staticcheck
+ if options.CertificateProvider != nil && options.ACME != nil {
+ return nil, E.New("certificate_provider and acme are mutually exclusive")
+ }
var tlsConfig *tls.Config
+ var certificateProvider managedCertificateProvider
var acmeService adapter.SimpleLifecycle
var err error
- if options.ACME != nil && len(options.ACME.Domain) > 0 {
+ if options.CertificateProvider != nil {
+ certificateProvider, err = newCertificateProvider(ctx, logger, options.CertificateProvider)
+ if err != nil {
+ return nil, err
+ }
+ tlsConfig = &tls.Config{
+ GetCertificate: certificateProvider.GetCertificate,
+ }
+ if options.Insecure {
+ return nil, errInsecureUnused
+ }
+ } else if options.ACME != nil && len(options.ACME.Domain) > 0 { //nolint:staticcheck
+ deprecated.Report(ctx, deprecated.OptionInlineACME)
//nolint:staticcheck
tlsConfig, acmeService, err = startACME(ctx, logger, common.PtrValueOrDefault(options.ACME))
if err != nil {
@@ -273,7 +401,7 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.
certificate []byte
key []byte
)
- if acmeService == nil {
+ if certificateProvider == nil && acmeService == nil {
if len(options.Certificate) > 0 {
certificate = []byte(strings.Join(options.Certificate, "\n"))
} else if options.CertificatePath != "" {
@@ -346,7 +474,7 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.
tlsConfig.ClientAuth = tls.RequestClientCert
}
tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
- return verifyPublicKeySHA256(options.ClientCertificatePublicKeySHA256, rawCerts, tlsConfig.Time)
+ return VerifyPublicKeySHA256(options.ClientCertificatePublicKeySHA256, rawCerts)
}
} else {
return nil, E.New("missing client_certificate, client_certificate_path or client_certificate_public_key_sha256 for client authentication")
@@ -359,9 +487,17 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.
return nil, err
}
}
+ var handshakeTimeout time.Duration
+ if options.HandshakeTimeout > 0 {
+ handshakeTimeout = options.HandshakeTimeout.Build()
+ } else {
+ handshakeTimeout = C.TCPTimeout
+ }
serverConfig := &STDServerConfig{
config: tlsConfig,
+ handshakeTimeout: handshakeTimeout,
logger: logger,
+ certificateProvider: certificateProvider,
acmeService: acmeService,
certificate: certificate,
key: key,
@@ -371,8 +507,8 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.
echKeyPath: echKeyPath,
}
serverConfig.config.GetConfigForClient = func(info *tls.ClientHelloInfo) (*tls.Config, error) {
- serverConfig.access.Lock()
- defer serverConfig.access.Unlock()
+ serverConfig.access.RLock()
+ defer serverConfig.access.RUnlock()
return serverConfig.config, nil
}
var config ServerConfig = serverConfig
@@ -389,3 +525,27 @@ func NewSTDServer(ctx context.Context, logger log.ContextLogger, options option.
}
return config, nil
}
+
+func newCertificateProvider(ctx context.Context, logger log.ContextLogger, options *option.CertificateProviderOptions) (managedCertificateProvider, error) {
+ if options.IsShared() {
+ manager := service.FromContext[adapter.CertificateProviderManager](ctx)
+ if manager == nil {
+ return nil, E.New("missing certificate provider manager in context")
+ }
+ return &sharedCertificateProvider{
+ tag: options.Tag,
+ manager: manager,
+ }, nil
+ }
+ registry := service.FromContext[adapter.CertificateProviderRegistry](ctx)
+ if registry == nil {
+ return nil, E.New("missing certificate provider registry in context")
+ }
+ provider, err := registry.Create(ctx, logger, "", options.Type, options.Options)
+ if err != nil {
+ return nil, E.Cause(err, "create inline certificate provider")
+ }
+ return &inlineCertificateProvider{
+ provider: provider,
+ }, nil
+}
diff --git a/common/tls/system_client.go b/common/tls/system_client.go
new file mode 100644
index 0000000000..ade2bd3636
--- /dev/null
+++ b/common/tls/system_client.go
@@ -0,0 +1,123 @@
+package tls
+
+import (
+ "context"
+ "crypto/x509"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/service"
+)
+
+type SystemTLSValidated struct {
+ MinVersion uint16
+ MaxVersion uint16
+ UserPEM []byte
+ Exclusive bool
+ Store adapter.CertificateStore
+}
+
+func ValidateSystemTLSOptions(ctx context.Context, options option.OutboundTLSOptions, engineName string) (SystemTLSValidated, error) {
+ if options.Reality != nil && options.Reality.Enabled {
+ return SystemTLSValidated{}, E.New("reality is unsupported in ", engineName)
+ }
+ if options.UTLS != nil && options.UTLS.Enabled {
+ return SystemTLSValidated{}, E.New("utls is unsupported in ", engineName)
+ }
+ if options.ECH != nil && options.ECH.Enabled {
+ return SystemTLSValidated{}, E.New("ech is unsupported in ", engineName)
+ }
+ if options.DisableSNI {
+ return SystemTLSValidated{}, E.New("disable_sni is unsupported in ", engineName)
+ }
+ if len(options.CipherSuites) > 0 {
+ return SystemTLSValidated{}, E.New("cipher_suites is unsupported in ", engineName)
+ }
+ if len(options.CurvePreferences) > 0 {
+ return SystemTLSValidated{}, E.New("curve_preferences is unsupported in ", engineName)
+ }
+ if len(options.ClientCertificate) > 0 || options.ClientCertificatePath != "" || len(options.ClientKey) > 0 || options.ClientKeyPath != "" {
+ return SystemTLSValidated{}, E.New("client certificate is unsupported in ", engineName)
+ }
+ if options.Fragment || options.RecordFragment {
+ return SystemTLSValidated{}, E.New("tls fragment is unsupported in ", engineName)
+ }
+ if options.KernelTx || options.KernelRx {
+ return SystemTLSValidated{}, E.New("ktls is unsupported in ", engineName)
+ }
+ if options.Spoof != "" || options.SpoofMethod != "" {
+ return SystemTLSValidated{}, E.New("spoof is unsupported in ", engineName)
+ }
+ if len(options.CertificatePublicKeySHA256) > 0 && (len(options.Certificate) > 0 || options.CertificatePath != "") {
+ return SystemTLSValidated{}, E.New("certificate_public_key_sha256 is conflict with certificate or certificate_path")
+ }
+ var minVersion uint16
+ if options.MinVersion != "" {
+ parsed, err := ParseTLSVersion(options.MinVersion)
+ if err != nil {
+ return SystemTLSValidated{}, E.Cause(err, "parse min_version")
+ }
+ minVersion = parsed
+ }
+ var maxVersion uint16
+ if options.MaxVersion != "" {
+ parsed, err := ParseTLSVersion(options.MaxVersion)
+ if err != nil {
+ return SystemTLSValidated{}, E.Cause(err, "parse max_version")
+ }
+ maxVersion = parsed
+ }
+ userPEM, exclusive, store, err := resolveSystemAnchors(ctx, options)
+ if err != nil {
+ return SystemTLSValidated{}, err
+ }
+ return SystemTLSValidated{
+ MinVersion: minVersion,
+ MaxVersion: maxVersion,
+ UserPEM: userPEM,
+ Exclusive: exclusive,
+ Store: store,
+ }, nil
+}
+
+func resolveSystemAnchors(ctx context.Context, options option.OutboundTLSOptions) ([]byte, bool, adapter.CertificateStore, error) {
+ if len(options.Certificate) > 0 {
+ return []byte(strings.Join(options.Certificate, "\n")), true, nil, nil
+ }
+ if options.CertificatePath != "" {
+ content, err := os.ReadFile(options.CertificatePath)
+ if err != nil {
+ return nil, false, nil, E.Cause(err, "read certificate")
+ }
+ return content, true, nil, nil
+ }
+ store := service.FromContext[adapter.CertificateStore](ctx)
+ if store == nil {
+ return nil, false, nil, nil
+ }
+ return nil, store.ExclusiveAnchors(), store, nil
+}
+
+func verifySystemTLSPeer(roots *x509.CertPool, serverName string, timeFunc func() time.Time, peerCertificates []*x509.Certificate) error {
+ if len(peerCertificates) == 0 {
+ return E.New("no peer certificates")
+ }
+ intermediates := x509.NewCertPool()
+ for _, cert := range peerCertificates[1:] {
+ intermediates.AddCert(cert)
+ }
+ verifyOptions := x509.VerifyOptions{
+ Roots: roots,
+ Intermediates: intermediates,
+ DNSName: serverName,
+ }
+ if timeFunc != nil {
+ verifyOptions.CurrentTime = timeFunc()
+ }
+ _, err := peerCertificates[0].Verify(verifyOptions)
+ return err
+}
diff --git a/common/tls/system_client_engine.go b/common/tls/system_client_engine.go
new file mode 100644
index 0000000000..5fc89959fc
--- /dev/null
+++ b/common/tls/system_client_engine.go
@@ -0,0 +1,108 @@
+//go:build (darwin && cgo) || windows
+
+package tls
+
+import (
+ "context"
+ "net"
+ "os"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/ntp"
+)
+
+type systemTLSConfig struct {
+ serverName string
+ nextProtos []string
+ handshakeTimeout time.Duration
+ minVersion uint16
+ maxVersion uint16
+ insecure bool
+ anchorOnly bool
+ certificatePublicKeySHA256 [][]byte
+ timeFunc func() time.Time
+ store adapter.CertificateStore
+}
+
+func (c *systemTLSConfig) ServerName() string {
+ return c.serverName
+}
+
+func (c *systemTLSConfig) SetServerName(serverName string) {
+ c.serverName = serverName
+}
+
+func (c *systemTLSConfig) NextProtos() []string {
+ return c.nextProtos
+}
+
+func (c *systemTLSConfig) SetNextProtos(nextProto []string) {
+ c.nextProtos = append([]string(nil), nextProto...)
+}
+
+func (c *systemTLSConfig) HandshakeTimeout() time.Duration {
+ return c.handshakeTimeout
+}
+
+func (c *systemTLSConfig) SetHandshakeTimeout(timeout time.Duration) {
+ c.handshakeTimeout = timeout
+}
+
+func (c *systemTLSConfig) STDConfig() (*STDConfig, error) {
+ return nil, E.New("STDConfig is unsupported for the system TLS engine")
+}
+
+func (c *systemTLSConfig) Client(conn net.Conn) (Conn, error) {
+ return nil, os.ErrInvalid
+}
+
+func (c *systemTLSConfig) clone() systemTLSConfig {
+ return systemTLSConfig{
+ serverName: c.serverName,
+ nextProtos: append([]string(nil), c.nextProtos...),
+ handshakeTimeout: c.handshakeTimeout,
+ minVersion: c.minVersion,
+ maxVersion: c.maxVersion,
+ insecure: c.insecure,
+ anchorOnly: c.anchorOnly,
+ certificatePublicKeySHA256: append([][]byte(nil), c.certificatePublicKeySHA256...),
+ timeFunc: c.timeFunc,
+ store: c.store,
+ }
+}
+
+func newSystemTLSConfig(ctx context.Context, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool, engineName string) (systemTLSConfig, SystemTLSValidated, error) {
+ validated, err := ValidateSystemTLSOptions(ctx, options, engineName)
+ if err != nil {
+ return systemTLSConfig{}, SystemTLSValidated{}, err
+ }
+ var serverName string
+ if options.ServerName != "" {
+ serverName = options.ServerName
+ } else if serverAddress != "" {
+ serverName = serverAddress
+ }
+ if serverName == "" && !options.Insecure && !allowEmptyServerName {
+ return systemTLSConfig{}, SystemTLSValidated{}, errMissingServerName
+ }
+ handshakeTimeout := C.TCPTimeout
+ if options.HandshakeTimeout > 0 {
+ handshakeTimeout = options.HandshakeTimeout.Build()
+ }
+ return systemTLSConfig{
+ serverName: serverName,
+ nextProtos: append([]string(nil), options.ALPN...),
+ handshakeTimeout: handshakeTimeout,
+ minVersion: validated.MinVersion,
+ maxVersion: validated.MaxVersion,
+ insecure: options.Insecure || len(options.CertificatePublicKeySHA256) > 0,
+ anchorOnly: validated.Exclusive,
+ certificatePublicKeySHA256: append([][]byte(nil), options.CertificatePublicKeySHA256...),
+ timeFunc: ntp.TimeFuncFromContext(ctx),
+ store: validated.Store,
+ }, validated, nil
+}
diff --git a/common/tls/utls_client.go b/common/tls/utls_client.go
index 941192ba16..1cc41554fa 100644
--- a/common/tls/utls_client.go
+++ b/common/tls/utls_client.go
@@ -14,6 +14,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tlsfragment"
+ "github.com/sagernet/sing-box/common/tlsspoof"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
@@ -28,17 +29,33 @@ import (
type UTLSClientConfig struct {
ctx context.Context
config *utls.Config
+ serverName string
+ disableSNI bool
+ verifyServerName bool
+ handshakeTimeout time.Duration
id utls.ClientHelloID
fragment bool
fragmentFallbackDelay time.Duration
recordFragment bool
+ spoof string
+ spoofMethod tlsspoof.Method
}
func (c *UTLSClientConfig) ServerName() string {
- return c.config.ServerName
+ return c.serverName
}
func (c *UTLSClientConfig) SetServerName(serverName string) {
+ c.serverName = serverName
+ if c.disableSNI {
+ c.config.ServerName = ""
+ if c.verifyServerName {
+ c.config.InsecureServerNameToVerify = serverName
+ } else {
+ c.config.InsecureServerNameToVerify = ""
+ }
+ return
+ }
c.config.ServerName = serverName
}
@@ -53,14 +70,26 @@ func (c *UTLSClientConfig) SetNextProtos(nextProto []string) {
c.config.NextProtos = nextProto
}
+func (c *UTLSClientConfig) HandshakeTimeout() time.Duration {
+ return c.handshakeTimeout
+}
+
+func (c *UTLSClientConfig) SetHandshakeTimeout(timeout time.Duration) {
+ c.handshakeTimeout = timeout
+}
+
func (c *UTLSClientConfig) STDConfig() (*STDConfig, error) {
return nil, E.New("unsupported usage for uTLS")
}
func (c *UTLSClientConfig) Client(conn net.Conn) (Conn, error) {
- if c.recordFragment {
+ if c.fragment || c.recordFragment {
conn = tf.NewConn(conn, c.ctx, c.fragment, c.recordFragment, c.fragmentFallbackDelay)
}
+ conn, err := applyTLSSpoof(conn, c.spoof, c.spoofMethod)
+ if err != nil {
+ return nil, err
+ }
return &utlsALPNWrapper{utlsConnWrapper{utls.UClient(conn, c.config.Clone(), c.id)}, c.config.NextProtos}, nil
}
@@ -69,9 +98,22 @@ func (c *UTLSClientConfig) SetSessionIDGenerator(generator func(clientHello []by
}
func (c *UTLSClientConfig) Clone() Config {
- return &UTLSClientConfig{
- c.ctx, c.config.Clone(), c.id, c.fragment, c.fragmentFallbackDelay, c.recordFragment,
+ cloned := &UTLSClientConfig{
+ ctx: c.ctx,
+ config: c.config.Clone(),
+ serverName: c.serverName,
+ disableSNI: c.disableSNI,
+ verifyServerName: c.verifyServerName,
+ handshakeTimeout: c.handshakeTimeout,
+ id: c.id,
+ fragment: c.fragment,
+ fragmentFallbackDelay: c.fragmentFallbackDelay,
+ recordFragment: c.recordFragment,
+ spoof: c.spoof,
+ spoofMethod: c.spoofMethod,
}
+ cloned.SetServerName(cloned.serverName)
+ return cloned
}
func (c *UTLSClientConfig) ECHConfigList() []byte {
@@ -143,29 +185,29 @@ func (c *utlsALPNWrapper) HandshakeContext(ctx context.Context) error {
}
func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
+ return newUTLSClient(ctx, logger, serverAddress, options, false)
+}
+
+func newUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
var serverName string
if options.ServerName != "" {
serverName = options.ServerName
} else if serverAddress != "" {
serverName = serverAddress
}
- if serverName == "" && !options.Insecure {
- return nil, E.New("missing server_name or insecure=true")
+ if serverName == "" && !options.Insecure && !allowEmptyServerName {
+ return nil, errMissingServerName
}
var tlsConfig utls.Config
tlsConfig.Time = ntp.TimeFuncFromContext(ctx)
tlsConfig.RootCAs = adapter.RootPoolFromContext(ctx)
- if !options.DisableSNI {
- tlsConfig.ServerName = serverName
- }
if options.Insecure {
tlsConfig.InsecureSkipVerify = options.Insecure
} else if options.DisableSNI {
if options.Reality != nil && options.Reality.Enabled {
return nil, E.New("disable_sni is unsupported in reality")
}
- tlsConfig.InsecureServerNameToVerify = serverName
}
if len(options.CertificatePublicKeySHA256) > 0 {
if len(options.Certificate) > 0 || options.CertificatePath != "" {
@@ -173,7 +215,7 @@ func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddre
}
tlsConfig.InsecureSkipVerify = true
tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
- return verifyPublicKeySHA256(options.CertificatePublicKeySHA256, rawCerts, tlsConfig.Time)
+ return VerifyPublicKeySHA256(options.CertificatePublicKeySHA256, rawCerts)
}
}
if len(options.ALPN) > 0 {
@@ -251,11 +293,35 @@ func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddre
} else if len(clientCertificate) > 0 || len(clientKey) > 0 {
return nil, E.New("client certificate and client key must be provided together")
}
+ var handshakeTimeout time.Duration
+ if options.HandshakeTimeout > 0 {
+ handshakeTimeout = options.HandshakeTimeout.Build()
+ } else {
+ handshakeTimeout = C.TCPTimeout
+ }
+ spoof, spoofMethod, err := parseTLSSpoofOptions(serverName, options)
+ if err != nil {
+ return nil, err
+ }
id, err := uTLSClientHelloID(options.UTLS.Fingerprint)
if err != nil {
return nil, err
}
- var config Config = &UTLSClientConfig{ctx, &tlsConfig, id, options.Fragment, time.Duration(options.FragmentFallbackDelay), options.RecordFragment}
+ var config Config = &UTLSClientConfig{
+ ctx: ctx,
+ config: &tlsConfig,
+ serverName: serverName,
+ disableSNI: options.DisableSNI,
+ verifyServerName: options.DisableSNI && !options.Insecure,
+ handshakeTimeout: handshakeTimeout,
+ id: id,
+ fragment: options.Fragment,
+ fragmentFallbackDelay: time.Duration(options.FragmentFallbackDelay),
+ recordFragment: options.RecordFragment,
+ spoof: spoof,
+ spoofMethod: spoofMethod,
+ }
+ config.SetServerName(serverName)
if options.ECH != nil && options.ECH.Enabled {
if options.Reality != nil && options.Reality.Enabled {
return nil, E.New("Reality is conflict with ECH")
diff --git a/common/tls/utls_client_test.go b/common/tls/utls_client_test.go
new file mode 100644
index 0000000000..48c1e327ec
--- /dev/null
+++ b/common/tls/utls_client_test.go
@@ -0,0 +1,73 @@
+//go:build with_utls
+
+package tls
+
+import (
+ "context"
+ "net"
+ "testing"
+
+ tf "github.com/sagernet/sing-box/common/tlsfragment"
+
+ utls "github.com/metacubex/utls"
+ "github.com/stretchr/testify/require"
+)
+
+// Guards the wrap gate in UTLSClientConfig.Client(): tf.Conn must wrap the
+// underlying connection whenever either `fragment` or `record_fragment` is
+// set. Mirrors the STDClientConfig gate tests to keep both code paths in
+// lockstep.
+
+func newUTLSClientConfigForGateTest(fragment, recordFragment bool) *UTLSClientConfig {
+ return &UTLSClientConfig{
+ ctx: context.Background(),
+ config: &utls.Config{ServerName: "example.com", InsecureSkipVerify: true},
+ id: utls.HelloChrome_Auto,
+ fragment: fragment,
+ recordFragment: recordFragment,
+ }
+}
+
+func TestUTLSClient_Client_NoFragment_DoesNotWrap(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newUTLSClientConfigForGateTest(false, false).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.False(t, isTF, "no fragment flags: must not wrap with tf.Conn")
+}
+
+func TestUTLSClient_Client_FragmentOnly_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newUTLSClientConfigForGateTest(true, false).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "fragment=true: must wrap with tf.Conn")
+}
+
+func TestUTLSClient_Client_RecordFragmentOnly_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newUTLSClientConfigForGateTest(false, true).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "record_fragment=true: must wrap with tf.Conn")
+}
+
+func TestUTLSClient_Client_BothFragment_Wraps(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ wrapped, err := newUTLSClientConfigForGateTest(true, true).Client(client)
+ require.NoError(t, err)
+ _, isTF := wrapped.NetConn().(*tf.Conn)
+ require.True(t, isTF, "both fragment flags: must wrap with tf.Conn")
+}
diff --git a/common/tls/utls_stub.go b/common/tls/utls_stub.go
index 3eddd28e85..67fac20983 100644
--- a/common/tls/utls_stub.go
+++ b/common/tls/utls_stub.go
@@ -12,10 +12,18 @@ import (
)
func NewUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
+ return newUTLSClient(ctx, logger, serverAddress, options, false)
+}
+
+func newUTLSClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
return nil, E.New(`uTLS is not included in this build, rebuild with -tags with_utls`)
}
func NewRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
+ return newRealityClient(ctx, logger, serverAddress, options, false)
+}
+
+func newRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
return nil, E.New(`uTLS, which is required by reality is not included in this build, rebuild with -tags with_utls`)
}
diff --git a/common/tls/windows_client.go b/common/tls/windows_client.go
new file mode 100644
index 0000000000..9a865c0aa1
--- /dev/null
+++ b/common/tls/windows_client.go
@@ -0,0 +1,848 @@
+//go:build windows
+
+package tls
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "errors"
+ "io"
+ "net"
+ "os"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/common/schannel"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const (
+ windowsTLSEngineName = "Windows TLS engine"
+ handshakeReadChunkSize = 8192
+ readScratchSize = 16 * 1024
+ readWaitCiphertextChunkSize = 4096
+)
+
+type windowsClientConfig struct {
+ systemTLSConfig
+ userRoots *x509.CertPool
+}
+
+func (c *windowsClientConfig) Clone() Config {
+ return &windowsClientConfig{
+ systemTLSConfig: c.systemTLSConfig.clone(),
+ userRoots: c.userRoots,
+ }
+}
+
+func newWindowsClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
+ err := schannel.CheckPlatform()
+ if err != nil {
+ return nil, err
+ }
+ base, validated, err := newSystemTLSConfig(ctx, serverAddress, options, allowEmptyServerName, windowsTLSEngineName)
+ if err != nil {
+ return nil, err
+ }
+ var userRoots *x509.CertPool
+ if len(validated.UserPEM) > 0 {
+ userRoots = x509.NewCertPool()
+ if !userRoots.AppendCertsFromPEM(validated.UserPEM) {
+ return nil, E.New("parse certificate PEM")
+ }
+ }
+ return &windowsClientConfig{
+ systemTLSConfig: base,
+ userRoots: userRoots,
+ }, nil
+}
+
+func (c *windowsClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) (Conn, error) {
+ deadline, hasDeadline := ctx.Deadline()
+ if hasDeadline {
+ deadlineErr := conn.SetDeadline(deadline)
+ if deadlineErr != nil {
+ return nil, E.Cause(deadlineErr, "set handshake deadline")
+ }
+ defer conn.SetDeadline(time.Time{})
+ }
+
+ client, err := schannel.NewClientContext(c.minVersion, c.maxVersion, c.serverName, c.nextProtos)
+ if err != nil {
+ return nil, err
+ }
+
+ handshakeOK := false
+ defer func() {
+ if !handshakeOK {
+ client.Close()
+ }
+ }()
+
+ stopCancel := installHandshakeCancel(ctx, conn)
+ defer stopCancel()
+
+ scratch := make([]byte, handshakeReadChunkSize)
+ leftover, err := driveHandshake(ctx, conn, client, scratch)
+ if err != nil {
+ return nil, err
+ }
+ state, rawCerts, err := buildConnectionState(c.serverName, client)
+ if err != nil {
+ return nil, err
+ }
+ err = c.verifyPeerCertificates(state.PeerCertificates)
+ if err != nil {
+ return nil, err
+ }
+ if len(c.certificatePublicKeySHA256) > 0 {
+ err = VerifyPublicKeySHA256(c.certificatePublicKeySHA256, rawCerts)
+ if err != nil {
+ return nil, err
+ }
+ }
+ header, trailer, maxMessage, err := client.StreamSizes()
+ if err != nil {
+ return nil, err
+ }
+
+ handshakeOK = true
+ tlsConn := &windowsTLSConn{
+ rawConn: conn,
+ client: client,
+ state: state,
+ header: header,
+ trailer: trailer,
+ maxMessage: maxMessage,
+ cipher: leftover,
+ }
+ return tlsConn, nil
+}
+
+func driveHandshake(ctx context.Context, conn net.Conn, client *schannel.ClientContext, scratch []byte) ([]byte, error) {
+ readMore := func() ([]byte, error) {
+ more, err := readTLSRaw(conn, scratch, true)
+ if err != nil {
+ return nil, handshakeIOError(ctx, err, "read handshake")
+ }
+ return more, nil
+ }
+ writeOut := func(data []byte) error {
+ _, err := conn.Write(data)
+ if err != nil {
+ return handshakeIOError(ctx, err, "write handshake")
+ }
+ return nil
+ }
+ leftover, err := driveSteps(nil, client.Step, readMore, writeOut)
+ if err != nil {
+ return nil, E.Cause(err, "tls handshake")
+ }
+ return leftover, nil
+}
+
+func driveSteps(
+ initial []byte,
+ step func([]byte) (schannel.StepResult, error),
+ readMore func() ([]byte, error),
+ writeOut func([]byte) error,
+) ([]byte, error) {
+ buffer := initial
+ for {
+ result, stepErr := step(buffer)
+ if stepErr != nil {
+ return nil, stepErr
+ }
+ if len(result.Output) > 0 {
+ writeErr := writeOut(result.Output)
+ if writeErr != nil {
+ return nil, writeErr
+ }
+ }
+ if result.Incomplete {
+ // readMore reuses scratch storage, so keep the buffered handshake
+ // bytes in stable memory before the next read overwrites them.
+ buffer = append([]byte(nil), buffer...)
+ more, readErr := readMore()
+ if readErr != nil {
+ return nil, readErr
+ }
+ buffer = append(buffer, more...)
+ continue
+ }
+ if result.Consumed > len(buffer) {
+ return nil, E.New("schannel: Consumed > input length")
+ }
+ buffer = buffer[result.Consumed:]
+ if result.Done {
+ return buffer, nil
+ }
+ if len(buffer) == 0 {
+ more, readErr := readMore()
+ if readErr != nil {
+ return nil, readErr
+ }
+ buffer = append(buffer, more...)
+ }
+ }
+}
+
+// installHandshakeCancel unblocks an in-flight read/write by forcing an
+// immediate deadline on conn when ctx is cancelled. The returned cleanup
+// waits for a racing cancel to finish and clears the forced deadline.
+func installHandshakeCancel(ctx context.Context, conn net.Conn) func() {
+ var fired atomic.Bool
+ done := make(chan struct{})
+ stop := context.AfterFunc(ctx, func() {
+ defer close(done)
+ fired.Store(true)
+ _ = conn.SetDeadline(time.Now())
+ })
+ return func() {
+ if stop() {
+ return
+ }
+ <-done
+ if fired.Load() {
+ _ = conn.SetDeadline(time.Time{})
+ }
+ }
+}
+
+func handshakeIOError(ctx context.Context, err error, message string) error {
+ ctxErr := ctx.Err()
+ if ctxErr != nil && isTimeoutError(err) {
+ return ctxErr
+ }
+ return E.Cause(err, message)
+}
+
+func readTLSRaw(conn net.Conn, scratch []byte, requireMore bool) ([]byte, error) {
+ n, err := conn.Read(scratch)
+ if n > 0 {
+ return scratch[:n], nil
+ }
+ if err != nil {
+ if requireMore && errors.Is(err, io.EOF) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ return nil, err
+ }
+ return nil, io.ErrUnexpectedEOF
+}
+
+func isTimeoutError(err error) bool {
+ if errors.Is(err, os.ErrDeadlineExceeded) {
+ return true
+ }
+ var netErr net.Error
+ return errors.As(err, &netErr) && netErr.Timeout()
+}
+
+func buildConnectionState(serverName string, client *schannel.ClientContext) (tls.ConnectionState, [][]byte, error) {
+ version, cipherSuite, err := client.ConnectionInfo()
+ if err != nil {
+ return tls.ConnectionState{}, nil, err
+ }
+ alpn, err := client.ApplicationProtocol()
+ if err != nil {
+ return tls.ConnectionState{}, nil, err
+ }
+ rawCerts, err := client.RemoteCertificateChain()
+ if err != nil {
+ return tls.ConnectionState{}, nil, err
+ }
+ peerCertificates := make([]*x509.Certificate, 0, len(rawCerts))
+ for index, der := range rawCerts {
+ cert, parseErr := x509.ParseCertificate(der)
+ if parseErr != nil {
+ return tls.ConnectionState{}, nil, E.Cause(parseErr, "parse peer certificate ", index)
+ }
+ peerCertificates = append(peerCertificates, cert)
+ }
+ return tls.ConnectionState{
+ Version: version,
+ HandshakeComplete: true,
+ CipherSuite: cipherSuite,
+ NegotiatedProtocol: alpn,
+ ServerName: serverName,
+ PeerCertificates: peerCertificates,
+ }, rawCerts, nil
+}
+
+func (c *windowsClientConfig) verifyPeerCertificates(peerCertificates []*x509.Certificate) error {
+ if c.insecure {
+ return nil
+ }
+ var roots *x509.CertPool
+ switch {
+ case c.userRoots != nil:
+ roots = c.userRoots
+ case c.store != nil:
+ roots = c.store.Pool()
+ }
+ return verifySystemTLSPeer(roots, c.serverName, c.timeFunc, peerCertificates)
+}
+
+type windowsTLSConn struct {
+ rawConn net.Conn
+ client *schannel.ClientContext
+ state tls.ConnectionState
+ header uint32
+ trailer uint32
+ maxMessage uint32
+
+ readAccess sync.Mutex
+ writeAccess sync.Mutex
+ contextAccess sync.RWMutex
+
+ writeState sync.Mutex
+ writeStateOnce sync.Once
+ writeReady *sync.Cond
+ postHandshake bool
+ writeActive bool
+
+ cipher []byte
+ plain []byte
+ readScratch []byte
+ writeScratch []byte
+ readEOF bool
+
+ deadlineAccess sync.Mutex
+ readDeadline time.Time
+ writeDeadline time.Time
+ closed atomic.Bool
+}
+
+var (
+ _ N.ExtendedConn = (*windowsTLSConn)(nil)
+ _ N.ReadWaitCreator = (*windowsTLSConn)(nil)
+)
+
+type (
+ windowsTLSAppendCipherFunc func(requireMore bool) error
+ windowsTLSReadRawFunc func(requireMore bool) ([]byte, error)
+)
+
+func (c *windowsTLSConn) Read(p []byte) (int, error) {
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if len(p) == 0 {
+ return 0, nil
+ }
+ if c.isClosed() {
+ return 0, net.ErrClosed
+ }
+ return c.readIntoLocked(p, c.appendRaw, c.readRaw)
+}
+
+func (c *windowsTLSConn) ReadBuffer(buffer *buf.Buffer) error {
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if buffer.IsFull() {
+ return io.ErrShortBuffer
+ }
+ if c.isClosed() {
+ return net.ErrClosed
+ }
+ startLen := buffer.Len()
+ n, err := c.readIntoLocked(buffer.FreeBytes(), c.appendRaw, c.readRaw)
+ buffer.Truncate(startLen + n)
+ return err
+}
+
+func (c *windowsTLSConn) readIntoLocked(p []byte, appendCipher windowsTLSAppendCipherFunc, readRaw windowsTLSReadRawFunc) (int, error) {
+ plaintext, err := c.readPlaintextLocked(appendCipher, readRaw)
+ if err != nil {
+ return 0, err
+ }
+ n := copy(p, plaintext)
+ if n < len(plaintext) {
+ c.plain = append([]byte(nil), plaintext[n:]...)
+ }
+ return n, nil
+}
+
+func (c *windowsTLSConn) readPlaintextLocked(appendCipher windowsTLSAppendCipherFunc, readRaw windowsTLSReadRawFunc) ([]byte, error) {
+ if len(c.plain) > 0 {
+ plaintext := c.plain
+ c.plain = nil
+ return plaintext, nil
+ }
+ if c.readEOF {
+ return nil, io.EOF
+ }
+
+ cleanup, err := c.applyReadDeadline()
+ if err != nil {
+ return nil, err
+ }
+ defer cleanup()
+
+ for {
+ if len(c.cipher) > 0 {
+ result, decryptErr := c.decrypt(c.cipher)
+ if decryptErr != nil {
+ return nil, decryptErr
+ }
+ if result.Expired {
+ c.readEOF = true
+ return nil, io.EOF
+ }
+ if !result.Incomplete {
+ plaintext := result.Plaintext
+ if result.Renegotiate && len(plaintext) > 0 {
+ plaintext = append([]byte(nil), plaintext...)
+ }
+ nextCipher := c.cipher[result.ConsumedTotal:]
+ if len(result.RenegotiateToken) > 0 {
+ nextCipher = result.RenegotiateToken
+ }
+ c.cipher = nextCipher
+ if len(c.cipher) == 0 {
+ c.cipher = nil
+ }
+ if result.Renegotiate {
+ postErr := c.drivePostHandshake(readRaw)
+ if postErr != nil {
+ return nil, postErr
+ }
+ }
+ if len(plaintext) > 0 {
+ return plaintext, nil
+ }
+ continue
+ }
+ }
+ err = appendCipher(len(c.cipher) > 0)
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+func (c *windowsTLSConn) drivePostHandshake(readRaw windowsTLSReadRawFunc) error {
+ initial := c.cipher
+ c.cipher = nil
+ err := c.beginPostHandshakeWrite()
+ if err != nil {
+ return err
+ }
+ defer c.finishPostHandshakeWrite()
+ c.contextAccess.Lock()
+ if c.client == nil {
+ c.contextAccess.Unlock()
+ return net.ErrClosed
+ }
+ writeFailed := false
+ readMore := func() ([]byte, error) {
+ more, err := readRaw(true)
+ if err != nil {
+ return nil, E.Cause(err, "tls post-handshake read")
+ }
+ return more, nil
+ }
+ writeOut := func(data []byte) error {
+ err := c.writePostHandshakeReplyLocked(data)
+ if err != nil {
+ writeFailed = true
+ return E.Cause(err, "tls post-handshake write")
+ }
+ return nil
+ }
+ leftover, err := driveSteps(initial, c.client.PostHandshake, readMore, writeOut)
+ c.contextAccess.Unlock()
+ if err != nil {
+ if writeFailed {
+ _ = c.Close()
+ }
+ return E.Cause(err, "tls post-handshake")
+ }
+ if len(leftover) > 0 {
+ c.cipher = leftover
+ }
+ return nil
+}
+
+func (c *windowsTLSConn) writePostHandshakeReplyLocked(data []byte) error {
+ c.deadlineAccess.Lock()
+ deadline := c.readDeadline
+ c.deadlineAccess.Unlock()
+ cleanup, err := c.applyDeadline(deadline, c.rawConn.SetWriteDeadline)
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+ _, err = c.rawConn.Write(data)
+ return err
+}
+
+func (c *windowsTLSConn) decrypt(input []byte) (schannel.DecryptResult, error) {
+ c.contextAccess.RLock()
+ defer c.contextAccess.RUnlock()
+ if c.client == nil {
+ return schannel.DecryptResult{}, net.ErrClosed
+ }
+ return c.client.Decrypt(input)
+}
+
+func (c *windowsTLSConn) encrypt(plaintext []byte) ([]byte, error) {
+ c.contextAccess.RLock()
+ defer c.contextAccess.RUnlock()
+ if c.client == nil {
+ return nil, net.ErrClosed
+ }
+ if c.writeScratch == nil {
+ c.writeScratch = make([]byte, int(c.header)+int(c.maxMessage)+int(c.trailer))
+ }
+ return c.client.Encrypt(c.header, c.trailer, plaintext, c.writeScratch)
+}
+
+func (c *windowsTLSConn) readRaw(requireMore bool) ([]byte, error) {
+ if c.readScratch == nil {
+ c.readScratch = make([]byte, readScratchSize)
+ }
+ return readTLSRaw(c.rawConn, c.readScratch, requireMore)
+}
+
+func (c *windowsTLSConn) appendRaw(requireMore bool) error {
+ more, err := c.readRaw(requireMore)
+ if err != nil {
+ return err
+ }
+ c.cipher = append(c.cipher, more...)
+ return nil
+}
+
+func (c *windowsTLSConn) Write(p []byte) (int, error) {
+ err := c.beginWrite()
+ if err != nil {
+ return 0, err
+ }
+ defer c.finishWrite()
+ if len(p) == 0 {
+ return 0, nil
+ }
+ if c.isClosed() {
+ return 0, net.ErrClosed
+ }
+
+ cleanup, err := c.applyWriteDeadline()
+ if err != nil {
+ return 0, err
+ }
+ defer cleanup()
+
+ total := 0
+ chunkSize := int(c.maxMessage)
+ for len(p) > 0 {
+ chunk := p
+ if len(chunk) > chunkSize {
+ chunk = chunk[:chunkSize]
+ }
+ encrypted, encryptErr := c.encrypt(chunk)
+ if encryptErr != nil {
+ if errors.Is(encryptErr, net.ErrClosed) {
+ return total, net.ErrClosed
+ }
+ return total, E.Cause(encryptErr, "tls encrypt")
+ }
+ _, writeErr := c.rawConn.Write(encrypted)
+ if writeErr != nil {
+ _ = c.Close()
+ return total, E.Cause(writeErr, "tls write")
+ }
+ total += len(chunk)
+ p = p[len(chunk):]
+ }
+ return total, nil
+}
+
+func (c *windowsTLSConn) WriteBuffer(buffer *buf.Buffer) error {
+ defer buffer.Release()
+ _, err := c.Write(buffer.Bytes())
+ return err
+}
+
+func (c *windowsTLSConn) CreateReadWaiter() (N.ReadWaiter, bool) {
+ rawWaiter, ok := bufio.CreateReadWaiter(c.rawConn)
+ if !ok {
+ return nil, false
+ }
+ return &windowsTLSReadWaiter{
+ conn: c,
+ rawWaiter: rawWaiter,
+ }, true
+}
+
+func (c *windowsTLSConn) Close() error {
+ if !c.closed.CompareAndSwap(false, true) {
+ return nil
+ }
+ ready := c.writeCondition()
+ c.writeState.Lock()
+ ready.Broadcast()
+ c.writeState.Unlock()
+ closeErr := c.rawConn.Close()
+ c.contextAccess.Lock()
+ if c.client != nil {
+ c.client.Close()
+ c.client = nil
+ }
+ c.contextAccess.Unlock()
+ return closeErr
+}
+
+func (c *windowsTLSConn) LocalAddr() net.Addr {
+ return c.rawConn.LocalAddr()
+}
+
+func (c *windowsTLSConn) RemoteAddr() net.Addr {
+ return c.rawConn.RemoteAddr()
+}
+
+func (c *windowsTLSConn) SetDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ defer c.deadlineAccess.Unlock()
+ err := c.rawConn.SetDeadline(t)
+ if err != nil {
+ return err
+ }
+ c.readDeadline = t
+ c.writeDeadline = t
+ return nil
+}
+
+func (c *windowsTLSConn) SetReadDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ defer c.deadlineAccess.Unlock()
+ err := c.rawConn.SetReadDeadline(t)
+ if err != nil {
+ return err
+ }
+ c.readDeadline = t
+ return nil
+}
+
+func (c *windowsTLSConn) SetWriteDeadline(t time.Time) error {
+ c.deadlineAccess.Lock()
+ defer c.deadlineAccess.Unlock()
+ err := c.rawConn.SetWriteDeadline(t)
+ if err != nil {
+ return err
+ }
+ c.writeDeadline = t
+ return nil
+}
+
+func (c *windowsTLSConn) NetConn() net.Conn {
+ return c.rawConn
+}
+
+func (c *windowsTLSConn) HandshakeContext(ctx context.Context) error {
+ return nil
+}
+
+func (c *windowsTLSConn) ConnectionState() ConnectionState {
+ return c.state
+}
+
+func (c *windowsTLSConn) applyReadDeadline() (func(), error) {
+ c.deadlineAccess.Lock()
+ deadline := c.readDeadline
+ c.deadlineAccess.Unlock()
+ return c.applyDeadline(deadline, c.rawConn.SetReadDeadline)
+}
+
+func (c *windowsTLSConn) applyWriteDeadline() (func(), error) {
+ c.deadlineAccess.Lock()
+ deadline := c.writeDeadline
+ c.deadlineAccess.Unlock()
+ return c.applyDeadline(deadline, c.rawConn.SetWriteDeadline)
+}
+
+func (c *windowsTLSConn) applyDeadline(deadline time.Time, set func(time.Time) error) (func(), error) {
+ if deadline.IsZero() {
+ return func() {}, nil
+ }
+ if !deadline.After(time.Now()) {
+ return nil, os.ErrDeadlineExceeded
+ }
+ err := set(deadline)
+ if err != nil {
+ return nil, err
+ }
+ return func() { _ = set(time.Time{}) }, nil
+}
+
+func (c *windowsTLSConn) beginWrite() error {
+ ready := c.writeCondition()
+ c.writeState.Lock()
+ for c.postHandshake || c.writeActive {
+ if c.closed.Load() {
+ c.writeState.Unlock()
+ return net.ErrClosed
+ }
+ ready.Wait()
+ }
+ c.writeActive = true
+ c.writeState.Unlock()
+
+ c.writeAccess.Lock()
+ if c.closed.Load() {
+ c.writeAccess.Unlock()
+ c.writeState.Lock()
+ c.writeActive = false
+ ready.Broadcast()
+ c.writeState.Unlock()
+ return net.ErrClosed
+ }
+ return nil
+}
+
+func (c *windowsTLSConn) finishWrite() {
+ c.writeAccess.Unlock()
+ ready := c.writeCondition()
+ c.writeState.Lock()
+ c.writeActive = false
+ ready.Broadcast()
+ c.writeState.Unlock()
+}
+
+func (c *windowsTLSConn) beginPostHandshakeWrite() error {
+ ready := c.writeCondition()
+ c.writeState.Lock()
+ c.postHandshake = true
+ for c.writeActive {
+ if c.closed.Load() {
+ c.postHandshake = false
+ ready.Broadcast()
+ c.writeState.Unlock()
+ return net.ErrClosed
+ }
+ ready.Wait()
+ }
+ c.writeActive = true
+ c.writeState.Unlock()
+
+ c.writeAccess.Lock()
+ if c.closed.Load() {
+ c.writeAccess.Unlock()
+ c.writeState.Lock()
+ c.writeActive = false
+ c.postHandshake = false
+ ready.Broadcast()
+ c.writeState.Unlock()
+ return net.ErrClosed
+ }
+ return nil
+}
+
+func (c *windowsTLSConn) finishPostHandshakeWrite() {
+ c.writeAccess.Unlock()
+ ready := c.writeCondition()
+ c.writeState.Lock()
+ c.writeActive = false
+ c.postHandshake = false
+ ready.Broadcast()
+ c.writeState.Unlock()
+}
+
+func (c *windowsTLSConn) writeCondition() *sync.Cond {
+ c.writeStateOnce.Do(func() {
+ c.writeReady = sync.NewCond(&c.writeState)
+ })
+ return c.writeReady
+}
+
+func (c *windowsTLSConn) isClosed() bool {
+ return c.closed.Load()
+}
+
+type windowsTLSReadWaiter struct {
+ conn *windowsTLSConn
+ rawWaiter N.ReadWaiter
+ options N.ReadWaitOptions
+}
+
+var _ N.ReadWaiter = (*windowsTLSReadWaiter)(nil)
+
+func (w *windowsTLSReadWaiter) InitializeReadWaiter(options N.ReadWaitOptions) (needCopy bool) {
+ w.options = options
+ w.rawWaiter.InitializeReadWaiter(N.ReadWaitOptions{
+ MTU: readWaitCiphertextChunkSize,
+ })
+ return false
+}
+
+func (w *windowsTLSReadWaiter) WaitReadBuffer() (*buf.Buffer, error) {
+ c := w.conn
+ c.readAccess.Lock()
+ defer c.readAccess.Unlock()
+ if c.isClosed() {
+ return nil, net.ErrClosed
+ }
+ plaintext, err := c.readPlaintextLocked(w.appendRaw, w.readRaw)
+ if err != nil {
+ return nil, err
+ }
+ buffer := w.options.NewBuffer()
+ n, writeErr := buffer.Write(plaintext)
+ if writeErr != nil {
+ buffer.Release()
+ return nil, writeErr
+ }
+ if n == 0 {
+ buffer.Release()
+ return nil, io.ErrShortBuffer
+ }
+ if n < len(plaintext) {
+ c.plain = append([]byte(nil), plaintext[n:]...)
+ }
+ w.options.PostReturn(buffer)
+ return buffer, nil
+}
+
+func (w *windowsTLSReadWaiter) appendRaw(requireMore bool) error {
+ rawBuffer, err := w.readRawBuffer(requireMore)
+ if err != nil {
+ return err
+ }
+ w.conn.cipher = append(w.conn.cipher, rawBuffer.Bytes()...)
+ rawBuffer.Release()
+ return nil
+}
+
+func (w *windowsTLSReadWaiter) readRaw(requireMore bool) ([]byte, error) {
+ rawBuffer, err := w.readRawBuffer(requireMore)
+ if err != nil {
+ return nil, err
+ }
+ data := append([]byte(nil), rawBuffer.Bytes()...)
+ rawBuffer.Release()
+ return data, nil
+}
+
+func (w *windowsTLSReadWaiter) readRawBuffer(requireMore bool) (*buf.Buffer, error) {
+ rawBuffer, err := w.rawWaiter.WaitReadBuffer()
+ if err != nil {
+ if requireMore && errors.Is(err, io.EOF) {
+ return nil, io.ErrUnexpectedEOF
+ }
+ return nil, err
+ }
+ if rawBuffer == nil || rawBuffer.Len() == 0 {
+ if rawBuffer != nil {
+ rawBuffer.Release()
+ }
+ return nil, io.ErrUnexpectedEOF
+ }
+ return rawBuffer, nil
+}
diff --git a/common/tls/windows_client_stub.go b/common/tls/windows_client_stub.go
new file mode 100644
index 0000000000..7ad506a725
--- /dev/null
+++ b/common/tls/windows_client_stub.go
@@ -0,0 +1,15 @@
+//go:build !windows
+
+package tls
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+)
+
+func newWindowsClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions, allowEmptyServerName bool) (Config, error) {
+ return nil, E.New("Windows TLS engine is not available on non-Windows platforms")
+}
diff --git a/common/tls/windows_client_test.go b/common/tls/windows_client_test.go
new file mode 100644
index 0000000000..755aea59de
--- /dev/null
+++ b/common/tls/windows_client_test.go
@@ -0,0 +1,2505 @@
+//go:build windows
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ stdtls "crypto/tls"
+ "crypto/x509"
+ "errors"
+ "io"
+ "net"
+ "os"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/sagernet/sing-box/common/schannel"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/bufio"
+ "github.com/sagernet/sing/common/json/badoption"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+const windowsTLSTestTimeout = 5 * time.Second
+
+var (
+ _ N.ExtendedConn = (*windowsTLSConn)(nil)
+ _ N.ReadWaitCreator = (*windowsTLSConn)(nil)
+)
+
+func newTestWindowsTLSConn(rawConn net.Conn) *windowsTLSConn {
+ return &windowsTLSConn{rawConn: rawConn}
+}
+
+// writePostHandshakeReply wraps writePostHandshakeReplyLocked with the
+// writeAccess locking and auto-close behavior that drivePostHandshake
+// composes from beginPostHandshakeWrite/finishPostHandshakeWrite plus the
+// writeFailed → Close branch.
+// Kept here as a test seam.
+func (c *windowsTLSConn) writePostHandshakeReply(data []byte) error {
+ c.writeAccess.Lock()
+ defer c.writeAccess.Unlock()
+ err := c.writePostHandshakeReplyLocked(data)
+ if err != nil {
+ _ = c.Close()
+ }
+ return err
+}
+
+type windowsTLSServerResult struct {
+ state stdtls.ConnectionState
+ err error
+}
+
+type windowsTestDeadlineConn struct {
+ access sync.Mutex
+ readCalled chan struct{}
+ writeCalled chan struct{}
+ readCalledOnce sync.Once
+ writeCalledOnce sync.Once
+ readDeadline time.Time
+ writeDeadline time.Time
+ readDeadlines []time.Time
+ writeDeadlines []time.Time
+}
+
+type windowsTestWriteGateConn struct {
+ writeCalled chan struct{}
+ releaseWrite chan struct{}
+}
+
+type windowsTestIOConn struct {
+ access sync.Mutex
+ readErr error
+ writeErr error
+ writeN int
+ writeCalls int
+ closed bool
+}
+
+func (c *windowsTestDeadlineConn) Read(_ []byte) (int, error) {
+ if c.readCalled != nil {
+ c.readCalledOnce.Do(func() {
+ close(c.readCalled)
+ })
+ }
+ for {
+ c.access.Lock()
+ deadline := c.readDeadline
+ c.access.Unlock()
+ if deadline.IsZero() {
+ time.Sleep(5 * time.Millisecond)
+ continue
+ }
+ if !deadline.After(time.Now()) {
+ return 0, os.ErrDeadlineExceeded
+ }
+ time.Sleep(time.Until(deadline))
+ return 0, os.ErrDeadlineExceeded
+ }
+}
+
+func (c *windowsTestDeadlineConn) Write(_ []byte) (int, error) {
+ if c.writeCalled != nil {
+ c.writeCalledOnce.Do(func() {
+ close(c.writeCalled)
+ })
+ }
+ for {
+ c.access.Lock()
+ deadline := c.writeDeadline
+ c.access.Unlock()
+ if deadline.IsZero() {
+ time.Sleep(5 * time.Millisecond)
+ continue
+ }
+ if !deadline.After(time.Now()) {
+ return 0, os.ErrDeadlineExceeded
+ }
+ time.Sleep(time.Until(deadline))
+ return 0, os.ErrDeadlineExceeded
+ }
+}
+
+func (c *windowsTestDeadlineConn) Close() error {
+ return nil
+}
+
+func (c *windowsTestDeadlineConn) LocalAddr() net.Addr {
+ return windowsTestAddr("local")
+}
+
+func (c *windowsTestDeadlineConn) RemoteAddr() net.Addr {
+ return windowsTestAddr("remote")
+}
+
+func (c *windowsTestDeadlineConn) SetDeadline(t time.Time) error {
+ c.access.Lock()
+ c.readDeadline = t
+ c.writeDeadline = t
+ c.readDeadlines = append(c.readDeadlines, t)
+ c.writeDeadlines = append(c.writeDeadlines, t)
+ c.access.Unlock()
+ return nil
+}
+
+func (c *windowsTestDeadlineConn) SetReadDeadline(t time.Time) error {
+ c.access.Lock()
+ c.readDeadline = t
+ c.readDeadlines = append(c.readDeadlines, t)
+ c.access.Unlock()
+ return nil
+}
+
+func (c *windowsTestDeadlineConn) SetWriteDeadline(t time.Time) error {
+ c.access.Lock()
+ c.writeDeadline = t
+ c.writeDeadlines = append(c.writeDeadlines, t)
+ c.access.Unlock()
+ return nil
+}
+
+func (c *windowsTestDeadlineConn) recordedWriteDeadlines() []time.Time {
+ c.access.Lock()
+ defer c.access.Unlock()
+ return append([]time.Time(nil), c.writeDeadlines...)
+}
+
+func (c *windowsTestDeadlineConn) recordedReadDeadlines() []time.Time {
+ c.access.Lock()
+ defer c.access.Unlock()
+ return append([]time.Time(nil), c.readDeadlines...)
+}
+
+func (c *windowsTestWriteGateConn) Read(_ []byte) (int, error) {
+ return 0, io.EOF
+}
+
+func (c *windowsTestWriteGateConn) Write(p []byte) (int, error) {
+ close(c.writeCalled)
+ <-c.releaseWrite
+ return len(p), nil
+}
+
+func (c *windowsTestWriteGateConn) Close() error {
+ return nil
+}
+
+func (c *windowsTestWriteGateConn) LocalAddr() net.Addr {
+ return windowsTestAddr("local")
+}
+
+func (c *windowsTestWriteGateConn) RemoteAddr() net.Addr {
+ return windowsTestAddr("remote")
+}
+
+func (c *windowsTestWriteGateConn) SetDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestWriteGateConn) SetReadDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestWriteGateConn) SetWriteDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestIOConn) Read(_ []byte) (int, error) {
+ return 0, c.readErr
+}
+
+func (c *windowsTestIOConn) Write(p []byte) (int, error) {
+ c.access.Lock()
+ defer c.access.Unlock()
+ c.writeCalls++
+ if c.writeErr == nil {
+ return len(p), nil
+ }
+ n := c.writeN
+ if n <= 0 || n > len(p) {
+ n = 0
+ }
+ return n, c.writeErr
+}
+
+func (c *windowsTestIOConn) Close() error {
+ c.access.Lock()
+ c.closed = true
+ c.access.Unlock()
+ return nil
+}
+
+func (c *windowsTestIOConn) LocalAddr() net.Addr {
+ return windowsTestAddr("local")
+}
+
+func (c *windowsTestIOConn) RemoteAddr() net.Addr {
+ return windowsTestAddr("remote")
+}
+
+func (c *windowsTestIOConn) SetDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestIOConn) SetReadDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestIOConn) SetWriteDeadline(time.Time) error {
+ return nil
+}
+
+func (c *windowsTestIOConn) isClosed() bool {
+ c.access.Lock()
+ defer c.access.Unlock()
+ return c.closed
+}
+
+func (c *windowsTestIOConn) totalWriteCalls() int {
+ c.access.Lock()
+ defer c.access.Unlock()
+ return c.writeCalls
+}
+
+type windowsTestAddr string
+
+func (a windowsTestAddr) Network() string {
+ return "test"
+}
+
+func (a windowsTestAddr) String() string {
+ return string(a)
+}
+
+type windowsOpaqueConn struct {
+ net.Conn
+}
+
+func TestWindowsClientHandshakeTLS12(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverResult, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2"},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ clientState := clientConn.ConnectionState()
+ if clientState.Version != stdtls.VersionTLS12 {
+ t.Fatalf("unexpected negotiated version: %x", clientState.Version)
+ }
+ if clientState.NegotiatedProtocol != "h2" {
+ t.Fatalf("unexpected negotiated protocol: %q", clientState.NegotiatedProtocol)
+ }
+ if !clientState.HandshakeComplete {
+ t.Fatal("HandshakeComplete is false")
+ }
+ if len(clientState.PeerCertificates) == 0 {
+ t.Fatal("no peer certificates")
+ }
+
+ result := <-serverResult
+ if result.err != nil {
+ t.Fatal(result.err)
+ }
+ if result.state.Version != stdtls.VersionTLS12 {
+ t.Fatalf("server negotiated unexpected version: %x", result.state.Version)
+ }
+ if result.state.NegotiatedProtocol != "h2" {
+ t.Fatalf("server negotiated unexpected protocol: %q", result.state.NegotiatedProtocol)
+ }
+}
+
+func TestWindowsClientHandshakeWrappedConn(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverResult, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+
+ ctx, cancel := context.WithTimeout(context.Background(), windowsTLSTestTimeout)
+ t.Cleanup(cancel)
+
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: ctx,
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ rawConn, err := net.DialTimeout(N.NetworkTCP, serverAddress, windowsTLSTestTimeout)
+ if err != nil {
+ t.Fatal(err)
+ }
+ tlsConn, err := ClientHandshake(ctx, windowsOpaqueConn{Conn: rawConn}, clientConfig)
+ if err != nil {
+ rawConn.Close()
+ t.Fatal(err)
+ }
+ _ = tlsConn.Close()
+
+ result := <-serverResult
+ if result.err != nil {
+ t.Fatal(result.err)
+ }
+ if result.state.Version != stdtls.VersionTLS12 {
+ t.Fatalf("server negotiated unexpected version: %x", result.state.Version)
+ }
+}
+
+func TestWindowsClientHandshakeTLS13(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverResult, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS13,
+ MaxVersion: stdtls.VersionTLS13,
+ NextProtos: []string{"h2"},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.3",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ clientState := clientConn.ConnectionState()
+ if clientState.Version != stdtls.VersionTLS13 {
+ t.Fatalf("expected TLS 1.3, got %x", clientState.Version)
+ }
+ if clientState.NegotiatedProtocol != "h2" {
+ t.Fatalf("expected negotiated protocol h2, got %q", clientState.NegotiatedProtocol)
+ }
+
+ result := <-serverResult
+ if result.err != nil {
+ t.Fatal(result.err)
+ }
+ if result.state.Version != stdtls.VersionTLS13 {
+ t.Fatalf("server negotiated unexpected version: %x", result.state.Version)
+ }
+}
+
+func TestWindowsClientHandshakeALPNNoOverlap(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"http/1.1"},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ MaxVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ // Go's TLS server returns a TLS alert when the client advertises ALPN but
+ // the server has no overlap. The handshake fails.
+ if err == nil {
+ _ = clientConn.Close()
+ t.Fatal("expected handshake to fail with no ALPN overlap")
+ }
+}
+
+func TestWindowsClientHandshakeMultipleALPN(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2", "http/1.1"},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ ALPN: badoption.Listable[string]{"spdy/3", "h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ // Schannel follows the standard selection: first protocol offered by
+ // the client that the server also supports. Here: spdy/3 is not in the
+ // server list but h2 is, so h2 wins.
+ if got := clientConn.ConnectionState().NegotiatedProtocol; got != "h2" {
+ t.Fatalf("expected h2, got %q", got)
+ }
+}
+
+func TestWindowsClientHandshakeRejectsVersionMismatch(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverResult, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS13,
+ MaxVersion: stdtls.VersionTLS13,
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MaxVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected version mismatch handshake to fail")
+ }
+
+ result := <-serverResult
+ if result.err == nil {
+ t.Fatal("expected server handshake to fail on version mismatch")
+ }
+}
+
+func TestWindowsClientHandshakeRejectsServerNameMismatch(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "example.com",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected server name mismatch handshake to fail")
+ }
+}
+
+func TestWindowsClientHandshakeRejectsUntrustedCA(t *testing.T) {
+ serverCertificate, _ := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected untrusted CA handshake to fail")
+ }
+}
+
+func TestWindowsClientHandshakeInsecureSkipsValidation(t *testing.T) {
+ serverCertificate, _ := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ // Server name mismatch but insecure=true → handshake succeeds.
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "example.com",
+ Insecure: true,
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ if !clientConn.ConnectionState().HandshakeComplete {
+ t.Fatal("expected handshake to complete with insecure=true")
+ }
+}
+
+func TestWindowsClientHandshakeHonorsPublicKeyPinSuccess(t *testing.T) {
+ serverCertificate, _ := newWindowsTestCertificate(t, "localhost")
+ pin := publicKeyPin(t, serverCertificate.Leaf)
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ CertificatePublicKeySHA256: [][]byte{pin},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+}
+
+func TestWindowsClientHandshakeHonorsPublicKeyPinFailure(t *testing.T) {
+ serverCertificate, _ := newWindowsTestCertificate(t, "localhost")
+ wrongPin := sha256.Sum256([]byte("not the public key"))
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ CertificatePublicKeySHA256: [][]byte{wrongPin[:]},
+ })
+ if err == nil {
+ clientConn.Close()
+ t.Fatal("expected public-key pin mismatch to fail")
+ }
+}
+
+func TestWindowsClientHandshakeContextCancellation(t *testing.T) {
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ clientHelloRead := make(chan struct{}, 1)
+ serverDone := make(chan struct{})
+ defer close(serverDone)
+ go func() {
+ c, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer c.Close()
+ buffer := make([]byte, 8192)
+ n, readErr := c.Read(buffer)
+ if n > 0 {
+ clientHelloRead <- struct{}{}
+ }
+ if readErr != nil {
+ return
+ }
+ <-serverDone
+ }()
+
+ _, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+
+ ctx, cancel := context.WithCancel(context.Background())
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: ctx,
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ conn, err := net.DialTimeout("tcp", listener.Addr().String(), windowsTLSTestTimeout)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+
+ handshakeDone := make(chan error, 1)
+ go func() {
+ _, err := ClientHandshake(ctx, conn, clientConfig)
+ handshakeDone <- err
+ }()
+
+ select {
+ case <-clientHelloRead:
+ case <-time.After(2 * time.Second):
+ t.Fatal("server did not receive the client hello")
+ }
+
+ cancel()
+
+ select {
+ case err := <-handshakeDone:
+ if !errors.Is(err, context.Canceled) {
+ t.Fatalf("expected context.Canceled, got %v", err)
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("handshake did not return after cancellation")
+ }
+}
+
+func TestWindowsClientHandshakeTimeout(t *testing.T) {
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ // Accept but never respond.
+ go func() {
+ c, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer c.Close()
+ time.Sleep(3 * time.Second)
+ }()
+
+ _, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+
+ ctx, cancel := context.WithTimeout(context.Background(), windowsTLSTestTimeout)
+ defer cancel()
+
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: ctx,
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ HandshakeTimeout: badoption.Duration(300 * time.Millisecond),
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ conn, err := net.DialTimeout("tcp", listener.Addr().String(), windowsTLSTestTimeout)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+
+ start := time.Now()
+ _, err = ClientHandshake(ctx, conn, clientConfig)
+ elapsed := time.Since(start)
+ if err == nil {
+ t.Fatal("expected handshake to time out")
+ }
+ if elapsed > 2*time.Second {
+ t.Fatalf("handshake took %v, expected ~300ms timeout", elapsed)
+ }
+}
+
+func TestWindowsClientRoundtrip(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ defer clientConn.Close()
+
+ _, err := clientConn.Write([]byte("ping"))
+ if err != nil {
+ t.Fatalf("write: %v", err)
+ }
+ reply := make([]byte, 4)
+ _, err = io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read: %v", err)
+ }
+ if string(reply) != "ping" {
+ t.Fatalf("unexpected reply: %q", string(reply))
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientRoundtripTLS13(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS13)
+ defer clientConn.Close()
+
+ payload := []byte("hello tls 1.3")
+ _, err := clientConn.Write(payload)
+ if err != nil {
+ t.Fatalf("write: %v", err)
+ }
+ reply := make([]byte, len(payload))
+ _, err = io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read: %v", err)
+ }
+ if !bytes.Equal(payload, reply) {
+ t.Fatalf("unexpected reply: %q", string(reply))
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientReadBuffer(t *testing.T) {
+ payload := []byte("windows tls read buffer payload")
+ clientConn, serverErr := startWindowsPayloadServer(t, stdtls.VersionTLS12, payload)
+ defer clientConn.Close()
+
+ const (
+ frontHeadroom = 8
+ rearHeadroom = 8
+ )
+ buffer := buf.NewSize(len(payload) + frontHeadroom + rearHeadroom)
+ defer buffer.Release()
+ buffer.Resize(frontHeadroom, 0)
+ buffer.Reserve(rearHeadroom)
+
+ err := clientConn.ReadBuffer(buffer)
+ if err != nil {
+ t.Fatalf("ReadBuffer: %v", err)
+ }
+ if buffer.Start() != frontHeadroom {
+ t.Fatalf("expected front headroom %d, got %d", frontHeadroom, buffer.Start())
+ }
+ if !bytes.Equal(buffer.Bytes(), payload) {
+ t.Fatalf("unexpected payload: %q", string(buffer.Bytes()))
+ }
+ if err = <-serverErr; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWindowsClientWriteBuffer(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoEngineServer(t, stdtls.VersionTLS12)
+ defer clientConn.Close()
+
+ payload := []byte("windows tls write buffer payload")
+ buffer := buf.NewSize(len(payload))
+ _, err := buffer.Write(payload)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ err = clientConn.WriteBuffer(buffer)
+ if err != nil {
+ t.Fatalf("WriteBuffer: %v", err)
+ }
+ if buffer.RawCap() != 0 {
+ t.Fatalf("expected WriteBuffer to release buffer, raw cap %d", buffer.RawCap())
+ }
+
+ reply := make([]byte, len(payload))
+ _, err = io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read echo: %v", err)
+ }
+ if !bytes.Equal(reply, payload) {
+ t.Fatalf("unexpected echo: %q", string(reply))
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientCreateReadWaiter(t *testing.T) {
+ payload := []byte("windows tls read waiter payload")
+ clientConn, serverErr := startWindowsPayloadServer(t, stdtls.VersionTLS12, payload)
+ defer clientConn.Close()
+
+ readWaiter, created := bufio.CreateReadWaiter(clientConn)
+ if !created {
+ t.Fatal("expected read waiter")
+ }
+ readWaiter.InitializeReadWaiter(N.ReadWaitOptions{
+ FrontHeadroom: 7,
+ RearHeadroom: 5,
+ MTU: len(payload),
+ })
+
+ buffer, err := readWaiter.WaitReadBuffer()
+ if err != nil {
+ t.Fatalf("WaitReadBuffer: %v", err)
+ }
+ defer buffer.Release()
+ if buffer.Start() != 7 {
+ t.Fatalf("expected front headroom 7, got %d", buffer.Start())
+ }
+ if buffer.FreeLen() < 5 {
+ t.Fatalf("expected rear headroom at least 5, got %d", buffer.FreeLen())
+ }
+ if !bytes.Equal(buffer.Bytes(), payload) {
+ t.Fatalf("unexpected payload: %q", string(buffer.Bytes()))
+ }
+ if err = <-serverErr; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWindowsClientCreateReadWaiterFallback(t *testing.T) {
+ tlsConn := newTestWindowsTLSConn(&windowsTestIOConn{})
+ _, created := tlsConn.CreateReadWaiter()
+ if created {
+ t.Fatal("expected read waiter fallback")
+ }
+}
+
+func TestWindowsClientTLS13PostHandshakeConcurrentWrite(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ const payloadSize = 4 << 20
+ const prefixSize = 32 << 10
+ reply := []byte("tls13 post-handshake reply")
+
+ serverErr := make(chan error, 1)
+ prefixRead := make(chan struct{})
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ serverErr <- acceptErr
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS13,
+ MaxVersion: stdtls.VersionTLS13,
+ })
+ defer tlsConn.Close()
+
+ err := tlsConn.SetDeadline(time.Now().Add(2 * windowsTLSTestTimeout))
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ err = tlsConn.Handshake()
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ prefix := make([]byte, prefixSize)
+ _, err = io.ReadFull(tlsConn, prefix)
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ close(prefixRead)
+ _, err = tlsConn.Write(reply)
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ _, err = io.Copy(io.Discard, io.LimitReader(tlsConn, int64(payloadSize-prefixSize)))
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ serverErr <- nil
+ }()
+
+ clientConn, err := newWindowsTestClientConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.3",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ payload := make([]byte, payloadSize)
+ for index := range payload {
+ payload[index] = byte(index % 251)
+ }
+ writeDone := make(chan error, 1)
+ go func() {
+ _, err := clientConn.Write(payload)
+ writeDone <- err
+ }()
+
+ select {
+ case <-prefixRead:
+ case <-time.After(2 * time.Second):
+ t.Fatal("server did not observe the client write")
+ }
+
+ replyBuffer := make([]byte, len(reply))
+ _, err = io.ReadFull(clientConn, replyBuffer)
+ if err != nil {
+ t.Fatalf("read: %v", err)
+ }
+ if !bytes.Equal(reply, replyBuffer) {
+ t.Fatalf("unexpected reply: %q", string(replyBuffer))
+ }
+
+ writeErr := <-writeDone
+ if writeErr != nil {
+ t.Fatalf("write: %v", writeErr)
+ }
+ serverErrValue := <-serverErr
+ if serverErrValue != nil {
+ t.Fatal(serverErrValue)
+ }
+}
+
+func TestWindowsClientLargeMessage(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ defer clientConn.Close()
+
+ // 1 MiB exercises multiple TLS records and the chunking logic.
+ // Writes must run concurrently with reads to avoid TCP-buffer deadlock.
+ payload := make([]byte, 1<<20)
+ for index := range payload {
+ payload[index] = byte(index % 251)
+ }
+ writeErr := make(chan error, 1)
+ go func() {
+ _, err := clientConn.Write(payload)
+ writeErr <- err
+ }()
+
+ reply := make([]byte, len(payload))
+ _, err := io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read: %v", err)
+ }
+ writeResult := <-writeErr
+ if writeResult != nil {
+ t.Fatalf("write: %v", writeResult)
+ }
+ if !bytes.Equal(payload, reply) {
+ t.Fatal("payload mismatch after round-trip")
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientFullDuplexLargePayload(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ const payloadSize = 2 << 20
+ clientPayload := make([]byte, payloadSize)
+ serverPayload := make([]byte, payloadSize)
+ for index := range clientPayload {
+ clientPayload[index] = byte(index % 251)
+ serverPayload[index] = byte((index + 97) % 251)
+ }
+
+ serverErr := make(chan error, 1)
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ serverErr <- acceptErr
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ defer tlsConn.Close()
+ err := tlsConn.SetDeadline(time.Now().Add(2 * windowsTLSTestTimeout))
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ err = tlsConn.Handshake()
+ if err != nil {
+ serverErr <- err
+ return
+ }
+
+ readDone := make(chan error, 1)
+ writeDone := make(chan error, 1)
+ go func() {
+ received := make([]byte, len(clientPayload))
+ _, readErr := io.ReadFull(tlsConn, received)
+ if readErr == nil && !bytes.Equal(received, clientPayload) {
+ readErr = errors.New("client payload mismatch")
+ }
+ readDone <- readErr
+ }()
+ go func() {
+ _, writeErr := tlsConn.Write(serverPayload)
+ writeDone <- writeErr
+ }()
+ if readErr := <-readDone; readErr != nil {
+ serverErr <- readErr
+ return
+ }
+ serverErr <- <-writeDone
+ }()
+
+ clientConn, err := newWindowsTestEngineConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ writeDone := make(chan error, 1)
+ go func() {
+ n, writeErr := clientConn.Write(clientPayload)
+ if writeErr == nil && n != len(clientPayload) {
+ writeErr = io.ErrShortWrite
+ }
+ writeDone <- writeErr
+ }()
+
+ reply := make([]byte, len(serverPayload))
+ _, err = io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read: %v", err)
+ }
+ if !bytes.Equal(reply, serverPayload) {
+ t.Fatal("server payload mismatch")
+ }
+ if writeErr := <-writeDone; writeErr != nil {
+ t.Fatalf("write: %v", writeErr)
+ }
+ if err = <-serverErr; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWindowsClientMultipleRoundtrips(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ defer clientConn.Close()
+
+ for i := range 100 {
+ payload := []byte("msg" + string(rune('A'+(i%26))))
+ _, err := clientConn.Write(payload)
+ if err != nil {
+ t.Fatalf("write %d: %v", i, err)
+ }
+ reply := make([]byte, len(payload))
+ _, err = io.ReadFull(clientConn, reply)
+ if err != nil {
+ t.Fatalf("read %d: %v", i, err)
+ }
+ if !bytes.Equal(payload, reply) {
+ t.Fatalf("iteration %d: expected %q got %q", i, payload, reply)
+ }
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientConcurrentReadWrite(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ defer clientConn.Close()
+
+ const messageCount = 200
+ const messageSize = 64
+ payloads := make([][]byte, messageCount)
+ for i := range payloads {
+ buffer := make([]byte, messageSize)
+ for j := range buffer {
+ buffer[j] = byte(i + j)
+ }
+ payloads[i] = buffer
+ }
+
+ readErr := make(chan error, 1)
+ readBack := make(chan []byte, messageCount)
+ go func() {
+ for range messageCount {
+ reply := make([]byte, messageSize)
+ _, err := io.ReadFull(clientConn, reply)
+ if err != nil {
+ readErr <- err
+ return
+ }
+ readBack <- reply
+ }
+ readErr <- nil
+ }()
+
+ for i, payload := range payloads {
+ _, err := clientConn.Write(payload)
+ if err != nil {
+ t.Fatalf("write %d: %v", i, err)
+ }
+ }
+
+ readResult := <-readErr
+ if readResult != nil {
+ t.Fatal(readResult)
+ }
+ for i := range messageCount {
+ got := <-readBack
+ if !bytes.Equal(payloads[i], got) {
+ t.Fatalf("iteration %d: payload mismatch", i)
+ }
+ }
+
+ clientConn.Close()
+ <-serverDone
+}
+
+func TestWindowsClientServerCloseReturnsEOF(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ done := make(chan struct{})
+ go func() {
+ defer close(done)
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ _ = tlsConn.Handshake()
+ // Send close_notify then exit.
+ _ = tlsConn.Close()
+ }()
+
+ clientConn, err := newWindowsTestClientConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ buffer := make([]byte, 16)
+ _, err = clientConn.Read(buffer)
+ if !errors.Is(err, io.EOF) {
+ t.Fatalf("expected io.EOF, got %v", err)
+ }
+ <-done
+}
+
+func TestWindowsClientCloseUnblocksRead(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ readDone := make(chan error, 1)
+ go func() {
+ buffer := make([]byte, 16)
+ _, err := clientConn.Read(buffer)
+ readDone <- err
+ }()
+
+ time.Sleep(100 * time.Millisecond)
+ clientConn.Close()
+
+ select {
+ case err := <-readDone:
+ if err == nil {
+ t.Fatal("expected Read to return an error after Close")
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("Read did not return within 2s after Close")
+ }
+}
+
+func TestWindowsClientReadAfterCloseReturnsError(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ clientConn.Close()
+ <-serverDone
+
+ buffer := make([]byte, 16)
+ _, err := clientConn.Read(buffer)
+ if err == nil {
+ t.Fatal("expected Read after Close to return error")
+ }
+}
+
+func TestWindowsClientReadAfterCloseDoesNotServeBufferedPlaintext(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ serverDone := make(chan struct{})
+ serverErr := make(chan error, 1)
+ payload := bytes.Repeat([]byte("buffered plaintext "), 32)
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ serverErr <- acceptErr
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ defer tlsConn.Close()
+
+ err := tlsConn.SetDeadline(time.Now().Add(windowsTLSTestTimeout))
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ err = tlsConn.Handshake()
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ _, err = tlsConn.Write(payload)
+ if err != nil {
+ serverErr <- err
+ return
+ }
+ <-serverDone
+ serverErr <- nil
+ }()
+
+ clientConn, err := newWindowsTestClientConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ buffer := make([]byte, 8)
+ n, err := clientConn.Read(buffer)
+ if err != nil {
+ t.Fatalf("first read: %v", err)
+ }
+ if n != len(buffer) {
+ t.Fatalf("expected first read to fill the buffer, got %d", n)
+ }
+
+ clientConn.Close()
+ close(serverDone)
+
+ _, err = clientConn.Read(make([]byte, len(payload)))
+ if !errors.Is(err, net.ErrClosed) {
+ t.Fatalf("expected net.ErrClosed, got %v", err)
+ }
+ serverErrValue := <-serverErr
+ if serverErrValue != nil {
+ t.Fatal(serverErrValue)
+ }
+}
+
+func TestWindowsClientWriteAfterCloseReturnsError(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ clientConn.Close()
+ <-serverDone
+
+ _, err := clientConn.Write([]byte("after close"))
+ if err == nil {
+ t.Fatal("expected Write after Close to return error")
+ }
+}
+
+func TestWindowsClientReadDeadline(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverDone, serverAddress := startWindowsTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+ defer close(serverDone)
+
+ err = clientConn.SetReadDeadline(time.Now().Add(200 * time.Millisecond))
+ if err != nil {
+ t.Fatalf("SetReadDeadline: %v", err)
+ }
+
+ readDone := make(chan error, 1)
+ buffer := make([]byte, 64)
+ go func() {
+ _, readErr := clientConn.Read(buffer)
+ readDone <- readErr
+ }()
+
+ select {
+ case readErr := <-readDone:
+ if !errors.Is(readErr, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", readErr)
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("Read did not return within 2s after deadline")
+ }
+}
+
+func TestWindowsClientSetReadDeadlinePreExpired(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverDone, serverAddress := startWindowsTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+ defer close(serverDone)
+
+ err = clientConn.SetReadDeadline(time.Now().Add(-time.Second))
+ if err != nil {
+ t.Fatalf("SetReadDeadline past: %v", err)
+ }
+
+ buffer := make([]byte, 16)
+ _, err = clientConn.Read(buffer)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+
+ // Clearing the deadline must restore normal blocking behaviour.
+ err = clientConn.SetReadDeadline(time.Time{})
+ if err != nil {
+ t.Fatalf("SetReadDeadline zero: %v", err)
+ }
+ err = clientConn.SetReadDeadline(time.Now().Add(200 * time.Millisecond))
+ if err != nil {
+ t.Fatalf("SetReadDeadline future: %v", err)
+ }
+ start := time.Now()
+ _, err = clientConn.Read(buffer)
+ elapsed := time.Since(start)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded after re-arm, got %v", err)
+ }
+ if elapsed < 150*time.Millisecond {
+ t.Fatalf("Read returned too fast (%v), pre-expired flag leaked", elapsed)
+ }
+}
+
+func TestWindowsClientSetDeadlinePropagatesToRawConn(t *testing.T) {
+ rawConn := &windowsTestDeadlineConn{}
+ tlsConn := newTestWindowsTLSConn(rawConn)
+
+ deadline := time.Now().Add(time.Second)
+ err := tlsConn.SetDeadline(deadline)
+ if err != nil {
+ t.Fatalf("SetDeadline: %v", err)
+ }
+
+ readDeadlines := rawConn.recordedReadDeadlines()
+ if len(readDeadlines) != 1 {
+ t.Fatalf("expected 1 read deadline update, got %d", len(readDeadlines))
+ }
+ if !readDeadlines[0].Equal(deadline) {
+ t.Fatalf("expected read deadline %v, got %v", deadline, readDeadlines[0])
+ }
+
+ writeDeadlines := rawConn.recordedWriteDeadlines()
+ if len(writeDeadlines) != 1 {
+ t.Fatalf("expected 1 write deadline update, got %d", len(writeDeadlines))
+ }
+ if !writeDeadlines[0].Equal(deadline) {
+ t.Fatalf("expected write deadline %v, got %v", deadline, writeDeadlines[0])
+ }
+}
+
+func TestWindowsClientSetReadDeadlineCancelsBlockedRead(t *testing.T) {
+ rawConn := &windowsTestDeadlineConn{
+ readCalled: make(chan struct{}),
+ }
+ tlsConn := newTestWindowsTLSConn(rawConn)
+ tlsConn.readScratch = make([]byte, 16)
+
+ readErrCh := make(chan error, 1)
+ go func() {
+ _, err := tlsConn.Read(make([]byte, 1))
+ readErrCh <- err
+ }()
+
+ select {
+ case <-rawConn.readCalled:
+ case <-time.After(time.Second):
+ t.Fatal("Read did not reach the raw connection")
+ }
+
+ deadline := time.Now().Add(150 * time.Millisecond)
+ err := tlsConn.SetReadDeadline(deadline)
+ if err != nil {
+ t.Fatalf("SetReadDeadline: %v", err)
+ }
+
+ select {
+ case err = <-readErrCh:
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("Read did not return after SetReadDeadline")
+ }
+
+ readDeadlines := rawConn.recordedReadDeadlines()
+ if len(readDeadlines) != 1 {
+ t.Fatalf("expected 1 read deadline update, got %d", len(readDeadlines))
+ }
+ if !readDeadlines[0].Equal(deadline) {
+ t.Fatalf("expected read deadline %v, got %v", deadline, readDeadlines[0])
+ }
+}
+
+func TestWindowsClientSetWriteDeadlineCancelsBlockedWrite(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverDone, serverAddress := startWindowsTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ defer close(serverDone)
+
+ tlsConn, err := newWindowsTestEngineConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ originalRawConn := tlsConn.rawConn
+ rawConn := &windowsTestDeadlineConn{
+ writeCalled: make(chan struct{}),
+ }
+ tlsConn.rawConn = rawConn
+ t.Cleanup(func() {
+ _ = originalRawConn.Close()
+ _ = tlsConn.Close()
+ })
+
+ writeErrCh := make(chan error, 1)
+ go func() {
+ _, err := tlsConn.Write([]byte("ping"))
+ writeErrCh <- err
+ }()
+
+ select {
+ case <-rawConn.writeCalled:
+ case <-time.After(time.Second):
+ t.Fatal("Write did not reach the raw connection")
+ }
+
+ deadline := time.Now().Add(150 * time.Millisecond)
+ err = tlsConn.SetWriteDeadline(deadline)
+ if err != nil {
+ t.Fatalf("SetWriteDeadline: %v", err)
+ }
+
+ select {
+ case err = <-writeErrCh:
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ case <-time.After(2 * time.Second):
+ t.Fatal("Write did not return after SetWriteDeadline")
+ }
+
+ writeDeadlines := rawConn.recordedWriteDeadlines()
+ if len(writeDeadlines) != 1 {
+ t.Fatalf("expected 1 write deadline update, got %d", len(writeDeadlines))
+ }
+ if !writeDeadlines[0].Equal(deadline) {
+ t.Fatalf("expected write deadline %v, got %v", deadline, writeDeadlines[0])
+ }
+}
+
+func TestWindowsClientPostHandshakeReplyUsesReadDeadline(t *testing.T) {
+ rawConn := &windowsTestDeadlineConn{}
+ tlsConn := newTestWindowsTLSConn(rawConn)
+
+ readDeadline := time.Now().Add(150 * time.Millisecond)
+ err := tlsConn.SetReadDeadline(readDeadline)
+ if err != nil {
+ t.Fatalf("SetReadDeadline: %v", err)
+ }
+
+ start := time.Now()
+ err = tlsConn.writePostHandshakeReply([]byte("reply"))
+ elapsed := time.Since(start)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ if elapsed < 100*time.Millisecond {
+ t.Fatalf("post-handshake write returned too fast: %v", elapsed)
+ }
+
+ deadlines := rawConn.recordedWriteDeadlines()
+ if len(deadlines) != 2 {
+ t.Fatalf("expected 2 write deadline updates, got %d", len(deadlines))
+ }
+ if !deadlines[0].Equal(readDeadline) {
+ t.Fatalf("expected first write deadline %v, got %v", readDeadline, deadlines[0])
+ }
+ if !deadlines[1].IsZero() {
+ t.Fatalf("expected write deadline cleanup, got %v", deadlines[1])
+ }
+}
+
+func TestWindowsClientPostHandshakeReplyPreExpiredReadDeadline(t *testing.T) {
+ rawConn := &windowsTestDeadlineConn{}
+ tlsConn := newTestWindowsTLSConn(rawConn)
+
+ err := tlsConn.SetReadDeadline(time.Now().Add(-time.Second))
+ if err != nil {
+ t.Fatalf("SetReadDeadline: %v", err)
+ }
+
+ start := time.Now()
+ err = tlsConn.writePostHandshakeReply([]byte("reply"))
+ elapsed := time.Since(start)
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ if elapsed > 50*time.Millisecond {
+ t.Fatalf("pre-expired post-handshake write returned too slowly: %v", elapsed)
+ }
+
+ deadlines := rawConn.recordedWriteDeadlines()
+ if len(deadlines) != 0 {
+ t.Fatalf("expected no write deadline update for pre-expired read deadline, got %d", len(deadlines))
+ }
+}
+
+func TestDriveStepsPreservesBufferedHandshakeBytes(t *testing.T) {
+ scratch := make([]byte, 8)
+ copy(scratch, "abc")
+
+ readCalls := 0
+ stepCalls := 0
+ leftover, err := driveSteps(
+ scratch[:3],
+ func(input []byte) (schannel.StepResult, error) {
+ stepCalls++
+ switch stepCalls {
+ case 1:
+ if string(input) != "abc" {
+ t.Fatalf("first step input = %q, want %q", input, "abc")
+ }
+ return schannel.StepResult{Incomplete: true}, nil
+ case 2:
+ if string(input) != "abcdef" {
+ t.Fatalf("second step input = %q, want %q", input, "abcdef")
+ }
+ return schannel.StepResult{Consumed: len(input), Done: true}, nil
+ default:
+ t.Fatalf("unexpected step call %d", stepCalls)
+ return schannel.StepResult{}, nil
+ }
+ },
+ func() ([]byte, error) {
+ readCalls++
+ copy(scratch, "def")
+ return scratch[:3], nil
+ },
+ func([]byte) error { return nil },
+ )
+ if err != nil {
+ t.Fatal(err)
+ }
+ if readCalls != 1 {
+ t.Fatalf("readMore called %d times, want 1", readCalls)
+ }
+ if len(leftover) != 0 {
+ t.Fatalf("leftover = %q, want empty", leftover)
+ }
+}
+
+func TestWindowsTLSRawReadEOFAtRecordBoundary(t *testing.T) {
+ rawConn := &windowsTestIOConn{readErr: io.EOF}
+ _, err := readTLSRaw(rawConn, make([]byte, 16), false)
+ if !errors.Is(err, io.EOF) {
+ t.Fatalf("expected io.EOF, got %v", err)
+ }
+}
+
+func TestWindowsTLSRawReadEOFWithPendingRecord(t *testing.T) {
+ rawConn := &windowsTestIOConn{readErr: io.EOF}
+ _, err := readTLSRaw(rawConn, make([]byte, 16), true)
+ if !errors.Is(err, io.ErrUnexpectedEOF) {
+ t.Fatalf("expected io.ErrUnexpectedEOF, got %v", err)
+ }
+}
+
+func TestWindowsClientPostHandshakeReplyWaitsForWriteAccess(t *testing.T) {
+ rawConn := &windowsTestWriteGateConn{
+ writeCalled: make(chan struct{}),
+ releaseWrite: make(chan struct{}),
+ }
+ tlsConn := newTestWindowsTLSConn(rawConn)
+
+ tlsConn.writeAccess.Lock()
+ errCh := make(chan error, 1)
+ go func() {
+ errCh <- tlsConn.writePostHandshakeReply([]byte("reply"))
+ }()
+
+ select {
+ case <-rawConn.writeCalled:
+ t.Fatal("post-handshake write bypassed writeAccess")
+ case <-time.After(100 * time.Millisecond):
+ }
+
+ tlsConn.writeAccess.Unlock()
+
+ select {
+ case <-rawConn.writeCalled:
+ case <-time.After(time.Second):
+ t.Fatal("post-handshake write did not resume after writeAccess release")
+ }
+
+ close(rawConn.releaseWrite)
+ err := <-errCh
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWindowsClientPostHandshakeWritePreemptsNewWrite(t *testing.T) {
+ tlsConn := newTestWindowsTLSConn(&windowsTestIOConn{})
+ err := tlsConn.beginWrite()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ postHandshakeReady := make(chan error, 1)
+ go func() {
+ postHandshakeReady <- tlsConn.beginPostHandshakeWrite()
+ }()
+
+ deadline := time.After(time.Second)
+ for {
+ tlsConn.writeState.Lock()
+ pending := tlsConn.postHandshake
+ tlsConn.writeState.Unlock()
+ if pending {
+ break
+ }
+ select {
+ case <-deadline:
+ t.Fatal("post-handshake write did not become pending")
+ default:
+ time.Sleep(time.Millisecond)
+ }
+ }
+
+ writeReady := make(chan error, 1)
+ go func() {
+ writeReady <- tlsConn.beginWrite()
+ }()
+
+ tlsConn.finishWrite()
+
+ select {
+ case err = <-postHandshakeReady:
+ if err != nil {
+ t.Fatal(err)
+ }
+ case err = <-writeReady:
+ t.Fatalf("new write preempted post-handshake write: %v", err)
+ case <-time.After(time.Second):
+ t.Fatal("post-handshake write did not resume")
+ }
+
+ select {
+ case err = <-writeReady:
+ t.Fatalf("new write acquired before post-handshake finished: %v", err)
+ case <-time.After(100 * time.Millisecond):
+ }
+
+ tlsConn.finishPostHandshakeWrite()
+ select {
+ case err = <-writeReady:
+ if err != nil {
+ t.Fatal(err)
+ }
+ case <-time.After(time.Second):
+ t.Fatal("new write did not resume after post-handshake write")
+ }
+ tlsConn.finishWrite()
+}
+
+func TestWindowsClientPostHandshakeReplyErrorClosesConn(t *testing.T) {
+ rawConn := &windowsTestIOConn{
+ writeErr: os.ErrDeadlineExceeded,
+ writeN: 1,
+ }
+ tlsConn := newTestWindowsTLSConn(rawConn)
+
+ err := tlsConn.writePostHandshakeReply([]byte("reply"))
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ if !rawConn.isClosed() {
+ t.Fatal("expected raw conn to be closed")
+ }
+ if !tlsConn.isClosed() {
+ t.Fatal("expected tls conn to be closed")
+ }
+}
+
+func TestWindowsClientWriteErrorClosesConn(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ serverDone, serverAddress := startWindowsTLSSilentServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ MaxVersion: stdtls.VersionTLS12,
+ })
+ defer close(serverDone)
+
+ tlsConn, err := newWindowsTestEngineConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ originalRawConn := tlsConn.rawConn
+ rawConn := &windowsTestIOConn{
+ writeErr: os.ErrDeadlineExceeded,
+ writeN: 1,
+ }
+ tlsConn.rawConn = rawConn
+ t.Cleanup(func() {
+ _ = originalRawConn.Close()
+ _ = tlsConn.Close()
+ })
+
+ _, err = tlsConn.Write([]byte("ping"))
+ if !errors.Is(err, os.ErrDeadlineExceeded) {
+ t.Fatalf("expected os.ErrDeadlineExceeded, got %v", err)
+ }
+ if !rawConn.isClosed() {
+ t.Fatal("expected raw conn to be closed")
+ }
+ if !tlsConn.isClosed() {
+ t.Fatal("expected tls conn to be closed")
+ }
+
+ _, err = tlsConn.Write([]byte("again"))
+ if !errors.Is(err, net.ErrClosed) {
+ t.Fatalf("expected net.ErrClosed on second write, got %v", err)
+ }
+ if rawConn.totalWriteCalls() != 1 {
+ t.Fatalf("expected exactly 1 raw write, got %d", rawConn.totalWriteCalls())
+ }
+
+ _, err = tlsConn.Read(make([]byte, 1))
+ if !errors.Is(err, net.ErrClosed) {
+ t.Fatalf("expected net.ErrClosed on read after write failure, got %v", err)
+ }
+}
+
+func TestWindowsClientConnectionStateFields(t *testing.T) {
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ _, serverAddress := startWindowsTLSTestServer(t, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: stdtls.VersionTLS12,
+ NextProtos: []string{"h2"},
+ })
+
+ clientConn, err := newWindowsTestClientConn(t, serverAddress, option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: "1.2",
+ ALPN: badoption.Listable[string]{"h2"},
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer clientConn.Close()
+
+ state := clientConn.ConnectionState()
+ if state.ServerName != "localhost" {
+ t.Errorf("ServerName: expected localhost, got %q", state.ServerName)
+ }
+ if state.NegotiatedProtocol != "h2" {
+ t.Errorf("NegotiatedProtocol: expected h2, got %q", state.NegotiatedProtocol)
+ }
+ if !state.HandshakeComplete {
+ t.Error("HandshakeComplete: expected true")
+ }
+ if state.Version < stdtls.VersionTLS12 || state.Version > stdtls.VersionTLS13 {
+ t.Errorf("Version: expected TLS 1.2–1.3, got %x", state.Version)
+ }
+ if len(state.PeerCertificates) == 0 {
+ t.Fatal("PeerCertificates: expected at least one certificate")
+ }
+ // CipherSuite may be 0 when the Schannel name does not map to a Go
+ // constant; just ensure it's consistent with the protocol.
+ if state.Version == stdtls.VersionTLS13 && state.CipherSuite != 0 {
+ switch state.CipherSuite {
+ case stdtls.TLS_AES_128_GCM_SHA256, stdtls.TLS_AES_256_GCM_SHA384, stdtls.TLS_CHACHA20_POLY1305_SHA256:
+ default:
+ t.Errorf("unexpected TLS 1.3 cipher suite: %x", state.CipherSuite)
+ }
+ }
+}
+
+func TestWindowsClientNetConnReturnsUnderlying(t *testing.T) {
+ clientConn, serverDone := startWindowsEchoServer(t, stdtls.VersionTLS12)
+ defer func() { <-serverDone }()
+ defer clientConn.Close()
+
+ underlying := clientConn.NetConn()
+ if _, isTCP := underlying.(*net.TCPConn); !isTCP {
+ t.Fatalf("NetConn returned %T, expected *net.TCPConn", underlying)
+ }
+}
+
+func TestNewWindowsClientMissingServerName(t *testing.T) {
+ _, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ },
+ })
+ if err == nil {
+ t.Fatal("expected missing server_name error")
+ }
+}
+
+func TestNewWindowsClientInsecureAllowsMissingServerName(t *testing.T) {
+ _, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ Insecure: true,
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestWindowsClientConfigSTDConfigReturnsError(t *testing.T) {
+ config, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = config.STDConfig()
+ if err == nil {
+ t.Fatal("expected STDConfig() to return error for Windows engine")
+ }
+ if !strings.Contains(err.Error(), "system TLS engine") {
+ t.Fatalf("expected error to name the engine, got %q", err.Error())
+ }
+}
+
+func TestWindowsClientConfigClientReturnsErrInvalid(t *testing.T) {
+ config, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, err = config.Client(nil)
+ if !errors.Is(err, os.ErrInvalid) {
+ t.Fatalf("expected os.ErrInvalid, got %v", err)
+ }
+}
+
+func TestWindowsClientConfigClone(t *testing.T) {
+ config, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ ALPN: badoption.Listable[string]{"h2", "http/1.1"},
+ },
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ clone := config.Clone()
+
+ // Mutating the clone must not affect the original.
+ clone.SetServerName("other")
+ clone.SetNextProtos([]string{"h3"})
+ if config.ServerName() == "other" {
+ t.Error("Clone shares server name with original")
+ }
+ if len(config.NextProtos()) != 2 {
+ t.Error("Clone shares ALPN slice with original")
+ }
+}
+
+func TestValidateWindowsTLSOptionsRejections(t *testing.T) {
+ cases := []struct {
+ name string
+ options option.OutboundTLSOptions
+ needle string
+ }{
+ {"reality", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ Reality: &option.OutboundRealityOptions{Enabled: true, ShortID: "abc"},
+ }, "reality"},
+ {"utls", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ UTLS: &option.OutboundUTLSOptions{Enabled: true},
+ }, "utls"},
+ {"ech", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ ECH: &option.OutboundECHOptions{Enabled: true},
+ }, "ech"},
+ {"disable_sni", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ DisableSNI: true,
+ }, "disable_sni"},
+ {"cipher_suites", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ CipherSuites: []string{"TLS_AES_128_GCM_SHA256"},
+ }, "cipher_suites"},
+ {"curve_preferences", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ CurvePreferences: []option.CurvePreference{option.CurvePreference(29)},
+ }, "curve_preferences"},
+ {"client_certificate", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ ClientCertificate: badoption.Listable[string]{"pem"},
+ }, "client certificate"},
+ {"fragment", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ Fragment: true,
+ }, "tls fragment"},
+ {"record_fragment", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ RecordFragment: true,
+ }, "tls fragment"},
+ {"kernel_tx", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ KernelTx: true,
+ }, "ktls"},
+ {"kernel_rx", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ KernelRx: true,
+ }, "ktls"},
+ {"spoof", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ Spoof: "decoy.example",
+ }, "spoof"},
+ {"pin_and_cert_conflict", option.OutboundTLSOptions{
+ Enabled: true, Engine: C.TLSEngineWindows, ServerName: "x",
+ Certificate: badoption.Listable[string]{"-----BEGIN CERTIFICATE-----"},
+ CertificatePublicKeySHA256: [][]byte{make([]byte, 32)},
+ }, "certificate_public_key_sha256"},
+ }
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ _, err := NewClientWithOptions(ClientOptions{
+ Context: context.Background(),
+ Logger: logger.NOP(),
+ Options: tc.options,
+ })
+ if err == nil {
+ t.Fatalf("expected error containing %q, got nil", tc.needle)
+ }
+ if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.needle)) {
+ t.Fatalf("expected error to contain %q, got %q", tc.needle, err.Error())
+ }
+ })
+ }
+}
+
+func startWindowsTLSSilentServer(t *testing.T, tlsConfig *stdtls.Config) (chan<- struct{}, string) {
+ t.Helper()
+
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ if tcpListener, isTCP := listener.(*net.TCPListener); isTCP {
+ err = tcpListener.SetDeadline(time.Now().Add(windowsTLSTestTimeout))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ done := make(chan struct{})
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+ deadlineErr := conn.SetDeadline(time.Now().Add(windowsTLSTestTimeout))
+ if deadlineErr != nil {
+ return
+ }
+ tlsConn := stdtls.Server(conn, tlsConfig)
+ defer tlsConn.Close()
+ handshakeErr := tlsConn.Handshake()
+ if handshakeErr != nil {
+ return
+ }
+ handshakeErr = conn.SetDeadline(time.Time{})
+ if handshakeErr != nil {
+ return
+ }
+ <-done
+ }()
+ return done, listener.Addr().String()
+}
+
+// sharedWindowsTestCertificate caches a localhost certificate so the RSA key
+// generation runs once per test binary instead of once per test.
+var sharedWindowsTestCertificate = sync.OnceValues(func() (stdtls.Certificate, string) {
+ return generateWindowsTestCertificate("localhost")
+})
+
+func newWindowsTestCertificate(t *testing.T, serverName string) (stdtls.Certificate, string) {
+ t.Helper()
+ if serverName == "localhost" {
+ return sharedWindowsTestCertificate()
+ }
+ return generateWindowsTestCertificate(serverName)
+}
+
+func generateWindowsTestCertificate(serverName string) (stdtls.Certificate, string) {
+ privateKeyPEM, certificatePEM, err := GenerateCertificate(nil, nil, time.Now, serverName, time.Now().Add(time.Hour))
+ if err != nil {
+ panic(err)
+ }
+ certificate, err := stdtls.X509KeyPair(certificatePEM, privateKeyPEM)
+ if err != nil {
+ panic(err)
+ }
+ leaf, err := x509.ParseCertificate(certificate.Certificate[0])
+ if err != nil {
+ panic(err)
+ }
+ certificate.Leaf = leaf
+ return certificate, string(certificatePEM)
+}
+
+func publicKeyPin(t *testing.T, cert *x509.Certificate) []byte {
+ t.Helper()
+ pub, err := x509.MarshalPKIXPublicKey(cert.PublicKey)
+ if err != nil {
+ t.Fatal(err)
+ }
+ sum := sha256.Sum256(pub)
+ return sum[:]
+}
+
+func startWindowsTLSTestServer(t *testing.T, tlsConfig *stdtls.Config) (<-chan windowsTLSServerResult, string) {
+ t.Helper()
+
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ if tcpListener, isTCP := listener.(*net.TCPListener); isTCP {
+ err = tcpListener.SetDeadline(time.Now().Add(windowsTLSTestTimeout))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+
+ result := make(chan windowsTLSServerResult, 1)
+ go func() {
+ defer close(result)
+
+ conn, err := listener.Accept()
+ if err != nil {
+ result <- windowsTLSServerResult{err: err}
+ return
+ }
+ defer conn.Close()
+
+ err = conn.SetDeadline(time.Now().Add(windowsTLSTestTimeout))
+ if err != nil {
+ result <- windowsTLSServerResult{err: err}
+ return
+ }
+
+ tlsConn := stdtls.Server(conn, tlsConfig)
+ defer tlsConn.Close()
+
+ err = tlsConn.Handshake()
+ if err != nil {
+ result <- windowsTLSServerResult{err: err}
+ return
+ }
+
+ result <- windowsTLSServerResult{state: tlsConn.ConnectionState()}
+ }()
+
+ return result, listener.Addr().String()
+}
+
+func newWindowsTestClientConn(t *testing.T, serverAddress string, options option.OutboundTLSOptions) (Conn, error) {
+ t.Helper()
+
+ ctx, cancel := context.WithTimeout(context.Background(), windowsTLSTestTimeout)
+ t.Cleanup(cancel)
+
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: ctx,
+ Logger: logger.NOP(),
+ ServerAddress: "",
+ Options: options,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ conn, err := net.DialTimeout("tcp", serverAddress, windowsTLSTestTimeout)
+ if err != nil {
+ return nil, err
+ }
+
+ tlsConn, err := ClientHandshake(ctx, conn, clientConfig)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return tlsConn, nil
+}
+
+func newWindowsTestEngineConn(t *testing.T, serverAddress string, options option.OutboundTLSOptions) (*windowsTLSConn, error) {
+ t.Helper()
+
+ ctx, cancel := context.WithTimeout(context.Background(), windowsTLSTestTimeout)
+ t.Cleanup(cancel)
+
+ clientConfig, err := NewClientWithOptions(ClientOptions{
+ Context: ctx,
+ Logger: logger.NOP(),
+ ServerAddress: "",
+ Options: options,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ engineConfig, ok := clientConfig.(*windowsClientConfig)
+ if !ok {
+ return nil, errors.New("unexpected windows config type")
+ }
+
+ conn, err := net.DialTimeout("tcp", serverAddress, windowsTLSTestTimeout)
+ if err != nil {
+ return nil, err
+ }
+
+ tlsConn, err := engineConfig.ClientHandshake(ctx, conn)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+
+ engineConn, ok := tlsConn.(*windowsTLSConn)
+ if !ok {
+ tlsConn.Close()
+ return nil, errors.New("unexpected windows conn type")
+ }
+ return engineConn, nil
+}
+
+func startWindowsPayloadServer(t *testing.T, minVersion uint16, payload []byte) (*windowsTLSConn, <-chan error) {
+ t.Helper()
+
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ serverErr := make(chan error, 1)
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ serverErr <- acceptErr
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: minVersion,
+ MaxVersion: minVersion,
+ })
+ defer tlsConn.Close()
+
+ handshakeErr := tlsConn.Handshake()
+ if handshakeErr != nil {
+ serverErr <- handshakeErr
+ return
+ }
+ _, writeErr := tlsConn.Write(payload)
+ serverErr <- writeErr
+ }()
+
+ version := "1.2"
+ if minVersion == stdtls.VersionTLS13 {
+ version = "1.3"
+ }
+ clientConn, err := newWindowsTestEngineConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: version,
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ return clientConn, serverErr
+}
+
+// startWindowsEchoServer brings up a TLS echo server with a self-signed cert
+// and dials an engine client against it. The returned channel closes after
+// the server goroutine exits.
+func startWindowsEchoServer(t *testing.T, minVersion uint16) (Conn, <-chan struct{}) {
+ t.Helper()
+
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ done := make(chan struct{})
+ go func() {
+ defer close(done)
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: minVersion,
+ MaxVersion: minVersion,
+ })
+ defer tlsConn.Close()
+
+ handshakeErr := tlsConn.Handshake()
+ if handshakeErr != nil {
+ return
+ }
+
+ buffer := make([]byte, 32*1024)
+ for {
+ n, readErr := tlsConn.Read(buffer)
+ if n > 0 {
+ _, writeErr := tlsConn.Write(buffer[:n])
+ if writeErr != nil {
+ return
+ }
+ }
+ if readErr != nil {
+ return
+ }
+ }
+ }()
+
+ version := "1.2"
+ if minVersion == stdtls.VersionTLS13 {
+ version = "1.3"
+ }
+ clientConn, err := newWindowsTestClientConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: version,
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ return clientConn, done
+}
+
+func startWindowsEchoEngineServer(t *testing.T, minVersion uint16) (*windowsTLSConn, <-chan struct{}) {
+ t.Helper()
+
+ serverCertificate, serverCertificatePEM := newWindowsTestCertificate(t, "localhost")
+ listener, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Cleanup(func() { listener.Close() })
+
+ done := make(chan struct{})
+ go func() {
+ defer close(done)
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+
+ tlsConn := stdtls.Server(conn, &stdtls.Config{
+ Certificates: []stdtls.Certificate{serverCertificate},
+ MinVersion: minVersion,
+ MaxVersion: minVersion,
+ })
+ defer tlsConn.Close()
+
+ handshakeErr := tlsConn.Handshake()
+ if handshakeErr != nil {
+ return
+ }
+
+ buffer := make([]byte, 32*1024)
+ for {
+ n, readErr := tlsConn.Read(buffer)
+ if n > 0 {
+ _, writeErr := tlsConn.Write(buffer[:n])
+ if writeErr != nil {
+ return
+ }
+ }
+ if readErr != nil {
+ return
+ }
+ }
+ }()
+
+ version := "1.2"
+ if minVersion == stdtls.VersionTLS13 {
+ version = "1.3"
+ }
+ clientConn, err := newWindowsTestEngineConn(t, listener.Addr().String(), option.OutboundTLSOptions{
+ Enabled: true,
+ Engine: C.TLSEngineWindows,
+ ServerName: "localhost",
+ MinVersion: version,
+ Certificate: badoption.Listable[string]{serverCertificatePEM},
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ return clientConn, done
+}
diff --git a/common/tlsfragment/index.go b/common/tlsfragment/index.go
index 0d58c445c8..83e4bcbc11 100644
--- a/common/tlsfragment/index.go
+++ b/common/tlsfragment/index.go
@@ -23,9 +23,10 @@ const (
)
type MyServerName struct {
- Index int
- Length int
- ServerName string
+ Index int
+ Length int
+ ServerName string
+ ExtensionsListLengthIndex int
}
func IndexTLSServerName(payload []byte) *MyServerName {
@@ -41,6 +42,7 @@ func IndexTLSServerName(payload []byte) *MyServerName {
return nil
}
serverName.Index += recordLayerHeaderLen
+ serverName.ExtensionsListLengthIndex += recordLayerHeaderLen
return serverName
}
@@ -82,6 +84,7 @@ func indexTLSServerNameFromHandshake(handshake []byte) *MyServerName {
return nil
}
serverName.Index += currentIndex
+ serverName.ExtensionsListLengthIndex = currentIndex
return serverName
}
diff --git a/common/tlsspoof/README.md b/common/tlsspoof/README.md
new file mode 100644
index 0000000000..de684e15cd
--- /dev/null
+++ b/common/tlsspoof/README.md
@@ -0,0 +1,3 @@
+# tls spoof
+
+idea from https://github.com/therealaleph/sni-spoofing-rust
diff --git a/common/tlsspoof/client_hello.go b/common/tlsspoof/client_hello.go
new file mode 100644
index 0000000000..abdfa31753
--- /dev/null
+++ b/common/tlsspoof/client_hello.go
@@ -0,0 +1,37 @@
+package tlsspoof
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+// buildFakeClientHello drives crypto/tls against a write-only in-memory conn
+// to capture a generated ClientHello. CurvePreferences pins classical groups
+// to suppress Go's default X25519MLKEM768 hybrid key share; without this the
+// post-quantum public key alone (~1184 bytes) pushes the record past one MSS,
+// and middleboxes do not reassemble fragmented ClientHellos. The handshake
+// error is discarded because the stub conn's Read returns immediately.
+func buildFakeClientHello(sni string) ([]byte, error) {
+ if sni == "" {
+ return nil, E.New("empty sni")
+ }
+ var buf bytes.Buffer
+ tlsConn := tls.Client(bufio.NewWriteOnlyConn(&buf), &tls.Config{
+ ServerName: sni,
+ // Order matches what browsers advertised before post-quantum.
+ CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384},
+ MinVersion: tls.VersionTLS12,
+ MaxVersion: tls.VersionTLS13,
+ NextProtos: []string{"h2", "http/1.1"},
+ InsecureSkipVerify: true,
+ })
+ _ = tlsConn.HandshakeContext(context.Background())
+ if buf.Len() == 0 {
+ return nil, E.New("tls ClientHello not produced")
+ }
+ return buf.Bytes(), nil
+}
diff --git a/common/tlsspoof/client_hello_test.go b/common/tlsspoof/client_hello_test.go
new file mode 100644
index 0000000000..3eb7a2e040
--- /dev/null
+++ b/common/tlsspoof/client_hello_test.go
@@ -0,0 +1,83 @@
+package tlsspoof
+
+import (
+ "bytes"
+ "encoding/binary"
+ "strings"
+ "testing"
+
+ tf "github.com/sagernet/sing-box/common/tlsfragment"
+
+ "github.com/stretchr/testify/require"
+)
+
+// x25519MLKEM768 is the IANA code point for the post-quantum hybrid named
+// group (0x11EC). The fake ClientHello must never carry it — its 1184-byte
+// key share is the reason kernel-generated ClientHellos exceed one MSS, and
+// the reason this builder has to force CurvePreferences.
+const x25519MLKEM768 uint16 = 0x11EC
+
+func TestBuildFakeClientHello_ParsesWithSNI(t *testing.T) {
+ t.Parallel()
+ record, err := buildFakeClientHello("example.com")
+ require.NoError(t, err)
+
+ serverName := tf.IndexTLSServerName(record)
+ require.NotNil(t, serverName, "output must parse as a ClientHello")
+ require.Equal(t, "example.com", serverName.ServerName)
+
+ recordLen := binary.BigEndian.Uint16(record[3:5])
+ require.Equal(t, len(record)-5, int(recordLen),
+ "record length header must match on-wire record size")
+ handshakeLen := int(record[6])<<16 | int(record[7])<<8 | int(record[8])
+ require.Equal(t, len(record)-5-4, handshakeLen,
+ "handshake length header must match handshake body size")
+}
+
+// TestBuildFakeClientHello_FitsOneSegment is the regression guard for the
+// whole point of the rewrite: the fake must never need fragmenting on a
+// standard 1500-byte path MTU. 1200 leaves ~260 bytes for IP+TCP headers and
+// a generous safety margin — the X25519MLKEM768 ClientHello this replaces
+// hit ~1400+.
+func TestBuildFakeClientHello_FitsOneSegment(t *testing.T) {
+ t.Parallel()
+ for _, sni := range []string{"a.io", "example.com", strings.Repeat("a", 253)} {
+ record, err := buildFakeClientHello(sni)
+ require.NoError(t, err, "sni=%q", sni)
+ require.Less(t, len(record), 1200, "sni=%q built %d bytes", sni, len(record))
+ }
+}
+
+// TestBuildFakeClientHello_NoPostQuantumKeyShare catches regressions that
+// would accidentally pull an X25519MLKEM768 key share (the reason the prior
+// implementation had to fragment) back into the fake — e.g. if CurvePreferences
+// stopped being respected by a future Go version.
+func TestBuildFakeClientHello_NoPostQuantumKeyShare(t *testing.T) {
+ t.Parallel()
+ record, err := buildFakeClientHello("example.com")
+ require.NoError(t, err)
+
+ var needle [2]byte
+ binary.BigEndian.PutUint16(needle[:], x25519MLKEM768)
+ require.False(t, bytes.Contains(record, needle[:]),
+ "output must not contain the X25519MLKEM768 code point (0x%04x)", x25519MLKEM768)
+}
+
+// TestBuildFakeClientHello_RandomizesPerCall ensures crypto/tls generates a
+// fresh random + session_id + key_share on every call, as required to avoid
+// trivial fingerprinting of the spoof.
+func TestBuildFakeClientHello_RandomizesPerCall(t *testing.T) {
+ t.Parallel()
+ first, err := buildFakeClientHello("example.com")
+ require.NoError(t, err)
+ second, err := buildFakeClientHello("example.com")
+ require.NoError(t, err)
+ require.NotEqual(t, first, second,
+ "repeated calls must produce distinct bytes (random/session_id/key_share must vary)")
+}
+
+func TestBuildFakeClientHello_RejectsEmpty(t *testing.T) {
+ t.Parallel()
+ _, err := buildFakeClientHello("")
+ require.Error(t, err)
+}
diff --git a/common/tlsspoof/conn_test.go b/common/tlsspoof/conn_test.go
new file mode 100644
index 0000000000..b41cf54753
--- /dev/null
+++ b/common/tlsspoof/conn_test.go
@@ -0,0 +1,369 @@
+package tlsspoof
+
+import (
+ "bytes"
+ "context"
+ "encoding/binary"
+ "encoding/hex"
+ "io"
+ "net"
+ "testing"
+ "time"
+
+ tf "github.com/sagernet/sing-box/common/tlsfragment"
+
+ "github.com/stretchr/testify/require"
+)
+
+// realClientHello is a captured Chrome ClientHello for github.com. Tests that
+// stack tlsspoof.Conn on top of tf.Conn still need a parseable payload to
+// exercise the fragment transform.
+const realClientHello = "16030105f8010005f403036e35de7389a679c54029cf452611f2211c70d9ac3897271de589ab6155f8e4ab20637d225f1ef969ad87ed78bfb9d171300bcb1703b6f314ccefb964f79b7d0961002a0a0a130213031301c02cc02bcca9c030c02fcca8c00ac009c014c013009d009c0035002fc008c012000a01000581baba00000000000f000d00000a6769746875622e636f6d00170000ff01000100000a000e000c3a3a11ec001d001700180019000b000201000010000e000c02683208687474702f312e31000500050100000000000d00160014040308040401050308050805050108060601020100120000003304ef04ed3a3a00010011ec04c0aeb2250c092a3463161cccb29d9183331a424964248579507ed23a180b0ceab2a5f5d9ce41547e497a89055471ea572867ba3a1fc3c9e45025274a20f60c6b60e62476b6afed0403af59ab83660ef4112ae20386a602010d0a5d454c0ed34c84ed4423e750213e6a2baab1bf9c4367a6007ab40a33d95220c2dcaa44f257024a5626b545db0510f4311b1a60714154909c6a61fdfca011fb2626d657aeb6070bf078508babe3b584555013e34acc56198ed4663742b3155a664a9901794c4586820a7dc162c01827291f3792e1237f801a8d1ef096013c181c4a58d2f6859ba75022d18cc4418bd4f351d5c18f83a58857d05af860c4b9ac018a5b63f17184e591532c6bc2cf2215d4a282c8a8a4f6f7aee110422c8bc9ebd3b1d609c568523aaae555db320e6c269473d87af38c256cbb9febc20aea6380c32a8916f7a373c8b1e37554e3260bf6621f6b804ee80b3c516b1d01985bf4c603b6daa9a5991de6a7a29f3a7122b8afb843a7660110fce62b43c615f5bcc2db688ba012649c0952b0a2c031e732d2b454c6b2968683cb8d244be2c9a7fa163222979eaf92722b92b862d81a3d94450c2b60c318421ebb4307c42d1f0473592a5c30e42039cc68cda9721e61aa63f49def17c15221680ed444896340133bbee67556f56b9f9d78a4df715f926a12add0cc9c862e46ea8b7316ae468282c18601b2771c9c9322f982228cf93effaacd3f80cbd12bce5fc36f56e2a3caf91e578a5fae00c9b23a8ed1a66764f4433c3628a70b8f0a6196adc60a4cb4226f07ba4c6b363fe9065563bfc1347452946386bab488686e837ab979c64f9047417fca635fe1bb4f074f256cc8af837c7b455e280426547755af90a61640169ef180aea3a77e662bb6dac1b6c3696027129b1a5edf495314e9c7f4b6110e16378ec893fa24642330a40aba1a85326101acb97c620fd8d71389e69eaed7bdb01bbe1fd428d66191150c7b2cd1ad4257391676a82ba8ce07fb2667c3b289f159003a7c7bc31d361b7b7f49a802961739d950dfcc0fa1c7abce5abdd2245101da391151490862028110465950b9e9c03d08a90998ab83267838d2e74a0593bc81f74cdf734519a05b351c0e5488c68dd810e6e9142ccc1e2f4a7f464297eb340e27acc6b9d64e12e38cce8492b3d939140b5a9e149a75597f10a23874c84323a07cdd657274378f887c85c4259b9c04cd33ba58ed630ef2a744f8e19dd34843dff331d2a6be7e2332c599289cd248a611c73d7481cd4a9bd43449a3836f14b2af18a1739e17999e4c67e85cc5bcecabb14185e5bcaff3c96098f03dc5aba819f29587758f49f940585354a2a780830528d68ccd166920dadcaa25cab5fc1907272a826aba3f08bc6b88757776812ecb6c7cec69a223ec0a13a7b62a2349a0f63ed7a27a3b15ba21d71fe6864ec6e089ae17cadd433fa3138f7ee24353c11365818f8fc34f43a05542d18efaac24bfccc1f748a0cc1a67ad379468b76fd34973dba785f5c91d618333cd810fe0700d1bbc8422029782628070a624c52c5309a4a64d625b11f8033ab28df34a1add297517fcc06b92b6817b3c5144438cf260867c57bde68c8c4b82e6a135ef676a52fbae5708002a404e6189a60e2836de565ad1b29e3819e5ed49f6810bcb28e1bd6de57306f94b79d9dae1cc4624d2a068499beef81cd5fe4b76dcbfff2a2008001d002001976128c6d5a934533f28b9914d2480aab2a8c1ab03d212529ce8b27640a716002d00020101002b000706caca03040303001b00030200015a5a000100"
+
+func decodeClientHello(t *testing.T) []byte {
+ t.Helper()
+ payload, err := hex.DecodeString(realClientHello)
+ require.NoError(t, err)
+ return payload
+}
+
+type fakeSpoofer struct {
+ injected [][]byte
+ err error
+ closeErr error
+}
+
+func (f *fakeSpoofer) Inject(payload []byte) error {
+ if f.err != nil {
+ return f.err
+ }
+ f.injected = append(f.injected, append([]byte(nil), payload...))
+ return nil
+}
+
+func (f *fakeSpoofer) Close() error {
+ return f.closeErr
+}
+
+func readAll(t *testing.T, conn net.Conn) []byte {
+ t.Helper()
+ data, err := io.ReadAll(conn)
+ require.NoError(t, err)
+ return data
+}
+
+func TestConn_Write_InjectsThenForwards(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ spoofer := &fakeSpoofer{}
+ wrapped, err := newConn(client, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() {
+ serverRead <- readAll(t, server)
+ }()
+
+ n, err := wrapped.Write(payload)
+ require.NoError(t, err)
+ require.Equal(t, len(payload), n)
+ require.NoError(t, wrapped.Close())
+
+ forwarded := <-serverRead
+ require.Equal(t, payload, forwarded, "underlying conn must receive the real ClientHello unchanged")
+ require.Len(t, spoofer.injected, 1)
+
+ injected := spoofer.injected[0]
+ serverName := tf.IndexTLSServerName(injected)
+ require.NotNil(t, serverName, "injected payload must parse as ClientHello")
+ require.Equal(t, "letsencrypt.org", serverName.ServerName)
+}
+
+func TestConn_Write_SecondWriteDoesNotInject(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ spoofer := &fakeSpoofer{}
+ wrapped, err := newConn(client, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() {
+ serverRead <- readAll(t, server)
+ }()
+
+ _, err = wrapped.Write(payload)
+ require.NoError(t, err)
+ _, err = wrapped.Write([]byte("second"))
+ require.NoError(t, err)
+ require.NoError(t, wrapped.Close())
+
+ forwarded := <-serverRead
+ require.Equal(t, append(append([]byte(nil), payload...), []byte("second")...), forwarded)
+ require.Len(t, spoofer.injected, 1)
+}
+
+// TestConn_Write_SurfacesCloseError guards against the defer pattern silently
+// dropping the spoofer's Close() error on the success path.
+func TestConn_Write_SurfacesCloseError(t *testing.T) {
+ t.Parallel()
+
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ spoofer := &fakeSpoofer{closeErr: errSpoofClose}
+ wrapped, err := newConn(client, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ go func() { _, _ = io.ReadAll(server) }()
+
+ _, err = wrapped.Write([]byte("trigger inject"))
+ require.ErrorIs(t, err, errSpoofClose,
+ "Close() error must be wrapped into Write's return")
+}
+
+func TestConn_NewConn_RejectsEmptySNI(t *testing.T) {
+ t.Parallel()
+ client, server := net.Pipe()
+ defer client.Close()
+ defer server.Close()
+ _, err := newConn(client, &fakeSpoofer{}, "")
+ require.Error(t, err, "empty SNI must fail at construction")
+}
+
+var errSpoofClose = errTest("spoof-close-failed")
+
+type errTest string
+
+func (e errTest) Error() string { return string(e) }
+
+// recordingConn intercepts each Write call so tests can assert how many
+// downstream writes occurred and in what order with respect to spoof
+// injection. It does not implement WithUpstream, so tf.Conn's
+// N.UnwrapReader(conn).(*net.TCPConn) returns nil and fragment-mode falls
+// back to its plain Write + time.Sleep path — which is what we want to
+// exercise over a net.Pipe.
+type recordingConn struct {
+ net.Conn
+ writes [][]byte
+ timeline *[]string
+}
+
+func (c *recordingConn) Write(p []byte) (int, error) {
+ c.writes = append(c.writes, append([]byte(nil), p...))
+ if c.timeline != nil {
+ *c.timeline = append(*c.timeline, "write")
+ }
+ return c.Conn.Write(p)
+}
+
+type tlsRecord struct {
+ contentType byte
+ payload []byte
+}
+
+func parseTLSRecords(t *testing.T, data []byte) []tlsRecord {
+ t.Helper()
+ var records []tlsRecord
+ for len(data) > 0 {
+ require.GreaterOrEqual(t, len(data), 5, "record header incomplete")
+ recordLen := int(binary.BigEndian.Uint16(data[3:5]))
+ require.GreaterOrEqual(t, len(data), 5+recordLen, "record payload truncated")
+ records = append(records, tlsRecord{
+ contentType: data[0],
+ payload: append([]byte(nil), data[5:5+recordLen]...),
+ })
+ data = data[5+recordLen:]
+ }
+ return records
+}
+
+// TestConn_StackedWithRecordFragment mirrors the wrapping order that
+// STDClientConfig.Client() produces when record_fragment is enabled:
+// tls.Client → tlsspoof.Conn → tf.Conn → raw conn.
+// Asserts the decoy is injected and the real handshake arrives split into
+// multiple TLS records whose payloads reassemble to the original.
+func TestConn_StackedWithRecordFragment(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ defer server.Close()
+
+ fragConn := tf.NewConn(client, context.Background(), false, true, time.Millisecond)
+ spoofer := &fakeSpoofer{}
+ wrapped, err := newConn(fragConn, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() { serverRead <- readAll(t, server) }()
+
+ _, err = wrapped.Write(payload)
+ require.NoError(t, err)
+ require.NoError(t, wrapped.Close())
+ forwarded := <-serverRead
+
+ require.Len(t, spoofer.injected, 1, "spoof must inject exactly once")
+ injected := tf.IndexTLSServerName(spoofer.injected[0])
+ require.NotNil(t, injected, "injected payload must parse as ClientHello")
+ require.Equal(t, "letsencrypt.org", injected.ServerName)
+
+ records := parseTLSRecords(t, forwarded)
+ require.Greater(t, len(records), 1, "record_fragment must produce multiple records")
+ var reassembled []byte
+ for _, r := range records {
+ require.Equal(t, byte(0x16), r.contentType, "all records must be handshake")
+ reassembled = append(reassembled, r.payload...)
+ }
+ require.Equal(t, payload[5:], reassembled, "record payloads must reassemble to original handshake")
+}
+
+// TestConn_StackedWithPacketFragment is the primary regression test for the
+// fragment-only gate fix in STDClientConfig.Client(). It verifies that
+// packet-level fragmentation combined with spoof produces:
+// - one spoof injection carrying the decoy SNI,
+// - multiple separate writes to the underlying conn,
+// - an unmodified byte stream when those writes are concatenated
+// (no extra record framing).
+func TestConn_StackedWithPacketFragment(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ defer server.Close()
+
+ rc := &recordingConn{Conn: client}
+ fragConn := tf.NewConn(rc, context.Background(), true, false, time.Millisecond)
+ spoofer := &fakeSpoofer{}
+ wrapped, err := newConn(fragConn, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() { serverRead <- readAll(t, server) }()
+
+ _, err = wrapped.Write(payload)
+ require.NoError(t, err)
+ require.NoError(t, wrapped.Close())
+ forwarded := <-serverRead
+
+ require.Len(t, spoofer.injected, 1, "spoof must inject exactly once")
+ injected := tf.IndexTLSServerName(spoofer.injected[0])
+ require.NotNil(t, injected)
+ require.Equal(t, "letsencrypt.org", injected.ServerName)
+
+ require.Greater(t, len(rc.writes), 1, "fragment must split the ClientHello into multiple writes")
+ require.Equal(t, payload, bytes.Join(rc.writes, nil),
+ "concatenated writes must equal original bytes (no extra framing)")
+ require.Equal(t, payload, forwarded)
+}
+
+// TestConn_StackedWithBothFragment exercises the combination that produces
+// the strongest obfuscation: each chunk becomes its own TLS record and its
+// own TCP write.
+func TestConn_StackedWithBothFragment(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ defer server.Close()
+
+ rc := &recordingConn{Conn: client}
+ fragConn := tf.NewConn(rc, context.Background(), true, true, time.Millisecond)
+ spoofer := &fakeSpoofer{}
+ wrapped, err := newConn(fragConn, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() { serverRead <- readAll(t, server) }()
+
+ _, err = wrapped.Write(payload)
+ require.NoError(t, err)
+ require.NoError(t, wrapped.Close())
+ forwarded := <-serverRead
+
+ require.Len(t, spoofer.injected, 1)
+ injected := tf.IndexTLSServerName(spoofer.injected[0])
+ require.NotNil(t, injected)
+ require.Equal(t, "letsencrypt.org", injected.ServerName)
+
+ require.Greater(t, len(rc.writes), 1, "split-packet must produce multiple writes")
+ records := parseTLSRecords(t, forwarded)
+ require.Greater(t, len(records), 1, "split-record must produce multiple records")
+ var reassembled []byte
+ for _, r := range records {
+ require.Equal(t, byte(0x16), r.contentType)
+ reassembled = append(reassembled, r.payload...)
+ }
+ require.Equal(t, payload[5:], reassembled,
+ "record payloads must reassemble to the original handshake")
+}
+
+// trackingSpoofer adds the spoof injection to a shared event timeline so
+// TestConn_StackedInjectionOrder can prove the decoy precedes the first
+// downstream write.
+type trackingSpoofer struct {
+ injected [][]byte
+ timeline *[]string
+}
+
+func (s *trackingSpoofer) Inject(payload []byte) error {
+ s.injected = append(s.injected, append([]byte(nil), payload...))
+ *s.timeline = append(*s.timeline, "inject")
+ return nil
+}
+
+func (s *trackingSpoofer) Close() error { return nil }
+
+// TestConn_StackedInjectionOrder asserts the documented wire order: the
+// decoy injection happens before any write reaches the underlying conn.
+func TestConn_StackedInjectionOrder(t *testing.T) {
+ t.Parallel()
+ payload := decodeClientHello(t)
+
+ client, server := net.Pipe()
+ defer server.Close()
+
+ var timeline []string
+ rc := &recordingConn{Conn: client, timeline: &timeline}
+ fragConn := tf.NewConn(rc, context.Background(), true, true, time.Millisecond)
+ spoofer := &trackingSpoofer{timeline: &timeline}
+ wrapped, err := newConn(fragConn, spoofer, "letsencrypt.org")
+ require.NoError(t, err)
+
+ serverRead := make(chan []byte, 1)
+ go func() { serverRead <- readAll(t, server) }()
+
+ _, err = wrapped.Write(payload)
+ require.NoError(t, err)
+ require.NoError(t, wrapped.Close())
+ <-serverRead
+
+ require.NotEmpty(t, timeline)
+ require.Equal(t, "inject", timeline[0], "decoy must be injected before any downstream write")
+ require.Contains(t, timeline[1:], "write", "at least one downstream write must follow the inject")
+}
+
+func TestParseMethod(t *testing.T) {
+ t.Parallel()
+ cases := map[string]struct {
+ want Method
+ ok bool
+ }{
+ "": {MethodWrongSequence, true},
+ "wrong-sequence": {MethodWrongSequence, true},
+ "wrong-checksum": {MethodWrongChecksum, true},
+ "nonsense": {0, false},
+ }
+ for input, expected := range cases {
+ m, err := ParseMethod(input)
+ if !expected.ok {
+ require.Error(t, err, "input=%q", input)
+ continue
+ }
+ require.NoError(t, err, "input=%q", input)
+ require.Equal(t, expected.want, m, "input=%q", input)
+ }
+}
diff --git a/common/tlsspoof/endpoints.go b/common/tlsspoof/endpoints.go
new file mode 100644
index 0000000000..2cc8df1225
--- /dev/null
+++ b/common/tlsspoof/endpoints.go
@@ -0,0 +1,31 @@
+//go:build linux || darwin || (windows && (amd64 || 386))
+
+package tlsspoof
+
+import (
+ "net"
+ "net/netip"
+
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+)
+
+// The returned addresses are v4-unmapped and share the same family.
+func tcpEndpoints(conn net.Conn) (*net.TCPConn, netip.AddrPort, netip.AddrPort, error) {
+ tcpConn, isTCP := common.Cast[*net.TCPConn](conn)
+ if !isTCP {
+ return nil, netip.AddrPort{}, netip.AddrPort{}, E.New("tls_spoof: underlying conn is not *net.TCPConn")
+ }
+ local := M.AddrPortFromNet(tcpConn.LocalAddr())
+ remote := M.AddrPortFromNet(tcpConn.RemoteAddr())
+ if !local.IsValid() || !remote.IsValid() {
+ return nil, netip.AddrPort{}, netip.AddrPort{}, E.New("tls_spoof: invalid conn address")
+ }
+ local = netip.AddrPortFrom(local.Addr().Unmap(), local.Port())
+ remote = netip.AddrPortFrom(remote.Addr().Unmap(), remote.Port())
+ if local.Addr().Is4() != remote.Addr().Is4() {
+ return nil, netip.AddrPort{}, netip.AddrPort{}, E.New("tls_spoof: local/remote address family mismatch")
+ }
+ return tcpConn, local, remote, nil
+}
diff --git a/common/tlsspoof/integration_darwin_test.go b/common/tlsspoof/integration_darwin_test.go
new file mode 100644
index 0000000000..60a933e5f9
--- /dev/null
+++ b/common/tlsspoof/integration_darwin_test.go
@@ -0,0 +1,5 @@
+//go:build darwin
+
+package tlsspoof
+
+const loopbackInterface = "lo0"
diff --git a/common/tlsspoof/integration_linux_test.go b/common/tlsspoof/integration_linux_test.go
new file mode 100644
index 0000000000..3294c272e5
--- /dev/null
+++ b/common/tlsspoof/integration_linux_test.go
@@ -0,0 +1,5 @@
+//go:build linux
+
+package tlsspoof
+
+const loopbackInterface = "lo"
diff --git a/common/tlsspoof/integration_test.go b/common/tlsspoof/integration_test.go
new file mode 100644
index 0000000000..23a83ff174
--- /dev/null
+++ b/common/tlsspoof/integration_test.go
@@ -0,0 +1,141 @@
+//go:build linux || darwin
+
+package tlsspoof
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "os/exec"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+)
+
+func requireRoot(t *testing.T) {
+ t.Helper()
+ if os.Geteuid() != 0 {
+ t.Skip("integration test requires root; re-run with `go test -exec sudo`")
+ }
+}
+
+func tcpdumpObserver(t *testing.T, iface string, port uint16, needle string, do func(), wait time.Duration) bool {
+ t.Helper()
+ return tcpdumpObserverMulti(t, iface, port, []string{needle}, do, wait)[needle]
+}
+
+// tcpdumpObserverMulti captures tcpdump output while do() executes and reports
+// which of the provided needles were observed in the raw ASCII dump. Use this
+// to assert that distinct payloads (e.g. fake vs real ClientHello) are both on
+// the wire.
+func tcpdumpObserverMulti(t *testing.T, iface string, port uint16, needles []string, do func(), wait time.Duration) map[string]bool {
+ t.Helper()
+ ctx, cancel := context.WithTimeout(context.Background(), wait)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, "tcpdump", "-i", iface, "-n", "-A", "-l",
+ "-s", "4096", fmt.Sprintf("tcp and port %d", port))
+ cmd.Cancel = func() error {
+ return cmd.Process.Signal(os.Interrupt)
+ }
+ stdout, err := cmd.StdoutPipe()
+ require.NoError(t, err)
+ stderr, err := cmd.StderrPipe()
+ require.NoError(t, err)
+ require.NoError(t, cmd.Start())
+ t.Cleanup(func() {
+ _ = cmd.Process.Signal(os.Interrupt)
+ _ = cmd.Wait()
+ })
+
+ ready := make(chan struct{})
+ go func() {
+ scanner := bufio.NewScanner(stderr)
+ for scanner.Scan() {
+ if strings.Contains(scanner.Text(), "listening on") {
+ close(ready)
+ io.Copy(io.Discard, stderr)
+ return
+ }
+ }
+ }()
+
+ select {
+ case <-ready:
+ case <-time.After(2 * time.Second):
+ t.Fatal("tcpdump did not attach within 2s")
+ }
+
+ var access sync.Mutex
+ found := make(map[string]bool, len(needles))
+ readerDone := make(chan struct{})
+ go func() {
+ defer close(readerDone)
+ scanner := bufio.NewScanner(stdout)
+ scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024)
+ for scanner.Scan() {
+ line := scanner.Text()
+ access.Lock()
+ for _, needle := range needles {
+ if !found[needle] && strings.Contains(line, needle) {
+ found[needle] = true
+ }
+ }
+ access.Unlock()
+ }
+ }()
+
+ do()
+
+ time.Sleep(200 * time.Millisecond)
+ _ = cmd.Process.Signal(os.Interrupt)
+ <-readerDone
+ access.Lock()
+ defer access.Unlock()
+ result := make(map[string]bool, len(needles))
+ for _, needle := range needles {
+ result[needle] = found[needle]
+ }
+ return result
+}
+
+func dialLocalEchoServer(t *testing.T) (client net.Conn, serverPort uint16) {
+ return dialLocalEchoServerFamily(t, "tcp4", "127.0.0.1:0")
+}
+
+func dialLocalEchoServerIPv6(t *testing.T) (client net.Conn, serverPort uint16) {
+ return dialLocalEchoServerFamily(t, "tcp6", "[::1]:0")
+}
+
+func dialLocalEchoServerFamily(t *testing.T, network, address string) (client net.Conn, serverPort uint16) {
+ t.Helper()
+ listener, err := net.Listen(network, address)
+ require.NoError(t, err)
+
+ accepted := make(chan net.Conn, 1)
+ go func() {
+ c, err := listener.Accept()
+ if err == nil {
+ accepted <- c
+ }
+ close(accepted)
+ }()
+ addr := listener.Addr().(*net.TCPAddr)
+ client, err = net.Dial(network, addr.String())
+ require.NoError(t, err)
+ server := <-accepted
+ require.NotNil(t, server)
+
+ go io.Copy(io.Discard, server)
+ t.Cleanup(func() {
+ client.Close()
+ server.Close()
+ listener.Close()
+ })
+ return client, uint16(addr.Port)
+}
diff --git a/common/tlsspoof/integration_tls_test.go b/common/tlsspoof/integration_tls_test.go
new file mode 100644
index 0000000000..d179c3841c
--- /dev/null
+++ b/common/tlsspoof/integration_tls_test.go
@@ -0,0 +1,118 @@
+//go:build linux || darwin
+
+package tlsspoof
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/tls"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
+ "io"
+ "math/big"
+ "net"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+)
+
+// generateSelfSignedCert returns a TLS certificate valid for the given SAN.
+func generateSelfSignedCert(t *testing.T, commonName string, sans ...string) tls.Certificate {
+ t.Helper()
+ priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ require.NoError(t, err)
+ serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
+ require.NoError(t, err)
+ template := x509.Certificate{
+ SerialNumber: serial,
+ Subject: pkix.Name{CommonName: commonName},
+ NotBefore: time.Now().Add(-time.Hour),
+ NotAfter: time.Now().Add(time.Hour),
+ KeyUsage: x509.KeyUsageDigitalSignature,
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+ DNSNames: sans,
+ }
+ der, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
+ require.NoError(t, err)
+ certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der})
+ keyDER, err := x509.MarshalPKCS8PrivateKey(priv)
+ require.NoError(t, err)
+ keyPEM := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: keyDER})
+ cert, err := tls.X509KeyPair(certPEM, keyPEM)
+ require.NoError(t, err)
+ return cert
+}
+
+// TestIntegrationConn_RealTLSHandshake drives a real crypto/tls ClientHello
+// through the spoofer and asserts the on-wire fake packet carries the fake SNI
+// while the server receives the real SNI. This exercises the full
+// `tls.Client(wrapped, config).Handshake()` path rather than a static hex
+// payload, matching what user-facing code hits.
+func TestIntegrationConn_RealTLSHandshake(t *testing.T) {
+ requireRoot(t)
+ const realSNI = "real.test"
+ const fakeSNI = "fake.test"
+
+ serverCert := generateSelfSignedCert(t, realSNI, realSNI)
+ tlsConfig := &tls.Config{Certificates: []tls.Certificate{serverCert}}
+
+ listener, err := tls.Listen("tcp4", "127.0.0.1:0", tlsConfig)
+ require.NoError(t, err)
+ t.Cleanup(func() { listener.Close() })
+
+ serverSNI := make(chan string, 1)
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ return
+ }
+ defer conn.Close()
+ tlsConn := conn.(*tls.Conn)
+ _ = tlsConn.SetDeadline(time.Now().Add(3 * time.Second))
+ if handshakeErr := tlsConn.Handshake(); handshakeErr != nil {
+ serverSNI <- "handshake-error:" + handshakeErr.Error()
+ return
+ }
+ serverSNI <- tlsConn.ConnectionState().ServerName
+ _, _ = io.Copy(io.Discard, conn)
+ }()
+
+ addr := listener.Addr().(*net.TCPAddr)
+ serverPort := uint16(addr.Port)
+ raw, err := net.Dial("tcp4", addr.String())
+ require.NoError(t, err)
+ t.Cleanup(func() { raw.Close() })
+
+ wrapped, err := NewConn(raw, MethodWrongSequence, fakeSNI)
+ require.NoError(t, err)
+
+ clientConfig := &tls.Config{
+ ServerName: realSNI,
+ InsecureSkipVerify: true,
+ }
+ tlsClient := tls.Client(wrapped, clientConfig)
+ t.Cleanup(func() { tlsClient.Close() })
+
+ seen := tcpdumpObserverMulti(t, loopbackInterface, serverPort,
+ []string{realSNI, fakeSNI}, func() {
+ _ = tlsClient.SetDeadline(time.Now().Add(3 * time.Second))
+ err := tlsClient.Handshake()
+ require.NoError(t, err, "TLS handshake must succeed (wrong-sequence fake is dropped by peer)")
+ }, 4*time.Second)
+
+ require.True(t, seen[realSNI],
+ "real ClientHello on the wire must contain original SNI %q", realSNI)
+ require.True(t, seen[fakeSNI],
+ "fake ClientHello on the wire must contain fake SNI %q", fakeSNI)
+
+ select {
+ case sniOnServer := <-serverSNI:
+ require.Equal(t, realSNI, sniOnServer,
+ "TLS server must see the real SNI (fake packet dropped by peer TCP stack)")
+ case <-time.After(3 * time.Second):
+ t.Fatal("TLS server did not complete handshake")
+ }
+}
diff --git a/common/tlsspoof/integration_unix_test.go b/common/tlsspoof/integration_unix_test.go
new file mode 100644
index 0000000000..6b262ff71b
--- /dev/null
+++ b/common/tlsspoof/integration_unix_test.go
@@ -0,0 +1,185 @@
+//go:build linux || darwin
+
+package tlsspoof
+
+import (
+ "encoding/hex"
+ "io"
+ "net"
+ "runtime"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestIntegrationSpoofer(t *testing.T) {
+ requireRoot(t)
+ methods := []struct {
+ name string
+ method Method
+ }{
+ {"WrongChecksum", MethodWrongChecksum},
+ {"WrongSequence", MethodWrongSequence},
+ {"WrongAcknowledgment", MethodWrongAcknowledgment},
+ {"WrongMD5Sig", MethodWrongMD5Sig},
+ {"WrongTimestamp", MethodWrongTimestamp},
+ }
+ families := []struct {
+ name string
+ dial func(*testing.T) (net.Conn, uint16)
+ }{
+ {"IPv4", dialLocalEchoServer},
+ {"IPv6", dialLocalEchoServerIPv6},
+ }
+ for _, family := range families {
+ for _, tc := range methods {
+ t.Run(family.name+"/"+tc.name, func(t *testing.T) {
+ if tc.method == MethodWrongTimestamp && runtime.GOOS == "darwin" {
+ t.Skip("wrong-timestamp is not supported on macOS")
+ }
+ client, serverPort := family.dial(t)
+ spoofer, err := newRawSpoofer(client, tc.method)
+ require.NoError(t, err)
+ defer spoofer.Close()
+
+ fake, err := buildFakeClientHello("letsencrypt.org")
+ require.NoError(t, err)
+
+ captured := tcpdumpObserver(t, loopbackInterface, serverPort, "letsencrypt.org", func() {
+ require.NoError(t, spoofer.Inject(fake))
+ }, 3*time.Second)
+ require.True(t, captured, "injected fake ClientHello must be observable on loopback")
+ })
+ }
+ }
+}
+
+// Loopback bypasses TCP checksum validation, so wrong-sequence is used instead.
+func TestIntegrationConn_InjectsThenForwardsRealCH(t *testing.T) {
+ requireRoot(t)
+ runInjectsThenForwardsRealCH(t, "tcp4", "127.0.0.1:0")
+}
+
+func TestIntegrationConn_IPv6_InjectsThenForwardsRealCH(t *testing.T) {
+ requireRoot(t)
+ runInjectsThenForwardsRealCH(t, "tcp6", "[::1]:0")
+}
+
+// TestIntegrationConn_FakeAndRealHaveDistinctSNIs asserts that the on-wire fake
+// packet carries the fake SNI (letsencrypt.org) AND the real packet still
+// carries the original SNI (github.com). If the builder regresses to producing
+// empty or mismatched bytes, the fake-SNI needle will be missing.
+func TestIntegrationConn_FakeAndRealHaveDistinctSNIs(t *testing.T) {
+ requireRoot(t)
+ runFakeAndRealHaveDistinctSNIs(t, "tcp4", "127.0.0.1:0", "letsencrypt.org")
+}
+
+func TestIntegrationConn_IPv6_FakeAndRealHaveDistinctSNIs(t *testing.T) {
+ requireRoot(t)
+ runFakeAndRealHaveDistinctSNIs(t, "tcp6", "[::1]:0", "letsencrypt.org")
+}
+
+func runFakeAndRealHaveDistinctSNIs(t *testing.T, network, address, fakeSNI string) {
+ t.Helper()
+ const originalSNI = "github.com"
+ require.NotEqual(t, originalSNI, fakeSNI)
+
+ listener, err := net.Listen(network, address)
+ require.NoError(t, err)
+
+ serverReceived := make(chan []byte, 1)
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ return
+ }
+ defer conn.Close()
+ _ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
+ got, _ := io.ReadAll(conn)
+ serverReceived <- got
+ }()
+
+ addr := listener.Addr().(*net.TCPAddr)
+ serverPort := uint16(addr.Port)
+ client, err := net.Dial(network, addr.String())
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ client.Close()
+ listener.Close()
+ })
+
+ wrapped, err := NewConn(client, MethodWrongSequence, fakeSNI)
+ require.NoError(t, err)
+
+ payload, err := hex.DecodeString(realClientHello)
+ require.NoError(t, err)
+
+ seen := tcpdumpObserverMulti(t, loopbackInterface, serverPort,
+ []string{originalSNI, fakeSNI}, func() {
+ n, err := wrapped.Write(payload)
+ require.NoError(t, err)
+ require.Equal(t, len(payload), n)
+ }, 3*time.Second)
+ require.True(t, seen[originalSNI],
+ "real ClientHello must carry original SNI %q on the wire", originalSNI)
+ require.True(t, seen[fakeSNI],
+ "fake ClientHello must carry fake SNI %q on the wire", fakeSNI)
+
+ _ = wrapped.Close()
+ select {
+ case got := <-serverReceived:
+ require.Equal(t, payload, got,
+ "server must receive real ClientHello unchanged (wrong-sequence fake must be dropped)")
+ case <-time.After(2 * time.Second):
+ t.Fatal("echo server did not receive real ClientHello")
+ }
+}
+
+func runInjectsThenForwardsRealCH(t *testing.T, network, address string) {
+ t.Helper()
+ listener, err := net.Listen(network, address)
+ require.NoError(t, err)
+
+ serverReceived := make(chan []byte, 1)
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ return
+ }
+ defer conn.Close()
+ _ = conn.SetReadDeadline(time.Now().Add(2 * time.Second))
+ got, _ := io.ReadAll(conn)
+ serverReceived <- got
+ }()
+
+ addr := listener.Addr().(*net.TCPAddr)
+ serverPort := uint16(addr.Port)
+ client, err := net.Dial(network, addr.String())
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ client.Close()
+ listener.Close()
+ })
+
+ wrapped, err := NewConn(client, MethodWrongSequence, "letsencrypt.org")
+ require.NoError(t, err)
+
+ payload, err := hex.DecodeString(realClientHello)
+ require.NoError(t, err)
+
+ captured := tcpdumpObserver(t, loopbackInterface, serverPort, "letsencrypt.org", func() {
+ n, err := wrapped.Write(payload)
+ require.NoError(t, err)
+ require.Equal(t, len(payload), n)
+ }, 3*time.Second)
+ require.True(t, captured, "fake ClientHello with letsencrypt.org SNI must be on the wire")
+
+ _ = wrapped.Close()
+ select {
+ case got := <-serverReceived:
+ require.Equal(t, payload, got, "server must receive real ClientHello unchanged (wrong-sequence fake must be dropped)")
+ case <-time.After(2 * time.Second):
+ t.Fatal("echo server did not receive real ClientHello")
+ }
+}
diff --git a/common/tlsspoof/integration_windows_test.go b/common/tlsspoof/integration_windows_test.go
new file mode 100644
index 0000000000..b0461a31b2
--- /dev/null
+++ b/common/tlsspoof/integration_windows_test.go
@@ -0,0 +1,138 @@
+//go:build windows && (amd64 || 386)
+
+package tlsspoof
+
+import (
+ "encoding/hex"
+ "io"
+ "net"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+)
+
+func newSpoofer(t *testing.T, conn net.Conn, method Method) rawSpoofer {
+ t.Helper()
+ s, err := newRawSpoofer(conn, method)
+ require.NoError(t, err)
+ return s
+}
+
+// Basic lifecycle: opening a spoofer against a live TCP conn installs
+// the driver, spawns run(), then shuts down cleanly without ever
+// injecting. Exercises the close path that cancels an in-flight Recv.
+func TestIntegrationSpooferOpenClose(t *testing.T) {
+ listener, err := net.Listen("tcp4", "127.0.0.1:0")
+ require.NoError(t, err)
+ t.Cleanup(func() { listener.Close() })
+
+ accepted := make(chan net.Conn, 1)
+ go func() {
+ c, _ := listener.Accept()
+ accepted <- c
+ }()
+ client, err := net.Dial("tcp4", listener.Addr().String())
+ require.NoError(t, err)
+ t.Cleanup(func() { client.Close() })
+ server := <-accepted
+ t.Cleanup(func() {
+ if server != nil {
+ server.Close()
+ }
+ })
+
+ spoofer := newSpoofer(t, client, MethodWrongSequence)
+ require.NoError(t, spoofer.Close())
+}
+
+// End-to-end: Conn.Write injects a fake ClientHello with a fresh SNI, then
+// forwards the real ClientHello. With wrong-sequence, the fake lands before
+// the connection's send-next sequence — the peer TCP stack treats it as
+// already-received and only surfaces the real bytes to the echo server.
+func TestIntegrationConnInjectsThenForwardsRealCH(t *testing.T) {
+ listener, err := net.Listen("tcp4", "127.0.0.1:0")
+ require.NoError(t, err)
+ t.Cleanup(func() { listener.Close() })
+
+ serverReceived := make(chan []byte, 1)
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+ _ = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
+ got, _ := io.ReadAll(conn)
+ serverReceived <- got
+ }()
+
+ client, err := net.Dial("tcp4", listener.Addr().String())
+ require.NoError(t, err)
+ t.Cleanup(func() { client.Close() })
+
+ wrapped, err := NewConn(client, MethodWrongSequence, "letsencrypt.org")
+ require.NoError(t, err)
+
+ payload, err := hex.DecodeString(realClientHello)
+ require.NoError(t, err)
+
+ n, err := wrapped.Write(payload)
+ require.NoError(t, err)
+ require.Equal(t, len(payload), n)
+ _ = wrapped.Close()
+
+ select {
+ case got := <-serverReceived:
+ require.Equal(t, payload, got,
+ "server must receive real ClientHello unchanged (wrong-sequence fake must be dropped)")
+ case <-time.After(5 * time.Second):
+ t.Fatal("echo server did not receive real ClientHello within 5s")
+ }
+}
+
+// Inject before any kernel payload: stages the fake, then Write flushes
+// the real CH. Same terminal expectation as the Conn variant but via the
+// raw spoofer primitive directly.
+func TestIntegrationSpooferInjectThenWrite(t *testing.T) {
+ listener, err := net.Listen("tcp4", "127.0.0.1:0")
+ require.NoError(t, err)
+ t.Cleanup(func() { listener.Close() })
+
+ serverReceived := make(chan []byte, 1)
+ go func() {
+ conn, acceptErr := listener.Accept()
+ if acceptErr != nil {
+ return
+ }
+ defer conn.Close()
+ _ = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
+ got, _ := io.ReadAll(conn)
+ serverReceived <- got
+ }()
+
+ client, err := net.Dial("tcp4", listener.Addr().String())
+ require.NoError(t, err)
+ t.Cleanup(func() { client.Close() })
+
+ spoofer := newSpoofer(t, client, MethodWrongSequence)
+ t.Cleanup(func() { spoofer.Close() })
+
+ fake, err := buildFakeClientHello("letsencrypt.org")
+ require.NoError(t, err)
+ require.NoError(t, spoofer.Inject(fake))
+
+ payload, err := hex.DecodeString(realClientHello)
+ require.NoError(t, err)
+ n, err := client.Write(payload)
+ require.NoError(t, err)
+ require.Equal(t, len(payload), n)
+ _ = client.Close()
+
+ select {
+ case got := <-serverReceived:
+ require.Equal(t, payload, got)
+ case <-time.After(5 * time.Second):
+ t.Fatal("echo server did not receive real ClientHello within 5s")
+ }
+}
diff --git a/common/tlsspoof/packet.go b/common/tlsspoof/packet.go
new file mode 100644
index 0000000000..2b0210c070
--- /dev/null
+++ b/common/tlsspoof/packet.go
@@ -0,0 +1,177 @@
+//go:build linux || darwin || (windows && (amd64 || 386))
+
+package tlsspoof
+
+import (
+ "encoding/binary"
+ "net/netip"
+
+ "github.com/sagernet/sing-tun/gtcpip/checksum"
+ "github.com/sagernet/sing-tun/gtcpip/header"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+const (
+ defaultTTL uint8 = 64
+ defaultWindowSize uint16 = 0xFFFF
+ tcpHeaderLen = header.TCPMinimumSize
+
+ tcpOptionMD5Signature = 19
+ tcpOptionMD5SignatureLength = 18
+ tcpTimestampBackdate = 3600000
+)
+
+type spoofPacketInfo struct {
+ seqNum uint32
+ ackNum uint32
+ corrupt bool
+ options []byte
+}
+
+func buildTCPSegment(
+ src netip.AddrPort,
+ dst netip.AddrPort,
+ packetInfo spoofPacketInfo,
+ payload []byte,
+) []byte {
+ if src.Addr().Is4() != dst.Addr().Is4() {
+ panic("tlsspoof: mixed IPv4/IPv6 address family")
+ }
+ var (
+ frame []byte
+ ipHeaderLen int
+ )
+ ipPayloadLen := tcpHeaderLen + len(packetInfo.options) + len(payload)
+ if src.Addr().Is4() {
+ ipHeaderLen = header.IPv4MinimumSize
+ frame = make([]byte, ipHeaderLen+ipPayloadLen)
+ ip := header.IPv4(frame[:ipHeaderLen])
+ ip.Encode(&header.IPv4Fields{
+ TotalLength: uint16(len(frame)),
+ ID: 0,
+ TTL: defaultTTL,
+ Protocol: uint8(header.TCPProtocolNumber),
+ SrcAddr: src.Addr(),
+ DstAddr: dst.Addr(),
+ })
+ ip.SetChecksum(^ip.CalculateChecksum())
+ } else {
+ ipHeaderLen = header.IPv6MinimumSize
+ frame = make([]byte, ipHeaderLen+ipPayloadLen)
+ ip := header.IPv6(frame[:ipHeaderLen])
+ ip.Encode(&header.IPv6Fields{
+ PayloadLength: uint16(ipPayloadLen),
+ TransportProtocol: header.TCPProtocolNumber,
+ HopLimit: defaultTTL,
+ SrcAddr: src.Addr(),
+ DstAddr: dst.Addr(),
+ })
+ }
+ encodeTCP(frame, ipHeaderLen, src, dst, packetInfo, payload)
+ return frame
+}
+
+func encodeTCP(frame []byte, ipHeaderLen int, src, dst netip.AddrPort, packetInfo spoofPacketInfo, payload []byte) {
+ tcp := header.TCP(frame[ipHeaderLen:])
+ copy(frame[ipHeaderLen+tcpHeaderLen:], packetInfo.options)
+ optionsLen := len(packetInfo.options)
+ copy(frame[ipHeaderLen+tcpHeaderLen+optionsLen:], payload)
+ tcp.Encode(&header.TCPFields{
+ SrcPort: src.Port(),
+ DstPort: dst.Port(),
+ SeqNum: packetInfo.seqNum,
+ AckNum: packetInfo.ackNum,
+ DataOffset: uint8(tcpHeaderLen + optionsLen),
+ Flags: header.TCPFlagAck | header.TCPFlagPsh,
+ WindowSize: defaultWindowSize,
+ })
+ applyTCPChecksum(tcp, src.Addr(), dst.Addr(), payload, packetInfo.corrupt)
+}
+
+func buildSpoofFrame(method Method, src, dst netip.AddrPort, sendNext, receiveNext, timestamp uint32, tcpOptions, payload []byte) ([]byte, error) {
+ packetInfo, err := resolveSpoofPacketInfo(method, sendNext, receiveNext, timestamp, tcpOptions, payload)
+ if err != nil {
+ return nil, err
+ }
+ return buildTCPSegment(src, dst, packetInfo, payload), nil
+}
+
+func resolveSpoofPacketInfo(method Method, sendNext, receiveNext, timestamp uint32, tcpOptions, payload []byte) (spoofPacketInfo, error) {
+ packetInfo := spoofPacketInfo{seqNum: sendNext, ackNum: receiveNext}
+ switch method {
+ case MethodWrongSequence:
+ packetInfo.seqNum = sendNext - uint32(len(payload))
+ case MethodWrongChecksum:
+ packetInfo.corrupt = true
+ case MethodWrongAcknowledgment:
+ packetInfo.ackNum = receiveNext - uint32(defaultWindowSize/2)
+ case MethodWrongMD5Sig:
+ packetInfo.options = buildMD5SignatureOptions()
+ case MethodWrongTimestamp:
+ packetInfo.options = buildWrongTimestampOptions(timestamp, tcpOptions)
+ default:
+ return packetInfo, E.New("tls_spoof: unknown method ", method)
+ }
+ return packetInfo, nil
+}
+
+func buildMD5SignatureOptions() []byte {
+ options := make([]byte, tcpOptionMD5SignatureLength+2)
+ options[0] = tcpOptionMD5Signature
+ options[1] = tcpOptionMD5SignatureLength
+ return options
+}
+
+func buildWrongTimestampOptions(timestamp uint32, tcpOptions []byte) []byte {
+ spoofedTimestamp := timestamp
+ if spoofedTimestamp > tcpTimestampBackdate {
+ spoofedTimestamp -= tcpTimestampBackdate
+ } else {
+ spoofedTimestamp = 0
+ }
+ if rewriteTCPOptionTimestamp(tcpOptions, spoofedTimestamp) {
+ return tcpOptions
+ }
+ options := make([]byte, header.TCPOptionTSLength+2)
+ header.EncodeTSOption(spoofedTimestamp, 0, options)
+ return options
+}
+
+// rewriteTCPOptionTimestamp finds the TS option in tcpOptions and writes
+// timestamp into its TSVal field in place. The caller must own tcpOptions
+// (parseTCPPacket already returns a private copy on Windows).
+func rewriteTCPOptionTimestamp(tcpOptions []byte, timestamp uint32) bool {
+ for i := 0; i < len(tcpOptions); {
+ switch tcpOptions[i] {
+ case header.TCPOptionEOL:
+ return false
+ case header.TCPOptionNOP:
+ i++
+ continue
+ }
+ if i+1 >= len(tcpOptions) {
+ return false
+ }
+ optionLen := int(tcpOptions[i+1])
+ if optionLen < 2 || i+optionLen > len(tcpOptions) {
+ return false
+ }
+ if tcpOptions[i] == header.TCPOptionTS && optionLen == header.TCPOptionTSLength {
+ binary.BigEndian.PutUint32(tcpOptions[i+2:], timestamp)
+ return true
+ }
+ i += optionLen
+ }
+ return false
+}
+
+func applyTCPChecksum(tcp header.TCP, srcAddr, dstAddr netip.Addr, payload []byte, corrupt bool) {
+ tcpLen := int(tcp.DataOffset()) + len(payload)
+ pseudo := header.PseudoHeaderChecksum(header.TCPProtocolNumber, srcAddr.AsSlice(), dstAddr.AsSlice(), uint16(tcpLen))
+ payloadChecksum := checksum.Checksum(payload, 0)
+ tcpChecksum := ^tcp.CalculateChecksum(checksum.Combine(pseudo, payloadChecksum))
+ if corrupt {
+ tcpChecksum ^= 0xFFFF
+ }
+ tcp.SetChecksum(tcpChecksum)
+}
diff --git a/common/tlsspoof/packet_darwin.go b/common/tlsspoof/packet_darwin.go
new file mode 100644
index 0000000000..4d12bd37ef
--- /dev/null
+++ b/common/tlsspoof/packet_darwin.go
@@ -0,0 +1,15 @@
+package tlsspoof
+
+import "net/netip"
+
+// buildSpoofTCPSegment returns a TCP segment without an IP header, for
+// platforms where the kernel synthesises the IP header (darwin IPv6).
+func buildSpoofTCPSegment(method Method, src, dst netip.AddrPort, sendNext, receiveNext, timestamp uint32, payload []byte) ([]byte, error) {
+ packetInfo, err := resolveSpoofPacketInfo(method, sendNext, receiveNext, timestamp, nil, payload)
+ if err != nil {
+ return nil, err
+ }
+ segment := make([]byte, tcpHeaderLen+len(packetInfo.options)+len(payload))
+ encodeTCP(segment, 0, src, dst, packetInfo, payload)
+ return segment, nil
+}
diff --git a/common/tlsspoof/packet_test.go b/common/tlsspoof/packet_test.go
new file mode 100644
index 0000000000..5c6d5b6be4
--- /dev/null
+++ b/common/tlsspoof/packet_test.go
@@ -0,0 +1,136 @@
+package tlsspoof
+
+import (
+ "net/netip"
+ "testing"
+
+ "github.com/sagernet/sing-tun/gtcpip"
+ "github.com/sagernet/sing-tun/gtcpip/checksum"
+ "github.com/sagernet/sing-tun/gtcpip/header"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestBuildTCPSegment_IPv4_ValidChecksum(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ payload := []byte("fake-client-hello")
+ frame := buildTCPSegment(src, dst, 100_000, 200_000, payload, false)
+
+ ip := header.IPv4(frame[:header.IPv4MinimumSize])
+ require.True(t, ip.IsChecksumValid())
+
+ tcp := header.TCP(frame[header.IPv4MinimumSize:])
+ payloadChecksum := checksum.Checksum(payload, 0)
+ require.True(t, tcp.IsChecksumValid(
+ tcpip.AddrFrom4(src.Addr().As4()),
+ tcpip.AddrFrom4(dst.Addr().As4()),
+ payloadChecksum,
+ uint16(len(payload)),
+ ))
+}
+
+func TestBuildTCPSegment_IPv4_CorruptChecksum(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ payload := []byte("fake-client-hello")
+ frame := buildTCPSegment(src, dst, 100_000, 200_000, payload, true)
+
+ tcp := header.TCP(frame[header.IPv4MinimumSize:])
+ payloadChecksum := checksum.Checksum(payload, 0)
+ require.False(t, tcp.IsChecksumValid(
+ tcpip.AddrFrom4(src.Addr().As4()),
+ tcpip.AddrFrom4(dst.Addr().As4()),
+ payloadChecksum,
+ uint16(len(payload)),
+ ))
+ // IP checksum must still be valid so the router forwards the packet.
+ require.True(t, header.IPv4(frame[:header.IPv4MinimumSize]).IsChecksumValid())
+}
+
+func TestBuildTCPSegment_IPv6_ValidChecksum(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("[fe80::1]:54321")
+ dst := netip.MustParseAddrPort("[2606:4700::1]:443")
+ payload := []byte("fake-client-hello")
+ frame := buildTCPSegment(src, dst, 0xDEADBEEF, 0x12345678, payload, false)
+
+ tcp := header.TCP(frame[header.IPv6MinimumSize:])
+ payloadChecksum := checksum.Checksum(payload, 0)
+ require.True(t, tcp.IsChecksumValid(
+ tcpip.AddrFrom16(src.Addr().As16()),
+ tcpip.AddrFrom16(dst.Addr().As16()),
+ payloadChecksum,
+ uint16(len(payload)),
+ ))
+}
+
+func TestBuildTCPSegment_MixedFamilyPanics(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("[2606:4700::1]:443")
+ require.Panics(t, func() {
+ buildTCPSegment(src, dst, 0, 0, nil, false)
+ })
+}
+
+func TestBuildSpoofFrame_WrongSequence(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ payload := []byte("fake-client-hello")
+ const sendNext uint32 = 10_000
+ frame, err := buildSpoofFrame(MethodWrongSequence, src, dst, sendNext, 20_000, payload)
+ require.NoError(t, err)
+
+ tcp := header.TCP(frame[header.IPv4MinimumSize:])
+ require.Equal(t, sendNext-uint32(len(payload)), tcp.SequenceNumber(),
+ "wrong-sequence places the fake at sendNext-len(payload)")
+ require.True(t, tcp.Flags().Contains(header.TCPFlagAck|header.TCPFlagPsh))
+
+ // Checksum must still be valid — only the sequence number is wrong.
+ payloadChecksum := checksum.Checksum(payload, 0)
+ require.True(t, tcp.IsChecksumValid(
+ tcpip.AddrFrom4(src.Addr().As4()),
+ tcpip.AddrFrom4(dst.Addr().As4()),
+ payloadChecksum,
+ uint16(len(payload)),
+ ))
+}
+
+func TestBuildSpoofFrame_WrongChecksum(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ payload := []byte("fake-client-hello")
+ const sendNext uint32 = 5_000
+ frame, err := buildSpoofFrame(MethodWrongChecksum, src, dst, sendNext, 20_000, payload)
+ require.NoError(t, err)
+
+ tcp := header.TCP(frame[header.IPv4MinimumSize:])
+ require.Equal(t, sendNext, tcp.SequenceNumber(),
+ "wrong-checksum keeps the real sequence number")
+
+ payloadChecksum := checksum.Checksum(payload, 0)
+ require.False(t, tcp.IsChecksumValid(
+ tcpip.AddrFrom4(src.Addr().As4()),
+ tcpip.AddrFrom4(dst.Addr().As4()),
+ payloadChecksum,
+ uint16(len(payload)),
+ ))
+ require.True(t, header.IPv4(frame[:header.IPv4MinimumSize]).IsChecksumValid(),
+ "IPv4 checksum must remain valid so the router forwards the packet")
+}
+
+func TestBuildSpoofTCPSegment_EncodesWithoutIPHeader(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("[fe80::1]:54321")
+ dst := netip.MustParseAddrPort("[2606:4700::1]:443")
+ payload := []byte("fake-client-hello")
+ segment, err := buildSpoofTCPSegment(MethodWrongSequence, src, dst, 1000, 2000, payload)
+ require.NoError(t, err)
+ require.Equal(t, tcpHeaderLen+len(payload), len(segment),
+ "segment must be TCP header + payload, no IP header")
+}
diff --git a/common/tlsspoof/raw_darwin.go b/common/tlsspoof/raw_darwin.go
new file mode 100644
index 0000000000..6f1dd96b6e
--- /dev/null
+++ b/common/tlsspoof/raw_darwin.go
@@ -0,0 +1,199 @@
+package tlsspoof
+
+import (
+ "encoding/binary"
+ "net"
+ "net/netip"
+ "strconv"
+ "strings"
+ "sync"
+ "syscall"
+
+ "github.com/sagernet/sing-tun/gtcpip/header"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/unix"
+)
+
+const PlatformSupported = true
+
+// Offsets into xinpcb_n within each net.inet.tcp.pcblist_n record, identical
+// to the values used by common/process/searcher_darwin_shared.go.
+const (
+ darwinXinpgenSize = 24
+ darwinXsocketOffset = 104
+ darwinXinpcbForeignPort = 16
+ darwinXinpcbLocalPort = 18
+ darwinXinpcbVFlag = 44
+ darwinXinpcbForeignAddr = 48
+ darwinXinpcbLocalAddr = 64
+ darwinXinpcbIPv4Offset = 12
+
+ darwinTCPExtraSize = 208
+
+ darwinXtcpcbSndNxtOffset = 56
+ darwinXtcpcbRcvNxtOffset = 80
+)
+
+// darwinStructSize returns the size of xinpcb_n for the running Darwin kernel.
+// Darwin 22 (macOS 13 Ventura) grew the struct from 384 to 408 bytes; there is
+// no ABI-stable way to read it, so we key off the kernel version.
+var darwinStructSize = sync.OnceValues(func() (int, error) {
+ value, err := syscall.Sysctl("kern.osrelease")
+ if err != nil {
+ return 0, E.Cause(err, "sysctl kern.osrelease")
+ }
+ major, _, ok := strings.Cut(value, ".")
+ if !ok {
+ return 0, E.New("unexpected kern.osrelease format: ", value)
+ }
+ n, err := strconv.ParseInt(major, 10, 64)
+ if err != nil {
+ return 0, E.Cause(err, "parse kern.osrelease major version: ", value)
+ }
+ if n >= 22 {
+ return 408, nil
+ }
+ return 384, nil
+})
+
+type darwinSpoofer struct {
+ method Method
+ src netip.AddrPort
+ dst netip.AddrPort
+ rawFD int
+ rawSockAddr unix.Sockaddr
+ sendNext uint32
+ receiveNext uint32
+}
+
+func newRawSpoofer(conn net.Conn, method Method) (rawSpoofer, error) {
+ if method == MethodWrongTimestamp {
+ return nil, E.New("tls_spoof: wrong-timestamp is not supported on macOS")
+ }
+ _, src, dst, err := tcpEndpoints(conn)
+ if err != nil {
+ return nil, err
+ }
+ fd, sockaddr, err := openDarwinRawSocket(src, dst)
+ if err != nil {
+ return nil, err
+ }
+ sendNext, receiveNext, err := readDarwinTCPSequence(src, dst)
+ if err != nil {
+ unix.Close(fd)
+ return nil, err
+ }
+ return &darwinSpoofer{
+ method: method,
+ src: src,
+ dst: dst,
+ rawFD: fd,
+ rawSockAddr: sockaddr,
+ sendNext: sendNext,
+ receiveNext: receiveNext,
+ }, nil
+}
+
+// readDarwinTCPSequence scans net.inet.tcp.pcblist_n for the PCB that matches
+// src -> dst and returns (snd_nxt, rcv_nxt). These live in xtcpcb_n at the end
+// of each record; see darwin-xnu bsd/netinet/in_pcblist.c:get_pcblist_n.
+func readDarwinTCPSequence(src, dst netip.AddrPort) (uint32, uint32, error) {
+ buffer, err := unix.SysctlRaw("net.inet.tcp.pcblist_n")
+ if err != nil {
+ return 0, 0, E.Cause(err, "sysctl net.inet.tcp.pcblist_n")
+ }
+ structSize, err := darwinStructSize()
+ if err != nil {
+ return 0, 0, err
+ }
+ itemSize := structSize + darwinTCPExtraSize
+ for i := darwinXinpgenSize; i+itemSize <= len(buffer); i += itemSize {
+ inpcb := buffer[i : i+darwinXsocketOffset]
+ xtcpcb := buffer[i+structSize : i+itemSize]
+ localPort := binary.BigEndian.Uint16(inpcb[darwinXinpcbLocalPort : darwinXinpcbLocalPort+2])
+ remotePort := binary.BigEndian.Uint16(inpcb[darwinXinpcbForeignPort : darwinXinpcbForeignPort+2])
+ if localPort != src.Port() || remotePort != dst.Port() {
+ continue
+ }
+ versionFlag := inpcb[darwinXinpcbVFlag]
+ var localAddr, remoteAddr netip.Addr
+ switch {
+ case versionFlag&0x1 != 0:
+ localAddr = netip.AddrFrom4([4]byte(inpcb[darwinXinpcbLocalAddr+darwinXinpcbIPv4Offset : darwinXinpcbLocalAddr+darwinXinpcbIPv4Offset+4]))
+ remoteAddr = netip.AddrFrom4([4]byte(inpcb[darwinXinpcbForeignAddr+darwinXinpcbIPv4Offset : darwinXinpcbForeignAddr+darwinXinpcbIPv4Offset+4]))
+ case versionFlag&0x2 != 0:
+ localAddr = netip.AddrFrom16([16]byte(inpcb[darwinXinpcbLocalAddr : darwinXinpcbLocalAddr+16]))
+ remoteAddr = netip.AddrFrom16([16]byte(inpcb[darwinXinpcbForeignAddr : darwinXinpcbForeignAddr+16]))
+ default:
+ continue
+ }
+ if localAddr.Unmap() != src.Addr() || remoteAddr.Unmap() != dst.Addr() {
+ continue
+ }
+ sendNext := binary.NativeEndian.Uint32(xtcpcb[darwinXtcpcbSndNxtOffset : darwinXtcpcbSndNxtOffset+4])
+ receiveNext := binary.NativeEndian.Uint32(xtcpcb[darwinXtcpcbRcvNxtOffset : darwinXtcpcbRcvNxtOffset+4])
+ return sendNext, receiveNext, nil
+ }
+ return 0, 0, E.New("tls_spoof: connection ", src, "->", dst, " not found in pcblist_n")
+}
+
+func openDarwinRawSocket(src, dst netip.AddrPort) (int, unix.Sockaddr, error) {
+ if dst.Addr().Is4() {
+ return openIPv4RawSocket(dst)
+ }
+ // macOS does not accept IPV6_HDRINCL on AF_INET6 SOCK_RAW IPPROTO_TCP
+ // sockets, so the kernel builds the IPv6 header itself. Bind to the real
+ // connection's source address so in6_selectsrc returns it, and rely on
+ // in6p_cksum defaulting to -1 so the user-supplied TCP checksum is
+ // preserved (including deliberately corrupted ones).
+ fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_TCP)
+ if err != nil {
+ return -1, nil, E.Cause(err, "open AF_INET6 SOCK_RAW")
+ }
+ err = unix.Bind(fd, &unix.SockaddrInet6{Addr: src.Addr().As16()})
+ if err != nil {
+ unix.Close(fd)
+ return -1, nil, E.Cause(err, "bind AF_INET6 SOCK_RAW")
+ }
+ sockaddr := &unix.SockaddrInet6{Port: int(dst.Port()), Addr: dst.Addr().As16()}
+ return fd, sockaddr, nil
+}
+
+func (s *darwinSpoofer) Inject(payload []byte) error {
+ if !s.src.Addr().Is4() {
+ segment, err := buildSpoofTCPSegment(s.method, s.src, s.dst, s.sendNext, s.receiveNext, 0, payload)
+ if err != nil {
+ return err
+ }
+ err = unix.Sendto(s.rawFD, segment, 0, s.rawSockAddr)
+ if err != nil {
+ return E.Cause(err, "sendto raw socket")
+ }
+ return nil
+ }
+ frame, err := buildSpoofFrame(s.method, s.src, s.dst, s.sendNext, s.receiveNext, 0, nil, payload)
+ if err != nil {
+ return err
+ }
+ // Darwin inherits the historical BSD quirk: with IP_HDRINCL the kernel
+ // expects ip_len and ip_off in host byte order, not network byte order.
+ // Apple's rip_output swaps them back before transmission.
+ ip := header.IPv4(frame)
+ ip.SetTotalLengthDarwinRaw(ip.TotalLength())
+ ip.SetFlagsFragmentOffsetDarwinRaw(ip.Flags(), ip.FragmentOffset())
+ err = unix.Sendto(s.rawFD, frame, 0, s.rawSockAddr)
+ if err != nil {
+ return E.Cause(err, "sendto raw socket")
+ }
+ return nil
+}
+
+func (s *darwinSpoofer) Close() error {
+ if s.rawFD < 0 {
+ return nil
+ }
+ err := unix.Close(s.rawFD)
+ s.rawFD = -1
+ return err
+}
diff --git a/common/tlsspoof/raw_linux.go b/common/tlsspoof/raw_linux.go
new file mode 100644
index 0000000000..3e4761147e
--- /dev/null
+++ b/common/tlsspoof/raw_linux.go
@@ -0,0 +1,149 @@
+package tlsspoof
+
+import (
+ "net"
+ "net/netip"
+
+ "github.com/sagernet/sing/common/control"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/unix"
+)
+
+const PlatformSupported = true
+
+const (
+ // Values of enum { TCP_NO_QUEUE, TCP_RECV_QUEUE, TCP_SEND_QUEUE } from
+ // include/net/tcp.h; not exported by golang.org/x/sys/unix.
+ tcpRecvQueue = 1
+ tcpSendQueue = 2
+)
+
+type linuxSpoofer struct {
+ method Method
+ src netip.AddrPort
+ dst netip.AddrPort
+ rawFD int
+ rawSockAddr unix.Sockaddr
+ sendNext uint32
+ receiveNext uint32
+ timestamp uint32
+}
+
+func newRawSpoofer(conn net.Conn, method Method) (rawSpoofer, error) {
+ tcpConn, src, dst, err := tcpEndpoints(conn)
+ if err != nil {
+ return nil, err
+ }
+ fd, sockaddr, err := openLinuxRawSocket(dst)
+ if err != nil {
+ return nil, err
+ }
+ spoofer := &linuxSpoofer{
+ method: method,
+ src: src,
+ dst: dst,
+ rawFD: fd,
+ rawSockAddr: sockaddr,
+ }
+ err = spoofer.loadSequenceNumbers(tcpConn)
+ if err != nil {
+ unix.Close(fd)
+ return nil, err
+ }
+ return spoofer, nil
+}
+
+func openLinuxRawSocket(dst netip.AddrPort) (int, unix.Sockaddr, error) {
+ if dst.Addr().Is4() {
+ return openIPv4RawSocket(dst)
+ }
+ fd, err := unix.Socket(unix.AF_INET6, unix.SOCK_RAW, unix.IPPROTO_TCP)
+ if err != nil {
+ return -1, nil, E.Cause(err, "open AF_INET6 SOCK_RAW")
+ }
+ err = unix.SetsockoptInt(fd, unix.IPPROTO_IPV6, unix.IPV6_HDRINCL, 1)
+ if err != nil {
+ unix.Close(fd)
+ return -1, nil, E.Cause(err, "set IPV6_HDRINCL")
+ }
+ // Linux raw IPv6 sockets interpret sin6_port as a nexthdr protocol number
+ // (see raw(7)); any value other than 0 or the socket's IPPROTO_TCP causes
+ // sendto to fail with EINVAL. The destination is already encoded in the
+ // user-supplied IPv6 header under IPV6_HDRINCL.
+ sockaddr := &unix.SockaddrInet6{Addr: dst.Addr().As16()}
+ return fd, sockaddr, nil
+}
+
+// loadSequenceNumbers puts the socket briefly into TCP_REPAIR mode to read
+// snd_nxt and rcv_nxt from the kernel. TCP_REPAIR requires CAP_NET_ADMIN;
+// callers must run as root or grant both CAP_NET_RAW and CAP_NET_ADMIN.
+//
+// If the TCP_REPAIR_OFF revert fails, the socket would stay in TCP_REPAIR
+// state and subsequent Write() calls would silently buffer instead of sending.
+// Surface that error so callers can abort.
+func (s *linuxSpoofer) loadSequenceNumbers(tcpConn *net.TCPConn) error {
+ return control.Conn(tcpConn, func(raw uintptr) (err error) {
+ fd := int(raw)
+
+ if s.method == MethodWrongTimestamp {
+ timestamp, err := unix.GetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_TIMESTAMP)
+ if err != nil {
+ return E.Cause(err, "read timestamp")
+ }
+ s.timestamp = uint32(timestamp)
+ }
+
+ err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR, unix.TCP_REPAIR_ON)
+ if err != nil {
+ return E.Cause(err, "enter TCP_REPAIR (need CAP_NET_ADMIN)")
+ }
+ defer func() {
+ offErr := unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR, unix.TCP_REPAIR_OFF)
+ if err == nil && offErr != nil {
+ err = E.Cause(offErr, "leave TCP_REPAIR")
+ }
+ }()
+
+ err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR_QUEUE, tcpSendQueue)
+ if err != nil {
+ return E.Cause(err, "select TCP_SEND_QUEUE")
+ }
+ sendSequence, err := unix.GetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_QUEUE_SEQ)
+ if err != nil {
+ return E.Cause(err, "read send queue sequence")
+ }
+ err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_REPAIR_QUEUE, tcpRecvQueue)
+ if err != nil {
+ return E.Cause(err, "select TCP_RECV_QUEUE")
+ }
+ receiveSequence, err := unix.GetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_QUEUE_SEQ)
+ if err != nil {
+ return E.Cause(err, "read recv queue sequence")
+ }
+ s.sendNext = uint32(sendSequence)
+ s.receiveNext = uint32(receiveSequence)
+ return nil
+ })
+}
+
+func (s *linuxSpoofer) Inject(payload []byte) error {
+ frame, err := buildSpoofFrame(s.method, s.src, s.dst, s.sendNext, s.receiveNext, s.timestamp, nil, payload)
+ if err != nil {
+ return err
+ }
+ err = unix.Sendto(s.rawFD, frame, 0, s.rawSockAddr)
+ if err != nil {
+ return E.Cause(err, "sendto raw socket")
+ }
+ return nil
+}
+
+func (s *linuxSpoofer) Close() error {
+ if s.rawFD < 0 {
+ return nil
+ }
+ err := unix.Close(s.rawFD)
+ s.rawFD = -1
+ return err
+}
diff --git a/common/tlsspoof/raw_stub.go b/common/tlsspoof/raw_stub.go
new file mode 100644
index 0000000000..7edf2441a6
--- /dev/null
+++ b/common/tlsspoof/raw_stub.go
@@ -0,0 +1,15 @@
+//go:build !linux && !darwin && !(windows && (amd64 || 386))
+
+package tlsspoof
+
+import (
+ "net"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+const PlatformSupported = false
+
+func newRawSpoofer(conn net.Conn, method Method) (rawSpoofer, error) {
+ return nil, E.New("tls_spoof: unsupported platform")
+}
diff --git a/common/tlsspoof/raw_unix.go b/common/tlsspoof/raw_unix.go
new file mode 100644
index 0000000000..7ab1d44a27
--- /dev/null
+++ b/common/tlsspoof/raw_unix.go
@@ -0,0 +1,26 @@
+//go:build linux || darwin
+
+package tlsspoof
+
+import (
+ "net/netip"
+
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/unix"
+)
+
+func openIPv4RawSocket(dst netip.AddrPort) (int, unix.Sockaddr, error) {
+ fd, err := unix.Socket(unix.AF_INET, unix.SOCK_RAW, unix.IPPROTO_TCP)
+ if err != nil {
+ return -1, nil, E.Cause(err, "open AF_INET SOCK_RAW")
+ }
+ err = unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_HDRINCL, 1)
+ if err != nil {
+ unix.Close(fd)
+ return -1, nil, E.Cause(err, "set IP_HDRINCL")
+ }
+ sockaddr := &unix.SockaddrInet4{Port: int(dst.Port())}
+ sockaddr.Addr = dst.Addr().As4()
+ return fd, sockaddr, nil
+}
diff --git a/common/tlsspoof/raw_windows.go b/common/tlsspoof/raw_windows.go
new file mode 100644
index 0000000000..d7d8a2682a
--- /dev/null
+++ b/common/tlsspoof/raw_windows.go
@@ -0,0 +1,237 @@
+//go:build windows && (amd64 || 386)
+
+package tlsspoof
+
+import (
+ "errors"
+ "net"
+ "net/netip"
+ "slices"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/common/windivert"
+ "github.com/sagernet/sing-tun/gtcpip/header"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/windows"
+)
+
+const PlatformSupported = true
+
+// closeGracePeriod caps how long Close() waits for the divert goroutine to
+// observe the kernel-emitted real ClientHello and perform the reorder
+// (fake → real). In practice this completes in microseconds; the cap
+// bounds the pathological case where the kernel buffers the packet.
+const closeGracePeriod = 2 * time.Second
+
+// windowsSpoofer uses a single WinDivert handle for both capture and
+// injection. Sequential Send() calls on one handle traverse one driver queue,
+// so the fake provably precedes the released real on the wire — a guarantee
+// two separate handles cannot make because cross-handle order depends on the
+// scheduler.
+type windowsSpoofer struct {
+ method Method
+ src, dst netip.AddrPort
+ divertH *windivert.Handle
+
+ fakeReady chan []byte // buffered(1): staged by Inject
+ done chan struct{} // closed by run() on exit
+ closeOnce sync.Once
+ runErr atomic.Pointer[error]
+}
+
+func newRawSpoofer(conn net.Conn, method Method) (rawSpoofer, error) {
+ _, src, dst, err := tcpEndpoints(conn)
+ if err != nil {
+ return nil, err
+ }
+ filter, err := windivert.OutboundTCP(src, dst)
+ if err != nil {
+ return nil, err
+ }
+ divertH, err := windivert.Open(filter, windivert.LayerNetwork, 0, 0)
+ if err != nil {
+ return nil, E.Cause(err, "tls_spoof: open WinDivert")
+ }
+ s := &windowsSpoofer{
+ method: method,
+ src: src,
+ dst: dst,
+ divertH: divertH,
+ fakeReady: make(chan []byte, 1),
+ done: make(chan struct{}),
+ }
+ go s.run()
+ return s, nil
+}
+
+func (s *windowsSpoofer) Inject(payload []byte) error {
+ select {
+ case s.fakeReady <- payload:
+ return nil
+ case <-s.done:
+ if p := s.runErr.Load(); p != nil {
+ return *p
+ }
+ return E.New("tls_spoof: spoofer closed before Inject")
+ }
+}
+
+func (s *windowsSpoofer) Close() error {
+ s.closeOnce.Do(func() {
+ // Give run() a grace window to finish handling the real packet.
+ select {
+ case <-s.done:
+ case <-time.After(closeGracePeriod):
+ // Force Recv() to return by closing the divert handle.
+ s.divertH.Close()
+ <-s.done
+ }
+ })
+ if p := s.runErr.Load(); p != nil {
+ return *p
+ }
+ return nil
+}
+
+func (s *windowsSpoofer) recordErr(err error) { s.runErr.Store(&err) }
+
+func (s *windowsSpoofer) run() {
+ defer close(s.done)
+ defer s.divertH.Close()
+
+ buf := make([]byte, windivert.MTUMax)
+ for {
+ n, addr, err := s.divertH.Recv(buf)
+ if err != nil {
+ if errors.Is(err, windows.ERROR_OPERATION_ABORTED) ||
+ errors.Is(err, windows.ERROR_NO_DATA) {
+ return
+ }
+ s.recordErr(E.Cause(err, "windivert recv"))
+ return
+ }
+ pkt := buf[:n]
+ seq, ack, tcpOptions, payloadLen, ok := parseTCPPacket(pkt, addr.IPv6())
+ if !ok {
+ // Our filter is OutboundTCP(src, dst); a non-TCP or truncated
+ // match means driver state is suspect. Re-inject so the kernel
+ // still sees the byte stream, then abort — continuing would risk
+ // reordering against an unknown reference point.
+ _, sendErr := s.divertH.Send(pkt, &addr)
+ if sendErr != nil {
+ s.recordErr(E.Cause(sendErr, "windivert re-inject malformed"))
+ return
+ }
+ s.recordErr(E.New("windivert received malformed packet matching spoof filter"))
+ return
+ }
+ if payloadLen == 0 {
+ // Handshake ACK, keepalive, FIN — pass through unchanged.
+ _, err := s.divertH.Send(pkt, &addr)
+ if err != nil {
+ s.recordErr(E.Cause(err, "windivert re-inject empty"))
+ return
+ }
+ continue
+ }
+
+ // Non-empty outbound TCP payload = the real ClientHello.
+ var fake []byte
+ select {
+ case fake = <-s.fakeReady:
+ default:
+ // Inject() not yet called — pass through and keep observing.
+ _, err := s.divertH.Send(pkt, &addr)
+ if err != nil {
+ s.recordErr(E.Cause(err, "windivert re-inject early data"))
+ return
+ }
+ continue
+ }
+
+ var timestamp uint32
+ if parsed := header.ParseTCPOptions(tcpOptions); parsed.TS {
+ timestamp = parsed.TSVal
+ }
+ frame, err := buildSpoofFrame(s.method, s.src, s.dst, seq, ack, timestamp, tcpOptions, fake)
+ if err != nil {
+ s.recordErr(err)
+ return
+ }
+ fakeAddr := addr // inherit Outbound, IfIdx
+ // buildSpoofFrame emits ready-to-wire bytes. The driver recomputes
+ // checksums on Send when TCPChecksum/IPChecksum are 0 — which would
+ // overwrite the intentionally corrupt checksum in WrongChecksum mode.
+ // Force both to 1 to keep our bytes intact.
+ fakeAddr.SetIPChecksum(true)
+ fakeAddr.SetTCPChecksum(true)
+ _, err = s.divertH.Send(frame, &fakeAddr)
+ if err != nil {
+ s.recordErr(E.Cause(err, "windivert inject fake"))
+ return
+ }
+ _, err = s.divertH.Send(pkt, &addr)
+ if err != nil {
+ s.recordErr(E.Cause(err, "windivert re-inject real"))
+ return
+ }
+ return // single-shot reorder complete
+ }
+}
+
+func parseTCPPacket(pkt []byte, isV6 bool) (seq, ack uint32, options []byte, payloadLen int, ok bool) {
+ if isV6 {
+ if len(pkt) < header.IPv6MinimumSize+header.TCPMinimumSize {
+ return 0, 0, nil, 0, false
+ }
+ ip := header.IPv6(pkt)
+ if ip.TransportProtocol() != header.TCPProtocolNumber {
+ return 0, 0, nil, 0, false
+ }
+ tcp := header.TCP(pkt[header.IPv6MinimumSize:])
+ tcpHdr := int(tcp.DataOffset())
+ if tcpHdr < header.TCPMinimumSize || header.IPv6MinimumSize+tcpHdr > len(pkt) {
+ return 0, 0, nil, 0, false
+ }
+ total := header.IPv6MinimumSize + int(ip.PayloadLength())
+ if total == header.IPv6MinimumSize || total > len(pkt) {
+ total = len(pkt)
+ }
+ if total < header.IPv6MinimumSize+tcpHdr {
+ return 0, 0, nil, 0, false
+ }
+ return tcp.SequenceNumber(), tcp.AckNumber(), slices.Clone(tcp.Options()),
+ total - header.IPv6MinimumSize - tcpHdr, true
+ }
+ if len(pkt) < header.IPv4MinimumSize+header.TCPMinimumSize {
+ return 0, 0, nil, 0, false
+ }
+ ip := header.IPv4(pkt)
+ if ip.Protocol() != uint8(header.TCPProtocolNumber) {
+ return 0, 0, nil, 0, false
+ }
+ ihl := int(ip.HeaderLength())
+ // ihl+TCPMinimumSize guards the TCP-header field reads below; without
+ // this, an IPv4 packet with options (ihl>20) against a 40-byte buffer
+ // reads past the TCP slice when calling DataOffset.
+ if ihl < header.IPv4MinimumSize || ihl+header.TCPMinimumSize > len(pkt) {
+ return 0, 0, nil, 0, false
+ }
+ tcp := header.TCP(pkt[ihl:])
+ tcpHdr := int(tcp.DataOffset())
+ if tcpHdr < header.TCPMinimumSize || ihl+tcpHdr > len(pkt) {
+ return 0, 0, nil, 0, false
+ }
+ total := int(ip.TotalLength())
+ if total == 0 || total > len(pkt) {
+ total = len(pkt)
+ }
+ if total < ihl+tcpHdr {
+ return 0, 0, nil, 0, false
+ }
+ return tcp.SequenceNumber(), tcp.AckNumber(), slices.Clone(tcp.Options()),
+ total - ihl - tcpHdr, true
+}
diff --git a/common/tlsspoof/raw_windows_test.go b/common/tlsspoof/raw_windows_test.go
new file mode 100644
index 0000000000..58566b8759
--- /dev/null
+++ b/common/tlsspoof/raw_windows_test.go
@@ -0,0 +1,112 @@
+//go:build windows && (amd64 || 386)
+
+package tlsspoof
+
+import (
+ "net/netip"
+ "testing"
+
+ "github.com/sagernet/sing-tun/gtcpip/header"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestParseTCPFieldsIPv4Valid(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ payload := []byte("hello")
+ frame := buildTCPSegment(src, dst, 1000, 2000, payload, false)
+
+ seq, ack, payloadLen, ok := parseTCPFields(frame, false)
+ require.True(t, ok)
+ require.Equal(t, uint32(1000), seq)
+ require.Equal(t, uint32(2000), ack)
+ require.Equal(t, len(payload), payloadLen)
+}
+
+func TestParseTCPFieldsIPv4NoPayload(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ frame := buildTCPSegment(src, dst, 42, 100, nil, false)
+
+ seq, ack, payloadLen, ok := parseTCPFields(frame, false)
+ require.True(t, ok)
+ require.Equal(t, uint32(42), seq)
+ require.Equal(t, uint32(100), ack)
+ require.Equal(t, 0, payloadLen)
+}
+
+func TestParseTCPFieldsIPv6Valid(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("[fe80::1]:54321")
+ dst := netip.MustParseAddrPort("[2606:4700::1]:443")
+ payload := []byte("hello-v6")
+ frame := buildTCPSegment(src, dst, 0xDEADBEEF, 0x12345678, payload, false)
+
+ seq, ack, payloadLen, ok := parseTCPFields(frame, true)
+ require.True(t, ok)
+ require.Equal(t, uint32(0xDEADBEEF), seq)
+ require.Equal(t, uint32(0x12345678), ack)
+ require.Equal(t, len(payload), payloadLen)
+}
+
+func TestParseTCPFieldsIPv4TooShort(t *testing.T) {
+ t.Parallel()
+ _, _, _, ok := parseTCPFields(make([]byte, header.IPv4MinimumSize+header.TCPMinimumSize-1), false)
+ require.False(t, ok)
+}
+
+func TestParseTCPFieldsIPv6TooShort(t *testing.T) {
+ t.Parallel()
+ _, _, _, ok := parseTCPFields(make([]byte, header.IPv6MinimumSize+header.TCPMinimumSize-1), true)
+ require.False(t, ok)
+}
+
+// buildTCPSegment only produces TCP; a UDP packet hitting parseTCPFields
+// (for example from a mis-specified filter) must be rejected.
+func TestParseTCPFieldsIPv4WrongProtocol(t *testing.T) {
+ t.Parallel()
+ frame := make([]byte, header.IPv4MinimumSize+header.TCPMinimumSize)
+ ip := header.IPv4(frame[:header.IPv4MinimumSize])
+ ip.Encode(&header.IPv4Fields{
+ TotalLength: uint16(len(frame)),
+ TTL: 64,
+ Protocol: 17, // UDP
+ SrcAddr: netip.MustParseAddr("10.0.0.1"),
+ DstAddr: netip.MustParseAddr("10.0.0.2"),
+ })
+ _, _, _, ok := parseTCPFields(frame, false)
+ require.False(t, ok)
+}
+
+func TestParseTCPFieldsIPv6WrongProtocol(t *testing.T) {
+ t.Parallel()
+ frame := make([]byte, header.IPv6MinimumSize+header.TCPMinimumSize)
+ ip := header.IPv6(frame[:header.IPv6MinimumSize])
+ ip.Encode(&header.IPv6Fields{
+ PayloadLength: header.TCPMinimumSize,
+ TransportProtocol: 17, // UDP
+ HopLimit: 64,
+ SrcAddr: netip.MustParseAddr("fe80::1"),
+ DstAddr: netip.MustParseAddr("fe80::2"),
+ })
+ _, _, _, ok := parseTCPFields(frame, true)
+ require.False(t, ok)
+}
+
+// ihl > 20 must not read past the TCP slice. Build an IPv4 packet with
+// options header but truncate so ihl*4 + TCPMinimumSize exceeds len.
+func TestParseTCPFieldsIPv4OptionsOverflow(t *testing.T) {
+ t.Parallel()
+ // Start with a valid IPv4+TCP frame, then lie about the header length.
+ src := netip.MustParseAddrPort("10.0.0.1:1")
+ dst := netip.MustParseAddrPort("10.0.0.2:2")
+ frame := buildTCPSegment(src, dst, 0, 0, []byte("x"), false)
+ ip := header.IPv4(frame[:header.IPv4MinimumSize])
+ // ihl=15 → 60 bytes of IP header claimed, but buffer only has 20.
+ ip.SetHeaderLength(60)
+ _, _, _, ok := parseTCPFields(frame, false)
+ require.False(t, ok)
+}
diff --git a/common/tlsspoof/spoof.go b/common/tlsspoof/spoof.go
new file mode 100644
index 0000000000..e36d39e1f0
--- /dev/null
+++ b/common/tlsspoof/spoof.go
@@ -0,0 +1,149 @@
+package tlsspoof
+
+import (
+ "net"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type Method int
+
+const (
+ MethodWrongSequence Method = iota
+ MethodWrongChecksum
+ MethodWrongAcknowledgment
+ MethodWrongMD5Sig
+ MethodWrongTimestamp
+)
+
+const (
+ MethodNameWrongSequence = "wrong-sequence"
+ MethodNameWrongChecksum = "wrong-checksum"
+ MethodNameWrongAcknowledgment = "wrong-ack"
+ MethodNameWrongMD5Sig = "wrong-md5"
+ MethodNameWrongTimestamp = "wrong-timestamp"
+)
+
+func ParseOptions(spoof, method string) (string, Method, error) {
+ if spoof == "" {
+ if method != "" {
+ return "", 0, E.New("spoof_method requires spoof")
+ }
+ return "", 0, nil
+ }
+ if !PlatformSupported {
+ return "", 0, E.New("tls_spoof is not supported on this platform")
+ }
+ parsedMethod, err := ParseMethod(method)
+ if err != nil {
+ return "", 0, err
+ }
+ return spoof, parsedMethod, nil
+}
+
+func ParseMethod(s string) (Method, error) {
+ switch s {
+ case "", MethodNameWrongSequence:
+ return MethodWrongSequence, nil
+ case MethodNameWrongChecksum:
+ return MethodWrongChecksum, nil
+ case MethodNameWrongAcknowledgment:
+ return MethodWrongAcknowledgment, nil
+ case MethodNameWrongMD5Sig:
+ return MethodWrongMD5Sig, nil
+ case MethodNameWrongTimestamp:
+ return MethodWrongTimestamp, nil
+ default:
+ return 0, E.New("tls_spoof: unknown method: ", s)
+ }
+}
+
+func (m Method) String() string {
+ switch m {
+ case MethodWrongSequence:
+ return MethodNameWrongSequence
+ case MethodWrongChecksum:
+ return MethodNameWrongChecksum
+ case MethodWrongAcknowledgment:
+ return MethodNameWrongAcknowledgment
+ case MethodWrongMD5Sig:
+ return MethodNameWrongMD5Sig
+ case MethodWrongTimestamp:
+ return MethodNameWrongTimestamp
+ default:
+ return "unknown"
+ }
+}
+
+type rawSpoofer interface {
+ Inject(payload []byte) error
+ Close() error
+}
+
+type Conn struct {
+ net.Conn
+ spoofer rawSpoofer
+ fakeHello []byte
+ injected bool
+}
+
+func NewConn(conn net.Conn, method Method, fakeSNI string) (*Conn, error) {
+ spoofer, err := newRawSpoofer(conn, method)
+ if err != nil {
+ return nil, err
+ }
+ result, err := newConn(conn, spoofer, fakeSNI)
+ if err != nil {
+ spoofer.Close()
+ return nil, err
+ }
+ return result, nil
+}
+
+func newConn(conn net.Conn, spoofer rawSpoofer, fakeSNI string) (*Conn, error) {
+ fakeHello, err := buildFakeClientHello(fakeSNI)
+ if err != nil {
+ return nil, E.Cause(err, "tls_spoof: build fake ClientHello")
+ }
+ return &Conn{
+ Conn: conn,
+ spoofer: spoofer,
+ fakeHello: fakeHello,
+ }, nil
+}
+
+func (c *Conn) Write(b []byte) (n int, err error) {
+ if c.injected {
+ return c.Conn.Write(b)
+ }
+ defer func() {
+ closeErr := c.spoofer.Close()
+ if err == nil && closeErr != nil {
+ err = E.Cause(closeErr, "tls_spoof: close spoofer")
+ }
+ }()
+ err = c.spoofer.Inject(c.fakeHello)
+ if err != nil {
+ return 0, E.Cause(err, "tls_spoof: inject")
+ }
+ c.injected = true
+ return c.Conn.Write(b)
+}
+
+func (c *Conn) Close() error {
+ return E.Append(c.Conn.Close(), c.spoofer.Close(), func(e error) error {
+ return E.Cause(e, "tls_spoof: close spoofer")
+ })
+}
+
+func (c *Conn) ReaderReplaceable() bool {
+ return true
+}
+
+func (c *Conn) WriterReplaceable() bool {
+ return c.injected
+}
+
+func (c *Conn) Upstream() any {
+ return c.Conn
+}
diff --git a/common/tlsspoof/testdata_test.go b/common/tlsspoof/testdata_test.go
new file mode 100644
index 0000000000..2596ebf619
--- /dev/null
+++ b/common/tlsspoof/testdata_test.go
@@ -0,0 +1,6 @@
+//go:build linux || darwin || (windows && (amd64 || 386))
+
+package tlsspoof
+
+// realClientHello is a captured Chrome ClientHello for github.com.
+const realClientHello = "16030105f8010005f403036e35de7389a679c54029cf452611f2211c70d9ac3897271de589ab6155f8e4ab20637d225f1ef969ad87ed78bfb9d171300bcb1703b6f314ccefb964f79b7d0961002a0a0a130213031301c02cc02bcca9c030c02fcca8c00ac009c014c013009d009c0035002fc008c012000a01000581baba00000000000f000d00000a6769746875622e636f6d00170000ff01000100000a000e000c3a3a11ec001d001700180019000b000201000010000e000c02683208687474702f312e31000500050100000000000d00160014040308040401050308050805050108060601020100120000003304ef04ed3a3a00010011ec04c0aeb2250c092a3463161cccb29d9183331a424964248579507ed23a180b0ceab2a5f5d9ce41547e497a89055471ea572867ba3a1fc3c9e45025274a20f60c6b60e62476b6afed0403af59ab83660ef4112ae20386a602010d0a5d454c0ed34c84ed4423e750213e6a2baab1bf9c4367a6007ab40a33d95220c2dcaa44f257024a5626b545db0510f4311b1a60714154909c6a61fdfca011fb2626d657aeb6070bf078508babe3b584555013e34acc56198ed4663742b3155a664a9901794c4586820a7dc162c01827291f3792e1237f801a8d1ef096013c181c4a58d2f6859ba75022d18cc4418bd4f351d5c18f83a58857d05af860c4b9ac018a5b63f17184e591532c6bc2cf2215d4a282c8a8a4f6f7aee110422c8bc9ebd3b1d609c568523aaae555db320e6c269473d87af38c256cbb9febc20aea6380c32a8916f7a373c8b1e37554e3260bf6621f6b804ee80b3c516b1d01985bf4c603b6daa9a5991de6a7a29f3a7122b8afb843a7660110fce62b43c615f5bcc2db688ba012649c0952b0a2c031e732d2b454c6b2968683cb8d244be2c9a7fa163222979eaf92722b92b862d81a3d94450c2b60c318421ebb4307c42d1f0473592a5c30e42039cc68cda9721e61aa63f49def17c15221680ed444896340133bbee67556f56b9f9d78a4df715f926a12add0cc9c862e46ea8b7316ae468282c18601b2771c9c9322f982228cf93effaacd3f80cbd12bce5fc36f56e2a3caf91e578a5fae00c9b23a8ed1a66764f4433c3628a70b8f0a6196adc60a4cb4226f07ba4c6b363fe9065563bfc1347452946386bab488686e837ab979c64f9047417fca635fe1bb4f074f256cc8af837c7b455e280426547755af90a61640169ef180aea3a77e662bb6dac1b6c3696027129b1a5edf495314e9c7f4b6110e16378ec893fa24642330a40aba1a85326101acb97c620fd8d71389e69eaed7bdb01bbe1fd428d66191150c7b2cd1ad4257391676a82ba8ce07fb2667c3b289f159003a7c7bc31d361b7b7f49a802961739d950dfcc0fa1c7abce5abdd2245101da391151490862028110465950b9e9c03d08a90998ab83267838d2e74a0593bc81f74cdf734519a05b351c0e5488c68dd810e6e9142ccc1e2f4a7f464297eb340e27acc6b9d64e12e38cce8492b3d939140b5a9e149a75597f10a23874c84323a07cdd657274378f887c85c4259b9c04cd33ba58ed630ef2a744f8e19dd34843dff331d2a6be7e2332c599289cd248a611c73d7481cd4a9bd43449a3836f14b2af18a1739e17999e4c67e85cc5bcecabb14185e5bcaff3c96098f03dc5aba819f29587758f49f940585354a2a780830528d68ccd166920dadcaa25cab5fc1907272a826aba3f08bc6b88757776812ecb6c7cec69a223ec0a13a7b62a2349a0f63ed7a27a3b15ba21d71fe6864ec6e089ae17cadd433fa3138f7ee24353c11365818f8fc34f43a05542d18efaac24bfccc1f748a0cc1a67ad379468b76fd34973dba785f5c91d618333cd810fe0700d1bbc8422029782628070a624c52c5309a4a64d625b11f8033ab28df34a1add297517fcc06b92b6817b3c5144438cf260867c57bde68c8c4b82e6a135ef676a52fbae5708002a404e6189a60e2836de565ad1b29e3819e5ed49f6810bcb28e1bd6de57306f94b79d9dae1cc4624d2a068499beef81cd5fe4b76dcbfff2a2008001d002001976128c6d5a934533f28b9914d2480aab2a8c1ab03d212529ce8b27640a716002d00020101002b000706caca03040303001b00030200015a5a000100"
diff --git a/common/urltest/context.go b/common/urltest/context.go
new file mode 100644
index 0000000000..002ff26553
--- /dev/null
+++ b/common/urltest/context.go
@@ -0,0 +1,13 @@
+package urltest
+
+import "context"
+
+type contextKeyIsUnifiedDelay struct{}
+
+func ContextWithIsUnifiedDelay(ctx context.Context) context.Context {
+ return context.WithValue(ctx, contextKeyIsUnifiedDelay{}, true)
+}
+
+func IsUnifiedDelayFromContext(ctx context.Context) bool {
+ return ctx.Value(contextKeyIsUnifiedDelay{}) != nil
+}
diff --git a/common/urltest/urltest.go b/common/urltest/urltest.go
index 29d790e4d0..5e53d9912f 100644
--- a/common/urltest/urltest.go
+++ b/common/urltest/urltest.go
@@ -3,6 +3,7 @@ package urltest
import (
"context"
"crypto/tls"
+ "fmt"
"net"
"net/http"
"net/url"
@@ -45,17 +46,42 @@ func (s *HistoryStorage) LoadURLTestHistory(tag string) *adapter.URLTestHistory
}
func (s *HistoryStorage) DeleteURLTestHistory(tag string) {
+ s.StoreURLTestHistory(tag, &adapter.URLTestHistory{
+ Delay: 65535,
+ Time: time.Now(),
+ })
+ // s.access.Lock()
+ // // delete(s.delayHistory, tag)
+ // s.access.Unlock()
+ // s.notifyUpdated()
+}
+
+func (s *HistoryStorage) StoreURLTestHistory(tag string, history *adapter.URLTestHistory) *adapter.URLTestHistory {
s.access.Lock()
- delete(s.delayHistory, tag)
- s.notifyUpdated()
+ if old, ok := s.delayHistory[tag]; ok && history != nil {
+ old.Delay = history.Delay
+ old.Time = history.Time
+ if history.IpInfo != nil {
+ old.IpInfo = history.IpInfo
+ }
+ } else {
+ s.delayHistory[tag] = history
+ }
+ history = s.delayHistory[tag]
s.access.Unlock()
+ s.notifyUpdated()
+ return history
}
-func (s *HistoryStorage) StoreURLTestHistory(tag string, history *adapter.URLTestHistory) {
+func (s *HistoryStorage) AddOnlyIpToHistory(tag string, history *adapter.URLTestHistory) {
s.access.Lock()
- s.delayHistory[tag] = history
- s.notifyUpdated()
+ if old, ok := s.delayHistory[tag]; ok && history != nil {
+ old.IpInfo = history.IpInfo
+ } else {
+ s.delayHistory[tag] = history
+ }
s.access.Unlock()
+ s.notifyUpdated()
}
func (s *HistoryStorage) notifyUpdated() {
@@ -73,6 +99,10 @@ func (s *HistoryStorage) Close() error {
}
func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err error) {
+ if detour == nil {
+ err = fmt.Errorf("urltest dialer is nil")
+ return
+ }
if link == "" {
link = "https://www.gstatic.com/generate_204"
}
@@ -104,6 +134,11 @@ func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err e
if err != nil {
return
}
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ }
client := http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
@@ -120,11 +155,32 @@ func URLTest(ctx context.Context, link string, detour N.Dialer) (t uint16, err e
Timeout: C.TCPTimeout,
}
defer client.CloseIdleConnections()
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ }
resp, err := client.Do(req.WithContext(ctx))
if err != nil {
return
}
resp.Body.Close()
+
t = uint16(time.Since(start) / time.Millisecond)
+
+ if IsUnifiedDelayFromContext(ctx) {
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ }
+ second := time.Now()
+ resp, err = client.Do(req)
+ if err != nil {
+ return
+ }
+ resp.Body.Close()
+ t = uint16(time.Since(second) / time.Millisecond) //to avid timeout in the second call
+ }
return
}
diff --git a/common/vision/hook.go b/common/vision/hook.go
new file mode 100644
index 0000000000..8a63cb7f2a
--- /dev/null
+++ b/common/vision/hook.go
@@ -0,0 +1,25 @@
+package vision
+
+import (
+ "context"
+ "net"
+)
+
+type Hook func(net.Conn)
+
+type hookKey struct{}
+
+func WithHook(ctx context.Context, hook Hook) context.Context {
+ if hook == nil {
+ return ctx
+ }
+ return context.WithValue(ctx, hookKey{}, hook)
+}
+
+func HookFromContext(ctx context.Context) (Hook, bool) {
+ if ctx == nil {
+ return nil, false
+ }
+ hook, ok := ctx.Value(hookKey{}).(Hook)
+ return hook, ok
+}
diff --git a/common/windivert/address_test.go b/common/windivert/address_test.go
new file mode 100644
index 0000000000..bfc995589d
--- /dev/null
+++ b/common/windivert/address_test.go
@@ -0,0 +1,53 @@
+package windivert
+
+import (
+ "testing"
+ "unsafe"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestAddressSize(t *testing.T) {
+ t.Parallel()
+ require.Equal(t, uintptr(80), unsafe.Sizeof(Address{}))
+}
+
+func TestAddressIPv6(t *testing.T) {
+ t.Parallel()
+ var addr Address
+ require.False(t, addr.IPv6())
+ addr.bits = 1 << addrBitIPv6
+ require.True(t, addr.IPv6())
+}
+
+func TestAddressSetIPChecksum(t *testing.T) {
+ t.Parallel()
+ var addr Address
+ addr.SetIPChecksum(true)
+ require.Equal(t, uint32(1<
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
+==============================================================================
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
+==============================================================================
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ , 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
+
diff --git a/common/windivert/assets/WinDivert32.sys b/common/windivert/assets/WinDivert32.sys
new file mode 100644
index 0000000000..d06738cbb7
Binary files /dev/null and b/common/windivert/assets/WinDivert32.sys differ
diff --git a/common/windivert/assets/WinDivert64.sys b/common/windivert/assets/WinDivert64.sys
new file mode 100644
index 0000000000..218ccaf423
Binary files /dev/null and b/common/windivert/assets/WinDivert64.sys differ
diff --git a/common/windivert/assets_386.go b/common/windivert/assets_386.go
new file mode 100644
index 0000000000..0cbf35ed5c
--- /dev/null
+++ b/common/windivert/assets_386.go
@@ -0,0 +1,14 @@
+//go:build windows && 386
+
+package windivert
+
+import _ "embed"
+
+//go:embed assets/WinDivert32.sys
+var sysBytes []byte
+
+func assetFiles() []assetFile {
+ return []assetFile{{"WinDivert32.sys", sysBytes}}
+}
+
+func driverSysName() string { return "WinDivert32.sys" }
diff --git a/common/windivert/assets_amd64.go b/common/windivert/assets_amd64.go
new file mode 100644
index 0000000000..2c9fb6c6ad
--- /dev/null
+++ b/common/windivert/assets_amd64.go
@@ -0,0 +1,14 @@
+//go:build windows && amd64
+
+package windivert
+
+import _ "embed"
+
+//go:embed assets/WinDivert64.sys
+var sysBytes []byte
+
+func assetFiles() []assetFile {
+ return []assetFile{{"WinDivert64.sys", sysBytes}}
+}
+
+func driverSysName() string { return "WinDivert64.sys" }
diff --git a/common/windivert/assets_unsupported.go b/common/windivert/assets_unsupported.go
new file mode 100644
index 0000000000..04698953fa
--- /dev/null
+++ b/common/windivert/assets_unsupported.go
@@ -0,0 +1,7 @@
+//go:build windows && !amd64 && !386
+
+package windivert
+
+func assetFiles() []assetFile { return nil }
+
+func driverSysName() string { return "" }
diff --git a/common/windivert/driver_windows.go b/common/windivert/driver_windows.go
new file mode 100644
index 0000000000..d6bc59f893
--- /dev/null
+++ b/common/windivert/driver_windows.go
@@ -0,0 +1,212 @@
+//go:build windows
+
+package windivert
+
+import (
+ "errors"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "sync"
+
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/windows"
+)
+
+const (
+ driverServiceName = "WinDivert"
+ driverDeviceName = `\\.\WinDivert`
+)
+
+var (
+ driverOnce sync.Once
+ driverErr error
+ // driverDevName is ASCII-safe and must be available before ensureDriver
+ // so Open can try CreateFile first and only install on FILE_NOT_FOUND.
+ driverDevName, _ = windows.UTF16PtrFromString(driverDeviceName)
+)
+
+// Requires SeLoadDriverPrivilege (Administrator). Running the 386 build
+// under WOW64 on a 64-bit kernel is rejected — use the amd64 build.
+func ensureDriver() error {
+ driverOnce.Do(func() {
+ driverErr = installDriver()
+ })
+ return driverErr
+}
+
+func installDriver() error {
+ if runtime.GOARCH == "386" {
+ var isWow64 bool
+ err := windows.IsWow64Process(windows.CurrentProcess(), &isWow64)
+ if err == nil && isWow64 {
+ return E.New("windivert: 386 build detected running under WOW64 on a 64-bit kernel; use the amd64 build")
+ }
+ }
+
+ dir, err := ensureExtracted()
+ if err != nil {
+ return err
+ }
+ sysPath := filepath.Join(dir, driverSysName())
+ sysPathW, err := windows.UTF16PtrFromString(sysPath)
+ if err != nil {
+ return E.Cause(err, "windivert: utf16 driver path")
+ }
+
+ // Serialize driver install across concurrent processes.
+ mutexName, _ := windows.UTF16PtrFromString("WinDivertDriverInstallMutex")
+ mutex, err := windows.CreateMutex(nil, false, mutexName)
+ if err != nil {
+ return E.Cause(err, "windivert: create install mutex")
+ }
+ defer windows.CloseHandle(mutex)
+ _, err = windows.WaitForSingleObject(mutex, windows.INFINITE)
+ if err != nil {
+ return E.Cause(err, "windivert: wait install mutex")
+ }
+ defer windows.ReleaseMutex(mutex)
+
+ manager, err := windows.OpenSCManager(nil, nil, windows.SC_MANAGER_ALL_ACCESS)
+ if err != nil {
+ return E.Cause(err, "windivert: open SCM")
+ }
+ defer windows.CloseServiceHandle(manager)
+
+ serviceNameW, _ := windows.UTF16PtrFromString(driverServiceName)
+ service, err := windows.OpenService(manager, serviceNameW, windows.SERVICE_ALL_ACCESS)
+ if err != nil {
+ service, err = windows.CreateService(
+ manager,
+ serviceNameW,
+ serviceNameW,
+ windows.SERVICE_ALL_ACCESS,
+ windows.SERVICE_KERNEL_DRIVER,
+ windows.SERVICE_DEMAND_START,
+ windows.SERVICE_ERROR_NORMAL,
+ sysPathW,
+ nil, nil, nil, nil, nil,
+ )
+ if err != nil {
+ if errors.Is(err, windows.ERROR_SERVICE_EXISTS) {
+ service, err = windows.OpenService(manager, serviceNameW, windows.SERVICE_ALL_ACCESS)
+ }
+ if err != nil {
+ return wrapDriverInstallError(err)
+ }
+ }
+ }
+ defer windows.CloseServiceHandle(service)
+
+ err = windows.StartService(service, 0, nil)
+ if err != nil && errors.Is(err, windows.ERROR_SERVICE_DISABLED) {
+ // A prior process called DeleteService on a still-running kernel
+ // driver: SCM marks the record for deletion and flips START_TYPE
+ // to DISABLED until the last handle closes. Re-enable so we can
+ // start it instead of waiting for a reboot.
+ err = windows.ChangeServiceConfig(
+ service,
+ windows.SERVICE_NO_CHANGE,
+ windows.SERVICE_DEMAND_START,
+ windows.SERVICE_NO_CHANGE,
+ nil, nil, nil, nil, nil, nil, nil,
+ )
+ if err != nil {
+ return E.Cause(err, "windivert: re-enable disabled service")
+ }
+ err = windows.StartService(service, 0, nil)
+ }
+ if err == nil {
+ // Mark for deletion so the driver unregisters when the last handle
+ // closes or on next reboot. Matches the upstream DLL's behavior:
+ // only the process that actually started the service takes on the
+ // cleanup responsibility. If another process already started it,
+ // we leave DeleteService to them.
+ _ = windows.DeleteService(service)
+ } else if !errors.Is(err, windows.ERROR_SERVICE_ALREADY_RUNNING) {
+ return E.Cause(err, "windivert: start service")
+ }
+ return nil
+}
+
+func wrapDriverInstallError(err error) error {
+ if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
+ return E.Cause(err, "windivert: installing the kernel driver requires Administrator privileges")
+ }
+ return E.Cause(err, "windivert: create service")
+}
+
+type assetFile struct {
+ name string
+ data []byte
+}
+
+var (
+ extractOnce sync.Once
+ extractErr error
+ extractDir string
+)
+
+// The on-disk copy is protected by Windows Authenticode signature
+// enforcement, which rejects any tampered .sys at StartService time.
+func ensureExtracted() (string, error) {
+ extractOnce.Do(func() {
+ extractDir, extractErr = extractImpl()
+ })
+ return extractDir, extractErr
+}
+
+func extractImpl() (string, error) {
+ files := assetFiles()
+ if len(files) == 0 {
+ return "", E.New("windivert: unsupported architecture ", runtime.GOARCH)
+ }
+
+ base, err := os.UserCacheDir()
+ if err != nil {
+ return "", E.Cause(err, "windivert: locate user cache dir")
+ }
+ dir := filepath.Join(base, "sing-box", "windivert", "v"+AssetVersion)
+ err = os.MkdirAll(dir, 0o755)
+ if err != nil {
+ return "", E.Cause(err, "windivert: mkdir ", dir)
+ }
+
+ for _, asset := range files {
+ err = ensureAsset(dir, asset)
+ if err != nil {
+ return "", err
+ }
+ }
+ return dir, nil
+}
+
+// Concurrent sing-box processes race on os.Rename (atomic on NTFS);
+// whichever wins creates the final file. Writers that lose the race
+// silently discard their temp copy.
+func ensureAsset(dir string, asset assetFile) error {
+ target := filepath.Join(dir, asset.name)
+ _, err := os.Stat(target)
+ if err == nil {
+ return nil
+ }
+ if !os.IsNotExist(err) {
+ return E.Cause(err, "windivert: stat ", asset.name)
+ }
+ tmp := target + ".tmp-" + strconv.Itoa(os.Getpid())
+ err = os.WriteFile(tmp, asset.data, 0o644)
+ if err != nil {
+ return E.Cause(err, "windivert: write ", asset.name)
+ }
+ err = os.Rename(tmp, target)
+ if err != nil {
+ os.Remove(tmp)
+ if _, statErr := os.Stat(target); statErr == nil {
+ return nil
+ }
+ return E.Cause(err, "windivert: rename ", asset.name)
+ }
+ return nil
+}
diff --git a/common/windivert/filter.go b/common/windivert/filter.go
new file mode 100644
index 0000000000..5c8fb5adcd
--- /dev/null
+++ b/common/windivert/filter.go
@@ -0,0 +1,182 @@
+package windivert
+
+import (
+ "encoding/binary"
+ "net/netip"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+// WINDIVERT_FILTER VM instruction layout (24 bytes, #pragma pack(1)):
+//
+// word 0 (LE): field:11 | test:5 | success:16
+// word 1 (LE): failure:16 | neg:1 | reserved:15
+// words 2..5: arg[4] (native-endian uint32 each)
+//
+// The driver walks this as a decision tree: evaluate the test at inst i;
+// on success jump to success; on failure jump to failure. Continuations
+// 0x7FFE and 0x7FFF are ACCEPT and REJECT terminals.
+const (
+ filterInstBytes = 24
+ filterMaxInsts = 256
+
+ fieldZero = 0
+ fieldOutbound = 2
+ fieldIP = 5
+ fieldIPv6 = 6
+ fieldTCP = 8
+ fieldIPSrcAddr = 21
+ fieldIPDstAddr = 22
+ fieldIPv6SrcAddr = 28
+ fieldIPv6DstAddr = 29
+ fieldTCPSrcPort = 38
+ fieldTCPDstPort = 39
+
+ testEQ = 0
+
+ resultAccept uint16 = 0x7FFE
+ resultReject uint16 = 0x7FFF
+)
+
+// Filter flags passed to IOCTL_WINDIVERT_STARTUP alongside the compiled
+// filter. These tell the driver what *kinds* of packets the filter might
+// match, used as a kernel-side fast-reject.
+const (
+ filterFlagOutbound uint64 = 0x0020
+ filterFlagIP uint64 = 0x0040
+ filterFlagIPv6 uint64 = 0x0080
+)
+
+type filterInst struct {
+ field uint16 // 11 bits used
+ test uint8 // 5 bits used
+ success uint16
+ failure uint16
+ neg bool
+ arg [4]uint32
+}
+
+// Filter is a typed specification of packets to capture. It replaces
+// WinDivert's filter string language.
+//
+// Zero value = "reject all" (match nothing), suitable for send-only handles.
+type Filter struct {
+ insts []filterInst
+ flags uint64 // filter flags for STARTUP ioctl
+}
+
+// reject returns a filter that matches no packet. The empty insts slice
+// is encoded as a single rejecting instruction by encode().
+func reject() *Filter {
+ return &Filter{}
+}
+
+// OutboundTCP returns a filter matching outbound TCP packets on the given
+// 5-tuple. Both addresses must share an address family (IPv4 or IPv6).
+func OutboundTCP(src, dst netip.AddrPort) (*Filter, error) {
+ if !src.IsValid() || !dst.IsValid() {
+ return nil, E.New("windivert: filter: invalid address port")
+ }
+ if src.Addr().Is4() != dst.Addr().Is4() {
+ return nil, E.New("windivert: filter: mixed IPv4/IPv6")
+ }
+ f := &Filter{
+ flags: filterFlagOutbound,
+ }
+ // Insts chain as AND: each test's failure = REJECT, success = next inst.
+ // The final inst's success = ACCEPT.
+ f.add(fieldOutbound, testEQ, argUint32(1))
+ if src.Addr().Is4() {
+ f.flags |= filterFlagIP
+ f.add(fieldIP, testEQ, argUint32(1))
+ f.add(fieldTCP, testEQ, argUint32(1))
+ f.add(fieldIPSrcAddr, testEQ, argIPv4(src.Addr()))
+ f.add(fieldIPDstAddr, testEQ, argIPv4(dst.Addr()))
+ } else {
+ f.flags |= filterFlagIPv6
+ f.add(fieldIPv6, testEQ, argUint32(1))
+ f.add(fieldTCP, testEQ, argUint32(1))
+ f.add(fieldIPv6SrcAddr, testEQ, argIPv6(src.Addr()))
+ f.add(fieldIPv6DstAddr, testEQ, argIPv6(dst.Addr()))
+ }
+ f.add(fieldTCPSrcPort, testEQ, argUint32(uint32(src.Port())))
+ f.add(fieldTCPDstPort, testEQ, argUint32(uint32(dst.Port())))
+ return f, nil
+}
+
+func (f *Filter) add(field uint16, test uint8, arg [4]uint32) {
+ f.insts = append(f.insts, filterInst{field: field, test: test, arg: arg})
+}
+
+func argUint32(v uint32) [4]uint32 { return [4]uint32{v, 0, 0, 0} }
+
+// argIPv4 encodes an IPv4 address for IP_SRCADDR/IP_DSTADDR. The driver
+// compares against an IPv4-mapped-IPv6 form: {host_order_u32, 0x0000FFFF,
+// 0, 0} (see sys/windivert.c windivert_get_ipv4_addr and the IPv4_SRCADDR
+// val-word construction). Omitting the 0x0000FFFF marker causes the EQ
+// test to fail for every packet.
+func argIPv4(addr netip.Addr) [4]uint32 {
+ b := addr.As4()
+ return [4]uint32{binary.BigEndian.Uint32(b[:]), 0x0000FFFF, 0, 0}
+}
+
+// argIPv6 encodes an IPv6 address for IPV6_SRCADDR/IPV6_DSTADDR. The
+// driver stores the address as four host-order uint32s in REVERSED word
+// order: val[0]=low (bytes 12..15), val[3]=high (bytes 0..3). See
+// sys/windivert.c windivert_outbound_network_v6_classify val-word
+// construction.
+func argIPv6(addr netip.Addr) [4]uint32 {
+ b := addr.As16()
+ return [4]uint32{
+ binary.BigEndian.Uint32(b[12:16]),
+ binary.BigEndian.Uint32(b[8:12]),
+ binary.BigEndian.Uint32(b[4:8]),
+ binary.BigEndian.Uint32(b[0:4]),
+ }
+}
+
+// encode serializes the Filter to the on-wire WINDIVERT_FILTER[] format
+// plus the filter_flags for STARTUP ioctl.
+func (f *Filter) encode() ([]byte, uint64, error) {
+ if len(f.insts) == 0 {
+ // "Reject all" — one instruction, ZERO == 0 is always true, but we
+ // invert by setting both success and failure to REJECT.
+ return encodeInst(filterInst{
+ field: fieldZero,
+ test: testEQ,
+ success: resultReject,
+ failure: resultReject,
+ }), 0, nil
+ }
+ if len(f.insts) > filterMaxInsts-1 {
+ return nil, 0, E.New("windivert: filter too long")
+ }
+ buf := make([]byte, 0, filterInstBytes*len(f.insts))
+ for i, inst := range f.insts {
+ if i == len(f.insts)-1 {
+ inst.success = resultAccept
+ } else {
+ inst.success = uint16(i + 1)
+ }
+ inst.failure = resultReject
+ buf = append(buf, encodeInst(inst)...)
+ }
+ return buf, f.flags, nil
+}
+
+func encodeInst(inst filterInst) []byte {
+ out := make([]byte, filterInstBytes)
+ word0 := uint32(inst.field&0x7FF) | uint32(inst.test&0x1F)<<11 |
+ uint32(inst.success)<<16
+ word1 := uint32(inst.failure)
+ if inst.neg {
+ word1 |= 1 << 16
+ }
+ binary.LittleEndian.PutUint32(out[0:4], word0)
+ binary.LittleEndian.PutUint32(out[4:8], word1)
+ binary.LittleEndian.PutUint32(out[8:12], inst.arg[0])
+ binary.LittleEndian.PutUint32(out[12:16], inst.arg[1])
+ binary.LittleEndian.PutUint32(out[16:20], inst.arg[2])
+ binary.LittleEndian.PutUint32(out[20:24], inst.arg[3])
+ return out
+}
diff --git a/common/windivert/filter_test.go b/common/windivert/filter_test.go
new file mode 100644
index 0000000000..babac3e86a
--- /dev/null
+++ b/common/windivert/filter_test.go
@@ -0,0 +1,140 @@
+package windivert
+
+import (
+ "encoding/binary"
+ "net/netip"
+ "testing"
+)
+
+func TestRejectFilter(t *testing.T) {
+ t.Parallel()
+ bin, flags, err := reject().encode()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(bin) != filterInstBytes {
+ t.Fatalf("reject filter len: got %d, want %d", len(bin), filterInstBytes)
+ }
+ if flags != 0 {
+ t.Fatalf("reject filter flags: got %x, want 0", flags)
+ }
+ // word0: field=ZERO=0, test=EQ=0, success=REJECT=0x7FFF
+ word0 := binary.LittleEndian.Uint32(bin[0:4])
+ if word0 != uint32(resultReject)<<16 {
+ t.Fatalf("reject word0 = %08x", word0)
+ }
+ // word1: failure=REJECT
+ word1 := binary.LittleEndian.Uint32(bin[4:8])
+ if word1 != uint32(resultReject) {
+ t.Fatalf("reject word1 = %08x", word1)
+ }
+}
+
+func TestOutboundTCPFilterIPv4(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.1.2.3:54321")
+ dst := netip.MustParseAddrPort("1.2.3.4:443")
+ f, err := OutboundTCP(src, dst)
+ if err != nil {
+ t.Fatal(err)
+ }
+ bin, flags, err := f.encode()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if want := filterFlagOutbound | filterFlagIP; flags != want {
+ t.Fatalf("flags: got %x, want %x", flags, want)
+ }
+ // 7 instructions: OUTBOUND, IP, TCP, IP_SRCADDR, IP_DSTADDR, TCP_SRCPORT, TCP_DSTPORT
+ const wantInsts = 7
+ if len(bin) != wantInsts*filterInstBytes {
+ t.Fatalf("instruction count: got %d, want %d", len(bin)/filterInstBytes, wantInsts)
+ }
+
+ // Inst 0: OUTBOUND == 1, success=1, failure=REJECT
+ checkInst(t, bin[0*filterInstBytes:], 0, fieldOutbound, testEQ, 1, resultReject, 1)
+ // Inst 1: IP == 1, success=2
+ checkInst(t, bin[1*filterInstBytes:], 1, fieldIP, testEQ, 2, resultReject, 1)
+ // Inst 2: TCP == 1, success=3
+ checkInst(t, bin[2*filterInstBytes:], 2, fieldTCP, testEQ, 3, resultReject, 1)
+ // Inst 3: IP_SRCADDR == 10.1.2.3 (host-order uint32 = 0x0A010203, arg[1]=0x0000FFFF marker)
+ checkInst(t, bin[3*filterInstBytes:], 3, fieldIPSrcAddr, testEQ, 4, resultReject, 0x0A010203)
+ checkArg1(t, bin[3*filterInstBytes:], 3, 0x0000FFFF)
+ // Inst 4: IP_DSTADDR == 1.2.3.4
+ checkInst(t, bin[4*filterInstBytes:], 4, fieldIPDstAddr, testEQ, 5, resultReject, 0x01020304)
+ checkArg1(t, bin[4*filterInstBytes:], 4, 0x0000FFFF)
+ // Inst 5: TCP_SRCPORT == 54321
+ checkInst(t, bin[5*filterInstBytes:], 5, fieldTCPSrcPort, testEQ, 6, resultReject, 54321)
+ // Last inst 6: TCP_DSTPORT == 443, success=ACCEPT
+ checkInst(t, bin[6*filterInstBytes:], 6, fieldTCPDstPort, testEQ, resultAccept, resultReject, 443)
+}
+
+func TestOutboundTCPFilterIPv6(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("[2001:db8::1]:54321")
+ dst := netip.MustParseAddrPort("[2001:db8::2]:443")
+ f, err := OutboundTCP(src, dst)
+ if err != nil {
+ t.Fatal(err)
+ }
+ bin, flags, err := f.encode()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if want := filterFlagOutbound | filterFlagIPv6; flags != want {
+ t.Fatalf("flags: got %x, want %x", flags, want)
+ }
+ // Inst 3: IPv6_SRCADDR. The driver stores the address in reversed
+ // word order: arg[0]=low (bytes 12..15)=1, arg[3]=high (bytes 0..3)=0x20010db8.
+ off := 3 * filterInstBytes
+ a0 := binary.LittleEndian.Uint32(bin[off+8:])
+ a1 := binary.LittleEndian.Uint32(bin[off+12:])
+ a2 := binary.LittleEndian.Uint32(bin[off+16:])
+ a3 := binary.LittleEndian.Uint32(bin[off+20:])
+ if a0 != 1 || a1 != 0 || a2 != 0 || a3 != 0x20010db8 {
+ t.Fatalf("ipv6 src arg=[%08x %08x %08x %08x], want [1 0 0 0x20010db8]", a0, a1, a2, a3)
+ }
+}
+
+func TestOutboundTCPFilterMixedFamily(t *testing.T) {
+ t.Parallel()
+ src := netip.MustParseAddrPort("10.0.0.1:1234")
+ dst := netip.MustParseAddrPort("[2001:db8::1]:443")
+ if _, err := OutboundTCP(src, dst); err == nil {
+ t.Fatal("expected error for mixed families")
+ }
+}
+
+func checkArg1(t *testing.T, raw []byte, idx int, arg1 uint32) {
+ t.Helper()
+ got := binary.LittleEndian.Uint32(raw[12:16])
+ if got != arg1 {
+ t.Errorf("inst %d arg[1]: got %08x, want %08x", idx, got, arg1)
+ }
+}
+
+func checkInst(t *testing.T, raw []byte, idx int, field uint16, test uint8, success, failure uint16, arg0 uint32) {
+ t.Helper()
+ word0 := binary.LittleEndian.Uint32(raw[0:4])
+ word1 := binary.LittleEndian.Uint32(raw[4:8])
+ a0 := binary.LittleEndian.Uint32(raw[8:12])
+ gotField := uint16(word0 & 0x7FF)
+ gotTest := uint8((word0 >> 11) & 0x1F)
+ gotSuccess := uint16(word0 >> 16)
+ gotFailure := uint16(word1 & 0xFFFF)
+ if gotField != field {
+ t.Errorf("inst %d field: got %d, want %d", idx, gotField, field)
+ }
+ if gotTest != test {
+ t.Errorf("inst %d test: got %d, want %d", idx, gotTest, test)
+ }
+ if gotSuccess != success {
+ t.Errorf("inst %d success: got %d, want %d", idx, gotSuccess, success)
+ }
+ if gotFailure != failure {
+ t.Errorf("inst %d failure: got %d, want %d", idx, gotFailure, failure)
+ }
+ if a0 != arg0 {
+ t.Errorf("inst %d arg[0]: got %08x, want %08x", idx, a0, arg0)
+ }
+}
diff --git a/common/windivert/handle_windows.go b/common/windivert/handle_windows.go
new file mode 100644
index 0000000000..1d7aebfdef
--- /dev/null
+++ b/common/windivert/handle_windows.go
@@ -0,0 +1,324 @@
+//go:build windows
+
+package windivert
+
+import (
+ "encoding/binary"
+ "errors"
+ "runtime"
+ "sync"
+ "unsafe"
+
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/sys/windows"
+)
+
+// Handle owns a WinDivert kernel device handle plus a private event for
+// overlapped I/O. Methods on *Handle are not safe for concurrent use
+// across goroutines (there is a single shared event per Handle).
+//
+// addr is a per-Handle Address buffer the IOCTL struct embeds a pointer
+// to. It lives on the heap (as a field of a heap-allocated Handle) so
+// the pointer value stored as bytes in the ioctl buffer remains valid
+// across stack growth between buildIoctl* and the DeviceIoControl
+// syscall — stack-local Address values are not safe for this pattern
+// because Go's escape analysis does not see the pointer through the
+// unsafe.Pointer → uintptr → bytes conversion.
+type Handle struct {
+ device windows.Handle
+ event windows.Handle
+ closing sync.Once
+ closeErr error
+ addr Address
+}
+
+// Filter may be nil for "reject all", suitable for send-only handles.
+// Requires Administrator on first call per process (installs the kernel
+// driver via SCM); subsequent calls reuse the running driver.
+func Open(filter *Filter, layer Layer, priority int16, flags Flag) (*Handle, error) {
+ err := validateOpenArgs(layer, priority, flags)
+ if err != nil {
+ return nil, err
+ }
+ if filter == nil {
+ filter = reject()
+ }
+ filterBin, filterFlags, err := filter.encode()
+ if err != nil {
+ return nil, err
+ }
+ device, err := openDevice()
+ if err != nil {
+ if !errors.Is(err, windows.ERROR_FILE_NOT_FOUND) &&
+ !errors.Is(err, windows.ERROR_PATH_NOT_FOUND) {
+ if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
+ return nil, E.Cause(err, "windivert: open device (administrator required)")
+ }
+ return nil, E.Cause(err, "windivert: open device")
+ }
+ // Device node missing: kernel driver not loaded. Install + retry.
+ // Matches WinDivertOpen's lazy-install path; avoids racing StartService
+ // against a still-loaded driver whose SCM record is marked for deletion.
+ err = ensureDriver()
+ if err != nil {
+ return nil, err
+ }
+ device, err = openDevice()
+ if err != nil {
+ if errors.Is(err, windows.ERROR_ACCESS_DENIED) {
+ return nil, E.Cause(err, "windivert: open device (administrator required)")
+ }
+ return nil, E.Cause(err, "windivert: open device")
+ }
+ }
+ event, err := windows.CreateEvent(nil, 1, 0, nil) // manual reset, unsignaled
+ if err != nil {
+ windows.CloseHandle(device)
+ return nil, E.Cause(err, "windivert: create event")
+ }
+ h := &Handle{device: device, event: event}
+
+ err = h.initialize(layer, priority, flags)
+ if err != nil {
+ h.Close()
+ return nil, err
+ }
+ err = h.startup(filterBin, filterFlags)
+ if err != nil {
+ h.Close()
+ return nil, err
+ }
+ return h, nil
+}
+
+func openDevice() (windows.Handle, error) {
+ return windows.CreateFile(
+ driverDevName,
+ windows.GENERIC_READ|windows.GENERIC_WRITE,
+ 0, nil,
+ windows.OPEN_EXISTING,
+ windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_OVERLAPPED,
+ 0,
+ )
+}
+
+func validateOpenArgs(layer Layer, priority int16, flags Flag) error {
+ if layer != LayerNetwork {
+ return E.New("windivert: invalid layer ", uint32(layer))
+ }
+ if priority < PriorityLowest || priority > PriorityHighest {
+ return E.New("windivert: priority out of range")
+ }
+ const supportedFlags = FlagSniff | FlagSendOnly
+ if flags&^supportedFlags != 0 {
+ return E.New("windivert: unknown flag bits")
+ }
+ if flags&FlagSniff != 0 && flags&FlagSendOnly != 0 {
+ return E.New("windivert: FlagSniff and FlagSendOnly are mutually exclusive")
+ }
+ return nil
+}
+
+func (h *Handle) initialize(layer Layer, priority int16, flags Flag) error {
+ in := buildIoctlInitialize(layer, priority, flags)
+ // WINDIVERT_VERSION is a 64-byte packed struct; only the first 20
+ // bytes (magic, major, minor, bits) carry data, the rest is reserved.
+ var outBuf [versionStructSize]byte
+ binary.LittleEndian.PutUint64(outBuf[0:8], magicDLL)
+ binary.LittleEndian.PutUint32(outBuf[8:12], versionMajor)
+ binary.LittleEndian.PutUint32(outBuf[12:16], versionMinor)
+ binary.LittleEndian.PutUint32(outBuf[16:20], uint32(unsafe.Sizeof(uintptr(0))*8))
+ _, err := doIoctl(h.device, ioctlInitialize, in[:], outBuf[:], h.event)
+ if err != nil {
+ return E.Cause(err, "windivert: initialize ioctl")
+ }
+ gotMagic := binary.LittleEndian.Uint64(outBuf[0:8])
+ if gotMagic != magicSYS {
+ return E.New("windivert: driver magic mismatch (got ", gotMagic, ")")
+ }
+ gotMajor := binary.LittleEndian.Uint32(outBuf[8:12])
+ if gotMajor < versionMajor {
+ gotMinor := binary.LittleEndian.Uint32(outBuf[12:16])
+ return E.New("windivert: driver version too old: ", gotMajor, ".", gotMinor)
+ }
+ return nil
+}
+
+func (h *Handle) startup(filterBin []byte, filterFlags uint64) error {
+ in := buildIoctlStartup(filterFlags)
+ _, err := doIoctl(h.device, ioctlStartup, in[:], filterBin, h.event)
+ if err != nil {
+ return E.Cause(err, "windivert: startup ioctl")
+ }
+ return nil
+}
+
+// If the handle is closed mid-Recv the error wraps ERROR_OPERATION_ABORTED.
+func (h *Handle) Recv(buf []byte) (int, Address, error) {
+ if len(buf) == 0 {
+ return 0, Address{}, E.New("windivert: recv: zero-length buffer")
+ }
+ h.addr = Address{}
+ in := buildIoctlRecv(&h.addr)
+ n, err := doIoctl(h.device, ioctlRecv, in[:], buf, h.event)
+ runtime.KeepAlive(h)
+ if err != nil {
+ return 0, Address{}, err
+ }
+ return int(n), h.addr, nil
+}
+
+// The address's Outbound flag controls whether the packet is sent toward
+// the wire (outbound=true) or delivered up the stack (outbound=false).
+// IfIdx and SubIfIdx can stay zero — the driver uses the routing table
+// when IfIdx=0.
+func (h *Handle) Send(packet []byte, addr *Address) (int, error) {
+ if len(packet) == 0 {
+ return 0, E.New("windivert: send: empty packet")
+ }
+ if addr == nil {
+ return 0, E.New("windivert: send: nil address")
+ }
+ h.addr = *addr
+ in := buildIoctlSend(&h.addr)
+ n, err := doIoctl(h.device, ioctlSend, in[:], packet, h.event)
+ runtime.KeepAlive(h)
+ if err != nil {
+ return 0, err
+ }
+ return int(n), nil
+}
+
+// Idempotent. Aborts any in-flight I/O on the handle.
+func (h *Handle) Close() error {
+ h.closing.Do(func() {
+ var errs []error
+ if h.device != 0 {
+ err := windows.CloseHandle(h.device)
+ if err != nil {
+ errs = append(errs, err)
+ }
+ h.device = 0
+ }
+ if h.event != 0 {
+ err := windows.CloseHandle(h.event)
+ if err != nil {
+ errs = append(errs, err)
+ }
+ h.event = 0
+ }
+ h.closeErr = E.Errors(errs...)
+ })
+ return h.closeErr
+}
+
+// IOCTL codes from windivert_device.h. CTL_CODE macro layout:
+//
+// (DeviceType << 16) | (Access << 14) | (Function << 2) | Method
+const (
+ fileDeviceNetwork uint32 = 0x12
+ accessReadWrite uint32 = 3 // FILE_READ_DATA | FILE_WRITE_DATA
+ accessRead uint32 = 1
+
+ methodInDirect uint32 = 1
+ methodOutDirect uint32 = 2
+)
+
+func ctlCode(deviceType, access, function, method uint32) uint32 {
+ return (deviceType << 16) | (access << 14) | (function << 2) | method
+}
+
+var (
+ ioctlInitialize = ctlCode(fileDeviceNetwork, accessReadWrite, 0x921, methodOutDirect)
+ ioctlStartup = ctlCode(fileDeviceNetwork, accessReadWrite, 0x922, methodInDirect)
+ ioctlRecv = ctlCode(fileDeviceNetwork, accessRead, 0x923, methodOutDirect)
+ ioctlSend = ctlCode(fileDeviceNetwork, accessReadWrite, 0x924, methodInDirect)
+)
+
+// Magic numbers exchanged during INITIALIZE. DLL sends magicDLL in the
+// version struct; driver returns magicSYS on success.
+const (
+ magicDLL uint64 = 0x4C4C447669645724 // "$WdivDLL" in LE bytes
+ magicSYS uint64 = 0x5359537669645723 // "#WdivSYS" in LE bytes
+)
+
+const (
+ versionMajor uint32 = 2
+ versionMinor uint32 = 2
+)
+
+// Size of the WINDIVERT_IOCTL union on wire (packed).
+const ioctlSize = 16
+
+// Size of WINDIVERT_VERSION on wire (packed). Only the first 20 bytes
+// carry data; the rest is reserved zero padding.
+const versionStructSize = 64
+
+// doIoctl performs a single synchronous (blocking) overlapped
+// DeviceIoControl. The handle is opened with FILE_FLAG_OVERLAPPED so
+// DeviceIoControl returns ERROR_IO_PENDING; we then wait for completion
+// via GetOverlappedResult. Event is passed in so callers can reuse it
+// across calls on the same handle (avoids per-call CreateEvent).
+func doIoctl(handle windows.Handle, code uint32, in []byte, out []byte, event windows.Handle) (uint32, error) {
+ var overlapped windows.Overlapped
+ overlapped.HEvent = event
+ _ = windows.ResetEvent(event)
+
+ var inPtr *byte
+ var inLen uint32
+ if len(in) > 0 {
+ inPtr = &in[0]
+ inLen = uint32(len(in))
+ }
+ var outPtr *byte
+ var outLen uint32
+ if len(out) > 0 {
+ outPtr = &out[0]
+ outLen = uint32(len(out))
+ }
+ var returned uint32
+ err := windows.DeviceIoControl(handle, code, inPtr, inLen, outPtr, outLen, &returned, &overlapped)
+ if err != nil && !errors.Is(err, windows.ERROR_IO_PENDING) {
+ return 0, err
+ }
+ err = windows.GetOverlappedResult(handle, &overlapped, &returned, true)
+ if err != nil {
+ return 0, err
+ }
+ return returned, nil
+}
+
+func buildIoctlInitialize(layer Layer, priority int16, flags Flag) [ioctlSize]byte {
+ var buf [ioctlSize]byte
+ binary.LittleEndian.PutUint32(buf[0:4], uint32(layer))
+ // The driver expects priority + WINDIVERT_PRIORITY_HIGHEST (30000) so
+ // the low range maps to non-negative integers.
+ binary.LittleEndian.PutUint32(buf[4:8], uint32(int32(priority)+int32(PriorityHighest)))
+ binary.LittleEndian.PutUint64(buf[8:16], uint64(flags))
+ return buf
+}
+
+func buildIoctlStartup(filterFlags uint64) [ioctlSize]byte {
+ var buf [ioctlSize]byte
+ binary.LittleEndian.PutUint64(buf[0:8], filterFlags)
+ return buf
+}
+
+// buildIoctlRecv packs a user-space pointer to a WINDIVERT_ADDRESS into
+// the ioctl struct. The driver dereferences it to write the address for
+// the received packet. Caller must keep the Address alive via
+// runtime.KeepAlive.
+func buildIoctlRecv(addr *Address) [ioctlSize]byte {
+ var buf [ioctlSize]byte
+ binary.LittleEndian.PutUint64(buf[0:8], uint64(uintptr(unsafe.Pointer(addr))))
+ binary.LittleEndian.PutUint64(buf[8:16], 0)
+ return buf
+}
+
+func buildIoctlSend(addr *Address) [ioctlSize]byte {
+ var buf [ioctlSize]byte
+ binary.LittleEndian.PutUint64(buf[0:8], uint64(uintptr(unsafe.Pointer(addr))))
+ binary.LittleEndian.PutUint64(buf[8:16], uint64(unsafe.Sizeof(Address{})))
+ return buf
+}
diff --git a/common/windivert/handle_windows_test.go b/common/windivert/handle_windows_test.go
new file mode 100644
index 0000000000..73dfbb166a
--- /dev/null
+++ b/common/windivert/handle_windows_test.go
@@ -0,0 +1,109 @@
+//go:build windows
+
+package windivert
+
+import (
+ "encoding/binary"
+ "testing"
+ "unsafe"
+
+ "github.com/stretchr/testify/require"
+)
+
+// CTL_CODE macro from Windows DDK:
+//
+// (DeviceType<<16) | (Access<<14) | (Function<<2) | Method
+func TestCtlCodeMatchesDDK(t *testing.T) {
+ t.Parallel()
+ // FILE_DEVICE_NETWORK=0x12, FILE_READ_DATA|FILE_WRITE_DATA=3, METHOD_OUT_DIRECT=2
+ require.Equal(t, uint32(0x12E486), ctlCode(0x12, 3, 0x921, 2))
+ // FILE_READ_DATA=1, METHOD_OUT_DIRECT=2
+ require.Equal(t, uint32(0x12648E), ctlCode(0x12, 1, 0x923, 2))
+}
+
+// Baked-in against windivert_device.h @ v2.2.2. A mismatch here means the
+// kernel will reject every ioctl with ERROR_INVALID_FUNCTION.
+func TestIoctlCodesMatchUpstream(t *testing.T) {
+ t.Parallel()
+ require.Equal(t, uint32(0x12E486), ioctlInitialize)
+ require.Equal(t, uint32(0x12E489), ioctlStartup)
+ require.Equal(t, uint32(0x12648E), ioctlRecv)
+ require.Equal(t, uint32(0x12E491), ioctlSend)
+}
+
+func TestBuildIoctlInitialize(t *testing.T) {
+ t.Parallel()
+ buf := buildIoctlInitialize(LayerNetwork, 100, FlagSendOnly)
+ require.Equal(t, uint32(LayerNetwork), binary.LittleEndian.Uint32(buf[0:4]))
+ // Driver expects priority+PriorityHighest(30000) so the range is non-negative.
+ require.Equal(t, uint32(30100), binary.LittleEndian.Uint32(buf[4:8]))
+ require.Equal(t, uint64(FlagSendOnly), binary.LittleEndian.Uint64(buf[8:16]))
+}
+
+func TestBuildIoctlInitializePriorityRange(t *testing.T) {
+ t.Parallel()
+ lowest := buildIoctlInitialize(LayerNetwork, PriorityLowest, 0)
+ require.Equal(t, uint32(0), binary.LittleEndian.Uint32(lowest[4:8]))
+ highest := buildIoctlInitialize(LayerNetwork, PriorityHighest, 0)
+ require.Equal(t, uint32(60000), binary.LittleEndian.Uint32(highest[4:8]))
+ zero := buildIoctlInitialize(LayerNetwork, 0, 0)
+ require.Equal(t, uint32(30000), binary.LittleEndian.Uint32(zero[4:8]))
+}
+
+func TestBuildIoctlStartup(t *testing.T) {
+ t.Parallel()
+ flags := filterFlagOutbound | filterFlagIP
+ buf := buildIoctlStartup(flags)
+ require.Equal(t, flags, binary.LittleEndian.Uint64(buf[0:8]))
+ // The second quad-word is unused for STARTUP.
+ require.Equal(t, uint64(0), binary.LittleEndian.Uint64(buf[8:16]))
+}
+
+func TestBuildIoctlRecvEmbedsAddressPointer(t *testing.T) {
+ t.Parallel()
+ addr := &Address{Timestamp: 0xCAFEBABE}
+ buf := buildIoctlRecv(addr)
+ require.Equal(t, uint64(uintptr(unsafe.Pointer(addr))),
+ binary.LittleEndian.Uint64(buf[0:8]))
+ // RECV does not carry an address length; driver writes full Address back.
+ require.Equal(t, uint64(0), binary.LittleEndian.Uint64(buf[8:16]))
+}
+
+func TestBuildIoctlSendEmbedsAddressPointerAndSize(t *testing.T) {
+ t.Parallel()
+ addr := &Address{}
+ buf := buildIoctlSend(addr)
+ require.Equal(t, uint64(uintptr(unsafe.Pointer(addr))),
+ binary.LittleEndian.Uint64(buf[0:8]))
+ require.Equal(t, uint64(unsafe.Sizeof(Address{})),
+ binary.LittleEndian.Uint64(buf[8:16]))
+ require.Equal(t, uint64(80), binary.LittleEndian.Uint64(buf[8:16]))
+}
+
+func TestValidateOpenArgsLayer(t *testing.T) {
+ t.Parallel()
+ require.NoError(t, validateOpenArgs(LayerNetwork, 0, 0))
+ require.Error(t, validateOpenArgs(Layer(1), 0, 0))
+ require.Error(t, validateOpenArgs(Layer(42), 0, 0))
+}
+
+func TestValidateOpenArgsPriorityBounds(t *testing.T) {
+ t.Parallel()
+ require.NoError(t, validateOpenArgs(LayerNetwork, PriorityHighest, 0))
+ require.NoError(t, validateOpenArgs(LayerNetwork, PriorityLowest, 0))
+ require.NoError(t, validateOpenArgs(LayerNetwork, 0, 0))
+ require.Error(t, validateOpenArgs(LayerNetwork, PriorityHighest+1, 0))
+ require.Error(t, validateOpenArgs(LayerNetwork, PriorityLowest-1, 0))
+}
+
+func TestValidateOpenArgsFlags(t *testing.T) {
+ t.Parallel()
+ require.NoError(t, validateOpenArgs(LayerNetwork, 0, 0))
+ require.NoError(t, validateOpenArgs(LayerNetwork, 0, FlagSendOnly))
+ require.NoError(t, validateOpenArgs(LayerNetwork, 0, FlagSniff))
+ // Sniff and send-only describe contradictory handle roles.
+ require.Error(t, validateOpenArgs(LayerNetwork, 0, FlagSniff|FlagSendOnly))
+ // Unknown flag bits must be rejected to surface caller mistakes early.
+ require.Error(t, validateOpenArgs(LayerNetwork, 0, Flag(0x10)))
+ require.Error(t, validateOpenArgs(LayerNetwork, 0, FlagSendOnly|Flag(0x10)))
+}
diff --git a/common/windivert/integration_windows_test.go b/common/windivert/integration_windows_test.go
new file mode 100644
index 0000000000..1b4ce958cc
--- /dev/null
+++ b/common/windivert/integration_windows_test.go
@@ -0,0 +1,88 @@
+//go:build windows
+
+package windivert
+
+import (
+ "errors"
+ "net/netip"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+ "golang.org/x/sys/windows"
+)
+
+func openHandle(t *testing.T, filter *Filter, flags Flag) *Handle {
+ t.Helper()
+ h, err := Open(filter, LayerNetwork, 0, flags)
+ require.NoError(t, err)
+ return h
+}
+
+// A send-only handle installs+opens the driver but does not attach a
+// receive filter, so it exercises the full driver-install path without
+// diverting any live traffic on the host.
+func TestIntegrationOpenSendOnly(t *testing.T) {
+ h := openHandle(t, nil, FlagSendOnly)
+ require.NoError(t, h.Close())
+}
+
+// Close is idempotent per the doc contract.
+func TestIntegrationCloseTwice(t *testing.T) {
+ h := openHandle(t, nil, FlagSendOnly)
+ require.NoError(t, h.Close())
+ require.NoError(t, h.Close())
+}
+
+// Recv must unblock when the handle is closed concurrently. Without this,
+// the spoofer's run goroutine could deadlock on shutdown.
+func TestIntegrationRecvAbortsOnClose(t *testing.T) {
+ // A filter no live traffic will match, so Recv blocks indefinitely
+ // until Close aborts the overlapped I/O.
+ filter, err := OutboundTCP(
+ netip.MustParseAddrPort("10.255.255.254:1"),
+ netip.MustParseAddrPort("10.255.255.253:2"),
+ )
+ require.NoError(t, err)
+ h := openHandle(t, filter, 0)
+
+ errCh := make(chan error, 1)
+ go func() {
+ buf := make([]byte, MTUMax)
+ _, _, recvErr := h.Recv(buf)
+ errCh <- recvErr
+ }()
+
+ // Let Recv reach the blocking DeviceIoControl before Close races in.
+ time.Sleep(200 * time.Millisecond)
+ require.NoError(t, h.Close())
+
+ select {
+ case err := <-errCh:
+ require.Error(t, err)
+ require.True(t, errors.Is(err, windows.ERROR_OPERATION_ABORTED),
+ "Recv should return ERROR_OPERATION_ABORTED, got %v", err)
+ case <-time.After(3 * time.Second):
+ t.Fatal("Recv did not unblock within 3s after Close")
+ }
+}
+
+// Two concurrent Open calls must both succeed: the first wins the driver
+// install race, the second reuses the already-running service.
+func TestIntegrationConcurrentOpen(t *testing.T) {
+ errCh := make(chan error, 2)
+ handles := make(chan *Handle, 2)
+ for range 2 {
+ go func() {
+ h, err := Open(nil, LayerNetwork, 0, FlagSendOnly)
+ handles <- h
+ errCh <- err
+ }()
+ }
+ for range 2 {
+ err := <-errCh
+ h := <-handles
+ require.NoError(t, err)
+ require.NoError(t, h.Close())
+ }
+}
diff --git a/common/windivert/windivert.go b/common/windivert/windivert.go
new file mode 100644
index 0000000000..619e41b611
--- /dev/null
+++ b/common/windivert/windivert.go
@@ -0,0 +1,78 @@
+// Package windivert provides a pure-Go binding to the WinDivert kernel
+// driver on Windows (amd64 and 386). User-mode WinDivert calls are
+// reimplemented in Go; only the signed kernel driver is embedded as an
+// asset, since SCM-installed drivers must live on disk and their
+// Authenticode signature forbids modification.
+//
+// Administrator is required for the first Open in a process so SCM can
+// load the driver. Upstream: https://github.com/basil00/WinDivert v2.2.2,
+// redistributed under its LGPL v3 option; see assets/LICENSE.txt.
+package windivert
+
+import "unsafe"
+
+const AssetVersion = "2.2.2"
+
+// MTUMax is WINDIVERT_MTU_MAX from windivert.h (40 + 0xFFFF). Suitable as
+// a single-packet receive buffer size.
+const MTUMax = 40 + 0xFFFF
+
+type Layer uint32
+
+const LayerNetwork Layer = 0
+
+type Flag uint64
+
+const (
+ // FlagSniff opens a passive observer: the driver copies matching packets
+ // to userspace without removing them from the network stack. Send is not
+ // required (and not allowed) on a sniffing handle.
+ FlagSniff Flag = 0x0001
+ // FlagSendOnly opens a write-only injection handle; Recv is not allowed.
+ FlagSendOnly Flag = 0x0008
+)
+
+const (
+ PriorityHighest int16 = 30000
+ PriorityLowest int16 = -30000
+)
+
+// Address mirrors WINDIVERT_ADDRESS from windivert.h (80 bytes,
+// little-endian on both amd64 and 386):
+//
+// 0: INT64 Timestamp
+// 8: UINT32 bitfield: Layer:8 | Event:8 | flags | Reserved1:8
+// 12: UINT32 Reserved2
+// 16: 64 bytes union (WINDIVERT_DATA_NETWORK / FLOW / SOCKET / REFLECT)
+type Address struct {
+ Timestamp int64
+ bits uint32
+ Reserved2 uint32
+ _ [64]byte
+}
+
+var _ [80]byte = [unsafe.Sizeof(Address{})]byte{}
+
+// Bit positions inside the Address's packed flags word.
+const (
+ addrBitIPv6 = 20
+ addrBitIPChecksum = 21
+ addrBitTCPChecksum = 22
+)
+
+func getFlagBit(bits uint32, pos uint) bool { return bits&(1<= Size {
+ buf = buf[:Size]
+ } else {
+ buf = make([]byte, Size)
+ }
+
+ return &Buffer{
+ v: buf,
+ }
+}
+
+// NewExisted creates a standard size Buffer with an existed bytearray, managed.
+func NewExisted(b []byte) *Buffer {
+ if cap(b) < Size {
+ panic("Invalid buffer")
+ }
+
+ oLen := len(b)
+ if oLen < Size {
+ b = b[:Size]
+ }
+
+ return &Buffer{
+ v: b,
+ end: int32(oLen),
+ }
+}
+
+// FromBytes creates a Buffer with an existed bytearray, unmanaged.
+func FromBytes(b []byte) *Buffer {
+ return &Buffer{
+ v: b,
+ end: int32(len(b)),
+ ownership: unmanaged,
+ }
+}
+
+// StackNew creates a new Buffer object on stack, managed.
+// This method is for buffers that is released in the same function.
+func StackNew() Buffer {
+ buf := pool.Get().([]byte)
+ if cap(buf) >= Size {
+ buf = buf[:Size]
+ } else {
+ buf = make([]byte, Size)
+ }
+
+ return Buffer{
+ v: buf,
+ }
+}
+
+// NewWithSize creates a Buffer with 0 length and capacity with at least the given size, bytespool's.
+func NewWithSize(size int32) *Buffer {
+ return &Buffer{
+ v: bytespool.Alloc(size),
+ ownership: bytespools,
+ }
+}
+
+// Release recycles the buffer into an internal buffer pool.
+func (b *Buffer) Release() {
+ if b == nil || b.v == nil || b.ownership == unmanaged {
+ return
+ }
+
+ p := b.v
+ b.v = nil
+ b.Clear()
+
+ switch b.ownership {
+ case managed:
+ if cap(p) == Size {
+ pool.Put(p)
+ }
+ case bytespools:
+ bytespool.Free(p)
+ }
+ b.UDP = nil
+}
+
+// Clear clears the content of the buffer, results an empty buffer with
+// Len() = 0.
+func (b *Buffer) Clear() {
+ b.start = 0
+ b.end = 0
+}
+
+// Byte returns the bytes at index.
+func (b *Buffer) Byte(index int32) byte {
+ return b.v[b.start+index]
+}
+
+// SetByte sets the byte value at index.
+func (b *Buffer) SetByte(index int32, value byte) {
+ b.v[b.start+index] = value
+}
+
+// Bytes returns the content bytes of this Buffer.
+func (b *Buffer) Bytes() []byte {
+ return b.v[b.start:b.end]
+}
+
+// Extend increases the buffer size by n bytes, and returns the extended part.
+// It panics if result size is larger than size of this buffer.
+func (b *Buffer) Extend(n int32) []byte {
+ end := b.end + n
+ if end > int32(len(b.v)) {
+ panic("extending out of bound")
+ }
+ ext := b.v[b.end:end]
+ b.end = end
+ clear(ext)
+ return ext
+}
+
+// BytesRange returns a slice of this buffer with given from and to boundary.
+func (b *Buffer) BytesRange(from, to int32) []byte {
+ if from < 0 {
+ from += b.Len()
+ }
+ if to < 0 {
+ to += b.Len()
+ }
+ return b.v[b.start+from : b.start+to]
+}
+
+// BytesFrom returns a slice of this Buffer starting from the given position.
+func (b *Buffer) BytesFrom(from int32) []byte {
+ if from < 0 {
+ from += b.Len()
+ }
+ return b.v[b.start+from : b.end]
+}
+
+// BytesTo returns a slice of this Buffer from start to the given position.
+func (b *Buffer) BytesTo(to int32) []byte {
+ if to < 0 {
+ to += b.Len()
+ }
+ if to < 0 {
+ to = 0
+ }
+ return b.v[b.start : b.start+to]
+}
+
+// Check makes sure that 0 <= b.start <= b.end.
+func (b *Buffer) Check() {
+ if b.start < 0 {
+ b.start = 0
+ }
+ if b.end < 0 {
+ b.end = 0
+ }
+ if b.start > b.end {
+ b.start = b.end
+ }
+}
+
+// Resize cuts the buffer at the given position.
+func (b *Buffer) Resize(from, to int32) {
+ oldEnd := b.end
+ if from < 0 {
+ from += b.Len()
+ }
+ if to < 0 {
+ to += b.Len()
+ }
+ if to < from {
+ panic("Invalid slice")
+ }
+ b.end = b.start + to
+ b.start += from
+ b.Check()
+ if b.end > oldEnd {
+ clear(b.v[oldEnd:b.end])
+ }
+}
+
+// Advance cuts the buffer at the given position.
+func (b *Buffer) Advance(from int32) {
+ if from < 0 {
+ from += b.Len()
+ }
+ b.start += from
+ b.Check()
+}
+
+// Len returns the length of the buffer content.
+func (b *Buffer) Len() int32 {
+ if b == nil {
+ return 0
+ }
+ return b.end - b.start
+}
+
+// Cap returns the capacity of the buffer content.
+func (b *Buffer) Cap() int32 {
+ if b == nil {
+ return 0
+ }
+ return int32(len(b.v))
+}
+
+// Available returns the available capacity of the buffer content.
+func (b *Buffer) Available() int32 {
+ if b == nil {
+ return 0
+ }
+ return int32(len(b.v)) - b.end
+}
+
+// IsEmpty returns true if the buffer is empty.
+func (b *Buffer) IsEmpty() bool {
+ return b.Len() == 0
+}
+
+// IsFull returns true if the buffer has no more room to grow.
+func (b *Buffer) IsFull() bool {
+ return b != nil && b.end == int32(len(b.v))
+}
+
+// Write implements Write method in io.Writer.
+func (b *Buffer) Write(data []byte) (int, error) {
+ nBytes := copy(b.v[b.end:], data)
+ b.end += int32(nBytes)
+ if nBytes < len(data) {
+ return nBytes, ErrBufferFull
+ }
+ return nBytes, nil
+}
+
+// WriteByte writes a single byte into the buffer.
+func (b *Buffer) WriteByte(v byte) error {
+ if b.IsFull() {
+ return ErrBufferFull
+ }
+ b.v[b.end] = v
+ b.end++
+ return nil
+}
+
+// WriteString implements io.StringWriter.
+func (b *Buffer) WriteString(s string) (int, error) {
+ return b.Write([]byte(s))
+}
+
+// ReadByte implements io.ByteReader
+func (b *Buffer) ReadByte() (byte, error) {
+ if b.start == b.end {
+ return 0, io.EOF
+ }
+
+ nb := b.v[b.start]
+ b.start++
+ return nb, nil
+}
+
+// ReadBytes implements bufio.Reader.ReadBytes
+func (b *Buffer) ReadBytes(length int32) ([]byte, error) {
+ if b.end-b.start < length {
+ return nil, io.EOF
+ }
+
+ nb := b.v[b.start : b.start+length]
+ b.start += length
+ return nb, nil
+}
+
+// Read implements io.Reader.Read().
+func (b *Buffer) Read(data []byte) (int, error) {
+ if b.Len() == 0 {
+ return 0, io.EOF
+ }
+ nBytes := copy(data, b.v[b.start:b.end])
+ if int32(nBytes) == b.Len() {
+ b.Clear()
+ } else {
+ b.start += int32(nBytes)
+ }
+ return nBytes, nil
+}
+
+// ReadFrom implements io.ReaderFrom.
+func (b *Buffer) ReadFrom(reader io.Reader) (int64, error) {
+ n, err := reader.Read(b.v[b.end:])
+ b.end += int32(n)
+ return int64(n), err
+}
+
+// ReadFullFrom reads exact size of bytes from given reader, or until error occurs.
+func (b *Buffer) ReadFullFrom(reader io.Reader, size int32) (int64, error) {
+ end := b.end + size
+ if end > int32(len(b.v)) {
+ v := end
+ return 0, E.New("out of bound: ", v)
+ }
+ n, err := io.ReadFull(reader, b.v[b.end:end])
+ b.end += int32(n)
+ return int64(n), err
+}
+
+// String returns the string form of this Buffer.
+func (b *Buffer) String() string {
+ return string(b.Bytes())
+}
diff --git a/common/xray/buf/copy.go b/common/xray/buf/copy.go
new file mode 100644
index 0000000000..efab0e175a
--- /dev/null
+++ b/common/xray/buf/copy.go
@@ -0,0 +1,124 @@
+package buf
+
+import (
+ "io"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/errors"
+ "github.com/sagernet/sing-box/common/xray/signal"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type dataHandler func(MultiBuffer)
+
+type copyHandler struct {
+ onData []dataHandler
+}
+
+// SizeCounter is for counting bytes copied by Copy().
+type SizeCounter struct {
+ Size int64
+}
+
+// CopyOption is an option for copying data.
+type CopyOption func(*copyHandler)
+
+// UpdateActivity is a CopyOption to update activity on each data copy operation.
+func UpdateActivity(timer signal.ActivityUpdater) CopyOption {
+ return func(handler *copyHandler) {
+ handler.onData = append(handler.onData, func(MultiBuffer) {
+ timer.Update()
+ })
+ }
+}
+
+// CountSize is a CopyOption that sums the total size of data copied into the given SizeCounter.
+func CountSize(sc *SizeCounter) CopyOption {
+ return func(handler *copyHandler) {
+ handler.onData = append(handler.onData, func(b MultiBuffer) {
+ sc.Size += int64(b.Len())
+ })
+ }
+}
+
+type readError struct {
+ error
+}
+
+func (e readError) Error() string {
+ return e.error.Error()
+}
+
+func (e readError) Unwrap() error {
+ return e.error
+}
+
+// IsReadError returns true if the error in Copy() comes from reading.
+func IsReadError(err error) bool {
+ _, ok := err.(readError)
+ return ok
+}
+
+type writeError struct {
+ error
+}
+
+func (e writeError) Error() string {
+ return e.error.Error()
+}
+
+func (e writeError) Unwrap() error {
+ return e.error
+}
+
+// IsWriteError returns true if the error in Copy() comes from writing.
+func IsWriteError(err error) bool {
+ _, ok := err.(writeError)
+ return ok
+}
+
+func copyInternal(reader Reader, writer Writer, handler *copyHandler) error {
+ for {
+ buffer, err := reader.ReadMultiBuffer()
+ if !buffer.IsEmpty() {
+ for _, handler := range handler.onData {
+ handler(buffer)
+ }
+
+ if werr := writer.WriteMultiBuffer(buffer); werr != nil {
+ return writeError{werr}
+ }
+ }
+
+ if err != nil {
+ return readError{err}
+ }
+ }
+}
+
+// Copy dumps all payload from reader to writer or stops when an error occurs. It returns nil when EOF.
+func Copy(reader Reader, writer Writer, options ...CopyOption) error {
+ var handler copyHandler
+ for _, option := range options {
+ option(&handler)
+ }
+ err := copyInternal(reader, writer, &handler)
+ if err != nil && errors.Cause(err) != io.EOF {
+ return err
+ }
+ return nil
+}
+
+var ErrNotTimeoutReader = E.New("not a TimeoutReader")
+
+func CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration) error {
+ timeoutReader, ok := reader.(TimeoutReader)
+ if !ok {
+ return ErrNotTimeoutReader
+ }
+ mb, err := timeoutReader.ReadMultiBufferTimeout(timeout)
+ if err != nil {
+ return err
+ }
+ return writer.WriteMultiBuffer(mb)
+}
diff --git a/common/xray/buf/io.go b/common/xray/buf/io.go
new file mode 100644
index 0000000000..5b7826e0de
--- /dev/null
+++ b/common/xray/buf/io.go
@@ -0,0 +1,127 @@
+package buf
+
+import (
+ "io"
+ "net"
+ "syscall"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/stat"
+ "github.com/sagernet/sing-box/common/xray/stats"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+// Reader extends io.Reader with MultiBuffer.
+type Reader interface {
+ // ReadMultiBuffer reads content from underlying reader, and put it into a MultiBuffer.
+ ReadMultiBuffer() (MultiBuffer, error)
+}
+
+// ErrReadTimeout is an error that happens with IO timeout.
+var ErrReadTimeout = E.New("IO timeout")
+
+// TimeoutReader is a reader that returns error if Read() operation takes longer than the given timeout.
+type TimeoutReader interface {
+ Reader
+ ReadMultiBufferTimeout(time.Duration) (MultiBuffer, error)
+}
+
+// Writer extends io.Writer with MultiBuffer.
+type Writer interface {
+ // WriteMultiBuffer writes a MultiBuffer into underlying writer.
+ WriteMultiBuffer(MultiBuffer) error
+}
+
+// WriteAllBytes ensures all bytes are written into the given writer.
+func WriteAllBytes(writer io.Writer, payload []byte, c stats.Counter) error {
+ wc := 0
+ defer func() {
+ if c != nil {
+ c.Add(int64(wc))
+ }
+ }()
+
+ for len(payload) > 0 {
+ n, err := writer.Write(payload)
+ wc += n
+ if err != nil {
+ return err
+ }
+ payload = payload[n:]
+ }
+ return nil
+}
+
+func isPacketReader(reader io.Reader) bool {
+ _, ok := reader.(net.PacketConn)
+ return ok
+}
+
+// NewReader creates a new Reader.
+// The Reader instance doesn't take the ownership of reader.
+func NewReader(reader io.Reader) Reader {
+ if mr, ok := reader.(Reader); ok {
+ return mr
+ }
+
+ if isPacketReader(reader) {
+ return &PacketReader{
+ Reader: reader,
+ }
+ }
+
+ return &SingleReader{
+ Reader: reader,
+ }
+}
+
+// NewPacketReader creates a new PacketReader based on the given reader.
+func NewPacketReader(reader io.Reader) Reader {
+ if mr, ok := reader.(Reader); ok {
+ return mr
+ }
+
+ return &PacketReader{
+ Reader: reader,
+ }
+}
+
+func isPacketWriter(writer io.Writer) bool {
+ if _, ok := writer.(net.PacketConn); ok {
+ return true
+ }
+
+ // If the writer doesn't implement syscall.Conn, it is probably not a TCP connection.
+ if _, ok := writer.(syscall.Conn); !ok {
+ return true
+ }
+ return false
+}
+
+// NewWriter creates a new Writer.
+func NewWriter(writer io.Writer) Writer {
+ if mw, ok := writer.(Writer); ok {
+ return mw
+ }
+
+ iConn := writer
+ if statConn, ok := writer.(*stat.CounterConnection); ok {
+ iConn = statConn.Connection
+ }
+
+ if isPacketWriter(iConn) {
+ return &SequentialWriter{
+ Writer: writer,
+ }
+ }
+
+ var counter stats.Counter
+
+ if statConn, ok := writer.(*stat.CounterConnection); ok {
+ counter = statConn.WriteCounter
+ }
+ return &BufferToBytesWriter{
+ Writer: iConn,
+ counter: counter,
+ }
+}
diff --git a/common/xray/buf/multi_buffer.go b/common/xray/buf/multi_buffer.go
new file mode 100644
index 0000000000..44dd499c00
--- /dev/null
+++ b/common/xray/buf/multi_buffer.go
@@ -0,0 +1,310 @@
+package buf
+
+import (
+ "io"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/errors"
+ "github.com/sagernet/sing-box/common/xray/serial"
+)
+
+// ReadAllToBytes reads all content from the reader into a byte array, until EOF.
+func ReadAllToBytes(reader io.Reader) ([]byte, error) {
+ mb, err := ReadFrom(reader)
+ if err != nil {
+ return nil, err
+ }
+ if mb.Len() == 0 {
+ return nil, nil
+ }
+ b := make([]byte, mb.Len())
+ mb, _ = SplitBytes(mb, b)
+ ReleaseMulti(mb)
+ return b, nil
+}
+
+// MultiBuffer is a list of Buffers. The order of Buffer matters.
+type MultiBuffer []*Buffer
+
+// MergeMulti merges content from src to dest, and returns the new address of dest and src
+func MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBuffer) {
+ dest = append(dest, src...)
+ for idx := range src {
+ src[idx] = nil
+ }
+ return dest, src[:0]
+}
+
+// MergeBytes merges the given bytes into MultiBuffer and return the new address of the merged MultiBuffer.
+func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer {
+ n := len(dest)
+ if n > 0 && !(dest)[n-1].IsFull() {
+ nBytes, _ := (dest)[n-1].Write(src)
+ src = src[nBytes:]
+ }
+
+ for len(src) > 0 {
+ b := New()
+ nBytes, _ := b.Write(src)
+ src = src[nBytes:]
+ dest = append(dest, b)
+ }
+
+ return dest
+}
+
+// ReleaseMulti releases all content of the MultiBuffer, and returns an empty MultiBuffer.
+func ReleaseMulti(mb MultiBuffer) MultiBuffer {
+ for i := range mb {
+ mb[i].Release()
+ mb[i] = nil
+ }
+ return mb[:0]
+}
+
+// Copy copied the beginning part of the MultiBuffer into the given byte array.
+func (mb MultiBuffer) Copy(b []byte) int {
+ total := 0
+ for _, bb := range mb {
+ nBytes := copy(b[total:], bb.Bytes())
+ total += nBytes
+ if int32(nBytes) < bb.Len() {
+ break
+ }
+ }
+ return total
+}
+
+// ReadFrom reads all content from reader until EOF.
+func ReadFrom(reader io.Reader) (MultiBuffer, error) {
+ mb := make(MultiBuffer, 0, 16)
+ for {
+ b := New()
+ _, err := b.ReadFullFrom(reader, Size)
+ if b.IsEmpty() {
+ b.Release()
+ } else {
+ mb = append(mb, b)
+ }
+ if err != nil {
+ if errors.Cause(err) == io.EOF || errors.Cause(err) == io.ErrUnexpectedEOF {
+ return mb, nil
+ }
+ return mb, err
+ }
+ }
+}
+
+// SplitBytes splits the given amount of bytes from the beginning of the MultiBuffer.
+// It returns the new address of MultiBuffer leftover, and number of bytes written into the input byte slice.
+func SplitBytes(mb MultiBuffer, b []byte) (MultiBuffer, int) {
+ totalBytes := 0
+ endIndex := -1
+ for i := range mb {
+ pBuffer := mb[i]
+ nBytes, _ := pBuffer.Read(b)
+ totalBytes += nBytes
+ b = b[nBytes:]
+ if !pBuffer.IsEmpty() {
+ endIndex = i
+ break
+ }
+ pBuffer.Release()
+ mb[i] = nil
+ }
+
+ if endIndex == -1 {
+ mb = mb[:0]
+ } else {
+ mb = mb[endIndex:]
+ }
+
+ return mb, totalBytes
+}
+
+// SplitFirstBytes splits the first buffer from MultiBuffer, and then copy its content into the given slice.
+func SplitFirstBytes(mb MultiBuffer, p []byte) (MultiBuffer, int) {
+ mb, b := SplitFirst(mb)
+ if b == nil {
+ return mb, 0
+ }
+ n := copy(p, b.Bytes())
+ b.Release()
+ return mb, n
+}
+
+// Compact returns another MultiBuffer by merging all content of the given one together.
+func Compact(mb MultiBuffer) MultiBuffer {
+ if len(mb) == 0 {
+ return mb
+ }
+
+ mb2 := make(MultiBuffer, 0, len(mb))
+ last := mb[0]
+
+ for i := 1; i < len(mb); i++ {
+ curr := mb[i]
+ if curr.Len() > last.Available() {
+ mb2 = append(mb2, last)
+ last = curr
+ } else {
+ common.Must2(last.ReadFrom(curr))
+ curr.Release()
+ }
+ }
+
+ mb2 = append(mb2, last)
+ return mb2
+}
+
+// SplitFirst splits the first Buffer from the beginning of the MultiBuffer.
+func SplitFirst(mb MultiBuffer) (MultiBuffer, *Buffer) {
+ if len(mb) == 0 {
+ return mb, nil
+ }
+
+ b := mb[0]
+ mb[0] = nil
+ mb = mb[1:]
+ return mb, b
+}
+
+// SplitSize splits the beginning of the MultiBuffer into another one, for at most size bytes.
+func SplitSize(mb MultiBuffer, size int32) (MultiBuffer, MultiBuffer) {
+ if len(mb) == 0 {
+ return mb, nil
+ }
+
+ if mb[0].Len() > size {
+ b := New()
+ copy(b.Extend(size), mb[0].BytesTo(size))
+ mb[0].Advance(size)
+ return mb, MultiBuffer{b}
+ }
+
+ totalBytes := int32(0)
+ var r MultiBuffer
+ endIndex := -1
+ for i := range mb {
+ if totalBytes+mb[i].Len() > size {
+ endIndex = i
+ break
+ }
+ totalBytes += mb[i].Len()
+ r = append(r, mb[i])
+ mb[i] = nil
+ }
+ if endIndex == -1 {
+ // To reuse mb array
+ mb = mb[:0]
+ } else {
+ mb = mb[endIndex:]
+ }
+ return mb, r
+}
+
+// SplitMulti splits the beginning of the MultiBuffer into first one, the index i and after into second one
+func SplitMulti(mb MultiBuffer, i int) (MultiBuffer, MultiBuffer) {
+ mb2 := make(MultiBuffer, 0, len(mb))
+ if i < len(mb) && i >= 0 {
+ mb2 = append(mb2, mb[i:]...)
+ for j := i; j < len(mb); j++ {
+ mb[j] = nil
+ }
+ mb = mb[:i]
+ }
+ return mb, mb2
+}
+
+// WriteMultiBuffer writes all buffers from the MultiBuffer to the Writer one by one, and return error if any, with leftover MultiBuffer.
+func WriteMultiBuffer(writer io.Writer, mb MultiBuffer) (MultiBuffer, error) {
+ for {
+ mb2, b := SplitFirst(mb)
+ mb = mb2
+ if b == nil {
+ break
+ }
+
+ _, err := writer.Write(b.Bytes())
+ b.Release()
+ if err != nil {
+ return mb, err
+ }
+ }
+
+ return nil, nil
+}
+
+// Len returns the total number of bytes in the MultiBuffer.
+func (mb MultiBuffer) Len() int32 {
+ if mb == nil {
+ return 0
+ }
+
+ size := int32(0)
+ for _, b := range mb {
+ size += b.Len()
+ }
+ return size
+}
+
+// IsEmpty returns true if the MultiBuffer has no content.
+func (mb MultiBuffer) IsEmpty() bool {
+ for _, b := range mb {
+ if !b.IsEmpty() {
+ return false
+ }
+ }
+ return true
+}
+
+// String returns the content of the MultiBuffer in string.
+func (mb MultiBuffer) String() string {
+ v := make([]interface{}, len(mb))
+ for i, b := range mb {
+ v[i] = b
+ }
+ return serial.Concat(v...)
+}
+
+// MultiBufferContainer is a ReadWriteCloser wrapper over MultiBuffer.
+type MultiBufferContainer struct {
+ MultiBuffer
+}
+
+// Read implements io.Reader.
+func (c *MultiBufferContainer) Read(b []byte) (int, error) {
+ if c.MultiBuffer.IsEmpty() {
+ return 0, io.EOF
+ }
+
+ mb, nBytes := SplitBytes(c.MultiBuffer, b)
+ c.MultiBuffer = mb
+ return nBytes, nil
+}
+
+// ReadMultiBuffer implements Reader.
+func (c *MultiBufferContainer) ReadMultiBuffer() (MultiBuffer, error) {
+ mb := c.MultiBuffer
+ c.MultiBuffer = nil
+ return mb, nil
+}
+
+// Write implements io.Writer.
+func (c *MultiBufferContainer) Write(b []byte) (int, error) {
+ c.MultiBuffer = MergeBytes(c.MultiBuffer, b)
+ return len(b), nil
+}
+
+// WriteMultiBuffer implements Writer.
+func (c *MultiBufferContainer) WriteMultiBuffer(b MultiBuffer) error {
+ mb, _ := MergeMulti(c.MultiBuffer, b)
+ c.MultiBuffer = mb
+ return nil
+}
+
+// Close implements io.Closer.
+func (c *MultiBufferContainer) Close() error {
+ c.MultiBuffer = ReleaseMulti(c.MultiBuffer)
+ return nil
+}
diff --git a/common/xray/buf/override.go b/common/xray/buf/override.go
new file mode 100644
index 0000000000..2032854f6f
--- /dev/null
+++ b/common/xray/buf/override.go
@@ -0,0 +1,38 @@
+package buf
+
+import (
+ "github.com/sagernet/sing-box/common/xray/net"
+)
+
+type EndpointOverrideReader struct {
+ Reader
+ Dest net.Address
+ OriginalDest net.Address
+}
+
+func (r *EndpointOverrideReader) ReadMultiBuffer() (MultiBuffer, error) {
+ mb, err := r.Reader.ReadMultiBuffer()
+ if err == nil {
+ for _, b := range mb {
+ if b.UDP != nil && b.UDP.Address == r.OriginalDest {
+ b.UDP.Address = r.Dest
+ }
+ }
+ }
+ return mb, err
+}
+
+type EndpointOverrideWriter struct {
+ Writer
+ Dest net.Address
+ OriginalDest net.Address
+}
+
+func (w *EndpointOverrideWriter) WriteMultiBuffer(mb MultiBuffer) error {
+ for _, b := range mb {
+ if b.UDP != nil && b.UDP.Address == w.Dest {
+ b.UDP.Address = w.OriginalDest
+ }
+ }
+ return w.Writer.WriteMultiBuffer(mb)
+}
diff --git a/common/xray/buf/reader.go b/common/xray/buf/reader.go
new file mode 100644
index 0000000000..17b2e49191
--- /dev/null
+++ b/common/xray/buf/reader.go
@@ -0,0 +1,175 @@
+package buf
+
+import (
+ "io"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/errors"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func readOneUDP(r io.Reader) (*Buffer, error) {
+ b := New()
+ for i := 0; i < 64; i++ {
+ _, err := b.ReadFrom(r)
+ if !b.IsEmpty() {
+ return b, nil
+ }
+ if err != nil {
+ b.Release()
+ return nil, err
+ }
+ }
+
+ b.Release()
+ return nil, E.New("Reader returns too many empty payloads.")
+}
+
+// ReadBuffer reads a Buffer from the given reader.
+func ReadBuffer(r io.Reader) (*Buffer, error) {
+ b := New()
+ n, err := b.ReadFrom(r)
+ if n > 0 {
+ return b, err
+ }
+ b.Release()
+ return nil, err
+}
+
+// BufferedReader is a Reader that keeps its internal buffer.
+type BufferedReader struct {
+ // Reader is the underlying reader to be read from
+ Reader Reader
+ // Buffer is the internal buffer to be read from first
+ Buffer MultiBuffer
+ // Splitter is a function to read bytes from MultiBuffer
+ Splitter func(MultiBuffer, []byte) (MultiBuffer, int)
+}
+
+// BufferedBytes returns the number of bytes that is cached in this reader.
+func (r *BufferedReader) BufferedBytes() int32 {
+ return r.Buffer.Len()
+}
+
+// ReadByte implements io.ByteReader.
+func (r *BufferedReader) ReadByte() (byte, error) {
+ var b [1]byte
+ _, err := r.Read(b[:])
+ return b[0], err
+}
+
+// Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader.
+func (r *BufferedReader) Read(b []byte) (int, error) {
+ spliter := r.Splitter
+ if spliter == nil {
+ spliter = SplitBytes
+ }
+
+ if !r.Buffer.IsEmpty() {
+ buffer, nBytes := spliter(r.Buffer, b)
+ r.Buffer = buffer
+ if r.Buffer.IsEmpty() {
+ r.Buffer = nil
+ }
+ return nBytes, nil
+ }
+
+ mb, err := r.Reader.ReadMultiBuffer()
+ if err != nil {
+ return 0, err
+ }
+
+ mb, nBytes := spliter(mb, b)
+ if !mb.IsEmpty() {
+ r.Buffer = mb
+ }
+ return nBytes, nil
+}
+
+// ReadMultiBuffer implements Reader.
+func (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) {
+ if !r.Buffer.IsEmpty() {
+ mb := r.Buffer
+ r.Buffer = nil
+ return mb, nil
+ }
+
+ return r.Reader.ReadMultiBuffer()
+}
+
+// ReadAtMost returns a MultiBuffer with at most size.
+func (r *BufferedReader) ReadAtMost(size int32) (MultiBuffer, error) {
+ if r.Buffer.IsEmpty() {
+ mb, err := r.Reader.ReadMultiBuffer()
+ if mb.IsEmpty() && err != nil {
+ return nil, err
+ }
+ r.Buffer = mb
+ }
+
+ rb, mb := SplitSize(r.Buffer, size)
+ r.Buffer = rb
+ if r.Buffer.IsEmpty() {
+ r.Buffer = nil
+ }
+ return mb, nil
+}
+
+func (r *BufferedReader) writeToInternal(writer io.Writer) (int64, error) {
+ mbWriter := NewWriter(writer)
+ var sc SizeCounter
+ if r.Buffer != nil {
+ sc.Size = int64(r.Buffer.Len())
+ if err := mbWriter.WriteMultiBuffer(r.Buffer); err != nil {
+ return 0, err
+ }
+ r.Buffer = nil
+ }
+
+ err := Copy(r.Reader, mbWriter, CountSize(&sc))
+ return sc.Size, err
+}
+
+// WriteTo implements io.WriterTo.
+func (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) {
+ nBytes, err := r.writeToInternal(writer)
+ if errors.Cause(err) == io.EOF {
+ return nBytes, nil
+ }
+ return nBytes, err
+}
+
+// Interrupt implements common.Interruptible.
+func (r *BufferedReader) Interrupt() {
+ common.Interrupt(r.Reader)
+}
+
+// Close implements io.Closer.
+func (r *BufferedReader) Close() error {
+ return common.Close(r.Reader)
+}
+
+// SingleReader is a Reader that read one Buffer every time.
+type SingleReader struct {
+ io.Reader
+}
+
+// ReadMultiBuffer implements Reader.
+func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
+ b, err := ReadBuffer(r.Reader)
+ return MultiBuffer{b}, err
+}
+
+// PacketReader is a Reader that read one Buffer every time.
+type PacketReader struct {
+ io.Reader
+}
+
+// ReadMultiBuffer implements Reader.
+func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {
+ b, err := readOneUDP(r.Reader)
+ if err != nil {
+ return nil, err
+ }
+ return MultiBuffer{b}, nil
+}
diff --git a/common/xray/buf/writer.go b/common/xray/buf/writer.go
new file mode 100644
index 0000000000..c76316c576
--- /dev/null
+++ b/common/xray/buf/writer.go
@@ -0,0 +1,284 @@
+package buf
+
+import (
+ "io"
+ "net"
+ "sync"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/errors"
+ "github.com/sagernet/sing-box/common/xray/stats"
+)
+
+// BufferToBytesWriter is a Writer that writes alloc.Buffer into underlying writer.
+type BufferToBytesWriter struct {
+ io.Writer
+
+ counter stats.Counter
+ cache [][]byte
+}
+
+// WriteMultiBuffer implements Writer. This method takes ownership of the given buffer.
+func (w *BufferToBytesWriter) WriteMultiBuffer(mb MultiBuffer) error {
+ defer ReleaseMulti(mb)
+
+ size := mb.Len()
+ if size == 0 {
+ return nil
+ }
+
+ if len(mb) == 1 {
+ return WriteAllBytes(w.Writer, mb[0].Bytes(), w.counter)
+ }
+
+ if cap(w.cache) < len(mb) {
+ w.cache = make([][]byte, 0, len(mb))
+ }
+
+ bs := w.cache
+ for _, b := range mb {
+ bs = append(bs, b.Bytes())
+ }
+
+ defer func() {
+ for idx := range bs {
+ bs[idx] = nil
+ }
+ }()
+
+ nb := net.Buffers(bs)
+ wc := int64(0)
+ defer func() {
+ if w.counter != nil {
+ w.counter.Add(wc)
+ }
+ }()
+ for size > 0 {
+ n, err := nb.WriteTo(w.Writer)
+ wc += n
+ if err != nil {
+ return err
+ }
+ size -= int32(n)
+ }
+
+ return nil
+}
+
+// ReadFrom implements io.ReaderFrom.
+func (w *BufferToBytesWriter) ReadFrom(reader io.Reader) (int64, error) {
+ var sc SizeCounter
+ err := Copy(NewReader(reader), w, CountSize(&sc))
+ return sc.Size, err
+}
+
+// BufferedWriter is a Writer with internal buffer.
+type BufferedWriter struct {
+ sync.Mutex
+ writer Writer
+ buffer *Buffer
+ buffered bool
+ flushNext bool
+}
+
+// NewBufferedWriter creates a new BufferedWriter.
+func NewBufferedWriter(writer Writer) *BufferedWriter {
+ return &BufferedWriter{
+ writer: writer,
+ buffer: New(),
+ buffered: true,
+ }
+}
+
+// WriteByte implements io.ByteWriter.
+func (w *BufferedWriter) WriteByte(c byte) error {
+ return common.Error2(w.Write([]byte{c}))
+}
+
+// Write implements io.Writer.
+func (w *BufferedWriter) Write(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+
+ w.Lock()
+ defer w.Unlock()
+
+ if !w.buffered {
+ if writer, ok := w.writer.(io.Writer); ok {
+ return writer.Write(b)
+ }
+ }
+
+ totalBytes := 0
+ for len(b) > 0 {
+ if w.buffer == nil {
+ w.buffer = New()
+ }
+
+ nBytes, err := w.buffer.Write(b)
+ totalBytes += nBytes
+ if err != nil {
+ return totalBytes, err
+ }
+ if !w.buffered || w.buffer.IsFull() {
+ if err := w.flushInternal(); err != nil {
+ return totalBytes, err
+ }
+ }
+ b = b[nBytes:]
+ }
+
+ return totalBytes, nil
+}
+
+// WriteMultiBuffer implements Writer. It takes ownership of the given MultiBuffer.
+func (w *BufferedWriter) WriteMultiBuffer(b MultiBuffer) error {
+ if b.IsEmpty() {
+ return nil
+ }
+
+ w.Lock()
+ defer w.Unlock()
+
+ if !w.buffered {
+ return w.writer.WriteMultiBuffer(b)
+ }
+
+ reader := MultiBufferContainer{
+ MultiBuffer: b,
+ }
+ defer reader.Close()
+
+ for !reader.MultiBuffer.IsEmpty() {
+ if w.buffer == nil {
+ w.buffer = New()
+ }
+ common.Must2(w.buffer.ReadFrom(&reader))
+ if w.buffer.IsFull() {
+ if err := w.flushInternal(); err != nil {
+ return err
+ }
+ }
+ }
+
+ if w.flushNext {
+ w.buffered = false
+ w.flushNext = false
+ return w.flushInternal()
+ }
+
+ return nil
+}
+
+// Flush flushes buffered content into underlying writer.
+func (w *BufferedWriter) Flush() error {
+ w.Lock()
+ defer w.Unlock()
+
+ return w.flushInternal()
+}
+
+func (w *BufferedWriter) flushInternal() error {
+ if w.buffer.IsEmpty() {
+ return nil
+ }
+
+ b := w.buffer
+ w.buffer = nil
+
+ if writer, ok := w.writer.(io.Writer); ok {
+ err := WriteAllBytes(writer, b.Bytes(), nil)
+ b.Release()
+ return err
+ }
+
+ return w.writer.WriteMultiBuffer(MultiBuffer{b})
+}
+
+// SetBuffered sets whether the internal buffer is used. If set to false, Flush() will be called to clear the buffer.
+func (w *BufferedWriter) SetBuffered(f bool) error {
+ w.Lock()
+ defer w.Unlock()
+
+ w.buffered = f
+ if !f {
+ return w.flushInternal()
+ }
+ return nil
+}
+
+// SetFlushNext will wait the next WriteMultiBuffer to flush and set buffered = false
+func (w *BufferedWriter) SetFlushNext() {
+ w.Lock()
+ defer w.Unlock()
+ w.flushNext = true
+}
+
+// ReadFrom implements io.ReaderFrom.
+func (w *BufferedWriter) ReadFrom(reader io.Reader) (int64, error) {
+ if err := w.SetBuffered(false); err != nil {
+ return 0, err
+ }
+
+ var sc SizeCounter
+ err := Copy(NewReader(reader), w, CountSize(&sc))
+ return sc.Size, err
+}
+
+// Close implements io.Closable.
+func (w *BufferedWriter) Close() error {
+ if err := w.Flush(); err != nil {
+ return err
+ }
+ return common.Close(w.writer)
+}
+
+// SequentialWriter is a Writer that writes MultiBuffer sequentially into the underlying io.Writer.
+type SequentialWriter struct {
+ io.Writer
+}
+
+// WriteMultiBuffer implements Writer.
+func (w *SequentialWriter) WriteMultiBuffer(mb MultiBuffer) error {
+ mb, err := WriteMultiBuffer(w.Writer, mb)
+ ReleaseMulti(mb)
+ return err
+}
+
+type noOpWriter byte
+
+func (noOpWriter) WriteMultiBuffer(b MultiBuffer) error {
+ ReleaseMulti(b)
+ return nil
+}
+
+func (noOpWriter) Write(b []byte) (int, error) {
+ return len(b), nil
+}
+
+func (noOpWriter) ReadFrom(reader io.Reader) (int64, error) {
+ b := New()
+ defer b.Release()
+
+ totalBytes := int64(0)
+ for {
+ b.Clear()
+ _, err := b.ReadFrom(reader)
+ totalBytes += int64(b.Len())
+ if err != nil {
+ if errors.Cause(err) == io.EOF {
+ return totalBytes, nil
+ }
+ return totalBytes, err
+ }
+ }
+}
+
+var (
+ // Discard is a Writer that swallows all contents written in.
+ Discard Writer = noOpWriter(0)
+
+ // DiscardBytes is an io.Writer that swallows all contents written in.
+ DiscardBytes io.Writer = noOpWriter(0)
+)
diff --git a/common/xray/bytespool/pool.go b/common/xray/bytespool/pool.go
new file mode 100644
index 0000000000..6f632d5241
--- /dev/null
+++ b/common/xray/bytespool/pool.go
@@ -0,0 +1,72 @@
+package bytespool
+
+import "sync"
+
+func createAllocFunc(size int32) func() interface{} {
+ return func() interface{} {
+ return make([]byte, size)
+ }
+}
+
+// The following parameters controls the size of buffer pools.
+// There are numPools pools. Starting from 2k size, the size of each pool is sizeMulti of the previous one.
+// Package buf is guaranteed to not use buffers larger than the largest pool.
+// Other packets may use larger buffers.
+const (
+ numPools = 4
+ sizeMulti = 4
+)
+
+var (
+ pool [numPools]sync.Pool
+ poolSize [numPools]int32
+)
+
+func init() {
+ size := int32(2048)
+ for i := 0; i < numPools; i++ {
+ pool[i] = sync.Pool{
+ New: createAllocFunc(size),
+ }
+ poolSize[i] = size
+ size *= sizeMulti
+ }
+}
+
+// GetPool returns a sync.Pool that generates bytes array with at least the given size.
+// It may return nil if no such pool exists.
+//
+// xray:api:stable
+func GetPool(size int32) *sync.Pool {
+ for idx, ps := range poolSize {
+ if size <= ps {
+ return &pool[idx]
+ }
+ }
+ return nil
+}
+
+// Alloc returns a byte slice with at least the given size. Minimum size of returned slice is 2048.
+//
+// xray:api:stable
+func Alloc(size int32) []byte {
+ pool := GetPool(size)
+ if pool != nil {
+ return pool.Get().([]byte)
+ }
+ return make([]byte, size)
+}
+
+// Free puts a byte slice into the internal pool.
+//
+// xray:api:stable
+func Free(b []byte) {
+ size := int32(cap(b))
+ b = b[0:cap(b)]
+ for i := numPools - 1; i >= 0; i-- {
+ if size >= poolSize[i] {
+ pool[i].Put(b)
+ return
+ }
+ }
+}
diff --git a/common/xray/common.go b/common/xray/common.go
new file mode 100644
index 0000000000..266f57ef92
--- /dev/null
+++ b/common/xray/common.go
@@ -0,0 +1,32 @@
+package common
+
+import "reflect"
+
+// Must panics if err is not nil.
+func Must(err error) {
+ if err != nil {
+ panic(err)
+ }
+}
+
+// Must2 panics if the second parameter is not nil, otherwise returns the first parameter.
+func Must2(v interface{}, err error) interface{} {
+ Must(err)
+ return v
+}
+
+// Error2 returns the err from the 2nd parameter.
+func Error2(v interface{}, err error) error {
+ return err
+}
+
+// CloseIfExists call obj.Close() if obj is not nil.
+func CloseIfExists(obj any) error {
+ if obj != nil {
+ v := reflect.ValueOf(obj)
+ if !v.IsNil() {
+ return Close(obj)
+ }
+ }
+ return nil
+}
diff --git a/common/xray/cpuid/cpuid.go b/common/xray/cpuid/cpuid.go
new file mode 100644
index 0000000000..60938fe3f5
--- /dev/null
+++ b/common/xray/cpuid/cpuid.go
@@ -0,0 +1,18 @@
+package cpuid
+
+import (
+ "runtime"
+
+ "golang.org/x/sys/cpu"
+)
+
+var (
+ // Keep in sync with crypto/tls/cipher_suites.go.
+ hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
+ hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
+ hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasGHASH
+ hasGCMAsmPPC64 = runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"
+
+ // HasAESGCM indicates whether the CPU has AES-GCM hardware acceleration.
+ HasAESGCM = hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X || hasGCMAsmPPC64
+)
diff --git a/common/xray/crypto/crypto.go b/common/xray/crypto/crypto.go
new file mode 100644
index 0000000000..4356d41255
--- /dev/null
+++ b/common/xray/crypto/crypto.go
@@ -0,0 +1,17 @@
+package crypto
+
+import (
+ "crypto/rand"
+ "math/big"
+)
+
+func RandBetween(from int64, to int64) int64 {
+ if from == to {
+ return from
+ }
+ if from > to {
+ from, to = to, from
+ }
+ bigInt, _ := rand.Int(rand.Reader, big.NewInt(to-from))
+ return from + bigInt.Int64()
+}
diff --git a/common/xray/errors/errors.go b/common/xray/errors/errors.go
new file mode 100644
index 0000000000..54af7cbe1d
--- /dev/null
+++ b/common/xray/errors/errors.go
@@ -0,0 +1,25 @@
+package errors
+
+type hasInnerError interface {
+ // Unwrap returns the underlying error of this one.
+ Unwrap() error
+}
+
+func Cause(err error) error {
+ if err == nil {
+ return nil
+ }
+L:
+ for {
+ switch inner := err.(type) {
+ case hasInnerError:
+ if inner.Unwrap() == nil {
+ break L
+ }
+ err = inner.Unwrap()
+ default:
+ break L
+ }
+ }
+ return err
+}
diff --git a/common/xray/interfaces.go b/common/xray/interfaces.go
new file mode 100644
index 0000000000..428c3388f7
--- /dev/null
+++ b/common/xray/interfaces.go
@@ -0,0 +1,52 @@
+package common
+
+// Closable is the interface for objects that can release its resources.
+//
+// xray:api:beta
+type Closable interface {
+ // Close release all resources used by this object, including goroutines.
+ Close() error
+}
+
+// Interruptible is an interface for objects that can be stopped before its completion.
+//
+// xray:api:beta
+type Interruptible interface {
+ Interrupt()
+}
+
+// Close closes the obj if it is a Closable.
+//
+// xray:api:beta
+func Close(obj interface{}) error {
+ if c, ok := obj.(Closable); ok {
+ return c.Close()
+ }
+ return nil
+}
+
+// Interrupt calls Interrupt() if object implements Interruptible interface, or Close() if the object implements Closable interface.
+//
+// xray:api:beta
+func Interrupt(obj interface{}) error {
+ if c, ok := obj.(Interruptible); ok {
+ c.Interrupt()
+ return nil
+ }
+ return Close(obj)
+}
+
+// Runnable is the interface for objects that can start to work and stop on demand.
+type Runnable interface {
+ // Start starts the runnable object. Upon the method returning nil, the object begins to function properly.
+ Start() error
+
+ Closable
+}
+
+// HasType is the interface for objects that knows its type.
+type HasType interface {
+ // Type returns the type of the object.
+ // Usually it returns (*Type)(nil) of the object.
+ Type() interface{}
+}
diff --git a/common/xray/json/badoption/range.go b/common/xray/json/badoption/range.go
new file mode 100644
index 0000000000..056a8106a1
--- /dev/null
+++ b/common/xray/json/badoption/range.go
@@ -0,0 +1,76 @@
+package badoption
+
+import (
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/sagernet/sing-box/common/xray/crypto"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type Range struct {
+ From int32 `json:"from"`
+ To int32 `json:"to"`
+}
+
+func (c *Range) Build() *Range {
+ return (*Range)(c)
+}
+
+func (c *Range) MarshalJSON() ([]byte, error) {
+ if c.From == 0 && c.To == 0 {
+ return json.Marshal("")
+ }
+ return json.Marshal(fmt.Sprintf("%d-%d", c.From, c.To))
+}
+
+func (c *Range) UnmarshalJSON(content []byte) error {
+ var rangeValue struct {
+ From int32 `json:"from"`
+ To int32 `json:"to"`
+ }
+ var stringValue string
+
+ if err := json.Unmarshal(content, &stringValue); err == nil {
+
+ parts := strings.Split(stringValue, "-")
+ if stringValue == "" {
+ rangeValue.From, rangeValue.To = 0, 0
+ } else if len(parts) != 2 {
+ from, err := strconv.ParseInt(parts[0], 10, 32)
+ if err != nil {
+ return err
+ }
+ rangeValue.From, rangeValue.To = int32(from), int32(from)
+ } else {
+ from, err := strconv.ParseInt(parts[0], 10, 32)
+ if err != nil {
+ return err
+ }
+ to, err := strconv.ParseInt(parts[1], 10, 32)
+ if err != nil {
+ return err
+ }
+ rangeValue.From, rangeValue.To = int32(from), int32(to)
+ }
+ } else {
+ var intValue int
+ if err := json.Unmarshal(content, &intValue); err == nil {
+ rangeValue.From, rangeValue.To = int32(intValue), int32(intValue)
+ } else if err := json.Unmarshal(content, &rangeValue); err != nil {
+ return err
+ }
+
+ }
+ if rangeValue.From > rangeValue.To {
+ return E.New("invalid range")
+ }
+ *c = Range{rangeValue.From, rangeValue.To}
+ return nil
+}
+
+func (c Range) Rand() int32 {
+ return int32(crypto.RandBetween(int64(c.From), int64(c.To)))
+}
diff --git a/common/xray/net/address.go b/common/xray/net/address.go
new file mode 100644
index 0000000000..7a99c8adc9
--- /dev/null
+++ b/common/xray/net/address.go
@@ -0,0 +1,181 @@
+package net
+
+import (
+ "bytes"
+ "net"
+ "strings"
+)
+
+var (
+ // LocalHostIP is a constant value for localhost IP in IPv4.
+ LocalHostIP = IPAddress([]byte{127, 0, 0, 1})
+
+ // AnyIP is a constant value for any IP in IPv4.
+ AnyIP = IPAddress([]byte{0, 0, 0, 0})
+
+ // LocalHostDomain is a constant value for localhost domain.
+ LocalHostDomain = DomainAddress("localhost")
+
+ // LocalHostIPv6 is a constant value for localhost IP in IPv6.
+ LocalHostIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})
+
+ // AnyIPv6 is a constant value for any IP in IPv6.
+ AnyIPv6 = IPAddress([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+)
+
+// AddressFamily is the type of address.
+type AddressFamily byte
+
+const (
+ // AddressFamilyIPv4 represents address as IPv4
+ AddressFamilyIPv4 = AddressFamily(0)
+
+ // AddressFamilyIPv6 represents address as IPv6
+ AddressFamilyIPv6 = AddressFamily(1)
+
+ // AddressFamilyDomain represents address as Domain
+ AddressFamilyDomain = AddressFamily(2)
+)
+
+// IsIPv4 returns true if current AddressFamily is IPv4.
+func (af AddressFamily) IsIPv4() bool {
+ return af == AddressFamilyIPv4
+}
+
+// IsIPv6 returns true if current AddressFamily is IPv6.
+func (af AddressFamily) IsIPv6() bool {
+ return af == AddressFamilyIPv6
+}
+
+// IsIP returns true if current AddressFamily is IPv6 or IPv4.
+func (af AddressFamily) IsIP() bool {
+ return af == AddressFamilyIPv4 || af == AddressFamilyIPv6
+}
+
+// IsDomain returns true if current AddressFamily is Domain.
+func (af AddressFamily) IsDomain() bool {
+ return af == AddressFamilyDomain
+}
+
+// Address represents a network address to be communicated with. It may be an IP address or domain
+// address, not both. This interface doesn't resolve IP address for a given domain.
+type Address interface {
+ IP() net.IP // IP of this Address
+ Domain() string // Domain of this Address
+ Family() AddressFamily
+
+ String() string // String representation of this Address
+}
+
+func isAlphaNum(c byte) bool {
+ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+// ParseAddress parses a string into an Address. The return value will be an IPAddress when
+// the string is in the form of IPv4 or IPv6 address, or a DomainAddress otherwise.
+func ParseAddress(addr string) Address {
+ // Handle IPv6 address in form as "[2001:4860:0:2001::68]"
+ lenAddr := len(addr)
+ if lenAddr > 0 && addr[0] == '[' && addr[lenAddr-1] == ']' {
+ addr = addr[1 : lenAddr-1]
+ lenAddr -= 2
+ }
+
+ if lenAddr > 0 && (!isAlphaNum(addr[0]) || !isAlphaNum(addr[len(addr)-1])) {
+ addr = strings.TrimSpace(addr)
+ }
+
+ ip := net.ParseIP(addr)
+ if ip != nil {
+ return IPAddress(ip)
+ }
+ return DomainAddress(addr)
+}
+
+var bytes0 = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+// IPAddress creates an Address with given IP.
+func IPAddress(ip []byte) Address {
+ switch len(ip) {
+ case net.IPv4len:
+ var addr ipv4Address = [4]byte{ip[0], ip[1], ip[2], ip[3]}
+ return addr
+ case net.IPv6len:
+ if bytes.Equal(ip[:10], bytes0) && ip[10] == 0xff && ip[11] == 0xff {
+ return IPAddress(ip[12:16])
+ }
+ var addr ipv6Address = [16]byte{
+ ip[0], ip[1], ip[2], ip[3],
+ ip[4], ip[5], ip[6], ip[7],
+ ip[8], ip[9], ip[10], ip[11],
+ ip[12], ip[13], ip[14], ip[15],
+ }
+ return addr
+ default:
+ return nil
+ }
+}
+
+// DomainAddress creates an Address with given domain.
+// This is an internal function that forcibly converts a string to domain.
+// It's mainly used in test files and mux.
+// Unless you have a specific reason, use net.ParseAddress instead,
+// as this function does not check whether the input is an IP address.
+// Otherwise, you will get strange results like domain: 1.1.1.1
+func DomainAddress(domain string) Address {
+ return domainAddress(domain)
+}
+
+type ipv4Address [4]byte
+
+func (a ipv4Address) IP() net.IP {
+ return net.IP(a[:])
+}
+
+func (ipv4Address) Domain() string {
+ panic("Calling Domain() on an IPv4Address.")
+}
+
+func (ipv4Address) Family() AddressFamily {
+ return AddressFamilyIPv4
+}
+
+func (a ipv4Address) String() string {
+ return a.IP().String()
+}
+
+type ipv6Address [16]byte
+
+func (a ipv6Address) IP() net.IP {
+ return net.IP(a[:])
+}
+
+func (ipv6Address) Domain() string {
+ panic("Calling Domain() on an IPv6Address.")
+}
+
+func (ipv6Address) Family() AddressFamily {
+ return AddressFamilyIPv6
+}
+
+func (a ipv6Address) String() string {
+ return "[" + a.IP().String() + "]"
+}
+
+type domainAddress string
+
+func (domainAddress) IP() net.IP {
+ panic("Calling IP() on a DomainAddress.")
+}
+
+func (a domainAddress) Domain() string {
+ return string(a)
+}
+
+func (domainAddress) Family() AddressFamily {
+ return AddressFamilyDomain
+}
+
+func (a domainAddress) String() string {
+ return a.Domain()
+}
diff --git a/common/xray/net/destination.go b/common/xray/net/destination.go
new file mode 100644
index 0000000000..561c7726ba
--- /dev/null
+++ b/common/xray/net/destination.go
@@ -0,0 +1,146 @@
+package net
+
+import (
+ "net"
+ "strings"
+)
+
+// Destination represents a network destination including address and protocol (tcp / udp).
+type Destination struct {
+ Address Address
+ Port Port
+ Network Network
+}
+
+// DestinationFromAddr generates a Destination from a net address.
+func DestinationFromAddr(addr net.Addr) Destination {
+ switch addr := addr.(type) {
+ case *net.TCPAddr:
+ return TCPDestination(IPAddress(addr.IP), Port(addr.Port))
+ case *net.UDPAddr:
+ return UDPDestination(IPAddress(addr.IP), Port(addr.Port))
+ case *net.UnixAddr:
+ return UnixDestination(DomainAddress(addr.Name))
+ default:
+ panic("Net: Unknown address type.")
+ }
+}
+
+// ParseDestination converts a destination from its string presentation.
+func ParseDestination(dest string) (Destination, error) {
+ d := Destination{
+ Address: AnyIP,
+ Port: Port(0),
+ }
+ if strings.HasPrefix(dest, "tcp:") {
+ d.Network = Network_TCP
+ dest = dest[4:]
+ } else if strings.HasPrefix(dest, "udp:") {
+ d.Network = Network_UDP
+ dest = dest[4:]
+ } else if strings.HasPrefix(dest, "unix:") {
+ d = UnixDestination(DomainAddress(dest[5:]))
+ return d, nil
+ }
+
+ hstr, pstr, err := SplitHostPort(dest)
+ if err != nil {
+ return d, err
+ }
+ if len(hstr) > 0 {
+ d.Address = ParseAddress(hstr)
+ }
+ if len(pstr) > 0 {
+ port, err := PortFromString(pstr)
+ if err != nil {
+ return d, err
+ }
+ d.Port = port
+ }
+ return d, nil
+}
+
+// TCPDestination creates a TCP destination with given address
+func TCPDestination(address Address, port Port) Destination {
+ return Destination{
+ Network: Network_TCP,
+ Address: address,
+ Port: port,
+ }
+}
+
+// UDPDestination creates a UDP destination with given address
+func UDPDestination(address Address, port Port) Destination {
+ return Destination{
+ Network: Network_UDP,
+ Address: address,
+ Port: port,
+ }
+}
+
+// UnixDestination creates a Unix destination with given address
+func UnixDestination(address Address) Destination {
+ return Destination{
+ Network: Network_UNIX,
+ Address: address,
+ }
+}
+
+// NetAddr returns the network address in this Destination in string form.
+func (d Destination) NetAddr() string {
+ addr := ""
+ if d.Network == Network_TCP || d.Network == Network_UDP {
+ addr = d.Address.String() + ":" + d.Port.String()
+ } else if d.Network == Network_UNIX {
+ addr = d.Address.String()
+ }
+ return addr
+}
+
+// RawNetAddr converts a net.Addr from its Destination presentation.
+func (d Destination) RawNetAddr() net.Addr {
+ var addr net.Addr
+ switch d.Network {
+ case Network_TCP:
+ if d.Address.Family().IsIP() {
+ addr = &net.TCPAddr{
+ IP: d.Address.IP(),
+ Port: int(d.Port),
+ }
+ }
+ case Network_UDP:
+ if d.Address.Family().IsIP() {
+ addr = &net.UDPAddr{
+ IP: d.Address.IP(),
+ Port: int(d.Port),
+ }
+ }
+ case Network_UNIX:
+ if d.Address.Family().IsDomain() {
+ addr = &net.UnixAddr{
+ Name: d.Address.String(),
+ Net: d.Network.SystemString(),
+ }
+ }
+ }
+ return addr
+}
+
+// String returns the strings form of this Destination.
+func (d Destination) String() string {
+ prefix := "unknown:"
+ switch d.Network {
+ case Network_TCP:
+ prefix = "tcp:"
+ case Network_UDP:
+ prefix = "udp:"
+ case Network_UNIX:
+ prefix = "unix:"
+ }
+ return prefix + d.NetAddr()
+}
+
+// IsValid returns true if this Destination is valid.
+func (d Destination) IsValid() bool {
+ return d.Network != Network_Unknown
+}
diff --git a/common/xray/net/net.go b/common/xray/net/net.go
new file mode 100644
index 0000000000..9bc049d98a
--- /dev/null
+++ b/common/xray/net/net.go
@@ -0,0 +1,13 @@
+package net
+
+import "time"
+
+// defines the maximum time an idle TCP session can survive in the tunnel, so
+// it should be consistent across HTTP versions and with other transports.
+const ConnIdleTimeout = 300 * time.Second
+
+// consistent with quic-go
+const QuicgoH3KeepAlivePeriod = 10 * time.Second
+
+// consistent with chrome
+const ChromeH2KeepAlivePeriod = 45 * time.Second
diff --git a/common/xray/net/network.go b/common/xray/net/network.go
new file mode 100644
index 0000000000..356d7fdab8
--- /dev/null
+++ b/common/xray/net/network.go
@@ -0,0 +1,33 @@
+package net
+
+type Network int32
+
+const (
+ Network_Unknown Network = 0
+ Network_TCP Network = 2
+ Network_UDP Network = 3
+ Network_UNIX Network = 4
+)
+
+func (n Network) SystemString() string {
+ switch n {
+ case Network_TCP:
+ return "tcp"
+ case Network_UDP:
+ return "udp"
+ case Network_UNIX:
+ return "unix"
+ default:
+ return "unknown"
+ }
+}
+
+// HasNetwork returns true if the network list has a certain network.
+func HasNetwork(list []Network, network Network) bool {
+ for _, value := range list {
+ if value == network {
+ return true
+ }
+ }
+ return false
+}
diff --git a/common/xray/net/port.go b/common/xray/net/port.go
new file mode 100644
index 0000000000..6d42c40b6f
--- /dev/null
+++ b/common/xray/net/port.go
@@ -0,0 +1,55 @@
+package net
+
+import (
+ "encoding/binary"
+ "strconv"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+// Port represents a network port in TCP and UDP protocol.
+type Port uint16
+
+// PortFromBytes converts a byte array to a Port, assuming bytes are in big endian order.
+// @unsafe Caller must ensure that the byte array has at least 2 elements.
+func PortFromBytes(port []byte) Port {
+ return Port(binary.BigEndian.Uint16(port))
+}
+
+// PortFromInt converts an integer to a Port.
+// @error when the integer is not positive or larger then 65535
+func PortFromInt(val uint32) (Port, error) {
+ if val > 65535 {
+ return Port(0), E.New("invalid port range: ", val)
+ }
+ return Port(val), nil
+}
+
+// PortFromString converts a string to a Port.
+// @error when the string is not an integer or the integral value is a not a valid Port.
+func PortFromString(s string) (Port, error) {
+ val, err := strconv.ParseUint(s, 10, 32)
+ if err != nil {
+ return Port(0), E.New("invalid port range: ", s)
+ }
+ return PortFromInt(uint32(val))
+}
+
+// Value return the corresponding uint16 value of a Port.
+func (p Port) Value() uint16 {
+ return uint16(p)
+}
+
+// String returns the string presentation of a Port.
+func (p Port) String() string {
+ return strconv.Itoa(int(p))
+}
+
+type MemoryPortRange struct {
+ From Port
+ To Port
+}
+
+func (r MemoryPortRange) Contains(port Port) bool {
+ return r.From <= port && port <= r.To
+}
diff --git a/common/xray/net/system.go b/common/xray/net/system.go
new file mode 100644
index 0000000000..7e1c4b01a3
--- /dev/null
+++ b/common/xray/net/system.go
@@ -0,0 +1,84 @@
+package net
+
+import "net"
+
+// DialTCP is an alias of net.DialTCP.
+var (
+ DialTCP = net.DialTCP
+ DialUDP = net.DialUDP
+ DialUnix = net.DialUnix
+ Dial = net.Dial
+)
+
+type ListenConfig = net.ListenConfig
+
+var (
+ Listen = net.Listen
+ ListenTCP = net.ListenTCP
+ ListenUDP = net.ListenUDP
+ ListenUnix = net.ListenUnix
+)
+
+var LookupIP = net.LookupIP
+
+var FileConn = net.FileConn
+
+// ParseIP is an alias of net.ParseIP
+var ParseIP = net.ParseIP
+
+var SplitHostPort = net.SplitHostPort
+
+var CIDRMask = net.CIDRMask
+
+type (
+ Addr = net.Addr
+ Conn = net.Conn
+ PacketConn = net.PacketConn
+)
+
+type (
+ TCPAddr = net.TCPAddr
+ TCPConn = net.TCPConn
+)
+
+type (
+ UDPAddr = net.UDPAddr
+ UDPConn = net.UDPConn
+)
+
+type (
+ UnixAddr = net.UnixAddr
+ UnixConn = net.UnixConn
+)
+
+// IP is an alias for net.IP.
+type (
+ IP = net.IP
+ IPMask = net.IPMask
+ IPNet = net.IPNet
+)
+
+const (
+ IPv4len = net.IPv4len
+ IPv6len = net.IPv6len
+)
+
+type (
+ Error = net.Error
+ AddrError = net.AddrError
+)
+
+type (
+ Dialer = net.Dialer
+ Listener = net.Listener
+ TCPListener = net.TCPListener
+ UnixListener = net.UnixListener
+)
+
+var (
+ ResolveTCPAddr = net.ResolveTCPAddr
+ ResolveUDPAddr = net.ResolveUDPAddr
+ ResolveUnixAddr = net.ResolveUnixAddr
+)
+
+type Resolver = net.Resolver
diff --git a/common/xray/pipe/impl.go b/common/xray/pipe/impl.go
new file mode 100644
index 0000000000..7b2a97a80b
--- /dev/null
+++ b/common/xray/pipe/impl.go
@@ -0,0 +1,209 @@
+package pipe
+
+import (
+ "errors"
+ "io"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/buf"
+ "github.com/sagernet/sing-box/common/xray/signal"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+)
+
+type state byte
+
+const (
+ open state = iota
+ closed
+ errord
+)
+
+type pipeOption struct {
+ limit int32 // maximum buffer size in bytes
+ discardOverflow bool
+}
+
+func (o *pipeOption) isFull(curSize int32) bool {
+ return o.limit >= 0 && curSize > o.limit
+}
+
+type pipe struct {
+ sync.Mutex
+ data buf.MultiBuffer
+ readSignal *signal.Notifier
+ writeSignal *signal.Notifier
+ done *done.Instance
+ errChan chan error
+ option pipeOption
+ state state
+}
+
+var (
+ errBufferFull = errors.New("buffer full")
+ errSlowDown = errors.New("slow down")
+)
+
+func (p *pipe) Len() int32 {
+ data := p.data
+ if data == nil {
+ return 0
+ }
+ return data.Len()
+}
+
+func (p *pipe) getState(forRead bool) error {
+ switch p.state {
+ case open:
+ if !forRead && p.option.isFull(p.data.Len()) {
+ return errBufferFull
+ }
+ return nil
+ case closed:
+ if !forRead {
+ return io.ErrClosedPipe
+ }
+ if !p.data.IsEmpty() {
+ return nil
+ }
+ return io.EOF
+ case errord:
+ return io.ErrClosedPipe
+ default:
+ panic("impossible case")
+ }
+}
+
+func (p *pipe) readMultiBufferInternal() (buf.MultiBuffer, error) {
+ p.Lock()
+ defer p.Unlock()
+
+ if err := p.getState(true); err != nil {
+ return nil, err
+ }
+
+ data := p.data
+ p.data = nil
+ return data, nil
+}
+
+func (p *pipe) ReadMultiBuffer() (buf.MultiBuffer, error) {
+ for {
+ data, err := p.readMultiBufferInternal()
+ if data != nil || err != nil {
+ p.writeSignal.Signal()
+ return data, err
+ }
+
+ select {
+ case <-p.readSignal.Wait():
+ case <-p.done.Wait():
+ case err = <-p.errChan:
+ return nil, err
+ }
+ }
+}
+
+func (p *pipe) ReadMultiBufferTimeout(d time.Duration) (buf.MultiBuffer, error) {
+ timer := time.NewTimer(d)
+ defer timer.Stop()
+
+ for {
+ data, err := p.readMultiBufferInternal()
+ if data != nil || err != nil {
+ p.writeSignal.Signal()
+ return data, err
+ }
+
+ select {
+ case <-p.readSignal.Wait():
+ case <-p.done.Wait():
+ case <-timer.C:
+ return nil, buf.ErrReadTimeout
+ }
+ }
+}
+
+func (p *pipe) writeMultiBufferInternal(mb buf.MultiBuffer) error {
+ p.Lock()
+ defer p.Unlock()
+
+ if err := p.getState(false); err != nil {
+ return err
+ }
+
+ if p.data == nil {
+ p.data = mb
+ } else {
+ p.data, _ = buf.MergeMulti(p.data, mb)
+ }
+ return nil
+}
+
+func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
+ if mb.IsEmpty() {
+ return nil
+ }
+
+ for {
+ err := p.writeMultiBufferInternal(mb)
+ if err == nil {
+ p.readSignal.Signal()
+ return nil
+ }
+
+ if err == errBufferFull {
+ if p.option.discardOverflow {
+ buf.ReleaseMulti(mb)
+ return nil
+ }
+ select {
+ case <-p.writeSignal.Wait():
+ continue
+ case <-p.done.Wait():
+ buf.ReleaseMulti(mb)
+ return io.ErrClosedPipe
+ }
+ }
+
+ buf.ReleaseMulti(mb)
+ p.readSignal.Signal()
+ return err
+ }
+}
+
+func (p *pipe) Close() error {
+ p.Lock()
+ defer p.Unlock()
+
+ if p.state == closed || p.state == errord {
+ return nil
+ }
+
+ p.state = closed
+ common.Must(p.done.Close())
+ return nil
+}
+
+// Interrupt implements common.Interruptible.
+func (p *pipe) Interrupt() {
+ p.Lock()
+ defer p.Unlock()
+
+ if !p.data.IsEmpty() {
+ buf.ReleaseMulti(p.data)
+ p.data = nil
+ if p.state == closed {
+ p.state = errord
+ }
+ }
+
+ if p.state == closed || p.state == errord {
+ return
+ }
+
+ p.state = errord
+
+ common.Must(p.done.Close())
+}
diff --git a/common/xray/pipe/pipe.go b/common/xray/pipe/pipe.go
new file mode 100644
index 0000000000..dad266788c
--- /dev/null
+++ b/common/xray/pipe/pipe.go
@@ -0,0 +1,53 @@
+package pipe
+
+import (
+ "github.com/sagernet/sing-box/common/xray/signal"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+)
+
+// Option for creating new Pipes.
+type Option func(*pipeOption)
+
+// WithoutSizeLimit returns an Option for Pipe to have no size limit.
+func WithoutSizeLimit() Option {
+ return func(opt *pipeOption) {
+ opt.limit = -1
+ }
+}
+
+// WithSizeLimit returns an Option for Pipe to have the given size limit.
+func WithSizeLimit(limit int32) Option {
+ return func(opt *pipeOption) {
+ opt.limit = limit
+ }
+}
+
+// DiscardOverflow returns an Option for Pipe to discard writes if full.
+func DiscardOverflow() Option {
+ return func(opt *pipeOption) {
+ opt.discardOverflow = true
+ }
+}
+
+// New creates a new Reader and Writer that connects to each other.
+func New(opts ...Option) (*Reader, *Writer) {
+ p := &pipe{
+ readSignal: signal.NewNotifier(),
+ writeSignal: signal.NewNotifier(),
+ done: done.New(),
+ errChan: make(chan error, 1),
+ option: pipeOption{
+ limit: -1,
+ },
+ }
+
+ for _, opt := range opts {
+ opt(&(p.option))
+ }
+
+ return &Reader{
+ pipe: p,
+ }, &Writer{
+ pipe: p,
+ }
+}
diff --git a/common/xray/pipe/reader.go b/common/xray/pipe/reader.go
new file mode 100644
index 0000000000..cafe444a49
--- /dev/null
+++ b/common/xray/pipe/reader.go
@@ -0,0 +1,41 @@
+package pipe
+
+import (
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/buf"
+)
+
+// Reader is a buf.Reader that reads content from a pipe.
+type Reader struct {
+ pipe *pipe
+}
+
+// ReadMultiBuffer implements buf.Reader.
+func (r *Reader) ReadMultiBuffer() (buf.MultiBuffer, error) {
+ return r.pipe.ReadMultiBuffer()
+}
+
+// ReadMultiBufferTimeout reads content from a pipe within the given duration, or returns buf.ErrTimeout otherwise.
+func (r *Reader) ReadMultiBufferTimeout(d time.Duration) (buf.MultiBuffer, error) {
+ return r.pipe.ReadMultiBufferTimeout(d)
+}
+
+// Interrupt implements common.Interruptible.
+func (r *Reader) Interrupt() {
+ r.pipe.Interrupt()
+}
+
+// ReturnAnError makes ReadMultiBuffer return an error, only once.
+func (r *Reader) ReturnAnError(err error) {
+ r.pipe.errChan <- err
+}
+
+// Recover catches an error set by ReturnAnError, if exists.
+func (r *Reader) Recover() (err error) {
+ select {
+ case err = <-r.pipe.errChan:
+ default:
+ }
+ return
+}
diff --git a/common/xray/pipe/writer.go b/common/xray/pipe/writer.go
new file mode 100644
index 0000000000..153126357c
--- /dev/null
+++ b/common/xray/pipe/writer.go
@@ -0,0 +1,29 @@
+package pipe
+
+import (
+ "github.com/sagernet/sing-box/common/xray/buf"
+)
+
+// Writer is a buf.Writer that writes data into a pipe.
+type Writer struct {
+ pipe *pipe
+}
+
+// WriteMultiBuffer implements buf.Writer.
+func (w *Writer) WriteMultiBuffer(mb buf.MultiBuffer) error {
+ return w.pipe.WriteMultiBuffer(mb)
+}
+
+// Close implements io.Closer. After the pipe is closed, writing to the pipe will return io.ErrClosedPipe, while reading will return io.EOF.
+func (w *Writer) Close() error {
+ return w.pipe.Close()
+}
+
+func (w *Writer) Len() int32 {
+ return w.pipe.Len()
+}
+
+// Interrupt implements common.Interruptible.
+func (w *Writer) Interrupt() {
+ w.pipe.Interrupt()
+}
diff --git a/common/xray/serial/serial.go b/common/xray/serial/serial.go
new file mode 100644
index 0000000000..9d8cb4caf6
--- /dev/null
+++ b/common/xray/serial/serial.go
@@ -0,0 +1,29 @@
+package serial
+
+import (
+ "encoding/binary"
+ "io"
+)
+
+// ReadUint16 reads first two bytes from the reader, and then converts them to an uint16 value.
+func ReadUint16(reader io.Reader) (uint16, error) {
+ var b [2]byte
+ if _, err := io.ReadFull(reader, b[:]); err != nil {
+ return 0, err
+ }
+ return binary.BigEndian.Uint16(b[:]), nil
+}
+
+// WriteUint16 writes an uint16 value into writer.
+func WriteUint16(writer io.Writer, value uint16) (int, error) {
+ var b [2]byte
+ binary.BigEndian.PutUint16(b[:], value)
+ return writer.Write(b[:])
+}
+
+// WriteUint64 writes an uint64 value into writer.
+func WriteUint64(writer io.Writer, value uint64) (int, error) {
+ var b [8]byte
+ binary.BigEndian.PutUint64(b[:], value)
+ return writer.Write(b[:])
+}
diff --git a/common/xray/serial/string.go b/common/xray/serial/string.go
new file mode 100644
index 0000000000..8fdcd7f61f
--- /dev/null
+++ b/common/xray/serial/string.go
@@ -0,0 +1,35 @@
+package serial
+
+import (
+ "fmt"
+ "strings"
+)
+
+// ToString serializes an arbitrary value into string.
+func ToString(v interface{}) string {
+ if v == nil {
+ return ""
+ }
+
+ switch value := v.(type) {
+ case string:
+ return value
+ case *string:
+ return *value
+ case fmt.Stringer:
+ return value.String()
+ case error:
+ return value.Error()
+ default:
+ return fmt.Sprintf("%+v", value)
+ }
+}
+
+// Concat concatenates all input into a single string.
+func Concat(v ...interface{}) string {
+ builder := strings.Builder{}
+ for _, value := range v {
+ builder.WriteString(ToString(value))
+ }
+ return builder.String()
+}
diff --git a/common/xray/signal/done/done.go b/common/xray/signal/done/done.go
new file mode 100644
index 0000000000..5fe0cfedeb
--- /dev/null
+++ b/common/xray/signal/done/done.go
@@ -0,0 +1,41 @@
+package done
+
+import (
+ "sync"
+)
+
+type Instance struct {
+ once sync.Once
+ c chan struct{}
+}
+
+// New returns a new Done.
+func New() *Instance {
+ return &Instance{
+ c: make(chan struct{}),
+ }
+}
+
+// Done returns true if Close() is called.
+func (d *Instance) Done() bool {
+ select {
+ case <-d.c:
+ return true
+ default:
+ return false
+ }
+}
+
+// Wait returns a channel for waiting for done.
+func (d *Instance) Wait() <-chan struct{} {
+ return d.c
+}
+
+// Close marks this Done 'done'. This method may be called multiple times.
+// All calls after the first call have no effect.
+func (d *Instance) Close() error {
+ d.once.Do(func() {
+ close(d.c)
+ })
+ return nil
+}
diff --git a/common/xray/signal/notifier.go b/common/xray/signal/notifier.go
new file mode 100644
index 0000000000..19836e54f9
--- /dev/null
+++ b/common/xray/signal/notifier.go
@@ -0,0 +1,26 @@
+package signal
+
+// Notifier is a utility for notifying changes. The change producer may notify changes multiple time, and the consumer may get notified asynchronously.
+type Notifier struct {
+ c chan struct{}
+}
+
+// NewNotifier creates a new Notifier.
+func NewNotifier() *Notifier {
+ return &Notifier{
+ c: make(chan struct{}, 1),
+ }
+}
+
+// Signal signals a change, usually by producer. This method never blocks.
+func (n *Notifier) Signal() {
+ select {
+ case n.c <- struct{}{}:
+ default:
+ }
+}
+
+// Wait returns a channel for waiting for changes. The returned channel never gets closed.
+func (n *Notifier) Wait() <-chan struct{} {
+ return n.c
+}
diff --git a/common/xray/signal/pubsub/pubsub.go b/common/xray/signal/pubsub/pubsub.go
new file mode 100644
index 0000000000..6de453e852
--- /dev/null
+++ b/common/xray/signal/pubsub/pubsub.go
@@ -0,0 +1,105 @@
+package pubsub
+
+import (
+ "errors"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+ "github.com/sagernet/sing-box/common/xray/task"
+)
+
+type Subscriber struct {
+ buffer chan interface{}
+ done *done.Instance
+}
+
+func (s *Subscriber) push(msg interface{}) {
+ select {
+ case s.buffer <- msg:
+ default:
+ }
+}
+
+func (s *Subscriber) Wait() <-chan interface{} {
+ return s.buffer
+}
+
+func (s *Subscriber) Close() error {
+ return s.done.Close()
+}
+
+func (s *Subscriber) IsClosed() bool {
+ return s.done.Done()
+}
+
+type Service struct {
+ sync.RWMutex
+ subs map[string][]*Subscriber
+ ctask *task.Periodic
+}
+
+func NewService() *Service {
+ s := &Service{
+ subs: make(map[string][]*Subscriber),
+ }
+ s.ctask = &task.Periodic{
+ Execute: s.Cleanup,
+ Interval: time.Second * 30,
+ }
+ return s
+}
+
+// Cleanup cleans up internal caches of subscribers.
+// Visible for testing only.
+func (s *Service) Cleanup() error {
+ s.Lock()
+ defer s.Unlock()
+
+ if len(s.subs) == 0 {
+ return errors.New("nothing to do")
+ }
+
+ for name, subs := range s.subs {
+ newSub := make([]*Subscriber, 0, len(s.subs))
+ for _, sub := range subs {
+ if !sub.IsClosed() {
+ newSub = append(newSub, sub)
+ }
+ }
+ if len(newSub) == 0 {
+ delete(s.subs, name)
+ } else {
+ s.subs[name] = newSub
+ }
+ }
+
+ if len(s.subs) == 0 {
+ s.subs = make(map[string][]*Subscriber)
+ }
+ return nil
+}
+
+func (s *Service) Subscribe(name string) *Subscriber {
+ sub := &Subscriber{
+ buffer: make(chan interface{}, 16),
+ done: done.New(),
+ }
+ s.Lock()
+ s.subs[name] = append(s.subs[name], sub)
+ s.Unlock()
+ common.Must(s.ctask.Start())
+ return sub
+}
+
+func (s *Service) Publish(name string, message interface{}) {
+ s.RLock()
+ defer s.RUnlock()
+
+ for _, sub := range s.subs[name] {
+ if !sub.IsClosed() {
+ sub.push(message)
+ }
+ }
+}
diff --git a/common/xray/signal/semaphore/semaphore.go b/common/xray/signal/semaphore/semaphore.go
new file mode 100644
index 0000000000..8696b148bd
--- /dev/null
+++ b/common/xray/signal/semaphore/semaphore.go
@@ -0,0 +1,27 @@
+package semaphore
+
+// Instance is an implementation of semaphore.
+type Instance struct {
+ token chan struct{}
+}
+
+// New create a new Semaphore with n permits.
+func New(n int) *Instance {
+ s := &Instance{
+ token: make(chan struct{}, n),
+ }
+ for i := 0; i < n; i++ {
+ s.token <- struct{}{}
+ }
+ return s
+}
+
+// Wait returns a channel for acquiring a permit.
+func (s *Instance) Wait() <-chan struct{} {
+ return s.token
+}
+
+// Signal releases a permit into the semaphore.
+func (s *Instance) Signal() {
+ s.token <- struct{}{}
+}
diff --git a/common/xray/signal/timer.go b/common/xray/signal/timer.go
new file mode 100644
index 0000000000..52961bf56e
--- /dev/null
+++ b/common/xray/signal/timer.go
@@ -0,0 +1,85 @@
+package signal
+
+import (
+ "context"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/task"
+)
+
+type ActivityUpdater interface {
+ Update()
+}
+
+type ActivityTimer struct {
+ mu sync.RWMutex
+ updated chan struct{}
+ checkTask *task.Periodic
+ onTimeout func()
+ consumed atomic.Bool
+ once sync.Once
+}
+
+func (t *ActivityTimer) Update() {
+ select {
+ case t.updated <- struct{}{}:
+ default:
+ }
+}
+
+func (t *ActivityTimer) check() error {
+ select {
+ case <-t.updated:
+ default:
+ t.finish()
+ }
+ return nil
+}
+
+func (t *ActivityTimer) finish() {
+ t.once.Do(func() {
+ t.consumed.Store(true)
+ t.mu.Lock()
+ defer t.mu.Unlock()
+
+ common.CloseIfExists(t.checkTask)
+ t.onTimeout()
+ })
+}
+
+func (t *ActivityTimer) SetTimeout(timeout time.Duration) {
+ if t.consumed.Load() {
+ return
+ }
+ if timeout == 0 {
+ t.finish()
+ return
+ }
+
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ // double check, just in case
+ if t.consumed.Load() {
+ return
+ }
+ newCheckTask := &task.Periodic{
+ Interval: timeout,
+ Execute: t.check,
+ }
+ common.CloseIfExists(t.checkTask)
+ t.checkTask = newCheckTask
+ t.Update()
+ common.Must(newCheckTask.Start())
+}
+
+func CancelAfterInactivity(ctx context.Context, cancel context.CancelFunc, timeout time.Duration) *ActivityTimer {
+ timer := &ActivityTimer{
+ updated: make(chan struct{}, 1),
+ onTimeout: cancel,
+ }
+ timer.SetTimeout(timeout)
+ return timer
+}
diff --git a/common/xray/stat/connection.go b/common/xray/stat/connection.go
new file mode 100644
index 0000000000..463db62d5c
--- /dev/null
+++ b/common/xray/stat/connection.go
@@ -0,0 +1,34 @@
+package stat
+
+import (
+ "net"
+
+ "github.com/sagernet/sing-box/common/xray/stats"
+)
+
+type Connection interface {
+ net.Conn
+}
+
+type CounterConnection struct {
+ Connection
+ ReadCounter stats.Counter
+ WriteCounter stats.Counter
+}
+
+func (c *CounterConnection) Read(b []byte) (int, error) {
+ nBytes, err := c.Connection.Read(b)
+ if c.ReadCounter != nil {
+ c.ReadCounter.Add(int64(nBytes))
+ }
+
+ return nBytes, err
+}
+
+func (c *CounterConnection) Write(b []byte) (int, error) {
+ nBytes, err := c.Connection.Write(b)
+ if c.WriteCounter != nil {
+ c.WriteCounter.Add(int64(nBytes))
+ }
+ return nBytes, err
+}
diff --git a/common/xray/stats/stats.go b/common/xray/stats/stats.go
new file mode 100644
index 0000000000..70bbd0269d
--- /dev/null
+++ b/common/xray/stats/stats.go
@@ -0,0 +1,13 @@
+package stats
+
+// Counter is the interface for stats counters.
+//
+// xray:api:stable
+type Counter interface {
+ // Value is the current value of the counter.
+ Value() int64
+ // Set sets a new value to the counter, and returns the previous one.
+ Set(int64) int64
+ // Add adds a value to the current counter value, and returns the previous value.
+ Add(int64) int64
+}
diff --git a/common/xray/task/common.go b/common/xray/task/common.go
new file mode 100644
index 0000000000..11078fb991
--- /dev/null
+++ b/common/xray/task/common.go
@@ -0,0 +1,10 @@
+package task
+
+import "github.com/sagernet/sing-box/common/xray"
+
+// Close returns a func() that closes v.
+func Close(v interface{}) func() error {
+ return func() error {
+ return common.Close(v)
+ }
+}
diff --git a/common/xray/task/periodic.go b/common/xray/task/periodic.go
new file mode 100644
index 0000000000..6abe41ae0b
--- /dev/null
+++ b/common/xray/task/periodic.go
@@ -0,0 +1,85 @@
+package task
+
+import (
+ "sync"
+ "time"
+)
+
+// Periodic is a task that runs periodically.
+type Periodic struct {
+ // Interval of the task being run
+ Interval time.Duration
+ // Execute is the task function
+ Execute func() error
+
+ access sync.Mutex
+ timer *time.Timer
+ running bool
+}
+
+func (t *Periodic) hasClosed() bool {
+ t.access.Lock()
+ defer t.access.Unlock()
+
+ return !t.running
+}
+
+func (t *Periodic) checkedExecute() error {
+ if t.hasClosed() {
+ return nil
+ }
+
+ if err := t.Execute(); err != nil {
+ t.access.Lock()
+ t.running = false
+ t.access.Unlock()
+ return err
+ }
+
+ t.access.Lock()
+ defer t.access.Unlock()
+
+ if !t.running {
+ return nil
+ }
+
+ t.timer = time.AfterFunc(t.Interval, func() {
+ t.checkedExecute()
+ })
+
+ return nil
+}
+
+// Start implements common.Runnable.
+func (t *Periodic) Start() error {
+ t.access.Lock()
+ if t.running {
+ t.access.Unlock()
+ return nil
+ }
+ t.running = true
+ t.access.Unlock()
+
+ if err := t.checkedExecute(); err != nil {
+ t.access.Lock()
+ t.running = false
+ t.access.Unlock()
+ return err
+ }
+
+ return nil
+}
+
+// Close implements common.Closable.
+func (t *Periodic) Close() error {
+ t.access.Lock()
+ defer t.access.Unlock()
+
+ t.running = false
+ if t.timer != nil {
+ t.timer.Stop()
+ t.timer = nil
+ }
+
+ return nil
+}
diff --git a/common/xray/task/task.go b/common/xray/task/task.go
new file mode 100644
index 0000000000..a153839249
--- /dev/null
+++ b/common/xray/task/task.go
@@ -0,0 +1,64 @@
+package task
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/common/xray/signal/semaphore"
+)
+
+// OnSuccess executes g() after f() returns nil.
+func OnSuccess(f func() error, g func() error) func() error {
+ return func() error {
+ if err := f(); err != nil {
+ return err
+ }
+ return g()
+ }
+}
+
+// Run executes a list of tasks in parallel, returns the first error encountered or nil if all tasks pass.
+func Run(ctx context.Context, tasks ...func() error) error {
+ n := len(tasks)
+ s := semaphore.New(n)
+ done := make(chan error, 1)
+
+ for _, task := range tasks {
+ <-s.Wait()
+ go func(f func() error) {
+ err := f()
+ if err == nil {
+ s.Signal()
+ return
+ }
+
+ select {
+ case done <- err:
+ default:
+ }
+ }(task)
+ }
+
+ /*
+ if altctx := ctx.Value("altctx"); altctx != nil {
+ ctx = altctx.(context.Context)
+ }
+ */
+
+ for i := 0; i < n; i++ {
+ select {
+ case err := <-done:
+ return err
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-s.Wait():
+ }
+ }
+
+ /*
+ if cancel := ctx.Value("cancel"); cancel != nil {
+ cancel.(context.CancelFunc)()
+ }
+ */
+
+ return nil
+}
diff --git a/common/xray/utils/browser.go b/common/xray/utils/browser.go
new file mode 100644
index 0000000000..91209f4bda
--- /dev/null
+++ b/common/xray/utils/browser.go
@@ -0,0 +1,28 @@
+package utils
+
+import (
+ "math/rand"
+ "strconv"
+ "time"
+
+ "github.com/klauspost/cpuid/v2"
+)
+
+func ChromeVersion() int {
+ // Use only CPU info as seed for PRNG
+ seed := int64(cpuid.CPU.Family + cpuid.CPU.Model + cpuid.CPU.PhysicalCores + cpuid.CPU.LogicalCores + cpuid.CPU.CacheLine)
+ rng := rand.New(rand.NewSource(seed))
+ // Start from Chrome 144 released on 2026.1.13
+ releaseDate := time.Date(2026, 1, 13, 0, 0, 0, 0, time.UTC)
+ version := 144
+ now := time.Now()
+ // Each version has random 25-45 day interval
+ for releaseDate.Before(now) {
+ releaseDate = releaseDate.AddDate(0, 0, rng.Intn(21)+25)
+ version++
+ }
+ return version - 1
+}
+
+// ChromeUA provides default browser User-Agent based on CPU-seeded PRNG.
+var ChromeUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" + strconv.Itoa(ChromeVersion()) + ".0.0.0 Safari/537.36"
diff --git a/common/xray/utils/padding.go b/common/xray/utils/padding.go
new file mode 100644
index 0000000000..fe95ba9a13
--- /dev/null
+++ b/common/xray/utils/padding.go
@@ -0,0 +1,24 @@
+package utils
+
+import (
+ "math/rand/v2"
+)
+
+var (
+ // 8 ÷ (397/62)
+ h2packCorrectionFactor = 1.2493702770780857
+ base62TotalCharsNum = 62
+ base62Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+)
+
+// H2Base62Pad generates a base62 padding string for HTTP/2 header
+// The total len will be slightly longer than the input to match the length after h2(h3 also) header huffman encoding
+func H2Base62Pad[T int32 | int64 | int](expectedLen T) string {
+ actualLenFloat := float64(expectedLen) * h2packCorrectionFactor
+ actualLen := int(actualLenFloat)
+ result := make([]byte, actualLen)
+ for i := range actualLen {
+ result[i] = base62Chars[rand.N(base62TotalCharsNum)]
+ }
+ return string(result)
+}
diff --git a/common/xray/uuid/uuid.go b/common/xray/uuid/uuid.go
new file mode 100644
index 0000000000..31c7b531a4
--- /dev/null
+++ b/common/xray/uuid/uuid.go
@@ -0,0 +1,105 @@
+package uuid
+
+import (
+ "bytes"
+ "crypto/rand"
+ "crypto/sha1"
+ "encoding/hex"
+
+ "github.com/sagernet/sing-box/common/xray"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+var byteGroups = []int{8, 4, 4, 4, 12}
+
+type UUID [16]byte
+
+// String returns the string representation of this UUID.
+func (u *UUID) String() string {
+ bytes := u.Bytes()
+ result := hex.EncodeToString(bytes[0 : byteGroups[0]/2])
+ start := byteGroups[0] / 2
+ for i := 1; i < len(byteGroups); i++ {
+ nBytes := byteGroups[i] / 2
+ result += "-"
+ result += hex.EncodeToString(bytes[start : start+nBytes])
+ start += nBytes
+ }
+ return result
+}
+
+// Bytes returns the bytes representation of this UUID.
+func (u *UUID) Bytes() []byte {
+ return u[:]
+}
+
+// Equals returns true if this UUID equals another UUID by value.
+func (u *UUID) Equals(another *UUID) bool {
+ if u == nil && another == nil {
+ return true
+ }
+ if u == nil || another == nil {
+ return false
+ }
+ return bytes.Equal(u.Bytes(), another.Bytes())
+}
+
+// New creates a UUID with random value.
+func New() UUID {
+ var uuid UUID
+ common.Must2(rand.Read(uuid.Bytes()))
+ uuid[6] = (uuid[6] & 0x0f) | (4 << 4)
+ uuid[8] = (uuid[8]&(0xff>>2) | (0x02 << 6))
+ return uuid
+}
+
+// ParseBytes converts a UUID in byte form to object.
+func ParseBytes(b []byte) (UUID, error) {
+ var uuid UUID
+ if len(b) != 16 {
+ return uuid, E.New("invalid UUID: ", b)
+ }
+ copy(uuid[:], b)
+ return uuid, nil
+}
+
+// ParseString converts a UUID in string form to object.
+func ParseString(str string) (UUID, error) {
+ var uuid UUID
+
+ text := []byte(str)
+ if l := len(text); l < 32 || l > 36 {
+ if l == 0 || l > 30 {
+ return uuid, E.New("invalid UUID: ", str)
+ }
+ h := sha1.New()
+ h.Write(uuid[:])
+ h.Write(text)
+ u := h.Sum(nil)[:16]
+ u[6] = (u[6] & 0x0f) | (5 << 4)
+ u[8] = (u[8]&(0xff>>2) | (0x02 << 6))
+ copy(uuid[:], u)
+ return uuid, nil
+ }
+
+ b := uuid.Bytes()
+
+ for _, byteGroup := range byteGroups {
+ if len(text) > 0 && text[0] == '-' {
+ text = text[1:]
+ }
+
+ if len(text) < byteGroup {
+ return uuid, E.New("invalid UUID: ", str)
+ }
+
+ if _, err := hex.Decode(b[:byteGroup/2], text[:byteGroup]); err != nil {
+ return uuid, err
+ }
+
+ text = text[byteGroup:]
+ b = b[byteGroup/2:]
+ }
+
+ return uuid, nil
+}
diff --git a/constant/dns.go b/constant/dns.go
index 15d6096c78..22b7967bf2 100644
--- a/constant/dns.go
+++ b/constant/dns.go
@@ -15,19 +15,21 @@ const (
)
const (
- DNSTypeLegacy = "legacy"
- DNSTypeLegacyRcode = "legacy_rcode"
- DNSTypeUDP = "udp"
- DNSTypeTCP = "tcp"
- DNSTypeTLS = "tls"
- DNSTypeHTTPS = "https"
- DNSTypeQUIC = "quic"
- DNSTypeHTTP3 = "h3"
- DNSTypeLocal = "local"
- DNSTypeHosts = "hosts"
- DNSTypeFakeIP = "fakeip"
- DNSTypeDHCP = "dhcp"
- DNSTypeTailscale = "tailscale"
+ DNSTypeLegacy = "legacy"
+ DNSTypeUDP = "udp"
+ DNSTypeTCP = "tcp"
+ DNSTypeTLS = "tls"
+ DNSTypeHTTPS = "https"
+ DNSTypeQUIC = "quic"
+ DNSTypeHTTP3 = "h3"
+ DNSTypeLocal = "local"
+ DNSTypeHosts = "hosts"
+ DNSTypeFakeIP = "fakeip"
+ DNSTypeDHCP = "dhcp"
+ DNSTypeMDNS = "mdns"
+ DNSTypeMulti = "multi" //H
+ DNSTypeSDNS = "sdns" //H
+ DNSTypeTailscale = "tailscale"
)
const (
diff --git a/constant/hysteria2.go b/constant/hysteria2.go
index 35c0b14f20..2d6e6ee8b3 100644
--- a/constant/hysteria2.go
+++ b/constant/hysteria2.go
@@ -1,5 +1,10 @@
package constant
+const (
+ Hysteria2ObfsTypeSalamander = "salamander"
+ Hysteria2ObfsTypeGecko = "gecko"
+)
+
const (
Hysterai2MasqueradeTypeFile = "file"
Hysterai2MasqueradeTypeProxy = "proxy"
diff --git a/constant/proxy.go b/constant/proxy.go
index 278a46c2f6..27c8dee1c6 100644
--- a/constant/proxy.go
+++ b/constant/proxy.go
@@ -1,36 +1,58 @@
package constant
const (
- TypeTun = "tun"
- TypeRedirect = "redirect"
- TypeTProxy = "tproxy"
- TypeDirect = "direct"
- TypeBlock = "block"
- TypeDNS = "dns"
- TypeSOCKS = "socks"
- TypeHTTP = "http"
- TypeMixed = "mixed"
- TypeShadowsocks = "shadowsocks"
- TypeVMess = "vmess"
- TypeTrojan = "trojan"
- TypeNaive = "naive"
- TypeWireGuard = "wireguard"
- TypeHysteria = "hysteria"
- TypeTor = "tor"
- TypeSSH = "ssh"
- TypeShadowTLS = "shadowtls"
- TypeAnyTLS = "anytls"
- TypeShadowsocksR = "shadowsocksr"
- TypeVLESS = "vless"
- TypeTUIC = "tuic"
- TypeHysteria2 = "hysteria2"
- TypeTailscale = "tailscale"
- TypeDERP = "derp"
- TypeResolved = "resolved"
- TypeSSMAPI = "ssm-api"
- TypeCCM = "ccm"
- TypeOCM = "ocm"
- TypeOOMKiller = "oom-killer"
+ TypeTun = "tun"
+ TypeRedirect = "redirect"
+ TypeTProxy = "tproxy"
+ TypeDirect = "direct"
+ TypeBlock = "block"
+ TypeDNS = "dns"
+ TypeSOCKS = "socks"
+ TypeHTTP = "http"
+ TypeMixed = "mixed"
+ TypeShadowsocks = "shadowsocks"
+ TypeVMess = "vmess"
+ TypeTrojan = "trojan"
+ TypeNaive = "naive"
+ TypeWireGuard = "wireguard"
+ TypeWARP = "warp"
+ TypeHysteria = "hysteria"
+ TypeTor = "tor"
+ TypeSSH = "ssh"
+ TypeShadowTLS = "shadowtls"
+ TypeMieru = "mieru"
+ TypeAnyTLS = "anytls"
+ TypeSnell = "snell"
+ TypeMASQUE = "masque"
+ TypeShadowsocksR = "shadowsocksr"
+ TypeVLESS = "vless"
+ TypeTUIC = "tuic"
+ TypeHysteria2 = "hysteria2"
+ TypeHysteriaRealm = "hysteria-realm"
+ TypePsiphon = "psiphon"
+ TypeTunnelClient = "tunnel_client"
+ TypeTunnelServer = "tunnel_server"
+ TypeTailscale = "tailscale"
+ TypeCloudflared = "cloudflared"
+ TypeDERP = "derp"
+ TypeResolved = "resolved"
+ TypeSSMAPI = "ssm-api"
+ TypeCCM = "ccm"
+ TypeOCM = "ocm"
+ TypeOOMKiller = "oom-killer"
+ TypeACME = "acme"
+ TypeCloudflareOriginCA = "cloudflare-origin-ca"
+
+ TypeHInvalidConfig = "hinvalid" //H
+ TypeXray = "xray" //H
+ TypeCustom = "custom" //H
+ TypeAwg = "awg" //H
+ TypeBalancer = "balancer" //H
+ TypeDNSTT = "dnstt" //H
+ TypeGooseRelay = "gooserelay" //H
+ TypeFirebaseTunnelInbound = "firebasetunnel-in" //H
+ TypeFirebaseTunnelOutbound = "firebasetunnel-out" //H
+ TypeSmartDNSPool = "smart_dns_pool" //H — local recursive-resolver pool with AIMD throttling + recovery probing (github.com/hiddify/hmrd_multi_resolver_dns)
)
const (
@@ -68,6 +90,8 @@ func ProxyDisplayName(proxyType string) string {
return "Naive"
case TypeWireGuard:
return "WireGuard"
+ case TypeWARP:
+ return "WARP"
case TypeHysteria:
return "Hysteria"
case TypeTor:
@@ -84,15 +108,49 @@ func ProxyDisplayName(proxyType string) string {
return "TUIC"
case TypeHysteria2:
return "Hysteria2"
+ case TypeMieru:
+ return "Mieru"
case TypeAnyTLS:
return "AnyTLS"
+ case TypeSnell:
+ return "Snell"
+ case TypeMASQUE:
+ return "MASQUE"
+ case TypePsiphon:
+ return "Psiphon"
case TypeTailscale:
return "Tailscale"
+ case TypeCloudflared:
+ return "Cloudflared"
case TypeSelector:
return "Selector"
case TypeURLTest:
return "URLTest"
+ case TypeHInvalidConfig:
+ return "Invalid"
+ case TypeXray:
+ return "xray"
+ case TypeCustom:
+ return "custom"
+ case TypeTunnelClient:
+ return "Tunnel Client"
+ case TypeTunnelServer:
+ return "Tunnel Server"
+ case TypeAwg:
+ return "Awg"
+ case TypeBalancer:
+ return "Balancer"
+ case TypeDNSTT:
+ return "DNSTT"
+ case TypeGooseRelay:
+ return "GooseRelay"
+ case TypeFirebaseTunnelInbound:
+ return "Firebase Tunnel (inbound)"
+ case TypeFirebaseTunnelOutbound:
+ return "Firebase Tunnel (outbound)"
default:
return "Unknown"
}
}
+
+const DefaultBrowserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"
diff --git a/constant/rule.go b/constant/rule.go
index 55cad2e137..efd4a2d32d 100644
--- a/constant/rule.go
+++ b/constant/rule.go
@@ -23,12 +23,15 @@ const (
RuleSetVersion2
RuleSetVersion3
RuleSetVersion4
- RuleSetVersionCurrent = RuleSetVersion4
+ RuleSetVersion5
+ RuleSetVersionCurrent = RuleSetVersion5
)
const (
RuleActionTypeRoute = "route"
RuleActionTypeRouteOptions = "route-options"
+ RuleActionTypeEvaluate = "evaluate"
+ RuleActionTypeRespond = "respond"
RuleActionTypeDirect = "direct"
RuleActionTypeBypass = "bypass"
RuleActionTypeReject = "reject"
diff --git a/constant/tls.go b/constant/tls.go
new file mode 100644
index 0000000000..fdd813b758
--- /dev/null
+++ b/constant/tls.go
@@ -0,0 +1,10 @@
+package constant
+
+const ACMETLS1Protocol = "acme-tls/1"
+
+const (
+ TLSEngineDefault = ""
+ TLSEngineGo = "go"
+ TLSEngineApple = "apple"
+ TLSEngineWindows = "windows"
+)
diff --git a/constant/v2ray.go b/constant/v2ray.go
index c3089a6cf6..1811df5f26 100644
--- a/constant/v2ray.go
+++ b/constant/v2ray.go
@@ -6,4 +6,5 @@ const (
V2RayTransportTypeQUIC = "quic"
V2RayTransportTypeGRPC = "grpc"
V2RayTransportTypeHTTPUpgrade = "httpupgrade"
+ V2RayTransportTypeXHTTP = "xhttp"
)
diff --git a/constant/warp.go b/constant/warp.go
new file mode 100644
index 0000000000..038ce346ea
--- /dev/null
+++ b/constant/warp.go
@@ -0,0 +1,20 @@
+package constant
+
+type WARPConfig struct {
+ PrivateKey string `json:"private_key"`
+ Interface struct {
+ Addresses struct {
+ V4 string `json:"v4"`
+ V6 string `json:"v6"`
+ } `json:"addresses"`
+ } `json:"interface"`
+ Peers []struct {
+ PublicKey string `json:"public_key"`
+ Endpoint struct {
+ V4 string `json:"v4"`
+ V6 string `json:"v6"`
+ Host string `json:"host"`
+ Ports []int `json:"ports"`
+ } `json:"endpoint"`
+ } `json:"peers"`
+}
diff --git a/daemon/instance.go b/daemon/instance.go
index 3acf75ccf9..1cbe50195a 100644
--- a/daemon/instance.go
+++ b/daemon/instance.go
@@ -4,7 +4,7 @@ import (
"bytes"
"context"
- "github.com/sagernet/sing-box"
+ box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/urltest"
C "github.com/sagernet/sing-box/constant"
@@ -71,12 +71,17 @@ type OverrideOptions struct {
func (s *StartedService) newInstance(profileContent string, overrideOptions *OverrideOptions) (*Instance, error) {
ctx := service.ExtendContext(s.ctx)
service.MustRegister[deprecated.Manager](ctx, new(deprecatedManager))
- ctx, cancel := context.WithCancel(include.Context(ctx))
+ // ctx, cancel := context.WithCancel(include.Context(ctx))
options, err := parseConfig(ctx, profileContent)
if err != nil {
- cancel()
+ // cancel()
return nil, err
}
+ return s.newInstanceOptions(options, overrideOptions)
+}
+func (s *StartedService) newInstanceOptions(options option.Options, overrideOptions *OverrideOptions) (*Instance, error) {
+ ctx := s.ctx
+ ctx, cancel := context.WithCancel(include.Context(ctx))
if overrideOptions != nil {
for _, inbound := range options.Inbounds {
if tunInboundOptions, isTUN := inbound.Options.(*option.TunInboundOptions); isTUN {
@@ -87,12 +92,17 @@ func (s *StartedService) newInstance(profileContent string, overrideOptions *Ove
}
}
}
- if s.oomKiller && C.IsIos {
+ if s.oomKillerEnabled {
if !common.Any(options.Services, func(it option.Service) bool {
return it.Type == C.TypeOOMKiller
}) {
+ oomOptions := &option.OOMKillerServiceOptions{
+ KillerDisabled: s.oomKillerDisabled,
+ MemoryLimitOverride: s.oomMemoryLimit,
+ }
options.Services = append(options.Services, option.Service{
- Type: C.TypeOOMKiller,
+ Type: C.TypeOOMKiller,
+ Options: oomOptions,
})
}
}
@@ -112,6 +122,10 @@ func (s *StartedService) newInstance(profileContent string, overrideOptions *Ove
cancel()
return nil, err
}
+ experimentalOptions := common.PtrValueOrDefault(options.Experimental)
+ if experimentalOptions.UnifiedDelay != nil && experimentalOptions.UnifiedDelay.Enabled {
+ ctx = urltest.ContextWithIsUnifiedDelay(ctx)
+ }
i.instance = boxInstance
i.connectionManager = service.FromContext[adapter.ConnectionManager](ctx)
i.clashServer = service.FromContext[adapter.ClashServer](ctx)
@@ -146,3 +160,18 @@ func parseConfig(ctx context.Context, configContent string) (option.Options, err
}
return options, nil
}
+
+func (i *Instance) UrlTestHistory() *urltest.HistoryStorage {
+ return i.urlTestHistoryStorage
+}
+
+func (i *Instance) Context() context.Context {
+ return i.ctx
+}
+
+func (i *Instance) CacheFile() adapter.CacheFile {
+ return i.cacheFile
+}
+func (i *Instance) ClashServer() adapter.ClashServer {
+ return i.clashServer
+}
diff --git a/daemon/platform.go b/daemon/platform.go
index 37906aff08..3d24fc2592 100644
--- a/daemon/platform.go
+++ b/daemon/platform.go
@@ -5,5 +5,7 @@ type PlatformHandler interface {
ServiceReload() error
SystemProxyStatus() (*SystemProxyStatus, error)
SetSystemProxyEnabled(enabled bool) error
+ TriggerNativeCrash() error
WriteDebugMessage(message string)
+ ConnectSSHAgent() (int32, error)
}
diff --git a/daemon/started_service.go b/daemon/started_service.go
index 3af0ea5afa..8f13cda564 100644
--- a/daemon/started_service.go
+++ b/daemon/started_service.go
@@ -6,14 +6,21 @@ import (
"runtime"
"sync"
"time"
+ "unsafe"
"github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/networkquality"
+ "github.com/sagernet/sing-box/common/stun"
"github.com/sagernet/sing-box/common/urltest"
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/experimental/clashapi"
"github.com/sagernet/sing-box/experimental/clashapi/trafficontrol"
"github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/group"
+ "github.com/sagernet/sing-box/service/oomkiller"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/batch"
E "github.com/sagernet/sing/common/exceptions"
@@ -24,6 +31,8 @@ import (
"github.com/gofrs/uuid/v5"
"google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
@@ -32,10 +41,12 @@ var _ StartedServiceServer = (*StartedService)(nil)
type StartedService struct {
ctx context.Context
// platform adapter.PlatformInterface
- handler PlatformHandler
- debug bool
- logMaxLines int
- oomKiller bool
+ handler PlatformHandler
+ debug bool
+ logMaxLines int
+ oomKillerEnabled bool
+ oomKillerDisabled bool
+ oomMemoryLimit uint64
// workingDirectory string
// tempDirectory string
// userID int
@@ -59,30 +70,37 @@ type StartedService struct {
connectionEventSubscriber *observable.Subscriber[trafficontrol.ConnectionEvent]
connectionEventObserver *observable.Observer[trafficontrol.ConnectionEvent]
+
+ extraServices []adapter.LifecycleService //H
}
type ServiceOptions struct {
Context context.Context
// Platform adapter.PlatformInterface
- Handler PlatformHandler
- Debug bool
- LogMaxLines int
- OOMKiller bool
+ Handler PlatformHandler
+ Debug bool
+ LogMaxLines int
+ OOMKillerEnabled bool
+ OOMKillerDisabled bool
+ OOMMemoryLimit uint64
// WorkingDirectory string
// TempDirectory string
// UserID int
// GroupID int
// SystemProxyEnabled bool
+ ExtraServices []adapter.LifecycleService //H
}
func NewStartedService(options ServiceOptions) *StartedService {
s := &StartedService{
ctx: options.Context,
// platform: options.Platform,
- handler: options.Handler,
- debug: options.Debug,
- logMaxLines: options.LogMaxLines,
- oomKiller: options.OOMKiller,
+ handler: options.Handler,
+ debug: options.Debug,
+ logMaxLines: options.LogMaxLines,
+ oomKillerEnabled: options.OOMKillerEnabled,
+ oomKillerDisabled: options.OOMKillerDisabled,
+ oomMemoryLimit: options.OOMMemoryLimit,
// workingDirectory: options.WorkingDirectory,
// tempDirectory: options.TempDirectory,
// userID: options.UserID,
@@ -95,6 +113,7 @@ func NewStartedService(options ServiceOptions) *StartedService {
urlTestHistoryStorage: urltest.NewHistoryStorage(),
clashModeSubscriber: observable.NewSubscriber[struct{}](1),
connectionEventSubscriber: observable.NewSubscriber[trafficontrol.ConnectionEvent](256),
+ extraServices: options.ExtraServices,
}
s.serviceStatusObserver = observable.NewObserver(s.serviceStatusSubscriber, 2)
s.logObserver = observable.NewObserver(s.logSubscriber, 64)
@@ -164,8 +183,13 @@ func (s *StartedService) waitForStarted(ctx context.Context) error {
}
}
}
-
func (s *StartedService) StartOrReloadService(profileContent string, options *OverrideOptions) error {
+ return s.startOrReloadServiceImp(nil, profileContent, options)
+}
+func (s *StartedService) StartOrReloadServiceOptions(profileOptions option.Options) error {
+ return s.startOrReloadServiceImp(&profileOptions, "", nil)
+}
+func (s *StartedService) startOrReloadServiceImp(profileOptions *option.Options, profileContent string, options *OverrideOptions) error {
s.serviceAccess.Lock()
switch s.serviceStatus.Status {
case ServiceStatus_IDLE, ServiceStatus_STARTED, ServiceStatus_STARTING, ServiceStatus_FATAL:
@@ -182,11 +206,21 @@ func (s *StartedService) StartOrReloadService(profileContent string, options *Ov
}
s.updateStatus(ServiceStatus_STARTING)
s.resetLogs()
- instance, err := s.newInstance(profileContent, options)
+ var err error
+ var instance *Instance
+ if profileContent == "" && profileOptions != nil {
+ instance, err = s.newInstanceOptions(*profileOptions, options)
+ } else {
+ instance, err = s.newInstance(profileContent, options)
+
+ }
if err != nil {
return s.updateStatusError(err)
}
s.instance = instance
+ for _, extraService := range s.extraServices {
+ s.instance.Box().AddService(extraService)
+ }
instance.urlTestHistoryStorage.SetHook(s.urlTestSubscriber)
if instance.clashServer != nil {
instance.clashServer.SetModeUpdateHook(s.clashModeSubscriber)
@@ -408,6 +442,9 @@ func (s *StartedService) SubscribeStatus(request *SubscribeStatusRequest, server
}
}
+func (s *StartedService) ReadStatus() *Status {
+ return s.readStatus()
+}
func (s *StartedService) readStatus() *Status {
var status Status
status.Memory = memory.Total()
@@ -603,7 +640,10 @@ func (s *StartedService) URLTest(ctx context.Context, request *URLTestRequest) (
return false
}
_, isGroup := it.(adapter.OutboundGroup)
- return !isGroup
+ if isGroup {
+ return false
+ }
+ return true
})
b, _ := batch.New(boxService.ctx, batch.WithConcurrencyNum[any](10))
for _, detour := range outbounds {
@@ -679,7 +719,42 @@ func (s *StartedService) SetSystemProxyEnabled(ctx context.Context, request *Set
if err != nil {
return nil, err
}
- return nil, err
+ return &emptypb.Empty{}, nil
+}
+
+func (s *StartedService) TriggerDebugCrash(ctx context.Context, request *DebugCrashRequest) (*emptypb.Empty, error) {
+ if !s.debug {
+ return nil, status.Error(codes.PermissionDenied, "debug crash trigger unavailable")
+ }
+ if request == nil {
+ return nil, status.Error(codes.InvalidArgument, "missing debug crash request")
+ }
+ switch request.Type {
+ case DebugCrashRequest_GO:
+ time.AfterFunc(200*time.Millisecond, func() {
+ *(*int)(unsafe.Pointer(uintptr(0))) = 0
+ })
+ case DebugCrashRequest_NATIVE:
+ err := s.handler.TriggerNativeCrash()
+ if err != nil {
+ return nil, err
+ }
+ default:
+ return nil, status.Error(codes.InvalidArgument, "unknown debug crash type")
+ }
+ return &emptypb.Empty{}, nil
+}
+
+func (s *StartedService) TriggerOOMReport(ctx context.Context, _ *emptypb.Empty) (*emptypb.Empty, error) {
+ instance := s.Instance()
+ if instance == nil {
+ return nil, status.Error(codes.FailedPrecondition, "service not started")
+ }
+ reporter := service.FromContext[oomkiller.OOMReporter](instance.ctx)
+ if reporter == nil {
+ return nil, status.Error(codes.Unavailable, "OOM reporter not available")
+ }
+ return &emptypb.Empty{}, reporter.WriteReport(memory.Total())
}
func (s *StartedService) SubscribeConnections(request *SubscribeConnectionsRequest, server grpc.ServerStreamingServer[ConnectionEvents]) error {
@@ -1016,9 +1091,12 @@ func (s *StartedService) GetDeprecatedWarnings(ctx context.Context, empty *empty
return &DeprecatedWarnings{
Warnings: common.Map(notes, func(it deprecated.Note) *DeprecatedWarning {
return &DeprecatedWarning{
- Message: it.Message(),
- Impending: it.Impending(),
- MigrationLink: it.MigrationLink,
+ Message: it.Message(),
+ Impending: it.Impending(),
+ MigrationLink: it.MigrationLink,
+ Description: it.Description,
+ DeprecatedVersion: it.DeprecatedVersion,
+ ScheduledVersion: it.ScheduledVersion,
}
}),
}, nil
@@ -1030,6 +1108,426 @@ func (s *StartedService) GetStartedAt(ctx context.Context, empty *emptypb.Empty)
return &StartedAt{StartedAt: s.startedAt.UnixMilli()}, nil
}
+func (s *StartedService) SubscribeOutbounds(_ *emptypb.Empty, server grpc.ServerStreamingServer[OutboundList]) error {
+ err := s.waitForStarted(server.Context())
+ if err != nil {
+ return err
+ }
+ subscription, done, err := s.urlTestObserver.Subscribe()
+ if err != nil {
+ return err
+ }
+ defer s.urlTestObserver.UnSubscribe(subscription)
+ for {
+ s.serviceAccess.RLock()
+ if s.serviceStatus.Status != ServiceStatus_STARTED {
+ s.serviceAccess.RUnlock()
+ return os.ErrInvalid
+ }
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+ historyStorage := boxService.urlTestHistoryStorage
+ var list OutboundList
+ for _, ob := range boxService.instance.Outbound().Outbounds() {
+ item := &GroupItem{
+ Tag: ob.Tag(),
+ Type: ob.Type(),
+ }
+ if history := historyStorage.LoadURLTestHistory(adapter.OutboundTag(ob)); history != nil {
+ item.UrlTestTime = history.Time.Unix()
+ item.UrlTestDelay = int32(history.Delay)
+ }
+ list.Outbounds = append(list.Outbounds, item)
+ }
+ for _, ep := range boxService.instance.Endpoint().Endpoints() {
+ item := &GroupItem{
+ Tag: ep.Tag(),
+ Type: ep.Type(),
+ }
+ if history := historyStorage.LoadURLTestHistory(adapter.OutboundTag(ep)); history != nil {
+ item.UrlTestTime = history.Time.Unix()
+ item.UrlTestDelay = int32(history.Delay)
+ }
+ list.Outbounds = append(list.Outbounds, item)
+ }
+ err = server.Send(&list)
+ if err != nil {
+ return err
+ }
+ select {
+ case <-subscription:
+ case <-s.ctx.Done():
+ return s.ctx.Err()
+ case <-server.Context().Done():
+ return server.Context().Err()
+ case <-done:
+ return nil
+ }
+ }
+}
+
+func resolveOutbound(instance *Instance, tag string) (adapter.Outbound, error) {
+ if tag == "" {
+ return instance.instance.Outbound().Default(), nil
+ }
+ outbound, loaded := instance.instance.Outbound().Outbound(tag)
+ if !loaded {
+ return nil, E.New("outbound not found: ", tag)
+ }
+ return outbound, nil
+}
+
+func resolveTailscaleEndpoint(instance *Instance, tag string) (adapter.Endpoint, error) {
+ endpointManager := service.FromContext[adapter.EndpointManager](instance.ctx)
+ endpoint, loaded := endpointManager.Get(tag)
+ if !loaded {
+ return nil, E.New("endpoint not found: ", tag)
+ }
+ if endpoint.Type() != C.TypeTailscale {
+ return nil, E.New("endpoint is not Tailscale: ", tag)
+ }
+ return endpoint, nil
+}
+
+func (s *StartedService) StartNetworkQualityTest(
+ request *NetworkQualityTestRequest,
+ server grpc.ServerStreamingServer[NetworkQualityTestProgress],
+) error {
+ err := s.waitForStarted(server.Context())
+ if err != nil {
+ return err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ outbound, err := resolveOutbound(boxService, request.OutboundTag)
+ if err != nil {
+ return err
+ }
+
+ resolvedDialer := dialer.NewResolveDialer(boxService.ctx, outbound, true, "", adapter.DNSQueryOptions{}, 0)
+ httpClient := networkquality.NewHTTPClient(resolvedDialer)
+ defer httpClient.CloseIdleConnections()
+
+ measurementClientFactory, err := networkquality.NewOptionalHTTP3Factory(resolvedDialer, request.Http3)
+ if err != nil {
+ return err
+ }
+
+ result, nqErr := networkquality.Run(networkquality.Options{
+ ConfigURL: request.ConfigURL,
+ HTTPClient: httpClient,
+ NewMeasurementClient: measurementClientFactory,
+ Serial: request.Serial,
+ MaxRuntime: time.Duration(request.MaxRuntimeSeconds) * time.Second,
+ Context: server.Context(),
+ OnProgress: func(p networkquality.Progress) {
+ _ = server.Send(&NetworkQualityTestProgress{
+ Phase: int32(p.Phase),
+ DownloadCapacity: p.DownloadCapacity,
+ UploadCapacity: p.UploadCapacity,
+ DownloadRPM: p.DownloadRPM,
+ UploadRPM: p.UploadRPM,
+ IdleLatencyMs: p.IdleLatencyMs,
+ ElapsedMs: p.ElapsedMs,
+ DownloadCapacityAccuracy: int32(p.DownloadCapacityAccuracy),
+ UploadCapacityAccuracy: int32(p.UploadCapacityAccuracy),
+ DownloadRPMAccuracy: int32(p.DownloadRPMAccuracy),
+ UploadRPMAccuracy: int32(p.UploadRPMAccuracy),
+ })
+ },
+ })
+ if nqErr != nil {
+ return server.Send(&NetworkQualityTestProgress{
+ IsFinal: true,
+ Error: nqErr.Error(),
+ })
+ }
+ return server.Send(&NetworkQualityTestProgress{
+ Phase: int32(networkquality.PhaseDone),
+ DownloadCapacity: result.DownloadCapacity,
+ UploadCapacity: result.UploadCapacity,
+ DownloadRPM: result.DownloadRPM,
+ UploadRPM: result.UploadRPM,
+ IdleLatencyMs: result.IdleLatencyMs,
+ IsFinal: true,
+ DownloadCapacityAccuracy: int32(result.DownloadCapacityAccuracy),
+ UploadCapacityAccuracy: int32(result.UploadCapacityAccuracy),
+ DownloadRPMAccuracy: int32(result.DownloadRPMAccuracy),
+ UploadRPMAccuracy: int32(result.UploadRPMAccuracy),
+ })
+}
+
+func (s *StartedService) StartSTUNTest(
+ request *STUNTestRequest,
+ server grpc.ServerStreamingServer[STUNTestProgress],
+) error {
+ err := s.waitForStarted(server.Context())
+ if err != nil {
+ return err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ outbound, err := resolveOutbound(boxService, request.OutboundTag)
+ if err != nil {
+ return err
+ }
+
+ resolvedDialer := dialer.NewResolveDialer(boxService.ctx, outbound, true, "", adapter.DNSQueryOptions{}, 0)
+
+ result, stunErr := stun.Run(stun.Options{
+ Server: request.Server,
+ Dialer: resolvedDialer,
+ Context: server.Context(),
+ OnProgress: func(p stun.Progress) {
+ _ = server.Send(&STUNTestProgress{
+ Phase: int32(p.Phase),
+ ExternalAddr: p.ExternalAddr,
+ LatencyMs: p.LatencyMs,
+ NatMapping: int32(p.NATMapping),
+ NatFiltering: int32(p.NATFiltering),
+ })
+ },
+ })
+ if stunErr != nil {
+ return server.Send(&STUNTestProgress{
+ IsFinal: true,
+ Error: stunErr.Error(),
+ })
+ }
+ return server.Send(&STUNTestProgress{
+ Phase: int32(stun.PhaseDone),
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ NatMapping: int32(result.NATMapping),
+ NatFiltering: int32(result.NATFiltering),
+ IsFinal: true,
+ NatTypeSupported: result.NATTypeSupported,
+ })
+}
+
+func (s *StartedService) SubscribeTailscaleStatus(
+ _ *emptypb.Empty,
+ server grpc.ServerStreamingServer[TailscaleStatusUpdate],
+) error {
+ err := s.waitForStarted(server.Context())
+ if err != nil {
+ return err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ endpointManager := service.FromContext[adapter.EndpointManager](boxService.ctx)
+ if endpointManager == nil {
+ return status.Error(codes.FailedPrecondition, "endpoint manager not available")
+ }
+
+ type tailscaleEndpoint struct {
+ tag string
+ provider adapter.TailscaleEndpoint
+ }
+ var endpoints []tailscaleEndpoint
+ for _, endpoint := range endpointManager.Endpoints() {
+ if endpoint.Type() != C.TypeTailscale {
+ continue
+ }
+ provider, loaded := endpoint.(adapter.TailscaleEndpoint)
+ if !loaded {
+ continue
+ }
+ endpoints = append(endpoints, tailscaleEndpoint{
+ tag: endpoint.Tag(),
+ provider: provider,
+ })
+ }
+ if len(endpoints) == 0 {
+ return status.Error(codes.NotFound, "no Tailscale endpoint found")
+ }
+
+ type taggedStatus struct {
+ tag string
+ status *adapter.TailscaleEndpointStatus
+ }
+ updates := make(chan taggedStatus, len(endpoints))
+ ctx, cancel := context.WithCancel(server.Context())
+ defer cancel()
+
+ var waitGroup sync.WaitGroup
+ for _, endpoint := range endpoints {
+ waitGroup.Add(1)
+ go func(tag string, provider adapter.TailscaleEndpoint) {
+ defer waitGroup.Done()
+ _ = provider.SubscribeTailscaleStatus(ctx, func(endpointStatus *adapter.TailscaleEndpointStatus) {
+ select {
+ case updates <- taggedStatus{tag: tag, status: endpointStatus}:
+ case <-ctx.Done():
+ }
+ })
+ }(endpoint.tag, endpoint.provider)
+ }
+
+ go func() {
+ waitGroup.Wait()
+ close(updates)
+ }()
+
+ var tags []string
+ statuses := make(map[string]*adapter.TailscaleEndpointStatus, len(endpoints))
+ for update := range updates {
+ if _, exists := statuses[update.tag]; !exists {
+ tags = append(tags, update.tag)
+ }
+ statuses[update.tag] = update.status
+ protoEndpoints := make([]*TailscaleEndpointStatus, 0, len(statuses))
+ for _, tag := range tags {
+ protoEndpoints = append(protoEndpoints, tailscaleEndpointStatusToProto(tag, statuses[tag]))
+ }
+ sendErr := server.Send(&TailscaleStatusUpdate{
+ Endpoints: protoEndpoints,
+ })
+ if sendErr != nil {
+ return sendErr
+ }
+ }
+ return nil
+}
+
+func tailscaleEndpointStatusToProto(tag string, s *adapter.TailscaleEndpointStatus) *TailscaleEndpointStatus {
+ userGroups := make([]*TailscaleUserGroup, len(s.UserGroups))
+ for i, group := range s.UserGroups {
+ peers := make([]*TailscalePeer, len(group.Peers))
+ for j, peer := range group.Peers {
+ peers[j] = tailscalePeerToProto(peer)
+ }
+ userGroups[i] = &TailscaleUserGroup{
+ UserID: group.UserID,
+ LoginName: group.LoginName,
+ DisplayName: group.DisplayName,
+ ProfilePicURL: group.ProfilePicURL,
+ Peers: peers,
+ }
+ }
+ result := &TailscaleEndpointStatus{
+ EndpointTag: tag,
+ BackendState: s.BackendState,
+ AuthURL: s.AuthURL,
+ NetworkName: s.NetworkName,
+ MagicDNSSuffix: s.MagicDNSSuffix,
+ UserGroups: userGroups,
+ }
+ if s.Self != nil {
+ result.Self = tailscalePeerToProto(s.Self)
+ }
+ if s.ExitNode != nil {
+ result.ExitNode = tailscalePeerToProto(s.ExitNode)
+ }
+ return result
+}
+
+func tailscalePeerToProto(peer *adapter.TailscalePeer) *TailscalePeer {
+ return &TailscalePeer{
+ StableID: peer.StableID,
+ HostName: peer.HostName,
+ DnsName: peer.DNSName,
+ Os: peer.OS,
+ TailscaleIPs: peer.TailscaleIPs,
+ SshHostKeys: peer.SSHHostKeys,
+ Online: peer.Online,
+ ExitNode: peer.ExitNode,
+ ExitNodeOption: peer.ExitNodeOption,
+ ShareeNode: peer.ShareeNode,
+ Expired: peer.Expired,
+ Active: peer.Active,
+ RxBytes: peer.RxBytes,
+ TxBytes: peer.TxBytes,
+ KeyExpiry: peer.KeyExpiry,
+ LastSeen: peer.LastSeen,
+ }
+}
+
+func (s *StartedService) StartTailscalePing(
+ request *TailscalePingRequest,
+ server grpc.ServerStreamingServer[TailscalePingResponse],
+) error {
+ err := s.waitForStarted(server.Context())
+ if err != nil {
+ return err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ var provider adapter.TailscaleEndpoint
+ if request.EndpointTag != "" {
+ endpoint, err := resolveTailscaleEndpoint(boxService, request.EndpointTag)
+ if err != nil {
+ return err
+ }
+ pingProvider, loaded := endpoint.(adapter.TailscaleEndpoint)
+ if !loaded {
+ return status.Error(codes.FailedPrecondition, "endpoint does not support ping")
+ }
+ provider = pingProvider
+ } else {
+ endpointManager := service.FromContext[adapter.EndpointManager](boxService.ctx)
+ if endpointManager == nil {
+ return status.Error(codes.FailedPrecondition, "endpoint manager not available")
+ }
+ for _, endpoint := range endpointManager.Endpoints() {
+ if endpoint.Type() != C.TypeTailscale {
+ continue
+ }
+ pingProvider, loaded := endpoint.(adapter.TailscaleEndpoint)
+ if loaded {
+ provider = pingProvider
+ break
+ }
+ }
+ if provider == nil {
+ return status.Error(codes.NotFound, "no Tailscale endpoint found")
+ }
+ }
+
+ return provider.StartTailscalePing(server.Context(), request.PeerIP, func(result *adapter.TailscalePingResult) {
+ _ = server.Send(&TailscalePingResponse{
+ LatencyMs: result.LatencyMs,
+ IsDirect: result.IsDirect,
+ Endpoint: result.Endpoint,
+ DerpRegionID: result.DERPRegionID,
+ DerpRegionCode: result.DERPRegionCode,
+ Error: result.Error,
+ })
+ })
+}
+
+func (s *StartedService) SetTailscaleExitNode(ctx context.Context, request *SetTailscaleExitNodeRequest) (*emptypb.Empty, error) {
+ err := s.waitForStarted(ctx)
+ if err != nil {
+ return nil, err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ endpoint, err := resolveTailscaleEndpoint(boxService, request.EndpointTag)
+ if err != nil {
+ return nil, err
+ }
+ tsEndpoint, loaded := endpoint.(adapter.TailscaleEndpoint)
+ if !loaded {
+ return nil, status.Error(codes.FailedPrecondition, "endpoint does not support tailscale")
+ }
+ err = tsEndpoint.SetTailscaleExitNode(ctx, request.StableID)
+ if err != nil {
+ return nil, err
+ }
+ return &emptypb.Empty{}, nil
+}
+
func (s *StartedService) mustEmbedUnimplementedStartedServiceServer() {
}
diff --git a/daemon/started_service.pb.go b/daemon/started_service.pb.go
index 927fb5149d..3eb41c842f 100644
--- a/daemon/started_service.pb.go
+++ b/daemon/started_service.pb.go
@@ -182,6 +182,52 @@ func (ServiceStatus_Type) EnumDescriptor() ([]byte, []int) {
return file_daemon_started_service_proto_rawDescGZIP(), []int{0, 0}
}
+type DebugCrashRequest_Type int32
+
+const (
+ DebugCrashRequest_GO DebugCrashRequest_Type = 0
+ DebugCrashRequest_NATIVE DebugCrashRequest_Type = 1
+)
+
+// Enum value maps for DebugCrashRequest_Type.
+var (
+ DebugCrashRequest_Type_name = map[int32]string{
+ 0: "GO",
+ 1: "NATIVE",
+ }
+ DebugCrashRequest_Type_value = map[string]int32{
+ "GO": 0,
+ "NATIVE": 1,
+ }
+)
+
+func (x DebugCrashRequest_Type) Enum() *DebugCrashRequest_Type {
+ p := new(DebugCrashRequest_Type)
+ *p = x
+ return p
+}
+
+func (x DebugCrashRequest_Type) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (DebugCrashRequest_Type) Descriptor() protoreflect.EnumDescriptor {
+ return file_daemon_started_service_proto_enumTypes[3].Descriptor()
+}
+
+func (DebugCrashRequest_Type) Type() protoreflect.EnumType {
+ return &file_daemon_started_service_proto_enumTypes[3]
+}
+
+func (x DebugCrashRequest_Type) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use DebugCrashRequest_Type.Descriptor instead.
+func (DebugCrashRequest_Type) EnumDescriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{16, 0}
+}
+
type ServiceStatus struct {
state protoimpl.MessageState `protogen:"open.v1"`
Status ServiceStatus_Type `protobuf:"varint,1,opt,name=status,proto3,enum=daemon.ServiceStatus_Type" json:"status,omitempty"`
@@ -1062,6 +1108,50 @@ func (x *SetSystemProxyEnabledRequest) GetEnabled() bool {
return false
}
+type DebugCrashRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Type DebugCrashRequest_Type `protobuf:"varint,1,opt,name=type,proto3,enum=daemon.DebugCrashRequest_Type" json:"type,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *DebugCrashRequest) Reset() {
+ *x = DebugCrashRequest{}
+ mi := &file_daemon_started_service_proto_msgTypes[16]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *DebugCrashRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DebugCrashRequest) ProtoMessage() {}
+
+func (x *DebugCrashRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[16]
+ 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 DebugCrashRequest.ProtoReflect.Descriptor instead.
+func (*DebugCrashRequest) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *DebugCrashRequest) GetType() DebugCrashRequest_Type {
+ if x != nil {
+ return x.Type
+ }
+ return DebugCrashRequest_GO
+}
+
type SubscribeConnectionsRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Interval int64 `protobuf:"varint,1,opt,name=interval,proto3" json:"interval,omitempty"`
@@ -1071,7 +1161,7 @@ type SubscribeConnectionsRequest struct {
func (x *SubscribeConnectionsRequest) Reset() {
*x = SubscribeConnectionsRequest{}
- mi := &file_daemon_started_service_proto_msgTypes[16]
+ mi := &file_daemon_started_service_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1083,7 +1173,7 @@ func (x *SubscribeConnectionsRequest) String() string {
func (*SubscribeConnectionsRequest) ProtoMessage() {}
func (x *SubscribeConnectionsRequest) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[16]
+ mi := &file_daemon_started_service_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1096,7 +1186,7 @@ func (x *SubscribeConnectionsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SubscribeConnectionsRequest.ProtoReflect.Descriptor instead.
func (*SubscribeConnectionsRequest) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{16}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{17}
}
func (x *SubscribeConnectionsRequest) GetInterval() int64 {
@@ -1120,7 +1210,7 @@ type ConnectionEvent struct {
func (x *ConnectionEvent) Reset() {
*x = ConnectionEvent{}
- mi := &file_daemon_started_service_proto_msgTypes[17]
+ mi := &file_daemon_started_service_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1132,7 +1222,7 @@ func (x *ConnectionEvent) String() string {
func (*ConnectionEvent) ProtoMessage() {}
func (x *ConnectionEvent) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[17]
+ mi := &file_daemon_started_service_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1145,7 +1235,7 @@ func (x *ConnectionEvent) ProtoReflect() protoreflect.Message {
// Deprecated: Use ConnectionEvent.ProtoReflect.Descriptor instead.
func (*ConnectionEvent) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{17}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{18}
}
func (x *ConnectionEvent) GetType() ConnectionEventType {
@@ -1200,7 +1290,7 @@ type ConnectionEvents struct {
func (x *ConnectionEvents) Reset() {
*x = ConnectionEvents{}
- mi := &file_daemon_started_service_proto_msgTypes[18]
+ mi := &file_daemon_started_service_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1212,7 +1302,7 @@ func (x *ConnectionEvents) String() string {
func (*ConnectionEvents) ProtoMessage() {}
func (x *ConnectionEvents) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[18]
+ mi := &file_daemon_started_service_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1225,7 +1315,7 @@ func (x *ConnectionEvents) ProtoReflect() protoreflect.Message {
// Deprecated: Use ConnectionEvents.ProtoReflect.Descriptor instead.
func (*ConnectionEvents) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{18}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{19}
}
func (x *ConnectionEvents) GetEvents() []*ConnectionEvent {
@@ -1272,7 +1362,7 @@ type Connection struct {
func (x *Connection) Reset() {
*x = Connection{}
- mi := &file_daemon_started_service_proto_msgTypes[19]
+ mi := &file_daemon_started_service_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1284,7 +1374,7 @@ func (x *Connection) String() string {
func (*Connection) ProtoMessage() {}
func (x *Connection) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[19]
+ mi := &file_daemon_started_service_proto_msgTypes[20]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1297,7 +1387,7 @@ func (x *Connection) ProtoReflect() protoreflect.Message {
// Deprecated: Use Connection.ProtoReflect.Descriptor instead.
func (*Connection) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{19}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{20}
}
func (x *Connection) GetId() string {
@@ -1467,7 +1557,7 @@ type ProcessInfo struct {
func (x *ProcessInfo) Reset() {
*x = ProcessInfo{}
- mi := &file_daemon_started_service_proto_msgTypes[20]
+ mi := &file_daemon_started_service_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1479,7 +1569,7 @@ func (x *ProcessInfo) String() string {
func (*ProcessInfo) ProtoMessage() {}
func (x *ProcessInfo) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[20]
+ mi := &file_daemon_started_service_proto_msgTypes[21]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1492,7 +1582,7 @@ func (x *ProcessInfo) ProtoReflect() protoreflect.Message {
// Deprecated: Use ProcessInfo.ProtoReflect.Descriptor instead.
func (*ProcessInfo) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{20}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{21}
}
func (x *ProcessInfo) GetProcessId() uint32 {
@@ -1539,7 +1629,7 @@ type CloseConnectionRequest struct {
func (x *CloseConnectionRequest) Reset() {
*x = CloseConnectionRequest{}
- mi := &file_daemon_started_service_proto_msgTypes[21]
+ mi := &file_daemon_started_service_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1551,7 +1641,7 @@ func (x *CloseConnectionRequest) String() string {
func (*CloseConnectionRequest) ProtoMessage() {}
func (x *CloseConnectionRequest) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[21]
+ mi := &file_daemon_started_service_proto_msgTypes[22]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1564,7 +1654,7 @@ func (x *CloseConnectionRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CloseConnectionRequest.ProtoReflect.Descriptor instead.
func (*CloseConnectionRequest) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{21}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{22}
}
func (x *CloseConnectionRequest) GetId() string {
@@ -1583,7 +1673,7 @@ type DeprecatedWarnings struct {
func (x *DeprecatedWarnings) Reset() {
*x = DeprecatedWarnings{}
- mi := &file_daemon_started_service_proto_msgTypes[22]
+ mi := &file_daemon_started_service_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1595,7 +1685,7 @@ func (x *DeprecatedWarnings) String() string {
func (*DeprecatedWarnings) ProtoMessage() {}
func (x *DeprecatedWarnings) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[22]
+ mi := &file_daemon_started_service_proto_msgTypes[23]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1608,7 +1698,7 @@ func (x *DeprecatedWarnings) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeprecatedWarnings.ProtoReflect.Descriptor instead.
func (*DeprecatedWarnings) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{22}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{23}
}
func (x *DeprecatedWarnings) GetWarnings() []*DeprecatedWarning {
@@ -1619,17 +1709,20 @@ func (x *DeprecatedWarnings) GetWarnings() []*DeprecatedWarning {
}
type DeprecatedWarning struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
- Impending bool `protobuf:"varint,2,opt,name=impending,proto3" json:"impending,omitempty"`
- MigrationLink string `protobuf:"bytes,3,opt,name=migrationLink,proto3" json:"migrationLink,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+ Impending bool `protobuf:"varint,2,opt,name=impending,proto3" json:"impending,omitempty"`
+ MigrationLink string `protobuf:"bytes,3,opt,name=migrationLink,proto3" json:"migrationLink,omitempty"`
+ Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"`
+ DeprecatedVersion string `protobuf:"bytes,5,opt,name=deprecatedVersion,proto3" json:"deprecatedVersion,omitempty"`
+ ScheduledVersion string `protobuf:"bytes,6,opt,name=scheduledVersion,proto3" json:"scheduledVersion,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
}
func (x *DeprecatedWarning) Reset() {
*x = DeprecatedWarning{}
- mi := &file_daemon_started_service_proto_msgTypes[23]
+ mi := &file_daemon_started_service_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1641,7 +1734,7 @@ func (x *DeprecatedWarning) String() string {
func (*DeprecatedWarning) ProtoMessage() {}
func (x *DeprecatedWarning) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[23]
+ mi := &file_daemon_started_service_proto_msgTypes[24]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1654,7 +1747,7 @@ func (x *DeprecatedWarning) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeprecatedWarning.ProtoReflect.Descriptor instead.
func (*DeprecatedWarning) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{23}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{24}
}
func (x *DeprecatedWarning) GetMessage() string {
@@ -1678,6 +1771,27 @@ func (x *DeprecatedWarning) GetMigrationLink() string {
return ""
}
+func (x *DeprecatedWarning) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *DeprecatedWarning) GetDeprecatedVersion() string {
+ if x != nil {
+ return x.DeprecatedVersion
+ }
+ return ""
+}
+
+func (x *DeprecatedWarning) GetScheduledVersion() string {
+ if x != nil {
+ return x.ScheduledVersion
+ }
+ return ""
+}
+
type StartedAt struct {
state protoimpl.MessageState `protogen:"open.v1"`
StartedAt int64 `protobuf:"varint,1,opt,name=startedAt,proto3" json:"startedAt,omitempty"`
@@ -1687,7 +1801,7 @@ type StartedAt struct {
func (x *StartedAt) Reset() {
*x = StartedAt{}
- mi := &file_daemon_started_service_proto_msgTypes[24]
+ mi := &file_daemon_started_service_proto_msgTypes[25]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1699,7 +1813,7 @@ func (x *StartedAt) String() string {
func (*StartedAt) ProtoMessage() {}
func (x *StartedAt) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[24]
+ mi := &file_daemon_started_service_proto_msgTypes[25]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1712,7 +1826,7 @@ func (x *StartedAt) ProtoReflect() protoreflect.Message {
// Deprecated: Use StartedAt.ProtoReflect.Descriptor instead.
func (*StartedAt) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{24}
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{25}
}
func (x *StartedAt) GetStartedAt() int64 {
@@ -1722,29 +1836,28 @@ func (x *StartedAt) GetStartedAt() int64 {
return 0
}
-type Log_Message struct {
+type OutboundList struct {
state protoimpl.MessageState `protogen:"open.v1"`
- Level LogLevel `protobuf:"varint,1,opt,name=level,proto3,enum=daemon.LogLevel" json:"level,omitempty"`
- Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+ Outbounds []*GroupItem `protobuf:"bytes,1,rep,name=outbounds,proto3" json:"outbounds,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
-func (x *Log_Message) Reset() {
- *x = Log_Message{}
- mi := &file_daemon_started_service_proto_msgTypes[25]
+func (x *OutboundList) Reset() {
+ *x = OutboundList{}
+ mi := &file_daemon_started_service_proto_msgTypes[26]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
-func (x *Log_Message) String() string {
+func (x *OutboundList) String() string {
return protoimpl.X.MessageStringOf(x)
}
-func (*Log_Message) ProtoMessage() {}
+func (*OutboundList) ProtoMessage() {}
-func (x *Log_Message) ProtoReflect() protoreflect.Message {
- mi := &file_daemon_started_service_proto_msgTypes[25]
+func (x *OutboundList) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[26]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1755,101 +1868,1776 @@ func (x *Log_Message) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
-// Deprecated: Use Log_Message.ProtoReflect.Descriptor instead.
-func (*Log_Message) Descriptor() ([]byte, []int) {
- return file_daemon_started_service_proto_rawDescGZIP(), []int{3, 0}
+// Deprecated: Use OutboundList.ProtoReflect.Descriptor instead.
+func (*OutboundList) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{26}
}
-func (x *Log_Message) GetLevel() LogLevel {
+func (x *OutboundList) GetOutbounds() []*GroupItem {
if x != nil {
- return x.Level
+ return x.Outbounds
}
- return LogLevel_PANIC
+ return nil
}
-func (x *Log_Message) GetMessage() string {
+type NetworkQualityTestRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ ConfigURL string `protobuf:"bytes,1,opt,name=configURL,proto3" json:"configURL,omitempty"`
+ OutboundTag string `protobuf:"bytes,2,opt,name=outboundTag,proto3" json:"outboundTag,omitempty"`
+ Serial bool `protobuf:"varint,3,opt,name=serial,proto3" json:"serial,omitempty"`
+ MaxRuntimeSeconds int32 `protobuf:"varint,4,opt,name=maxRuntimeSeconds,proto3" json:"maxRuntimeSeconds,omitempty"`
+ Http3 bool `protobuf:"varint,5,opt,name=http3,proto3" json:"http3,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *NetworkQualityTestRequest) Reset() {
+ *x = NetworkQualityTestRequest{}
+ mi := &file_daemon_started_service_proto_msgTypes[27]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *NetworkQualityTestRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NetworkQualityTestRequest) ProtoMessage() {}
+
+func (x *NetworkQualityTestRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[27]
if x != nil {
- return x.Message
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use NetworkQualityTestRequest.ProtoReflect.Descriptor instead.
+func (*NetworkQualityTestRequest) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{27}
+}
+
+func (x *NetworkQualityTestRequest) GetConfigURL() string {
+ if x != nil {
+ return x.ConfigURL
}
return ""
}
-var File_daemon_started_service_proto protoreflect.FileDescriptor
+func (x *NetworkQualityTestRequest) GetOutboundTag() string {
+ if x != nil {
+ return x.OutboundTag
+ }
+ return ""
+}
-const file_daemon_started_service_proto_rawDesc = "" +
- "\n" +
- "\x1cdaemon/started_service.proto\x12\x06daemon\x1a\x1bgoogle/protobuf/empty.proto\"\xad\x01\n" +
- "\rServiceStatus\x122\n" +
- "\x06status\x18\x01 \x01(\x0e2\x1a.daemon.ServiceStatus.TypeR\x06status\x12\"\n" +
- "\ferrorMessage\x18\x02 \x01(\tR\ferrorMessage\"D\n" +
- "\x04Type\x12\b\n" +
- "\x04IDLE\x10\x00\x12\f\n" +
- "\bSTARTING\x10\x01\x12\v\n" +
- "\aSTARTED\x10\x02\x12\f\n" +
- "\bSTOPPING\x10\x03\x12\t\n" +
- "\x05FATAL\x10\x04\"D\n" +
- "\x14ReloadServiceRequest\x12,\n" +
- "\x11newProfileContent\x18\x01 \x01(\tR\x11newProfileContent\"4\n" +
- "\x16SubscribeStatusRequest\x12\x1a\n" +
- "\binterval\x18\x01 \x01(\x03R\binterval\"\x99\x01\n" +
- "\x03Log\x12/\n" +
- "\bmessages\x18\x01 \x03(\v2\x13.daemon.Log.MessageR\bmessages\x12\x14\n" +
- "\x05reset\x18\x02 \x01(\bR\x05reset\x1aK\n" +
- "\aMessage\x12&\n" +
- "\x05level\x18\x01 \x01(\x0e2\x10.daemon.LogLevelR\x05level\x12\x18\n" +
- "\amessage\x18\x02 \x01(\tR\amessage\"9\n" +
- "\x0fDefaultLogLevel\x12&\n" +
- "\x05level\x18\x01 \x01(\x0e2\x10.daemon.LogLevelR\x05level\"\xb6\x02\n" +
- "\x06Status\x12\x16\n" +
- "\x06memory\x18\x01 \x01(\x04R\x06memory\x12\x1e\n" +
- "\n" +
- "goroutines\x18\x02 \x01(\x05R\n" +
- "goroutines\x12$\n" +
- "\rconnectionsIn\x18\x03 \x01(\x05R\rconnectionsIn\x12&\n" +
- "\x0econnectionsOut\x18\x04 \x01(\x05R\x0econnectionsOut\x12*\n" +
- "\x10trafficAvailable\x18\x05 \x01(\bR\x10trafficAvailable\x12\x16\n" +
- "\x06uplink\x18\x06 \x01(\x03R\x06uplink\x12\x1a\n" +
- "\bdownlink\x18\a \x01(\x03R\bdownlink\x12 \n" +
- "\vuplinkTotal\x18\b \x01(\x03R\vuplinkTotal\x12$\n" +
- "\rdownlinkTotal\x18\t \x01(\x03R\rdownlinkTotal\"-\n" +
- "\x06Groups\x12#\n" +
- "\x05group\x18\x01 \x03(\v2\r.daemon.GroupR\x05group\"\xae\x01\n" +
- "\x05Group\x12\x10\n" +
- "\x03tag\x18\x01 \x01(\tR\x03tag\x12\x12\n" +
- "\x04type\x18\x02 \x01(\tR\x04type\x12\x1e\n" +
- "\n" +
- "selectable\x18\x03 \x01(\bR\n" +
- "selectable\x12\x1a\n" +
- "\bselected\x18\x04 \x01(\tR\bselected\x12\x1a\n" +
- "\bisExpand\x18\x05 \x01(\bR\bisExpand\x12'\n" +
- "\x05items\x18\x06 \x03(\v2\x11.daemon.GroupItemR\x05items\"w\n" +
- "\tGroupItem\x12\x10\n" +
- "\x03tag\x18\x01 \x01(\tR\x03tag\x12\x12\n" +
- "\x04type\x18\x02 \x01(\tR\x04type\x12 \n" +
- "\vurlTestTime\x18\x03 \x01(\x03R\vurlTestTime\x12\"\n" +
- "\furlTestDelay\x18\x04 \x01(\x05R\furlTestDelay\"2\n" +
- "\x0eURLTestRequest\x12 \n" +
- "\voutboundTag\x18\x01 \x01(\tR\voutboundTag\"U\n" +
- "\x15SelectOutboundRequest\x12\x1a\n" +
- "\bgroupTag\x18\x01 \x01(\tR\bgroupTag\x12 \n" +
- "\voutboundTag\x18\x02 \x01(\tR\voutboundTag\"O\n" +
- "\x15SetGroupExpandRequest\x12\x1a\n" +
- "\bgroupTag\x18\x01 \x01(\tR\bgroupTag\x12\x1a\n" +
- "\bisExpand\x18\x02 \x01(\bR\bisExpand\"\x1f\n" +
- "\tClashMode\x12\x12\n" +
- "\x04mode\x18\x03 \x01(\tR\x04mode\"O\n" +
- "\x0fClashModeStatus\x12\x1a\n" +
- "\bmodeList\x18\x01 \x03(\tR\bmodeList\x12 \n" +
- "\vcurrentMode\x18\x02 \x01(\tR\vcurrentMode\"K\n" +
- "\x11SystemProxyStatus\x12\x1c\n" +
- "\tavailable\x18\x01 \x01(\bR\tavailable\x12\x18\n" +
- "\aenabled\x18\x02 \x01(\bR\aenabled\"8\n" +
- "\x1cSetSystemProxyEnabledRequest\x12\x18\n" +
- "\aenabled\x18\x01 \x01(\bR\aenabled\"9\n" +
- "\x1bSubscribeConnectionsRequest\x12\x1a\n" +
- "\binterval\x18\x01 \x01(\x03R\binterval\"\xea\x01\n" +
- "\x0fConnectionEvent\x12/\n" +
- "\x04type\x18\x01 \x01(\x0e2\x1b.daemon.ConnectionEventTypeR\x04type\x12\x0e\n" +
+func (x *NetworkQualityTestRequest) GetSerial() bool {
+ if x != nil {
+ return x.Serial
+ }
+ return false
+}
+
+func (x *NetworkQualityTestRequest) GetMaxRuntimeSeconds() int32 {
+ if x != nil {
+ return x.MaxRuntimeSeconds
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestRequest) GetHttp3() bool {
+ if x != nil {
+ return x.Http3
+ }
+ return false
+}
+
+type NetworkQualityTestProgress struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Phase int32 `protobuf:"varint,1,opt,name=phase,proto3" json:"phase,omitempty"`
+ DownloadCapacity int64 `protobuf:"varint,2,opt,name=downloadCapacity,proto3" json:"downloadCapacity,omitempty"`
+ UploadCapacity int64 `protobuf:"varint,3,opt,name=uploadCapacity,proto3" json:"uploadCapacity,omitempty"`
+ DownloadRPM int32 `protobuf:"varint,4,opt,name=downloadRPM,proto3" json:"downloadRPM,omitempty"`
+ UploadRPM int32 `protobuf:"varint,5,opt,name=uploadRPM,proto3" json:"uploadRPM,omitempty"`
+ IdleLatencyMs int32 `protobuf:"varint,6,opt,name=idleLatencyMs,proto3" json:"idleLatencyMs,omitempty"`
+ ElapsedMs int64 `protobuf:"varint,7,opt,name=elapsedMs,proto3" json:"elapsedMs,omitempty"`
+ IsFinal bool `protobuf:"varint,8,opt,name=isFinal,proto3" json:"isFinal,omitempty"`
+ Error string `protobuf:"bytes,9,opt,name=error,proto3" json:"error,omitempty"`
+ DownloadCapacityAccuracy int32 `protobuf:"varint,10,opt,name=downloadCapacityAccuracy,proto3" json:"downloadCapacityAccuracy,omitempty"`
+ UploadCapacityAccuracy int32 `protobuf:"varint,11,opt,name=uploadCapacityAccuracy,proto3" json:"uploadCapacityAccuracy,omitempty"`
+ DownloadRPMAccuracy int32 `protobuf:"varint,12,opt,name=downloadRPMAccuracy,proto3" json:"downloadRPMAccuracy,omitempty"`
+ UploadRPMAccuracy int32 `protobuf:"varint,13,opt,name=uploadRPMAccuracy,proto3" json:"uploadRPMAccuracy,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *NetworkQualityTestProgress) Reset() {
+ *x = NetworkQualityTestProgress{}
+ mi := &file_daemon_started_service_proto_msgTypes[28]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *NetworkQualityTestProgress) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*NetworkQualityTestProgress) ProtoMessage() {}
+
+func (x *NetworkQualityTestProgress) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[28]
+ 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 NetworkQualityTestProgress.ProtoReflect.Descriptor instead.
+func (*NetworkQualityTestProgress) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{28}
+}
+
+func (x *NetworkQualityTestProgress) GetPhase() int32 {
+ if x != nil {
+ return x.Phase
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetDownloadCapacity() int64 {
+ if x != nil {
+ return x.DownloadCapacity
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetUploadCapacity() int64 {
+ if x != nil {
+ return x.UploadCapacity
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetDownloadRPM() int32 {
+ if x != nil {
+ return x.DownloadRPM
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetUploadRPM() int32 {
+ if x != nil {
+ return x.UploadRPM
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetIdleLatencyMs() int32 {
+ if x != nil {
+ return x.IdleLatencyMs
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetElapsedMs() int64 {
+ if x != nil {
+ return x.ElapsedMs
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetIsFinal() bool {
+ if x != nil {
+ return x.IsFinal
+ }
+ return false
+}
+
+func (x *NetworkQualityTestProgress) GetError() string {
+ if x != nil {
+ return x.Error
+ }
+ return ""
+}
+
+func (x *NetworkQualityTestProgress) GetDownloadCapacityAccuracy() int32 {
+ if x != nil {
+ return x.DownloadCapacityAccuracy
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetUploadCapacityAccuracy() int32 {
+ if x != nil {
+ return x.UploadCapacityAccuracy
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetDownloadRPMAccuracy() int32 {
+ if x != nil {
+ return x.DownloadRPMAccuracy
+ }
+ return 0
+}
+
+func (x *NetworkQualityTestProgress) GetUploadRPMAccuracy() int32 {
+ if x != nil {
+ return x.UploadRPMAccuracy
+ }
+ return 0
+}
+
+type STUNTestRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Server string `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"`
+ OutboundTag string `protobuf:"bytes,2,opt,name=outboundTag,proto3" json:"outboundTag,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *STUNTestRequest) Reset() {
+ *x = STUNTestRequest{}
+ mi := &file_daemon_started_service_proto_msgTypes[29]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *STUNTestRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*STUNTestRequest) ProtoMessage() {}
+
+func (x *STUNTestRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[29]
+ 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 STUNTestRequest.ProtoReflect.Descriptor instead.
+func (*STUNTestRequest) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{29}
+}
+
+func (x *STUNTestRequest) GetServer() string {
+ if x != nil {
+ return x.Server
+ }
+ return ""
+}
+
+func (x *STUNTestRequest) GetOutboundTag() string {
+ if x != nil {
+ return x.OutboundTag
+ }
+ return ""
+}
+
+type STUNTestProgress struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Phase int32 `protobuf:"varint,1,opt,name=phase,proto3" json:"phase,omitempty"`
+ ExternalAddr string `protobuf:"bytes,2,opt,name=externalAddr,proto3" json:"externalAddr,omitempty"`
+ LatencyMs int32 `protobuf:"varint,3,opt,name=latencyMs,proto3" json:"latencyMs,omitempty"`
+ NatMapping int32 `protobuf:"varint,4,opt,name=natMapping,proto3" json:"natMapping,omitempty"`
+ NatFiltering int32 `protobuf:"varint,5,opt,name=natFiltering,proto3" json:"natFiltering,omitempty"`
+ IsFinal bool `protobuf:"varint,6,opt,name=isFinal,proto3" json:"isFinal,omitempty"`
+ Error string `protobuf:"bytes,7,opt,name=error,proto3" json:"error,omitempty"`
+ NatTypeSupported bool `protobuf:"varint,8,opt,name=natTypeSupported,proto3" json:"natTypeSupported,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *STUNTestProgress) Reset() {
+ *x = STUNTestProgress{}
+ mi := &file_daemon_started_service_proto_msgTypes[30]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *STUNTestProgress) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*STUNTestProgress) ProtoMessage() {}
+
+func (x *STUNTestProgress) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[30]
+ 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 STUNTestProgress.ProtoReflect.Descriptor instead.
+func (*STUNTestProgress) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{30}
+}
+
+func (x *STUNTestProgress) GetPhase() int32 {
+ if x != nil {
+ return x.Phase
+ }
+ return 0
+}
+
+func (x *STUNTestProgress) GetExternalAddr() string {
+ if x != nil {
+ return x.ExternalAddr
+ }
+ return ""
+}
+
+func (x *STUNTestProgress) GetLatencyMs() int32 {
+ if x != nil {
+ return x.LatencyMs
+ }
+ return 0
+}
+
+func (x *STUNTestProgress) GetNatMapping() int32 {
+ if x != nil {
+ return x.NatMapping
+ }
+ return 0
+}
+
+func (x *STUNTestProgress) GetNatFiltering() int32 {
+ if x != nil {
+ return x.NatFiltering
+ }
+ return 0
+}
+
+func (x *STUNTestProgress) GetIsFinal() bool {
+ if x != nil {
+ return x.IsFinal
+ }
+ return false
+}
+
+func (x *STUNTestProgress) GetError() string {
+ if x != nil {
+ return x.Error
+ }
+ return ""
+}
+
+func (x *STUNTestProgress) GetNatTypeSupported() bool {
+ if x != nil {
+ return x.NatTypeSupported
+ }
+ return false
+}
+
+type TailscaleStatusUpdate struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Endpoints []*TailscaleEndpointStatus `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleStatusUpdate) Reset() {
+ *x = TailscaleStatusUpdate{}
+ mi := &file_daemon_started_service_proto_msgTypes[31]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleStatusUpdate) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleStatusUpdate) ProtoMessage() {}
+
+func (x *TailscaleStatusUpdate) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[31]
+ 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 TailscaleStatusUpdate.ProtoReflect.Descriptor instead.
+func (*TailscaleStatusUpdate) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{31}
+}
+
+func (x *TailscaleStatusUpdate) GetEndpoints() []*TailscaleEndpointStatus {
+ if x != nil {
+ return x.Endpoints
+ }
+ return nil
+}
+
+type TailscaleEndpointStatus struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
+ BackendState string `protobuf:"bytes,2,opt,name=backendState,proto3" json:"backendState,omitempty"`
+ AuthURL string `protobuf:"bytes,3,opt,name=authURL,proto3" json:"authURL,omitempty"`
+ NetworkName string `protobuf:"bytes,4,opt,name=networkName,proto3" json:"networkName,omitempty"`
+ MagicDNSSuffix string `protobuf:"bytes,5,opt,name=magicDNSSuffix,proto3" json:"magicDNSSuffix,omitempty"`
+ Self *TailscalePeer `protobuf:"bytes,6,opt,name=self,proto3" json:"self,omitempty"`
+ UserGroups []*TailscaleUserGroup `protobuf:"bytes,7,rep,name=userGroups,proto3" json:"userGroups,omitempty"`
+ ExitNode *TailscalePeer `protobuf:"bytes,8,opt,name=exitNode,proto3" json:"exitNode,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleEndpointStatus) Reset() {
+ *x = TailscaleEndpointStatus{}
+ mi := &file_daemon_started_service_proto_msgTypes[32]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleEndpointStatus) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleEndpointStatus) ProtoMessage() {}
+
+func (x *TailscaleEndpointStatus) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[32]
+ 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 TailscaleEndpointStatus.ProtoReflect.Descriptor instead.
+func (*TailscaleEndpointStatus) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{32}
+}
+
+func (x *TailscaleEndpointStatus) GetEndpointTag() string {
+ if x != nil {
+ return x.EndpointTag
+ }
+ return ""
+}
+
+func (x *TailscaleEndpointStatus) GetBackendState() string {
+ if x != nil {
+ return x.BackendState
+ }
+ return ""
+}
+
+func (x *TailscaleEndpointStatus) GetAuthURL() string {
+ if x != nil {
+ return x.AuthURL
+ }
+ return ""
+}
+
+func (x *TailscaleEndpointStatus) GetNetworkName() string {
+ if x != nil {
+ return x.NetworkName
+ }
+ return ""
+}
+
+func (x *TailscaleEndpointStatus) GetMagicDNSSuffix() string {
+ if x != nil {
+ return x.MagicDNSSuffix
+ }
+ return ""
+}
+
+func (x *TailscaleEndpointStatus) GetSelf() *TailscalePeer {
+ if x != nil {
+ return x.Self
+ }
+ return nil
+}
+
+func (x *TailscaleEndpointStatus) GetUserGroups() []*TailscaleUserGroup {
+ if x != nil {
+ return x.UserGroups
+ }
+ return nil
+}
+
+func (x *TailscaleEndpointStatus) GetExitNode() *TailscalePeer {
+ if x != nil {
+ return x.ExitNode
+ }
+ return nil
+}
+
+type TailscaleUserGroup struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ UserID int64 `protobuf:"varint,1,opt,name=userID,proto3" json:"userID,omitempty"`
+ LoginName string `protobuf:"bytes,2,opt,name=loginName,proto3" json:"loginName,omitempty"`
+ DisplayName string `protobuf:"bytes,3,opt,name=displayName,proto3" json:"displayName,omitempty"`
+ ProfilePicURL string `protobuf:"bytes,4,opt,name=profilePicURL,proto3" json:"profilePicURL,omitempty"`
+ Peers []*TailscalePeer `protobuf:"bytes,5,rep,name=peers,proto3" json:"peers,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleUserGroup) Reset() {
+ *x = TailscaleUserGroup{}
+ mi := &file_daemon_started_service_proto_msgTypes[33]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleUserGroup) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleUserGroup) ProtoMessage() {}
+
+func (x *TailscaleUserGroup) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[33]
+ 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 TailscaleUserGroup.ProtoReflect.Descriptor instead.
+func (*TailscaleUserGroup) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{33}
+}
+
+func (x *TailscaleUserGroup) GetUserID() int64 {
+ if x != nil {
+ return x.UserID
+ }
+ return 0
+}
+
+func (x *TailscaleUserGroup) GetLoginName() string {
+ if x != nil {
+ return x.LoginName
+ }
+ return ""
+}
+
+func (x *TailscaleUserGroup) GetDisplayName() string {
+ if x != nil {
+ return x.DisplayName
+ }
+ return ""
+}
+
+func (x *TailscaleUserGroup) GetProfilePicURL() string {
+ if x != nil {
+ return x.ProfilePicURL
+ }
+ return ""
+}
+
+func (x *TailscaleUserGroup) GetPeers() []*TailscalePeer {
+ if x != nil {
+ return x.Peers
+ }
+ return nil
+}
+
+type TailscalePeer struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ HostName string `protobuf:"bytes,1,opt,name=hostName,proto3" json:"hostName,omitempty"`
+ DnsName string `protobuf:"bytes,2,opt,name=dnsName,proto3" json:"dnsName,omitempty"`
+ Os string `protobuf:"bytes,3,opt,name=os,proto3" json:"os,omitempty"`
+ TailscaleIPs []string `protobuf:"bytes,4,rep,name=tailscaleIPs,proto3" json:"tailscaleIPs,omitempty"`
+ Online bool `protobuf:"varint,5,opt,name=online,proto3" json:"online,omitempty"`
+ ExitNode bool `protobuf:"varint,6,opt,name=exitNode,proto3" json:"exitNode,omitempty"`
+ ExitNodeOption bool `protobuf:"varint,7,opt,name=exitNodeOption,proto3" json:"exitNodeOption,omitempty"`
+ Active bool `protobuf:"varint,8,opt,name=active,proto3" json:"active,omitempty"`
+ RxBytes int64 `protobuf:"varint,9,opt,name=rxBytes,proto3" json:"rxBytes,omitempty"`
+ TxBytes int64 `protobuf:"varint,10,opt,name=txBytes,proto3" json:"txBytes,omitempty"`
+ KeyExpiry int64 `protobuf:"varint,11,opt,name=keyExpiry,proto3" json:"keyExpiry,omitempty"`
+ StableID string `protobuf:"bytes,12,opt,name=stableID,proto3" json:"stableID,omitempty"`
+ Expired bool `protobuf:"varint,13,opt,name=expired,proto3" json:"expired,omitempty"`
+ SshHostKeys []string `protobuf:"bytes,14,rep,name=sshHostKeys,proto3" json:"sshHostKeys,omitempty"`
+ ShareeNode bool `protobuf:"varint,15,opt,name=shareeNode,proto3" json:"shareeNode,omitempty"`
+ LastSeen int64 `protobuf:"varint,16,opt,name=lastSeen,proto3" json:"lastSeen,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscalePeer) Reset() {
+ *x = TailscalePeer{}
+ mi := &file_daemon_started_service_proto_msgTypes[34]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscalePeer) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscalePeer) ProtoMessage() {}
+
+func (x *TailscalePeer) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[34]
+ 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 TailscalePeer.ProtoReflect.Descriptor instead.
+func (*TailscalePeer) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{34}
+}
+
+func (x *TailscalePeer) GetHostName() string {
+ if x != nil {
+ return x.HostName
+ }
+ return ""
+}
+
+func (x *TailscalePeer) GetDnsName() string {
+ if x != nil {
+ return x.DnsName
+ }
+ return ""
+}
+
+func (x *TailscalePeer) GetOs() string {
+ if x != nil {
+ return x.Os
+ }
+ return ""
+}
+
+func (x *TailscalePeer) GetTailscaleIPs() []string {
+ if x != nil {
+ return x.TailscaleIPs
+ }
+ return nil
+}
+
+func (x *TailscalePeer) GetOnline() bool {
+ if x != nil {
+ return x.Online
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetExitNode() bool {
+ if x != nil {
+ return x.ExitNode
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetExitNodeOption() bool {
+ if x != nil {
+ return x.ExitNodeOption
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetActive() bool {
+ if x != nil {
+ return x.Active
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetRxBytes() int64 {
+ if x != nil {
+ return x.RxBytes
+ }
+ return 0
+}
+
+func (x *TailscalePeer) GetTxBytes() int64 {
+ if x != nil {
+ return x.TxBytes
+ }
+ return 0
+}
+
+func (x *TailscalePeer) GetKeyExpiry() int64 {
+ if x != nil {
+ return x.KeyExpiry
+ }
+ return 0
+}
+
+func (x *TailscalePeer) GetStableID() string {
+ if x != nil {
+ return x.StableID
+ }
+ return ""
+}
+
+func (x *TailscalePeer) GetExpired() bool {
+ if x != nil {
+ return x.Expired
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetSshHostKeys() []string {
+ if x != nil {
+ return x.SshHostKeys
+ }
+ return nil
+}
+
+func (x *TailscalePeer) GetShareeNode() bool {
+ if x != nil {
+ return x.ShareeNode
+ }
+ return false
+}
+
+func (x *TailscalePeer) GetLastSeen() int64 {
+ if x != nil {
+ return x.LastSeen
+ }
+ return 0
+}
+
+type TailscalePingRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
+ PeerIP string `protobuf:"bytes,2,opt,name=peerIP,proto3" json:"peerIP,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscalePingRequest) Reset() {
+ *x = TailscalePingRequest{}
+ mi := &file_daemon_started_service_proto_msgTypes[35]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscalePingRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscalePingRequest) ProtoMessage() {}
+
+func (x *TailscalePingRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[35]
+ 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 TailscalePingRequest.ProtoReflect.Descriptor instead.
+func (*TailscalePingRequest) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{35}
+}
+
+func (x *TailscalePingRequest) GetEndpointTag() string {
+ if x != nil {
+ return x.EndpointTag
+ }
+ return ""
+}
+
+func (x *TailscalePingRequest) GetPeerIP() string {
+ if x != nil {
+ return x.PeerIP
+ }
+ return ""
+}
+
+type TailscalePingResponse struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ LatencyMs float64 `protobuf:"fixed64,1,opt,name=latencyMs,proto3" json:"latencyMs,omitempty"`
+ IsDirect bool `protobuf:"varint,2,opt,name=isDirect,proto3" json:"isDirect,omitempty"`
+ Endpoint string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
+ DerpRegionID int32 `protobuf:"varint,4,opt,name=derpRegionID,proto3" json:"derpRegionID,omitempty"`
+ DerpRegionCode string `protobuf:"bytes,5,opt,name=derpRegionCode,proto3" json:"derpRegionCode,omitempty"`
+ Error string `protobuf:"bytes,6,opt,name=error,proto3" json:"error,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscalePingResponse) Reset() {
+ *x = TailscalePingResponse{}
+ mi := &file_daemon_started_service_proto_msgTypes[36]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscalePingResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscalePingResponse) ProtoMessage() {}
+
+func (x *TailscalePingResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[36]
+ 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 TailscalePingResponse.ProtoReflect.Descriptor instead.
+func (*TailscalePingResponse) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{36}
+}
+
+func (x *TailscalePingResponse) GetLatencyMs() float64 {
+ if x != nil {
+ return x.LatencyMs
+ }
+ return 0
+}
+
+func (x *TailscalePingResponse) GetIsDirect() bool {
+ if x != nil {
+ return x.IsDirect
+ }
+ return false
+}
+
+func (x *TailscalePingResponse) GetEndpoint() string {
+ if x != nil {
+ return x.Endpoint
+ }
+ return ""
+}
+
+func (x *TailscalePingResponse) GetDerpRegionID() int32 {
+ if x != nil {
+ return x.DerpRegionID
+ }
+ return 0
+}
+
+func (x *TailscalePingResponse) GetDerpRegionCode() string {
+ if x != nil {
+ return x.DerpRegionCode
+ }
+ return ""
+}
+
+func (x *TailscalePingResponse) GetError() string {
+ if x != nil {
+ return x.Error
+ }
+ return ""
+}
+
+type SetTailscaleExitNodeRequest struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
+ StableID string `protobuf:"bytes,2,opt,name=stableID,proto3" json:"stableID,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *SetTailscaleExitNodeRequest) Reset() {
+ *x = SetTailscaleExitNodeRequest{}
+ mi := &file_daemon_started_service_proto_msgTypes[37]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *SetTailscaleExitNodeRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SetTailscaleExitNodeRequest) ProtoMessage() {}
+
+func (x *SetTailscaleExitNodeRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[37]
+ 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 SetTailscaleExitNodeRequest.ProtoReflect.Descriptor instead.
+func (*SetTailscaleExitNodeRequest) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{37}
+}
+
+func (x *SetTailscaleExitNodeRequest) GetEndpointTag() string {
+ if x != nil {
+ return x.EndpointTag
+ }
+ return ""
+}
+
+func (x *SetTailscaleExitNodeRequest) GetStableID() string {
+ if x != nil {
+ return x.StableID
+ }
+ return ""
+}
+
+type TailscaleSSHClientMessage struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Types that are valid to be assigned to Message:
+ //
+ // *TailscaleSSHClientMessage_Start
+ // *TailscaleSSHClientMessage_Input
+ // *TailscaleSSHClientMessage_Resize
+ Message isTailscaleSSHClientMessage_Message `protobuf_oneof:"message"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHClientMessage) Reset() {
+ *x = TailscaleSSHClientMessage{}
+ mi := &file_daemon_started_service_proto_msgTypes[38]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHClientMessage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHClientMessage) ProtoMessage() {}
+
+func (x *TailscaleSSHClientMessage) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[38]
+ 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 TailscaleSSHClientMessage.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHClientMessage) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{38}
+}
+
+func (x *TailscaleSSHClientMessage) GetMessage() isTailscaleSSHClientMessage_Message {
+ if x != nil {
+ return x.Message
+ }
+ return nil
+}
+
+func (x *TailscaleSSHClientMessage) GetStart() *TailscaleSSHStart {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHClientMessage_Start); ok {
+ return x.Start
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHClientMessage) GetInput() *TailscaleSSHInput {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHClientMessage_Input); ok {
+ return x.Input
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHClientMessage) GetResize() *TailscaleSSHResize {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHClientMessage_Resize); ok {
+ return x.Resize
+ }
+ }
+ return nil
+}
+
+type isTailscaleSSHClientMessage_Message interface {
+ isTailscaleSSHClientMessage_Message()
+}
+
+type TailscaleSSHClientMessage_Start struct {
+ Start *TailscaleSSHStart `protobuf:"bytes,1,opt,name=start,proto3,oneof"`
+}
+
+type TailscaleSSHClientMessage_Input struct {
+ Input *TailscaleSSHInput `protobuf:"bytes,2,opt,name=input,proto3,oneof"`
+}
+
+type TailscaleSSHClientMessage_Resize struct {
+ Resize *TailscaleSSHResize `protobuf:"bytes,3,opt,name=resize,proto3,oneof"`
+}
+
+func (*TailscaleSSHClientMessage_Start) isTailscaleSSHClientMessage_Message() {}
+
+func (*TailscaleSSHClientMessage_Input) isTailscaleSSHClientMessage_Message() {}
+
+func (*TailscaleSSHClientMessage_Resize) isTailscaleSSHClientMessage_Message() {}
+
+type TailscaleSSHStart struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ EndpointTag string `protobuf:"bytes,1,opt,name=endpointTag,proto3" json:"endpointTag,omitempty"`
+ PeerAddress string `protobuf:"bytes,2,opt,name=peerAddress,proto3" json:"peerAddress,omitempty"`
+ Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"`
+ TerminalType string `protobuf:"bytes,4,opt,name=terminalType,proto3" json:"terminalType,omitempty"`
+ Columns int32 `protobuf:"varint,5,opt,name=columns,proto3" json:"columns,omitempty"`
+ Rows int32 `protobuf:"varint,6,opt,name=rows,proto3" json:"rows,omitempty"`
+ WidthPixels int32 `protobuf:"varint,7,opt,name=widthPixels,proto3" json:"widthPixels,omitempty"`
+ HeightPixels int32 `protobuf:"varint,8,opt,name=heightPixels,proto3" json:"heightPixels,omitempty"`
+ HostKeys []string `protobuf:"bytes,9,rep,name=hostKeys,proto3" json:"hostKeys,omitempty"`
+ ForwardAgent bool `protobuf:"varint,10,opt,name=forward_agent,json=forwardAgent,proto3" json:"forward_agent,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHStart) Reset() {
+ *x = TailscaleSSHStart{}
+ mi := &file_daemon_started_service_proto_msgTypes[39]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHStart) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHStart) ProtoMessage() {}
+
+func (x *TailscaleSSHStart) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[39]
+ 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 TailscaleSSHStart.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHStart) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{39}
+}
+
+func (x *TailscaleSSHStart) GetEndpointTag() string {
+ if x != nil {
+ return x.EndpointTag
+ }
+ return ""
+}
+
+func (x *TailscaleSSHStart) GetPeerAddress() string {
+ if x != nil {
+ return x.PeerAddress
+ }
+ return ""
+}
+
+func (x *TailscaleSSHStart) GetUsername() string {
+ if x != nil {
+ return x.Username
+ }
+ return ""
+}
+
+func (x *TailscaleSSHStart) GetTerminalType() string {
+ if x != nil {
+ return x.TerminalType
+ }
+ return ""
+}
+
+func (x *TailscaleSSHStart) GetColumns() int32 {
+ if x != nil {
+ return x.Columns
+ }
+ return 0
+}
+
+func (x *TailscaleSSHStart) GetRows() int32 {
+ if x != nil {
+ return x.Rows
+ }
+ return 0
+}
+
+func (x *TailscaleSSHStart) GetWidthPixels() int32 {
+ if x != nil {
+ return x.WidthPixels
+ }
+ return 0
+}
+
+func (x *TailscaleSSHStart) GetHeightPixels() int32 {
+ if x != nil {
+ return x.HeightPixels
+ }
+ return 0
+}
+
+func (x *TailscaleSSHStart) GetHostKeys() []string {
+ if x != nil {
+ return x.HostKeys
+ }
+ return nil
+}
+
+func (x *TailscaleSSHStart) GetForwardAgent() bool {
+ if x != nil {
+ return x.ForwardAgent
+ }
+ return false
+}
+
+type TailscaleSSHInput struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHInput) Reset() {
+ *x = TailscaleSSHInput{}
+ mi := &file_daemon_started_service_proto_msgTypes[40]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHInput) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHInput) ProtoMessage() {}
+
+func (x *TailscaleSSHInput) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[40]
+ 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 TailscaleSSHInput.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHInput) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{40}
+}
+
+func (x *TailscaleSSHInput) GetData() []byte {
+ if x != nil {
+ return x.Data
+ }
+ return nil
+}
+
+type TailscaleSSHResize struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Columns int32 `protobuf:"varint,1,opt,name=columns,proto3" json:"columns,omitempty"`
+ Rows int32 `protobuf:"varint,2,opt,name=rows,proto3" json:"rows,omitempty"`
+ WidthPixels int32 `protobuf:"varint,3,opt,name=widthPixels,proto3" json:"widthPixels,omitempty"`
+ HeightPixels int32 `protobuf:"varint,4,opt,name=heightPixels,proto3" json:"heightPixels,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHResize) Reset() {
+ *x = TailscaleSSHResize{}
+ mi := &file_daemon_started_service_proto_msgTypes[41]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHResize) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHResize) ProtoMessage() {}
+
+func (x *TailscaleSSHResize) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[41]
+ 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 TailscaleSSHResize.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHResize) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{41}
+}
+
+func (x *TailscaleSSHResize) GetColumns() int32 {
+ if x != nil {
+ return x.Columns
+ }
+ return 0
+}
+
+func (x *TailscaleSSHResize) GetRows() int32 {
+ if x != nil {
+ return x.Rows
+ }
+ return 0
+}
+
+func (x *TailscaleSSHResize) GetWidthPixels() int32 {
+ if x != nil {
+ return x.WidthPixels
+ }
+ return 0
+}
+
+func (x *TailscaleSSHResize) GetHeightPixels() int32 {
+ if x != nil {
+ return x.HeightPixels
+ }
+ return 0
+}
+
+type TailscaleSSHServerMessage struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // Types that are valid to be assigned to Message:
+ //
+ // *TailscaleSSHServerMessage_AuthBanner
+ // *TailscaleSSHServerMessage_Ready
+ // *TailscaleSSHServerMessage_Output
+ // *TailscaleSSHServerMessage_Exit
+ // *TailscaleSSHServerMessage_Error
+ Message isTailscaleSSHServerMessage_Message `protobuf_oneof:"message"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHServerMessage) Reset() {
+ *x = TailscaleSSHServerMessage{}
+ mi := &file_daemon_started_service_proto_msgTypes[42]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHServerMessage) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHServerMessage) ProtoMessage() {}
+
+func (x *TailscaleSSHServerMessage) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[42]
+ 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 TailscaleSSHServerMessage.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHServerMessage) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{42}
+}
+
+func (x *TailscaleSSHServerMessage) GetMessage() isTailscaleSSHServerMessage_Message {
+ if x != nil {
+ return x.Message
+ }
+ return nil
+}
+
+func (x *TailscaleSSHServerMessage) GetAuthBanner() *TailscaleSSHAuthBanner {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHServerMessage_AuthBanner); ok {
+ return x.AuthBanner
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHServerMessage) GetReady() *TailscaleSSHReady {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHServerMessage_Ready); ok {
+ return x.Ready
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHServerMessage) GetOutput() *TailscaleSSHOutput {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHServerMessage_Output); ok {
+ return x.Output
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHServerMessage) GetExit() *TailscaleSSHExit {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHServerMessage_Exit); ok {
+ return x.Exit
+ }
+ }
+ return nil
+}
+
+func (x *TailscaleSSHServerMessage) GetError() *TailscaleSSHError {
+ if x != nil {
+ if x, ok := x.Message.(*TailscaleSSHServerMessage_Error); ok {
+ return x.Error
+ }
+ }
+ return nil
+}
+
+type isTailscaleSSHServerMessage_Message interface {
+ isTailscaleSSHServerMessage_Message()
+}
+
+type TailscaleSSHServerMessage_AuthBanner struct {
+ AuthBanner *TailscaleSSHAuthBanner `protobuf:"bytes,1,opt,name=authBanner,proto3,oneof"`
+}
+
+type TailscaleSSHServerMessage_Ready struct {
+ Ready *TailscaleSSHReady `protobuf:"bytes,2,opt,name=ready,proto3,oneof"`
+}
+
+type TailscaleSSHServerMessage_Output struct {
+ Output *TailscaleSSHOutput `protobuf:"bytes,3,opt,name=output,proto3,oneof"`
+}
+
+type TailscaleSSHServerMessage_Exit struct {
+ Exit *TailscaleSSHExit `protobuf:"bytes,4,opt,name=exit,proto3,oneof"`
+}
+
+type TailscaleSSHServerMessage_Error struct {
+ Error *TailscaleSSHError `protobuf:"bytes,5,opt,name=error,proto3,oneof"`
+}
+
+func (*TailscaleSSHServerMessage_AuthBanner) isTailscaleSSHServerMessage_Message() {}
+
+func (*TailscaleSSHServerMessage_Ready) isTailscaleSSHServerMessage_Message() {}
+
+func (*TailscaleSSHServerMessage_Output) isTailscaleSSHServerMessage_Message() {}
+
+func (*TailscaleSSHServerMessage_Exit) isTailscaleSSHServerMessage_Message() {}
+
+func (*TailscaleSSHServerMessage_Error) isTailscaleSSHServerMessage_Message() {}
+
+type TailscaleSSHAuthBanner struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHAuthBanner) Reset() {
+ *x = TailscaleSSHAuthBanner{}
+ mi := &file_daemon_started_service_proto_msgTypes[43]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHAuthBanner) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHAuthBanner) ProtoMessage() {}
+
+func (x *TailscaleSSHAuthBanner) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[43]
+ 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 TailscaleSSHAuthBanner.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHAuthBanner) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{43}
+}
+
+func (x *TailscaleSSHAuthBanner) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type TailscaleSSHReady struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHReady) Reset() {
+ *x = TailscaleSSHReady{}
+ mi := &file_daemon_started_service_proto_msgTypes[44]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHReady) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHReady) ProtoMessage() {}
+
+func (x *TailscaleSSHReady) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[44]
+ 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 TailscaleSSHReady.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHReady) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{44}
+}
+
+type TailscaleSSHOutput struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHOutput) Reset() {
+ *x = TailscaleSSHOutput{}
+ mi := &file_daemon_started_service_proto_msgTypes[45]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHOutput) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHOutput) ProtoMessage() {}
+
+func (x *TailscaleSSHOutput) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[45]
+ 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 TailscaleSSHOutput.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHOutput) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{45}
+}
+
+func (x *TailscaleSSHOutput) GetData() []byte {
+ if x != nil {
+ return x.Data
+ }
+ return nil
+}
+
+type TailscaleSSHExit struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ ExitCode int32 `protobuf:"varint,1,opt,name=exitCode,proto3" json:"exitCode,omitempty"`
+ Signal string `protobuf:"bytes,2,opt,name=signal,proto3" json:"signal,omitempty"`
+ ErrorMessage string `protobuf:"bytes,3,opt,name=errorMessage,proto3" json:"errorMessage,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHExit) Reset() {
+ *x = TailscaleSSHExit{}
+ mi := &file_daemon_started_service_proto_msgTypes[46]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHExit) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHExit) ProtoMessage() {}
+
+func (x *TailscaleSSHExit) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[46]
+ 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 TailscaleSSHExit.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHExit) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{46}
+}
+
+func (x *TailscaleSSHExit) GetExitCode() int32 {
+ if x != nil {
+ return x.ExitCode
+ }
+ return 0
+}
+
+func (x *TailscaleSSHExit) GetSignal() string {
+ if x != nil {
+ return x.Signal
+ }
+ return ""
+}
+
+func (x *TailscaleSSHExit) GetErrorMessage() string {
+ if x != nil {
+ return x.ErrorMessage
+ }
+ return ""
+}
+
+type TailscaleSSHError struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *TailscaleSSHError) Reset() {
+ *x = TailscaleSSHError{}
+ mi := &file_daemon_started_service_proto_msgTypes[47]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *TailscaleSSHError) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TailscaleSSHError) ProtoMessage() {}
+
+func (x *TailscaleSSHError) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[47]
+ 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 TailscaleSSHError.ProtoReflect.Descriptor instead.
+func (*TailscaleSSHError) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{47}
+}
+
+func (x *TailscaleSSHError) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+type Log_Message struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Level LogLevel `protobuf:"varint,1,opt,name=level,proto3,enum=daemon.LogLevel" json:"level,omitempty"`
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *Log_Message) Reset() {
+ *x = Log_Message{}
+ mi := &file_daemon_started_service_proto_msgTypes[48]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *Log_Message) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Log_Message) ProtoMessage() {}
+
+func (x *Log_Message) ProtoReflect() protoreflect.Message {
+ mi := &file_daemon_started_service_proto_msgTypes[48]
+ 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 Log_Message.ProtoReflect.Descriptor instead.
+func (*Log_Message) Descriptor() ([]byte, []int) {
+ return file_daemon_started_service_proto_rawDescGZIP(), []int{3, 0}
+}
+
+func (x *Log_Message) GetLevel() LogLevel {
+ if x != nil {
+ return x.Level
+ }
+ return LogLevel_PANIC
+}
+
+func (x *Log_Message) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+var File_daemon_started_service_proto protoreflect.FileDescriptor
+
+const file_daemon_started_service_proto_rawDesc = "" +
+ "\n" +
+ "\x1cdaemon/started_service.proto\x12\x06daemon\x1a\x1bgoogle/protobuf/empty.proto\"\xad\x01\n" +
+ "\rServiceStatus\x122\n" +
+ "\x06status\x18\x01 \x01(\x0e2\x1a.daemon.ServiceStatus.TypeR\x06status\x12\"\n" +
+ "\ferrorMessage\x18\x02 \x01(\tR\ferrorMessage\"D\n" +
+ "\x04Type\x12\b\n" +
+ "\x04IDLE\x10\x00\x12\f\n" +
+ "\bSTARTING\x10\x01\x12\v\n" +
+ "\aSTARTED\x10\x02\x12\f\n" +
+ "\bSTOPPING\x10\x03\x12\t\n" +
+ "\x05FATAL\x10\x04\"D\n" +
+ "\x14ReloadServiceRequest\x12,\n" +
+ "\x11newProfileContent\x18\x01 \x01(\tR\x11newProfileContent\"4\n" +
+ "\x16SubscribeStatusRequest\x12\x1a\n" +
+ "\binterval\x18\x01 \x01(\x03R\binterval\"\x99\x01\n" +
+ "\x03Log\x12/\n" +
+ "\bmessages\x18\x01 \x03(\v2\x13.daemon.Log.MessageR\bmessages\x12\x14\n" +
+ "\x05reset\x18\x02 \x01(\bR\x05reset\x1aK\n" +
+ "\aMessage\x12&\n" +
+ "\x05level\x18\x01 \x01(\x0e2\x10.daemon.LogLevelR\x05level\x12\x18\n" +
+ "\amessage\x18\x02 \x01(\tR\amessage\"9\n" +
+ "\x0fDefaultLogLevel\x12&\n" +
+ "\x05level\x18\x01 \x01(\x0e2\x10.daemon.LogLevelR\x05level\"\xb6\x02\n" +
+ "\x06Status\x12\x16\n" +
+ "\x06memory\x18\x01 \x01(\x04R\x06memory\x12\x1e\n" +
+ "\n" +
+ "goroutines\x18\x02 \x01(\x05R\n" +
+ "goroutines\x12$\n" +
+ "\rconnectionsIn\x18\x03 \x01(\x05R\rconnectionsIn\x12&\n" +
+ "\x0econnectionsOut\x18\x04 \x01(\x05R\x0econnectionsOut\x12*\n" +
+ "\x10trafficAvailable\x18\x05 \x01(\bR\x10trafficAvailable\x12\x16\n" +
+ "\x06uplink\x18\x06 \x01(\x03R\x06uplink\x12\x1a\n" +
+ "\bdownlink\x18\a \x01(\x03R\bdownlink\x12 \n" +
+ "\vuplinkTotal\x18\b \x01(\x03R\vuplinkTotal\x12$\n" +
+ "\rdownlinkTotal\x18\t \x01(\x03R\rdownlinkTotal\"-\n" +
+ "\x06Groups\x12#\n" +
+ "\x05group\x18\x01 \x03(\v2\r.daemon.GroupR\x05group\"\xae\x01\n" +
+ "\x05Group\x12\x10\n" +
+ "\x03tag\x18\x01 \x01(\tR\x03tag\x12\x12\n" +
+ "\x04type\x18\x02 \x01(\tR\x04type\x12\x1e\n" +
+ "\n" +
+ "selectable\x18\x03 \x01(\bR\n" +
+ "selectable\x12\x1a\n" +
+ "\bselected\x18\x04 \x01(\tR\bselected\x12\x1a\n" +
+ "\bisExpand\x18\x05 \x01(\bR\bisExpand\x12'\n" +
+ "\x05items\x18\x06 \x03(\v2\x11.daemon.GroupItemR\x05items\"w\n" +
+ "\tGroupItem\x12\x10\n" +
+ "\x03tag\x18\x01 \x01(\tR\x03tag\x12\x12\n" +
+ "\x04type\x18\x02 \x01(\tR\x04type\x12 \n" +
+ "\vurlTestTime\x18\x03 \x01(\x03R\vurlTestTime\x12\"\n" +
+ "\furlTestDelay\x18\x04 \x01(\x05R\furlTestDelay\"2\n" +
+ "\x0eURLTestRequest\x12 \n" +
+ "\voutboundTag\x18\x01 \x01(\tR\voutboundTag\"U\n" +
+ "\x15SelectOutboundRequest\x12\x1a\n" +
+ "\bgroupTag\x18\x01 \x01(\tR\bgroupTag\x12 \n" +
+ "\voutboundTag\x18\x02 \x01(\tR\voutboundTag\"O\n" +
+ "\x15SetGroupExpandRequest\x12\x1a\n" +
+ "\bgroupTag\x18\x01 \x01(\tR\bgroupTag\x12\x1a\n" +
+ "\bisExpand\x18\x02 \x01(\bR\bisExpand\"\x1f\n" +
+ "\tClashMode\x12\x12\n" +
+ "\x04mode\x18\x03 \x01(\tR\x04mode\"O\n" +
+ "\x0fClashModeStatus\x12\x1a\n" +
+ "\bmodeList\x18\x01 \x03(\tR\bmodeList\x12 \n" +
+ "\vcurrentMode\x18\x02 \x01(\tR\vcurrentMode\"K\n" +
+ "\x11SystemProxyStatus\x12\x1c\n" +
+ "\tavailable\x18\x01 \x01(\bR\tavailable\x12\x18\n" +
+ "\aenabled\x18\x02 \x01(\bR\aenabled\"8\n" +
+ "\x1cSetSystemProxyEnabledRequest\x12\x18\n" +
+ "\aenabled\x18\x01 \x01(\bR\aenabled\"c\n" +
+ "\x11DebugCrashRequest\x122\n" +
+ "\x04type\x18\x01 \x01(\x0e2\x1e.daemon.DebugCrashRequest.TypeR\x04type\"\x1a\n" +
+ "\x04Type\x12\x06\n" +
+ "\x02GO\x10\x00\x12\n" +
+ "\n" +
+ "\x06NATIVE\x10\x01\"9\n" +
+ "\x1bSubscribeConnectionsRequest\x12\x1a\n" +
+ "\binterval\x18\x01 \x01(\x03R\binterval\"\xea\x01\n" +
+ "\x0fConnectionEvent\x12/\n" +
+ "\x04type\x18\x01 \x01(\x0e2\x1b.daemon.ConnectionEventTypeR\x04type\x12\x0e\n" +
"\x02id\x18\x02 \x01(\tR\x02id\x122\n" +
"\n" +
"connection\x18\x03 \x01(\v2\x12.daemon.ConnectionR\n" +
@@ -1894,13 +3682,149 @@ const file_daemon_started_service_proto_rawDesc = "" +
"\x16CloseConnectionRequest\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\"K\n" +
"\x12DeprecatedWarnings\x125\n" +
- "\bwarnings\x18\x01 \x03(\v2\x19.daemon.DeprecatedWarningR\bwarnings\"q\n" +
+ "\bwarnings\x18\x01 \x03(\v2\x19.daemon.DeprecatedWarningR\bwarnings\"\xed\x01\n" +
"\x11DeprecatedWarning\x12\x18\n" +
"\amessage\x18\x01 \x01(\tR\amessage\x12\x1c\n" +
"\timpending\x18\x02 \x01(\bR\timpending\x12$\n" +
- "\rmigrationLink\x18\x03 \x01(\tR\rmigrationLink\")\n" +
+ "\rmigrationLink\x18\x03 \x01(\tR\rmigrationLink\x12 \n" +
+ "\vdescription\x18\x04 \x01(\tR\vdescription\x12,\n" +
+ "\x11deprecatedVersion\x18\x05 \x01(\tR\x11deprecatedVersion\x12*\n" +
+ "\x10scheduledVersion\x18\x06 \x01(\tR\x10scheduledVersion\")\n" +
"\tStartedAt\x12\x1c\n" +
- "\tstartedAt\x18\x01 \x01(\x03R\tstartedAt*U\n" +
+ "\tstartedAt\x18\x01 \x01(\x03R\tstartedAt\"?\n" +
+ "\fOutboundList\x12/\n" +
+ "\toutbounds\x18\x01 \x03(\v2\x11.daemon.GroupItemR\toutbounds\"\xb7\x01\n" +
+ "\x19NetworkQualityTestRequest\x12\x1c\n" +
+ "\tconfigURL\x18\x01 \x01(\tR\tconfigURL\x12 \n" +
+ "\voutboundTag\x18\x02 \x01(\tR\voutboundTag\x12\x16\n" +
+ "\x06serial\x18\x03 \x01(\bR\x06serial\x12,\n" +
+ "\x11maxRuntimeSeconds\x18\x04 \x01(\x05R\x11maxRuntimeSeconds\x12\x14\n" +
+ "\x05http3\x18\x05 \x01(\bR\x05http3\"\x8e\x04\n" +
+ "\x1aNetworkQualityTestProgress\x12\x14\n" +
+ "\x05phase\x18\x01 \x01(\x05R\x05phase\x12*\n" +
+ "\x10downloadCapacity\x18\x02 \x01(\x03R\x10downloadCapacity\x12&\n" +
+ "\x0euploadCapacity\x18\x03 \x01(\x03R\x0euploadCapacity\x12 \n" +
+ "\vdownloadRPM\x18\x04 \x01(\x05R\vdownloadRPM\x12\x1c\n" +
+ "\tuploadRPM\x18\x05 \x01(\x05R\tuploadRPM\x12$\n" +
+ "\ridleLatencyMs\x18\x06 \x01(\x05R\ridleLatencyMs\x12\x1c\n" +
+ "\telapsedMs\x18\a \x01(\x03R\telapsedMs\x12\x18\n" +
+ "\aisFinal\x18\b \x01(\bR\aisFinal\x12\x14\n" +
+ "\x05error\x18\t \x01(\tR\x05error\x12:\n" +
+ "\x18downloadCapacityAccuracy\x18\n" +
+ " \x01(\x05R\x18downloadCapacityAccuracy\x126\n" +
+ "\x16uploadCapacityAccuracy\x18\v \x01(\x05R\x16uploadCapacityAccuracy\x120\n" +
+ "\x13downloadRPMAccuracy\x18\f \x01(\x05R\x13downloadRPMAccuracy\x12,\n" +
+ "\x11uploadRPMAccuracy\x18\r \x01(\x05R\x11uploadRPMAccuracy\"K\n" +
+ "\x0fSTUNTestRequest\x12\x16\n" +
+ "\x06server\x18\x01 \x01(\tR\x06server\x12 \n" +
+ "\voutboundTag\x18\x02 \x01(\tR\voutboundTag\"\x8a\x02\n" +
+ "\x10STUNTestProgress\x12\x14\n" +
+ "\x05phase\x18\x01 \x01(\x05R\x05phase\x12\"\n" +
+ "\fexternalAddr\x18\x02 \x01(\tR\fexternalAddr\x12\x1c\n" +
+ "\tlatencyMs\x18\x03 \x01(\x05R\tlatencyMs\x12\x1e\n" +
+ "\n" +
+ "natMapping\x18\x04 \x01(\x05R\n" +
+ "natMapping\x12\"\n" +
+ "\fnatFiltering\x18\x05 \x01(\x05R\fnatFiltering\x12\x18\n" +
+ "\aisFinal\x18\x06 \x01(\bR\aisFinal\x12\x14\n" +
+ "\x05error\x18\a \x01(\tR\x05error\x12*\n" +
+ "\x10natTypeSupported\x18\b \x01(\bR\x10natTypeSupported\"V\n" +
+ "\x15TailscaleStatusUpdate\x12=\n" +
+ "\tendpoints\x18\x01 \x03(\v2\x1f.daemon.TailscaleEndpointStatusR\tendpoints\"\xdd\x02\n" +
+ "\x17TailscaleEndpointStatus\x12 \n" +
+ "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\"\n" +
+ "\fbackendState\x18\x02 \x01(\tR\fbackendState\x12\x18\n" +
+ "\aauthURL\x18\x03 \x01(\tR\aauthURL\x12 \n" +
+ "\vnetworkName\x18\x04 \x01(\tR\vnetworkName\x12&\n" +
+ "\x0emagicDNSSuffix\x18\x05 \x01(\tR\x0emagicDNSSuffix\x12)\n" +
+ "\x04self\x18\x06 \x01(\v2\x15.daemon.TailscalePeerR\x04self\x12:\n" +
+ "\n" +
+ "userGroups\x18\a \x03(\v2\x1a.daemon.TailscaleUserGroupR\n" +
+ "userGroups\x121\n" +
+ "\bexitNode\x18\b \x01(\v2\x15.daemon.TailscalePeerR\bexitNode\"\xbf\x01\n" +
+ "\x12TailscaleUserGroup\x12\x16\n" +
+ "\x06userID\x18\x01 \x01(\x03R\x06userID\x12\x1c\n" +
+ "\tloginName\x18\x02 \x01(\tR\tloginName\x12 \n" +
+ "\vdisplayName\x18\x03 \x01(\tR\vdisplayName\x12$\n" +
+ "\rprofilePicURL\x18\x04 \x01(\tR\rprofilePicURL\x12+\n" +
+ "\x05peers\x18\x05 \x03(\v2\x15.daemon.TailscalePeerR\x05peers\"\xd3\x03\n" +
+ "\rTailscalePeer\x12\x1a\n" +
+ "\bhostName\x18\x01 \x01(\tR\bhostName\x12\x18\n" +
+ "\adnsName\x18\x02 \x01(\tR\adnsName\x12\x0e\n" +
+ "\x02os\x18\x03 \x01(\tR\x02os\x12\"\n" +
+ "\ftailscaleIPs\x18\x04 \x03(\tR\ftailscaleIPs\x12\x16\n" +
+ "\x06online\x18\x05 \x01(\bR\x06online\x12\x1a\n" +
+ "\bexitNode\x18\x06 \x01(\bR\bexitNode\x12&\n" +
+ "\x0eexitNodeOption\x18\a \x01(\bR\x0eexitNodeOption\x12\x16\n" +
+ "\x06active\x18\b \x01(\bR\x06active\x12\x18\n" +
+ "\arxBytes\x18\t \x01(\x03R\arxBytes\x12\x18\n" +
+ "\atxBytes\x18\n" +
+ " \x01(\x03R\atxBytes\x12\x1c\n" +
+ "\tkeyExpiry\x18\v \x01(\x03R\tkeyExpiry\x12\x1a\n" +
+ "\bstableID\x18\f \x01(\tR\bstableID\x12\x18\n" +
+ "\aexpired\x18\r \x01(\bR\aexpired\x12 \n" +
+ "\vsshHostKeys\x18\x0e \x03(\tR\vsshHostKeys\x12\x1e\n" +
+ "\n" +
+ "shareeNode\x18\x0f \x01(\bR\n" +
+ "shareeNode\x12\x1a\n" +
+ "\blastSeen\x18\x10 \x01(\x03R\blastSeen\"P\n" +
+ "\x14TailscalePingRequest\x12 \n" +
+ "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x16\n" +
+ "\x06peerIP\x18\x02 \x01(\tR\x06peerIP\"\xcf\x01\n" +
+ "\x15TailscalePingResponse\x12\x1c\n" +
+ "\tlatencyMs\x18\x01 \x01(\x01R\tlatencyMs\x12\x1a\n" +
+ "\bisDirect\x18\x02 \x01(\bR\bisDirect\x12\x1a\n" +
+ "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\"\n" +
+ "\fderpRegionID\x18\x04 \x01(\x05R\fderpRegionID\x12&\n" +
+ "\x0ederpRegionCode\x18\x05 \x01(\tR\x0ederpRegionCode\x12\x14\n" +
+ "\x05error\x18\x06 \x01(\tR\x05error\"[\n" +
+ "\x1bSetTailscaleExitNodeRequest\x12 \n" +
+ "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12\x1a\n" +
+ "\bstableID\x18\x02 \x01(\tR\bstableID\"\xc2\x01\n" +
+ "\x19TailscaleSSHClientMessage\x121\n" +
+ "\x05start\x18\x01 \x01(\v2\x19.daemon.TailscaleSSHStartH\x00R\x05start\x121\n" +
+ "\x05input\x18\x02 \x01(\v2\x19.daemon.TailscaleSSHInputH\x00R\x05input\x124\n" +
+ "\x06resize\x18\x03 \x01(\v2\x1a.daemon.TailscaleSSHResizeH\x00R\x06resizeB\t\n" +
+ "\amessage\"\xcc\x02\n" +
+ "\x11TailscaleSSHStart\x12 \n" +
+ "\vendpointTag\x18\x01 \x01(\tR\vendpointTag\x12 \n" +
+ "\vpeerAddress\x18\x02 \x01(\tR\vpeerAddress\x12\x1a\n" +
+ "\busername\x18\x03 \x01(\tR\busername\x12\"\n" +
+ "\fterminalType\x18\x04 \x01(\tR\fterminalType\x12\x18\n" +
+ "\acolumns\x18\x05 \x01(\x05R\acolumns\x12\x12\n" +
+ "\x04rows\x18\x06 \x01(\x05R\x04rows\x12 \n" +
+ "\vwidthPixels\x18\a \x01(\x05R\vwidthPixels\x12\"\n" +
+ "\fheightPixels\x18\b \x01(\x05R\fheightPixels\x12\x1a\n" +
+ "\bhostKeys\x18\t \x03(\tR\bhostKeys\x12#\n" +
+ "\rforward_agent\x18\n" +
+ " \x01(\bR\fforwardAgent\"'\n" +
+ "\x11TailscaleSSHInput\x12\x12\n" +
+ "\x04data\x18\x01 \x01(\fR\x04data\"\x88\x01\n" +
+ "\x12TailscaleSSHResize\x12\x18\n" +
+ "\acolumns\x18\x01 \x01(\x05R\acolumns\x12\x12\n" +
+ "\x04rows\x18\x02 \x01(\x05R\x04rows\x12 \n" +
+ "\vwidthPixels\x18\x03 \x01(\x05R\vwidthPixels\x12\"\n" +
+ "\fheightPixels\x18\x04 \x01(\x05R\fheightPixels\"\xb4\x02\n" +
+ "\x19TailscaleSSHServerMessage\x12@\n" +
+ "\n" +
+ "authBanner\x18\x01 \x01(\v2\x1e.daemon.TailscaleSSHAuthBannerH\x00R\n" +
+ "authBanner\x121\n" +
+ "\x05ready\x18\x02 \x01(\v2\x19.daemon.TailscaleSSHReadyH\x00R\x05ready\x124\n" +
+ "\x06output\x18\x03 \x01(\v2\x1a.daemon.TailscaleSSHOutputH\x00R\x06output\x12.\n" +
+ "\x04exit\x18\x04 \x01(\v2\x18.daemon.TailscaleSSHExitH\x00R\x04exit\x121\n" +
+ "\x05error\x18\x05 \x01(\v2\x19.daemon.TailscaleSSHErrorH\x00R\x05errorB\t\n" +
+ "\amessage\"2\n" +
+ "\x16TailscaleSSHAuthBanner\x12\x18\n" +
+ "\amessage\x18\x01 \x01(\tR\amessage\"\x13\n" +
+ "\x11TailscaleSSHReady\"(\n" +
+ "\x12TailscaleSSHOutput\x12\x12\n" +
+ "\x04data\x18\x01 \x01(\fR\x04data\"j\n" +
+ "\x10TailscaleSSHExit\x12\x1a\n" +
+ "\bexitCode\x18\x01 \x01(\x05R\bexitCode\x12\x16\n" +
+ "\x06signal\x18\x02 \x01(\tR\x06signal\x12\"\n" +
+ "\ferrorMessage\x18\x03 \x01(\tR\ferrorMessage\"-\n" +
+ "\x11TailscaleSSHError\x12\x18\n" +
+ "\amessage\x18\x01 \x01(\tR\amessage*U\n" +
"\bLogLevel\x12\t\n" +
"\x05PANIC\x10\x00\x12\t\n" +
"\x05FATAL\x10\x01\x12\t\n" +
@@ -1912,7 +3836,7 @@ const file_daemon_started_service_proto_rawDesc = "" +
"\x13ConnectionEventType\x12\x18\n" +
"\x14CONNECTION_EVENT_NEW\x10\x00\x12\x1b\n" +
"\x17CONNECTION_EVENT_UPDATE\x10\x01\x12\x1b\n" +
- "\x17CONNECTION_EVENT_CLOSED\x10\x022\xe5\v\n" +
+ "\x17CONNECTION_EVENT_CLOSED\x10\x022\xd8\x11\n" +
"\x0eStartedService\x12=\n" +
"\vStopService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12?\n" +
"\rReloadService\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\x12K\n" +
@@ -1929,12 +3853,21 @@ const file_daemon_started_service_proto_rawDesc = "" +
"\x0eSelectOutbound\x12\x1d.daemon.SelectOutboundRequest\x1a\x16.google.protobuf.Empty\"\x00\x12I\n" +
"\x0eSetGroupExpand\x12\x1d.daemon.SetGroupExpandRequest\x1a\x16.google.protobuf.Empty\"\x00\x12K\n" +
"\x14GetSystemProxyStatus\x12\x16.google.protobuf.Empty\x1a\x19.daemon.SystemProxyStatus\"\x00\x12W\n" +
- "\x15SetSystemProxyEnabled\x12$.daemon.SetSystemProxyEnabledRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n" +
+ "\x15SetSystemProxyEnabled\x12$.daemon.SetSystemProxyEnabledRequest\x1a\x16.google.protobuf.Empty\"\x00\x12H\n" +
+ "\x11TriggerDebugCrash\x12\x19.daemon.DebugCrashRequest\x1a\x16.google.protobuf.Empty\"\x00\x12D\n" +
+ "\x10TriggerOOMReport\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n" +
"\x14SubscribeConnections\x12#.daemon.SubscribeConnectionsRequest\x1a\x18.daemon.ConnectionEvents\"\x000\x01\x12K\n" +
"\x0fCloseConnection\x12\x1e.daemon.CloseConnectionRequest\x1a\x16.google.protobuf.Empty\"\x00\x12G\n" +
"\x13CloseAllConnections\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.Empty\"\x00\x12M\n" +
"\x15GetDeprecatedWarnings\x12\x16.google.protobuf.Empty\x1a\x1a.daemon.DeprecatedWarnings\"\x00\x12;\n" +
- "\fGetStartedAt\x12\x16.google.protobuf.Empty\x1a\x11.daemon.StartedAt\"\x00B%Z#github.com/sagernet/sing-box/daemonb\x06proto3"
+ "\fGetStartedAt\x12\x16.google.protobuf.Empty\x1a\x11.daemon.StartedAt\"\x00\x12F\n" +
+ "\x12SubscribeOutbounds\x12\x16.google.protobuf.Empty\x1a\x14.daemon.OutboundList\"\x000\x01\x12d\n" +
+ "\x17StartNetworkQualityTest\x12!.daemon.NetworkQualityTestRequest\x1a\".daemon.NetworkQualityTestProgress\"\x000\x01\x12F\n" +
+ "\rStartSTUNTest\x12\x17.daemon.STUNTestRequest\x1a\x18.daemon.STUNTestProgress\"\x000\x01\x12U\n" +
+ "\x18SubscribeTailscaleStatus\x12\x16.google.protobuf.Empty\x1a\x1d.daemon.TailscaleStatusUpdate\"\x000\x01\x12U\n" +
+ "\x12StartTailscalePing\x12\x1c.daemon.TailscalePingRequest\x1a\x1d.daemon.TailscalePingResponse\"\x000\x01\x12U\n" +
+ "\x14SetTailscaleExitNode\x12#.daemon.SetTailscaleExitNodeRequest\x1a\x16.google.protobuf.Empty\"\x00\x12f\n" +
+ "\x18StartTailscaleSSHSession\x12!.daemon.TailscaleSSHClientMessage\x1a!.daemon.TailscaleSSHServerMessage\"\x00(\x010\x01B%Z#github.com/sagernet/sing-box/daemonb\x06proto3"
var (
file_daemon_started_service_proto_rawDescOnce sync.Once
@@ -1949,101 +3882,158 @@ func file_daemon_started_service_proto_rawDescGZIP() []byte {
}
var (
- file_daemon_started_service_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
- file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 26)
+ file_daemon_started_service_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
+ file_daemon_started_service_proto_msgTypes = make([]protoimpl.MessageInfo, 49)
file_daemon_started_service_proto_goTypes = []any{
(LogLevel)(0), // 0: daemon.LogLevel
(ConnectionEventType)(0), // 1: daemon.ConnectionEventType
(ServiceStatus_Type)(0), // 2: daemon.ServiceStatus.Type
- (*ServiceStatus)(nil), // 3: daemon.ServiceStatus
- (*ReloadServiceRequest)(nil), // 4: daemon.ReloadServiceRequest
- (*SubscribeStatusRequest)(nil), // 5: daemon.SubscribeStatusRequest
- (*Log)(nil), // 6: daemon.Log
- (*DefaultLogLevel)(nil), // 7: daemon.DefaultLogLevel
- (*Status)(nil), // 8: daemon.Status
- (*Groups)(nil), // 9: daemon.Groups
- (*Group)(nil), // 10: daemon.Group
- (*GroupItem)(nil), // 11: daemon.GroupItem
- (*URLTestRequest)(nil), // 12: daemon.URLTestRequest
- (*SelectOutboundRequest)(nil), // 13: daemon.SelectOutboundRequest
- (*SetGroupExpandRequest)(nil), // 14: daemon.SetGroupExpandRequest
- (*ClashMode)(nil), // 15: daemon.ClashMode
- (*ClashModeStatus)(nil), // 16: daemon.ClashModeStatus
- (*SystemProxyStatus)(nil), // 17: daemon.SystemProxyStatus
- (*SetSystemProxyEnabledRequest)(nil), // 18: daemon.SetSystemProxyEnabledRequest
- (*SubscribeConnectionsRequest)(nil), // 19: daemon.SubscribeConnectionsRequest
- (*ConnectionEvent)(nil), // 20: daemon.ConnectionEvent
- (*ConnectionEvents)(nil), // 21: daemon.ConnectionEvents
- (*Connection)(nil), // 22: daemon.Connection
- (*ProcessInfo)(nil), // 23: daemon.ProcessInfo
- (*CloseConnectionRequest)(nil), // 24: daemon.CloseConnectionRequest
- (*DeprecatedWarnings)(nil), // 25: daemon.DeprecatedWarnings
- (*DeprecatedWarning)(nil), // 26: daemon.DeprecatedWarning
- (*StartedAt)(nil), // 27: daemon.StartedAt
- (*Log_Message)(nil), // 28: daemon.Log.Message
- (*emptypb.Empty)(nil), // 29: google.protobuf.Empty
+ (DebugCrashRequest_Type)(0), // 3: daemon.DebugCrashRequest.Type
+ (*ServiceStatus)(nil), // 4: daemon.ServiceStatus
+ (*ReloadServiceRequest)(nil), // 5: daemon.ReloadServiceRequest
+ (*SubscribeStatusRequest)(nil), // 6: daemon.SubscribeStatusRequest
+ (*Log)(nil), // 7: daemon.Log
+ (*DefaultLogLevel)(nil), // 8: daemon.DefaultLogLevel
+ (*Status)(nil), // 9: daemon.Status
+ (*Groups)(nil), // 10: daemon.Groups
+ (*Group)(nil), // 11: daemon.Group
+ (*GroupItem)(nil), // 12: daemon.GroupItem
+ (*URLTestRequest)(nil), // 13: daemon.URLTestRequest
+ (*SelectOutboundRequest)(nil), // 14: daemon.SelectOutboundRequest
+ (*SetGroupExpandRequest)(nil), // 15: daemon.SetGroupExpandRequest
+ (*ClashMode)(nil), // 16: daemon.ClashMode
+ (*ClashModeStatus)(nil), // 17: daemon.ClashModeStatus
+ (*SystemProxyStatus)(nil), // 18: daemon.SystemProxyStatus
+ (*SetSystemProxyEnabledRequest)(nil), // 19: daemon.SetSystemProxyEnabledRequest
+ (*DebugCrashRequest)(nil), // 20: daemon.DebugCrashRequest
+ (*SubscribeConnectionsRequest)(nil), // 21: daemon.SubscribeConnectionsRequest
+ (*ConnectionEvent)(nil), // 22: daemon.ConnectionEvent
+ (*ConnectionEvents)(nil), // 23: daemon.ConnectionEvents
+ (*Connection)(nil), // 24: daemon.Connection
+ (*ProcessInfo)(nil), // 25: daemon.ProcessInfo
+ (*CloseConnectionRequest)(nil), // 26: daemon.CloseConnectionRequest
+ (*DeprecatedWarnings)(nil), // 27: daemon.DeprecatedWarnings
+ (*DeprecatedWarning)(nil), // 28: daemon.DeprecatedWarning
+ (*StartedAt)(nil), // 29: daemon.StartedAt
+ (*OutboundList)(nil), // 30: daemon.OutboundList
+ (*NetworkQualityTestRequest)(nil), // 31: daemon.NetworkQualityTestRequest
+ (*NetworkQualityTestProgress)(nil), // 32: daemon.NetworkQualityTestProgress
+ (*STUNTestRequest)(nil), // 33: daemon.STUNTestRequest
+ (*STUNTestProgress)(nil), // 34: daemon.STUNTestProgress
+ (*TailscaleStatusUpdate)(nil), // 35: daemon.TailscaleStatusUpdate
+ (*TailscaleEndpointStatus)(nil), // 36: daemon.TailscaleEndpointStatus
+ (*TailscaleUserGroup)(nil), // 37: daemon.TailscaleUserGroup
+ (*TailscalePeer)(nil), // 38: daemon.TailscalePeer
+ (*TailscalePingRequest)(nil), // 39: daemon.TailscalePingRequest
+ (*TailscalePingResponse)(nil), // 40: daemon.TailscalePingResponse
+ (*SetTailscaleExitNodeRequest)(nil), // 41: daemon.SetTailscaleExitNodeRequest
+ (*TailscaleSSHClientMessage)(nil), // 42: daemon.TailscaleSSHClientMessage
+ (*TailscaleSSHStart)(nil), // 43: daemon.TailscaleSSHStart
+ (*TailscaleSSHInput)(nil), // 44: daemon.TailscaleSSHInput
+ (*TailscaleSSHResize)(nil), // 45: daemon.TailscaleSSHResize
+ (*TailscaleSSHServerMessage)(nil), // 46: daemon.TailscaleSSHServerMessage
+ (*TailscaleSSHAuthBanner)(nil), // 47: daemon.TailscaleSSHAuthBanner
+ (*TailscaleSSHReady)(nil), // 48: daemon.TailscaleSSHReady
+ (*TailscaleSSHOutput)(nil), // 49: daemon.TailscaleSSHOutput
+ (*TailscaleSSHExit)(nil), // 50: daemon.TailscaleSSHExit
+ (*TailscaleSSHError)(nil), // 51: daemon.TailscaleSSHError
+ (*Log_Message)(nil), // 52: daemon.Log.Message
+ (*emptypb.Empty)(nil), // 53: google.protobuf.Empty
}
)
var file_daemon_started_service_proto_depIdxs = []int32{
2, // 0: daemon.ServiceStatus.status:type_name -> daemon.ServiceStatus.Type
- 28, // 1: daemon.Log.messages:type_name -> daemon.Log.Message
+ 52, // 1: daemon.Log.messages:type_name -> daemon.Log.Message
0, // 2: daemon.DefaultLogLevel.level:type_name -> daemon.LogLevel
- 10, // 3: daemon.Groups.group:type_name -> daemon.Group
- 11, // 4: daemon.Group.items:type_name -> daemon.GroupItem
- 1, // 5: daemon.ConnectionEvent.type:type_name -> daemon.ConnectionEventType
- 22, // 6: daemon.ConnectionEvent.connection:type_name -> daemon.Connection
- 20, // 7: daemon.ConnectionEvents.events:type_name -> daemon.ConnectionEvent
- 23, // 8: daemon.Connection.processInfo:type_name -> daemon.ProcessInfo
- 26, // 9: daemon.DeprecatedWarnings.warnings:type_name -> daemon.DeprecatedWarning
- 0, // 10: daemon.Log.Message.level:type_name -> daemon.LogLevel
- 29, // 11: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
- 29, // 12: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
- 29, // 13: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
- 29, // 14: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
- 29, // 15: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
- 29, // 16: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
- 5, // 17: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
- 29, // 18: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
- 29, // 19: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
- 29, // 20: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
- 15, // 21: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
- 12, // 22: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
- 13, // 23: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
- 14, // 24: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
- 29, // 25: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
- 18, // 26: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
- 19, // 27: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
- 24, // 28: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
- 29, // 29: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
- 29, // 30: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
- 29, // 31: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
- 29, // 32: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
- 29, // 33: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
- 3, // 34: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
- 6, // 35: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
- 7, // 36: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
- 29, // 37: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
- 8, // 38: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
- 9, // 39: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
- 16, // 40: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
- 15, // 41: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
- 29, // 42: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
- 29, // 43: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
- 29, // 44: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
- 29, // 45: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
- 17, // 46: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
- 29, // 47: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
- 21, // 48: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
- 29, // 49: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
- 29, // 50: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
- 25, // 51: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
- 27, // 52: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
- 32, // [32:53] is the sub-list for method output_type
- 11, // [11:32] is the sub-list for method input_type
- 11, // [11:11] is the sub-list for extension type_name
- 11, // [11:11] is the sub-list for extension extendee
- 0, // [0:11] is the sub-list for field type_name
+ 11, // 3: daemon.Groups.group:type_name -> daemon.Group
+ 12, // 4: daemon.Group.items:type_name -> daemon.GroupItem
+ 3, // 5: daemon.DebugCrashRequest.type:type_name -> daemon.DebugCrashRequest.Type
+ 1, // 6: daemon.ConnectionEvent.type:type_name -> daemon.ConnectionEventType
+ 24, // 7: daemon.ConnectionEvent.connection:type_name -> daemon.Connection
+ 22, // 8: daemon.ConnectionEvents.events:type_name -> daemon.ConnectionEvent
+ 25, // 9: daemon.Connection.processInfo:type_name -> daemon.ProcessInfo
+ 28, // 10: daemon.DeprecatedWarnings.warnings:type_name -> daemon.DeprecatedWarning
+ 12, // 11: daemon.OutboundList.outbounds:type_name -> daemon.GroupItem
+ 36, // 12: daemon.TailscaleStatusUpdate.endpoints:type_name -> daemon.TailscaleEndpointStatus
+ 38, // 13: daemon.TailscaleEndpointStatus.self:type_name -> daemon.TailscalePeer
+ 37, // 14: daemon.TailscaleEndpointStatus.userGroups:type_name -> daemon.TailscaleUserGroup
+ 38, // 15: daemon.TailscaleEndpointStatus.exitNode:type_name -> daemon.TailscalePeer
+ 38, // 16: daemon.TailscaleUserGroup.peers:type_name -> daemon.TailscalePeer
+ 43, // 17: daemon.TailscaleSSHClientMessage.start:type_name -> daemon.TailscaleSSHStart
+ 44, // 18: daemon.TailscaleSSHClientMessage.input:type_name -> daemon.TailscaleSSHInput
+ 45, // 19: daemon.TailscaleSSHClientMessage.resize:type_name -> daemon.TailscaleSSHResize
+ 47, // 20: daemon.TailscaleSSHServerMessage.authBanner:type_name -> daemon.TailscaleSSHAuthBanner
+ 48, // 21: daemon.TailscaleSSHServerMessage.ready:type_name -> daemon.TailscaleSSHReady
+ 49, // 22: daemon.TailscaleSSHServerMessage.output:type_name -> daemon.TailscaleSSHOutput
+ 50, // 23: daemon.TailscaleSSHServerMessage.exit:type_name -> daemon.TailscaleSSHExit
+ 51, // 24: daemon.TailscaleSSHServerMessage.error:type_name -> daemon.TailscaleSSHError
+ 0, // 25: daemon.Log.Message.level:type_name -> daemon.LogLevel
+ 53, // 26: daemon.StartedService.StopService:input_type -> google.protobuf.Empty
+ 53, // 27: daemon.StartedService.ReloadService:input_type -> google.protobuf.Empty
+ 53, // 28: daemon.StartedService.SubscribeServiceStatus:input_type -> google.protobuf.Empty
+ 53, // 29: daemon.StartedService.SubscribeLog:input_type -> google.protobuf.Empty
+ 53, // 30: daemon.StartedService.GetDefaultLogLevel:input_type -> google.protobuf.Empty
+ 53, // 31: daemon.StartedService.ClearLogs:input_type -> google.protobuf.Empty
+ 6, // 32: daemon.StartedService.SubscribeStatus:input_type -> daemon.SubscribeStatusRequest
+ 53, // 33: daemon.StartedService.SubscribeGroups:input_type -> google.protobuf.Empty
+ 53, // 34: daemon.StartedService.GetClashModeStatus:input_type -> google.protobuf.Empty
+ 53, // 35: daemon.StartedService.SubscribeClashMode:input_type -> google.protobuf.Empty
+ 16, // 36: daemon.StartedService.SetClashMode:input_type -> daemon.ClashMode
+ 13, // 37: daemon.StartedService.URLTest:input_type -> daemon.URLTestRequest
+ 14, // 38: daemon.StartedService.SelectOutbound:input_type -> daemon.SelectOutboundRequest
+ 15, // 39: daemon.StartedService.SetGroupExpand:input_type -> daemon.SetGroupExpandRequest
+ 53, // 40: daemon.StartedService.GetSystemProxyStatus:input_type -> google.protobuf.Empty
+ 19, // 41: daemon.StartedService.SetSystemProxyEnabled:input_type -> daemon.SetSystemProxyEnabledRequest
+ 20, // 42: daemon.StartedService.TriggerDebugCrash:input_type -> daemon.DebugCrashRequest
+ 53, // 43: daemon.StartedService.TriggerOOMReport:input_type -> google.protobuf.Empty
+ 21, // 44: daemon.StartedService.SubscribeConnections:input_type -> daemon.SubscribeConnectionsRequest
+ 26, // 45: daemon.StartedService.CloseConnection:input_type -> daemon.CloseConnectionRequest
+ 53, // 46: daemon.StartedService.CloseAllConnections:input_type -> google.protobuf.Empty
+ 53, // 47: daemon.StartedService.GetDeprecatedWarnings:input_type -> google.protobuf.Empty
+ 53, // 48: daemon.StartedService.GetStartedAt:input_type -> google.protobuf.Empty
+ 53, // 49: daemon.StartedService.SubscribeOutbounds:input_type -> google.protobuf.Empty
+ 31, // 50: daemon.StartedService.StartNetworkQualityTest:input_type -> daemon.NetworkQualityTestRequest
+ 33, // 51: daemon.StartedService.StartSTUNTest:input_type -> daemon.STUNTestRequest
+ 53, // 52: daemon.StartedService.SubscribeTailscaleStatus:input_type -> google.protobuf.Empty
+ 39, // 53: daemon.StartedService.StartTailscalePing:input_type -> daemon.TailscalePingRequest
+ 41, // 54: daemon.StartedService.SetTailscaleExitNode:input_type -> daemon.SetTailscaleExitNodeRequest
+ 42, // 55: daemon.StartedService.StartTailscaleSSHSession:input_type -> daemon.TailscaleSSHClientMessage
+ 53, // 56: daemon.StartedService.StopService:output_type -> google.protobuf.Empty
+ 53, // 57: daemon.StartedService.ReloadService:output_type -> google.protobuf.Empty
+ 4, // 58: daemon.StartedService.SubscribeServiceStatus:output_type -> daemon.ServiceStatus
+ 7, // 59: daemon.StartedService.SubscribeLog:output_type -> daemon.Log
+ 8, // 60: daemon.StartedService.GetDefaultLogLevel:output_type -> daemon.DefaultLogLevel
+ 53, // 61: daemon.StartedService.ClearLogs:output_type -> google.protobuf.Empty
+ 9, // 62: daemon.StartedService.SubscribeStatus:output_type -> daemon.Status
+ 10, // 63: daemon.StartedService.SubscribeGroups:output_type -> daemon.Groups
+ 17, // 64: daemon.StartedService.GetClashModeStatus:output_type -> daemon.ClashModeStatus
+ 16, // 65: daemon.StartedService.SubscribeClashMode:output_type -> daemon.ClashMode
+ 53, // 66: daemon.StartedService.SetClashMode:output_type -> google.protobuf.Empty
+ 53, // 67: daemon.StartedService.URLTest:output_type -> google.protobuf.Empty
+ 53, // 68: daemon.StartedService.SelectOutbound:output_type -> google.protobuf.Empty
+ 53, // 69: daemon.StartedService.SetGroupExpand:output_type -> google.protobuf.Empty
+ 18, // 70: daemon.StartedService.GetSystemProxyStatus:output_type -> daemon.SystemProxyStatus
+ 53, // 71: daemon.StartedService.SetSystemProxyEnabled:output_type -> google.protobuf.Empty
+ 53, // 72: daemon.StartedService.TriggerDebugCrash:output_type -> google.protobuf.Empty
+ 53, // 73: daemon.StartedService.TriggerOOMReport:output_type -> google.protobuf.Empty
+ 23, // 74: daemon.StartedService.SubscribeConnections:output_type -> daemon.ConnectionEvents
+ 53, // 75: daemon.StartedService.CloseConnection:output_type -> google.protobuf.Empty
+ 53, // 76: daemon.StartedService.CloseAllConnections:output_type -> google.protobuf.Empty
+ 27, // 77: daemon.StartedService.GetDeprecatedWarnings:output_type -> daemon.DeprecatedWarnings
+ 29, // 78: daemon.StartedService.GetStartedAt:output_type -> daemon.StartedAt
+ 30, // 79: daemon.StartedService.SubscribeOutbounds:output_type -> daemon.OutboundList
+ 32, // 80: daemon.StartedService.StartNetworkQualityTest:output_type -> daemon.NetworkQualityTestProgress
+ 34, // 81: daemon.StartedService.StartSTUNTest:output_type -> daemon.STUNTestProgress
+ 35, // 82: daemon.StartedService.SubscribeTailscaleStatus:output_type -> daemon.TailscaleStatusUpdate
+ 40, // 83: daemon.StartedService.StartTailscalePing:output_type -> daemon.TailscalePingResponse
+ 53, // 84: daemon.StartedService.SetTailscaleExitNode:output_type -> google.protobuf.Empty
+ 46, // 85: daemon.StartedService.StartTailscaleSSHSession:output_type -> daemon.TailscaleSSHServerMessage
+ 56, // [56:86] is the sub-list for method output_type
+ 26, // [26:56] is the sub-list for method input_type
+ 26, // [26:26] is the sub-list for extension type_name
+ 26, // [26:26] is the sub-list for extension extendee
+ 0, // [0:26] is the sub-list for field type_name
}
func init() { file_daemon_started_service_proto_init() }
@@ -2051,13 +4041,25 @@ func file_daemon_started_service_proto_init() {
if File_daemon_started_service_proto != nil {
return
}
+ file_daemon_started_service_proto_msgTypes[38].OneofWrappers = []any{
+ (*TailscaleSSHClientMessage_Start)(nil),
+ (*TailscaleSSHClientMessage_Input)(nil),
+ (*TailscaleSSHClientMessage_Resize)(nil),
+ }
+ file_daemon_started_service_proto_msgTypes[42].OneofWrappers = []any{
+ (*TailscaleSSHServerMessage_AuthBanner)(nil),
+ (*TailscaleSSHServerMessage_Ready)(nil),
+ (*TailscaleSSHServerMessage_Output)(nil),
+ (*TailscaleSSHServerMessage_Exit)(nil),
+ (*TailscaleSSHServerMessage_Error)(nil),
+ }
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_started_service_proto_rawDesc), len(file_daemon_started_service_proto_rawDesc)),
- NumEnums: 3,
- NumMessages: 26,
+ NumEnums: 4,
+ NumMessages: 49,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/daemon/started_service.proto b/daemon/started_service.proto
index 8a76081ab5..e74b8f7008 100644
--- a/daemon/started_service.proto
+++ b/daemon/started_service.proto
@@ -26,12 +26,22 @@ service StartedService {
rpc GetSystemProxyStatus(google.protobuf.Empty) returns(SystemProxyStatus) {}
rpc SetSystemProxyEnabled(SetSystemProxyEnabledRequest) returns(google.protobuf.Empty) {}
+ rpc TriggerDebugCrash(DebugCrashRequest) returns(google.protobuf.Empty) {}
+ rpc TriggerOOMReport(google.protobuf.Empty) returns(google.protobuf.Empty) {}
rpc SubscribeConnections(SubscribeConnectionsRequest) returns(stream ConnectionEvents) {}
rpc CloseConnection(CloseConnectionRequest) returns(google.protobuf.Empty) {}
rpc CloseAllConnections(google.protobuf.Empty) returns(google.protobuf.Empty) {}
rpc GetDeprecatedWarnings(google.protobuf.Empty) returns(DeprecatedWarnings) {}
rpc GetStartedAt(google.protobuf.Empty) returns(StartedAt) {}
+
+ rpc SubscribeOutbounds(google.protobuf.Empty) returns (stream OutboundList) {}
+ rpc StartNetworkQualityTest(NetworkQualityTestRequest) returns (stream NetworkQualityTestProgress) {}
+ rpc StartSTUNTest(STUNTestRequest) returns (stream STUNTestProgress) {}
+ rpc SubscribeTailscaleStatus(google.protobuf.Empty) returns (stream TailscaleStatusUpdate) {}
+ rpc StartTailscalePing(TailscalePingRequest) returns (stream TailscalePingResponse) {}
+ rpc SetTailscaleExitNode(SetTailscaleExitNodeRequest) returns (google.protobuf.Empty) {}
+ rpc StartTailscaleSSHSession(stream TailscaleSSHClientMessage) returns (stream TailscaleSSHServerMessage) {}
}
message ServiceStatus {
@@ -141,6 +151,15 @@ message SetSystemProxyEnabledRequest {
bool enabled = 1;
}
+message DebugCrashRequest {
+ enum Type {
+ GO = 0;
+ NATIVE = 1;
+ }
+
+ Type type = 1;
+}
+
message SubscribeConnectionsRequest {
int64 interval = 1;
}
@@ -210,8 +229,179 @@ message DeprecatedWarning {
string message = 1;
bool impending = 2;
string migrationLink = 3;
+ string description = 4;
+ string deprecatedVersion = 5;
+ string scheduledVersion = 6;
}
message StartedAt {
int64 startedAt = 1;
-}
\ No newline at end of file
+}
+
+message OutboundList {
+ repeated GroupItem outbounds = 1;
+}
+
+message NetworkQualityTestRequest {
+ string configURL = 1;
+ string outboundTag = 2;
+ bool serial = 3;
+ int32 maxRuntimeSeconds = 4;
+ bool http3 = 5;
+}
+
+message NetworkQualityTestProgress {
+ int32 phase = 1;
+ int64 downloadCapacity = 2;
+ int64 uploadCapacity = 3;
+ int32 downloadRPM = 4;
+ int32 uploadRPM = 5;
+ int32 idleLatencyMs = 6;
+ int64 elapsedMs = 7;
+ bool isFinal = 8;
+ string error = 9;
+ int32 downloadCapacityAccuracy = 10;
+ int32 uploadCapacityAccuracy = 11;
+ int32 downloadRPMAccuracy = 12;
+ int32 uploadRPMAccuracy = 13;
+}
+
+message STUNTestRequest {
+ string server = 1;
+ string outboundTag = 2;
+}
+
+message STUNTestProgress {
+ int32 phase = 1;
+ string externalAddr = 2;
+ int32 latencyMs = 3;
+ int32 natMapping = 4;
+ int32 natFiltering = 5;
+ bool isFinal = 6;
+ string error = 7;
+ bool natTypeSupported = 8;
+}
+
+message TailscaleStatusUpdate {
+ repeated TailscaleEndpointStatus endpoints = 1;
+}
+
+message TailscaleEndpointStatus {
+ string endpointTag = 1;
+ string backendState = 2;
+ string authURL = 3;
+ string networkName = 4;
+ string magicDNSSuffix = 5;
+ TailscalePeer self = 6;
+ repeated TailscaleUserGroup userGroups = 7;
+ TailscalePeer exitNode = 8;
+}
+
+message TailscaleUserGroup {
+ int64 userID = 1;
+ string loginName = 2;
+ string displayName = 3;
+ string profilePicURL = 4;
+ repeated TailscalePeer peers = 5;
+}
+
+message TailscalePeer {
+ string hostName = 1;
+ string dnsName = 2;
+ string os = 3;
+ repeated string tailscaleIPs = 4;
+ bool online = 5;
+ bool exitNode = 6;
+ bool exitNodeOption = 7;
+ bool active = 8;
+ int64 rxBytes = 9;
+ int64 txBytes = 10;
+ int64 keyExpiry = 11;
+ string stableID = 12;
+ bool expired = 13;
+ repeated string sshHostKeys = 14;
+ bool shareeNode = 15;
+ int64 lastSeen = 16;
+}
+
+message TailscalePingRequest {
+ string endpointTag = 1;
+ string peerIP = 2;
+}
+
+message TailscalePingResponse {
+ double latencyMs = 1;
+ bool isDirect = 2;
+ string endpoint = 3;
+ int32 derpRegionID = 4;
+ string derpRegionCode = 5;
+ string error = 6;
+}
+
+message SetTailscaleExitNodeRequest {
+ string endpointTag = 1;
+ string stableID = 2;
+}
+
+message TailscaleSSHClientMessage {
+ oneof message {
+ TailscaleSSHStart start = 1;
+ TailscaleSSHInput input = 2;
+ TailscaleSSHResize resize = 3;
+ }
+}
+
+message TailscaleSSHStart {
+ string endpointTag = 1;
+ string peerAddress = 2;
+ string username = 3;
+ string terminalType = 4;
+ int32 columns = 5;
+ int32 rows = 6;
+ int32 widthPixels = 7;
+ int32 heightPixels = 8;
+ repeated string hostKeys = 9;
+ bool forward_agent = 10;
+}
+
+message TailscaleSSHInput {
+ bytes data = 1;
+}
+
+message TailscaleSSHResize {
+ int32 columns = 1;
+ int32 rows = 2;
+ int32 widthPixels = 3;
+ int32 heightPixels = 4;
+}
+
+message TailscaleSSHServerMessage {
+ oneof message {
+ TailscaleSSHAuthBanner authBanner = 1;
+ TailscaleSSHReady ready = 2;
+ TailscaleSSHOutput output = 3;
+ TailscaleSSHExit exit = 4;
+ TailscaleSSHError error = 5;
+ }
+}
+
+message TailscaleSSHAuthBanner {
+ string message = 1;
+}
+
+message TailscaleSSHReady {
+}
+
+message TailscaleSSHOutput {
+ bytes data = 1;
+}
+
+message TailscaleSSHExit {
+ int32 exitCode = 1;
+ string signal = 2;
+ string errorMessage = 3;
+}
+
+message TailscaleSSHError {
+ string message = 1;
+}
diff --git a/daemon/started_service_grpc.pb.go b/daemon/started_service_grpc.pb.go
index 438cca5c35..02a7c32284 100644
--- a/daemon/started_service_grpc.pb.go
+++ b/daemon/started_service_grpc.pb.go
@@ -15,27 +15,36 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
- StartedService_StopService_FullMethodName = "/daemon.StartedService/StopService"
- StartedService_ReloadService_FullMethodName = "/daemon.StartedService/ReloadService"
- StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedService/SubscribeServiceStatus"
- StartedService_SubscribeLog_FullMethodName = "/daemon.StartedService/SubscribeLog"
- StartedService_GetDefaultLogLevel_FullMethodName = "/daemon.StartedService/GetDefaultLogLevel"
- StartedService_ClearLogs_FullMethodName = "/daemon.StartedService/ClearLogs"
- StartedService_SubscribeStatus_FullMethodName = "/daemon.StartedService/SubscribeStatus"
- StartedService_SubscribeGroups_FullMethodName = "/daemon.StartedService/SubscribeGroups"
- StartedService_GetClashModeStatus_FullMethodName = "/daemon.StartedService/GetClashModeStatus"
- StartedService_SubscribeClashMode_FullMethodName = "/daemon.StartedService/SubscribeClashMode"
- StartedService_SetClashMode_FullMethodName = "/daemon.StartedService/SetClashMode"
- StartedService_URLTest_FullMethodName = "/daemon.StartedService/URLTest"
- StartedService_SelectOutbound_FullMethodName = "/daemon.StartedService/SelectOutbound"
- StartedService_SetGroupExpand_FullMethodName = "/daemon.StartedService/SetGroupExpand"
- StartedService_GetSystemProxyStatus_FullMethodName = "/daemon.StartedService/GetSystemProxyStatus"
- StartedService_SetSystemProxyEnabled_FullMethodName = "/daemon.StartedService/SetSystemProxyEnabled"
- StartedService_SubscribeConnections_FullMethodName = "/daemon.StartedService/SubscribeConnections"
- StartedService_CloseConnection_FullMethodName = "/daemon.StartedService/CloseConnection"
- StartedService_CloseAllConnections_FullMethodName = "/daemon.StartedService/CloseAllConnections"
- StartedService_GetDeprecatedWarnings_FullMethodName = "/daemon.StartedService/GetDeprecatedWarnings"
- StartedService_GetStartedAt_FullMethodName = "/daemon.StartedService/GetStartedAt"
+ StartedService_StopService_FullMethodName = "/daemon.StartedService/StopService"
+ StartedService_ReloadService_FullMethodName = "/daemon.StartedService/ReloadService"
+ StartedService_SubscribeServiceStatus_FullMethodName = "/daemon.StartedService/SubscribeServiceStatus"
+ StartedService_SubscribeLog_FullMethodName = "/daemon.StartedService/SubscribeLog"
+ StartedService_GetDefaultLogLevel_FullMethodName = "/daemon.StartedService/GetDefaultLogLevel"
+ StartedService_ClearLogs_FullMethodName = "/daemon.StartedService/ClearLogs"
+ StartedService_SubscribeStatus_FullMethodName = "/daemon.StartedService/SubscribeStatus"
+ StartedService_SubscribeGroups_FullMethodName = "/daemon.StartedService/SubscribeGroups"
+ StartedService_GetClashModeStatus_FullMethodName = "/daemon.StartedService/GetClashModeStatus"
+ StartedService_SubscribeClashMode_FullMethodName = "/daemon.StartedService/SubscribeClashMode"
+ StartedService_SetClashMode_FullMethodName = "/daemon.StartedService/SetClashMode"
+ StartedService_URLTest_FullMethodName = "/daemon.StartedService/URLTest"
+ StartedService_SelectOutbound_FullMethodName = "/daemon.StartedService/SelectOutbound"
+ StartedService_SetGroupExpand_FullMethodName = "/daemon.StartedService/SetGroupExpand"
+ StartedService_GetSystemProxyStatus_FullMethodName = "/daemon.StartedService/GetSystemProxyStatus"
+ StartedService_SetSystemProxyEnabled_FullMethodName = "/daemon.StartedService/SetSystemProxyEnabled"
+ StartedService_TriggerDebugCrash_FullMethodName = "/daemon.StartedService/TriggerDebugCrash"
+ StartedService_TriggerOOMReport_FullMethodName = "/daemon.StartedService/TriggerOOMReport"
+ StartedService_SubscribeConnections_FullMethodName = "/daemon.StartedService/SubscribeConnections"
+ StartedService_CloseConnection_FullMethodName = "/daemon.StartedService/CloseConnection"
+ StartedService_CloseAllConnections_FullMethodName = "/daemon.StartedService/CloseAllConnections"
+ StartedService_GetDeprecatedWarnings_FullMethodName = "/daemon.StartedService/GetDeprecatedWarnings"
+ StartedService_GetStartedAt_FullMethodName = "/daemon.StartedService/GetStartedAt"
+ StartedService_SubscribeOutbounds_FullMethodName = "/daemon.StartedService/SubscribeOutbounds"
+ StartedService_StartNetworkQualityTest_FullMethodName = "/daemon.StartedService/StartNetworkQualityTest"
+ StartedService_StartSTUNTest_FullMethodName = "/daemon.StartedService/StartSTUNTest"
+ StartedService_SubscribeTailscaleStatus_FullMethodName = "/daemon.StartedService/SubscribeTailscaleStatus"
+ StartedService_StartTailscalePing_FullMethodName = "/daemon.StartedService/StartTailscalePing"
+ StartedService_SetTailscaleExitNode_FullMethodName = "/daemon.StartedService/SetTailscaleExitNode"
+ StartedService_StartTailscaleSSHSession_FullMethodName = "/daemon.StartedService/StartTailscaleSSHSession"
)
// StartedServiceClient is the client API for StartedService service.
@@ -58,11 +67,20 @@ type StartedServiceClient interface {
SetGroupExpand(ctx context.Context, in *SetGroupExpandRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
GetSystemProxyStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*SystemProxyStatus, error)
SetSystemProxyEnabled(ctx context.Context, in *SetSystemProxyEnabledRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+ TriggerDebugCrash(ctx context.Context, in *DebugCrashRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+ TriggerOOMReport(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error)
SubscribeConnections(ctx context.Context, in *SubscribeConnectionsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConnectionEvents], error)
CloseConnection(ctx context.Context, in *CloseConnectionRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
CloseAllConnections(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error)
GetDeprecatedWarnings(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*DeprecatedWarnings, error)
GetStartedAt(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*StartedAt, error)
+ SubscribeOutbounds(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OutboundList], error)
+ StartNetworkQualityTest(ctx context.Context, in *NetworkQualityTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NetworkQualityTestProgress], error)
+ StartSTUNTest(ctx context.Context, in *STUNTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[STUNTestProgress], error)
+ SubscribeTailscaleStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscaleStatusUpdate], error)
+ StartTailscalePing(ctx context.Context, in *TailscalePingRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscalePingResponse], error)
+ SetTailscaleExitNode(ctx context.Context, in *SetTailscaleExitNodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+ StartTailscaleSSHSession(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[TailscaleSSHClientMessage, TailscaleSSHServerMessage], error)
}
type startedServiceClient struct {
@@ -278,6 +296,26 @@ func (c *startedServiceClient) SetSystemProxyEnabled(ctx context.Context, in *Se
return out, nil
}
+func (c *startedServiceClient) TriggerDebugCrash(ctx context.Context, in *DebugCrashRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(emptypb.Empty)
+ err := c.cc.Invoke(ctx, StartedService_TriggerDebugCrash_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *startedServiceClient) TriggerOOMReport(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(emptypb.Empty)
+ err := c.cc.Invoke(ctx, StartedService_TriggerOOMReport_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
func (c *startedServiceClient) SubscribeConnections(ctx context.Context, in *SubscribeConnectionsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[ConnectionEvents], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[5], StartedService_SubscribeConnections_FullMethodName, cOpts...)
@@ -337,6 +375,124 @@ func (c *startedServiceClient) GetStartedAt(ctx context.Context, in *emptypb.Emp
return out, nil
}
+func (c *startedServiceClient) SubscribeOutbounds(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[OutboundList], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[6], StartedService_SubscribeOutbounds_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[emptypb.Empty, OutboundList]{ClientStream: stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_SubscribeOutboundsClient = grpc.ServerStreamingClient[OutboundList]
+
+func (c *startedServiceClient) StartNetworkQualityTest(ctx context.Context, in *NetworkQualityTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[NetworkQualityTestProgress], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[7], StartedService_StartNetworkQualityTest_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[NetworkQualityTestRequest, NetworkQualityTestProgress]{ClientStream: stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartNetworkQualityTestClient = grpc.ServerStreamingClient[NetworkQualityTestProgress]
+
+func (c *startedServiceClient) StartSTUNTest(ctx context.Context, in *STUNTestRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[STUNTestProgress], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[8], StartedService_StartSTUNTest_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[STUNTestRequest, STUNTestProgress]{ClientStream: stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartSTUNTestClient = grpc.ServerStreamingClient[STUNTestProgress]
+
+func (c *startedServiceClient) SubscribeTailscaleStatus(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscaleStatusUpdate], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[9], StartedService_SubscribeTailscaleStatus_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[emptypb.Empty, TailscaleStatusUpdate]{ClientStream: stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_SubscribeTailscaleStatusClient = grpc.ServerStreamingClient[TailscaleStatusUpdate]
+
+func (c *startedServiceClient) StartTailscalePing(ctx context.Context, in *TailscalePingRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TailscalePingResponse], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[10], StartedService_StartTailscalePing_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[TailscalePingRequest, TailscalePingResponse]{ClientStream: stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartTailscalePingClient = grpc.ServerStreamingClient[TailscalePingResponse]
+
+func (c *startedServiceClient) SetTailscaleExitNode(ctx context.Context, in *SetTailscaleExitNodeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(emptypb.Empty)
+ err := c.cc.Invoke(ctx, StartedService_SetTailscaleExitNode_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *startedServiceClient) StartTailscaleSSHSession(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[TailscaleSSHClientMessage, TailscaleSSHServerMessage], error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ stream, err := c.cc.NewStream(ctx, &StartedService_ServiceDesc.Streams[11], StartedService_StartTailscaleSSHSession_FullMethodName, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpc.GenericClientStream[TailscaleSSHClientMessage, TailscaleSSHServerMessage]{ClientStream: stream}
+ return x, nil
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartTailscaleSSHSessionClient = grpc.BidiStreamingClient[TailscaleSSHClientMessage, TailscaleSSHServerMessage]
+
// StartedServiceServer is the server API for StartedService service.
// All implementations must embed UnimplementedStartedServiceServer
// for forward compatibility.
@@ -357,11 +513,20 @@ type StartedServiceServer interface {
SetGroupExpand(context.Context, *SetGroupExpandRequest) (*emptypb.Empty, error)
GetSystemProxyStatus(context.Context, *emptypb.Empty) (*SystemProxyStatus, error)
SetSystemProxyEnabled(context.Context, *SetSystemProxyEnabledRequest) (*emptypb.Empty, error)
+ TriggerDebugCrash(context.Context, *DebugCrashRequest) (*emptypb.Empty, error)
+ TriggerOOMReport(context.Context, *emptypb.Empty) (*emptypb.Empty, error)
SubscribeConnections(*SubscribeConnectionsRequest, grpc.ServerStreamingServer[ConnectionEvents]) error
CloseConnection(context.Context, *CloseConnectionRequest) (*emptypb.Empty, error)
CloseAllConnections(context.Context, *emptypb.Empty) (*emptypb.Empty, error)
GetDeprecatedWarnings(context.Context, *emptypb.Empty) (*DeprecatedWarnings, error)
GetStartedAt(context.Context, *emptypb.Empty) (*StartedAt, error)
+ SubscribeOutbounds(*emptypb.Empty, grpc.ServerStreamingServer[OutboundList]) error
+ StartNetworkQualityTest(*NetworkQualityTestRequest, grpc.ServerStreamingServer[NetworkQualityTestProgress]) error
+ StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error
+ SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error
+ StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error
+ SetTailscaleExitNode(context.Context, *SetTailscaleExitNodeRequest) (*emptypb.Empty, error)
+ StartTailscaleSSHSession(grpc.BidiStreamingServer[TailscaleSSHClientMessage, TailscaleSSHServerMessage]) error
mustEmbedUnimplementedStartedServiceServer()
}
@@ -436,6 +601,14 @@ func (UnimplementedStartedServiceServer) SetSystemProxyEnabled(context.Context,
return nil, status.Error(codes.Unimplemented, "method SetSystemProxyEnabled not implemented")
}
+func (UnimplementedStartedServiceServer) TriggerDebugCrash(context.Context, *DebugCrashRequest) (*emptypb.Empty, error) {
+ return nil, status.Error(codes.Unimplemented, "method TriggerDebugCrash not implemented")
+}
+
+func (UnimplementedStartedServiceServer) TriggerOOMReport(context.Context, *emptypb.Empty) (*emptypb.Empty, error) {
+ return nil, status.Error(codes.Unimplemented, "method TriggerOOMReport not implemented")
+}
+
func (UnimplementedStartedServiceServer) SubscribeConnections(*SubscribeConnectionsRequest, grpc.ServerStreamingServer[ConnectionEvents]) error {
return status.Error(codes.Unimplemented, "method SubscribeConnections not implemented")
}
@@ -455,6 +628,34 @@ func (UnimplementedStartedServiceServer) GetDeprecatedWarnings(context.Context,
func (UnimplementedStartedServiceServer) GetStartedAt(context.Context, *emptypb.Empty) (*StartedAt, error) {
return nil, status.Error(codes.Unimplemented, "method GetStartedAt not implemented")
}
+
+func (UnimplementedStartedServiceServer) SubscribeOutbounds(*emptypb.Empty, grpc.ServerStreamingServer[OutboundList]) error {
+ return status.Error(codes.Unimplemented, "method SubscribeOutbounds not implemented")
+}
+
+func (UnimplementedStartedServiceServer) StartNetworkQualityTest(*NetworkQualityTestRequest, grpc.ServerStreamingServer[NetworkQualityTestProgress]) error {
+ return status.Error(codes.Unimplemented, "method StartNetworkQualityTest not implemented")
+}
+
+func (UnimplementedStartedServiceServer) StartSTUNTest(*STUNTestRequest, grpc.ServerStreamingServer[STUNTestProgress]) error {
+ return status.Error(codes.Unimplemented, "method StartSTUNTest not implemented")
+}
+
+func (UnimplementedStartedServiceServer) SubscribeTailscaleStatus(*emptypb.Empty, grpc.ServerStreamingServer[TailscaleStatusUpdate]) error {
+ return status.Error(codes.Unimplemented, "method SubscribeTailscaleStatus not implemented")
+}
+
+func (UnimplementedStartedServiceServer) StartTailscalePing(*TailscalePingRequest, grpc.ServerStreamingServer[TailscalePingResponse]) error {
+ return status.Error(codes.Unimplemented, "method StartTailscalePing not implemented")
+}
+
+func (UnimplementedStartedServiceServer) SetTailscaleExitNode(context.Context, *SetTailscaleExitNodeRequest) (*emptypb.Empty, error) {
+ return nil, status.Error(codes.Unimplemented, "method SetTailscaleExitNode not implemented")
+}
+
+func (UnimplementedStartedServiceServer) StartTailscaleSSHSession(grpc.BidiStreamingServer[TailscaleSSHClientMessage, TailscaleSSHServerMessage]) error {
+ return status.Error(codes.Unimplemented, "method StartTailscaleSSHSession not implemented")
+}
func (UnimplementedStartedServiceServer) mustEmbedUnimplementedStartedServiceServer() {}
func (UnimplementedStartedServiceServer) testEmbeddedByValue() {}
@@ -729,6 +930,42 @@ func _StartedService_SetSystemProxyEnabled_Handler(srv interface{}, ctx context.
return interceptor(ctx, in, info, handler)
}
+func _StartedService_TriggerDebugCrash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(DebugCrashRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(StartedServiceServer).TriggerDebugCrash(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: StartedService_TriggerDebugCrash_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(StartedServiceServer).TriggerDebugCrash(ctx, req.(*DebugCrashRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _StartedService_TriggerOOMReport_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(emptypb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(StartedServiceServer).TriggerOOMReport(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: StartedService_TriggerOOMReport_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(StartedServiceServer).TriggerOOMReport(ctx, req.(*emptypb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
func _StartedService_SubscribeConnections_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(SubscribeConnectionsRequest)
if err := stream.RecvMsg(m); err != nil {
@@ -812,6 +1049,86 @@ func _StartedService_GetStartedAt_Handler(srv interface{}, ctx context.Context,
return interceptor(ctx, in, info, handler)
}
+func _StartedService_SubscribeOutbounds_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(emptypb.Empty)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(StartedServiceServer).SubscribeOutbounds(m, &grpc.GenericServerStream[emptypb.Empty, OutboundList]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_SubscribeOutboundsServer = grpc.ServerStreamingServer[OutboundList]
+
+func _StartedService_StartNetworkQualityTest_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(NetworkQualityTestRequest)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(StartedServiceServer).StartNetworkQualityTest(m, &grpc.GenericServerStream[NetworkQualityTestRequest, NetworkQualityTestProgress]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartNetworkQualityTestServer = grpc.ServerStreamingServer[NetworkQualityTestProgress]
+
+func _StartedService_StartSTUNTest_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(STUNTestRequest)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(StartedServiceServer).StartSTUNTest(m, &grpc.GenericServerStream[STUNTestRequest, STUNTestProgress]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartSTUNTestServer = grpc.ServerStreamingServer[STUNTestProgress]
+
+func _StartedService_SubscribeTailscaleStatus_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(emptypb.Empty)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(StartedServiceServer).SubscribeTailscaleStatus(m, &grpc.GenericServerStream[emptypb.Empty, TailscaleStatusUpdate]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_SubscribeTailscaleStatusServer = grpc.ServerStreamingServer[TailscaleStatusUpdate]
+
+func _StartedService_StartTailscalePing_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(TailscalePingRequest)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(StartedServiceServer).StartTailscalePing(m, &grpc.GenericServerStream[TailscalePingRequest, TailscalePingResponse]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartTailscalePingServer = grpc.ServerStreamingServer[TailscalePingResponse]
+
+func _StartedService_SetTailscaleExitNode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(SetTailscaleExitNodeRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(StartedServiceServer).SetTailscaleExitNode(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: StartedService_SetTailscaleExitNode_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(StartedServiceServer).SetTailscaleExitNode(ctx, req.(*SetTailscaleExitNodeRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+func _StartedService_StartTailscaleSSHSession_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(StartedServiceServer).StartTailscaleSSHSession(&grpc.GenericServerStream[TailscaleSSHClientMessage, TailscaleSSHServerMessage]{ServerStream: stream})
+}
+
+// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
+type StartedService_StartTailscaleSSHSessionServer = grpc.BidiStreamingServer[TailscaleSSHClientMessage, TailscaleSSHServerMessage]
+
// StartedService_ServiceDesc is the grpc.ServiceDesc for StartedService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -863,6 +1180,14 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{
MethodName: "SetSystemProxyEnabled",
Handler: _StartedService_SetSystemProxyEnabled_Handler,
},
+ {
+ MethodName: "TriggerDebugCrash",
+ Handler: _StartedService_TriggerDebugCrash_Handler,
+ },
+ {
+ MethodName: "TriggerOOMReport",
+ Handler: _StartedService_TriggerOOMReport_Handler,
+ },
{
MethodName: "CloseConnection",
Handler: _StartedService_CloseConnection_Handler,
@@ -879,6 +1204,10 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetStartedAt",
Handler: _StartedService_GetStartedAt_Handler,
},
+ {
+ MethodName: "SetTailscaleExitNode",
+ Handler: _StartedService_SetTailscaleExitNode_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{
@@ -911,6 +1240,37 @@ var StartedService_ServiceDesc = grpc.ServiceDesc{
Handler: _StartedService_SubscribeConnections_Handler,
ServerStreams: true,
},
+ {
+ StreamName: "SubscribeOutbounds",
+ Handler: _StartedService_SubscribeOutbounds_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "StartNetworkQualityTest",
+ Handler: _StartedService_StartNetworkQualityTest_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "StartSTUNTest",
+ Handler: _StartedService_StartSTUNTest_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "SubscribeTailscaleStatus",
+ Handler: _StartedService_SubscribeTailscaleStatus_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "StartTailscalePing",
+ Handler: _StartedService_StartTailscalePing_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "StartTailscaleSSHSession",
+ Handler: _StartedService_StartTailscaleSSHSession_Handler,
+ ServerStreams: true,
+ ClientStreams: true,
+ },
},
Metadata: "daemon/started_service.proto",
}
diff --git a/daemon/started_service_tailscale_ssh.go b/daemon/started_service_tailscale_ssh.go
new file mode 100644
index 0000000000..f575e46426
--- /dev/null
+++ b/daemon/started_service_tailscale_ssh.go
@@ -0,0 +1,340 @@
+package daemon
+
+import (
+ "bytes"
+ "context"
+ "io"
+ "net"
+ "os"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ "golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/agent"
+ "google.golang.org/grpc"
+)
+
+type windowChangeRequest struct {
+ Columns uint32
+ Rows uint32
+ WidthPixels uint32
+ HeightPixels uint32
+}
+
+func (s *StartedService) StartTailscaleSSHSession(
+ server grpc.BidiStreamingServer[TailscaleSSHClientMessage, TailscaleSSHServerMessage],
+) error {
+ ctx := server.Context()
+ err := s.waitForStarted(ctx)
+ if err != nil {
+ return err
+ }
+ s.serviceAccess.RLock()
+ boxService := s.instance
+ s.serviceAccess.RUnlock()
+
+ firstMessage, err := server.Recv()
+ if err != nil {
+ return err
+ }
+ start := firstMessage.GetStart()
+
+ hostKeys := make([]ssh.PublicKey, 0, len(start.HostKeys))
+ for _, line := range start.HostKeys {
+ key, _, _, _, parseErr := ssh.ParseAuthorizedKey([]byte(line))
+ if parseErr != nil {
+ return E.Cause(parseErr, "parse host key")
+ }
+ hostKeys = append(hostKeys, key)
+ }
+
+ endpoint, err := resolveTailscaleEndpoint(boxService, start.EndpointTag)
+ if err != nil {
+ return err
+ }
+
+ peerAddr := M.ParseSocksaddrHostPort(start.PeerAddress, 22)
+
+ sessionCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ var sendAccess sync.Mutex
+ sendMessage := func(msg *TailscaleSSHServerMessage) {
+ sendAccess.Lock()
+ defer sendAccess.Unlock()
+ sendErr := server.Send(msg)
+ if sendErr != nil {
+ cancel()
+ }
+ }
+
+ finishWithError := func(message string) error {
+ sendMessage(&TailscaleSSHServerMessage{
+ Message: &TailscaleSSHServerMessage_Error{Error: &TailscaleSSHError{Message: message}},
+ })
+ return nil
+ }
+
+ peerConn, err := endpoint.DialContext(ctx, N.NetworkTCP, peerAddr)
+ if err != nil {
+ return finishWithError(E.Cause(err, "dial peer").Error())
+ }
+
+ var lastBanner string
+ config := &ssh.ClientConfig{
+ User: start.Username,
+ Auth: nil,
+ BannerCallback: func(message string) error {
+ lastBanner = message
+ sendMessage(&TailscaleSSHServerMessage{
+ Message: &TailscaleSSHServerMessage_AuthBanner{
+ AuthBanner: &TailscaleSSHAuthBanner{Message: message},
+ },
+ })
+ return nil
+ },
+ HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+ serverKey := key.Marshal()
+ for _, hostKey := range hostKeys {
+ if bytes.Equal(serverKey, hostKey.Marshal()) {
+ return nil
+ }
+ }
+ return E.New("untrusted host key: ", key.Type())
+ },
+ }
+ sshConn, chans, reqs, err := ssh.NewClientConn(peerConn, peerAddr.String(), config)
+ if err != nil {
+ common.Close(peerConn)
+ banner := strings.TrimSpace(lastBanner)
+ if banner != "" {
+ return finishWithError(banner)
+ }
+ return finishWithError(E.Cause(err, "ssh handshake").Error())
+ }
+ sshClient := ssh.NewClient(sshConn, chans, reqs)
+
+ if start.ForwardAgent {
+ agentChannels := sshClient.HandleChannelOpen("auth-agent@openssh.com")
+ if agentChannels != nil {
+ go func() {
+ for newChannel := range agentChannels {
+ channel, reqs, acceptErr := newChannel.Accept()
+ if acceptErr != nil {
+ continue
+ }
+ go ssh.DiscardRequests(reqs)
+ go s.forwardSSHAgentChannel(channel)
+ }
+ }()
+ }
+ }
+
+ sshSession, err := sshClient.NewSession()
+ if err != nil {
+ common.Close(sshClient)
+ return finishWithError(E.Cause(err, "open ssh session").Error())
+ }
+
+ cols := int(start.Columns)
+ rows := int(start.Rows)
+ err = sshSession.RequestPty(start.TerminalType, rows, cols, ssh.TerminalModes{
+ ssh.ECHO: 1,
+ ssh.ECHOE: 1,
+ ssh.ECHOK: 1,
+ ssh.ECHOKE: 1,
+ ssh.ECHOCTL: 1,
+ ssh.ICANON: 1,
+ ssh.ISIG: 1,
+ ssh.IEXTEN: 1,
+ ssh.ICRNL: 1,
+ ssh.IXON: 1,
+ ssh.IXANY: 1,
+ ssh.IMAXBEL: 1,
+ ssh.OPOST: 1,
+ ssh.ONLCR: 1,
+ ssh.TTY_OP_ISPEED: 14400,
+ ssh.TTY_OP_OSPEED: 14400,
+ })
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "request pty").Error())
+ }
+ if start.WidthPixels > 0 || start.HeightPixels > 0 {
+ _, _ = sshSession.SendRequest("window-change", false, ssh.Marshal(&windowChangeRequest{
+ Columns: uint32(start.Columns),
+ Rows: uint32(start.Rows),
+ WidthPixels: uint32(start.WidthPixels),
+ HeightPixels: uint32(start.HeightPixels),
+ }))
+ }
+
+ if start.ForwardAgent {
+ err = agent.RequestAgentForwarding(sshSession)
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "request agent forwarding").Error())
+ }
+ }
+
+ stdin, err := sshSession.StdinPipe()
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "stdin pipe").Error())
+ }
+ stdout, err := sshSession.StdoutPipe()
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "stdout pipe").Error())
+ }
+ stderr, err := sshSession.StderrPipe()
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "stderr pipe").Error())
+ }
+ err = sshSession.Shell()
+ if err != nil {
+ common.Close(sshSession, sshClient)
+ return finishWithError(E.Cause(err, "start shell").Error())
+ }
+
+ var workersWg sync.WaitGroup
+
+ sendMessage(&TailscaleSSHServerMessage{
+ Message: &TailscaleSSHServerMessage_Ready{Ready: &TailscaleSSHReady{}},
+ })
+
+ workersWg.Add(1)
+ go func() {
+ defer workersWg.Done()
+ for {
+ msg, recvErr := server.Recv()
+ if recvErr == io.EOF {
+ stdin.Close()
+ return
+ }
+ if recvErr != nil {
+ cancel()
+ return
+ }
+ switch m := msg.GetMessage().(type) {
+ case *TailscaleSSHClientMessage_Input:
+ if len(m.Input.Data) == 0 {
+ continue
+ }
+ _, writeErr := stdin.Write(m.Input.Data)
+ if writeErr != nil {
+ cancel()
+ return
+ }
+ case *TailscaleSSHClientMessage_Resize:
+ _, _ = sshSession.SendRequest("window-change", false, ssh.Marshal(&windowChangeRequest{
+ Columns: uint32(m.Resize.Columns),
+ Rows: uint32(m.Resize.Rows),
+ WidthPixels: uint32(m.Resize.WidthPixels),
+ HeightPixels: uint32(m.Resize.HeightPixels),
+ }))
+ }
+ }
+ }()
+
+ pumpReader := func(reader io.Reader) {
+ defer workersWg.Done()
+ buffer := buf.Get(buf.BufferSize)
+ defer buf.Put(buffer)
+ for {
+ n, readErr := reader.Read(buffer)
+ if n > 0 {
+ sendMessage(&TailscaleSSHServerMessage{
+ Message: &TailscaleSSHServerMessage_Output{Output: &TailscaleSSHOutput{Data: bytes.Clone(buffer[:n])}},
+ })
+ }
+ if readErr != nil {
+ return
+ }
+ }
+ }
+ workersWg.Add(1)
+ go pumpReader(stdout)
+ workersWg.Add(1)
+ go pumpReader(stderr)
+
+ workersWg.Add(1)
+ go func() {
+ defer workersWg.Done()
+ ticker := time.NewTicker(30 * time.Second)
+ defer ticker.Stop()
+ for {
+ select {
+ case <-sessionCtx.Done():
+ return
+ case <-ticker.C:
+ _, _, keepAliveErr := sshConn.SendRequest("keepalive@openssh.com", true, nil)
+ if keepAliveErr != nil {
+ cancel()
+ return
+ }
+ }
+ }
+ }()
+
+ workersWg.Add(1)
+ go func() {
+ defer workersWg.Done()
+ waitErr := sshSession.Wait()
+ exitMessage := &TailscaleSSHExit{}
+ switch waitErrTyped := waitErr.(type) {
+ case nil:
+ case *ssh.ExitError:
+ exitMessage.ExitCode = int32(waitErrTyped.ExitStatus())
+ exitMessage.Signal = waitErrTyped.Signal()
+ default:
+ exitMessage.ErrorMessage = waitErrTyped.Error()
+ }
+ sendMessage(&TailscaleSSHServerMessage{
+ Message: &TailscaleSSHServerMessage_Exit{Exit: exitMessage},
+ })
+ cancel()
+ }()
+
+ go func() {
+ <-sessionCtx.Done()
+ common.Close(peerConn, sshSession, sshClient)
+ }()
+
+ workersWg.Wait()
+ return nil
+}
+
+func (s *StartedService) forwardSSHAgentChannel(channel ssh.Channel) {
+ defer channel.Close()
+ fd, err := s.handler.ConnectSSHAgent()
+ if err != nil {
+ return
+ }
+ file := os.NewFile(uintptr(fd), "ssh-agent")
+ conn, err := net.FileConn(file)
+ file.Close()
+ if err != nil {
+ return
+ }
+ defer conn.Close()
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go func() {
+ defer wg.Done()
+ io.Copy(conn, channel)
+ }()
+ go func() {
+ defer wg.Done()
+ io.Copy(channel, conn)
+ }()
+ wg.Wait()
+}
diff --git a/dns/blocked_checker.go b/dns/blocked_checker.go
new file mode 100644
index 0000000000..75fcfbf84d
--- /dev/null
+++ b/dns/blocked_checker.go
@@ -0,0 +1,37 @@
+package dns
+
+import "net/netip"
+
+var blockedPrefixes = []netip.Prefix{
+ netip.MustParsePrefix("10.0.0.0/8"),
+ netip.MustParsePrefix("2001:4188:2:600::/64"),
+}
+
+func IsBlockedIP(ip netip.Addr) bool {
+ if !ip.IsValid() {
+ return true
+ }
+
+ for _, p := range blockedPrefixes {
+ if p.Contains(ip) {
+ return true
+ }
+ }
+ return false
+}
+
+func FilterBlocked(addrs []netip.Addr) []netip.Addr {
+ if addrs == nil {
+ return nil
+ }
+ if len(addrs) == 0 {
+ return addrs
+ }
+ out := addrs[:0] // in-place filter, no extra alloc
+ for _, ip := range addrs {
+ if !IsBlockedIP(ip) {
+ out = append(out, ip)
+ }
+ }
+ return out
+}
diff --git a/dns/client.go b/dns/client.go
index 89b6170c2a..ece3e0bdf4 100644
--- a/dns/client.go
+++ b/dns/client.go
@@ -5,7 +5,6 @@ import (
"errors"
"net"
"net/netip"
- "strings"
"time"
"github.com/sagernet/sing-box/adapter"
@@ -14,7 +13,6 @@ import (
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
- M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/task"
"github.com/sagernet/sing/contrab/freelru"
"github.com/sagernet/sing/contrab/maphash"
@@ -32,56 +30,63 @@ var (
var _ adapter.DNSClient = (*Client)(nil)
type Client struct {
- timeout time.Duration
- disableCache bool
- disableExpire bool
- independentCache bool
- clientSubnet netip.Prefix
- rdrc adapter.RDRCStore
- initRDRCFunc func() adapter.RDRCStore
- logger logger.ContextLogger
- cache freelru.Cache[dns.Question, *dns.Msg]
- cacheLock compatible.Map[dns.Question, chan struct{}]
- transportCache freelru.Cache[transportCacheKey, *dns.Msg]
- transportCacheLock compatible.Map[dns.Question, chan struct{}]
+ ctx context.Context
+ timeout time.Duration
+ disableCache bool
+ disableExpire bool
+ optimisticTimeout time.Duration
+ cacheCapacity uint32
+ clientSubnet netip.Prefix
+ rdrc adapter.RDRCStore
+ initRDRCFunc func() adapter.RDRCStore
+ dnsCache adapter.DNSCacheStore
+ initDNSCacheFunc func() adapter.DNSCacheStore
+ logger logger.ContextLogger
+ cache freelru.Cache[dnsCacheKey, *dns.Msg]
+ cacheLock compatible.Map[dnsCacheKey, chan struct{}]
+ backgroundRefresh compatible.Map[dnsCacheKey, struct{}]
}
type ClientOptions struct {
- Timeout time.Duration
- DisableCache bool
- DisableExpire bool
- IndependentCache bool
- CacheCapacity uint32
- ClientSubnet netip.Prefix
- RDRC func() adapter.RDRCStore
- Logger logger.ContextLogger
+ Context context.Context
+ Timeout time.Duration
+ DisableCache bool
+ DisableExpire bool
+ OptimisticTimeout time.Duration
+ CacheCapacity uint32
+ ClientSubnet netip.Prefix
+ RDRC func() adapter.RDRCStore
+ DNSCache func() adapter.DNSCacheStore
+ Logger logger.ContextLogger
}
func NewClient(options ClientOptions) *Client {
+ cacheCapacity := options.CacheCapacity
+ if cacheCapacity < 1024 {
+ cacheCapacity = 1024
+ }
client := &Client{
- timeout: options.Timeout,
- disableCache: options.DisableCache,
- disableExpire: options.DisableExpire,
- independentCache: options.IndependentCache,
- clientSubnet: options.ClientSubnet,
- initRDRCFunc: options.RDRC,
- logger: options.Logger,
+ ctx: options.Context,
+ timeout: options.Timeout,
+ disableCache: options.DisableCache,
+ disableExpire: options.DisableExpire,
+ optimisticTimeout: options.OptimisticTimeout,
+ cacheCapacity: cacheCapacity,
+ clientSubnet: options.ClientSubnet,
+ initRDRCFunc: options.RDRC,
+ initDNSCacheFunc: options.DNSCache,
+ logger: options.Logger,
}
if client.timeout == 0 {
client.timeout = C.DNSTimeout
}
- cacheCapacity := max(options.CacheCapacity, 1024)
- if !client.disableCache {
- if !client.independentCache {
- client.cache = common.Must1(freelru.NewSharded[dns.Question, *dns.Msg](cacheCapacity, maphash.NewHasher[dns.Question]().Hash32))
- } else {
- client.transportCache = common.Must1(freelru.NewSharded[transportCacheKey, *dns.Msg](cacheCapacity, maphash.NewHasher[transportCacheKey]().Hash32))
- }
+ if !client.disableCache && client.initDNSCacheFunc == nil {
+ client.initializeMemoryCache()
}
return client
}
-type transportCacheKey struct {
+type dnsCacheKey struct {
dns.Question
transportTag string
}
@@ -90,6 +95,19 @@ func (c *Client) Start() {
if c.initRDRCFunc != nil {
c.rdrc = c.initRDRCFunc()
}
+ if c.initDNSCacheFunc != nil {
+ c.dnsCache = c.initDNSCacheFunc()
+ }
+ if c.dnsCache == nil {
+ c.initializeMemoryCache()
+ }
+}
+
+func (c *Client) initializeMemoryCache() {
+ if c.disableCache || c.cache != nil {
+ return
+ }
+ c.cache = common.Must1(freelru.NewSharded[dnsCacheKey, *dns.Msg](c.cacheCapacity, maphash.NewHasher[dnsCacheKey]().Hash32))
}
func extractNegativeTTL(response *dns.Msg) (uint32, bool) {
@@ -106,7 +124,38 @@ func extractNegativeTTL(response *dns.Msg) (uint32, bool) {
return 0, false
}
-func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, message *dns.Msg, options adapter.DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) (*dns.Msg, error) {
+func computeTimeToLive(response *dns.Msg) uint32 {
+ var timeToLive uint32
+ if len(response.Answer) == 0 {
+ if soaTTL, hasSOA := extractNegativeTTL(response); hasSOA {
+ return soaTTL
+ }
+ }
+ for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ if record.Header().Rrtype == dns.TypeOPT {
+ continue
+ }
+ if timeToLive == 0 || record.Header().Ttl > 0 && record.Header().Ttl < timeToLive {
+ timeToLive = record.Header().Ttl
+ }
+ }
+ }
+ return timeToLive
+}
+
+func normalizeTTL(response *dns.Msg, timeToLive uint32) {
+ for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ if record.Header().Rrtype == dns.TypeOPT {
+ continue
+ }
+ record.Header().Ttl = timeToLive
+ }
+ }
+}
+
+func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, message *dns.Msg, options adapter.DNSQueryOptions, responseChecker func(response *dns.Msg) bool) (*dns.Msg, error) {
if len(message.Question) == 0 {
if c.logger != nil {
c.logger.WarnContext(ctx, "bad question size: ", len(message.Question))
@@ -120,13 +169,7 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
}
return FixedResponseStatus(message, dns.RcodeSuccess), nil
}
- clientSubnet := options.ClientSubnet
- if !clientSubnet.IsValid() {
- clientSubnet = c.clientSubnet
- }
- if clientSubnet.IsValid() {
- message = SetClientSubnet(message, clientSubnet)
- }
+ message = c.prepareExchangeMessage(message, options)
isSimpleRequest := len(message.Question) == 1 &&
len(message.Ns) == 0 &&
@@ -138,40 +181,34 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
!options.ClientSubnet.IsValid()
disableCache := !isSimpleRequest || c.disableCache || options.DisableCache
if !disableCache {
- if c.cache != nil {
- cond, loaded := c.cacheLock.LoadOrStore(question, make(chan struct{}))
- if loaded {
- select {
- case <-cond:
- case <-ctx.Done():
- return nil, ctx.Err()
- }
- } else {
- defer func() {
- c.cacheLock.Delete(question)
- close(cond)
- }()
- }
- } else if c.transportCache != nil {
- cond, loaded := c.transportCacheLock.LoadOrStore(question, make(chan struct{}))
- if loaded {
- select {
- case <-cond:
- case <-ctx.Done():
- return nil, ctx.Err()
- }
- } else {
- defer func() {
- c.transportCacheLock.Delete(question)
- close(cond)
- }()
+ cacheKey := dnsCacheKey{Question: question, transportTag: transport.Tag()}
+ cond, loaded := c.cacheLock.LoadOrStore(cacheKey, make(chan struct{}))
+ if loaded {
+ select {
+ case <-cond:
+ case <-time.After(c.timeout):
+ return nil, E.New("cache wait timeout")
+ case <-ctx.Done():
+ return nil, ctx.Err()
}
+ } else {
+ defer func() {
+ c.cacheLock.Delete(cacheKey)
+ close(cond)
+ }()
}
- response, ttl := c.loadResponse(question, transport)
+ response, ttl, isStale := c.loadResponse(question, transport)
if response != nil {
- logCachedResponse(c.logger, ctx, response, ttl)
- response.Id = message.Id
- return response, nil
+ if isStale && !options.DisableOptimisticCache {
+ c.backgroundRefreshDNS(transport, question, message.Copy(), options, responseChecker)
+ logOptimisticResponse(c.logger, ctx, response)
+ response.Id = message.Id
+ return response, nil
+ } else if !isStale {
+ logCachedResponse(c.logger, ctx, response, ttl)
+ response.Id = message.Id
+ return response, nil
+ }
}
}
@@ -187,62 +224,17 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
return nil, ErrResponseRejectedCached
}
}
- ctx, cancel := context.WithTimeout(ctx, c.timeout)
- response, err := transport.Exchange(ctx, message)
- cancel()
+ response, err := c.exchangeToTransport(ctx, transport, message)
if err != nil {
- var rcodeError RcodeError
- if errors.As(err, &rcodeError) {
- response = FixedResponseStatus(message, int(rcodeError))
- } else {
- return nil, err
- }
+ return nil, err
}
- /*if question.Qtype == dns.TypeA || question.Qtype == dns.TypeAAAA {
- validResponse := response
- loop:
- for {
- var (
- addresses int
- queryCNAME string
- )
- for _, rawRR := range validResponse.Answer {
- switch rr := rawRR.(type) {
- case *dns.A:
- break loop
- case *dns.AAAA:
- break loop
- case *dns.CNAME:
- queryCNAME = rr.Target
- }
- }
- if queryCNAME == "" {
- break
- }
- exMessage := *message
- exMessage.Question = []dns.Question{{
- Name: queryCNAME,
- Qtype: question.Qtype,
- }}
- validResponse, err = c.Exchange(ctx, transport, &exMessage, options, responseChecker)
- if err != nil {
- return nil, err
- }
- }
- if validResponse != response {
- response.Answer = append(response.Answer, validResponse.Answer...)
- }
- }*/
disableCache = disableCache || (response.Rcode != dns.RcodeSuccess && response.Rcode != dns.RcodeNameError)
if responseChecker != nil {
var rejected bool
- // TODO: add accept_any rule and support to check response instead of addresses
if response.Rcode != dns.RcodeSuccess && response.Rcode != dns.RcodeNameError {
rejected = true
- } else if len(response.Answer) == 0 {
- rejected = !responseChecker(nil)
} else {
- rejected = !responseChecker(MessageToAddresses(response))
+ rejected = !responseChecker(response)
}
if rejected {
if !disableCache && c.rdrc != nil {
@@ -252,54 +244,7 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
return response, ErrResponseRejected
}
}
- if question.Qtype == dns.TypeHTTPS {
- if options.Strategy == C.DomainStrategyIPv4Only || options.Strategy == C.DomainStrategyIPv6Only {
- for _, rr := range response.Answer {
- https, isHTTPS := rr.(*dns.HTTPS)
- if !isHTTPS {
- continue
- }
- content := https.SVCB
- content.Value = common.Filter(content.Value, func(it dns.SVCBKeyValue) bool {
- if options.Strategy == C.DomainStrategyIPv4Only {
- return it.Key() != dns.SVCB_IPV6HINT
- } else {
- return it.Key() != dns.SVCB_IPV4HINT
- }
- })
- https.SVCB = content
- }
- }
- }
- var timeToLive uint32
- if len(response.Answer) == 0 {
- if soaTTL, hasSOA := extractNegativeTTL(response); hasSOA {
- timeToLive = soaTTL
- }
- }
- if timeToLive == 0 {
- for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
- for _, record := range recordList {
- if record.Header().Rrtype == dns.TypeOPT {
- continue
- }
- if timeToLive == 0 || record.Header().Ttl > 0 && record.Header().Ttl < timeToLive {
- timeToLive = record.Header().Ttl
- }
- }
- }
- }
- if options.RewriteTTL != nil {
- timeToLive = *options.RewriteTTL
- }
- for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
- for _, record := range recordList {
- if record.Header().Rrtype == dns.TypeOPT {
- continue
- }
- record.Header().Ttl = timeToLive
- }
- }
+ timeToLive := applyResponseOptions(question, response, options)
if !disableCache {
c.storeCache(transport, question, response, timeToLive)
}
@@ -318,7 +263,7 @@ func (c *Client) Exchange(ctx context.Context, transport adapter.DNSTransport, m
return response, nil
}
-func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) ([]netip.Addr, error) {
+func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error) {
domain = FqdnToDomain(domain)
dnsName := dns.Fqdn(domain)
var strategy C.DomainStrategy
@@ -331,10 +276,9 @@ func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTransport, dom
if options.LookupStrategy != C.DomainStrategyAsIS {
lookupOptions.Strategy = strategy
}
- switch strategy {
- case C.DomainStrategyIPv4Only:
+ if strategy == C.DomainStrategyIPv4Only {
return c.lookupToExchange(ctx, transport, dnsName, dns.TypeA, lookupOptions, responseChecker)
- case C.DomainStrategyIPv6Only:
+ } else if strategy == C.DomainStrategyIPv6Only {
return c.lookupToExchange(ctx, transport, dnsName, dns.TypeAAAA, lookupOptions, responseChecker)
}
var response4 []netip.Addr
@@ -366,8 +310,12 @@ func (c *Client) Lookup(ctx context.Context, transport adapter.DNSTransport, dom
func (c *Client) ClearCache() {
if c.cache != nil {
c.cache.Purge()
- } else if c.transportCache != nil {
- c.transportCache.Purge()
+ }
+ if c.dnsCache != nil {
+ err := c.dnsCache.ClearDNSCache()
+ if err != nil && c.logger != nil {
+ c.logger.Warn("clear DNS cache: ", err)
+ }
}
}
@@ -383,46 +331,44 @@ func (c *Client) storeCache(transport adapter.DNSTransport, question dns.Questio
if timeToLive == 0 {
return
}
- if c.disableExpire {
- if !c.independentCache {
- c.cache.Add(question, message.Copy())
- } else {
- c.transportCache.Add(transportCacheKey{
- Question: question,
- transportTag: transport.Tag(),
- }, message.Copy())
+ if c.dnsCache != nil {
+ packed, err := message.Pack()
+ if err == nil {
+ expireAt := time.Now().Add(time.Second * time.Duration(timeToLive))
+ c.dnsCache.SaveDNSCacheAsync(transport.Tag(), question.Name, question.Qtype, packed, expireAt, c.logger)
}
+ return
+ }
+ if c.cache == nil {
+ return
+ }
+ key := dnsCacheKey{Question: question, transportTag: transport.Tag()}
+ if c.disableExpire {
+ c.cache.Add(key, message.Copy())
} else {
- if !c.independentCache {
- c.cache.AddWithLifetime(question, message.Copy(), time.Second*time.Duration(timeToLive))
- } else {
- c.transportCache.AddWithLifetime(transportCacheKey{
- Question: question,
- transportTag: transport.Tag(),
- }, message.Copy(), time.Second*time.Duration(timeToLive))
- }
+ c.cache.AddWithLifetime(key, message.Copy(), time.Second*time.Duration(timeToLive))
}
}
-func (c *Client) lookupToExchange(ctx context.Context, transport adapter.DNSTransport, name string, qType uint16, options adapter.DNSQueryOptions, responseChecker func(responseAddrs []netip.Addr) bool) ([]netip.Addr, error) {
+func (c *Client) lookupToExchange(ctx context.Context, transport adapter.DNSTransport, name string, qType uint16, options adapter.DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error) {
question := dns.Question{
Name: name,
Qtype: qType,
Qclass: dns.ClassINET,
}
- disableCache := c.disableCache || options.DisableCache
- if !disableCache {
- cachedAddresses, err := c.questionCache(question, transport)
- if err != ErrNotCached {
- return cachedAddresses, err
- }
- }
message := dns.Msg{
MsgHdr: dns.MsgHdr{
RecursionDesired: true,
},
Question: []dns.Question{question},
}
+ disableCache := c.disableCache || options.DisableCache
+ if !disableCache {
+ cachedAddresses, err := c.questionCache(ctx, transport, &message, options, responseChecker)
+ if err != ErrNotCached {
+ return cachedAddresses, err
+ }
+ }
response, err := c.Exchange(ctx, transport, &message, options, responseChecker)
if err != nil {
return nil, err
@@ -433,117 +379,206 @@ func (c *Client) lookupToExchange(ctx context.Context, transport adapter.DNSTran
return MessageToAddresses(response), nil
}
-func (c *Client) questionCache(question dns.Question, transport adapter.DNSTransport) ([]netip.Addr, error) {
- response, _ := c.loadResponse(question, transport)
+func (c *Client) questionCache(ctx context.Context, transport adapter.DNSTransport, message *dns.Msg, options adapter.DNSQueryOptions, responseChecker func(response *dns.Msg) bool) ([]netip.Addr, error) {
+ question := message.Question[0]
+ response, _, isStale := c.loadResponse(question, transport)
if response == nil {
return nil, ErrNotCached
}
+ if isStale {
+ if options.DisableOptimisticCache {
+ return nil, ErrNotCached
+ }
+ c.backgroundRefreshDNS(transport, question, c.prepareExchangeMessage(message.Copy(), options), options, responseChecker)
+ logOptimisticResponse(c.logger, ctx, response)
+ }
if response.Rcode != dns.RcodeSuccess {
return nil, RcodeError(response.Rcode)
}
return MessageToAddresses(response), nil
}
-func (c *Client) loadResponse(question dns.Question, transport adapter.DNSTransport) (*dns.Msg, int) {
- var (
- response *dns.Msg
- loaded bool
- )
+func (c *Client) loadResponse(question dns.Question, transport adapter.DNSTransport) (*dns.Msg, int, bool) {
+ if c.dnsCache != nil {
+ return c.loadPersistentResponse(question, transport)
+ }
+ if c.cache == nil {
+ return nil, 0, false
+ }
+ key := dnsCacheKey{Question: question, transportTag: transport.Tag()}
if c.disableExpire {
- if !c.independentCache {
- response, loaded = c.cache.Get(question)
- } else {
- response, loaded = c.transportCache.Get(transportCacheKey{
- Question: question,
- transportTag: transport.Tag(),
- })
- }
+ response, loaded := c.cache.Get(key)
if !loaded {
- return nil, 0
+ return nil, 0, false
}
- return response.Copy(), 0
- } else {
- var expireAt time.Time
- if !c.independentCache {
- response, expireAt, loaded = c.cache.GetWithLifetime(question)
- } else {
- response, expireAt, loaded = c.transportCache.GetWithLifetime(transportCacheKey{
- Question: question,
- transportTag: transport.Tag(),
- })
+ return response.Copy(), 0, false
+ }
+ response, expireAt, loaded := c.cache.GetWithLifetimeNoExpire(key)
+ if !loaded {
+ return nil, 0, false
+ }
+ timeNow := time.Now()
+ if timeNow.After(expireAt) {
+ if c.optimisticTimeout > 0 && timeNow.Before(expireAt.Add(c.optimisticTimeout)) {
+ response = response.Copy()
+ normalizeTTL(response, 1)
+ return response, 0, true
}
- if !loaded {
- return nil, 0
+ c.cache.Remove(key)
+ return nil, 0, false
+ }
+ nowTTL := int(expireAt.Sub(timeNow).Seconds())
+ if nowTTL < 0 {
+ nowTTL = 0
+ }
+ response = response.Copy()
+ normalizeTTL(response, uint32(nowTTL))
+ return response, nowTTL, false
+}
+
+func (c *Client) loadPersistentResponse(question dns.Question, transport adapter.DNSTransport) (*dns.Msg, int, bool) {
+ rawMessage, expireAt, loaded := c.dnsCache.LoadDNSCache(transport.Tag(), question.Name, question.Qtype)
+ if !loaded {
+ return nil, 0, false
+ }
+ response := new(dns.Msg)
+ err := response.Unpack(rawMessage)
+ if err != nil {
+ return nil, 0, false
+ }
+ if c.disableExpire {
+ return response, 0, false
+ }
+ timeNow := time.Now()
+ if timeNow.After(expireAt) {
+ if c.optimisticTimeout > 0 && timeNow.Before(expireAt.Add(c.optimisticTimeout)) {
+ normalizeTTL(response, 1)
+ return response, 0, true
}
- timeNow := time.Now()
- if timeNow.After(expireAt) {
- if !c.independentCache {
- c.cache.Remove(question)
- } else {
- c.transportCache.Remove(transportCacheKey{
- Question: question,
- transportTag: transport.Tag(),
- })
+ return nil, 0, false
+ }
+ nowTTL := int(expireAt.Sub(timeNow).Seconds())
+ if nowTTL < 0 {
+ nowTTL = 0
+ }
+ normalizeTTL(response, uint32(nowTTL))
+ return response, nowTTL, false
+}
+
+func applyResponseOptions(question dns.Question, response *dns.Msg, options adapter.DNSQueryOptions) uint32 {
+ if question.Qtype == dns.TypeHTTPS && (options.Strategy == C.DomainStrategyIPv4Only || options.Strategy == C.DomainStrategyIPv6Only) {
+ for _, rr := range response.Answer {
+ https, isHTTPS := rr.(*dns.HTTPS)
+ if !isHTTPS {
+ continue
}
- return nil, 0
- }
- var originTTL int
- for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
- for _, record := range recordList {
- if record.Header().Rrtype == dns.TypeOPT {
- continue
- }
- if originTTL == 0 || record.Header().Ttl > 0 && int(record.Header().Ttl) < originTTL {
- originTTL = int(record.Header().Ttl)
+ content := https.SVCB
+ content.Value = common.Filter(content.Value, func(it dns.SVCBKeyValue) bool {
+ if options.Strategy == C.DomainStrategyIPv4Only {
+ return it.Key() != dns.SVCB_IPV6HINT
}
+ return it.Key() != dns.SVCB_IPV4HINT
+ })
+ https.SVCB = content
+ }
+ }
+ timeToLive := computeTimeToLive(response)
+ if options.RewriteTTL != nil {
+ timeToLive = *options.RewriteTTL
+ }
+ normalizeTTL(response, timeToLive)
+ return timeToLive
+}
+
+func (c *Client) backgroundRefreshDNS(transport adapter.DNSTransport, question dns.Question, message *dns.Msg, options adapter.DNSQueryOptions, responseChecker func(response *dns.Msg) bool) {
+ key := dnsCacheKey{Question: question, transportTag: transport.Tag()}
+ _, loaded := c.backgroundRefresh.LoadOrStore(key, struct{}{})
+ if loaded {
+ return
+ }
+ go func() {
+ defer c.backgroundRefresh.Delete(key)
+ ctx := contextWithTransportTag(c.ctx, transport.Tag())
+ response, err := c.exchangeToTransport(ctx, transport, message)
+ if err != nil {
+ if c.logger != nil {
+ c.logger.Debug("optimistic refresh failed for ", FqdnToDomain(question.Name), ": ", err)
}
+ return
}
- nowTTL := max(int(expireAt.Sub(timeNow).Seconds()), 0)
- response = response.Copy()
- if originTTL > 0 {
- duration := uint32(originTTL - nowTTL)
- for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
- for _, record := range recordList {
- if record.Header().Rrtype == dns.TypeOPT {
- continue
- }
- record.Header().Ttl = record.Header().Ttl - duration
- }
+ if responseChecker != nil {
+ var rejected bool
+ if response.Rcode != dns.RcodeSuccess && response.Rcode != dns.RcodeNameError {
+ rejected = true
+ } else {
+ rejected = !responseChecker(response)
}
- } else {
- for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
- for _, record := range recordList {
- if record.Header().Rrtype == dns.TypeOPT {
- continue
- }
- record.Header().Ttl = uint32(nowTTL)
+ if rejected {
+ if c.rdrc != nil {
+ c.rdrc.SaveRDRCAsync(transport.Tag(), question.Name, question.Qtype, c.logger)
}
+ return
}
+ } else if response.Rcode != dns.RcodeSuccess && response.Rcode != dns.RcodeNameError {
+ return
+ }
+ timeToLive := applyResponseOptions(question, response, options)
+ c.storeCache(transport, question, response, timeToLive)
+ }()
+}
+
+func (c *Client) prepareExchangeMessage(message *dns.Msg, options adapter.DNSQueryOptions) *dns.Msg {
+ clientSubnet := options.ClientSubnet
+ if !clientSubnet.IsValid() {
+ clientSubnet = c.clientSubnet
+ }
+ if clientSubnet.IsValid() {
+ message = SetClientSubnet(message, clientSubnet)
+ }
+ return message
+}
+
+func stripDNSPadding(response *dns.Msg) {
+ for _, record := range response.Extra {
+ opt, isOpt := record.(*dns.OPT)
+ if !isOpt {
+ continue
}
- return response, nowTTL
+ opt.Option = common.Filter(opt.Option, func(it dns.EDNS0) bool {
+ return it.Option() != dns.EDNS0PADDING
+ })
}
}
-func MessageToAddresses(response *dns.Msg) []netip.Addr {
- if response == nil || response.Rcode != dns.RcodeSuccess {
- return nil
+func (c *Client) exchangeToTransport(ctx context.Context, transport adapter.DNSTransport, message *dns.Msg) (*dns.Msg, error) {
+ ctx, cancel := context.WithTimeout(ctx, c.timeout)
+ defer cancel()
+ response, err := transport.Exchange(ctx, message)
+ if err == nil {
+ stripDNSPadding(response)
+ return response, nil
}
- addresses := make([]netip.Addr, 0, len(response.Answer))
- for _, rawAnswer := range response.Answer {
- switch answer := rawAnswer.(type) {
- case *dns.A:
- addresses = append(addresses, M.AddrFromIP(answer.A))
- case *dns.AAAA:
- addresses = append(addresses, M.AddrFromIP(answer.AAAA))
- case *dns.HTTPS:
- for _, value := range answer.SVCB.Value {
- if value.Key() == dns.SVCB_IPV4HINT || value.Key() == dns.SVCB_IPV6HINT {
- addresses = append(addresses, common.Map(strings.Split(value.String(), ","), M.ParseAddr)...)
- }
- }
+ var rcodeError RcodeError
+ if errors.As(err, &rcodeError) {
+ return FixedResponseStatus(message, int(rcodeError)), nil
+ }
+ return nil, err
+}
+
+func MessageToAddresses(response *dns.Msg) []netip.Addr {
+ return adapter.DNSResponseAddresses(response)
+}
+
+func wrapError(err error) error {
+ switch dnsErr := err.(type) {
+ case *net.DNSError:
+ if dnsErr.IsNotFound {
+ return RcodeNameError
}
+ case *net.AddrError:
+ return RcodeNameError
}
- return addresses
+ return err
}
type transportKey struct{}
diff --git a/dns/client_log.go b/dns/client_log.go
index 67d0070841..abc726d3c4 100644
--- a/dns/client_log.go
+++ b/dns/client_log.go
@@ -22,6 +22,19 @@ func logCachedResponse(logger logger.ContextLogger, ctx context.Context, respons
}
}
+func logOptimisticResponse(logger logger.ContextLogger, ctx context.Context, response *dns.Msg) {
+ if logger == nil || len(response.Question) == 0 {
+ return
+ }
+ domain := FqdnToDomain(response.Question[0].Name)
+ logger.DebugContext(ctx, "optimistic ", domain, " ", dns.RcodeToString[response.Rcode])
+ for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ logger.InfoContext(ctx, "optimistic ", dns.Type(record.Header().Rrtype).String(), " ", FormatQuestion(record.String()))
+ }
+ }
+}
+
func logExchangedResponse(logger logger.ContextLogger, ctx context.Context, response *dns.Msg, ttl uint32) {
if logger == nil || len(response.Question) == 0 {
return
@@ -35,6 +48,19 @@ func logExchangedResponse(logger logger.ContextLogger, ctx context.Context, resp
}
}
+func logRefreshedResponse(logger logger.ContextLogger, ctx context.Context, response *dns.Msg, ttl uint32) {
+ if logger == nil || len(response.Question) == 0 {
+ return
+ }
+ domain := FqdnToDomain(response.Question[0].Name)
+ logger.DebugContext(ctx, "refreshed ", domain, " ", dns.RcodeToString[response.Rcode], " ", ttl)
+ for _, recordList := range [][]dns.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ logger.InfoContext(ctx, "refreshed ", dns.Type(record.Header().Rrtype).String(), " ", FormatQuestion(record.String()))
+ }
+ }
+}
+
func logRejectedResponse(logger logger.ContextLogger, ctx context.Context, response *dns.Msg) {
if logger == nil || len(response.Question) == 0 {
return
diff --git a/dns/rcode.go b/dns/rcode.go
index 59c564b658..417d41fa1e 100644
--- a/dns/rcode.go
+++ b/dns/rcode.go
@@ -5,10 +5,11 @@ import (
)
const (
- RcodeSuccess RcodeError = mDNS.RcodeSuccess
- RcodeFormatError RcodeError = mDNS.RcodeFormatError
- RcodeNameError RcodeError = mDNS.RcodeNameError
- RcodeRefused RcodeError = mDNS.RcodeRefused
+ RcodeSuccess RcodeError = mDNS.RcodeSuccess
+ RcodeServerFailure RcodeError = mDNS.RcodeServerFailure
+ RcodeFormatError RcodeError = mDNS.RcodeFormatError
+ RcodeNameError RcodeError = mDNS.RcodeNameError
+ RcodeRefused RcodeError = mDNS.RcodeRefused
)
type RcodeError int
diff --git a/dns/repro_test.go b/dns/repro_test.go
new file mode 100644
index 0000000000..113f7c49b9
--- /dev/null
+++ b/dns/repro_test.go
@@ -0,0 +1,111 @@
+package dns
+
+import (
+ "context"
+ "net/netip"
+ "testing"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json/badoption"
+
+ mDNS "github.com/miekg/dns"
+ "github.com/stretchr/testify/require"
+)
+
+func TestReproLookupWithRulesUsesRequestStrategy(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ var qTypes []uint16
+ router := newTestRouter(t, nil, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ qTypes = append(qTypes, message.Question[0].Qtype)
+ if message.Question[0].Qtype == mDNS.TypeA {
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2.2.2.2")}, 60), nil
+ }
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2001:db8::1")}, 60), nil
+ },
+ })
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
+ Strategy: C.DomainStrategyIPv4Only,
+ })
+ require.NoError(t, err)
+ require.Equal(t, []uint16{mDNS.TypeA}, qTypes)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("2.2.2.2")}, addresses)
+}
+
+func TestReproLogicalMatchResponseIPCIDR(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ IPCIDR: badoption.Listable[string]{"1.1.1.0/24"},
+ },
+ },
+ }},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
diff --git a/dns/router.go b/dns/router.go
index 4f18959b7c..549f42e205 100644
--- a/dns/router.go
+++ b/dns/router.go
@@ -5,20 +5,23 @@ import (
"errors"
"net/netip"
"strings"
+ "sync"
"time"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/taskmonitor"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
R "github.com/sagernet/sing-box/route/rule"
- "github.com/sagernet/sing-tun"
+ tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
+ "github.com/sagernet/sing/common/task"
"github.com/sagernet/sing/contrab/freelru"
"github.com/sagernet/sing/contrab/maphash"
"github.com/sagernet/sing/service"
@@ -26,7 +29,10 @@ import (
mDNS "github.com/miekg/dns"
)
-var _ adapter.DNSRouter = (*Router)(nil)
+var (
+ _ adapter.DNSRouter = (*Router)(nil)
+ _ adapter.DNSRuleSetUpdateValidator = (*Router)(nil)
+)
type Router struct {
ctx context.Context
@@ -34,27 +40,51 @@ type Router struct {
transport adapter.DNSTransportManager
outbound adapter.OutboundManager
client adapter.DNSClient
+ rawRules []option.DNSRule
rules []adapter.DNSRule
defaultDomainStrategy C.DomainStrategy
dnsReverseMapping freelru.Cache[netip.Addr, string]
platformInterface adapter.PlatformInterface
+ legacyDNSMode bool
+ rulesAccess sync.RWMutex
+ started bool
+ closing bool
}
-func NewRouter(ctx context.Context, logFactory log.Factory, options option.DNSOptions) *Router {
+func NewRouter(ctx context.Context, logFactory log.Factory, options option.DNSOptions) (*Router, error) {
router := &Router{
ctx: ctx,
logger: logFactory.NewLogger("dns"),
transport: service.FromContext[adapter.DNSTransportManager](ctx),
outbound: service.FromContext[adapter.OutboundManager](ctx),
+ rawRules: make([]option.DNSRule, 0, len(options.Rules)),
rules: make([]adapter.DNSRule, 0, len(options.Rules)),
defaultDomainStrategy: C.DomainStrategy(options.Strategy),
}
+ if options.DNSClientOptions.IndependentCache {
+ deprecated.Report(ctx, deprecated.OptionIndependentDNSCache)
+ }
+ var optimisticTimeout time.Duration
+ optimisticOptions := common.PtrValueOrDefault(options.DNSClientOptions.Optimistic)
+ if optimisticOptions.Enabled {
+ if options.DNSClientOptions.DisableCache {
+ return nil, E.New("`optimistic` is conflict with `disable_cache`")
+ }
+ if options.DNSClientOptions.DisableExpire {
+ return nil, E.New("`optimistic` is conflict with `disable_expire`")
+ }
+ optimisticTimeout = time.Duration(optimisticOptions.Timeout)
+ if optimisticTimeout == 0 {
+ optimisticTimeout = 3 * 24 * time.Hour
+ }
+ }
router.client = NewClient(ClientOptions{
- DisableCache: options.DNSClientOptions.DisableCache,
- DisableExpire: options.DNSClientOptions.DisableExpire,
- IndependentCache: options.DNSClientOptions.IndependentCache,
- CacheCapacity: options.DNSClientOptions.CacheCapacity,
- ClientSubnet: options.DNSClientOptions.ClientSubnet.Build(netip.Prefix{}),
+ Context: ctx,
+ DisableCache: options.DNSClientOptions.DisableCache,
+ DisableExpire: options.DNSClientOptions.DisableExpire,
+ OptimisticTimeout: optimisticTimeout,
+ CacheCapacity: options.DNSClientOptions.CacheCapacity,
+ ClientSubnet: options.DNSClientOptions.ClientSubnet.Build(netip.Prefix{}),
RDRC: func() adapter.RDRCStore {
cacheFile := service.FromContext[adapter.CacheFile](ctx)
if cacheFile == nil {
@@ -65,22 +95,33 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.DNSOp
}
return cacheFile
},
+ DNSCache: func() adapter.DNSCacheStore {
+ cacheFile := service.FromContext[adapter.CacheFile](ctx)
+ if cacheFile == nil {
+ return nil
+ }
+ if !cacheFile.StoreDNS() {
+ return nil
+ }
+ cacheFile.SetDisableExpire(options.DNSClientOptions.DisableExpire)
+ cacheFile.SetOptimisticTimeout(optimisticTimeout)
+ return cacheFile
+ },
Logger: router.logger,
})
if options.ReverseMapping {
router.dnsReverseMapping = common.Must1(freelru.NewSharded[netip.Addr, string](1024, maphash.NewHasher[netip.Addr]().Hash32))
}
- return router
+ return router, nil
}
func (r *Router) Initialize(rules []option.DNSRule) error {
- for i, ruleOptions := range rules {
- dnsRule, err := R.NewDNSRule(r.ctx, r.logger, ruleOptions, true)
- if err != nil {
- return E.Cause(err, "parse dns rule[", i, "]")
- }
- r.rules = append(r.rules, dnsRule)
+ r.rawRules = append(r.rawRules[:0], rules...)
+ newRules, _, _, err := r.buildRules(false)
+ if err != nil {
+ return err
}
+ closeRules(newRules)
return nil
}
@@ -92,32 +133,146 @@ func (r *Router) Start(stage adapter.StartStage) error {
r.client.Start()
monitor.Finish()
- for i, rule := range r.rules {
- monitor.Start("initialize DNS rule[", i, "]")
- err := rule.Start()
- monitor.Finish()
- if err != nil {
- return E.Cause(err, "initialize DNS rule[", i, "]")
- }
+ monitor.Start("initialize DNS rules")
+ newRules, legacyDNSMode, modeFlags, err := r.buildRules(true)
+ monitor.Finish()
+ if err != nil {
+ return err
+ }
+ r.rulesAccess.Lock()
+ if r.closing {
+ r.rulesAccess.Unlock()
+ closeRules(newRules)
+ return nil
+ }
+ r.rules = newRules
+ r.legacyDNSMode = legacyDNSMode
+ r.started = true
+ r.rulesAccess.Unlock()
+ if legacyDNSMode && common.Any(newRules, func(rule adapter.DNSRule) bool { return rule.WithAddressLimit() }) {
+ deprecated.Report(r.ctx, deprecated.OptionLegacyDNSAddressFilter)
+ }
+ if legacyDNSMode && modeFlags.neededFromStrategy {
+ deprecated.Report(r.ctx, deprecated.OptionLegacyDNSRuleStrategy)
}
}
return nil
}
func (r *Router) Close() error {
- monitor := taskmonitor.New(r.logger, C.StopTimeout)
- var err error
- for i, rule := range r.rules {
- monitor.Start("close dns rule[", i, "]")
- err = E.Append(err, rule.Close(), func(err error) error {
- return E.Cause(err, "close dns rule[", i, "]")
- })
- monitor.Finish()
+ r.rulesAccess.Lock()
+ if r.closing {
+ r.rulesAccess.Unlock()
+ return nil
+ }
+ r.closing = true
+ runtimeRules := r.rules
+ r.rules = nil
+ r.rulesAccess.Unlock()
+ closeRules(runtimeRules)
+ return nil
+}
+
+func (r *Router) buildRules(startRules bool) ([]adapter.DNSRule, bool, dnsRuleModeFlags, error) {
+ for i, ruleOptions := range r.rawRules {
+ err := R.ValidateNoNestedDNSRuleActions(ruleOptions)
+ if err != nil {
+ return nil, false, dnsRuleModeFlags{}, E.Cause(err, "parse dns rule[", i, "]")
+ }
+ }
+ router := service.FromContext[adapter.Router](r.ctx)
+ legacyDNSMode, modeFlags, err := resolveLegacyDNSMode(router, r.rawRules, nil)
+ if err != nil {
+ return nil, false, dnsRuleModeFlags{}, err
+ }
+ if !legacyDNSMode {
+ err = validateLegacyDNSModeDisabledRules(router, r.rawRules, nil)
+ if err != nil {
+ return nil, false, dnsRuleModeFlags{}, err
+ }
+ }
+ err = validateEvaluateFakeIPRules(r.rawRules, r.transport)
+ if err != nil {
+ return nil, false, dnsRuleModeFlags{}, err
+ }
+ newRules := make([]adapter.DNSRule, 0, len(r.rawRules))
+ for i, ruleOptions := range r.rawRules {
+ var dnsRule adapter.DNSRule
+ dnsRule, err = R.NewDNSRule(r.ctx, r.logger, ruleOptions, true, legacyDNSMode)
+ if err != nil {
+ closeRules(newRules)
+ return nil, false, dnsRuleModeFlags{}, E.Cause(err, "parse dns rule[", i, "]")
+ }
+ newRules = append(newRules, dnsRule)
+ }
+ if startRules {
+ for i, rule := range newRules {
+ err = rule.Start()
+ if err != nil {
+ closeRules(newRules)
+ return nil, false, dnsRuleModeFlags{}, E.Cause(err, "initialize DNS rule[", i, "]")
+ }
+ }
+ }
+ return newRules, legacyDNSMode, modeFlags, nil
+}
+
+func closeRules(rules []adapter.DNSRule) {
+ for _, rule := range rules {
+ _ = rule.Close()
+ }
+}
+
+func (r *Router) ValidateRuleSetMetadataUpdate(tag string, metadata adapter.RuleSetMetadata) error {
+ if len(r.rawRules) == 0 {
+ return nil
+ }
+ router := service.FromContext[adapter.Router](r.ctx)
+ if router == nil {
+ return E.New("router service not found")
+ }
+ overrides := map[string]adapter.RuleSetMetadata{
+ tag: metadata,
+ }
+ r.rulesAccess.RLock()
+ started := r.started
+ legacyDNSMode := r.legacyDNSMode
+ closing := r.closing
+ r.rulesAccess.RUnlock()
+ if closing {
+ return nil
+ }
+ if !started {
+ candidateLegacyDNSMode, _, err := resolveLegacyDNSMode(router, r.rawRules, overrides)
+ if err != nil {
+ return err
+ }
+ if !candidateLegacyDNSMode {
+ return validateLegacyDNSModeDisabledRules(router, r.rawRules, overrides)
+ }
+ return nil
+ }
+ candidateLegacyDNSMode, flags, err := resolveLegacyDNSMode(router, r.rawRules, overrides)
+ if err != nil {
+ return err
+ }
+ if legacyDNSMode {
+ if !candidateLegacyDNSMode && flags.disabled {
+ err := validateLegacyDNSModeDisabledRules(router, r.rawRules, overrides)
+ if err != nil {
+ return err
+ }
+ return E.New(deprecated.OptionLegacyDNSAddressFilter.MessageWithLink())
+ }
+ return nil
+ }
+ if candidateLegacyDNSMode {
+ return E.New(deprecated.OptionLegacyDNSAddressFilter.MessageWithLink())
}
- return err
+ return validateLegacyDNSModeDisabledRules(router, r.rawRules, overrides)
}
-func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int, isAddressQuery bool, options *adapter.DNSQueryOptions) (adapter.DNSTransport, adapter.DNSRule, int) {
+func (r *Router) matchDNS(ctx context.Context, rules []adapter.DNSRule, allowFakeIP bool, ruleIndex int, isAddressQuery bool, options *adapter.DNSQueryOptions) (adapter.DNSTransport, adapter.DNSRule, int) {
metadata := adapter.ContextFrom(ctx)
if metadata == nil {
panic("no context")
@@ -126,22 +281,18 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
if ruleIndex != -1 {
currentRuleIndex = ruleIndex + 1
}
- for ; currentRuleIndex < len(r.rules); currentRuleIndex++ {
- currentRule := r.rules[currentRuleIndex]
+ for ; currentRuleIndex < len(rules); currentRuleIndex++ {
+ currentRule := rules[currentRuleIndex]
if currentRule.WithAddressLimit() && !isAddressQuery {
continue
}
metadata.ResetRuleCache()
- if currentRule.Match(metadata) {
- displayRuleIndex := currentRuleIndex
- if displayRuleIndex != -1 {
- displayRuleIndex += displayRuleIndex + 1
- }
- ruleDescription := currentRule.String()
- if ruleDescription != "" {
- r.logger.DebugContext(ctx, "match[", displayRuleIndex, "] ", currentRule, " => ", currentRule.Action())
+ metadata.DestinationAddressMatchFromResponse = false
+ if currentRule.LegacyPreMatch(metadata) {
+ if ruleDescription := currentRule.String(); ruleDescription != "" {
+ r.logger.DebugContext(ctx, "match[", currentRuleIndex, "] ", currentRule, " => ", currentRule.Action())
} else {
- r.logger.DebugContext(ctx, "match[", displayRuleIndex, "] => ", currentRule.Action())
+ r.logger.DebugContext(ctx, "match[", currentRuleIndex, "] => ", currentRule.Action())
}
switch action := currentRule.Action().(type) {
case *R.RuleActionDNSRoute:
@@ -166,14 +317,6 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
if action.ClientSubnet.IsValid() {
options.ClientSubnet = action.ClientSubnet
}
- if legacyTransport, isLegacy := transport.(adapter.LegacyDNSTransport); isLegacy {
- if options.Strategy == C.DomainStrategyAsIS {
- options.Strategy = legacyTransport.LegacyStrategy()
- }
- if !options.ClientSubnet.IsValid() {
- options.ClientSubnet = legacyTransport.LegacyClientSubnet()
- }
- }
return transport, currentRule, currentRuleIndex
case *R.RuleActionDNSRouteOptions:
if action.Strategy != C.DomainStrategyAsIS {
@@ -196,15 +339,273 @@ func (r *Router) matchDNS(ctx context.Context, allowFakeIP bool, ruleIndex int,
}
}
transport := r.transport.Default()
- if legacyTransport, isLegacy := transport.(adapter.LegacyDNSTransport); isLegacy {
- if options.Strategy == C.DomainStrategyAsIS {
- options.Strategy = legacyTransport.LegacyStrategy()
+ return transport, nil, -1
+}
+
+func (r *Router) applyDNSRouteOptions(options *adapter.DNSQueryOptions, routeOptions R.RuleActionDNSRouteOptions) {
+ // Strategy is intentionally skipped here. A non-default DNS rule action strategy
+ // forces legacy mode via resolveLegacyDNSMode, so this path is only reachable
+ // when strategy remains at its default value.
+ if routeOptions.DisableCache {
+ options.DisableCache = true
+ }
+ if routeOptions.DisableOptimisticCache {
+ options.DisableOptimisticCache = true
+ }
+ if routeOptions.RewriteTTL != nil {
+ options.RewriteTTL = routeOptions.RewriteTTL
+ }
+ if routeOptions.ClientSubnet.IsValid() {
+ options.ClientSubnet = routeOptions.ClientSubnet
+ }
+}
+
+type dnsRouteStatus uint8
+
+const (
+ dnsRouteStatusMissing dnsRouteStatus = iota
+ dnsRouteStatusSkipped
+ dnsRouteStatusResolved
+)
+
+func (r *Router) resolveDNSRoute(server string, routeOptions R.RuleActionDNSRouteOptions, allowFakeIP bool, options *adapter.DNSQueryOptions) (adapter.DNSTransport, dnsRouteStatus) {
+ transport, loaded := r.transport.Transport(server)
+ if !loaded {
+ return nil, dnsRouteStatusMissing
+ }
+ isFakeIP := transport.Type() == C.DNSTypeFakeIP
+ if isFakeIP && !allowFakeIP {
+ return transport, dnsRouteStatusSkipped
+ }
+ r.applyDNSRouteOptions(options, routeOptions)
+ if isFakeIP {
+ options.DisableCache = true
+ }
+ return transport, dnsRouteStatusResolved
+}
+
+func (r *Router) logRuleMatch(ctx context.Context, ruleIndex int, currentRule adapter.DNSRule) {
+ if ruleDescription := currentRule.String(); ruleDescription != "" {
+ r.logger.DebugContext(ctx, "match[", ruleIndex, "] ", currentRule, " => ", currentRule.Action())
+ } else {
+ r.logger.DebugContext(ctx, "match[", ruleIndex, "] => ", currentRule.Action())
+ }
+}
+
+type exchangeWithRulesResult struct {
+ response *mDNS.Msg
+ transport adapter.DNSTransport
+ rejectAction *R.RuleActionReject
+ err error
+}
+
+const dnsRespondMissingResponseMessage = "respond action requires an evaluated response from a preceding evaluate action"
+
+func (r *Router) exchangeWithRules(ctx context.Context, rules []adapter.DNSRule, message *mDNS.Msg, options adapter.DNSQueryOptions, allowFakeIP bool) exchangeWithRulesResult {
+ metadata := adapter.ContextFrom(ctx)
+ if metadata == nil {
+ panic("no context")
+ }
+ effectiveOptions := options
+ var evaluatedResponse *mDNS.Msg
+ var evaluatedTransport adapter.DNSTransport
+ for currentRuleIndex, currentRule := range rules {
+ metadata.ResetRuleCache()
+ metadata.DNSResponse = evaluatedResponse
+ metadata.DestinationAddressMatchFromResponse = false
+ if !currentRule.Match(metadata) {
+ continue
}
- if !options.ClientSubnet.IsValid() {
- options.ClientSubnet = legacyTransport.LegacyClientSubnet()
+ r.logRuleMatch(ctx, currentRuleIndex, currentRule)
+ switch action := currentRule.Action().(type) {
+ case *R.RuleActionDNSRouteOptions:
+ r.applyDNSRouteOptions(&effectiveOptions, *action)
+ case *R.RuleActionEvaluate:
+ queryOptions := effectiveOptions
+ transport, loaded := r.transport.Transport(action.Server)
+ if !loaded {
+ r.logger.ErrorContext(ctx, "transport not found: ", action.Server)
+ evaluatedResponse = nil
+ evaluatedTransport = nil
+ continue
+ }
+ r.applyDNSRouteOptions(&queryOptions, action.RuleActionDNSRouteOptions)
+ exchangeOptions := queryOptions
+ if exchangeOptions.Strategy == C.DomainStrategyAsIS {
+ exchangeOptions.Strategy = r.defaultDomainStrategy
+ }
+ response, err := r.client.Exchange(adapter.OverrideContext(ctx), transport, message, exchangeOptions, nil)
+ if err != nil {
+ r.logger.ErrorContext(ctx, E.Cause(err, "exchange failed for ", FormatQuestion(message.Question[0].String())))
+ evaluatedResponse = nil
+ evaluatedTransport = nil
+ continue
+ }
+ evaluatedResponse = response
+ evaluatedTransport = transport
+ case *R.RuleActionRespond:
+ if evaluatedResponse == nil {
+ return exchangeWithRulesResult{
+ err: E.New(dnsRespondMissingResponseMessage),
+ }
+ }
+ return exchangeWithRulesResult{
+ response: evaluatedResponse,
+ transport: evaluatedTransport,
+ }
+ case *R.RuleActionDNSRoute:
+ queryOptions := effectiveOptions
+ transport, status := r.resolveDNSRoute(action.Server, action.RuleActionDNSRouteOptions, allowFakeIP, &queryOptions)
+ switch status {
+ case dnsRouteStatusMissing:
+ r.logger.ErrorContext(ctx, "transport not found: ", action.Server)
+ continue
+ case dnsRouteStatusSkipped:
+ continue
+ }
+ exchangeOptions := queryOptions
+ if exchangeOptions.Strategy == C.DomainStrategyAsIS {
+ exchangeOptions.Strategy = r.defaultDomainStrategy
+ }
+ response, err := r.client.Exchange(adapter.OverrideContext(ctx), transport, message, exchangeOptions, nil)
+ return exchangeWithRulesResult{
+ response: response,
+ transport: transport,
+ err: err,
+ }
+ case *R.RuleActionReject:
+ switch action.Method {
+ case C.RuleActionRejectMethodDefault:
+ return exchangeWithRulesResult{
+ response: &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Id: message.Id,
+ Rcode: mDNS.RcodeRefused,
+ Response: true,
+ },
+ Question: []mDNS.Question{message.Question[0]},
+ },
+ rejectAction: action,
+ }
+ case C.RuleActionRejectMethodDrop:
+ return exchangeWithRulesResult{
+ rejectAction: action,
+ err: tun.ErrDrop,
+ }
+ }
+ case *R.RuleActionPredefined:
+ return exchangeWithRulesResult{
+ response: action.Response(message),
+ }
}
}
- return transport, nil, -1
+ transport := r.transport.Default()
+ exchangeOptions := effectiveOptions
+ if exchangeOptions.Strategy == C.DomainStrategyAsIS {
+ exchangeOptions.Strategy = r.defaultDomainStrategy
+ }
+ response, err := r.client.Exchange(adapter.OverrideContext(ctx), transport, message, exchangeOptions, nil)
+ return exchangeWithRulesResult{
+ response: response,
+ transport: transport,
+ err: err,
+ }
+}
+
+func (r *Router) resolveLookupStrategy(options adapter.DNSQueryOptions) C.DomainStrategy {
+ if options.LookupStrategy != C.DomainStrategyAsIS {
+ return options.LookupStrategy
+ }
+ if options.Strategy != C.DomainStrategyAsIS {
+ return options.Strategy
+ }
+ return r.defaultDomainStrategy
+}
+
+func withLookupQueryMetadata(ctx context.Context, qType uint16) context.Context {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.QueryType = qType
+ metadata.IPVersion = 0
+ switch qType {
+ case mDNS.TypeA:
+ metadata.IPVersion = 4
+ case mDNS.TypeAAAA:
+ metadata.IPVersion = 6
+ }
+ return ctx
+}
+
+func filterAddressesByQueryType(addresses []netip.Addr, qType uint16) []netip.Addr {
+ switch qType {
+ case mDNS.TypeA:
+ return common.Filter(addresses, func(address netip.Addr) bool {
+ return address.Is4()
+ })
+ case mDNS.TypeAAAA:
+ return common.Filter(addresses, func(address netip.Addr) bool {
+ return address.Is6()
+ })
+ default:
+ return addresses
+ }
+}
+
+func (r *Router) lookupWithRules(ctx context.Context, rules []adapter.DNSRule, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, error) {
+ strategy := r.resolveLookupStrategy(options)
+ lookupOptions := options
+ if strategy != C.DomainStrategyAsIS {
+ lookupOptions.Strategy = strategy
+ }
+ if strategy == C.DomainStrategyIPv4Only {
+ return r.lookupWithRulesType(ctx, rules, domain, mDNS.TypeA, lookupOptions)
+ }
+ if strategy == C.DomainStrategyIPv6Only {
+ return r.lookupWithRulesType(ctx, rules, domain, mDNS.TypeAAAA, lookupOptions)
+ }
+ var (
+ response4 []netip.Addr
+ response6 []netip.Addr
+ )
+ var group task.Group
+ group.Append("exchange4", func(ctx context.Context) error {
+ result, err := r.lookupWithRulesType(ctx, rules, domain, mDNS.TypeA, lookupOptions)
+ response4 = result
+ return err
+ })
+ group.Append("exchange6", func(ctx context.Context) error {
+ result, err := r.lookupWithRulesType(ctx, rules, domain, mDNS.TypeAAAA, lookupOptions)
+ response6 = result
+ return err
+ })
+ err := group.Run(ctx)
+ if len(response4) == 0 && len(response6) == 0 {
+ return nil, err
+ }
+ return sortAddresses(response4, response6, strategy), nil
+}
+
+func (r *Router) lookupWithRulesType(ctx context.Context, rules []adapter.DNSRule, domain string, qType uint16, options adapter.DNSQueryOptions) ([]netip.Addr, error) {
+ request := &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ RecursionDesired: true,
+ },
+ Question: []mDNS.Question{{
+ Name: mDNS.Fqdn(domain),
+ Qtype: qType,
+ Qclass: mDNS.ClassINET,
+ }},
+ }
+ exchangeResult := r.exchangeWithRules(withLookupQueryMetadata(ctx, qType), rules, request, options, false)
+ if exchangeResult.rejectAction != nil {
+ return nil, exchangeResult.rejectAction.Error(ctx)
+ }
+ if exchangeResult.err != nil {
+ return nil, exchangeResult.err
+ }
+ if exchangeResult.response.Rcode != mDNS.RcodeSuccess {
+ return nil, RcodeError(exchangeResult.response.Rcode)
+ }
+ return filterAddressesByQueryType(MessageToAddresses(exchangeResult.response), qType), nil
}
func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapter.DNSQueryOptions) (*mDNS.Msg, error) {
@@ -220,6 +621,14 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
}
return &responseMessage, nil
}
+ r.rulesAccess.RLock()
+ if r.closing {
+ r.rulesAccess.RUnlock()
+ return nil, E.New("dns router closed")
+ }
+ rules := r.rules
+ legacyDNSMode := r.legacyDNSMode
+ r.rulesAccess.RUnlock()
r.logger.DebugContext(ctx, "exchange ", FormatQuestion(message.Question[0].String()))
var (
response *mDNS.Msg
@@ -230,6 +639,8 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
ctx, metadata = adapter.ExtendContext(ctx)
metadata.Destination = M.Socksaddr{}
metadata.QueryType = message.Question[0].Qtype
+ metadata.DNSResponse = nil
+ metadata.DestinationAddressMatchFromResponse = false
switch metadata.QueryType {
case mDNS.TypeA:
metadata.IPVersion = 4
@@ -239,18 +650,13 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
metadata.Domain = FqdnToDomain(message.Question[0].Name)
if options.Transport != nil {
transport = options.Transport
- if legacyTransport, isLegacy := transport.(adapter.LegacyDNSTransport); isLegacy {
- if options.Strategy == C.DomainStrategyAsIS {
- options.Strategy = legacyTransport.LegacyStrategy()
- }
- if !options.ClientSubnet.IsValid() {
- options.ClientSubnet = legacyTransport.LegacyClientSubnet()
- }
- }
if options.Strategy == C.DomainStrategyAsIS {
options.Strategy = r.defaultDomainStrategy
}
response, err = r.client.Exchange(ctx, transport, message, options, nil)
+ } else if !legacyDNSMode {
+ exchangeResult := r.exchangeWithRules(ctx, rules, message, options, true)
+ response, transport, err = exchangeResult.response, exchangeResult.transport, exchangeResult.err
} else {
var (
rule adapter.DNSRule
@@ -260,7 +666,7 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
for {
dnsCtx := adapter.OverrideContext(ctx)
dnsOptions := options
- transport, rule, ruleIndex = r.matchDNS(ctx, true, ruleIndex, isAddressQuery(message), &dnsOptions)
+ transport, rule, ruleIndex = r.matchDNS(ctx, rules, true, ruleIndex, isAddressQuery(message), &dnsOptions)
if rule != nil {
switch action := rule.Action().(type) {
case *R.RuleActionReject:
@@ -278,7 +684,9 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
return nil, tun.ErrDrop
}
case *R.RuleActionPredefined:
- return action.Response(message), nil
+ err = nil
+ response = action.Response(message)
+ goto done
}
}
responseCheck := addressLimitResponseCheck(rule, metadata)
@@ -287,25 +695,38 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
}
response, err = r.client.Exchange(dnsCtx, transport, message, dnsOptions, responseCheck)
var rejected bool
+ var bypass bool
if err != nil {
if errors.Is(err, ErrResponseRejectedCached) {
rejected = true
- r.logger.DebugContext(ctx, E.Cause(err, "response rejected for ", FormatQuestion(message.Question[0].String())), " (cached)")
+ r.logger.DebugContext(ctx, E.Cause(err, "response ", transport.Tag(), " rejected for ", FormatQuestion(message.Question[0].String())), " (cached)")
} else if errors.Is(err, ErrResponseRejected) {
rejected = true
- r.logger.DebugContext(ctx, E.Cause(err, "response rejected for ", FormatQuestion(message.Question[0].String())))
+ r.logger.DebugContext(ctx, E.Cause(err, "response ", transport.Tag(), " rejected for ", FormatQuestion(message.Question[0].String())))
} else if len(message.Question) > 0 {
- r.logger.ErrorContext(ctx, E.Cause(err, "exchange failed for ", FormatQuestion(message.Question[0].String())))
+ r.logger.ErrorContext(ctx, E.Cause(err, "exchange ", transport.Tag(), " failed for ", FormatQuestion(message.Question[0].String())))
} else {
- r.logger.ErrorContext(ctx, E.Cause(err, "exchange failed for "))
+ r.logger.ErrorContext(ctx, E.Cause(err, "exchange ", transport.Tag(), " failed for "))
+ }
+ if rule != nil && rule.BypassIfFailed() && ruleIndex != -1 {
+ select {
+ case <-ctx.Done():
+ default:
+ bypass = true
+ }
}
}
if responseCheck != nil && rejected {
continue
}
+ if bypass {
+ continue
+ }
+
break
}
}
+done:
if err != nil {
return nil, err
}
@@ -325,6 +746,14 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
}
func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, error) {
+ r.rulesAccess.RLock()
+ if r.closing {
+ r.rulesAccess.RUnlock()
+ return nil, E.New("dns router closed")
+ }
+ rules := r.rules
+ legacyDNSMode := r.legacyDNSMode
+ r.rulesAccess.RUnlock()
var (
responseAddrs []netip.Addr
err error
@@ -338,6 +767,8 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
r.logger.DebugContext(ctx, "response rejected for ", domain, " (cached)")
} else if errors.Is(err, ErrResponseRejected) {
r.logger.DebugContext(ctx, "response rejected for ", domain)
+ } else if R.IsRejected(err) {
+ r.logger.DebugContext(ctx, "lookup rejected for ", domain)
} else {
r.logger.ErrorContext(ctx, E.Cause(err, "lookup failed for ", domain))
}
@@ -350,20 +781,16 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
ctx, metadata := adapter.ExtendContext(ctx)
metadata.Destination = M.Socksaddr{}
metadata.Domain = FqdnToDomain(domain)
+ metadata.DNSResponse = nil
+ metadata.DestinationAddressMatchFromResponse = false
if options.Transport != nil {
transport := options.Transport
- if legacyTransport, isLegacy := transport.(adapter.LegacyDNSTransport); isLegacy {
- if options.Strategy == C.DomainStrategyAsIS {
- options.Strategy = legacyTransport.LegacyStrategy()
- }
- if !options.ClientSubnet.IsValid() {
- options.ClientSubnet = legacyTransport.LegacyClientSubnet()
- }
- }
if options.Strategy == C.DomainStrategyAsIS {
options.Strategy = r.defaultDomainStrategy
}
responseAddrs, err = r.client.Lookup(ctx, transport, domain, options, nil)
+ } else if !legacyDNSMode {
+ responseAddrs, err = r.lookupWithRules(ctx, rules, domain, options)
} else {
var (
transport adapter.DNSTransport
@@ -374,7 +801,7 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
for {
dnsCtx := adapter.OverrideContext(ctx)
dnsOptions := options
- transport, rule, ruleIndex = r.matchDNS(ctx, false, ruleIndex, true, &dnsOptions)
+ transport, rule, ruleIndex = r.matchDNS(ctx, rules, false, ruleIndex, true, &dnsOptions)
if rule != nil {
switch action := rule.Action().(type) {
case *R.RuleActionReject:
@@ -393,6 +820,8 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
responseAddrs = append(responseAddrs, M.AddrFromIP(record.AAAA))
}
}
+ responseAddrs = FilterBlocked(responseAddrs)
+
}
goto response
}
@@ -402,6 +831,9 @@ func (r *Router) Lookup(ctx context.Context, domain string, options adapter.DNSQ
dnsOptions.Strategy = r.defaultDomainStrategy
}
responseAddrs, err = r.client.Lookup(dnsCtx, transport, domain, dnsOptions, responseCheck)
+ if rule != nil && len(responseAddrs) == 0 && rule.BypassIfFailed() && ruleIndex != -1 {
+ continue
+ }
if responseCheck == nil || err == nil {
break
}
@@ -425,15 +857,14 @@ func isAddressQuery(message *mDNS.Msg) bool {
return false
}
-func addressLimitResponseCheck(rule adapter.DNSRule, metadata *adapter.InboundContext) func(responseAddrs []netip.Addr) bool {
+func addressLimitResponseCheck(rule adapter.DNSRule, metadata *adapter.InboundContext) func(response *mDNS.Msg) bool {
if rule == nil || !rule.WithAddressLimit() {
return nil
}
responseMetadata := *metadata
- return func(responseAddrs []netip.Addr) bool {
+ return func(response *mDNS.Msg) bool {
checkMetadata := responseMetadata
- checkMetadata.DestinationAddresses = responseAddrs
- return rule.MatchAddressLimit(&checkMetadata)
+ return rule.MatchAddressLimit(&checkMetadata, response)
}
}
@@ -458,3 +889,287 @@ func (r *Router) ResetNetwork() {
transport.Reset()
}
}
+
+func defaultRuleNeedsLegacyDNSModeFromAddressFilter(rule option.DefaultDNSRule) bool {
+ if rule.RuleSetIPCIDRAcceptEmpty { //nolint:staticcheck
+ return true
+ }
+ return !rule.MatchResponse && (rule.IPAcceptAny || len(rule.IPCIDR) > 0 || rule.IPIsPrivate)
+}
+
+func hasResponseMatchFields(rule option.DefaultDNSRule) bool {
+ return rule.ResponseRcode != nil ||
+ len(rule.ResponseAnswer) > 0 ||
+ len(rule.ResponseNs) > 0 ||
+ len(rule.ResponseExtra) > 0
+}
+
+func defaultRuleDisablesLegacyDNSMode(rule option.DefaultDNSRule) bool {
+ return rule.MatchResponse ||
+ hasResponseMatchFields(rule) ||
+ rule.Action == C.RuleActionTypeEvaluate ||
+ rule.Action == C.RuleActionTypeRespond ||
+ rule.IPVersion > 0 ||
+ len(rule.QueryType) > 0
+}
+
+type dnsRuleModeFlags struct {
+ disabled bool
+ needed bool
+ neededFromStrategy bool
+}
+
+func (f *dnsRuleModeFlags) merge(other dnsRuleModeFlags) {
+ f.disabled = f.disabled || other.disabled
+ f.needed = f.needed || other.needed
+ f.neededFromStrategy = f.neededFromStrategy || other.neededFromStrategy
+}
+
+func resolveLegacyDNSMode(router adapter.Router, rules []option.DNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (bool, dnsRuleModeFlags, error) {
+ flags, err := dnsRuleModeRequirements(router, rules, metadataOverrides)
+ if err != nil {
+ return false, flags, err
+ }
+ if flags.disabled && flags.neededFromStrategy {
+ return false, flags, E.New(deprecated.OptionLegacyDNSRuleStrategy.MessageWithLink())
+ }
+ if flags.disabled {
+ return false, flags, nil
+ }
+ return flags.needed, flags, nil
+}
+
+func dnsRuleModeRequirements(router adapter.Router, rules []option.DNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (dnsRuleModeFlags, error) {
+ var flags dnsRuleModeFlags
+ for i, rule := range rules {
+ ruleFlags, err := dnsRuleModeRequirementsInRule(router, rule, metadataOverrides)
+ if err != nil {
+ return dnsRuleModeFlags{}, E.Cause(err, "dns rule[", i, "]")
+ }
+ flags.merge(ruleFlags)
+ }
+ return flags, nil
+}
+
+func dnsRuleModeRequirementsInRule(router adapter.Router, rule option.DNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (dnsRuleModeFlags, error) {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ return dnsRuleModeRequirementsInDefaultRule(router, rule.DefaultOptions, metadataOverrides)
+ case C.RuleTypeLogical:
+ flags := dnsRuleModeFlags{
+ disabled: dnsRuleActionType(rule) == C.RuleActionTypeEvaluate ||
+ dnsRuleActionType(rule) == C.RuleActionTypeRespond ||
+ dnsRuleActionDisablesLegacyDNSMode(rule.LogicalOptions.DNSRuleAction),
+ neededFromStrategy: dnsRuleActionHasStrategy(rule.LogicalOptions.DNSRuleAction),
+ }
+ flags.needed = flags.neededFromStrategy
+ for i, subRule := range rule.LogicalOptions.Rules {
+ subFlags, err := dnsRuleModeRequirementsInRule(router, subRule, metadataOverrides)
+ if err != nil {
+ return dnsRuleModeFlags{}, E.Cause(err, "sub rule[", i, "]")
+ }
+ flags.merge(subFlags)
+ }
+ return flags, nil
+ default:
+ return dnsRuleModeFlags{}, nil
+ }
+}
+
+func dnsRuleModeRequirementsInDefaultRule(router adapter.Router, rule option.DefaultDNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (dnsRuleModeFlags, error) {
+ flags := dnsRuleModeFlags{
+ disabled: defaultRuleDisablesLegacyDNSMode(rule) || dnsRuleActionDisablesLegacyDNSMode(rule.DNSRuleAction),
+ neededFromStrategy: dnsRuleActionHasStrategy(rule.DNSRuleAction),
+ }
+ flags.needed = defaultRuleNeedsLegacyDNSModeFromAddressFilter(rule) || flags.neededFromStrategy
+ if len(rule.RuleSet) == 0 {
+ return flags, nil
+ }
+ if router == nil {
+ return dnsRuleModeFlags{}, E.New("router service not found")
+ }
+ for _, tag := range rule.RuleSet {
+ metadata, err := lookupDNSRuleSetMetadata(router, tag, metadataOverrides)
+ if err != nil {
+ return dnsRuleModeFlags{}, err
+ }
+ // ip_version is not a headless-rule item, so ContainsIPVersionRule is intentionally absent.
+ flags.disabled = flags.disabled || metadata.ContainsDNSQueryTypeRule
+ if !rule.RuleSetIPCIDRMatchSource && metadata.ContainsIPCIDRRule {
+ flags.needed = true
+ }
+ }
+ return flags, nil
+}
+
+func lookupDNSRuleSetMetadata(router adapter.Router, tag string, metadataOverrides map[string]adapter.RuleSetMetadata) (adapter.RuleSetMetadata, error) {
+ if metadataOverrides != nil {
+ if metadata, loaded := metadataOverrides[tag]; loaded {
+ return metadata, nil
+ }
+ }
+ ruleSet, loaded := router.RuleSet(tag)
+ if !loaded {
+ return adapter.RuleSetMetadata{}, E.New("rule-set not found: ", tag)
+ }
+ return ruleSet.Metadata(), nil
+}
+
+func referencedDNSRuleSetTags(rules []option.DNSRule) []string {
+ tagMap := make(map[string]bool)
+ var walkRule func(rule option.DNSRule)
+ walkRule = func(rule option.DNSRule) {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ for _, tag := range rule.DefaultOptions.RuleSet {
+ tagMap[tag] = true
+ }
+ case C.RuleTypeLogical:
+ for _, subRule := range rule.LogicalOptions.Rules {
+ walkRule(subRule)
+ }
+ }
+ }
+ for _, rule := range rules {
+ walkRule(rule)
+ }
+ tags := make([]string, 0, len(tagMap))
+ for tag := range tagMap {
+ if tag != "" {
+ tags = append(tags, tag)
+ }
+ }
+ return tags
+}
+
+func validateLegacyDNSModeDisabledRules(router adapter.Router, rules []option.DNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) error {
+ var seenEvaluate bool
+ for i, rule := range rules {
+ requiresPriorEvaluate, err := validateLegacyDNSModeDisabledRuleTree(router, rule, metadataOverrides)
+ if err != nil {
+ return E.Cause(err, "validate dns rule[", i, "]")
+ }
+ if requiresPriorEvaluate && !seenEvaluate {
+ return E.New("dns rule[", i, "]: response-based matching requires a preceding evaluate action")
+ }
+ if dnsRuleActionType(rule) == C.RuleActionTypeEvaluate {
+ seenEvaluate = true
+ }
+ }
+ return nil
+}
+
+func validateEvaluateFakeIPRules(rules []option.DNSRule, transportManager adapter.DNSTransportManager) error {
+ if transportManager == nil {
+ return nil
+ }
+ for i, rule := range rules {
+ if dnsRuleActionType(rule) != C.RuleActionTypeEvaluate {
+ continue
+ }
+ server := dnsRuleActionServer(rule)
+ if server == "" {
+ continue
+ }
+ transport, loaded := transportManager.Transport(server)
+ if !loaded || transport.Type() != C.DNSTypeFakeIP {
+ continue
+ }
+ return E.New("dns rule[", i, "]: evaluate action cannot use fakeip server: ", server)
+ }
+ return nil
+}
+
+func validateLegacyDNSModeDisabledRuleTree(router adapter.Router, rule option.DNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (bool, error) {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ return validateLegacyDNSModeDisabledDefaultRule(router, rule.DefaultOptions, metadataOverrides)
+ case C.RuleTypeLogical:
+ requiresPriorEvaluate := dnsRuleActionType(rule) == C.RuleActionTypeRespond
+ for i, subRule := range rule.LogicalOptions.Rules {
+ subRequiresPriorEvaluate, err := validateLegacyDNSModeDisabledRuleTree(router, subRule, metadataOverrides)
+ if err != nil {
+ return false, E.Cause(err, "sub rule[", i, "]")
+ }
+ requiresPriorEvaluate = requiresPriorEvaluate || subRequiresPriorEvaluate
+ }
+ return requiresPriorEvaluate, nil
+ default:
+ return false, nil
+ }
+}
+
+func validateLegacyDNSModeDisabledDefaultRule(router adapter.Router, rule option.DefaultDNSRule, metadataOverrides map[string]adapter.RuleSetMetadata) (bool, error) {
+ hasResponseRecords := hasResponseMatchFields(rule)
+ if (hasResponseRecords || len(rule.IPCIDR) > 0 || rule.IPIsPrivate || rule.IPAcceptAny) && !rule.MatchResponse {
+ return false, E.New("Response Match Fields (ip_cidr, ip_is_private, ip_accept_any, response_rcode, response_answer, response_ns, response_extra) require match_response to be enabled")
+ }
+ // rule_set entries are only rejected when every referenced set is pure-IP;
+ // mixed sets still fall through because their non-IP branches remain matchable
+ // before a DNS response is available.
+ if !rule.MatchResponse && len(rule.RuleSet) > 0 {
+ for _, tag := range rule.RuleSet {
+ metadata, err := lookupDNSRuleSetMetadata(router, tag, metadataOverrides)
+ if err != nil {
+ return false, err
+ }
+ if metadata.ContainsIPCIDRRule && !metadata.ContainsNonIPCIDRRule {
+ return false, E.New(deprecated.OptionLegacyDNSAddressFilter.MessageWithLink())
+ }
+ }
+ }
+ if rule.RuleSetIPCIDRAcceptEmpty { //nolint:staticcheck
+ return false, E.New(deprecated.OptionRuleSetIPCIDRAcceptEmpty.MessageWithLink())
+ }
+ return rule.MatchResponse || rule.Action == C.RuleActionTypeRespond, nil
+}
+
+func dnsRuleActionDisablesLegacyDNSMode(action option.DNSRuleAction) bool {
+ switch action.Action {
+ case "", C.RuleActionTypeRoute, C.RuleActionTypeEvaluate:
+ return action.RouteOptions.DisableOptimisticCache
+ case C.RuleActionTypeRouteOptions:
+ return action.RouteOptionsOptions.DisableOptimisticCache
+ default:
+ return false
+ }
+}
+
+func dnsRuleActionHasStrategy(action option.DNSRuleAction) bool {
+ switch action.Action {
+ case "", C.RuleActionTypeRoute, C.RuleActionTypeEvaluate:
+ return C.DomainStrategy(action.RouteOptions.Strategy) != C.DomainStrategyAsIS
+ case C.RuleActionTypeRouteOptions:
+ return C.DomainStrategy(action.RouteOptionsOptions.Strategy) != C.DomainStrategyAsIS
+ default:
+ return false
+ }
+}
+
+func dnsRuleActionType(rule option.DNSRule) string {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ if rule.DefaultOptions.Action == "" {
+ return C.RuleActionTypeRoute
+ }
+ return rule.DefaultOptions.Action
+ case C.RuleTypeLogical:
+ if rule.LogicalOptions.Action == "" {
+ return C.RuleActionTypeRoute
+ }
+ return rule.LogicalOptions.Action
+ default:
+ return ""
+ }
+}
+
+func dnsRuleActionServer(rule option.DNSRule) string {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ return rule.DefaultOptions.RouteOptions.Server
+ case C.RuleTypeLogical:
+ return rule.LogicalOptions.RouteOptions.Server
+ default:
+ return ""
+ }
+}
diff --git a/dns/router_test.go b/dns/router_test.go
new file mode 100644
index 0000000000..b5a7ebcfb5
--- /dev/null
+++ b/dns/router_test.go
@@ -0,0 +1,2670 @@
+package dns
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/experimental/deprecated"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ rulepkg "github.com/sagernet/sing-box/route/rule"
+ "github.com/sagernet/sing-tun"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json/badoption"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/x/list"
+ "github.com/sagernet/sing/service"
+
+ mDNS "github.com/miekg/dns"
+ "github.com/stretchr/testify/require"
+ "go4.org/netipx"
+)
+
+type fakeDNSTransport struct {
+ tag string
+ transportType string
+}
+
+func (t *fakeDNSTransport) Start(adapter.StartStage) error { return nil }
+func (t *fakeDNSTransport) Close() error { return nil }
+func (t *fakeDNSTransport) Type() string { return t.transportType }
+func (t *fakeDNSTransport) Tag() string { return t.tag }
+func (t *fakeDNSTransport) Dependencies() []string { return nil }
+func (t *fakeDNSTransport) Reset() {}
+func (t *fakeDNSTransport) Exchange(context.Context, *mDNS.Msg) (*mDNS.Msg, error) {
+ return nil, E.New("unused transport exchange")
+}
+
+type fakeDNSTransportManager struct {
+ defaultTransport adapter.DNSTransport
+ transports map[string]adapter.DNSTransport
+}
+
+func (m *fakeDNSTransportManager) Start(adapter.StartStage) error { return nil }
+func (m *fakeDNSTransportManager) Close() error { return nil }
+func (m *fakeDNSTransportManager) Transports() []adapter.DNSTransport {
+ transports := make([]adapter.DNSTransport, 0, len(m.transports))
+ for _, transport := range m.transports {
+ transports = append(transports, transport)
+ }
+ return transports
+}
+
+func (m *fakeDNSTransportManager) Transport(tag string) (adapter.DNSTransport, bool) {
+ transport, loaded := m.transports[tag]
+ return transport, loaded
+}
+func (m *fakeDNSTransportManager) Default() adapter.DNSTransport { return m.defaultTransport }
+func (m *fakeDNSTransportManager) FakeIP() adapter.FakeIPTransport {
+ return nil
+}
+func (m *fakeDNSTransportManager) Remove(string) error { return nil }
+func (m *fakeDNSTransportManager) Create(context.Context, log.ContextLogger, string, string, any) error {
+ return E.New("unsupported")
+}
+
+type fakeDNSClient struct {
+ beforeExchange func(ctx context.Context, transport adapter.DNSTransport, message *mDNS.Msg)
+ exchange func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error)
+ lookupWithCtx func(ctx context.Context, transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error)
+ lookup func(transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error)
+}
+
+type fakeDeprecatedManager struct {
+ features []deprecated.Note
+}
+
+type fakeRouter struct {
+ access sync.RWMutex
+ ruleSets map[string]adapter.RuleSet
+}
+
+func (r *fakeRouter) Start(adapter.StartStage) error { return nil }
+func (r *fakeRouter) Close() error { return nil }
+func (r *fakeRouter) PreMatch(metadata adapter.InboundContext, _ tun.DirectRouteContext, _ time.Duration, _ bool) (tun.DirectRouteDestination, error) {
+ return nil, nil
+}
+
+func (r *fakeRouter) RouteConnection(context.Context, net.Conn, adapter.InboundContext) error {
+ return nil
+}
+
+func (r *fakeRouter) RoutePacketConnection(context.Context, N.PacketConn, adapter.InboundContext) error {
+ return nil
+}
+
+func (r *fakeRouter) RouteConnectionEx(context.Context, net.Conn, adapter.InboundContext, N.CloseHandlerFunc) {
+}
+
+func (r *fakeRouter) RoutePacketConnectionEx(context.Context, N.PacketConn, adapter.InboundContext, N.CloseHandlerFunc) {
+}
+
+func (r *fakeRouter) RuleSet(tag string) (adapter.RuleSet, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ ruleSet, loaded := r.ruleSets[tag]
+ return ruleSet, loaded
+}
+
+func (r *fakeRouter) Rules() []adapter.Rule { return nil }
+func (r *fakeRouter) NeedFindProcess() bool { return false }
+func (r *fakeRouter) NeedFindNeighbor() bool { return false }
+func (r *fakeRouter) NeighborResolver() adapter.NeighborResolver { return nil }
+func (r *fakeRouter) AppendTracker(adapter.ConnectionTracker) {}
+func (r *fakeRouter) ResetNetwork() {}
+
+type fakeRuleSet struct {
+ access sync.Mutex
+ metadata adapter.RuleSetMetadata
+ metadataRead func(adapter.RuleSetMetadata) adapter.RuleSetMetadata
+ match func(*adapter.InboundContext) bool
+ callbacks list.List[adapter.RuleSetUpdateCallback]
+ refs int
+ afterIncrementReference func()
+ beforeDecrementReference func()
+}
+
+func (s *fakeRuleSet) Name() string { return "fake-rule-set" }
+func (s *fakeRuleSet) StartContext(context.Context, *adapter.HTTPStartContext) error { return nil }
+func (s *fakeRuleSet) PostStart() error { return nil }
+func (s *fakeRuleSet) Metadata() adapter.RuleSetMetadata {
+ s.access.Lock()
+ metadata := s.metadata
+ metadataRead := s.metadataRead
+ s.access.Unlock()
+ if metadataRead != nil {
+ return metadataRead(metadata)
+ }
+ return metadata
+}
+func (s *fakeRuleSet) ExtractIPSet() []*netipx.IPSet { return nil }
+func (s *fakeRuleSet) IncRef() {
+ s.access.Lock()
+ s.refs++
+ afterIncrementReference := s.afterIncrementReference
+ s.access.Unlock()
+ if afterIncrementReference != nil {
+ afterIncrementReference()
+ }
+}
+
+func (s *fakeRuleSet) DecRef() {
+ s.access.Lock()
+ beforeDecrementReference := s.beforeDecrementReference
+ s.access.Unlock()
+ if beforeDecrementReference != nil {
+ beforeDecrementReference()
+ }
+ s.access.Lock()
+ defer s.access.Unlock()
+ s.refs--
+ if s.refs < 0 {
+ panic("rule-set: negative refs")
+ }
+}
+func (s *fakeRuleSet) Cleanup() {}
+func (s *fakeRuleSet) RegisterCallback(callback adapter.RuleSetUpdateCallback) *list.Element[adapter.RuleSetUpdateCallback] {
+ s.access.Lock()
+ defer s.access.Unlock()
+ return s.callbacks.PushBack(callback)
+}
+
+func (s *fakeRuleSet) UnregisterCallback(element *list.Element[adapter.RuleSetUpdateCallback]) {
+ s.access.Lock()
+ defer s.access.Unlock()
+ s.callbacks.Remove(element)
+}
+func (s *fakeRuleSet) Close() error { return nil }
+func (s *fakeRuleSet) Match(metadata *adapter.InboundContext) bool {
+ s.access.Lock()
+ match := s.match
+ s.access.Unlock()
+ if match != nil {
+ return match(metadata)
+ }
+ return true
+}
+func (s *fakeRuleSet) String() string { return "fake-rule-set" }
+func (s *fakeRuleSet) updateMetadata(metadata adapter.RuleSetMetadata) {
+ s.access.Lock()
+ s.metadata = metadata
+ callbacks := s.callbacks.Array()
+ s.access.Unlock()
+ for _, callback := range callbacks {
+ callback(s)
+ }
+}
+
+func (s *fakeRuleSet) refCount() int {
+ s.access.Lock()
+ defer s.access.Unlock()
+ return s.refs
+}
+
+func (m *fakeDeprecatedManager) ReportDeprecated(feature deprecated.Note) {
+ m.features = append(m.features, feature)
+}
+
+func (c *fakeDNSClient) Start() {}
+
+func (c *fakeDNSClient) Exchange(ctx context.Context, transport adapter.DNSTransport, message *mDNS.Msg, _ adapter.DNSQueryOptions, _ func(*mDNS.Msg) bool) (*mDNS.Msg, error) {
+ if c.beforeExchange != nil {
+ c.beforeExchange(ctx, transport, message)
+ }
+ if c.exchange == nil {
+ if len(message.Question) != 1 {
+ return nil, E.New("unused client exchange")
+ }
+ var (
+ addresses []netip.Addr
+ response *mDNS.Msg
+ err error
+ )
+ if c.lookupWithCtx != nil {
+ addresses, response, err = c.lookupWithCtx(ctx, transport, FqdnToDomain(message.Question[0].Name), adapter.DNSQueryOptions{})
+ } else if c.lookup != nil {
+ addresses, response, err = c.lookup(transport, FqdnToDomain(message.Question[0].Name), adapter.DNSQueryOptions{})
+ } else {
+ return nil, E.New("unused client exchange")
+ }
+ if err != nil {
+ return nil, err
+ }
+ if response != nil {
+ return response, nil
+ }
+ return FixedResponse(0, message.Question[0], addresses, 60), nil
+ }
+ return c.exchange(transport, message)
+}
+
+func (c *fakeDNSClient) Lookup(ctx context.Context, transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions, responseChecker func(*mDNS.Msg) bool) ([]netip.Addr, error) {
+ if c.lookup == nil && c.lookupWithCtx == nil {
+ return nil, E.New("unused client lookup")
+ }
+ var (
+ addresses []netip.Addr
+ response *mDNS.Msg
+ err error
+ )
+ if c.lookupWithCtx != nil {
+ addresses, response, err = c.lookupWithCtx(ctx, transport, domain, options)
+ } else {
+ addresses, response, err = c.lookup(transport, domain, options)
+ }
+ if err != nil {
+ return nil, err
+ }
+ if response == nil {
+ response = FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), addresses, 60)
+ }
+ if responseChecker != nil && !responseChecker(response) {
+ return nil, ErrResponseRejected
+ }
+ if addresses != nil {
+ return addresses, nil
+ }
+ return MessageToAddresses(response), nil
+}
+
+func (c *fakeDNSClient) ClearCache() {}
+
+func newTestRouter(t *testing.T, rules []option.DNSRule, transportManager *fakeDNSTransportManager, client *fakeDNSClient) *Router {
+ router := newTestRouterWithContext(t, context.Background(), rules, transportManager, client)
+ t.Cleanup(func() {
+ router.Close()
+ })
+ return router
+}
+
+func newTestRouterWithContext(t *testing.T, ctx context.Context, rules []option.DNSRule, transportManager *fakeDNSTransportManager, client *fakeDNSClient) *Router {
+ return newTestRouterWithContextAndLogger(t, ctx, rules, transportManager, client, log.NewNOPFactory().NewLogger("dns"))
+}
+
+func newTestRouterWithContextAndLogger(t *testing.T, ctx context.Context, rules []option.DNSRule, transportManager *fakeDNSTransportManager, client *fakeDNSClient, dnsLogger log.ContextLogger) *Router {
+ t.Helper()
+ router := &Router{
+ ctx: ctx,
+ logger: dnsLogger,
+ transport: transportManager,
+ client: client,
+ rawRules: make([]option.DNSRule, 0, len(rules)),
+ rules: make([]adapter.DNSRule, 0, len(rules)),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ if rules != nil {
+ err := router.Initialize(rules)
+ require.NoError(t, err)
+ err = router.Start(adapter.StartStateStart)
+ require.NoError(t, err)
+ }
+ return router
+}
+
+func fixedQuestion(name string, qType uint16) mDNS.Question {
+ return mDNS.Question{
+ Name: mDNS.Fqdn(name),
+ Qtype: qType,
+ Qclass: mDNS.ClassINET,
+ }
+}
+
+func mustRecord(t *testing.T, record string) option.DNSRecordOptions {
+ t.Helper()
+ var value option.DNSRecordOptions
+ require.NoError(t, value.UnmarshalJSON([]byte(`"`+record+`"`)))
+ return value
+}
+
+func TestInitializeRejectsDirectLegacyRuleWhenRuleSetForcesNew(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+ ruleSet, err := rulepkg.NewRuleSet(ctx, log.NewNOPFactory().NewLogger("router"), option.RuleSet{
+ Type: C.RuleSetTypeInline,
+ Tag: "query-set",
+ InlineOptions: option.PlainRuleSet{
+ Rules: []option.HeadlessRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultHeadlessRule{
+ QueryType: badoption.Listable[option.DNSQueryType]{option.DNSQueryType(mDNS.TypeA)},
+ },
+ }},
+ },
+ })
+ require.NoError(t, err)
+ ctx = service.ContextWith[adapter.Router](ctx, &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "query-set": ruleSet,
+ },
+ })
+
+ router := &Router{
+ ctx: ctx,
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 2),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err = router.Initialize([]option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"query-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPIsPrivate: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "private"},
+ },
+ },
+ },
+ })
+ require.ErrorContains(t, err, "Response Match Fields")
+ require.ErrorContains(t, err, "require match_response")
+}
+
+func TestLookupLegacyDNSModeDefersRuleSetDestinationIPMatch(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+ ruleSet, err := rulepkg.NewRuleSet(ctx, log.NewNOPFactory().NewLogger("router"), option.RuleSet{
+ Type: C.RuleSetTypeInline,
+ Tag: "legacy-ipcidr-set",
+ InlineOptions: option.PlainRuleSet{
+ Rules: []option.HeadlessRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultHeadlessRule{
+ IPCIDR: badoption.Listable[string]{"10.0.0.0/8"},
+ },
+ }},
+ },
+ })
+ require.NoError(t, err)
+ ctx = service.ContextWith[adapter.Router](ctx, &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "legacy-ipcidr-set": ruleSet,
+ },
+ })
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ privateTransport := &fakeDNSTransport{tag: "private", transportType: C.DNSTypeUDP}
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"legacy-ipcidr-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "private"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "private": privateTransport,
+ },
+ }, &fakeDNSClient{
+ lookup: func(transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ require.Equal(t, "example.com", domain)
+ require.Equal(t, "private", transport.Tag())
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("10.0.0.1")}, 60)
+ return MessageToAddresses(response), response, nil
+ },
+ })
+
+ require.True(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
+ LookupStrategy: C.DomainStrategyIPv4Only,
+ })
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("10.0.0.1")}, addresses)
+}
+
+func TestRuleSetUpdateReleasesOldRuleSetRefs(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{}
+ ctx := service.ContextWith[adapter.Router](context.Background(), &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ })
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{})
+
+ require.Equal(t, 1, fakeSet.refCount())
+
+ fakeSet.updateMetadata(adapter.RuleSetMetadata{})
+ require.Equal(t, 1, fakeSet.refCount())
+
+ fakeSet.updateMetadata(adapter.RuleSetMetadata{})
+ require.Equal(t, 1, fakeSet.refCount())
+
+ require.NoError(t, router.Close())
+ require.Zero(t, fakeSet.refCount())
+}
+
+func TestValidateRuleSetMetadataUpdateRejectsRuleSetThatWouldDisableLegacyDNSMode(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPIsPrivate: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ lookup: func(adapter.DNSTransport, string, adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ return []netip.Addr{netip.MustParseAddr("10.0.0.1")}, nil, nil
+ },
+ })
+ require.True(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{
+ ContainsDNSQueryTypeRule: true,
+ })
+ require.ErrorContains(t, err, "require match_response")
+}
+
+func TestValidateRuleSetMetadataUpdateRejectsRuleSetOnlyLegacyModeSwitchToNew(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ lookup: func(adapter.DNSTransport, string, adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ return []netip.Addr{netip.MustParseAddr("10.0.0.1")}, nil, nil
+ },
+ })
+ require.True(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ ContainsDNSQueryTypeRule: true,
+ })
+ require.ErrorContains(t, err, "Address Filter Fields")
+}
+
+func TestValidateRuleSetMetadataUpdateBeforeStartUsesStartupValidation(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{}
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := &Router{
+ ctx: ctx,
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 2),
+ rules: make([]adapter.DNSRule, 0, 2),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPIsPrivate: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ })
+ require.NoError(t, err)
+ require.False(t, router.started)
+
+ err = router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{
+ ContainsDNSQueryTypeRule: true,
+ })
+ require.ErrorContains(t, err, "require match_response")
+}
+
+func TestValidateRuleSetMetadataUpdateRejectsRuleSetThatWouldRequireLegacyDNSMode(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{}
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ lookup: func(adapter.DNSTransport, string, adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ return []netip.Addr{netip.MustParseAddr("1.1.1.1")}, nil, nil
+ },
+ })
+ require.False(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ })
+ require.ErrorContains(t, err, "Address Filter Fields")
+}
+
+func TestValidateRuleSetMetadataUpdateAllowsRuleSetThatKeepsNonLegacyDNSMode(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{}
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ ContainsNonIPCIDRRule: true,
+ })
+ require.NoError(t, err)
+}
+
+func TestValidateRuleSetMetadataUpdateAllowsRelaxingLegacyRequirement(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "dynamic-set": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"dynamic-set"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ lookup: func(adapter.DNSTransport, string, adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ return []netip.Addr{netip.MustParseAddr("10.0.0.1")}, nil, nil
+ },
+ })
+ require.True(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("dynamic-set", adapter.RuleSetMetadata{})
+ require.NoError(t, err)
+}
+
+func TestInitializeRejectsPureIPRuleSetWhenLegacyDNSModeDisabled(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "pure-ip": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := &Router{
+ ctx: ctx,
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 2),
+ rules: make([]adapter.DNSRule, 0, 2),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ QueryType: badoption.Listable[option.DNSQueryType]{option.DNSQueryType(mDNS.TypeA)},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"pure-ip"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ })
+ require.ErrorContains(t, err, "Address Filter Fields")
+}
+
+func TestInitializeAllowsMixedRuleSetWhenLegacyDNSModeDisabled(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ ContainsNonIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "mixed": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ QueryType: badoption.Listable[option.DNSQueryType]{option.DNSQueryType(mDNS.TypeA)},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"mixed"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+}
+
+func TestValidateRuleSetMetadataUpdateRejectsRuleSetFlippingToPureIP(t *testing.T) {
+ t.Parallel()
+
+ fakeSet := &fakeRuleSet{
+ metadata: adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ ContainsNonIPCIDRRule: true,
+ },
+ }
+ routerService := &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "mixed": fakeSet,
+ },
+ }
+ ctx := service.ContextWith[adapter.Router](context.Background(), routerService)
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ QueryType: badoption.Listable[option.DNSQueryType]{option.DNSQueryType(mDNS.TypeA)},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"mixed"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ err := router.ValidateRuleSetMetadataUpdate("mixed", adapter.RuleSetMetadata{
+ ContainsIPCIDRRule: true,
+ })
+ require.ErrorContains(t, err, "Address Filter Fields")
+}
+
+func TestCloseWaitsForInFlightLookupUntilContextCancellation(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ selectedTransport := &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP}
+ lookupStarted := make(chan struct{})
+ var lookupStartedOnce sync.Once
+ router := newTestRouter(t, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "selected": selectedTransport,
+ },
+ }, &fakeDNSClient{
+ lookupWithCtx: func(ctx context.Context, transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ require.Equal(t, "selected", transport.Tag())
+ require.Equal(t, "example.com", domain)
+ lookupStartedOnce.Do(func() {
+ close(lookupStarted)
+ })
+ <-ctx.Done()
+ return nil, nil, ctx.Err()
+ },
+ })
+
+ lookupCtx, cancelLookup := context.WithCancel(context.Background())
+ defer cancelLookup()
+ var (
+ lookupErr error
+ closeErr error
+ )
+ lookupDone := make(chan struct{})
+ go func() {
+ _, lookupErr = router.Lookup(lookupCtx, "example.com", adapter.DNSQueryOptions{})
+ close(lookupDone)
+ }()
+
+ select {
+ case <-lookupStarted:
+ case <-time.After(time.Second):
+ t.Fatal("lookup did not reach DNS client")
+ }
+
+ closeDone := make(chan struct{})
+ go func() {
+ closeErr = router.Close()
+ close(closeDone)
+ }()
+
+ select {
+ case <-closeDone:
+ t.Fatal("close finished before lookup context cancellation")
+ default:
+ }
+
+ cancelLookup()
+
+ select {
+ case <-lookupDone:
+ case <-time.After(time.Second):
+ t.Fatal("lookup did not finish after cancellation")
+ }
+ select {
+ case <-closeDone:
+ case <-time.After(time.Second):
+ t.Fatal("close did not finish after lookup cancellation")
+ }
+
+ require.ErrorIs(t, lookupErr, context.Canceled)
+ require.NoError(t, closeErr)
+}
+
+func TestLookupLegacyDNSModeDefersDirectDestinationIPMatch(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ privateTransport := &fakeDNSTransport{tag: "private", transportType: C.DNSTypeUDP}
+ client := &fakeDNSClient{
+ lookup: func(transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ require.Equal(t, "example.com", domain)
+ require.Equal(t, C.DomainStrategyIPv4Only, options.LookupStrategy)
+ switch transport.Tag() {
+ case "private":
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("10.0.0.1")}, 60)
+ return MessageToAddresses(response), response, nil
+ case "default":
+ t.Fatal("default transport should not be used when legacy rule matches after response")
+ }
+ return nil, nil, E.New("unexpected transport")
+ },
+ }
+ router := newTestRouter(t, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPIsPrivate: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "private"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "private": privateTransport,
+ },
+ }, client)
+
+ require.True(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
+ LookupStrategy: C.DomainStrategyIPv4Only,
+ })
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("10.0.0.1")}, addresses)
+}
+
+func TestLookupLegacyDNSModeFallsBackAfterRejectedAddressLimitResponse(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ privateTransport := &fakeDNSTransport{tag: "private", transportType: C.DNSTypeUDP}
+ var lookupAccess sync.Mutex
+ var lookupTags []string
+ recordLookup := func(tag string) {
+ lookupAccess.Lock()
+ lookupTags = append(lookupTags, tag)
+ lookupAccess.Unlock()
+ }
+ currentLookupTags := func() []string {
+ lookupAccess.Lock()
+ defer lookupAccess.Unlock()
+ return append([]string(nil), lookupTags...)
+ }
+ client := &fakeDNSClient{
+ lookup: func(transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ require.Equal(t, "example.com", domain)
+ require.Equal(t, C.DomainStrategyIPv4Only, options.LookupStrategy)
+ recordLookup(transport.Tag())
+ switch transport.Tag() {
+ case "private":
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60)
+ return MessageToAddresses(response), response, nil
+ case "default":
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("9.9.9.9")}, 60)
+ return MessageToAddresses(response), response, nil
+ }
+ return nil, nil, E.New("unexpected transport")
+ },
+ }
+ router := newTestRouter(t, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPIsPrivate: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "private"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "private": privateTransport,
+ },
+ }, client)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
+ LookupStrategy: C.DomainStrategyIPv4Only,
+ })
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("9.9.9.9")}, addresses)
+ require.Equal(t, []string{"private", "default"}, currentLookupTags())
+}
+
+func TestLookupLegacyDNSModeRuleSetAcceptEmptyDoesNotTreatMismatchAsEmpty(t *testing.T) {
+ t.Parallel()
+
+ ctx := context.Background()
+ ruleSet, err := rulepkg.NewRuleSet(ctx, log.NewNOPFactory().NewLogger("router"), option.RuleSet{
+ Type: C.RuleSetTypeInline,
+ Tag: "legacy-ipcidr-set",
+ InlineOptions: option.PlainRuleSet{
+ Rules: []option.HeadlessRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultHeadlessRule{
+ IPCIDR: badoption.Listable[string]{"10.0.0.0/8"},
+ },
+ }},
+ },
+ })
+ require.NoError(t, err)
+ ctx = service.ContextWith[adapter.Router](ctx, &fakeRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "legacy-ipcidr-set": ruleSet,
+ },
+ })
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ privateTransport := &fakeDNSTransport{tag: "private", transportType: C.DNSTypeUDP}
+ var lookupAccess sync.Mutex
+ var lookupTags []string
+ recordLookup := func(tag string) {
+ lookupAccess.Lock()
+ lookupTags = append(lookupTags, tag)
+ lookupAccess.Unlock()
+ }
+ currentLookupTags := func() []string {
+ lookupAccess.Lock()
+ defer lookupAccess.Unlock()
+ return append([]string(nil), lookupTags...)
+ }
+ router := newTestRouterWithContext(t, ctx, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ RuleSet: badoption.Listable[string]{"legacy-ipcidr-set"},
+ RuleSetIPCIDRAcceptEmpty: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "private"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "private": privateTransport,
+ },
+ }, &fakeDNSClient{
+ lookup: func(transport adapter.DNSTransport, domain string, options adapter.DNSQueryOptions) ([]netip.Addr, *mDNS.Msg, error) {
+ require.Equal(t, "example.com", domain)
+ require.Equal(t, C.DomainStrategyIPv4Only, options.LookupStrategy)
+ recordLookup(transport.Tag())
+ switch transport.Tag() {
+ case "private":
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60)
+ return MessageToAddresses(response), response, nil
+ case "default":
+ response := FixedResponse(0, fixedQuestion(domain, mDNS.TypeA), []netip.Addr{netip.MustParseAddr("9.9.9.9")}, 60)
+ return MessageToAddresses(response), response, nil
+ }
+ return nil, nil, E.New("unexpected transport")
+ },
+ })
+
+ require.True(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{
+ LookupStrategy: C.DomainStrategyIPv4Only,
+ })
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("9.9.9.9")}, addresses)
+ require.Equal(t, []string{"private", "default"}, currentLookupTags())
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateMatchResponseRoute(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateMatchResponseRcodeRoute(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Rcode: mDNS.RcodeNameError,
+ },
+ Question: []mDNS.Question{message.Question[0]},
+ }, nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rcode := option.DNSRCode(mDNS.RcodeNameError)
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseRcode: &rcode,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateMatchResponseNsRoute(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ nsRecord := mustRecord(t, "example.com. IN NS ns1.example.com.")
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Rcode: mDNS.RcodeSuccess,
+ },
+ Question: []mDNS.Question{message.Question[0]},
+ Ns: []mDNS.RR{nsRecord.Build()},
+ }, nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseNs: badoption.Listable[option.DNSRecordOptions]{nsRecord},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateMatchResponseExtraRoute(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ extraRecord := mustRecord(t, "ns1.example.com. IN A 192.0.2.53")
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Rcode: mDNS.RcodeSuccess,
+ },
+ Question: []mDNS.Question{message.Question[0]},
+ Extra: []mDNS.RR{extraRecord.Build()},
+ }, nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseExtra: badoption.Listable[option.DNSRecordOptions]{extraRecord},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateDoesNotLeakAddressesToNextQuery(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ var inspectedSelected bool
+ client := &fakeDNSClient{
+ beforeExchange: func(ctx context.Context, transport adapter.DNSTransport, message *mDNS.Msg) {
+ if transport.Tag() != "selected" {
+ return
+ }
+ inspectedSelected = true
+ metadata := adapter.ContextFrom(ctx)
+ require.NotNil(t, metadata)
+ require.Empty(t, metadata.DestinationAddresses)
+ require.NotNil(t, metadata.DNSResponse)
+ },
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.True(t, inspectedSelected)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateRouteResolutionFailureClearsResponse(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ case "default":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("4.4.4.4")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "missing"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("4.4.4.4")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledSecondEvaluateOverwritesFirstResponse(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "first-upstream": &fakeDNSTransport{tag: "first-upstream", transportType: C.DNSTypeUDP},
+ "second-upstream": &fakeDNSTransport{tag: "second-upstream", transportType: C.DNSTypeUDP},
+ "first-match": &fakeDNSTransport{tag: "first-match", transportType: C.DNSTypeUDP},
+ "second-match": &fakeDNSTransport{tag: "second-match", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "first-upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case "second-upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2.2.2.2")}, 60), nil
+ case "first-match":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("7.7.7.7")}, 60), nil
+ case "second-match":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ case "default":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("4.4.4.4")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "first-upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "second-upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "first-match"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 2.2.2.2")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "second-match"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("8.8.8.8")}, MessageToAddresses(response))
+}
+
+func TestExchangeLegacyDNSModeDisabledEvaluateExchangeFailureUsesMatchResponseBooleanSemantics(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ invert bool
+ expectedAddr netip.Addr
+ }{
+ {
+ name: "plain match_response rule stays false",
+ expectedAddr: netip.MustParseAddr("4.4.4.4"),
+ },
+ {
+ name: "invert match_response rule becomes true",
+ invert: true,
+ expectedAddr: netip.MustParseAddr("8.8.8.8"),
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return nil, E.New("upstream exchange failed")
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ case "default":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("4.4.4.4")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ Invert: testCase.invert,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{testCase.expectedAddr}, MessageToAddresses(response))
+ })
+ }
+}
+
+func TestExchangeLegacyDNSModeDisabledRespondReturnsEvaluatedResponse(t *testing.T) {
+ t.Parallel()
+
+ var exchanges []string
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRespond,
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ exchanges = append(exchanges, transport.Tag())
+ require.Equal(t, "upstream", transport.Tag())
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ },
+ })
+ require.False(t, router.legacyDNSMode)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []string{"upstream"}, exchanges)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, MessageToAddresses(response))
+}
+
+func TestLookupLegacyDNSModeDisabledRespondReturnsEvaluatedResponse(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRespond,
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Equal(t, "upstream", transport.Tag())
+ switch message.Question[0].Qtype {
+ case mDNS.TypeA:
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case mDNS.TypeAAAA:
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2001:db8::1")}, 60), nil
+ default:
+ return nil, E.New("unexpected qtype")
+ }
+ },
+ })
+ require.False(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{
+ netip.MustParseAddr("1.1.1.1"),
+ netip.MustParseAddr("2001:db8::1"),
+ }, addresses)
+}
+
+func TestExchangeLegacyDNSModeDisabledRespondWithoutEvaluatedResponseReturnsError(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRespond,
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, _ *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Equal(t, "upstream", transport.Tag())
+ return nil, E.New("upstream exchange failed")
+ },
+ })
+ require.False(t, router.legacyDNSMode)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.Nil(t, response)
+ require.ErrorContains(t, err, dnsRespondMissingResponseMessage)
+}
+
+func TestLookupLegacyDNSModeDisabledAllowsPartialSuccessForExchangeFailure(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, nil, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Equal(t, "default", transport.Tag())
+ switch message.Question[0].Qtype {
+ case mDNS.TypeA:
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case mDNS.TypeAAAA:
+ return nil, E.New("ipv6 failed")
+ default:
+ return nil, E.New("unexpected qtype")
+ }
+ },
+ })
+ router.legacyDNSMode = false
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, addresses)
+}
+
+func TestLookupLegacyDNSModeDisabledAllowsPartialSuccessForRcodeError(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, nil, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Equal(t, "default", transport.Tag())
+ switch message.Question[0].Qtype {
+ case mDNS.TypeA:
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("1.1.1.1")}, 60), nil
+ case mDNS.TypeAAAA:
+ return &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Rcode: mDNS.RcodeNameError,
+ },
+ Question: []mDNS.Question{message.Question[0]},
+ }, nil
+ default:
+ return nil, E.New("unexpected qtype")
+ }
+ },
+ })
+ router.legacyDNSMode = false
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("1.1.1.1")}, addresses)
+}
+
+func TestLookupLegacyDNSModeDisabledSkipsFakeIPRule(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "fake"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ "fake": &fakeDNSTransport{tag: "fake", transportType: C.DNSTypeFakeIP},
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Equal(t, "default", transport.Tag())
+ if message.Question[0].Qtype == mDNS.TypeA {
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("2.2.2.2")}, 60), nil
+ }
+ return FixedResponse(0, message.Question[0], nil, 60), nil
+ },
+ })
+ router.legacyDNSMode = false
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("2.2.2.2")}, addresses)
+}
+
+func TestExchangeLegacyDNSModeDisabledAllowsRouteFakeIPRule(t *testing.T) {
+ t.Parallel()
+
+ fakeTransport := &fakeDNSTransport{tag: "fake", transportType: C.DNSTypeFakeIP}
+ router := newTestRouter(t, []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "fake"},
+ },
+ },
+ }}, &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ "fake": fakeTransport,
+ },
+ }, &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ require.Same(t, fakeTransport, transport)
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("198.18.0.1")}, 60), nil
+ },
+ })
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("198.18.0.1")}, MessageToAddresses(response))
+}
+
+func TestInitializeRejectsDNSRuleStrategyWhenLegacyDNSModeIsDisabledByEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{
+ Server: "default",
+ Strategy: option.DomainStrategy(C.DomainStrategyIPv4Only),
+ },
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "strategy")
+ require.ErrorContains(t, err, "deprecated")
+}
+
+func TestInitializeRejectsEvaluateFakeIPServerInDefaultRule(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{transports: map[string]adapter.DNSTransport{"fake": &fakeDNSTransport{tag: "fake", transportType: C.DNSTypeFakeIP}}},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "fake"},
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "evaluate action cannot use fakeip server")
+ require.ErrorContains(t, err, "fake")
+}
+
+func TestInitializeRejectsEvaluateFakeIPServerInLogicalRule(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{transports: map[string]adapter.DNSTransport{"fake": &fakeDNSTransport{tag: "fake", transportType: C.DNSTypeFakeIP}}},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ },
+ }},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "fake"},
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "evaluate action cannot use fakeip server")
+ require.ErrorContains(t, err, "fake")
+}
+
+func TestInitializeRejectsDNSRuleStrategyWhenLegacyDNSModeIsDisabledByMatchResponse(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRouteOptions,
+ RouteOptionsOptions: option.DNSRouteOptionsActionOptions{
+ Strategy: option.DomainStrategy(C.DomainStrategyIPv4Only),
+ },
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "strategy")
+ require.ErrorContains(t, err, "deprecated")
+}
+
+func TestInitializeRejectsDNSMatchResponseWithoutPrecedingEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "preceding evaluate action")
+}
+
+func TestInitializeRejectsDNSRespondWithoutPrecedingEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRespond,
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "preceding evaluate action")
+}
+
+func TestInitializeRejectsLogicalDNSRespondWithoutPrecedingEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ },
+ }},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRespond,
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "preceding evaluate action")
+}
+
+func TestInitializeRejectsEvaluateRuleWithResponseMatchWithoutPrecedingEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 1),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ },
+ },
+ },
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ }})
+ require.ErrorContains(t, err, "preceding evaluate action")
+}
+
+func TestInitializeAllowsEvaluateRuleWithResponseMatchAfterPrecedingEvaluate(t *testing.T) {
+ t.Parallel()
+
+ router := &Router{
+ ctx: context.Background(),
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ transport: &fakeDNSTransportManager{},
+ client: &fakeDNSClient{},
+ rawRules: make([]option.DNSRule, 0, 2),
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"bootstrap.example"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "bootstrap"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ ResponseAnswer: badoption.Listable[option.DNSRecordOptions]{mustRecord(t, "example.com. IN A 1.1.1.1")},
+ },
+ },
+ },
+ },
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ },
+ })
+ require.NoError(t, err)
+}
+
+func TestLookupLegacyDNSModeDisabledReturnsRejectedErrorForRejectAction(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeReject,
+ RejectOptions: option.RejectActionOptions{
+ Method: C.RuleActionRejectMethodDefault,
+ },
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.Nil(t, addresses)
+ require.Error(t, err)
+ require.True(t, rulepkg.IsRejected(err))
+}
+
+func TestExchangeLegacyDNSModeDisabledReturnsRefusedResponseForRejectAction(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeReject,
+ RejectOptions: option.RejectActionOptions{
+ Method: C.RuleActionRejectMethodDefault,
+ },
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, mDNS.RcodeRefused, response.Rcode)
+ require.Equal(t, []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)}, response.Question)
+}
+
+func TestExchangeLegacyDNSModeDisabledReturnsDropErrorForRejectDropAction(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeReject,
+ RejectOptions: option.RejectActionOptions{
+ Method: C.RuleActionRejectMethodDrop,
+ },
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.Nil(t, response)
+ require.ErrorIs(t, err, tun.ErrDrop)
+}
+
+func TestLookupLegacyDNSModeDisabledFiltersPerQueryTypeAddressesBeforeMerging(t *testing.T) {
+ t.Parallel()
+
+ defaultTransport := &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP}
+ router := newTestRouter(t, []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypePredefined,
+ PredefinedOptions: option.DNSRouteActionPredefined{
+ Answer: badoption.Listable[option.DNSRecordOptions]{
+ mustRecord(t, "example.com. IN A 1.1.1.1"),
+ mustRecord(t, "example.com. IN AAAA 2001:db8::1"),
+ },
+ },
+ },
+ },
+ },
+ }, &fakeDNSTransportManager{
+ defaultTransport: defaultTransport,
+ transports: map[string]adapter.DNSTransport{
+ "default": defaultTransport,
+ },
+ }, &fakeDNSClient{})
+ require.False(t, router.legacyDNSMode)
+
+ addresses, err := router.Lookup(context.Background(), "example.com", adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{
+ netip.MustParseAddr("1.1.1.1"),
+ netip.MustParseAddr("2001:db8::1"),
+ }, addresses)
+}
+
+func TestExchangeLegacyDNSModeDisabledLogicalMatchResponseIPCIDRFallsThrough(t *testing.T) {
+ t.Parallel()
+
+ transportManager := &fakeDNSTransportManager{
+ defaultTransport: &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ transports: map[string]adapter.DNSTransport{
+ "upstream": &fakeDNSTransport{tag: "upstream", transportType: C.DNSTypeUDP},
+ "selected": &fakeDNSTransport{tag: "selected", transportType: C.DNSTypeUDP},
+ "default": &fakeDNSTransport{tag: "default", transportType: C.DNSTypeUDP},
+ },
+ }
+ client := &fakeDNSClient{
+ exchange: func(transport adapter.DNSTransport, message *mDNS.Msg) (*mDNS.Msg, error) {
+ switch transport.Tag() {
+ case "upstream":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("9.9.9.9")}, 60), nil
+ case "selected":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("8.8.8.8")}, 60), nil
+ case "default":
+ return FixedResponse(0, message.Question[0], []netip.Addr{netip.MustParseAddr("4.4.4.4")}, 60), nil
+ default:
+ return nil, E.New("unexpected transport")
+ }
+ },
+ }
+ rules := []option.DNSRule{
+ {
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeEvaluate,
+ RouteOptions: option.DNSRouteActionOptions{Server: "upstream"},
+ },
+ },
+ },
+ {
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeOr,
+ Rules: []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ MatchResponse: true,
+ IPCIDR: badoption.Listable[string]{"1.1.1.0/24"},
+ },
+ },
+ }},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "selected"},
+ },
+ },
+ },
+ }
+ router := newTestRouter(t, rules, transportManager, client)
+
+ response, err := router.Exchange(context.Background(), &mDNS.Msg{
+ Question: []mDNS.Question{fixedQuestion("example.com", mDNS.TypeA)},
+ }, adapter.DNSQueryOptions{})
+ require.NoError(t, err)
+ require.Equal(t, []netip.Addr{netip.MustParseAddr("4.4.4.4")}, MessageToAddresses(response))
+}
+
+func TestLegacyDNSModeReportsLegacyAddressFilterDeprecation(t *testing.T) {
+ t.Parallel()
+
+ manager := &fakeDeprecatedManager{}
+ ctx := service.ContextWith[deprecated.Manager](context.Background(), manager)
+ router := &Router{
+ ctx: ctx,
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ client: &fakeDNSClient{},
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ IPCIDR: badoption.Listable[string]{"1.1.1.0/24"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{Server: "default"},
+ },
+ },
+ }})
+ require.NoError(t, err)
+
+ err = router.Start(adapter.StartStateStart)
+ require.NoError(t, err)
+ require.Len(t, manager.features, 1)
+ require.Equal(t, deprecated.OptionLegacyDNSAddressFilter.Name, manager.features[0].Name)
+}
+
+func TestLegacyDNSModeReportsDNSRuleStrategyDeprecation(t *testing.T) {
+ t.Parallel()
+
+ manager := &fakeDeprecatedManager{}
+ ctx := service.ContextWith[deprecated.Manager](context.Background(), manager)
+ router := &Router{
+ ctx: ctx,
+ logger: log.NewNOPFactory().NewLogger("dns"),
+ client: &fakeDNSClient{},
+ defaultDomainStrategy: C.DomainStrategyAsIS,
+ }
+ err := router.Initialize([]option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{
+ Server: "default",
+ Strategy: option.DomainStrategy(C.DomainStrategyIPv4Only),
+ },
+ },
+ },
+ }})
+ require.NoError(t, err)
+
+ err = router.Start(adapter.StartStateStart)
+ require.NoError(t, err)
+ require.Len(t, manager.features, 1)
+ require.Equal(t, deprecated.OptionLegacyDNSRuleStrategy.Name, manager.features[0].Name)
+}
diff --git a/dns/transport/base.go b/dns/transport/base.go
new file mode 100644
index 0000000000..06e41fd029
--- /dev/null
+++ b/dns/transport/base.go
@@ -0,0 +1,145 @@
+package transport
+
+import (
+ "context"
+ "os"
+ "sync"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+)
+
+type TransportState int
+
+const (
+ StateNew TransportState = iota
+ StateStarted
+ StateClosing
+ StateClosed
+)
+
+var (
+ ErrTransportClosed = os.ErrClosed
+ ErrConnectionReset = E.New("connection reset")
+)
+
+type BaseTransport struct {
+ dns.TransportAdapter
+ Logger logger.ContextLogger
+
+ mutex sync.Mutex
+ state TransportState
+ inFlight int32
+ queriesComplete chan struct{}
+ closeCtx context.Context
+ closeCancel context.CancelFunc
+}
+
+func NewBaseTransport(adapter dns.TransportAdapter, logger logger.ContextLogger) *BaseTransport {
+ ctx, cancel := context.WithCancel(context.Background())
+ return &BaseTransport{
+ TransportAdapter: adapter,
+ Logger: logger,
+ state: StateNew,
+ closeCtx: ctx,
+ closeCancel: cancel,
+ }
+}
+
+func (t *BaseTransport) State() TransportState {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ return t.state
+}
+
+func (t *BaseTransport) SetStarted() error {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ switch t.state {
+ case StateNew:
+ t.state = StateStarted
+ return nil
+ case StateStarted:
+ return nil
+ default:
+ return ErrTransportClosed
+ }
+}
+
+func (t *BaseTransport) BeginQuery() bool {
+ t.mutex.Lock()
+ defer t.mutex.Unlock()
+ if t.state != StateStarted {
+ return false
+ }
+ t.inFlight++
+ return true
+}
+
+func (t *BaseTransport) EndQuery() {
+ t.mutex.Lock()
+ if t.inFlight > 0 {
+ t.inFlight--
+ }
+ if t.inFlight == 0 && t.queriesComplete != nil {
+ close(t.queriesComplete)
+ t.queriesComplete = nil
+ }
+ t.mutex.Unlock()
+}
+
+func (t *BaseTransport) CloseContext() context.Context {
+ return t.closeCtx
+}
+
+func (t *BaseTransport) Shutdown(ctx context.Context) error {
+ t.mutex.Lock()
+
+ if t.state >= StateClosing {
+ t.mutex.Unlock()
+ return nil
+ }
+
+ if t.state == StateNew {
+ t.state = StateClosed
+ t.mutex.Unlock()
+ t.closeCancel()
+ return nil
+ }
+
+ t.state = StateClosing
+
+ if t.inFlight == 0 {
+ t.state = StateClosed
+ t.mutex.Unlock()
+ t.closeCancel()
+ return nil
+ }
+
+ t.queriesComplete = make(chan struct{})
+ queriesComplete := t.queriesComplete
+ t.mutex.Unlock()
+
+ t.closeCancel()
+
+ select {
+ case <-queriesComplete:
+ t.mutex.Lock()
+ t.state = StateClosed
+ t.mutex.Unlock()
+ return nil
+ case <-ctx.Done():
+ t.mutex.Lock()
+ t.state = StateClosed
+ t.mutex.Unlock()
+ return ctx.Err()
+ }
+}
+
+func (t *BaseTransport) Close() error {
+ ctx, cancel := context.WithTimeout(context.Background(), C.TCPTimeout)
+ defer cancel()
+ return t.Shutdown(ctx)
+}
diff --git a/dns/transport/connector.go b/dns/transport/connector.go
new file mode 100644
index 0000000000..0a64fea7dc
--- /dev/null
+++ b/dns/transport/connector.go
@@ -0,0 +1,323 @@
+package transport
+
+import (
+ "context"
+ "net"
+ "sync"
+ "time"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type ConnectorCallbacks[T any] struct {
+ IsClosed func(connection T) bool
+ Close func(connection T)
+ Reset func(connection T)
+}
+
+type Connector[T any] struct {
+ dial func(ctx context.Context) (T, error)
+ callbacks ConnectorCallbacks[T]
+
+ access sync.Mutex
+ connection T
+ hasConnection bool
+ connectionCancel context.CancelFunc
+ connecting chan struct{}
+
+ closeCtx context.Context
+ closed bool
+}
+
+func NewConnector[T any](closeCtx context.Context, dial func(context.Context) (T, error), callbacks ConnectorCallbacks[T]) *Connector[T] {
+ return &Connector[T]{
+ dial: dial,
+ callbacks: callbacks,
+ closeCtx: closeCtx,
+ }
+}
+
+func NewSingleflightConnector(closeCtx context.Context, dial func(context.Context) (*Connection, error)) *Connector[*Connection] {
+ return NewConnector(closeCtx, dial, ConnectorCallbacks[*Connection]{
+ IsClosed: func(connection *Connection) bool {
+ return connection.IsClosed()
+ },
+ Close: func(connection *Connection) {
+ connection.CloseWithError(ErrTransportClosed)
+ },
+ Reset: func(connection *Connection) {
+ connection.CloseWithError(ErrConnectionReset)
+ },
+ })
+}
+
+type contextKeyConnecting struct{}
+
+var errRecursiveConnectorDial = E.New("recursive connector dial")
+
+type connectorDialResult[T any] struct {
+ connection T
+ cancel context.CancelFunc
+ err error
+}
+
+func (c *Connector[T]) Get(ctx context.Context) (T, error) {
+ var zero T
+ for {
+ c.access.Lock()
+
+ if c.closed {
+ c.access.Unlock()
+ return zero, ErrTransportClosed
+ }
+
+ if c.hasConnection && !c.callbacks.IsClosed(c.connection) {
+ connection := c.connection
+ c.access.Unlock()
+ return connection, nil
+ }
+
+ c.hasConnection = false
+ if c.connectionCancel != nil {
+ c.connectionCancel()
+ c.connectionCancel = nil
+ }
+ if isRecursiveConnectorDial(ctx, c) {
+ c.access.Unlock()
+ return zero, errRecursiveConnectorDial
+ }
+
+ if c.connecting != nil {
+ connecting := c.connecting
+ c.access.Unlock()
+
+ select {
+ case <-connecting:
+ continue
+ case <-ctx.Done():
+ return zero, ctx.Err()
+ case <-c.closeCtx.Done():
+ return zero, ErrTransportClosed
+ }
+ }
+
+ if err := ctx.Err(); err != nil {
+ c.access.Unlock()
+ return zero, err
+ }
+
+ connecting := make(chan struct{})
+ c.connecting = connecting
+ dialContext := context.WithValue(ctx, contextKeyConnecting{}, c)
+ dialResult := make(chan connectorDialResult[T], 1)
+ c.access.Unlock()
+
+ go func() {
+ connection, cancel, err := c.dialWithCancellation(dialContext)
+ dialResult <- connectorDialResult[T]{
+ connection: connection,
+ cancel: cancel,
+ err: err,
+ }
+ }()
+
+ select {
+ case result := <-dialResult:
+ return c.completeDial(ctx, connecting, result)
+ case <-ctx.Done():
+ go func() {
+ result := <-dialResult
+ _, _ = c.completeDial(ctx, connecting, result)
+ }()
+ return zero, ctx.Err()
+ case <-c.closeCtx.Done():
+ go func() {
+ result := <-dialResult
+ _, _ = c.completeDial(ctx, connecting, result)
+ }()
+ return zero, ErrTransportClosed
+ }
+ }
+}
+
+func isRecursiveConnectorDial[T any](ctx context.Context, connector *Connector[T]) bool {
+ dialConnector, loaded := ctx.Value(contextKeyConnecting{}).(*Connector[T])
+ return loaded && dialConnector == connector
+}
+
+func (c *Connector[T]) completeDial(ctx context.Context, connecting chan struct{}, result connectorDialResult[T]) (T, error) {
+ var zero T
+
+ c.access.Lock()
+ defer c.access.Unlock()
+ defer func() {
+ if c.connecting == connecting {
+ c.connecting = nil
+ }
+ close(connecting)
+ }()
+
+ if result.err != nil {
+ return zero, result.err
+ }
+ if c.closed || c.closeCtx.Err() != nil {
+ result.cancel()
+ c.callbacks.Close(result.connection)
+ return zero, ErrTransportClosed
+ }
+ if err := ctx.Err(); err != nil {
+ result.cancel()
+ c.callbacks.Close(result.connection)
+ return zero, err
+ }
+
+ c.connection = result.connection
+ c.hasConnection = true
+ c.connectionCancel = result.cancel
+ return c.connection, nil
+}
+
+func (c *Connector[T]) dialWithCancellation(ctx context.Context) (T, context.CancelFunc, error) {
+ var zero T
+ if err := ctx.Err(); err != nil {
+ return zero, nil, err
+ }
+ connCtx, cancel := context.WithCancel(c.closeCtx)
+
+ var (
+ stateAccess sync.Mutex
+ dialComplete bool
+ )
+ stopCancel := context.AfterFunc(ctx, func() {
+ stateAccess.Lock()
+ if !dialComplete {
+ cancel()
+ }
+ stateAccess.Unlock()
+ })
+ select {
+ case <-ctx.Done():
+ stateAccess.Lock()
+ dialComplete = true
+ stateAccess.Unlock()
+ stopCancel()
+ cancel()
+ return zero, nil, ctx.Err()
+ default:
+ }
+
+ connection, err := c.dial(valueContext{connCtx, ctx})
+ stateAccess.Lock()
+ dialComplete = true
+ stateAccess.Unlock()
+ stopCancel()
+ if err != nil {
+ cancel()
+ return zero, nil, err
+ }
+ return connection, cancel, nil
+}
+
+type valueContext struct {
+ context.Context
+ parent context.Context
+}
+
+func (v valueContext) Value(key any) any {
+ return v.parent.Value(key)
+}
+
+func (v valueContext) Deadline() (time.Time, bool) {
+ return v.parent.Deadline()
+}
+
+func (c *Connector[T]) Close() error {
+ c.access.Lock()
+
+ if c.closed {
+ c.access.Unlock()
+ return nil
+ }
+ hasConnectiopn := c.hasConnection
+ c.closed = true
+ c.hasConnection = false
+ c.access.Unlock()
+
+ if c.connectionCancel != nil {
+ c.connectionCancel()
+ c.connectionCancel = nil
+ }
+ if hasConnectiopn {
+ c.callbacks.Close(c.connection)
+ }
+
+ return nil
+}
+
+func (c *Connector[T]) Reset() {
+ c.access.Lock()
+ defer c.access.Unlock()
+
+ if c.connectionCancel != nil {
+ c.connectionCancel()
+ c.connectionCancel = nil
+ }
+ if c.hasConnection {
+ c.callbacks.Reset(c.connection)
+ c.hasConnection = false
+ }
+}
+
+type Connection struct {
+ net.Conn
+
+ closeOnce sync.Once
+ done chan struct{}
+ closeError error
+}
+
+func WrapConnection(conn net.Conn) *Connection {
+ return &Connection{
+ Conn: conn,
+ done: make(chan struct{}),
+ }
+}
+
+func (c *Connection) Done() <-chan struct{} {
+ return c.done
+}
+
+func (c *Connection) IsClosed() bool {
+ select {
+ case <-c.done:
+ return true
+ default:
+ return false
+ }
+}
+
+func (c *Connection) CloseError() error {
+ select {
+ case <-c.done:
+ if c.closeError != nil {
+ return c.closeError
+ }
+ return ErrTransportClosed
+ default:
+ return nil
+ }
+}
+
+func (c *Connection) Close() error {
+ return c.CloseWithError(ErrTransportClosed)
+}
+
+func (c *Connection) CloseWithError(err error) error {
+ var returnError error
+ c.closeOnce.Do(func() {
+ c.closeError = err
+ returnError = c.Conn.Close()
+ close(c.done)
+ })
+ return returnError
+}
diff --git a/dns/transport/dhcp/dhcp.go b/dns/transport/dhcp/dhcp.go
index 8dc22c4954..9585629c8e 100644
--- a/dns/transport/dhcp/dhcp.go
+++ b/dns/transport/dhcp/dhcp.go
@@ -111,6 +111,7 @@ func (t *Transport) Close() error {
func (t *Transport) Reset() {
t.transportLock.Lock()
t.updatedAt = time.Time{}
+ t.lastError = nil
t.servers = nil
t.transportLock.Unlock()
}
diff --git a/dns/transport/hosts/hosts.go b/dns/transport/hosts/hosts.go
index f0e70a9a3c..d593ef8cc9 100644
--- a/dns/transport/hosts/hosts.go
+++ b/dns/transport/hosts/hosts.go
@@ -4,6 +4,8 @@ import (
"context"
"net/netip"
"os"
+ "regexp"
+ "strings"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
@@ -19,7 +21,10 @@ func RegisterTransport(registry *dns.TransportRegistry) {
dns.RegisterTransport[option.HostsDNSServerOptions](registry, C.DNSTypeHosts, NewTransport)
}
-var _ adapter.DNSTransport = (*Transport)(nil)
+var (
+ _ adapter.DNSTransport = (*Transport)(nil)
+ _ adapter.DNSTransportWithPreferredDomain = (*Transport)(nil)
+)
type Transport struct {
dns.TransportAdapter
@@ -33,7 +38,11 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
predefined = make(map[string][]netip.Addr)
)
if len(options.Path) == 0 {
- files = append(files, NewFile(DefaultPath))
+ defaultFile, err := NewDefault()
+ if err != nil {
+ return nil, err
+ }
+ files = append(files, defaultFile)
} else {
for _, path := range options.Path {
files = append(files, NewFile(filemanager.BasePath(ctx, os.ExpandEnv(path))))
@@ -62,6 +71,18 @@ func (t *Transport) Close() error {
func (t *Transport) Reset() {
}
+func (t *Transport) PreferredDomain(domain string) bool {
+ if _, loaded := t.predefined[domain]; loaded {
+ return true
+ }
+ for _, file := range t.files {
+ if len(file.Lookup(domain)) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
question := message.Question[0]
domain := mDNS.CanonicalName(question.Name)
@@ -75,6 +96,10 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
}
+ addresses := getIpOfSslip(domain)
+ if len(addresses) > 0 {
+ return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
+ }
}
return &mDNS.Msg{
MsgHdr: mDNS.MsgHdr{
@@ -85,3 +110,36 @@ func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg,
Question: []mDNS.Question{question},
}, nil
}
+
+const (
+ ipv4Pattern = `((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])[\.-](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])[\.-](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])[\.-](25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])).sslip.io$`
+ ipv6Pattern = `((([0-9a-fA-F]{1,4}-){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,7}-|([0-9a-fA-F]{1,4}-){1,6}-[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}-){1,5}(-[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}-){1,4}(-[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}-){1,3}(-[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}-){1,2}(-[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}-((-[0-9a-fA-F]{1,4}){1,6})|-((-[0-9a-fA-F]{1,4}){1,7}|-)|fe80-(-[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|--(ffff(-0{1,4}){0,1}-){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}-){1,4}-((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))).sslip.io$`
+)
+
+var (
+ ipv4Regex, _ = regexp.Compile(ipv4Pattern)
+ ipv6Regex, _ = regexp.Compile(ipv6Pattern)
+)
+
+func getIpOfSslip(sni string) []netip.Addr {
+ if !strings.HasSuffix(sni, ".sslip.io") {
+ return nil
+ }
+ submatches := ipv4Regex.FindStringSubmatch(sni)
+ ipstr := ""
+ if len(submatches) > 1 {
+ ipstr = strings.ReplaceAll(submatches[1], "-", ".")
+
+ } else {
+ submatches := ipv6Regex.FindStringSubmatch(sni)
+ if len(submatches) > 1 {
+ ipstr = strings.ReplaceAll(submatches[1], "-", ":")
+ }
+ }
+ ip, err := netip.ParseAddr(ipstr)
+ if err != nil {
+ return nil
+ }
+ return []netip.Addr{ip}
+
+}
diff --git a/dns/transport/hosts/hosts_file.go b/dns/transport/hosts/hosts_file.go
index ec384882a8..af507f012a 100644
--- a/dns/transport/hosts/hosts_file.go
+++ b/dns/transport/hosts/hosts_file.go
@@ -10,6 +10,8 @@ import (
"sync"
"time"
+ E "github.com/sagernet/sing/common/exceptions"
+
"github.com/miekg/dns"
)
@@ -30,6 +32,14 @@ func NewFile(path string) *File {
}
}
+func NewDefault() (*File, error) {
+ defaultPathResolved, err := defaultPath()
+ if err != nil {
+ return nil, E.Cause(err, "resolve default hosts path")
+ }
+ return NewFile(defaultPathResolved), nil
+}
+
func (f *File) Lookup(name string) []netip.Addr {
f.access.Lock()
defer f.access.Unlock()
diff --git a/dns/transport/hosts/hosts_test.go b/dns/transport/hosts/hosts_test.go
index 3ae160b789..61d20e0c63 100644
--- a/dns/transport/hosts/hosts_test.go
+++ b/dns/transport/hosts/hosts_test.go
@@ -1,16 +1,29 @@
-package hosts_test
+package hosts
import (
"net/netip"
+ "os"
+ "runtime"
"testing"
- "github.com/sagernet/sing-box/dns/transport/hosts"
+ E "github.com/sagernet/sing/common/exceptions"
"github.com/stretchr/testify/require"
)
func TestHosts(t *testing.T) {
t.Parallel()
- require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, hosts.NewFile("testdata/hosts").Lookup("localhost"))
- require.NotEmpty(t, hosts.NewFile(hosts.DefaultPath).Lookup("localhost"))
+ require.Equal(t, []netip.Addr{netip.AddrFrom4([4]byte{127, 0, 0, 1}), netip.IPv6Loopback()}, NewFile("testdata/hosts").Lookup("localhost"))
+ if runtime.GOOS != "windows" {
+ defaultPathResolved, err := defaultPath()
+ if err != nil {
+ t.Fatal(E.Cause(err, "resolve default hosts path"))
+ }
+ content, readErr := os.ReadFile(defaultPathResolved)
+ require.NoError(t, readErr)
+ hFile := NewFile(defaultPathResolved)
+ if len(hFile.Lookup("localhost")) == 0 {
+ t.Fatal("failed to resolve localhost: ", defaultPathResolved, ": \n", string(content))
+ }
+ }
}
diff --git a/dns/transport/hosts/hosts_unix.go b/dns/transport/hosts/hosts_unix.go
index 4caed8b406..9c44853194 100644
--- a/dns/transport/hosts/hosts_unix.go
+++ b/dns/transport/hosts/hosts_unix.go
@@ -2,4 +2,6 @@
package hosts
-var DefaultPath = "/etc/hosts"
+func defaultPath() (string, error) {
+ return "/etc/hosts", nil
+}
diff --git a/dns/transport/hosts/hosts_windows.go b/dns/transport/hosts/hosts_windows.go
index 3144e50d56..a17e6d2b87 100644
--- a/dns/transport/hosts/hosts_windows.go
+++ b/dns/transport/hosts/hosts_windows.go
@@ -2,16 +2,15 @@ package hosts
import (
"path/filepath"
+ "sync"
"golang.org/x/sys/windows"
)
-var DefaultPath string
-
-func init() {
+var defaultPath = sync.OnceValues(func() (string, error) {
systemDirectory, err := windows.GetSystemDirectory()
if err != nil {
- systemDirectory = "C:\\Windows\\System32"
+ return "", err
}
- DefaultPath = filepath.Join(systemDirectory, "Drivers/etc/hosts")
-}
+ return filepath.Join(systemDirectory, "Drivers", "etc", "hosts"), nil
+})
diff --git a/dns/transport/https.go b/dns/transport/https.go
index b508e6eae5..db89799cdf 100644
--- a/dns/transport/https.go
+++ b/dns/transport/https.go
@@ -120,13 +120,16 @@ func NewHTTPSRaw(
serverAddr M.Socksaddr,
tlsConfig tls.Config,
) *HTTPSTransport {
+ if tlsConfig != nil {
+ dialer = tls.NewDialer(dialer, tlsConfig)
+ }
return &HTTPSTransport{
TransportAdapter: adapter,
logger: logger,
dialer: dialer,
destination: destination,
headers: headers,
- transport: NewHTTPSTransportWrapper(tls.NewDialer(dialer, tlsConfig), serverAddr),
+ transport: NewHTTPSTransportWrapper(dialer, serverAddr, destination),
}
}
@@ -138,10 +141,7 @@ func (t *HTTPSTransport) Start(stage adapter.StartStage) error {
}
func (t *HTTPSTransport) Close() error {
- t.transportAccess.Lock()
- defer t.transportAccess.Unlock()
- t.transport.CloseIdleConnections()
- t.transport = t.transport.Clone()
+ t.Reset()
return nil
}
diff --git a/dns/transport/https_transport.go b/dns/transport/https_transport.go
index 84cfa17c37..c823718aa1 100644
--- a/dns/transport/https_transport.go
+++ b/dns/transport/https_transport.go
@@ -5,11 +5,13 @@ import (
"errors"
"net"
"net/http"
+ "net/url"
"sync/atomic"
"github.com/sagernet/sing-box/common/tls"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
"golang.org/x/net/http2"
)
@@ -22,27 +24,36 @@ type HTTPSTransportWrapper struct {
fallback *atomic.Bool
}
-func NewHTTPSTransportWrapper(dialer tls.Dialer, serverAddr M.Socksaddr) *HTTPSTransportWrapper {
+func NewHTTPSTransportWrapper(dialer N.Dialer, serverAddr M.Socksaddr, destination *url.URL) *HTTPSTransportWrapper {
var fallback atomic.Bool
+ if destination.Scheme == "http" {
+ // plain HTTP DoH used by Tailscale
+ fallback.Store(true)
+ }
return &HTTPSTransportWrapper{
http2Transport: &http2.Transport{
DialTLSContext: func(ctx context.Context, _, _ string, _ *tls.STDConfig) (net.Conn, error) {
- tlsConn, err := dialer.DialTLSContext(ctx, serverAddr)
+ resultConn, err := dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
if err != nil {
return nil, err
}
- state := tlsConn.ConnectionState()
- if state.NegotiatedProtocol == http2.NextProtoTLS {
- return tlsConn, nil
+ if tlsConn, isTLSConn := resultConn.(tls.Conn); isTLSConn {
+ state := tlsConn.ConnectionState()
+ if state.NegotiatedProtocol != http2.NextProtoTLS {
+ tlsConn.Close()
+ fallback.Store(true)
+ return nil, errFallback
+ }
}
- tlsConn.Close()
- fallback.Store(true)
- return nil, errFallback
+ return resultConn, nil
},
},
httpTransport: &http.Transport{
+ DialContext: func(ctx context.Context, _, addr string) (net.Conn, error) {
+ return dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
+ },
DialTLSContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
- return dialer.DialTLSContext(ctx, serverAddr)
+ return dialer.DialContext(ctx, N.NetworkTCP, serverAddr)
},
},
fallback: &fallback,
@@ -52,16 +63,15 @@ func NewHTTPSTransportWrapper(dialer tls.Dialer, serverAddr M.Socksaddr) *HTTPST
func (h *HTTPSTransportWrapper) RoundTrip(request *http.Request) (*http.Response, error) {
if h.fallback.Load() {
return h.httpTransport.RoundTrip(request)
- } else {
- response, err := h.http2Transport.RoundTrip(request)
- if err != nil {
- if errors.Is(err, errFallback) {
- return h.httpTransport.RoundTrip(request)
- }
- return nil, err
+ }
+ response, err := h.http2Transport.RoundTrip(request)
+ if err != nil {
+ if errors.Is(err, errFallback) {
+ return h.httpTransport.RoundTrip(request)
}
- return response, nil
+ return nil, err
}
+ return response, nil
}
func (h *HTTPSTransportWrapper) CloseIdleConnections() {
diff --git a/dns/transport/local/local.go b/dns/transport/local/local.go
index a3909acc81..34897e128e 100644
--- a/dns/transport/local/local.go
+++ b/dns/transport/local/local.go
@@ -1,5 +1,3 @@
-//go:build !darwin
-
package local
import (
@@ -9,11 +7,15 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/dns/transport/hosts"
+ "github.com/sagernet/sing-box/dns/transport/mdns"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
mDNS "github.com/miekg/dns"
)
@@ -22,16 +24,30 @@ func RegisterTransport(registry *dns.TransportRegistry) {
dns.RegisterTransport[option.LocalDNSServerOptions](registry, C.DNSTypeLocal, NewTransport)
}
-var _ adapter.DNSTransport = (*Transport)(nil)
+var (
+ _ adapter.DNSTransport = (*Transport)(nil)
+ _ adapter.DNSTransportWithPreferredDomain = (*Transport)(nil)
+)
type Transport struct {
dns.TransportAdapter
- ctx context.Context
- logger logger.ContextLogger
- hosts *hosts.File
- dialer N.Dialer
- preferGo bool
- resolved ResolvedResolver
+ ctx context.Context
+ logger logger.ContextLogger
+ hosts *hosts.File
+ dialer N.Dialer
+ preferGo bool
+ fallback bool
+ resolved ResolvedResolver
+ mdnsTransport adapter.DNSTransport
+ dhcpTransport dhcpTransport
+ neighborResolver adapter.NeighborResolver
+ neighborSuffixes []string
+}
+
+type dhcpTransport interface {
+ adapter.DNSTransport
+ Fetch() []M.Socksaddr
+ Exchange0(ctx context.Context, message *mDNS.Msg, servers []M.Socksaddr) (*mDNS.Msg, error)
}
func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.LocalDNSServerOptions) (adapter.DNSTransport, error) {
@@ -39,56 +55,128 @@ func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, opt
if err != nil {
return nil, err
}
+ suffixes, err := buildNeighborMatchers(options.NeighborDomain)
+ if err != nil {
+ return nil, err
+ }
return &Transport{
TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeLocal, tag, options),
ctx: ctx,
logger: logger,
- hosts: hosts.NewFile(hosts.DefaultPath),
dialer: transportDialer,
preferGo: options.PreferGo,
+ neighborSuffixes: suffixes,
}, nil
}
func (t *Transport) Start(stage adapter.StartStage) error {
switch stage {
case adapter.StartStateInitialize:
- if !t.preferGo {
- if isSystemdResolvedManaged() {
- resolvedResolver, err := NewResolvedResolver(t.ctx, t.logger)
+ defaultHosts, err := hosts.NewDefault()
+ if err != nil {
+ t.logger.Warn(err)
+ } else {
+ t.hosts = defaultHosts
+ }
+ if !t.preferGo && isSystemdResolvedManaged() {
+ resolvedResolver, err := NewResolvedResolver(t.ctx, t.logger)
+ if err == nil {
+ err = resolvedResolver.Start()
if err == nil {
- err = resolvedResolver.Start()
- if err == nil {
- t.resolved = resolvedResolver
- } else {
- t.logger.Warn(E.Cause(err, "initialize resolved resolver"))
- }
+ t.resolved = resolvedResolver
+ } else {
+ t.logger.Warn(E.Cause(err, "initialize resolved resolver"))
}
}
}
+ case adapter.StartStateStart:
+ if C.IsDarwin {
+ inboundManager := service.FromContext[adapter.InboundManager](t.ctx)
+ for _, inbound := range inboundManager.Inbounds() {
+ if inbound.Type() == C.TypeTun {
+ t.fallback = true
+ break
+ }
+ }
+ if t.fallback {
+ t.dhcpTransport = newDHCPTransport(t.TransportAdapter, log.ContextWithOverrideLevel(t.ctx, log.LevelDebug), t.dialer, t.logger)
+ }
+ } else {
+ t.mdnsTransport = mdns.NewRawTransport(t.TransportAdapter, t.ctx, t.logger)
+ }
+ router := service.FromContext[adapter.Router](t.ctx)
+ if router != nil {
+ t.neighborResolver = router.NeighborResolver()
+ }
+ fallthrough
+ default:
+ if t.dhcpTransport != nil {
+ err := t.dhcpTransport.Start(stage)
+ if err != nil {
+ return err
+ }
+ }
+ if t.mdnsTransport != nil {
+ err := t.mdnsTransport.Start(stage)
+ if err != nil {
+ return err
+ }
+ }
}
return nil
}
func (t *Transport) Close() error {
- if t.resolved != nil {
- return t.resolved.Close()
- }
- return nil
+ return common.Close(t.resolved, t.dhcpTransport, t.mdnsTransport)
}
func (t *Transport) Reset() {
+ if t.dhcpTransport != nil {
+ t.dhcpTransport.Reset()
+ }
+ if t.mdnsTransport != nil {
+ t.mdnsTransport.Reset()
+ }
}
-func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
- if t.resolved != nil {
- return t.resolved.Exchange(ctx, message)
+func (t *Transport) PreferredDomain(domain string) bool {
+ if t.hosts != nil {
+ if len(t.hosts.Lookup(dns.FqdnToDomain(domain))) > 0 {
+ return true
+ }
}
+ return t.hasNeighborHost(domain) || mdns.IsLocalDomain(domain)
+}
+
+func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
question := message.Question[0]
- if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
+ if t.hosts != nil && (question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA) {
addresses := t.hosts.Lookup(dns.FqdnToDomain(question.Name))
if len(addresses) > 0 {
return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
}
}
+ response := t.lookupNeighbor(message)
+ if response != nil {
+ return response, nil
+ }
+ if mdns.IsLocalDomain(question.Name) {
+ if C.IsDarwin {
+ return t.systemExchange(ctx, message)
+ }
+ return t.mdnsTransport.Exchange(ctx, message)
+ }
+ if t.resolved != nil {
+ return t.resolved.Exchange(ctx, message)
+ }
+ if t.dhcpTransport != nil {
+ servers := t.dhcpTransport.Fetch()
+ if len(servers) > 0 {
+ return t.dhcpTransport.Exchange0(ctx, message, servers)
+ }
+ }
+ if t.fallback {
+ return t.systemExchange(ctx, message)
+ }
return t.exchange(ctx, message, question.Name)
}
diff --git a/dns/transport/local/local_darwin.go b/dns/transport/local/local_darwin.go
deleted file mode 100644
index 5f1e60b15a..0000000000
--- a/dns/transport/local/local_darwin.go
+++ /dev/null
@@ -1,140 +0,0 @@
-//go:build darwin
-
-package local
-
-import (
- "context"
- "errors"
- "net"
-
- "github.com/sagernet/sing-box/adapter"
- C "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/dns"
- "github.com/sagernet/sing-box/dns/transport/hosts"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/logger"
- M "github.com/sagernet/sing/common/metadata"
- N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/service"
-
- mDNS "github.com/miekg/dns"
-)
-
-func RegisterTransport(registry *dns.TransportRegistry) {
- dns.RegisterTransport[option.LocalDNSServerOptions](registry, C.DNSTypeLocal, NewTransport)
-}
-
-var _ adapter.DNSTransport = (*Transport)(nil)
-
-type Transport struct {
- dns.TransportAdapter
- ctx context.Context
- logger logger.ContextLogger
- hosts *hosts.File
- dialer N.Dialer
- preferGo bool
- fallback bool
- dhcpTransport dhcpTransport
- resolver net.Resolver
-}
-
-type dhcpTransport interface {
- adapter.DNSTransport
- Fetch() []M.Socksaddr
- Exchange0(ctx context.Context, message *mDNS.Msg, servers []M.Socksaddr) (*mDNS.Msg, error)
-}
-
-func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.LocalDNSServerOptions) (adapter.DNSTransport, error) {
- transportDialer, err := dns.NewLocalDialer(ctx, options)
- if err != nil {
- return nil, err
- }
- transportAdapter := dns.NewTransportAdapterWithLocalOptions(C.DNSTypeLocal, tag, options)
- return &Transport{
- TransportAdapter: transportAdapter,
- ctx: ctx,
- logger: logger,
- hosts: hosts.NewFile(hosts.DefaultPath),
- dialer: transportDialer,
- preferGo: options.PreferGo,
- }, nil
-}
-
-func (t *Transport) Start(stage adapter.StartStage) error {
- if stage != adapter.StartStateStart {
- return nil
- }
- inboundManager := service.FromContext[adapter.InboundManager](t.ctx)
- for _, inbound := range inboundManager.Inbounds() {
- if inbound.Type() == C.TypeTun {
- t.fallback = true
- break
- }
- }
- if t.fallback {
- t.dhcpTransport = newDHCPTransport(t.TransportAdapter, log.ContextWithOverrideLevel(t.ctx, log.LevelDebug), t.dialer, t.logger)
- if t.dhcpTransport != nil {
- err := t.dhcpTransport.Start(stage)
- if err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func (t *Transport) Close() error {
- return common.Close(
- t.dhcpTransport,
- )
-}
-
-func (t *Transport) Reset() {
- if t.dhcpTransport != nil {
- t.dhcpTransport.Reset()
- }
-}
-
-func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
- question := message.Question[0]
- if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
- addresses := t.hosts.Lookup(dns.FqdnToDomain(question.Name))
- if len(addresses) > 0 {
- return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
- }
- }
- if !t.fallback {
- return t.exchange(ctx, message, question.Name)
- }
- if t.dhcpTransport != nil {
- dhcpTransports := t.dhcpTransport.Fetch()
- if len(dhcpTransports) > 0 {
- return t.dhcpTransport.Exchange0(ctx, message, dhcpTransports)
- }
- }
- if t.preferGo {
- // Assuming the user knows what they are doing, we still execute the query which will fail.
- return t.exchange(ctx, message, question.Name)
- }
- if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
- var network string
- if question.Qtype == mDNS.TypeA {
- network = "ip4"
- } else {
- network = "ip6"
- }
- addresses, err := t.resolver.LookupNetIP(ctx, network, question.Name)
- if err != nil {
- var dnsError *net.DNSError
- if errors.As(err, &dnsError) && dnsError.IsNotFound {
- return nil, dns.RcodeRefused
- }
- return nil, err
- }
- return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
- }
- return nil, E.New("only A and AAAA queries are supported on Apple platforms when using TUN and DHCP unavailable.")
-}
diff --git a/dns/transport/local/local_darwin_cgo.go b/dns/transport/local/local_darwin_cgo.go
new file mode 100644
index 0000000000..de2ec56a4b
--- /dev/null
+++ b/dns/transport/local/local_darwin_cgo.go
@@ -0,0 +1,118 @@
+//go:build darwin
+
+package local
+
+/*
+#include
+#include
+#include
+
+static int cgo_dns_search(const char *name, int class, int type,
+ unsigned char *answer, int anslen, int *out_h_errno) {
+ dns_handle_t handle = (dns_handle_t)dns_open(NULL);
+ if (handle == NULL) {
+ *out_h_errno = NO_RECOVERY;
+ return -1;
+ }
+ struct sockaddr_storage from;
+ uint32_t fromlen = sizeof(from);
+ h_errno = 0;
+ int n = dns_search(handle, name, class, type, (char *)answer, anslen,
+ (struct sockaddr *)&from, &fromlen);
+ *out_h_errno = h_errno;
+ dns_free(handle);
+ return n;
+}
+*/
+import "C"
+
+import (
+ "context"
+ "errors"
+ "unsafe"
+
+ "github.com/sagernet/sing-box/dns"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ mDNS "github.com/miekg/dns"
+)
+
+const (
+ darwinResolverHostNotFound = 1
+ darwinResolverTryAgain = 2
+ darwinResolverNoRecovery = 3
+ darwinResolverNoData = 4
+)
+
+func darwinLookupSystemDNS(name string, class, qtype int) (*mDNS.Msg, error) {
+ cName := C.CString(name)
+ defer C.free(unsafe.Pointer(cName))
+
+ answer := make([]byte, 4096)
+ var hErrno C.int
+ n := C.cgo_dns_search(cName, C.int(class), C.int(qtype),
+ (*C.uchar)(unsafe.Pointer(&answer[0])), C.int(len(answer)),
+ &hErrno)
+ if n <= 0 {
+ return nil, darwinResolverHErrno(name, int(hErrno))
+ }
+ var response mDNS.Msg
+ err := response.Unpack(answer[:int(n)])
+ if err != nil {
+ return nil, E.Cause(err, "unpack dns_search response")
+ }
+ return &response, nil
+}
+
+func darwinResolverHErrno(name string, hErrno int) error {
+ switch hErrno {
+ case darwinResolverHostNotFound:
+ return dns.RcodeNameError
+ case darwinResolverNoData:
+ return dns.RcodeSuccess
+ case darwinResolverTryAgain, darwinResolverNoRecovery:
+ return dns.RcodeServerFailure
+ default:
+ return E.New("dns_search: unknown h_errno ", hErrno, " for ", name)
+ }
+}
+
+func (t *Transport) systemExchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ question := message.Question[0]
+ type resolvResult struct {
+ response *mDNS.Msg
+ err error
+ }
+ resultCh := make(chan resolvResult, 1)
+ go func() {
+ response, err := darwinLookupSystemDNS(question.Name, int(question.Qclass), int(question.Qtype))
+ resultCh <- resolvResult{response, err}
+ }()
+ var result resolvResult
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case result = <-resultCh:
+ }
+ if result.err != nil {
+ var rcodeError dns.RcodeError
+ if errors.As(result.err, &rcodeError) {
+ return dns.FixedResponseStatus(message, int(rcodeError)), nil
+ }
+ return nil, result.err
+ }
+ result.response.Id = message.Id
+ // Workaround for a bug in Apple libresolv: res_query_mDNSResponder
+ // (libresolv/res_query.c), used when the resolver has
+ // DNS_FLAG_FORWARD_TO_MDNSRESPONDER set (typical inside a Network
+ // Extension), writes:
+ //
+ // ans->qr = 1;
+ // ans->qr = htons(ans->qr);
+ //
+ // HEADER.qr is a 1-bit bitfield (), so
+ // htons(1) == 0x0100 gets truncated back to 0, clearing the QR bit.
+ // Force it on so downstream clients see a valid response.
+ result.response.Response = true
+ return result.response, nil
+}
diff --git a/dns/transport/local/local_darwin_stun.go b/dns/transport/local/local_darwin_stun.go
new file mode 100644
index 0000000000..b99833c262
--- /dev/null
+++ b/dns/transport/local/local_darwin_stun.go
@@ -0,0 +1,15 @@
+//go:build darwin && !cgo
+
+package local
+
+import (
+ "context"
+
+ E "github.com/sagernet/sing/common/exceptions"
+
+ mDNS "github.com/miekg/dns"
+)
+
+func (t *Transport) systemExchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ return nil, E.New(`local DNS server requires CGO on darwin, rebuild with CGO_ENABLED=1`)
+}
diff --git a/dns/transport/local/local_darwin_dhcp.go b/dns/transport/local/local_dhcp.go
similarity index 93%
rename from dns/transport/local/local_darwin_dhcp.go
rename to dns/transport/local/local_dhcp.go
index b228b76a48..bf77ed252d 100644
--- a/dns/transport/local/local_darwin_dhcp.go
+++ b/dns/transport/local/local_dhcp.go
@@ -1,4 +1,4 @@
-//go:build darwin && with_dhcp
+//go:build with_dhcp
package local
diff --git a/dns/transport/local/local_neighbor.go b/dns/transport/local/local_neighbor.go
new file mode 100644
index 0000000000..3dd394a8b6
--- /dev/null
+++ b/dns/transport/local/local_neighbor.go
@@ -0,0 +1,68 @@
+package local
+
+import (
+ "strings"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ mDNS "github.com/miekg/dns"
+)
+
+func buildNeighborMatchers(domains []string) ([]string, error) {
+ if len(domains) == 0 {
+ return nil, nil
+ }
+ var suffixes []string
+ for _, domain := range domains {
+ if !strings.HasPrefix(domain, ".") {
+ return nil, E.New("neighbor_domain entry must start with '.': ", domain)
+ }
+ suffixes = append(suffixes, mDNS.CanonicalName(domain))
+ }
+ return suffixes, nil
+}
+
+func (t *Transport) lookupNeighbor(message *mDNS.Msg) *mDNS.Msg {
+ if t.neighborResolver == nil {
+ return nil
+ }
+ question := message.Question[0]
+ if question.Qtype != mDNS.TypeA && question.Qtype != mDNS.TypeAAAA {
+ return nil
+ }
+ host := extractNeighborHost(mDNS.CanonicalName(question.Name), t.neighborSuffixes)
+ if host == "" {
+ return nil
+ }
+ addresses := t.neighborResolver.LookupAddresses(host)
+ if len(addresses) == 0 {
+ return nil
+ }
+ return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL)
+}
+
+func (t *Transport) hasNeighborHost(domain string) bool {
+ if t.neighborResolver == nil {
+ return false
+ }
+ host := extractNeighborHost(domain, t.neighborSuffixes)
+ if host == "" {
+ return false
+ }
+ return len(t.neighborResolver.LookupAddresses(host)) > 0
+}
+
+func extractNeighborHost(canonical string, suffixes []string) string {
+ for _, suffix := range suffixes {
+ if !strings.HasSuffix(canonical, suffix) || len(canonical) <= len(suffix) {
+ continue
+ }
+ host := canonical[:len(canonical)-len(suffix)]
+ if !strings.ContainsRune(host, '.') {
+ return host
+ }
+ }
+ return ""
+}
diff --git a/dns/transport/local/local_darwin_nodhcp.go b/dns/transport/local/local_nodhcp.go
similarity index 90%
rename from dns/transport/local/local_darwin_nodhcp.go
rename to dns/transport/local/local_nodhcp.go
index 5ce84690a4..7893d416f6 100644
--- a/dns/transport/local/local_darwin_nodhcp.go
+++ b/dns/transport/local/local_nodhcp.go
@@ -1,4 +1,4 @@
-//go:build darwin && !with_dhcp
+//go:build !with_dhcp
package local
diff --git a/dns/transport/local/local_other.go b/dns/transport/local/local_other.go
new file mode 100644
index 0000000000..9bb3d7777a
--- /dev/null
+++ b/dns/transport/local/local_other.go
@@ -0,0 +1,14 @@
+//go:build !darwin
+
+package local
+
+import (
+ "context"
+ "os"
+
+ mDNS "github.com/miekg/dns"
+)
+
+func (t *Transport) systemExchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ return nil, os.ErrInvalid
+}
diff --git a/dns/transport/mdns/mdns.go b/dns/transport/mdns/mdns.go
new file mode 100644
index 0000000000..2db3390d53
--- /dev/null
+++ b/dns/transport/mdns/mdns.go
@@ -0,0 +1,456 @@
+package mdns
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "slices"
+ "strings"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/control"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json/badoption"
+ "github.com/sagernet/sing/common/logger"
+ "github.com/sagernet/sing/common/task"
+ "github.com/sagernet/sing/service"
+
+ mDNS "github.com/miekg/dns"
+ "golang.org/x/net/ipv4"
+ "golang.org/x/net/ipv6"
+)
+
+const (
+ mdnsPort = 5353
+ mdnsClassTopBit = 1 << 15
+ mdnsTimeout = time.Second
+)
+
+var (
+ mdnsGroupIPv4 = net.IPv4(224, 0, 0, 251)
+ mdnsGroupIPv6 = net.ParseIP("ff02::fb")
+ mdnsLocalZones = []string{
+ "local.",
+ "254.169.in-addr.arpa.",
+ "8.e.f.ip6.arpa.",
+ "9.e.f.ip6.arpa.",
+ "a.e.f.ip6.arpa.",
+ "b.e.f.ip6.arpa.",
+ }
+)
+
+func IsLocalDomain(name string) bool {
+ canonical := mDNS.CanonicalName(name)
+ return common.Any(mdnsLocalZones, func(zone string) bool {
+ return canonical == zone || strings.HasSuffix(canonical, "."+zone)
+ })
+}
+
+func RegisterTransport(registry *dns.TransportRegistry) {
+ dns.RegisterTransport[option.MDNSDNSServerOptions](registry, C.DNSTypeMDNS, NewTransport)
+}
+
+var (
+ _ adapter.DNSTransport = (*Transport)(nil)
+ _ adapter.DNSTransportWithPreferredDomain = (*Transport)(nil)
+)
+
+type Transport struct {
+ dns.TransportAdapter
+ ctx context.Context
+ logger logger.ContextLogger
+ networkManager adapter.NetworkManager
+ interfaceNames badoption.Listable[string]
+}
+
+func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.MDNSDNSServerOptions) (adapter.DNSTransport, error) {
+ return &Transport{
+ TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeMDNS, tag, options.LocalDNSServerOptions),
+ ctx: ctx,
+ logger: logger,
+ networkManager: service.FromContext[adapter.NetworkManager](ctx),
+ interfaceNames: options.Interface,
+ }, nil
+}
+
+func NewRawTransport(transportAdapter dns.TransportAdapter, ctx context.Context, logger log.ContextLogger) *Transport {
+ return &Transport{
+ TransportAdapter: transportAdapter,
+ ctx: ctx,
+ logger: logger,
+ networkManager: service.FromContext[adapter.NetworkManager](ctx),
+ }
+}
+
+func (t *Transport) Start(stage adapter.StartStage) error {
+ return nil
+}
+
+func (t *Transport) Close() error {
+ return nil
+}
+
+func (t *Transport) Reset() {
+}
+
+func (t *Transport) PreferredDomain(domain string) bool {
+ return IsLocalDomain(domain)
+}
+
+func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ targets, err := t.queryTargets()
+ if err != nil {
+ return nil, E.Cause(err, "mdns: prepare interfaces")
+ }
+ request := makeQueryMessage(message)
+ rawMessage, err := request.Pack()
+ if err != nil {
+ return nil, E.Cause(err, "mdns: pack request")
+ }
+ deadline, loaded := ctx.Deadline()
+ if !loaded || deadline.IsZero() {
+ deadline = time.Now().Add(mdnsTimeout)
+ }
+ exchangeCtx, cancel := context.WithDeadline(ctx, deadline)
+ defer cancel()
+ results := make(chan exchangeResult, len(targets))
+ var group task.Group
+ for _, target := range targets {
+ group.Append0(func(ctx context.Context) error {
+ response, err := t.exchangeTarget(ctx, target, rawMessage, message.Question[0], deadline)
+ if err != nil || response != nil {
+ results <- exchangeResult{
+ response: response,
+ err: err,
+ }
+ }
+ return nil
+ })
+ }
+ groupErr := group.Run(exchangeCtx)
+ close(results)
+ response := newResponse(message)
+ seenRecords := make(map[string]bool)
+ var lastErr error
+ for result := range results {
+ if result.err != nil {
+ lastErr = result.err
+ t.logger.TraceContext(ctx, result.err)
+ continue
+ }
+ mergeResponse(response, result.response, seenRecords)
+ }
+ if len(response.Answer) > 0 || len(response.Ns) > 0 || len(response.Extra) > 0 {
+ return response, nil
+ }
+ if lastErr != nil {
+ return nil, lastErr
+ }
+ if groupErr != nil && ctx.Err() != nil {
+ return nil, groupErr
+ }
+ return nil, E.New("mdns: query timeout")
+}
+
+type exchangeResult struct {
+ response *mDNS.Msg
+ err error
+}
+
+type queryTarget struct {
+ iface control.Interface
+ family string
+}
+
+func (t *Transport) exchangeTarget(ctx context.Context, target queryTarget, rawMessage []byte, question mDNS.Question, deadline time.Time) (*mDNS.Msg, error) {
+ packetConn, destination, err := t.listenPacket(ctx, target)
+ if err != nil {
+ return nil, err
+ }
+ defer packetConn.Close()
+
+ _, err = packetConn.WriteTo(rawMessage, destination)
+ if err != nil {
+ return nil, E.Cause(err, "mdns: write request on ", target.iface.Name, " ", target.family)
+ }
+ err = packetConn.SetReadDeadline(deadline)
+ if err != nil {
+ return nil, E.Cause(err, "mdns: set deadline on ", target.iface.Name, " ", target.family)
+ }
+ response := newResponseFromQuestion(question)
+ seenRecords := make(map[string]bool)
+ buffer := buf.Get(buf.UDPBufferSize)
+ defer buf.Put(buffer)
+ for {
+ n, source, readErr := packetConn.ReadFrom(buffer)
+ if readErr != nil {
+ if E.IsTimeout(readErr) {
+ if len(response.Answer) > 0 || len(response.Ns) > 0 || len(response.Extra) > 0 {
+ return response, nil
+ }
+ return nil, nil
+ }
+ return nil, E.Cause(readErr, "mdns: read response on ", target.iface.Name, " ", target.family)
+ }
+ if !validSource(source, target) {
+ continue
+ }
+ var candidate mDNS.Msg
+ err = candidate.Unpack(buffer[:n])
+ if err != nil {
+ t.logger.TraceContext(ctx, "mdns: unpack response: ", err)
+ continue
+ }
+ if !validResponse(&candidate, question) {
+ continue
+ }
+ normalizeResponse(&candidate, question)
+ mergeResponse(response, &candidate, seenRecords)
+ }
+}
+
+func (t *Transport) listenPacket(ctx context.Context, target queryTarget) (net.PacketConn, net.Addr, error) {
+ var listenConfig net.ListenConfig
+ listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(t.networkManager.InterfaceFinder(), target.iface.Name, target.iface.Index))
+ netInterface := target.iface.NetInterface()
+ switch target.family {
+ case "udp4":
+ packetConn, err := listenConfig.ListenPacket(ctx, "udp4", "0.0.0.0:0")
+ if err != nil {
+ return nil, nil, E.Cause(err, "mdns: listen on ", target.iface.Name, " udp4")
+ }
+ ipv4Conn := ipv4.NewPacketConn(packetConn)
+ err = ipv4Conn.SetMulticastInterface(&netInterface)
+ if err != nil {
+ packetConn.Close()
+ return nil, nil, E.Cause(err, "mdns: set multicast interface on ", target.iface.Name, " udp4")
+ }
+ _ = ipv4Conn.SetMulticastTTL(255)
+ return packetConn, &net.UDPAddr{IP: mdnsGroupIPv4, Port: mdnsPort}, nil
+ case "udp6":
+ packetConn, err := listenConfig.ListenPacket(ctx, "udp6", "[::]:0")
+ if err != nil {
+ return nil, nil, E.Cause(err, "mdns: listen on ", target.iface.Name, " udp6")
+ }
+ ipv6Conn := ipv6.NewPacketConn(packetConn)
+ err = ipv6Conn.SetMulticastInterface(&netInterface)
+ if err != nil {
+ packetConn.Close()
+ return nil, nil, E.Cause(err, "mdns: set multicast interface on ", target.iface.Name, " udp6")
+ }
+ _ = ipv6Conn.SetMulticastHopLimit(255)
+ return packetConn, &net.UDPAddr{IP: mdnsGroupIPv6, Port: mdnsPort, Zone: target.iface.Name}, nil
+ default:
+ return nil, nil, E.New("mdns: unknown network: ", target.family)
+ }
+}
+
+func (t *Transport) queryTargets() ([]queryTarget, error) {
+ interfaces, err := t.fetchInterfaces()
+ if err != nil {
+ return nil, err
+ }
+ var targets []queryTarget
+ for _, iface := range interfaces {
+ supports4, supports6 := interfaceFamilies(iface)
+ if supports4 {
+ targets = append(targets, queryTarget{
+ iface: iface,
+ family: "udp4",
+ })
+ }
+ if supports6 {
+ targets = append(targets, queryTarget{
+ iface: iface,
+ family: "udp6",
+ })
+ }
+ }
+ if len(targets) == 0 {
+ return nil, E.New("missing usable mDNS interfaces")
+ }
+ return targets, nil
+}
+
+func (t *Transport) fetchInterfaces() ([]control.Interface, error) {
+ finder := t.networkManager.InterfaceFinder()
+ var interfaces []control.Interface
+ if len(t.interfaceNames) > 0 {
+ for _, interfaceName := range t.interfaceNames {
+ iface, err := finder.ByName(interfaceName)
+ if err != nil {
+ t.logger.Warn("mdns: interface ", interfaceName, " not found")
+ continue
+ }
+ if !isUsableInterface(*iface) {
+ t.logger.Warn("mdns: interface ", interfaceName, " is not usable")
+ continue
+ }
+ interfaces = append(interfaces, *iface)
+ }
+ } else {
+ interfaces = common.Filter(finder.Interfaces(), isUsableInterface)
+ }
+ if len(interfaces) == 0 {
+ return nil, E.New("mdns: missing usable interface")
+ }
+ return interfaces, nil
+}
+
+func isUsableInterface(iface control.Interface) bool {
+ return iface.Flags&net.FlagUp != 0 &&
+ iface.Flags&net.FlagMulticast != 0 &&
+ iface.Flags&net.FlagLoopback == 0
+}
+
+func interfaceFamilies(iface control.Interface) (supports4, supports6 bool) {
+ for _, prefix := range iface.Addresses {
+ addr := prefix.Addr()
+ if addr.IsLoopback() {
+ continue
+ }
+ if addr.Is4() {
+ supports4 = true
+ } else if addr.Is6() && !addr.Is4In6() {
+ supports6 = true
+ }
+ if supports4 && supports6 {
+ return
+ }
+ }
+ return
+}
+
+func makeQueryMessage(message *mDNS.Msg) *mDNS.Msg {
+ request := &mDNS.Msg{
+ Question: slices.Clone(message.Question),
+ }
+ for i := range request.Question {
+ stripQuestionClass(&request.Question[i])
+ }
+ return request
+}
+
+func newResponse(message *mDNS.Msg) *mDNS.Msg {
+ response := newResponseFromQuestion(message.Question[0])
+ response.Id = message.Id
+ return response
+}
+
+func newResponseFromQuestion(question mDNS.Question) *mDNS.Msg {
+ stripQuestionClass(&question)
+ return &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Authoritative: true,
+ Rcode: mDNS.RcodeSuccess,
+ },
+ Question: []mDNS.Question{question},
+ }
+}
+
+func validSource(source net.Addr, target queryTarget) bool {
+ sourceUDP, isUDP := source.(*net.UDPAddr)
+ if !isUDP || sourceUDP.Port != mdnsPort {
+ return false
+ }
+ sourceAddr, loaded := netip.AddrFromSlice(sourceUDP.IP)
+ if !loaded {
+ return false
+ }
+ sourceAddr = sourceAddr.Unmap()
+ if (target.family == "udp4" && !sourceAddr.Is4()) || (target.family == "udp6" && !sourceAddr.Is6()) {
+ return false
+ }
+ for _, prefix := range target.iface.Addresses {
+ if prefix.Contains(sourceAddr) {
+ return true
+ }
+ }
+ return false
+}
+
+func validResponse(response *mDNS.Msg, question mDNS.Question) bool {
+ if !response.Response ||
+ response.Opcode != mDNS.OpcodeQuery ||
+ response.Rcode != mDNS.RcodeSuccess {
+ return false
+ }
+ for _, responseQuestion := range response.Question {
+ if questionMatches(responseQuestion, question) {
+ return true
+ }
+ }
+ return responseHasMatchingRecord(response, question)
+}
+
+func responseHasMatchingRecord(response *mDNS.Msg, question mDNS.Question) bool {
+ for _, recordList := range [][]mDNS.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ if recordMatchesQuestion(record, question) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func questionMatches(left mDNS.Question, right mDNS.Question) bool {
+ stripQuestionClass(&left)
+ stripQuestionClass(&right)
+ return left.Qtype == right.Qtype &&
+ left.Qclass == right.Qclass &&
+ strings.EqualFold(left.Name, right.Name)
+}
+
+func recordMatchesQuestion(record mDNS.RR, question mDNS.Question) bool {
+ header := record.Header()
+ return strings.EqualFold(header.Name, question.Name) &&
+ (question.Qtype == mDNS.TypeANY ||
+ header.Rrtype == question.Qtype ||
+ header.Rrtype == mDNS.TypeCNAME)
+}
+
+func normalizeResponse(response *mDNS.Msg, question mDNS.Question) {
+ response.Id = 0
+ response.Question = []mDNS.Question{question}
+ for i := range response.Question {
+ stripQuestionClass(&response.Question[i])
+ }
+ for _, recordList := range [][]mDNS.RR{response.Answer, response.Ns, response.Extra} {
+ for _, record := range recordList {
+ stripRecordClass(record)
+ }
+ }
+}
+
+func mergeResponse(destination *mDNS.Msg, source *mDNS.Msg, seenRecords map[string]bool) {
+ appendRecords := func(destinationRecords *[]mDNS.RR, sourceRecords []mDNS.RR) {
+ for _, record := range sourceRecords {
+ key := record.String()
+ if seenRecords[key] {
+ continue
+ }
+ seenRecords[key] = true
+ *destinationRecords = append(*destinationRecords, record)
+ }
+ }
+ appendRecords(&destination.Answer, source.Answer)
+ appendRecords(&destination.Ns, source.Ns)
+ appendRecords(&destination.Extra, source.Extra)
+}
+
+func stripQuestionClass(question *mDNS.Question) {
+ question.Qclass &^= mdnsClassTopBit
+}
+
+func stripRecordClass(record mDNS.RR) {
+ record.Header().Class &^= mdnsClassTopBit
+}
diff --git a/dns/transport/multi/multi.go b/dns/transport/multi/multi.go
new file mode 100644
index 0000000000..7e36a62286
--- /dev/null
+++ b/dns/transport/multi/multi.go
@@ -0,0 +1,251 @@
+package multi
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "sync"
+ "time"
+
+ mDNS "github.com/miekg/dns"
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterTransport(registry *dns.TransportRegistry) {
+ dns.RegisterTransport[option.MultiDNSServerOptions](registry, C.DNSTypeMulti, NewTransport)
+}
+
+var _ adapter.DNSTransport = (*Transport)(nil)
+
+type Transport struct {
+ dns.TransportAdapter
+ serverTags []string
+ parallel bool
+ transports []adapter.DNSTransport
+ manager adapter.DNSTransportManager
+ ignoredRanges []netip.Prefix
+ done chan struct{}
+ logger log.ContextLogger
+}
+
+func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.MultiDNSServerOptions) (adapter.DNSTransport, error) {
+ ignoreRanges := make([]netip.Prefix, 0, len(options.IgnoreRanges))
+ for _, r := range options.IgnoreRanges {
+ ignoreRanges = append(ignoreRanges, netip.Prefix(r))
+ }
+
+ return &Transport{
+ TransportAdapter: dns.NewTransportAdapter(C.DNSTypeMulti, tag, options.Servers),
+ manager: service.FromContext[adapter.DNSTransportManager](ctx),
+ serverTags: options.Servers,
+ parallel: options.Parallel,
+ ignoredRanges: ignoreRanges,
+ done: make(chan struct{}),
+ logger: logger,
+ }, nil
+}
+
+func (m *Transport) Start(stage adapter.StartStage) error {
+ if stage == adapter.StartStateStart {
+ for _, tag := range m.serverTags {
+ transport, found := m.manager.Transport(tag)
+ if !found {
+ return E.New("dns transport not found: ", tag)
+ }
+ m.transports = append(m.transports, transport)
+ }
+ }
+ return nil
+}
+
+func (t *Transport) Close() error {
+ t.logger.Debug("closing multi dns transport ", t.Tag())
+ close(t.done)
+ return nil
+}
+
+func (t *Transport) Reset() {
+}
+
+func (m *Transport) Exchange(ctx context.Context, msg *mDNS.Msg) (*mDNS.Msg, error) {
+ defer func() {
+ select {
+ case <-m.done:
+ m.logger.Debug("m done closing multi dns transport successfully ", m.Tag())
+ case <-ctx.Done():
+ m.logger.Debug("ctx done, closing multi dns transport successfully ", m.Tag(), " ctx error: ", ctx.Err())
+ default:
+ }
+ }()
+ if len(m.transports) == 0 {
+ return nil, E.New("no dns transports configured")
+ }
+
+ if !m.parallel {
+ return m.exchangeSerial(ctx, msg)
+ }
+
+ return m.exchangeParallel(ctx, msg)
+}
+func (m *Transport) exchangeSerial(parent context.Context, msg *mDNS.Msg) (*mDNS.Msg, error) {
+ ctx, cancel := context.WithTimeout(parent, 10*time.Second)
+ defer cancel()
+ var lastErr error
+ var lastResp *mDNS.Msg
+ for _, tr := range m.transports {
+ select {
+ case <-m.done:
+ return nil, E.New("transport closed")
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+
+ resp, err := tr.Exchange(ctx, msg)
+ if err != nil {
+ lastErr = err
+ continue
+ }
+ var change bool
+ resp, change = m.filterBlocked(resp)
+ if len(resp.Answer) > 0 {
+ return resp, nil
+ }
+ if !change {
+ lastResp = resp
+ }
+ }
+
+ if lastResp != nil {
+ return lastResp, nil
+ }
+ if lastErr != nil {
+ return nil, lastErr
+ }
+ return nil, E.New("no dns response")
+}
+func (m *Transport) exchangeParallel(parent context.Context, msg *mDNS.Msg) (*mDNS.Msg, error) {
+ ctx, cancel := context.WithTimeout(parent, 5*time.Second)
+ defer cancel()
+
+ type result struct {
+ resp *mDNS.Msg
+ err error
+ }
+
+ results := make(chan result, len(m.transports))
+
+ var wg sync.WaitGroup
+ wg.Add(len(m.transports))
+
+ for _, tr := range m.transports {
+ go func(tr adapter.DNSTransport) {
+ defer wg.Done()
+
+ resp, err := tr.Exchange(ctx, msg)
+ select {
+ case results <- result{resp: resp, err: err}:
+ case <-ctx.Done():
+ case <-m.done:
+ }
+ }(tr)
+ }
+
+ // Close results exactly once
+ go func() {
+ wg.Wait()
+ close(results)
+
+ }()
+
+ var lastErr error
+ var lastResp *mDNS.Msg
+
+ for {
+ select {
+ case r, ok := <-results:
+ if !ok {
+ m.logger.Trace("all transports completed, no response received")
+ if lastResp != nil {
+ return lastResp, nil
+ }
+ if lastErr != nil {
+ return nil, lastErr
+ }
+ return nil, E.New("no dns response")
+ }
+ if r.err != nil {
+ lastErr = r.err
+ continue
+ }
+ resp, change := m.filterBlocked(r.resp)
+ if len(resp.Answer) > 0 {
+ cancel() // stop others
+ return resp, nil
+ }
+ if !change {
+ lastResp = resp
+ }
+ case <-m.done:
+ return nil, E.New("transport closed")
+ case <-ctx.Done():
+ if lastResp != nil {
+ return lastResp, nil
+ }
+ if lastErr != nil {
+ return nil, lastErr
+ }
+ return nil, ctx.Err()
+ }
+ }
+}
+
+func (m *Transport) filterBlocked(msg *mDNS.Msg) (*mDNS.Msg, bool) {
+ if msg == nil {
+ return nil, false
+ }
+ if len(msg.Answer) == 0 {
+ return msg, false
+ }
+ answers := make([]mDNS.RR, 0)
+ for _, r := range msg.Answer {
+ switch answer := r.(type) {
+ case *mDNS.A:
+ if m.isBlocked(answer.A) {
+ continue
+ }
+ case *mDNS.AAAA:
+ if m.isBlocked(answer.AAAA) {
+ continue
+ }
+ default:
+ }
+ answers = append(answers, r)
+ }
+ hasChanged := len(answers) != len(msg.Answer)
+ msg.Answer = answers
+ return msg, hasChanged
+}
+
+func (m *Transport) isBlocked(ip net.IP) bool {
+ netipAddr, ok := netip.AddrFromSlice(ip)
+ if !ok {
+ return true
+ }
+ if !netipAddr.IsValid() {
+ return true
+ }
+
+ for _, p := range m.ignoredRanges {
+ if p.Contains(netipAddr) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/dns/transport/sdns.go b/dns/transport/sdns.go
new file mode 100644
index 0000000000..1c4a1a2390
--- /dev/null
+++ b/dns/transport/sdns.go
@@ -0,0 +1,73 @@
+package transport
+
+import (
+ "context"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/ameshkov/dnscrypt/v2"
+ mDNS "github.com/miekg/dns"
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+var _ adapter.DNSTransport = (*SDNSTransport)(nil)
+
+func RegisterSDNS(registry *dns.TransportRegistry) {
+ dns.RegisterTransport[option.SDNSDNSServerOptions](registry, C.DNSTypeSDNS, NewSDNSTransport)
+}
+
+type SDNSTransport struct {
+ dns.TransportAdapter
+ client *dnscrypt.Client
+ name string
+ stamp string
+
+ mtx sync.Mutex
+}
+
+func NewSDNSTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.SDNSDNSServerOptions) (adapter.DNSTransport, error) {
+ transportDialer, err := dns.NewRemoteDialer(ctx, options.RemoteDNSServerOptions)
+ if err != nil {
+ return nil, err
+ }
+ return &SDNSTransport{
+ client: &dnscrypt.Client{
+ Net: "udp",
+ Timeout: 10 * time.Second,
+ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return transportDialer.DialContext(ctx, N.NetworkName(network), M.ParseSocksaddr(addr))
+ },
+ },
+ stamp: options.Stamp,
+ }, err
+}
+
+func (t *SDNSTransport) Name() string {
+ return t.name
+}
+
+func (t *SDNSTransport) Start(adapter.StartStage) error {
+ return nil
+}
+
+func (t *SDNSTransport) Close() error {
+ return nil
+}
+
+func (t *SDNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ resolverInfo, err := t.client.Dial(t.stamp)
+ if err != nil {
+ return nil, err
+ }
+ return t.client.Exchange(message, resolverInfo)
+}
+
+func (t *SDNSTransport) Reset() {
+}
diff --git a/dns/transport_adapter.go b/dns/transport_adapter.go
index 4734570978..1e6620f25d 100644
--- a/dns/transport_adapter.go
+++ b/dns/transport_adapter.go
@@ -1,21 +1,13 @@
package dns
import (
- "net/netip"
-
- "github.com/sagernet/sing-box/adapter"
- C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
)
-var _ adapter.LegacyDNSTransport = (*TransportAdapter)(nil)
-
type TransportAdapter struct {
transportType string
transportTag string
dependencies []string
- strategy C.DomainStrategy
- clientSubnet netip.Prefix
}
func NewTransportAdapter(transportType string, transportTag string, dependencies []string) TransportAdapter {
@@ -35,8 +27,6 @@ func NewTransportAdapterWithLocalOptions(transportType string, transportTag stri
transportType: transportType,
transportTag: transportTag,
dependencies: dependencies,
- strategy: C.DomainStrategy(localOptions.LegacyStrategy),
- clientSubnet: localOptions.LegacyClientSubnet,
}
}
@@ -45,15 +35,10 @@ func NewTransportAdapterWithRemoteOptions(transportType string, transportTag str
if remoteOptions.DomainResolver != nil && remoteOptions.DomainResolver.Server != "" {
dependencies = append(dependencies, remoteOptions.DomainResolver.Server)
}
- if remoteOptions.LegacyAddressResolver != "" {
- dependencies = append(dependencies, remoteOptions.LegacyAddressResolver)
- }
return TransportAdapter{
transportType: transportType,
transportTag: transportTag,
dependencies: dependencies,
- strategy: C.DomainStrategy(remoteOptions.LegacyStrategy),
- clientSubnet: remoteOptions.LegacyClientSubnet,
}
}
@@ -68,11 +53,3 @@ func (a *TransportAdapter) Tag() string {
func (a *TransportAdapter) Dependencies() []string {
return a.dependencies
}
-
-func (a *TransportAdapter) LegacyStrategy() C.DomainStrategy {
- return a.strategy
-}
-
-func (a *TransportAdapter) LegacyClientSubnet() netip.Prefix {
- return a.clientSubnet
-}
diff --git a/dns/transport_dialer.go b/dns/transport_dialer.go
index b3ee8082ab..971002ac40 100644
--- a/dns/transport_dialer.go
+++ b/dns/transport_dialer.go
@@ -2,104 +2,25 @@ package dns
import (
"context"
- "net"
- "time"
- "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
- C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
- E "github.com/sagernet/sing/common/exceptions"
- M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/service"
)
func NewLocalDialer(ctx context.Context, options option.LocalDNSServerOptions) (N.Dialer, error) {
- if options.LegacyDefaultDialer {
- return dialer.NewDefaultOutbound(ctx), nil
- } else {
- return dialer.NewWithOptions(dialer.Options{
- Context: ctx,
- Options: options.DialerOptions,
- DirectResolver: true,
- LegacyDNSDialer: options.Legacy,
- })
- }
-}
-
-func NewRemoteDialer(ctx context.Context, options option.RemoteDNSServerOptions) (N.Dialer, error) {
- if options.LegacyDefaultDialer {
- transportDialer := dialer.NewDefaultOutbound(ctx)
- if options.LegacyAddressResolver != "" {
- transport := service.FromContext[adapter.DNSTransportManager](ctx)
- resolverTransport, loaded := transport.Transport(options.LegacyAddressResolver)
- if !loaded {
- return nil, E.New("address resolver not found: ", options.LegacyAddressResolver)
- }
- transportDialer = newTransportDialer(transportDialer, service.FromContext[adapter.DNSRouter](ctx), resolverTransport, C.DomainStrategy(options.LegacyAddressStrategy), time.Duration(options.LegacyAddressFallbackDelay))
- } else if options.ServerIsDomain() {
- return nil, E.New("missing address resolver for server: ", options.Server)
- }
- return transportDialer, nil
- } else {
- return dialer.NewWithOptions(dialer.Options{
- Context: ctx,
- Options: options.DialerOptions,
- RemoteIsDomain: options.ServerIsDomain(),
- DirectResolver: true,
- LegacyDNSDialer: options.Legacy,
- })
- }
-}
-
-type legacyTransportDialer struct {
- dialer N.Dialer
- dnsRouter adapter.DNSRouter
- transport adapter.DNSTransport
- strategy C.DomainStrategy
- fallbackDelay time.Duration
-}
-
-func newTransportDialer(dialer N.Dialer, dnsRouter adapter.DNSRouter, transport adapter.DNSTransport, strategy C.DomainStrategy, fallbackDelay time.Duration) *legacyTransportDialer {
- return &legacyTransportDialer{
- dialer,
- dnsRouter,
- transport,
- strategy,
- fallbackDelay,
- }
-}
-
-func (d *legacyTransportDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
- if destination.IsIP() {
- return d.dialer.DialContext(ctx, network, destination)
- }
- addresses, err := d.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{
- Transport: d.transport,
- Strategy: d.strategy,
+ return dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ DirectResolver: true,
})
- if err != nil {
- return nil, err
- }
- return N.DialParallel(ctx, d.dialer, network, destination, addresses, d.strategy == C.DomainStrategyPreferIPv6, d.fallbackDelay)
}
-func (d *legacyTransportDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
- if destination.IsIP() {
- return d.dialer.ListenPacket(ctx, destination)
- }
- addresses, err := d.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{
- Transport: d.transport,
- Strategy: d.strategy,
+func NewRemoteDialer(ctx context.Context, options option.RemoteDNSServerOptions) (N.Dialer, error) {
+ return dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: options.ServerIsDomain(),
+ DirectResolver: true,
})
- if err != nil {
- return nil, err
- }
- conn, _, err := N.ListenSerial(ctx, d.dialer, destination, addresses)
- return conn, err
-}
-
-func (d *legacyTransportDialer) Upstream() any {
- return d.dialer
}
diff --git a/docs/changelog.md b/docs/changelog.md
index ad33030c19..e1ac041f75 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -2,46 +2,391 @@
icon: material/alert-decagram
---
+#### 1.14.0-alpha.26
+
+* Add gecko obfs for Hysteria2 **1**
+* Fixes and improvements
+
+**1**:
+
+Adds `gecko` as a new QUIC traffic obfuscation type for
+[Hysteria2 inbound](/configuration/inbound/hysteria2/#obfstype) and
+[outbound](/configuration/outbound/hysteria2/#obfstype), alongside the
+existing `salamander`. Gecko supports configurable
+[`min_packet_size`](/configuration/inbound/hysteria2/#obfsmin_packet_size)
+(default 512) and
+[`max_packet_size`](/configuration/inbound/hysteria2/#obfsmax_packet_size)
+(default 1200) fields.
+
+#### 1.14.0-alpha.25
+
+* Revert Tailscale endpoint dial fields deprecation and remove `control_http_client` **1**
+* Fixes and improvements
+
+**1**:
+
+The `control_http_client` field on
+[Tailscale](/configuration/endpoint/tailscale/) endpoints introduced in
+`1.14.0-alpha.13` is removed, and the deprecation of
+[Dial Fields](/configuration/endpoint/tailscale/#dial-fields) is reverted.
+
#### 1.13.12
* Update naiveproxy to v148.0.7778.96-1
* Fixes and improvements
+#### 1.14.0-alpha.22
+
+* Add Hysteria Realm service and Hysteria2 NAT traversal support **1**
+* Fixes and improvements
+
+**1**:
+
+The new [Hysteria Realm service](/configuration/service/hysteria-realm/)
+is a rendezvous service for Hysteria2 NAT traversal. A Hysteria2 server
+behind NAT registers its STUN-discovered public addresses on a stable
+realm endpoint via the new
+[`realm`](/configuration/inbound/hysteria2/#realm) inbound field;
+clients query the realm via the new
+[`realm`](/configuration/outbound/hysteria2/#realm) outbound field to
+learn the server's current addresses and perform UDP hole-punching to
+establish a direct QUIC connection. Once hole-punching succeeds, all
+proxy traffic flows directly between client and server.
+
+#### 1.14.0-alpha.21
+
+* Allow customizing TUN DNS mode and hijack interface DNS by default **1**
+* Add mDNS DNS server **2**
+* Add `preferred_by` DNS rule item **3**
+* Add neighbor-based hostname resolution for the local DNS server **4**
+* Update NaiveProxy to 148.0.7778.96-1
+* Add more TLS spoof methods and route rule action support **5**
+* Fixes and improvements
+
+**1**:
+
+Adds [`dns_mode`](/configuration/inbound/tun/#dns_mode) and
+[`dns_address`](/configuration/inbound/tun/#dns_address) on the TUN inbound.
+The default `hijack` mode now sets the platform's native interface DNS
+(`systemd-resolved` on Linux, per-interface DNS on Windows and Apple) and
+installs platform-level DNS hijacking (an `iproute2` rule on Linux,
+nftables DNAT when `auto_redirect` is enabled, WFP filters on Windows when
+`strict_route` is enabled). Earlier versions did not touch the interface
+DNS or the platform firewall.
+
+**2**:
+
+The new [mDNS DNS server](/configuration/dns/server/mdns/) sends queries via
+multicast on the local network. The default
+[local DNS server](/configuration/dns/server/local/) also routes queries for
+`*.local.` and IPv4/IPv6 link-local reverse zones via mDNS on non-Apple
+platforms (and via the system resolver on Apple), so an explicit `mdns`
+server is only needed to reference it from
+[`preferred_by`](/configuration/dns/rule/#preferred_by) or to use it
+standalone.
+
+**3**:
+
+The new [`preferred_by`](/configuration/dns/rule/#preferred_by) DNS rule
+item matches domains that the listed DNS servers consider their preferred
+names. Supported server types are `hosts`, `local`, `mdns`, `tailscale`, and
+`resolved`. The [Tailscale](/configuration/dns/server/tailscale/),
+[Hosts](/configuration/dns/server/hosts/) and
+[Resolved](/configuration/dns/server/resolved/) example pages have been
+updated to use this rule item in place of the previous `evaluate` +
+`ip_accept_any` + `respond` pattern.
+
+**4**:
+
+Adds [`neighbor_domain`](/configuration/dns/server/local/#neighbor_domain)
+on the local DNS server. Listed suffixes (each starting with `.`) cause
+A/AAAA queries for single-label hosts under those suffixes to be answered
+from the [neighbor resolver](/configuration/shared/neighbor/) instead of
+the upstream (for example `[".", ".lan"]`).
+
+**5**:
+
+Adds `wrong-ack`, `wrong-md5`, and `wrong-timestamp`
+[spoof methods](/configuration/shared/tls/#spoof_method), and adds
+[`tls_spoof`](/configuration/route/rule_action/#tls_spoof) /
+[`tls_spoof_method`](/configuration/route/rule_action/#tls_spoof_method)
+to route rule actions for per-rule TLS spoofing without outbound TLS settings.
+
+#### 1.14.0-alpha.20
+
+** Fixes and improvements
+
+#### 1.14.0-alpha.19
+
+* Preserve comments between formatting
+* Add cipher, MAC, and key exchange algorithm options for SSH outbound **1**
+* Add DNS query timeout options **2**
+** Fixes and improvements
+
+**1**:
+
+See [SSH](/configuration/outbound/ssh/#cipher).
+
+**2**:
+
+Adds [`dns.timeout`](/configuration/dns/#timeout), with per-query
+overrides via [DNS rule action](/configuration/dns/rule_action/#timeout)
+and [`resolve` route rule action](/configuration/route/rule_action/#timeout),
+and a `timeout` field on
+[`domain_resolver`](/configuration/shared/dial/#domain_resolver).
+
+#### 1.14.0-alpha.18
+
+* Add Windows TLS engine **1**
+* Fixes and improvements
+
+**1**:
+
+The new `windows` value for outbound TLS
+[`engine`](/configuration/shared/tls/#engine) routes the TLS handshake
+through Schannel via SSPI. Only available on Windows build 17763 or
+later (Windows 10 version 1809, Windows Server 2019, or newer); TLS 1.3
+is only negotiated on Windows 11 or Windows Server 2022 and newer.
+
#### 1.13.11
* Fix process searcher failure introduced in 1.13.9
* Fixes and improvements
+#### 1.14.0-alpha.16
+
+* Add ACME profile support for IP address certificates **1**
+* Fixes and improvements
+
+**1**:
+
+See [ACME Certificate Provider](/configuration/shared/certificate-provider/acme/#profile).
+
#### 1.13.10
* Fix process searcher failure introduced in 1.13.9
+#### 1.14.0-alpha.15
+
+* Add search domain support for Tailscale DNS **1**
+* Fixes and improvements
+
+**1**:
+
+See [Tailscale DNS Server](/configuration/dns/server/tailscale/#accept_search_domain).
+
#### 1.13.9
* Fixes and improvements
+#### 1.14.0-alpha.13
+
+* Unify HTTP client **1**
+* Add Apple HTTP and TLS engines **2**
+* Unify HTTP/2 and QUIC parameters **3**
+* Add TLS spoof **4**
+* Fixes and improvements
+
+**1**:
+
+The new top-level [`http_clients`](/configuration/shared/http-client/)
+option defines reusable HTTP clients (engine, version, dialer, TLS,
+HTTP/2 and QUIC parameters). Components that make outbound HTTP requests
+— remote rule-sets, ACME and Cloudflare Origin CA certificate providers,
+DERP `verify_client_url`, and the Tailscale `control_http_client` — now
+accept an inline HTTP client object or the tag of an `http_clients`
+entry, replacing the dial and TLS fields previously inlined in each
+component. When the field is omitted, ACME, Cloudflare Origin CA, DERP
+and Tailscale dial direct (their existing default).
+
+Remote rule-sets are the only HTTP-using component whose default for an
+omitted `http_client` has historically resolved to the default outbound,
+not to direct, and a typical configuration contains many of them. To
+avoid repeating the same `http_client` block in every rule-set,
+[`route.default_http_client`](/configuration/route/#default_http_client)
+selects a default rule-set client by tag and is the only field that
+consults it. If `default_http_client` is empty and `http_clients` is
+non-empty, the first entry is used automatically. The legacy fallback
+(use the default outbound when `http_clients` is empty altogether) is
+preserved with a deprecation warning and will be removed in sing-box
+1.16.0, together with the legacy `download_detour` remote rule-set
+option and the legacy dialer fields on Tailscale endpoints.
+
+**2**:
+
+A new `apple` engine is available on Apple platforms in two independent
+places:
+
+* [HTTP client `engine`](/configuration/shared/http-client/#engine) —
+ routes HTTP requests through `NSURLSession`.
+* Outbound TLS [`engine`](/configuration/shared/tls/#engine) — routes
+ the TLS handshake through `Network.framework` for direct TCP TLS
+ client connections.
+
+The default remains `go`. Both engines come with additional CGO and
+framework memory overhead and platform restrictions documented on each
+field.
+
+**3**:
+
+[HTTP/2](/configuration/shared/http2/) and
+[QUIC](/configuration/shared/quic/) parameters
+(`idle_timeout`, `keep_alive_period`, `stream_receive_window`,
+`connection_receive_window`, `max_concurrent_streams`,
+`initial_packet_size`, `disable_path_mtu_discovery`) are now shared
+across QUIC-based outbounds
+([Hysteria](/configuration/outbound/hysteria/),
+[Hysteria2](/configuration/outbound/hysteria2/),
+[TUIC](/configuration/outbound/tuic/)) and HTTP clients running HTTP/2
+or HTTP/3.
+
+This deprecates the Hysteria v1 tuning fields `recv_window_conn`,
+`recv_window`, `recv_window_client`, `max_conn_client` and
+`disable_mtu_discovery`; they will be removed in sing-box 1.16.0.
+
+**4**:
+
+Added outbound TLS [`spoof`](/configuration/shared/tls/#spoof) and
+[`spoof_method`](/configuration/shared/tls/#spoof_method) fields. When
+enabled, a forged ClientHello carrying a whitelisted SNI is sent before
+the real handshake to fool SNI-filtering middleboxes. Requires
+`CAP_NET_RAW` + `CAP_NET_ADMIN` or root on Linux and macOS, and
+Administrator privileges on Windows (ARM64 is not supported). IP-literal
+server names are rejected.
+
+#### 1.14.0-alpha.12
+
+* Fix fake-ip DNS server should return SUCCESS when address type is not configured
+* Fixes and improvements
+
#### 1.13.8
* Update naiveproxy to v147.0.7727.49-1
* Fix fake-ip DNS server should return SUCCESS when address type is not configured
* Fixes and improvements
-#### 1.13.7
+#### 1.14.0-alpha.11
+* Add optimistic DNS cache **1**
+* Update NaiveProxy to 147.0.7727.49
* Fixes and improvements
+**1**:
+
+Optimistic DNS cache returns an expired cached response immediately while
+refreshing it in the background, reducing tail latency for repeated
+queries. Enabled via [`optimistic`](/configuration/dns/#optimistic)
+in DNS options, and can be persisted across restarts with the new
+[`store_dns`](/configuration/experimental/cache-file/#store_dns) cache
+file option. A per-query
+[`disable_optimistic_cache`](/configuration/dns/rule_action/#disable_optimistic_cache)
+field is also available on DNS rule actions and the `resolve` route rule
+action.
+
+This deprecates the `independent_cache` DNS option (the DNS cache now
+always keys by transport) and the `store_rdrc` cache file option
+(replaced by `store_dns`); both will be removed in sing-box 1.16.0.
+See [Migration](/migration/#migrate-independent-dns-cache).
+
+#### 1.14.0-alpha.10
+
+* Add `evaluate` DNS rule action and Response Match Fields **1**
+* `ip_version` and `query_type` now also take effect on internal DNS lookups **2**
+* Add `package_name_regex` route, DNS and headless rule item **3**
+* Add cloudflared inbound **4**
+* Fixes and improvements
+
+**1**:
+
+Response Match Fields
+([`response_rcode`](/configuration/dns/rule/#response_rcode),
+[`response_answer`](/configuration/dns/rule/#response_answer),
+[`response_ns`](/configuration/dns/rule/#response_ns),
+and [`response_extra`](/configuration/dns/rule/#response_extra))
+match the evaluated DNS response. They are gated by the new
+[`match_response`](/configuration/dns/rule/#match_response) field and
+populated by a preceding
+[`evaluate`](/configuration/dns/rule_action/#evaluate) DNS rule action;
+the evaluated response can also be returned directly by a
+[`respond`](/configuration/dns/rule_action/#respond) action.
+
+This deprecates the Legacy Address Filter Fields (`ip_cidr`,
+`ip_is_private` without `match_response`) in DNS rules, the Legacy
+`strategy` DNS rule action option, and the Legacy
+`rule_set_ip_cidr_accept_empty` DNS rule item; all three will be removed
+in sing-box 1.16.0.
+See [Migration](/migration/#migrate-address-filter-fields-to-response-matching).
+
+**2**:
+
+`ip_version` and `query_type` in DNS rules, together with `query_type` in
+referenced rule-sets, now take effect on every DNS rule evaluation,
+including matches from internal domain resolutions that do not target a
+specific DNS server (for example a `resolve` route rule action without
+`server` set). In earlier versions they were silently ignored in that
+path. Combining these fields with any of the legacy DNS fields deprecated
+in **1** in the same DNS configuration is no longer supported and is
+rejected at startup.
+See [Migration](/migration/#ip_version-and-query_type-behavior-changes-in-dns-rules).
+
+**3**:
+
+See [Route Rule](/configuration/route/rule/#package_name_regex),
+[DNS Rule](/configuration/dns/rule/#package_name_regex) and
+[Headless Rule](/configuration/rule-set/headless-rule/#package_name_regex).
+
+**4**:
+
+See [Cloudflared](/configuration/inbound/cloudflared/).
+
+#### 1.13.7
+
+* Fixes and improvement
+
#### 1.13.6
* Fixes and improvements
+#### 1.14.0-alpha.8
+
+* Add BBR profile and hop interval randomization for Hysteria2 **1**
+* Fixes and improvements
+
+**1**:
+
+See [Hysteria2 Inbound](/configuration/inbound/hysteria2/#bbr_profile) and [Hysteria2 Outbound](/configuration/outbound/hysteria2/#bbr_profile).
+
#### 1.13.5
* Fixes and improvements
+#### 1.14.0-alpha.7
+
+* Fixes and improvements
+
#### 1.13.4
* Fixes and improvements
+#### 1.14.0-alpha.4
+
+* Refactor ACME support to certificate provider system **1**
+* Add Cloudflare Origin CA certificate provider **2**
+* Add Tailscale certificate provider **3**
+* Fixes and improvements
+
+**1**:
+
+See [Certificate Provider](/configuration/shared/certificate-provider/) and [Migration](/migration/#migrate-inline-acme-to-certificate-provider).
+
+**2**:
+
+See [Cloudflare Origin CA](/configuration/shared/certificate-provider/cloudflare-origin-ca).
+
+**3**:
+
+See [Tailscale](/configuration/shared/certificate-provider/tailscale).
+
#### 1.13.3
* Add OpenWrt and Alpine APK packages to release **1**
@@ -66,6 +411,59 @@ from [SagerNet/go](https://github.com/SagerNet/go).
See [OCM](/configuration/service/ocm).
+#### 1.12.24
+
+* Fixes and improvements
+
+#### 1.14.0-alpha.2
+
+* Add OpenWrt and Alpine APK packages to release **1**
+* Backport to macOS 10.13 High Sierra **2**
+* OCM service: Add WebSocket support for Responses API **3**
+* Fixes and improvements
+
+**1**:
+
+Alpine APK files use `linux` in the filename to distinguish from OpenWrt APKs which use the `openwrt` prefix:
+
+- OpenWrt: `sing-box_{version}_openwrt_{architecture}.apk`
+- Alpine: `sing-box_{version}_linux_{architecture}.apk`
+
+**2**:
+
+Legacy macOS binaries (with `-legacy-macos-10.13` suffix) now support
+macOS 10.13 High Sierra, built using Go 1.25 with patches
+from [SagerNet/go](https://github.com/SagerNet/go).
+
+**3**:
+
+See [OCM](/configuration/service/ocm).
+
+#### 1.14.0-alpha.1
+
+* Add `source_mac_address` and `source_hostname` rule items **1**
+* Add `include_mac_address` and `exclude_mac_address` TUN options **2**
+* Update NaiveProxy to 145.0.7632.159 **3**
+* Fixes and improvements
+
+**1**:
+
+New rule items for matching LAN devices by MAC address and hostname via neighbor resolution.
+Supported on Linux, macOS, or in graphical clients on Android and macOS.
+
+See [Route Rule](/configuration/route/rule/#source_mac_address), [DNS Rule](/configuration/dns/rule/#source_mac_address) and [Neighbor Resolution](/configuration/shared/neighbor/).
+
+**2**:
+
+Limit or exclude devices from TUN routing by MAC address.
+Only supported on Linux with `auto_route` and `auto_redirect` enabled.
+
+See [TUN](/configuration/inbound/tun/#include_mac_address).
+
+**3**:
+
+This is not an official update from NaiveProxy. Instead, it's a Chromium codebase update maintained by Project S.
+
#### 1.13.2
* Fixes and improvements
@@ -687,7 +1085,7 @@ DNS servers are refactored for better performance and scalability.
See [DNS server](/configuration/dns/server/).
-For migration, see [Migrate to new DNS server formats](/migration/#migrate-to-new-dns-servers).
+For migration, see [Migrate to new DNS server formats](/migration/#migrate-to-new-dns-server-formats).
Compatibility for old formats will be removed in sing-box 1.14.0.
@@ -1157,7 +1555,7 @@ DNS servers are refactored for better performance and scalability.
See [DNS server](/configuration/dns/server/).
-For migration, see [Migrate to new DNS server formats](/migration/#migrate-to-new-dns-servers).
+For migration, see [Migrate to new DNS server formats](/migration/#migrate-to-new-dns-server-formats).
Compatibility for old formats will be removed in sing-box 1.14.0.
@@ -1993,7 +2391,7 @@ See [Migration](/migration/#process_path-format-update-on-windows).
The new DNS feature allows you to more precisely bypass Chinese websites via **DNS leaks**. Do not use plain local DNS
if using this method.
-See [Address Filter Fields](/configuration/dns/rule#address-filter-fields).
+See [Legacy Address Filter Fields](/configuration/dns/rule#legacy-address-filter-fields).
[Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) updated.
@@ -2007,7 +2405,7 @@ the [Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users
**5**:
The new feature allows you to cache the check results of
-[Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields) until expiration.
+[Legacy Address Filter Fields](/configuration/dns/rule/#legacy-address-filter-fields) until expiration.
**6**:
@@ -2188,7 +2586,7 @@ See [TUN](/configuration/inbound/tun) inbound.
**1**:
The new feature allows you to cache the check results of
-[Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields) until expiration.
+[Legacy Address Filter Fields](/configuration/dns/rule/#legacy-address-filter-fields) until expiration.
#### 1.9.0-alpha.7
@@ -2235,7 +2633,7 @@ See [Migration](/migration/#process_path-format-update-on-windows).
The new DNS feature allows you to more precisely bypass Chinese websites via **DNS leaks**. Do not use plain local DNS
if using this method.
-See [Address Filter Fields](/configuration/dns/rule#address-filter-fields).
+See [Legacy Address Filter Fields](/configuration/dns/rule#legacy-address-filter-fields).
[Client example](/manual/proxy/client#traffic-bypass-usage-for-chinese-users) updated.
diff --git a/docs/clients/android/features.md b/docs/clients/android/features.md
index f7f2caeec4..b76a6418e4 100644
--- a/docs/clients/android/features.md
+++ b/docs/clients/android/features.md
@@ -42,6 +42,7 @@ SFA provides an unprivileged TUN implementation through Android VpnService.
| `process_path` | :material-close: | No permission |
| `process_path_regex` | :material-close: | No permission |
| `package_name` | :material-check: | / |
+| `package_name_regex` | :material-check: | / |
| `user` | :material-close: | Use `package_name` instead |
| `user_id` | :material-close: | Use `package_name` instead |
| `wifi_ssid` | :material-check: | Fine location permission required |
diff --git a/docs/clients/apple/features.md b/docs/clients/apple/features.md
index d638517322..e1f3d7ccd1 100644
--- a/docs/clients/apple/features.md
+++ b/docs/clients/apple/features.md
@@ -44,6 +44,7 @@ SFI/SFM/SFT provides an unprivileged TUN implementation through NetworkExtension
| `process_path` | :material-close: | No permission |
| `process_path_regex` | :material-close: | No permission |
| `package_name` | :material-close: | / |
+| `package_name_regex` | :material-close: | / |
| `user` | :material-close: | No permission |
| `user_id` | :material-close: | No permission |
| `wifi_ssid` | :material-alert: | Only supported on iOS |
diff --git a/docs/configuration/dns/fakeip.md b/docs/configuration/dns/fakeip.md
index f9204d3452..a0524dc8b0 100644
--- a/docs/configuration/dns/fakeip.md
+++ b/docs/configuration/dns/fakeip.md
@@ -1,10 +1,10 @@
---
-icon: material/delete-clock
+icon: material/note-remove
---
-!!! failure "Deprecated in sing-box 1.12.0"
+!!! failure "Removed in sing-box 1.14.0"
- Legacy fake-ip configuration is deprecated and will be removed in sing-box 1.14.0, check [Migration](/migration/#migrate-to-new-dns-servers).
+ Legacy fake-ip configuration is deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, check [Migration](/migration/#migrate-to-new-dns-server-formats).
### Structure
@@ -26,6 +26,6 @@ Enable FakeIP service.
IPv4 address range for FakeIP.
-#### inet6_address
+#### inet6_range
IPv6 address range for FakeIP.
diff --git a/docs/configuration/dns/fakeip.zh.md b/docs/configuration/dns/fakeip.zh.md
index c8d5dfe301..1e5eca60b6 100644
--- a/docs/configuration/dns/fakeip.zh.md
+++ b/docs/configuration/dns/fakeip.zh.md
@@ -1,10 +1,10 @@
---
-icon: material/delete-clock
+icon: material/note-remove
---
-!!! failure "已在 sing-box 1.12.0 废弃"
+!!! failure "已在 sing-box 1.14.0 移除"
- 旧的 fake-ip 配置已废弃且将在 sing-box 1.14.0 中被移除,参阅 [迁移指南](/zh/migration/#迁移到新的-dns-服务器格式)。
+ 旧的 fake-ip 配置已在 sing-box 1.12.0 废弃且已在 sing-box 1.14.0 中被移除,参阅 [迁移指南](/zh/migration/#迁移到新的-dns-服务器格式)。
### 结构
diff --git a/docs/configuration/dns/index.md b/docs/configuration/dns/index.md
index c6750a01bb..19a183ac25 100644
--- a/docs/configuration/dns/index.md
+++ b/docs/configuration/dns/index.md
@@ -2,6 +2,12 @@
icon: material/alert-decagram
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-delete-clock: [independent_cache](#independent_cache)
+ :material-plus: [optimistic](#optimistic)
+ :material-plus: [timeout](#timeout)
+
!!! quote "Changes in sing-box 1.12.0"
:material-decagram: [servers](#servers)
@@ -25,6 +31,8 @@ icon: material/alert-decagram
"disable_expire": false,
"independent_cache": false,
"cache_capacity": 0,
+ "optimistic": false, // or {}
+ "timeout": "",
"reverse_mapping": false,
"client_subnet": "",
"fakeip": {}
@@ -39,7 +47,7 @@ icon: material/alert-decagram
|----------|---------------------------------|
| `server` | List of [DNS Server](./server/) |
| `rules` | List of [DNS Rule](./rule/) |
-| `fakeip` | [FakeIP](./fakeip/) |
+| `fakeip` | :material-note-remove: [FakeIP](./fakeip/) |
#### final
@@ -57,12 +65,20 @@ One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
Disable dns cache.
+Conflict with `optimistic`.
+
#### disable_expire
Disable dns cache expire.
+Conflict with `optimistic`.
+
#### independent_cache
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ `independent_cache` is deprecated and will be removed in sing-box 1.14.0, check [Migration](/migration/#migrate-independent-dns-cache).
+
Make each DNS server's cache independent for special purposes. If enabled, will slightly degrade performance.
#### cache_capacity
@@ -73,6 +89,44 @@ LRU cache capacity.
Value less than 1024 will be ignored.
+#### optimistic
+
+!!! question "Since sing-box 1.14.0"
+
+Enable optimistic DNS caching. When a cached DNS entry has expired but is still within the timeout window,
+the stale response is returned immediately while a background refresh is triggered.
+
+Conflict with `disable_cache` and `disable_expire`.
+
+Accepts a boolean or an object. When set to `true`, the default timeout of `3d` is used.
+
+```json
+{
+ "enabled": true,
+ "timeout": "3d"
+}
+```
+
+##### enabled
+
+Enable optimistic DNS caching.
+
+##### timeout
+
+The maximum time an expired cache entry can be served optimistically.
+
+`3d` is used by default.
+
+#### timeout
+
+!!! question "Since sing-box 1.14.0"
+
+Default timeout for each DNS query.
+
+`10s` is used by default.
+
+Can be overridden by `rules.[].timeout` (DNS rule action) or `domain_resolver.timeout`.
+
#### reverse_mapping
Stores a reverse mapping of IP addresses after responding to a DNS query in order to provide domain names when routing.
@@ -88,4 +142,4 @@ Append a `edns0-subnet` OPT extra record with the specified IP prefix to every q
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
-Can be overrides by `servers.[].client_subnet` or `rules.[].client_subnet`.
+Can be overridden by `servers.[].client_subnet` or `rules.[].client_subnet`.
diff --git a/docs/configuration/dns/index.zh.md b/docs/configuration/dns/index.zh.md
index 68927a5f41..e5c2213953 100644
--- a/docs/configuration/dns/index.zh.md
+++ b/docs/configuration/dns/index.zh.md
@@ -2,6 +2,12 @@
icon: material/alert-decagram
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-delete-clock: [independent_cache](#independent_cache)
+ :material-plus: [optimistic](#optimistic)
+ :material-plus: [timeout](#timeout)
+
!!! quote "sing-box 1.12.0 中的更改"
:material-decagram: [servers](#servers)
@@ -25,6 +31,8 @@ icon: material/alert-decagram
"disable_expire": false,
"independent_cache": false,
"cache_capacity": 0,
+ "optimistic": false, // or {}
+ "timeout": "",
"reverse_mapping": false,
"client_subnet": "",
"fakeip": {}
@@ -56,12 +64,20 @@ icon: material/alert-decagram
禁用 DNS 缓存。
+与 `optimistic` 冲突。
+
#### disable_expire
禁用 DNS 缓存过期。
+与 `optimistic` 冲突。
+
#### independent_cache
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ `independent_cache` 已在 sing-box 1.14.0 废弃,且将在 sing-box 1.16.0 中被移除,参阅[迁移指南](/zh/migration/#迁移-independent-dns-cache)。
+
使每个 DNS 服务器的缓存独立,以满足特殊目的。如果启用,将轻微降低性能。
#### cache_capacity
@@ -72,6 +88,44 @@ LRU 缓存容量。
小于 1024 的值将被忽略。
+#### optimistic
+
+!!! question "自 sing-box 1.14.0 起"
+
+启用乐观 DNS 缓存。当缓存的 DNS 条目已过期但仍在超时窗口内时,
+立即返回过期的响应,同时在后台触发刷新。
+
+与 `disable_cache` 和 `disable_expire` 冲突。
+
+接受布尔值或对象。当设置为 `true` 时,使用默认超时 `3d`。
+
+```json
+{
+ "enabled": true,
+ "timeout": "3d"
+}
+```
+
+##### enabled
+
+启用乐观 DNS 缓存。
+
+##### timeout
+
+过期缓存条目可被乐观提供的最长时间。
+
+默认使用 `3d`。
+
+#### timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+每次 DNS 查询的默认超时时间。
+
+默认使用 `10s`。
+
+可被 `rules.[].timeout`(DNS 规则动作)或 `domain_resolver.timeout` 覆盖。
+
#### reverse_mapping
在响应 DNS 查询后存储 IP 地址的反向映射以为路由目的提供域名。
@@ -88,6 +142,6 @@ LRU 缓存容量。
可以被 `servers.[].client_subnet` 或 `rules.[].client_subnet` 覆盖。
-#### fakeip
+#### fakeip :material-note-remove:
[FakeIP](./fakeip/) 设置。
diff --git a/docs/configuration/dns/rule.md b/docs/configuration/dns/rule.md
index 4348674847..1fc4eafaf3 100644
--- a/docs/configuration/dns/rule.md
+++ b/docs/configuration/dns/rule.md
@@ -2,6 +2,21 @@
icon: material/alert-decagram
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [source_mac_address](#source_mac_address)
+ :material-plus: [source_hostname](#source_hostname)
+ :material-plus: [preferred_by](#preferred_by)
+ :material-plus: [match_response](#match_response)
+ :material-delete-clock: [rule_set_ip_cidr_accept_empty](#rule_set_ip_cidr_accept_empty)
+ :material-plus: [response_rcode](#response_rcode)
+ :material-plus: [response_answer](#response_answer)
+ :material-plus: [response_ns](#response_ns)
+ :material-plus: [response_extra](#response_extra)
+ :material-plus: [package_name_regex](#package_name_regex)
+ :material-alert: [ip_version](#ip_version)
+ :material-alert: [query_type](#query_type)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [interface_address](#interface_address)
@@ -89,12 +104,6 @@ icon: material/alert-decagram
"192.168.0.1"
],
"source_ip_is_private": false,
- "ip_cidr": [
- "10.0.0.0/24",
- "192.168.0.1"
- ],
- "ip_is_private": false,
- "ip_accept_any": false,
"source_port": [
12345
],
@@ -124,6 +133,9 @@ icon: material/alert-decagram
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"user": [
"sekai"
],
@@ -149,6 +161,16 @@ icon: material/alert-decagram
"default_interface_address": [
"2000::/3"
],
+ "source_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "source_hostname": [
+ "my-device"
+ ],
+ "preferred_by": [
+ "local",
+ "ts-dns"
+ ],
"wifi_ssid": [
"My WIFI"
],
@@ -160,7 +182,17 @@ icon: material/alert-decagram
"geosite-cn"
],
"rule_set_ip_cidr_match_source": false,
- "rule_set_ip_cidr_accept_empty": false,
+ "match_response": false,
+ "ip_cidr": [
+ "10.0.0.0/24",
+ "192.168.0.1"
+ ],
+ "ip_is_private": false,
+ "ip_accept_any": false,
+ "response_rcode": "",
+ "response_answer": [],
+ "response_ns": [],
+ "response_extra": [],
"invert": false,
"outbound": [
"direct"
@@ -169,7 +201,8 @@ icon: material/alert-decagram
"server": "local",
// Deprecated
-
+
+ "rule_set_ip_cidr_accept_empty": false,
"rule_set_ipcidr_match_source": false,
"geosite": [
"cn"
@@ -217,12 +250,46 @@ Tags of [Inbound](/configuration/inbound/).
#### ip_version
+!!! quote "Changes in sing-box 1.14.0"
+
+ This field now also applies when a DNS rule is matched from an internal
+ domain resolution that does not target a specific DNS server, such as a
+ [`resolve`](../../route/rule_action/#resolve) route rule action without a
+ `server` set. In earlier versions, only DNS queries received from a
+ client evaluated this field. See
+ [Migration](/migration/#ip_version-and-query_type-behavior-changes-in-dns-rules)
+ for the full list.
+
+ Setting this field makes the DNS rule incompatible in the same DNS
+ configuration with Legacy Address Filter Fields in DNS rules, the Legacy
+ `strategy` DNS rule action option, and the Legacy
+ `rule_set_ip_cidr_accept_empty` DNS rule item. To combine with
+ address-based filtering, use the [`evaluate`](../rule_action/#evaluate)
+ action and [`match_response`](#match_response).
+
4 (A DNS query) or 6 (AAAA DNS query).
Not limited if empty.
#### query_type
+!!! quote "Changes in sing-box 1.14.0"
+
+ This field now also applies when a DNS rule is matched from an internal
+ domain resolution that does not target a specific DNS server, such as a
+ [`resolve`](../../route/rule_action/#resolve) route rule action without a
+ `server` set. In earlier versions, only DNS queries received from a
+ client evaluated this field. See
+ [Migration](/migration/#ip_version-and-query_type-behavior-changes-in-dns-rules)
+ for the full list.
+
+ Setting this field makes the DNS rule incompatible in the same DNS
+ configuration with Legacy Address Filter Fields in DNS rules, the Legacy
+ `strategy` DNS rule action option, and the Legacy
+ `rule_set_ip_cidr_accept_empty` DNS rule item. To combine with
+ address-based filtering, use the [`evaluate`](../rule_action/#evaluate)
+ action and [`match_response`](#match_response).
+
DNS query type. Values can be integers or type name strings.
#### network
@@ -325,6 +392,12 @@ Match process path using regular expression.
Match android package name.
+#### package_name_regex
+
+!!! question "Since sing-box 1.14.0"
+
+Match android package name using regular expression.
+
#### user
!!! quote ""
@@ -408,6 +481,40 @@ Matches network interface (same values as `network_type`) address.
Match default interface address.
+#### source_mac_address
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux, macOS, or in graphical clients on Android and macOS. See [Neighbor Resolution](/configuration/shared/neighbor/) for setup.
+
+Match source device MAC address.
+
+#### source_hostname
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux, macOS, or in graphical clients on Android and macOS. See [Neighbor Resolution](/configuration/shared/neighbor/) for setup.
+
+Match source device hostname from DHCP leases.
+
+#### preferred_by
+
+!!! question "Since sing-box 1.14.0"
+
+Match specified DNS servers' preferred domains.
+
+| Type | Match |
+|-------------|------------------------------------------------------------------------------|
+| `hosts` | Match predefined entries and entries in hosts files |
+| `local` | Match hosts entries, neighbor-resolved hosts, and mDNS local domains |
+| `mdns` | Match mDNS local domains (`*.local.` and IPv4/IPv6 link-local reverse zones) |
+| `tailscale` | Match MagicDNS hosts and DNS route suffixes |
+| `resolved` | Match split DNS and search domains from systemd-resolved links |
+
#### wifi_ssid
!!! quote ""
@@ -446,6 +553,25 @@ Make `ip_cidr` rule items in rule-sets match the source IP.
Make `ip_cidr` rule items in rule-sets match the source IP.
+#### match_response
+
+!!! question "Since sing-box 1.14.0"
+
+Enable response-based matching. When enabled, this rule matches against the evaluated response
+(set by a preceding [`evaluate`](/configuration/dns/rule_action/#evaluate) action)
+instead of only matching the original query.
+
+The evaluated response can also be returned directly by a later [`respond`](/configuration/dns/rule_action/#respond) action.
+
+Required for Response Match Fields (`response_rcode`, `response_answer`, `response_ns`, `response_extra`).
+Also required for `ip_cidr`, `ip_is_private`, and `ip_accept_any` when used with `evaluate` or Response Match Fields.
+
+#### ip_accept_any
+
+!!! question "Since sing-box 1.12.0"
+
+Match when the DNS query response contains at least one address.
+
#### invert
Invert match result.
@@ -490,7 +616,12 @@ See [DNS Rule Actions](../rule_action/) for details.
Moved to [DNS Rule Action](../rule_action#route).
-### Address Filter Fields
+### Legacy Address Filter Fields
+
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ Legacy Address Filter Fields are deprecated and will be removed in sing-box 1.16.0,
+ check [Migration](/migration/#migrate-address-filter-fields-to-response-matching).
Only takes effect for address requests (A/AAAA/HTTPS). When the query results do not match the address filtering rule items, the current rule will be skipped.
@@ -516,23 +647,61 @@ Match GeoIP with query response.
Match IP CIDR with query response.
+As a Legacy Address Filter Field, deprecated. Use with `match_response` instead,
+check [Migration](/migration/#migrate-address-filter-fields-to-response-matching).
+
#### ip_is_private
!!! question "Since sing-box 1.9.0"
Match private IP with query response.
+As a Legacy Address Filter Field, deprecated. Use with `match_response` instead,
+check [Migration](/migration/#migrate-address-filter-fields-to-response-matching).
+
#### rule_set_ip_cidr_accept_empty
!!! question "Since sing-box 1.10.0"
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ `rule_set_ip_cidr_accept_empty` is deprecated and will be removed in sing-box 1.16.0,
+ check [Migration](/migration/#migrate-address-filter-fields-to-response-matching).
+
Make `ip_cidr` rules in rule-sets accept empty query response.
-#### ip_accept_any
+### Response Match Fields
-!!! question "Since sing-box 1.12.0"
+!!! question "Since sing-box 1.14.0"
+
+Match fields for the evaluated response. Require `match_response` to be set to `true`
+and a preceding rule with [`evaluate`](/configuration/dns/rule_action/#evaluate) action to populate the response.
+
+That evaluated response may also be returned directly by a later [`respond`](/configuration/dns/rule_action/#respond) action.
+
+#### response_rcode
+
+Match DNS response code.
+
+Accepted values are the same as in the [predefined action rcode](/configuration/dns/rule_action/#rcode).
+
+#### response_answer
+
+Match DNS answer records.
+
+Record format is the same as in [predefined action answer](/configuration/dns/rule_action/#answer).
+
+#### response_ns
+
+Match DNS name server records.
+
+Record format is the same as in [predefined action ns](/configuration/dns/rule_action/#ns).
+
+#### response_extra
+
+Match DNS extra records.
-Match any IP with query response.
+Record format is the same as in [predefined action extra](/configuration/dns/rule_action/#extra).
### Logical Fields
diff --git a/docs/configuration/dns/rule.zh.md b/docs/configuration/dns/rule.zh.md
index f35cfc7e3e..c56e7f5bfc 100644
--- a/docs/configuration/dns/rule.zh.md
+++ b/docs/configuration/dns/rule.zh.md
@@ -2,6 +2,21 @@
icon: material/alert-decagram
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [source_mac_address](#source_mac_address)
+ :material-plus: [source_hostname](#source_hostname)
+ :material-plus: [preferred_by](#preferred_by)
+ :material-plus: [match_response](#match_response)
+ :material-delete-clock: [rule_set_ip_cidr_accept_empty](#rule_set_ip_cidr_accept_empty)
+ :material-plus: [response_rcode](#response_rcode)
+ :material-plus: [response_answer](#response_answer)
+ :material-plus: [response_ns](#response_ns)
+ :material-plus: [response_extra](#response_extra)
+ :material-plus: [package_name_regex](#package_name_regex)
+ :material-alert: [ip_version](#ip_version)
+ :material-alert: [query_type](#query_type)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [interface_address](#interface_address)
@@ -89,12 +104,6 @@ icon: material/alert-decagram
"192.168.0.1"
],
"source_ip_is_private": false,
- "ip_cidr": [
- "10.0.0.0/24",
- "192.168.0.1"
- ],
- "ip_is_private": false,
- "ip_accept_any": false,
"source_port": [
12345
],
@@ -124,6 +133,9 @@ icon: material/alert-decagram
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"user": [
"sekai"
],
@@ -149,6 +161,16 @@ icon: material/alert-decagram
"default_interface_address": [
"2000::/3"
],
+ "source_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "source_hostname": [
+ "my-device"
+ ],
+ "preferred_by": [
+ "local",
+ "ts-dns"
+ ],
"wifi_ssid": [
"My WIFI"
],
@@ -160,7 +182,17 @@ icon: material/alert-decagram
"geosite-cn"
],
"rule_set_ip_cidr_match_source": false,
- "rule_set_ip_cidr_accept_empty": false,
+ "match_response": false,
+ "ip_cidr": [
+ "10.0.0.0/24",
+ "192.168.0.1"
+ ],
+ "ip_is_private": false,
+ "ip_accept_any": false,
+ "response_rcode": "",
+ "response_answer": [],
+ "response_ns": [],
+ "response_extra": [],
"invert": false,
"outbound": [
"direct"
@@ -169,6 +201,8 @@ icon: material/alert-decagram
"server": "local",
// 已弃用
+
+ "rule_set_ip_cidr_accept_empty": false,
"rule_set_ipcidr_match_source": false,
"geosite": [
"cn"
@@ -216,12 +250,38 @@ icon: material/alert-decagram
#### ip_version
+!!! quote "sing-box 1.14.0 中的更改"
+
+ 此字段现在也会在 DNS 规则被未指定具体 DNS 服务器的内部域名解析匹配时生效,
+ 例如未设置 `server` 的 [`resolve`](../../route/rule_action/#resolve) 路由规则动作。
+ 此前只有来自客户端的 DNS 查询才会评估此字段。完整列表参阅
+ [迁移指南](/zh/migration/#dns-规则中的-ip_version-和-query_type-行为更改)。
+
+ 在 DNS 规则中设置此字段后,该 DNS 规则在同一 DNS 配置中不能与
+ 旧版地址筛选字段 (DNS 规则)、旧版 DNS 规则动作 `strategy` 选项,
+ 或旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项共存。如需与
+ 基于地址的筛选组合,请使用 [`evaluate`](../rule_action/#evaluate) 动作和
+ [`match_response`](#match_response)。
+
4 (A DNS 查询) 或 6 (AAAA DNS 查询)。
默认不限制。
#### query_type
+!!! quote "sing-box 1.14.0 中的更改"
+
+ 此字段现在也会在 DNS 规则被未指定具体 DNS 服务器的内部域名解析匹配时生效,
+ 例如未设置 `server` 的 [`resolve`](../../route/rule_action/#resolve) 路由规则动作。
+ 此前只有来自客户端的 DNS 查询才会评估此字段。完整列表参阅
+ [迁移指南](/zh/migration/#dns-规则中的-ip_version-和-query_type-行为更改)。
+
+ 在 DNS 规则中设置此字段后,该 DNS 规则在同一 DNS 配置中不能与
+ 旧版地址筛选字段 (DNS 规则)、旧版 DNS 规则动作 `strategy` 选项,
+ 或旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项共存。如需与
+ 基于地址的筛选组合,请使用 [`evaluate`](../rule_action/#evaluate) 动作和
+ [`match_response`](#match_response)。
+
DNS 查询类型。值可以为整数或者类型名称字符串。
#### network
@@ -324,6 +384,12 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
匹配 Android 应用包名。
+#### package_name_regex
+
+!!! question "自 sing-box 1.14.0 起"
+
+使用正则表达式匹配 Android 应用包名。
+
#### user
!!! quote ""
@@ -407,6 +473,40 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
匹配默认接口地址。
+#### source_mac_address
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux、macOS,或在 Android 和 macOS 图形客户端中支持。参阅 [邻居解析](/configuration/shared/neighbor/) 了解设置方法。
+
+匹配源设备 MAC 地址。
+
+#### source_hostname
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux、macOS,或在 Android 和 macOS 图形客户端中支持。参阅 [邻居解析](/configuration/shared/neighbor/) 了解设置方法。
+
+匹配源设备从 DHCP 租约获取的主机名。
+
+#### preferred_by
+
+!!! question "自 sing-box 1.14.0 起"
+
+匹配指定 DNS 服务器的首选域名。
+
+| 类型 | 匹配 |
+|-------------|-------------------------------------------------------------|
+| `hosts` | 匹配预定义条目和 hosts 文件中的条目 |
+| `local` | 匹配 hosts 中的条目、邻居解析得到的主机名以及 mDNS 本地域名 |
+| `mdns` | 匹配 mDNS 本地域名(`*.local.` 以及 IPv4/IPv6 链路本地反向区域) |
+| `tailscale` | 匹配 MagicDNS 主机和 DNS 路由后缀 |
+| `resolved` | 匹配 systemd-resolved 链路中的分流域名和搜索域 |
+
#### wifi_ssid
!!! quote ""
@@ -445,6 +545,23 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
使规则集中的 `ip_cidr` 规则匹配源 IP。
+#### match_response
+
+!!! question "自 sing-box 1.14.0 起"
+
+启用响应匹配。启用后,此规则将匹配已评估的响应(由前序 [`evaluate`](/zh/configuration/dns/rule_action/#evaluate) 动作设置),而不仅是匹配原始查询。
+
+该已评估的响应也可以被后续的 [`respond`](/zh/configuration/dns/rule_action/#respond) 动作直接返回。
+
+响应匹配字段(`response_rcode`、`response_answer`、`response_ns`、`response_extra`)需要此选项。
+当与 `evaluate` 或响应匹配字段一起使用时,`ip_cidr`、`ip_is_private` 和 `ip_accept_any` 也需要此选项。
+
+#### ip_accept_any
+
+!!! question "自 sing-box 1.12.0 起"
+
+当 DNS 查询响应包含至少一个地址时匹配。
+
#### invert
反选匹配结果。
@@ -489,7 +606,12 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
已移动到 [DNS 规则动作](../rule_action#route).
-### 地址筛选字段
+### 旧版地址筛选字段
+
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ 旧版地址筛选字段已废弃,且将在 sing-box 1.16.0 中被移除,
+ 参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
仅对地址请求 (A/AAAA/HTTPS) 生效。 当查询结果与地址筛选规则项不匹配时,将跳过当前规则。
@@ -516,24 +638,62 @@ Available values: `wifi`, `cellular`, `ethernet` and `other`.
与查询响应匹配 IP CIDR。
+作为旧版地址筛选字段已废弃。请改为配合 `match_response` 使用,
+参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
+
#### ip_is_private
!!! question "自 sing-box 1.9.0 起"
与查询响应匹配非公开 IP。
-#### ip_accept_any
-
-!!! question "自 sing-box 1.12.0 起"
-
-匹配任意 IP。
+作为旧版地址筛选字段已废弃。请改为配合 `match_response` 使用,
+参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
#### rule_set_ip_cidr_accept_empty
!!! question "自 sing-box 1.10.0 起"
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ `rule_set_ip_cidr_accept_empty` 已废弃且将在 sing-box 1.16.0 中被移除,
+ 参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
+
使规则集中的 `ip_cidr` 规则接受空查询响应。
+### 响应匹配字段
+
+!!! question "自 sing-box 1.14.0 起"
+
+已评估的响应的匹配字段。需要将 `match_response` 设为 `true`,
+且需要前序规则使用 [`evaluate`](/zh/configuration/dns/rule_action/#evaluate) 动作来填充响应。
+
+该已评估的响应也可以被后续的 [`respond`](/zh/configuration/dns/rule_action/#respond) 动作直接返回。
+
+#### response_rcode
+
+匹配 DNS 响应码。
+
+接受的值与 [predefined 动作 rcode](/zh/configuration/dns/rule_action/#rcode) 中相同。
+
+#### response_answer
+
+匹配 DNS 应答记录。
+
+记录格式与 [predefined 动作 answer](/zh/configuration/dns/rule_action/#answer) 中相同。
+
+#### response_ns
+
+匹配 DNS 名称服务器记录。
+
+记录格式与 [predefined 动作 ns](/zh/configuration/dns/rule_action/#ns) 中相同。
+
+#### response_extra
+
+匹配 DNS 额外记录。
+
+记录格式与 [predefined 动作 extra](/zh/configuration/dns/rule_action/#extra) 中相同。
+
### 逻辑字段
#### type
diff --git a/docs/configuration/dns/rule_action.md b/docs/configuration/dns/rule_action.md
index db9033f8b7..3555d6ede3 100644
--- a/docs/configuration/dns/rule_action.md
+++ b/docs/configuration/dns/rule_action.md
@@ -2,6 +2,14 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-delete-clock: [strategy](#strategy)
+ :material-plus: [evaluate](#evaluate)
+ :material-plus: [respond](#respond)
+ :material-plus: [disable_optimistic_cache](#disable_optimistic_cache)
+ :material-plus: [timeout](#timeout)
+
!!! quote "Changes in sing-box 1.12.0"
:material-plus: [strategy](#strategy)
@@ -17,7 +25,9 @@ icon: material/new-box
"server": "",
"strategy": "",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
@@ -34,6 +44,10 @@ Tag of target server.
!!! question "Since sing-box 1.12.0"
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ `strategy` is deprecated in sing-box 1.14.0 and will be removed in sing-box 1.16.0.
+
Set domain strategy for this query.
One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
@@ -42,17 +56,108 @@ One of `prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`.
Disable cache and save cache in this query.
+#### disable_optimistic_cache
+
+!!! question "Since sing-box 1.14.0"
+
+Disable optimistic DNS caching in this query.
+
+#### rewrite_ttl
+
+Rewrite TTL in DNS responses.
+
+#### timeout
+
+!!! question "Since sing-box 1.14.0"
+
+Override the DNS query timeout for matched queries.
+
+Will override `dns.timeout`.
+
+#### client_subnet
+
+Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
+
+If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
+
+Will override `dns.client_subnet`.
+
+### evaluate
+
+!!! question "Since sing-box 1.14.0"
+
+```json
+{
+ "action": "evaluate",
+ "server": "",
+ "disable_cache": false,
+ "disable_optimistic_cache": false,
+ "rewrite_ttl": null,
+ "timeout": "",
+ "client_subnet": null
+}
+```
+
+`evaluate` sends a DNS query to the specified server and saves the evaluated response for subsequent rules
+to match against using [`match_response`](/configuration/dns/rule/#match_response) and response fields.
+Unlike `route`, it does **not** terminate rule evaluation.
+
+Only allowed on top-level DNS rules (not inside logical sub-rules).
+Rules that use [`match_response`](/configuration/dns/rule/#match_response) or Response Match Fields
+require a preceding top-level rule with `evaluate` action. A rule's own `evaluate` action
+does not satisfy this requirement, because matching happens before the action runs.
+
+#### server
+
+==Required==
+
+Tag of target server.
+
+#### disable_cache
+
+Disable cache and save cache in this query.
+
+#### disable_optimistic_cache
+
+!!! question "Since sing-box 1.14.0"
+
+Disable optimistic DNS caching in this query.
+
#### rewrite_ttl
Rewrite TTL in DNS responses.
+#### timeout
+
+!!! question "Since sing-box 1.14.0"
+
+Override the DNS query timeout for matched queries.
+
+Will override `dns.timeout`.
+
#### client_subnet
Append a `edns0-subnet` OPT extra record with the specified IP prefix to every query by default.
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
-Will overrides `dns.client_subnet`.
+Will override `dns.client_subnet`.
+
+### respond
+
+!!! question "Since sing-box 1.14.0"
+
+```json
+{
+ "action": "respond"
+}
+```
+
+`respond` terminates rule evaluation and returns the evaluated response from a preceding [`evaluate`](/configuration/dns/rule_action/#evaluate) action.
+
+This action does not send a new DNS query and has no extra options.
+
+Only allowed after a preceding top-level `evaluate` rule. If the action is reached without an evaluated response at runtime, the request fails with an error instead of falling through to later rules.
### route-options
@@ -60,7 +165,9 @@ Will overrides `dns.client_subnet`.
{
"action": "route-options",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
diff --git a/docs/configuration/dns/rule_action.zh.md b/docs/configuration/dns/rule_action.zh.md
index 9e59c6bd2b..756051dd9b 100644
--- a/docs/configuration/dns/rule_action.zh.md
+++ b/docs/configuration/dns/rule_action.zh.md
@@ -2,6 +2,14 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-delete-clock: [strategy](#strategy)
+ :material-plus: [evaluate](#evaluate)
+ :material-plus: [respond](#respond)
+ :material-plus: [disable_optimistic_cache](#disable_optimistic_cache)
+ :material-plus: [timeout](#timeout)
+
!!! quote "sing-box 1.12.0 中的更改"
:material-plus: [strategy](#strategy)
@@ -17,7 +25,9 @@ icon: material/new-box
"server": "",
"strategy": "",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
@@ -34,6 +44,10 @@ icon: material/new-box
!!! question "自 sing-box 1.12.0 起"
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ `strategy` 已在 sing-box 1.14.0 废弃,且将在 sing-box 1.16.0 中被移除。
+
为此查询设置域名策略。
可选项:`prefer_ipv4` `prefer_ipv6` `ipv4_only` `ipv6_only`。
@@ -42,10 +56,24 @@ icon: material/new-box
在此查询中禁用缓存。
+#### disable_optimistic_cache
+
+!!! question "自 sing-box 1.14.0 起"
+
+在此查询中禁用乐观 DNS 缓存。
+
#### rewrite_ttl
重写 DNS 回应中的 TTL。
+#### timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+覆盖匹配查询的 DNS 查询超时时间。
+
+将覆盖 `dns.timeout`。
+
#### client_subnet
默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
@@ -54,13 +82,90 @@ icon: material/new-box
将覆盖 `dns.client_subnet`.
+### evaluate
+
+!!! question "自 sing-box 1.14.0 起"
+
+```json
+{
+ "action": "evaluate",
+ "server": "",
+ "disable_cache": false,
+ "disable_optimistic_cache": false,
+ "rewrite_ttl": null,
+ "timeout": "",
+ "client_subnet": null
+}
+```
+
+`evaluate` 向指定服务器发送 DNS 查询并保存已评估的响应,供后续规则通过 [`match_response`](/zh/configuration/dns/rule/#match_response) 和响应字段进行匹配。与 `route` 不同,它**不会**终止规则评估。
+
+仅允许在顶层 DNS 规则中使用(不可在逻辑子规则内部使用)。
+使用 [`match_response`](/zh/configuration/dns/rule/#match_response) 或响应匹配字段的规则,
+需要位于更早的顶层 `evaluate` 规则之后。规则自身的 `evaluate` 动作不能满足这个条件,
+因为匹配发生在动作执行之前。
+
+#### server
+
+==必填==
+
+目标 DNS 服务器的标签。
+
+#### disable_cache
+
+在此查询中禁用缓存。
+
+#### disable_optimistic_cache
+
+!!! question "自 sing-box 1.14.0 起"
+
+在此查询中禁用乐观 DNS 缓存。
+
+#### rewrite_ttl
+
+重写 DNS 回应中的 TTL。
+
+#### timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+覆盖匹配查询的 DNS 查询超时时间。
+
+将覆盖 `dns.timeout`。
+
+#### client_subnet
+
+默认情况下,将带有指定 IP 前缀的 `edns0-subnet` OPT 附加记录附加到每个查询。
+
+如果值是 IP 地址而不是前缀,则会自动附加 `/32` 或 `/128`。
+
+将覆盖 `dns.client_subnet`.
+
+### respond
+
+!!! question "自 sing-box 1.14.0 起"
+
+```json
+{
+ "action": "respond"
+}
+```
+
+`respond` 会终止规则评估,并直接返回前序 [`evaluate`](/zh/configuration/dns/rule_action/#evaluate) 动作保存的已评估的响应。
+
+此动作不会发起新的 DNS 查询,也没有额外选项。
+
+只能用于前面已有顶层 `evaluate` 规则的场景。如果运行时命中该动作时没有已评估的响应,则请求会直接返回错误,而不是继续匹配后续规则。
+
### route-options
```json
{
"action": "route-options",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
@@ -84,7 +189,7 @@ icon: material/new-box
- `default`: 返回 REFUSED。
- `drop`: 丢弃请求。
-默认使用 `defualt`。
+默认使用 `default`。
#### no_drop
diff --git a/docs/configuration/dns/server/hosts.md b/docs/configuration/dns/server/hosts.md
index ce859cca37..2b2cdee63b 100644
--- a/docs/configuration/dns/server/hosts.md
+++ b/docs/configuration/dns/server/hosts.md
@@ -73,24 +73,51 @@ Example:
=== "Use hosts if available"
- ```json
- {
- "dns": {
- "servers": [
- {
- ...
- },
- {
- "type": "hosts",
- "tag": "hosts"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ ...
+ },
+ {
+ "type": "hosts",
+ "tag": "hosts"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "hosts",
+ "action": "route",
+ "server": "hosts"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "hosts"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ ...
+ },
+ {
+ "type": "hosts",
+ "tag": "hosts"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "hosts"
+ }
+ ]
}
- ]
- }
- }
- ```
\ No newline at end of file
+ }
+ ```
\ No newline at end of file
diff --git a/docs/configuration/dns/server/hosts.zh.md b/docs/configuration/dns/server/hosts.zh.md
index 43878f4e4b..bd4ae7638d 100644
--- a/docs/configuration/dns/server/hosts.zh.md
+++ b/docs/configuration/dns/server/hosts.zh.md
@@ -73,24 +73,51 @@ hosts 文件路径列表。
=== "如果可用则使用 hosts"
- ```json
- {
- "dns": {
- "servers": [
- {
- ...
- },
- {
- "type": "hosts",
- "tag": "hosts"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ ...
+ },
+ {
+ "type": "hosts",
+ "tag": "hosts"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "hosts",
+ "action": "route",
+ "server": "hosts"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "hosts"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ ...
+ },
+ {
+ "type": "hosts",
+ "tag": "hosts"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "hosts"
+ }
+ ]
}
- ]
- }
- }
- ```
\ No newline at end of file
+ }
+ ```
\ No newline at end of file
diff --git a/docs/configuration/dns/server/index.md b/docs/configuration/dns/server/index.md
index 4f10948e58..bcb0586175 100644
--- a/docs/configuration/dns/server/index.md
+++ b/docs/configuration/dns/server/index.md
@@ -2,6 +2,10 @@
icon: material/alert-decagram
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [mdns](./mdns/)
+
!!! quote "Changes in sing-box 1.12.0"
:material-plus: [type](#type)
@@ -29,7 +33,7 @@ The type of the DNS server.
| Type | Format |
|-----------------|---------------------------|
-| empty (default) | [Legacy](./legacy/) |
+| empty (default) | :material-note-remove: [Legacy](./legacy/) |
| `local` | [Local](./local/) |
| `hosts` | [Hosts](./hosts/) |
| `tcp` | [TCP](./tcp/) |
@@ -39,6 +43,7 @@ The type of the DNS server.
| `https` | [HTTPS](./https/) |
| `h3` | [HTTP/3](./http3/) |
| `dhcp` | [DHCP](./dhcp/) |
+| `mdns` | [mDNS](./mdns/) |
| `fakeip` | [Fake IP](./fakeip/) |
| `tailscale` | [Tailscale](./tailscale/) |
| `resolved` | [Resolved](./resolved/) |
diff --git a/docs/configuration/dns/server/index.zh.md b/docs/configuration/dns/server/index.zh.md
index d6deef5a33..54dd97e7f9 100644
--- a/docs/configuration/dns/server/index.zh.md
+++ b/docs/configuration/dns/server/index.zh.md
@@ -2,6 +2,10 @@
icon: material/alert-decagram
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [mdns](./mdns/)
+
!!! quote "sing-box 1.12.0 中的更改"
:material-plus: [type](#type)
@@ -29,7 +33,7 @@ DNS 服务器的类型。
| 类型 | 格式 |
|-----------------|---------------------------|
-| empty (default) | [Legacy](./legacy/) |
+| empty (default) | :material-note-remove: [Legacy](./legacy/) |
| `local` | [Local](./local/) |
| `hosts` | [Hosts](./hosts/) |
| `tcp` | [TCP](./tcp/) |
@@ -39,6 +43,7 @@ DNS 服务器的类型。
| `https` | [HTTPS](./https/) |
| `h3` | [HTTP/3](./http3/) |
| `dhcp` | [DHCP](./dhcp/) |
+| `mdns` | [mDNS](./mdns/) |
| `fakeip` | [Fake IP](./fakeip/) |
| `tailscale` | [Tailscale](./tailscale/) |
| `resolved` | [Resolved](./resolved/) |
diff --git a/docs/configuration/dns/server/legacy.md b/docs/configuration/dns/server/legacy.md
index 387d76ec26..e27b19cbfd 100644
--- a/docs/configuration/dns/server/legacy.md
+++ b/docs/configuration/dns/server/legacy.md
@@ -1,10 +1,10 @@
---
-icon: material/delete-clock
+icon: material/note-remove
---
-!!! failure "Deprecated in sing-box 1.12.0"
+!!! failure "Removed in sing-box 1.14.0"
- Legacy DNS servers is deprecated and will be removed in sing-box 1.14.0, check [Migration](/migration/#migrate-to-new-dns-servers).
+ Legacy DNS servers are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, check [Migration](/migration/#migrate-to-new-dns-server-formats).
!!! quote "Changes in sing-box 1.9.0"
@@ -108,6 +108,6 @@ Append a `edns0-subnet` OPT extra record with the specified IP prefix to every q
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
-Can be overrides by `rules.[].client_subnet`.
+Can be overridden by `rules.[].client_subnet`.
-Will overrides `dns.client_subnet`.
+Will override `dns.client_subnet`.
diff --git a/docs/configuration/dns/server/legacy.zh.md b/docs/configuration/dns/server/legacy.zh.md
index 906db47c77..2ad36839f8 100644
--- a/docs/configuration/dns/server/legacy.zh.md
+++ b/docs/configuration/dns/server/legacy.zh.md
@@ -1,10 +1,10 @@
---
-icon: material/delete-clock
+icon: material/note-remove
---
-!!! failure "Deprecated in sing-box 1.12.0"
+!!! failure "已在 sing-box 1.14.0 移除"
- 旧的 DNS 服务器配置已废弃且将在 sing-box 1.14.0 中被移除,参阅 [迁移指南](/zh/migration/#迁移到新的-dns-服务器格式)。
+ 旧的 DNS 服务器配置已在 sing-box 1.12.0 废弃且已在 sing-box 1.14.0 中被移除,参阅 [迁移指南](/zh/migration/#迁移到新的-dns-服务器格式)。
!!! quote "sing-box 1.9.0 中的更改"
diff --git a/docs/configuration/dns/server/local.md b/docs/configuration/dns/server/local.md
index aa7f095a32..39c22b065c 100644
--- a/docs/configuration/dns/server/local.md
+++ b/docs/configuration/dns/server/local.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [neighbor_domain](#neighbor_domain)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [prefer_go](#prefer_go)
@@ -19,7 +23,8 @@ icon: material/new-box
{
"type": "local",
"tag": "",
- "prefer_go": false
+ "prefer_go": false,
+ "neighbor_domain": []
// Dial Fields
}
@@ -56,6 +61,19 @@ On devices running Android versions lower than 10, this interface can only resol
2. On macOS, `local` will try DHCP first in Network Extension, since DHCP respects DIal Fields,
it will not be disabled by `prefer_go`.
+#### neighbor_domain
+
+!!! question "Since sing-box 1.14.0"
+
+A list of domain suffixes for which A/AAAA queries are answered from the
+[neighbor resolver](/configuration/shared/neighbor/) instead of the upstream.
+
+Each entry must start with `.`. Only queries whose host part (the portion
+before the suffix) contains no dots are matched; `.` matches any
+single-label name such as `nas`.
+
+Example: `[".", ".lan"]`.
+
### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/dns/server/local.zh.md b/docs/configuration/dns/server/local.zh.md
index 50ac05acd9..c19efc1e15 100644
--- a/docs/configuration/dns/server/local.zh.md
+++ b/docs/configuration/dns/server/local.zh.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [neighbor_domain](#neighbor_domain)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [prefer_go](#prefer_go)
@@ -20,6 +24,7 @@ icon: material/new-box
"type": "local",
"tag": "",
"prefer_go": false,
+ "neighbor_domain": [],
// 拨号字段
}
@@ -56,6 +61,17 @@ icon: material/new-box
2. 在 macOS 上,`local` 会在 Network Extension 中首先尝试 DHCP,由于 DHCP 遵循拨号字段,
它不会被 `prefer_go` 禁用。
+#### neighbor_domain
+
+!!! question "自 sing-box 1.14.0 起"
+
+用于从[邻居解析器](/zh/configuration/shared/neighbor/)而非上游回答 A/AAAA 查询的域后缀列表。
+
+每一项必须以 `.` 开头。仅匹配后缀之前的主机名部分不包含点的查询;
+`.` 匹配任意单标签名称,例如 `nas`。
+
+示例:`[".", ".lan"]`。
+
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/) 了解详情。
\ No newline at end of file
diff --git a/docs/configuration/dns/server/mdns.md b/docs/configuration/dns/server/mdns.md
new file mode 100644
index 0000000000..d42e071522
--- /dev/null
+++ b/docs/configuration/dns/server/mdns.md
@@ -0,0 +1,42 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+# mDNS
+
+### Structure
+
+```json
+{
+ "dns": {
+ "servers": [
+ {
+ "type": "mdns",
+ "tag": "",
+
+ "interface": [],
+
+ // Dial Fields
+ }
+ ]
+ }
+}
+```
+
+!!! info ""
+
+ You usually do not need an explicit `mdns` server in addition to a [Local](./local/) server: the local server already routes queries for `*.local.` and IPv4/IPv6 link-local reverse zones via mDNS on non-Apple platforms and via the system resolver on Apple platforms. Add an explicit `mdns` server only when you want to reference it from [`preferred_by`](../rule/#preferred_by) or use it standalone.
+
+### Fields
+
+#### interface
+
+List of network interface names to send mDNS queries on.
+
+When empty, all interfaces that are up, multicast-capable, and non-loopback are used.
+
+### Dial Fields
+
+See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/dns/server/mdns.zh.md b/docs/configuration/dns/server/mdns.zh.md
new file mode 100644
index 0000000000..3af3763e5f
--- /dev/null
+++ b/docs/configuration/dns/server/mdns.zh.md
@@ -0,0 +1,42 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+# mDNS
+
+### 结构
+
+```json
+{
+ "dns": {
+ "servers": [
+ {
+ "type": "mdns",
+ "tag": "",
+
+ "interface": [],
+
+ // 拨号字段
+ }
+ ]
+ }
+}
+```
+
+!!! info ""
+
+ 通常不需要在 [Local](./local/) 服务器之外再添加显式的 `mdns` 服务器:本地服务器已经会在非 Apple 平台通过 mDNS、在 Apple 平台通过系统解析器来回答 `*.local.` 与 IPv4/IPv6 链路本地反向区域的查询。仅当需要从 [`preferred_by`](../rule/#preferred_by) 引用,或独立使用时,才需要显式添加 `mdns` 服务器。
+
+### 字段
+
+#### interface
+
+用于发送 mDNS 查询的网络接口名称列表。
+
+留空时,将使用所有处于 up 状态、支持多播且非环回的接口。
+
+### 拨号字段
+
+参阅 [拨号字段](/zh/configuration/shared/dial/) 了解详情。
diff --git a/docs/configuration/dns/server/resolved.md b/docs/configuration/dns/server/resolved.md
index b299d31789..44a4123c43 100644
--- a/docs/configuration/dns/server/resolved.md
+++ b/docs/configuration/dns/server/resolved.md
@@ -43,29 +43,58 @@ If not enabled, `NXDOMAIN` will be returned for requests that do not match searc
=== "Split DNS only"
- ```json
- {
- "dns": {
- "servers": [
- {
- "type": "local",
- "tag": "local"
- },
- {
- "type": "resolved",
- "tag": "resolved",
- "service": "resolved"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "resolved",
+ "tag": "resolved",
+ "service": "resolved"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "resolved",
+ "action": "route",
+ "server": "resolved"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "resolved"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "resolved",
+ "tag": "resolved",
+ "service": "resolved"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "resolved"
+ }
+ ]
}
- ]
- }
- }
- ```
+ }
+ ```
=== "Use as global DNS"
diff --git a/docs/configuration/dns/server/resolved.zh.md b/docs/configuration/dns/server/resolved.zh.md
index d59f838465..6102aa8099 100644
--- a/docs/configuration/dns/server/resolved.zh.md
+++ b/docs/configuration/dns/server/resolved.zh.md
@@ -42,29 +42,58 @@ icon: material/new-box
=== "仅分割 DNS"
- ```json
- {
- "dns": {
- "servers": [
- {
- "type": "local",
- "tag": "local"
- },
- {
- "type": "resolved",
- "tag": "resolved",
- "service": "resolved"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "resolved",
+ "tag": "resolved",
+ "service": "resolved"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "resolved",
+ "action": "route",
+ "server": "resolved"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "resolved"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "resolved",
+ "tag": "resolved",
+ "service": "resolved"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "resolved"
+ }
+ ]
}
- ]
- }
- }
- ```
+ }
+ ```
=== "用作全局 DNS"
diff --git a/docs/configuration/dns/server/tailscale.md b/docs/configuration/dns/server/tailscale.md
index 5ff1166064..d28a11c635 100644
--- a/docs/configuration/dns/server/tailscale.md
+++ b/docs/configuration/dns/server/tailscale.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [accept_search_domain](#accept_search_domain)
+
!!! question "Since sing-box 1.12.0"
# Tailscale
@@ -17,7 +21,8 @@ icon: material/new-box
"tag": "",
"endpoint": "ts-ep",
- "accept_default_resolvers": false
+ "accept_default_resolvers": false,
+ "accept_search_domain": false
}
]
}
@@ -38,33 +43,70 @@ Indicates whether default DNS resolvers should be accepted for fallback queries
if not enabled, `NXDOMAIN` will be returned for non-Tailscale domain queries.
+#### accept_search_domain
+
+!!! question "Since sing-box 1.14.0"
+
+When enabled, single-label queries (e.g. `my-device`) are retried against each Tailscale search domain until one resolves.
+
+Default resolvers are not consulted for single-label queries regardless of `accept_default_resolvers`.
+
### Examples
=== "MagicDNS only"
- ```json
- {
- "dns": {
- "servers": [
- {
- "type": "local",
- "tag": "local"
- },
- {
- "type": "tailscale",
- "tag": "ts",
- "endpoint": "ts-ep"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "tailscale",
+ "tag": "ts",
+ "endpoint": "ts-ep"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "ts",
+ "action": "route",
+ "server": "ts"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "ts"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "tailscale",
+ "tag": "ts",
+ "endpoint": "ts-ep"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "ts"
+ }
+ ]
}
- ]
- }
- }
- ```
+ }
+ ```
=== "Use as global DNS"
diff --git a/docs/configuration/dns/server/tailscale.zh.md b/docs/configuration/dns/server/tailscale.zh.md
index 5cb2077693..40fae69cc7 100644
--- a/docs/configuration/dns/server/tailscale.zh.md
+++ b/docs/configuration/dns/server/tailscale.zh.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [accept_search_domain](#accept_search_domain)
+
!!! question "自 sing-box 1.12.0 起"
# Tailscale
@@ -17,7 +21,8 @@ icon: material/new-box
"tag": "",
"endpoint": "ts-ep",
- "accept_default_resolvers": false
+ "accept_default_resolvers": false,
+ "accept_search_domain": false
}
]
}
@@ -38,33 +43,70 @@ icon: material/new-box
如果未启用,对于非 Tailscale 域名查询将返回 `NXDOMAIN`。
+#### accept_search_domain
+
+!!! question "自 sing-box 1.14.0 起"
+
+启用后,单标签查询(例如 `my-device`)将依次附加 Tailscale 搜索域进行重试,直到其中一个解析成功。
+
+对于单标签查询,无论 `accept_default_resolvers` 是否启用,都不会使用默认 DNS 解析器。
+
### 示例
=== "仅 MagicDNS"
- ```json
- {
- "dns": {
- "servers": [
- {
- "type": "local",
- "tag": "local"
- },
- {
- "type": "tailscale",
- "tag": "ts",
- "endpoint": "ts-ep"
+ === ":material-card-multiple: sing-box 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "tailscale",
+ "tag": "ts",
+ "endpoint": "ts-ep"
+ }
+ ],
+ "rules": [
+ {
+ "preferred_by": "ts",
+ "action": "route",
+ "server": "ts"
+ }
+ ]
}
- ],
- "rules": [
- {
- "ip_accept_any": true,
- "server": "ts"
+ }
+ ```
+
+ === ":material-card-remove: sing-box < 1.14.0"
+
+ ```json
+ {
+ "dns": {
+ "servers": [
+ {
+ "type": "local",
+ "tag": "local"
+ },
+ {
+ "type": "tailscale",
+ "tag": "ts",
+ "endpoint": "ts-ep"
+ }
+ ],
+ "rules": [
+ {
+ "ip_accept_any": true,
+ "server": "ts"
+ }
+ ]
}
- ]
- }
- }
- ```
+ }
+ ```
=== "用作全局 DNS"
diff --git a/docs/configuration/endpoint/tailscale.md b/docs/configuration/endpoint/tailscale.md
index 6cf10e2ba9..9ecebab9ac 100644
--- a/docs/configuration/endpoint/tailscale.md
+++ b/docs/configuration/endpoint/tailscale.md
@@ -2,6 +2,11 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [control_http_client](#control_http_client)
+ :material-delete-clock: [Dial Fields](#dial-fields)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [relay_server_port](#relay_server_port)
@@ -22,6 +27,7 @@ icon: material/new-box
"state_directory": "",
"auth_key": "",
"control_url": "",
+ "control_http_client": {}, // or ""
"ephemeral": false,
"hostname": "",
"accept_routes": false,
@@ -148,10 +154,18 @@ UDP NAT expiration time.
`5m` will be used by default.
+#### control_http_client
+
+!!! question "Since sing-box 1.14.0"
+
+HTTP Client for connecting to the Tailscale control plane.
+
+See [HTTP Client Fields](/configuration/shared/http-client/) for details.
+
### Dial Fields
-!!! note
+!!! failure "Deprecated in sing-box 1.14.0"
- Dial Fields in Tailscale endpoints only control how it connects to the control plane and have nothing to do with actual connections.
+ Dial Fields in Tailscale endpoints are deprecated in sing-box 1.14.0 and will be removed in sing-box 1.16.0, use `control_http_client` instead.
See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/endpoint/tailscale.zh.md b/docs/configuration/endpoint/tailscale.zh.md
index f881dd67f2..58b4708ae2 100644
--- a/docs/configuration/endpoint/tailscale.zh.md
+++ b/docs/configuration/endpoint/tailscale.zh.md
@@ -2,6 +2,11 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [control_http_client](#control_http_client)
+ :material-delete-clock: [拨号字段](#拨号字段)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [relay_server_port](#relay_server_port)
@@ -22,6 +27,7 @@ icon: material/new-box
"state_directory": "",
"auth_key": "",
"control_url": "",
+ "control_http_client": {}, // 或 ""
"ephemeral": false,
"hostname": "",
"accept_routes": false,
@@ -147,10 +153,18 @@ UDP NAT 过期时间。
默认使用 `5m`。
+#### control_http_client
+
+!!! question "自 sing-box 1.14.0 起"
+
+用于连接 Tailscale 控制平面的 HTTP 客户端。
+
+参阅 [HTTP 客户端字段](/zh/configuration/shared/http-client/) 了解详情。
+
### 拨号字段
-!!! note
+!!! failure "已在 sing-box 1.14.0 废弃"
- Tailscale 端点中的拨号字段仅控制它如何连接到控制平面,与实际连接无关。
+ Tailscale 端点中的拨号字段已在 sing-box 1.14.0 废弃且将在 sing-box 1.16.0 中被移除,请使用 `control_http_client` 代替。
参阅 [拨号字段](/zh/configuration/shared/dial/) 了解详情。
diff --git a/docs/configuration/experimental/cache-file.md b/docs/configuration/experimental/cache-file.md
index 4ad0361c86..b93aa19065 100644
--- a/docs/configuration/experimental/cache-file.md
+++ b/docs/configuration/experimental/cache-file.md
@@ -1,5 +1,10 @@
!!! question "Since sing-box 1.8.0"
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-delete-clock: [store_rdrc](#store_rdrc)
+ :material-plus: [store_dns](#store_dns)
+
!!! quote "Changes in sing-box 1.9.0"
:material-plus: [store_rdrc](#store_rdrc)
@@ -14,7 +19,8 @@
"cache_id": "",
"store_fakeip": false,
"store_rdrc": false,
- "rdrc_timeout": ""
+ "rdrc_timeout": "",
+ "store_dns": false
}
```
@@ -42,9 +48,13 @@ Store fakeip in the cache file
#### store_rdrc
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ `store_rdrc` is deprecated and will be removed in sing-box 1.16.0, check [Migration](/migration/#migrate-store-rdrc).
+
Store rejected DNS response cache in the cache file
-The check results of [Address filter DNS rule items](/configuration/dns/rule/#address-filter-fields)
+The check results of [Legacy Address Filter Fields](/configuration/dns/rule/#legacy-address-filter-fields)
will be cached until expiration.
#### rdrc_timeout
@@ -52,3 +62,9 @@ will be cached until expiration.
Timeout of rejected DNS response cache.
`7d` is used by default.
+
+#### store_dns
+
+!!! question "Since sing-box 1.14.0"
+
+Store DNS cache in the cache file.
diff --git a/docs/configuration/experimental/cache-file.zh.md b/docs/configuration/experimental/cache-file.zh.md
index 309e13a1ea..5382f3a185 100644
--- a/docs/configuration/experimental/cache-file.zh.md
+++ b/docs/configuration/experimental/cache-file.zh.md
@@ -1,5 +1,10 @@
!!! question "自 sing-box 1.8.0 起"
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-delete-clock: [store_rdrc](#store_rdrc)
+ :material-plus: [store_dns](#store_dns)
+
!!! quote "sing-box 1.9.0 中的更改"
:material-plus: [store_rdrc](#store_rdrc)
@@ -14,7 +19,8 @@
"cache_id": "",
"store_fakeip": false,
"store_rdrc": false,
- "rdrc_timeout": ""
+ "rdrc_timeout": "",
+ "store_dns": false
}
```
@@ -40,12 +46,22 @@
#### store_rdrc
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ `store_rdrc` 已在 sing-box 1.14.0 废弃,且将在 sing-box 1.16.0 中被移除,参阅[迁移指南](/zh/migration/#迁移-store_rdrc)。
+
将拒绝的 DNS 响应缓存存储在缓存文件中。
-[地址筛选 DNS 规则项](/zh/configuration/dns/rule/#地址筛选字段) 的检查结果将被缓存至过期。
+[旧版地址筛选字段](/zh/configuration/dns/rule/#旧版地址筛选字段) 的检查结果将被缓存至过期。
#### rdrc_timeout
拒绝的 DNS 响应缓存超时。
默认使用 `7d`。
+
+#### store_dns
+
+!!! question "自 sing-box 1.14.0 起"
+
+将 DNS 缓存存储在缓存文件中。
diff --git a/docs/configuration/inbound/cloudflared.md b/docs/configuration/inbound/cloudflared.md
new file mode 100644
index 0000000000..e91d73e09b
--- /dev/null
+++ b/docs/configuration/inbound/cloudflared.md
@@ -0,0 +1,89 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+`cloudflared` inbound runs an embedded Cloudflare Tunnel client and routes all
+incoming tunnel traffic (TCP, UDP, ICMP) through sing-box's routing engine.
+
+### Structure
+
+```json
+{
+ "type": "cloudflared",
+ "tag": "",
+
+ "token": "",
+ "ha_connections": 0,
+ "protocol": "",
+ "post_quantum": false,
+ "edge_ip_version": 0,
+ "datagram_version": "",
+ "grace_period": "",
+ "region": "",
+ "control_dialer": {
+ ... // Dial Fields
+ },
+ "tunnel_dialer": {
+ ... // Dial Fields
+ }
+}
+```
+
+### Fields
+
+#### token
+
+==Required==
+
+Base64-encoded tunnel token from the Cloudflare Zero Trust dashboard
+(`Networks → Tunnels → Install connector`).
+
+#### ha_connections
+
+Number of high-availability connections to the Cloudflare edge.
+
+Capped by the number of discovered edge addresses.
+
+#### protocol
+
+Transport protocol for edge connections.
+
+One of `quic` `http2`.
+
+#### post_quantum
+
+Enable post-quantum key exchange on the control connection.
+
+#### edge_ip_version
+
+IP version used when connecting to the Cloudflare edge.
+
+One of `0` (automatic) `4` `6`.
+
+#### datagram_version
+
+Datagram protocol version used for UDP proxying over QUIC.
+
+One of `v2` `v3`. Only meaningful when `protocol` is `quic`.
+
+#### grace_period
+
+Graceful shutdown window for in-flight edge connections.
+
+#### region
+
+Cloudflare edge region selector.
+
+Conflict with endpoints embedded in `token`.
+
+#### control_dialer
+
+[Dial Fields](/configuration/shared/dial/) used when the tunnel client dials the
+Cloudflare control plane.
+
+#### tunnel_dialer
+
+[Dial Fields](/configuration/shared/dial/) used when the tunnel client dials the
+Cloudflare edge data plane.
diff --git a/docs/configuration/inbound/cloudflared.zh.md b/docs/configuration/inbound/cloudflared.zh.md
new file mode 100644
index 0000000000..65aa7dcf81
--- /dev/null
+++ b/docs/configuration/inbound/cloudflared.zh.md
@@ -0,0 +1,89 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+`cloudflared` 入站运行一个内嵌的 Cloudflare Tunnel 客户端,并将所有传入的隧道流量
+(TCP、UDP、ICMP)通过 sing-box 的路由引擎转发。
+
+### 结构
+
+```json
+{
+ "type": "cloudflared",
+ "tag": "",
+
+ "token": "",
+ "ha_connections": 0,
+ "protocol": "",
+ "post_quantum": false,
+ "edge_ip_version": 0,
+ "datagram_version": "",
+ "grace_period": "",
+ "region": "",
+ "control_dialer": {
+ ... // 拨号字段
+ },
+ "tunnel_dialer": {
+ ... // 拨号字段
+ }
+}
+```
+
+### 字段
+
+#### token
+
+==必填==
+
+来自 Cloudflare Zero Trust 仪表板的 Base64 编码隧道令牌
+(`Networks → Tunnels → Install connector`)。
+
+#### ha_connections
+
+到 Cloudflare edge 的高可用连接数。
+
+上限为已发现的 edge 地址数量。
+
+#### protocol
+
+edge 连接使用的传输协议。
+
+`quic` `http2` 之一。
+
+#### post_quantum
+
+在控制连接上启用后量子密钥交换。
+
+#### edge_ip_version
+
+连接 Cloudflare edge 时使用的 IP 版本。
+
+`0`(自动)`4` `6` 之一。
+
+#### datagram_version
+
+通过 QUIC 进行 UDP 代理时使用的数据报协议版本。
+
+`v2` `v3` 之一。仅在 `protocol` 为 `quic` 时有效。
+
+#### grace_period
+
+正在处理的 edge 连接的优雅关闭窗口。
+
+#### region
+
+Cloudflare edge 区域选择器。
+
+与 `token` 中嵌入的 endpoint 冲突。
+
+#### control_dialer
+
+隧道客户端拨向 Cloudflare 控制面时使用的
+[拨号字段](/zh/configuration/shared/dial/)。
+
+#### tunnel_dialer
+
+隧道客户端拨向 Cloudflare edge 数据面时使用的
+[拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/inbound/hysteria.md b/docs/configuration/inbound/hysteria.md
index 4725aafcea..bd30973f77 100644
--- a/docs/configuration/inbound/hysteria.md
+++ b/docs/configuration/inbound/hysteria.md
@@ -21,11 +21,16 @@
}
],
+ "tls": {},
+
+ ... // QUIC Fields
+
+ // Deprecated
+
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
- "disable_mtu_discovery": false,
- "tls": {}
+ "disable_mtu_discovery": false
}
```
@@ -76,32 +81,38 @@ Authentication password, in base64.
Authentication password.
+#### tls
+
+==Required==
+
+TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
+
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
+### Deprecated Fields
+
#### recv_window_conn
-The QUIC stream-level flow control window for receiving data.
+!!! failure "Deprecated in sing-box 1.14.0"
-`15728640 (15 MB/s)` will be used if empty.
+ Use QUIC fields `stream_receive_window` instead.
#### recv_window_client
-The QUIC connection-level flow control window for receiving data.
+!!! failure "Deprecated in sing-box 1.14.0"
-`67108864 (64 MB/s)` will be used if empty.
+ Use QUIC fields `connection_receive_window` instead.
#### max_conn_client
-The maximum number of QUIC concurrent bidirectional streams that a peer is allowed to open.
+!!! failure "Deprecated in sing-box 1.14.0"
-`1024` will be used if empty.
+ Use QUIC fields `max_concurrent_streams` instead.
#### disable_mtu_discovery
-Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.
-
-Force enabled on for systems other than Linux and Windows (according to upstream).
-
-#### tls
-
-==Required==
+!!! failure "Deprecated in sing-box 1.14.0"
-TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
\ No newline at end of file
+ Use QUIC fields `disable_path_mtu_discovery` instead.
\ No newline at end of file
diff --git a/docs/configuration/inbound/hysteria.zh.md b/docs/configuration/inbound/hysteria.zh.md
index 561d7102e2..af1be8f6de 100644
--- a/docs/configuration/inbound/hysteria.zh.md
+++ b/docs/configuration/inbound/hysteria.zh.md
@@ -21,11 +21,16 @@
}
],
+ "tls": {},
+
+ ... // QUIC 字段
+
+ // 废弃的
+
"recv_window_conn": 0,
"recv_window_client": 0,
"max_conn_client": 0,
- "disable_mtu_discovery": false,
- "tls": {}
+ "disable_mtu_discovery": false
}
```
@@ -76,32 +81,38 @@ base64 编码的认证密码。
认证密码。
+#### tls
+
+==必填==
+
+TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#入站)。
+
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
+
+### 废弃字段
+
#### recv_window_conn
-用于接收数据的 QUIC 流级流控制窗口。
+!!! failure "已在 sing-box 1.14.0 废弃"
-默认 `15728640 (15 MB/s)`。
+ 请使用 QUIC 字段 `stream_receive_window` 代替。
#### recv_window_client
-用于接收数据的 QUIC 连接级流控制窗口。
+!!! failure "已在 sing-box 1.14.0 废弃"
-默认 `67108864 (64 MB/s)`。
+ 请使用 QUIC 字段 `connection_receive_window` 代替。
#### max_conn_client
-允许对等点打开的 QUIC 并发双向流的最大数量。
+!!! failure "已在 sing-box 1.14.0 废弃"
-默认 `1024`。
+ 请使用 QUIC 字段 `max_concurrent_streams` 代替。
#### disable_mtu_discovery
-禁用路径 MTU 发现 (RFC 8899)。 数据包的大小最多为 1252 (IPv4) / 1232 (IPv6) 字节。
-
-强制为 Linux 和 Windows 以外的系统启用(根据上游)。
-
-#### tls
-
-==必填==
+!!! failure "已在 sing-box 1.14.0 废弃"
-TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#入站)。
\ No newline at end of file
+ 请使用 QUIC 字段 `disable_path_mtu_discovery` 代替。
\ No newline at end of file
diff --git a/docs/configuration/inbound/hysteria2.md b/docs/configuration/inbound/hysteria2.md
index 3b7332b064..28caae87a0 100644
--- a/docs/configuration/inbound/hysteria2.md
+++ b/docs/configuration/inbound/hysteria2.md
@@ -2,6 +2,12 @@
icon: material/alert-decagram
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [bbr_profile](#bbr_profile)
+ :material-plus: [realm](#realm)
+ :material-alert: [obfs](#obfstype)
+
!!! quote "Changes in sing-box 1.11.0"
:material-alert: [masquerade](#masquerade)
@@ -30,8 +36,20 @@ icon: material/alert-decagram
],
"ignore_client_bandwidth": false,
"tls": {},
+
+ ... // QUIC Fields
+
"masquerade": "", // or {}
- "brutal_debug": false
+ "bbr_profile": "",
+ "brutal_debug": false,
+ "realm": {
+ "server_url": "https://realm.example.com",
+ "token": "",
+ "realm_id": "",
+ "stun_servers": [],
+ "stun_domain_resolver": "", // or {}
+ "http_client": {}
+ }
}
```
@@ -58,7 +76,7 @@ Conflict with `ignore_client_bandwidth`.
#### obfs.type
-QUIC traffic obfuscator type, only available with `salamander`.
+QUIC traffic obfuscator type, one of `salamander` `gecko`.
Disabled if empty.
@@ -66,6 +84,22 @@ Disabled if empty.
QUIC traffic obfuscator password.
+#### obfs.min_packet_size
+
+!!! question "Since sing-box 1.14.0"
+
+Minimum on-wire packet size in bytes. Gecko only.
+
+`512` is used by default.
+
+#### obfs.max_packet_size
+
+!!! question "Since sing-box 1.14.0"
+
+Maximum on-wire packet size in bytes. Gecko only.
+
+`1200` is used by default.
+
#### users
Hysteria2 users
@@ -90,6 +124,10 @@ Deny clients to use the BBR CC.
TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
#### masquerade
HTTP3 server behavior (URL string configuration) when authentication fails.
@@ -141,6 +179,66 @@ Fixed response headers.
Fixed response content.
+#### bbr_profile
+
+!!! question "Since sing-box 1.14.0"
+
+BBR congestion control algorithm profile, one of `conservative` `standard` `aggressive`.
+
+`standard` is used by default.
+
#### brutal_debug
Enable debug information logging for Hysteria Brutal CC.
+
+#### realm
+
+!!! question "Since sing-box 1.14.0"
+
+Register this inbound to a Hysteria Realm rendezvous service to enable NAT traversal.
+
+The inbound discovers its public addresses via STUN, registers them on the realm, and uses UDP hole-punching to accept incoming clients without a publicly reachable listen address.
+
+See [Hysteria Realm](/configuration/service/hysteria-realm/) for the rendezvous service.
+
+#### realm.server_url
+
+==Required==
+
+Realm rendezvous service URL.
+
+#### realm.token
+
+Bearer token for the realm. Must match one of `users[].token` configured on the realm.
+
+#### realm.realm_id
+
+==Required==
+
+Slot identifier on the realm.
+
+1–64 characters, must match `^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$`.
+
+Outbounds must use the same `realm_id` to find this server.
+
+#### realm.stun_servers
+
+==Required==
+
+List of STUN servers (`host` or `host:port`) used to discover public addresses.
+
+#### realm.stun_domain_resolver
+
+Set domain resolver to use for resolving STUN server domain names.
+
+This option uses the same format as the [route DNS rule action](/configuration/dns/rule_action/#route) without the `action` field.
+
+Setting this option directly to a string is equivalent to setting `server` of this options.
+
+If empty, the default domain resolver is used.
+
+#### realm.http_client
+
+HTTP client used to talk to the realm.
+
+See [HTTP Client](/configuration/shared/http-client/) for details.
diff --git a/docs/configuration/inbound/hysteria2.zh.md b/docs/configuration/inbound/hysteria2.zh.md
index 35a3c25bc7..d59101b386 100644
--- a/docs/configuration/inbound/hysteria2.zh.md
+++ b/docs/configuration/inbound/hysteria2.zh.md
@@ -2,6 +2,12 @@
icon: material/alert-decagram
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [bbr_profile](#bbr_profile)
+ :material-plus: [realm](#realm)
+ :material-alert: [obfs](#obfstype)
+
!!! quote "sing-box 1.11.0 中的更改"
:material-alert: [masquerade](#masquerade)
@@ -30,8 +36,20 @@ icon: material/alert-decagram
],
"ignore_client_bandwidth": false,
"tls": {},
+
+ ... // QUIC 字段
+
"masquerade": "", // 或 {}
- "brutal_debug": false
+ "bbr_profile": "",
+ "brutal_debug": false,
+ "realm": {
+ "server_url": "https://realm.example.com",
+ "token": "",
+ "realm_id": "",
+ "stun_servers": [],
+ "stun_domain_resolver": "", // 或 {}
+ "http_client": {}
+ }
}
```
@@ -55,13 +73,29 @@ icon: material/alert-decagram
#### obfs.type
-QUIC 流量混淆器类型,仅可设为 `salamander`。
+QUIC 流量混淆器类型,可选 `salamander` `gecko`。
如果为空则禁用。
#### obfs.password
-QUIC 流量混淆器密码.
+QUIC 流量混淆器密码。
+
+#### obfs.min_packet_size
+
+!!! question "自 sing-box 1.14.0 起"
+
+最小线上数据包大小(字节)。仅限 Gecko。
+
+默认使用 `512`。
+
+#### obfs.max_packet_size
+
+!!! question "自 sing-box 1.14.0 起"
+
+最大线上数据包大小(字节)。仅限 Gecko。
+
+默认使用 `1200`。
#### users
@@ -87,6 +121,10 @@ Hysteria 用户
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#入站)。
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
+
#### masquerade
HTTP3 服务器认证失败时的行为 (URL 字符串配置)。
@@ -138,6 +176,66 @@ HTTP3 服务器认证失败时的行为 (对象配置)。
固定响应内容。
+#### bbr_profile
+
+!!! question "自 sing-box 1.14.0 起"
+
+BBR 拥塞控制算法配置,可选 `conservative` `standard` `aggressive`。
+
+默认使用 `standard`。
+
#### brutal_debug
启用 Hysteria Brutal CC 的调试信息日志记录。
+
+#### realm
+
+!!! question "自 sing-box 1.14.0 起"
+
+将此入站注册到 Hysteria Realm 会合服务,以启用 NAT 穿透。
+
+入站通过 STUN 发现自己的公网地址并注册到 realm,借助 UDP 打洞接受客户端连接,无需可公网直达的监听地址。
+
+会合服务参阅 [Hysteria Realm](/zh/configuration/service/hysteria-realm/)。
+
+#### realm.server_url
+
+==必填==
+
+Realm 会合服务 URL。
+
+#### realm.token
+
+Realm 的 Bearer 令牌,需与 realm 上配置的 `users[].token` 之一匹配。
+
+#### realm.realm_id
+
+==必填==
+
+Realm 上的槽位标识符。
+
+1–64 字符,需匹配 `^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$`。
+
+出站需使用相同的 `realm_id` 才能找到本服务器。
+
+#### realm.stun_servers
+
+==必填==
+
+用于发现公网地址的 STUN 服务器列表(`host` 或 `host:port`)。
+
+#### realm.stun_domain_resolver
+
+用于解析 STUN 服务器域名的域名解析器。
+
+此选项的格式与 [路由 DNS 规则动作](/zh/configuration/dns/rule_action/#route) 相同,但不包含 `action` 字段。
+
+若直接将此选项设置为字符串,则等同于设置该选项的 `server` 字段。
+
+如果为空,则使用默认域名解析器。
+
+#### realm.http_client
+
+与 realm 通信使用的 HTTP 客户端。
+
+参阅 [HTTP 客户端](/zh/configuration/shared/http-client/) 了解详情。
diff --git a/docs/configuration/inbound/index.md b/docs/configuration/inbound/index.md
index 27cc9fdbbd..316302c83d 100644
--- a/docs/configuration/inbound/index.md
+++ b/docs/configuration/inbound/index.md
@@ -22,6 +22,7 @@
| `socks` | [SOCKS](./socks/) | TCP |
| `http` | [HTTP](./http/) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) | TCP |
+| `snell` | [Snell](./snell/) | TCP |
| `vmess` | [VMess](./vmess/) | TCP |
| `trojan` | [Trojan](./trojan/) | TCP |
| `naive` | [Naive](./naive/) | :material-close: |
@@ -34,6 +35,7 @@
| `tun` | [Tun](./tun/) | :material-close: |
| `redirect` | [Redirect](./redirect/) | :material-close: |
| `tproxy` | [TProxy](./tproxy/) | :material-close: |
+| `cloudflared` | [Cloudflared](./cloudflared/) | :material-close: |
#### tag
diff --git a/docs/configuration/inbound/index.zh.md b/docs/configuration/inbound/index.zh.md
index 1e0c0c4f65..9ed80d0f65 100644
--- a/docs/configuration/inbound/index.zh.md
+++ b/docs/configuration/inbound/index.zh.md
@@ -22,6 +22,7 @@
| `socks` | [SOCKS](./socks/) | TCP |
| `http` | [HTTP](./http/) | TCP |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) | TCP |
+| `snell` | [Snell](./snell/) | TCP |
| `vmess` | [VMess](./vmess/) | TCP |
| `trojan` | [Trojan](./trojan/) | TCP |
| `naive` | [Naive](./naive/) | :material-close: |
@@ -34,6 +35,7 @@
| `tun` | [Tun](./tun/) | :material-close: |
| `redirect` | [Redirect](./redirect/) | :material-close: |
| `tproxy` | [TProxy](./tproxy/) | :material-close: |
+| `cloudflared` | [Cloudflared](./cloudflared/) | :material-close: |
#### tag
diff --git a/docs/configuration/inbound/shadowsocks.md b/docs/configuration/inbound/shadowsocks.md
index e511585756..71f1448bcf 100644
--- a/docs/configuration/inbound/shadowsocks.md
+++ b/docs/configuration/inbound/shadowsocks.md
@@ -10,7 +10,9 @@
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"managed": false,
- "multiplex": {}
+ "multiplex": {},
+ "obfs_mode": "",
+ "obfs_host": ""
}
```
@@ -94,3 +96,15 @@ Defaults to `false`. Enable this when the inbound is managed by the [SSM API](/c
#### multiplex
See [Multiplex](/configuration/shared/multiplex#inbound) for details.
+
+#### obfs_mode
+
+Simple-obfs obfuscation mode.
+
+One of `http` `tls`, or empty to disable.
+
+#### obfs_host
+
+The obfuscation hostname used for HTTP/TLS obfuscation.
+
+Defaults to `bing.com` if not set.
diff --git a/docs/configuration/inbound/shadowsocks.zh.md b/docs/configuration/inbound/shadowsocks.zh.md
index a991b0c395..5cfb4bd6ca 100644
--- a/docs/configuration/inbound/shadowsocks.zh.md
+++ b/docs/configuration/inbound/shadowsocks.zh.md
@@ -10,7 +10,9 @@
"method": "2022-blake3-aes-128-gcm",
"password": "8JCsPssfgS8tiRwiMlhARg==",
"managed": false,
- "multiplex": {}
+ "multiplex": {},
+ "obfs_mode": "",
+ "obfs_host": ""
}
```
@@ -94,3 +96,15 @@
#### multiplex
参阅 [多路复用](/zh/configuration/shared/multiplex#入站)。
+
+#### obfs_mode
+
+Simple-obfs 混淆模式。
+
+可选值为 `http` `tls`,留空则禁用混淆。
+
+#### obfs_host
+
+HTTP/TLS 混淆使用的主机名。
+
+未设置时默认为 `bing.com`。
diff --git a/docs/configuration/inbound/snell.md b/docs/configuration/inbound/snell.md
new file mode 100644
index 0000000000..0bb747ae91
--- /dev/null
+++ b/docs/configuration/inbound/snell.md
@@ -0,0 +1,87 @@
+### Structure
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-in",
+
+ ... // Listen Fields
+
+ "psk": "my-pre-shared-key",
+ "version": 4,
+ "obfs_mode": "",
+ "obfs_host": ""
+}
+```
+
+### Multi-User Structure
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-in",
+
+ ... // Listen Fields
+
+ "users": [
+ {
+ "name": "alice",
+ "psk": "alice-pre-shared-key"
+ },
+ {
+ "name": "bob",
+ "psk": "bob-pre-shared-key"
+ }
+ ],
+ "version": 4,
+ "obfs_mode": "",
+ "obfs_host": ""
+}
+```
+
+### Listen Fields
+
+See [Listen Fields](/configuration/shared/listen/) for details.
+
+### Fields
+
+#### psk
+
+==Required if `users` is not set==
+
+The pre-shared key for single-user authentication. Mutually exclusive with `users`.
+
+#### users
+
+==Required if `psk` is not set==
+
+User list for multi-user mode. Each entry has a `name` and a `psk`. Mutually exclusive with `psk`.
+
+The matched user name is available to routing rules via `auth_user`.
+
+#### version
+
+Snell protocol version. Must be `4` or `5`.
+
+Defaults to `4`.
+
+!!! note "QUIC Proxy Mode (v5)"
+ When `version` is `5`, the server automatically accepts QUIC traffic on the
+ same port. The destination address and the first QUIC Initial packet are
+ encrypted by Snell; subsequent packets are forwarded as-is (QUIC provides
+ its own encryption). No additional configuration is required.
+
+#### obfs_mode
+
+Simple-obfs obfuscation mode.
+
+One of `http` `tls`, or empty to disable.
+
+!!! warning
+ TLS obfuscation is not supported for v4/v5. Use [ShadowTLS](/configuration/inbound/shadowtls/) instead.
+
+#### obfs_host
+
+The obfuscation hostname used for HTTP/TLS obfuscation.
+
+Defaults to `bing.com` if not set.
diff --git a/docs/configuration/inbound/snell.zh.md b/docs/configuration/inbound/snell.zh.md
new file mode 100644
index 0000000000..c9e054b5c7
--- /dev/null
+++ b/docs/configuration/inbound/snell.zh.md
@@ -0,0 +1,86 @@
+### 结构
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-in",
+
+ ... // 监听字段
+
+ "psk": "my-pre-shared-key",
+ "version": 4,
+ "obfs_mode": "",
+ "obfs_host": ""
+}
+```
+
+### 多用户结构
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-in",
+
+ ... // 监听字段
+
+ "users": [
+ {
+ "name": "alice",
+ "psk": "alice-pre-shared-key"
+ },
+ {
+ "name": "bob",
+ "psk": "bob-pre-shared-key"
+ }
+ ],
+ "version": 4,
+ "obfs_mode": "",
+ "obfs_host": ""
+}
+```
+
+### 监听字段
+
+参阅 [监听字段](/zh/configuration/shared/listen/)。
+
+### 字段
+
+#### psk
+
+==未设置 `users` 时必填==
+
+单用户模式的预共享密钥,与 `users` 互斥。
+
+#### users
+
+==未设置 `psk` 时必填==
+
+多用户模式的用户列表,每项包含 `name` 和 `psk`,与 `psk` 互斥。
+
+匹配到的用户名可在路由规则中通过 `auth_user` 使用。
+
+#### version
+
+Snell 协议版本,必须为 `4` 或 `5`。
+
+默认为 `4`。
+
+!!! note "QUIC 代理模式(v5)"
+ 当 `version` 为 `5` 时,服务端自动在同一端口接收 QUIC 流量。
+ 目标地址和首个 QUIC Initial 包经 Snell 加密传输,后续包直接转发(QUIC 本身已加密)。
+ 无需额外配置。
+
+#### obfs_mode
+
+simple-obfs 混淆模式。
+
+可选 `http` `tls`,留空则禁用混淆。
+
+!!! warning
+ v4/v5 不支持 TLS 混淆,请改用 [ShadowTLS](/zh/configuration/inbound/shadowtls/)。
+
+#### obfs_host
+
+用于 HTTP/TLS 混淆的主机名。
+
+未设置时默认为 `bing.com`。
diff --git a/docs/configuration/inbound/tuic.md b/docs/configuration/inbound/tuic.md
index 8a2d8c7e06..e7d1129b24 100644
--- a/docs/configuration/inbound/tuic.md
+++ b/docs/configuration/inbound/tuic.md
@@ -18,7 +18,9 @@
"auth_timeout": "3s",
"zero_rtt_handshake": false,
"heartbeat": "10s",
- "tls": {}
+ "tls": {},
+
+ ... // QUIC Fields
}
```
@@ -75,4 +77,8 @@ Interval for sending heartbeat packets for keeping the connection alive
==Required==
-TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
\ No newline at end of file
+TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
+
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
\ No newline at end of file
diff --git a/docs/configuration/inbound/tuic.zh.md b/docs/configuration/inbound/tuic.zh.md
index ae531635e6..6a231d794e 100644
--- a/docs/configuration/inbound/tuic.zh.md
+++ b/docs/configuration/inbound/tuic.zh.md
@@ -18,7 +18,9 @@
"auth_timeout": "3s",
"zero_rtt_handshake": false,
"heartbeat": "10s",
- "tls": {}
+ "tls": {},
+
+ ... // QUIC 字段
}
```
@@ -75,4 +77,8 @@ QUIC 拥塞控制算法
==必填==
-TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#入站)。
\ No newline at end of file
+TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#入站)。
+
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
\ No newline at end of file
diff --git a/docs/configuration/inbound/tun.md b/docs/configuration/inbound/tun.md
index 74d02dc933..9af118b68a 100644
--- a/docs/configuration/inbound/tun.md
+++ b/docs/configuration/inbound/tun.md
@@ -4,8 +4,10 @@ icon: material/new-box
!!! quote "Changes in sing-box 1.14.0"
- :material-plus: [include_mac_address](#include_mac_address)
- :material-plus: [exclude_mac_address](#exclude_mac_address)
+ :material-plus: [include_mac_address](#include_mac_address)
+ :material-plus: [exclude_mac_address](#exclude_mac_address)
+ :material-plus: [dns_mode](#dns_mode)
+ :material-plus: [dns_address](#dns_address)
!!! quote "Changes in sing-box 1.13.3"
@@ -73,6 +75,11 @@ icon: material/new-box
"fdfe:dcba:9876::1/126"
],
"mtu": 9000,
+ "dns_mode": "hijack",
+ "dns_address": [
+ "172.18.0.2",
+ "fdfe:dcba:9876::2"
+ ],
"auto_route": true,
"iproute2_table_index": 2022,
"iproute2_rule_index": 9000,
@@ -134,6 +141,12 @@ icon: material/new-box
"exclude_package": [
"com.android.captiveportallogin"
],
+ "include_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "exclude_mac_address": [
+ "66:77:88:99:aa:bb"
+ ],
"platform": {
"http_proxy": {
"enabled": false,
@@ -210,6 +223,52 @@ IPv6 prefix for the tun interface.
The maximum transmission unit.
+#### dns_mode
+
+!!! question "Since sing-box 1.14.0"
+
+How DNS is handled on the TUN interface.
+
+| Mode | Description |
+|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `disabled` | Do not configure native DNS and do not hijack DNS traffic. |
+| `native` | Set the platform's native interface DNS where possible: per-interface DNS on Windows and Apple platforms, and `systemd-resolved` interface DNS on Linux. |
+| `hijack` | Same as `native`, with additional port 53 hijacking described below. Used by default. |
+
+`hijack` adds the following on top of `native`:
+
+*On Linux*: only DNS sent to non-local destinations can be intercepted.
+Traffic destined to addresses on the host's own interfaces (such as
+`127.0.0.53` or the host's LAN-side IP) is delivered through the kernel
+`local` routing table before any user rule applies, and `OUTPUT` NAT cannot
+redirect packets going through `lo`.
+
+- Without `auto_redirect`, an `iproute2` rule makes port 53 skip the `main`
+ table's specific-route lookup, forcing DNS that would otherwise be
+ delivered through a directly-attached subnet through the TUN. Destination
+ addresses are not rewritten.
+- With `auto_redirect`, an nftables rule DNATs port 53 traffic directly to
+ [`dns_address`](#dns_address).
+
+*On Windows with [`strict_route`](#strict_route)*: a WFP filter blocks port
+53 traffic going through interfaces other than the TUN.
+
+#### dns_address
+
+!!! question "Since sing-box 1.14.0"
+
+List of DNS server addresses used by [`dns_mode`](#dns_mode).
+
+When unset, sing-box derives one address per family by taking the next IP after
+the first IPv4/IPv6 entry in [`address`](#address). Connections toward those
+derived addresses are additionally hijacked into the sing-box DNS module,
+equivalent to a [`hijack-dns`](/configuration/route/rule_action/#hijack-dns)
+route action; this preserves the behaviour from before this option was added.
+
+When set, this auto-hijack is not applied; configure an explicit
+[`hijack-dns`](/configuration/route/rule_action/#hijack-dns) route rule if the
+behaviour is still required.
+
#### gso
!!! failure "Deprecated in sing-box 1.11.0"
@@ -560,6 +619,30 @@ Limit android packages in route.
Exclude android packages in route.
+#### include_mac_address
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux with `auto_route` and `auto_redirect` enabled.
+
+Limit MAC addresses in route. Not limited by default.
+
+Conflict with `exclude_mac_address`.
+
+#### exclude_mac_address
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux with `auto_route` and `auto_redirect` enabled.
+
+Exclude MAC addresses in route.
+
+Conflict with `include_mac_address`.
+
#### platform
Platform-specific settings, provided by client applications.
diff --git a/docs/configuration/inbound/tun.zh.md b/docs/configuration/inbound/tun.zh.md
index eaf5ff49c3..7471771eec 100644
--- a/docs/configuration/inbound/tun.zh.md
+++ b/docs/configuration/inbound/tun.zh.md
@@ -2,6 +2,13 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [include_mac_address](#include_mac_address)
+ :material-plus: [exclude_mac_address](#exclude_mac_address)
+ :material-plus: [dns_mode](#dns_mode)
+ :material-plus: [dns_address](#dns_address)
+
!!! quote "sing-box 1.13.3 中的更改"
:material-alert: [strict_route](#strict_route)
@@ -68,6 +75,11 @@ icon: material/new-box
"fdfe:dcba:9876::1/126"
],
"mtu": 9000,
+ "dns_mode": "hijack",
+ "dns_address": [
+ "172.18.0.2",
+ "fdfe:dcba:9876::2"
+ ],
"auto_route": true,
"iproute2_table_index": 2022,
"iproute2_rule_index": 9000,
@@ -130,6 +142,12 @@ icon: material/new-box
"exclude_package": [
"com.android.captiveportallogin"
],
+ "include_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "exclude_mac_address": [
+ "66:77:88:99:aa:bb"
+ ],
"platform": {
"http_proxy": {
"enabled": false,
@@ -211,6 +229,46 @@ tun 接口的 IPv6 前缀。
最大传输单元。
+#### dns_mode
+
+!!! question "自 sing-box 1.14.0 起"
+
+TUN 接口上 DNS 的处理方式。
+
+| 模式 | 描述 |
+|------------|-------------------------------------------------------------------------------------------------------|
+| `disabled` | 不设置原生 DNS,也不劫持 DNS 流量。 |
+| `native` | 尽可能设置平台的原生接口 DNS:Windows 与 Apple 上的接口 DNS,Linux 上的 `systemd-resolved` 接口 DNS。 |
+| `hijack` | 与 `native` 相同,并额外执行下文所述的 53 端口劫持。默认使用。 |
+
+`hijack` 在 `native` 之上额外执行:
+
+*Linux*:只能劫持发往非本机地址的 DNS。发往本机接口地址(如 `127.0.0.53`
+或本机 LAN 接口 IP)的流量由内核 `local` 路由表在所有用户规则之前直接交付,
+`OUTPUT` 链 NAT 也无法对走 `lo` 的包生效。
+
+- 未启用 `auto_redirect` 时:通过 `iproute2` 规则让 53 端口跳过 `main` 表的
+ 具体路由查找,把本来会经直连子网直接送达的 DNS 改走 TUN —— 不重写目的地址。
+- 启用 `auto_redirect` 时:通过 nftables 规则将 53 端口流量直接 DNAT 至
+ [`dns_address`](#dns_address)。
+
+*Windows 启用 [`strict_route`](#strict_route) 时*:通过 WFP 过滤器阻止经由非
+TUN 接口的 53 端口流量。
+
+#### dns_address
+
+!!! question "自 sing-box 1.14.0 起"
+
+[`dns_mode`](#dns_mode) 使用的 DNS 服务器地址列表。
+
+未设置时,sing-box 会按地址族在 [`address`](#address) 的第一个 IPv4/IPv6
+条目后面取下一个 IP 作为 DNS 服务器地址,并将流向这些推导地址的连接额外劫持到
+sing-box DNS 模块,等价于一条
+[`hijack-dns`](/zh/configuration/route/rule_action/#hijack-dns) 路由动作;这与此选项加入之前的行为一致。
+
+设置后,将不再自动劫持;如仍需此行为,请显式配置
+[`hijack-dns`](/zh/configuration/route/rule_action/#hijack-dns) 路由规则。
+
#### gso
!!! failure "已在 sing-box 1.11.0 废弃"
@@ -543,6 +601,30 @@ TCP/IP 栈。
排除路由的 Android 应用包名。
+#### include_mac_address
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux,且需要 `auto_route` 和 `auto_redirect` 已启用。
+
+限制被路由的 MAC 地址。默认不限制。
+
+与 `exclude_mac_address` 冲突。
+
+#### exclude_mac_address
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux,且需要 `auto_route` 和 `auto_redirect` 已启用。
+
+排除路由的 MAC 地址。
+
+与 `include_mac_address` 冲突。
+
#### platform
平台特定的设置,由客户端应用提供。
diff --git a/docs/configuration/index.md b/docs/configuration/index.md
index 1f6eec1375..311161c1cc 100644
--- a/docs/configuration/index.md
+++ b/docs/configuration/index.md
@@ -1,7 +1,6 @@
# Introduction
sing-box uses JSON for configuration files.
-
### Structure
```json
@@ -10,6 +9,8 @@ sing-box uses JSON for configuration files.
"dns": {},
"ntp": {},
"certificate": {},
+ "certificate_providers": [],
+ "http_clients": [],
"endpoints": [],
"inbounds": [],
"outbounds": [],
@@ -27,6 +28,8 @@ sing-box uses JSON for configuration files.
| `dns` | [DNS](./dns/) |
| `ntp` | [NTP](./ntp/) |
| `certificate` | [Certificate](./certificate/) |
+| `certificate_providers` | [Certificate Provider](./shared/certificate-provider/) |
+| `http_clients` | [HTTP Client](./shared/http-client/) |
| `endpoints` | [Endpoint](./endpoint/) |
| `inbounds` | [Inbound](./inbound/) |
| `outbounds` | [Outbound](./outbound/) |
@@ -50,4 +53,4 @@ sing-box format -w -c config.json -D config_directory
```bash
sing-box merge output.json -c config.json -D config_directory
-```
\ No newline at end of file
+```
diff --git a/docs/configuration/index.zh.md b/docs/configuration/index.zh.md
index 3bdc352187..fbb44c79e1 100644
--- a/docs/configuration/index.zh.md
+++ b/docs/configuration/index.zh.md
@@ -1,7 +1,6 @@
# 引言
sing-box 使用 JSON 作为配置文件格式。
-
### 结构
```json
@@ -10,6 +9,8 @@ sing-box 使用 JSON 作为配置文件格式。
"dns": {},
"ntp": {},
"certificate": {},
+ "certificate_providers": [],
+ "http_clients": [],
"endpoints": [],
"inbounds": [],
"outbounds": [],
@@ -27,6 +28,8 @@ sing-box 使用 JSON 作为配置文件格式。
| `dns` | [DNS](./dns/) |
| `ntp` | [NTP](./ntp/) |
| `certificate` | [证书](./certificate/) |
+| `certificate_providers` | [证书提供者](./shared/certificate-provider/) |
+| `http_clients` | [HTTP 客户端](./shared/http-client/) |
| `endpoints` | [端点](./endpoint/) |
| `inbounds` | [入站](./inbound/) |
| `outbounds` | [出站](./outbound/) |
@@ -50,4 +53,4 @@ sing-box format -w -c config.json -D config_directory
```bash
sing-box merge output.json -c config.json -D config_directory
-```
\ No newline at end of file
+```
diff --git a/docs/configuration/outbound/hysteria.md b/docs/configuration/outbound/hysteria.md
index b326e06dcd..4908799bdb 100644
--- a/docs/configuration/outbound/hysteria.md
+++ b/docs/configuration/outbound/hysteria.md
@@ -27,13 +27,18 @@ icon: material/new-box
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
- "recv_window_conn": 0,
- "recv_window": 0,
- "disable_mtu_discovery": false,
- "network": "tcp",
+ "network": "",
"tls": {},
-
+
+ ... // QUIC Fields
+
... // Dial Fields
+
+ // Deprecated
+
+ "recv_window_conn": 0,
+ "recv_window": 0,
+ "disable_mtu_discovery": false
}
```
@@ -104,24 +109,6 @@ Authentication password, in base64.
Authentication password.
-#### recv_window_conn
-
-The QUIC stream-level flow control window for receiving data.
-
-`15728640 (15 MB/s)` will be used if empty.
-
-#### recv_window
-
-The QUIC connection-level flow control window for receiving data.
-
-`67108864 (64 MB/s)` will be used if empty.
-
-#### disable_mtu_discovery
-
-Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.
-
-Force enabled on for systems other than Linux and Windows (according to upstream).
-
#### network
Enabled network
@@ -136,6 +123,30 @@ Both is enabled by default.
TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details.
+
+### Deprecated Fields
+
+#### recv_window_conn
+
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ Use QUIC fields `stream_receive_window` instead.
+
+#### recv_window
+
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ Use QUIC fields `connection_receive_window` instead.
+
+#### disable_mtu_discovery
+
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ Use QUIC fields `disable_path_mtu_discovery` instead.
diff --git a/docs/configuration/outbound/hysteria.zh.md b/docs/configuration/outbound/hysteria.zh.md
index ae1d359004..004d2d165a 100644
--- a/docs/configuration/outbound/hysteria.zh.md
+++ b/docs/configuration/outbound/hysteria.zh.md
@@ -27,13 +27,18 @@ icon: material/new-box
"obfs": "fuck me till the daylight",
"auth": "",
"auth_str": "password",
- "recv_window_conn": 0,
- "recv_window": 0,
- "disable_mtu_discovery": false,
- "network": "tcp",
+ "network": "",
"tls": {},
-
+
+ ... // QUIC 字段
+
... // 拨号字段
+
+ // 废弃的
+
+ "recv_window_conn": 0,
+ "recv_window": 0,
+ "disable_mtu_discovery": false
}
```
@@ -104,24 +109,6 @@ base64 编码的认证密码。
认证密码。
-#### recv_window_conn
-
-用于接收数据的 QUIC 流级流控制窗口。
-
-默认 `15728640 (15 MB/s)`。
-
-#### recv_window
-
-用于接收数据的 QUIC 连接级流控制窗口。
-
-默认 `67108864 (64 MB/s)`。
-
-#### disable_mtu_discovery
-
-禁用路径 MTU 发现 (RFC 8899)。 数据包的大小最多为 1252 (IPv4) / 1232 (IPv6) 字节。
-
-强制为 Linux 和 Windows 以外的系统启用(根据上游)。
-
#### network
启用的网络协议。
@@ -136,7 +123,30 @@ base64 编码的认证密码。
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#出站)。
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/)。
+
+### 废弃字段
+
+#### recv_window_conn
+
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ 请使用 QUIC 字段 `stream_receive_window` 代替。
+
+#### recv_window
+
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ 请使用 QUIC 字段 `connection_receive_window` 代替。
+
+#### disable_mtu_discovery
+
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ 请使用 QUIC 字段 `disable_path_mtu_discovery` 代替。
diff --git a/docs/configuration/outbound/hysteria2.md b/docs/configuration/outbound/hysteria2.md
index dc0a496500..1df36cfc2b 100644
--- a/docs/configuration/outbound/hysteria2.md
+++ b/docs/configuration/outbound/hysteria2.md
@@ -1,3 +1,10 @@
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [hop_interval_max](#hop_interval_max)
+ :material-plus: [bbr_profile](#bbr_profile)
+ :material-plus: [realm](#realm)
+ :material-alert: [obfs](#obfstype)
+
!!! quote "Changes in sing-box 1.11.0"
:material-plus: [server_ports](#server_ports)
@@ -9,13 +16,14 @@
{
"type": "hysteria2",
"tag": "hy2-out",
-
+
"server": "127.0.0.1",
"server_port": 1080,
"server_ports": [
"2080:3000"
],
"hop_interval": "",
+ "hop_interval_max": "",
"up_mbps": 100,
"down_mbps": 100,
"obfs": {
@@ -25,8 +33,19 @@
"password": "goofy_ahh_password",
"network": "tcp",
"tls": {},
+
+ ... // QUIC Fields
+
+ "bbr_profile": "",
"brutal_debug": false,
-
+ "realm": {
+ "server_url": "https://realm.example.com",
+ "token": "",
+ "realm_id": "",
+ "stun_servers": [],
+ "http_client": {}
+ },
+
... // Dial Fields
}
```
@@ -51,6 +70,8 @@
The server address.
+Conflicts with `realm`.
+
#### server_port
==Required==
@@ -59,13 +80,15 @@ The server port.
Ignored if `server_ports` is set.
+Conflicts with `realm`.
+
#### server_ports
!!! question "Since sing-box 1.11.0"
Server port range list.
-Conflicts with `server_port`.
+Conflicts with `server_port` and `realm`.
#### hop_interval
@@ -75,6 +98,14 @@ Port hopping interval.
`30s` is used by default.
+#### hop_interval_max
+
+!!! question "Since sing-box 1.14.0"
+
+Maximum port hopping interval, used for randomization.
+
+If set, the actual hop interval will be randomly chosen between `hop_interval` and `hop_interval_max`.
+
#### up_mbps, down_mbps
Max bandwidth, in Mbps.
@@ -83,7 +114,7 @@ If empty, the BBR congestion control algorithm will be used instead of Hysteria
#### obfs.type
-QUIC traffic obfuscator type, only available with `salamander`.
+QUIC traffic obfuscator type, one of `salamander` `gecko`.
Disabled if empty.
@@ -91,6 +122,22 @@ Disabled if empty.
QUIC traffic obfuscator password.
+#### obfs.min_packet_size
+
+!!! question "Since sing-box 1.14.0"
+
+Minimum on-wire packet size in bytes. Gecko only.
+
+`512` is used by default.
+
+#### obfs.max_packet_size
+
+!!! question "Since sing-box 1.14.0"
+
+Maximum on-wire packet size in bytes. Gecko only.
+
+`1200` is used by default.
+
#### password
Authentication password.
@@ -109,10 +156,66 @@ Both is enabled by default.
TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
+#### bbr_profile
+
+!!! question "Since sing-box 1.14.0"
+
+BBR congestion control algorithm profile, one of `conservative` `standard` `aggressive`.
+
+`standard` is used by default.
+
#### brutal_debug
Enable debug information logging for Hysteria Brutal CC.
+#### realm
+
+!!! question "Since sing-box 1.14.0"
+
+Connect to a Hysteria2 server through a Hysteria Realm rendezvous service.
+
+The outbound queries the realm for the server's current public addresses, performs UDP hole-punching, and proceeds with the normal QUIC handshake.
+
+Conflicts with `server`, `server_port` and `server_ports`.
+
+The TLS SNI defaults to the host portion of `server_url`. Set `tls.server_name` to match the certificate the Hysteria2 server presents.
+
+See [Hysteria Realm](/configuration/service/hysteria-realm/) for the rendezvous service.
+
+#### realm.server_url
+
+==Required==
+
+Realm rendezvous service URL.
+
+#### realm.token
+
+Bearer token for the realm. Must match one of `users[].token` configured on the realm.
+
+#### realm.realm_id
+
+==Required==
+
+The same slot identifier the target Hysteria2 server registered.
+
+#### realm.stun_servers
+
+==Required==
+
+List of STUN servers (`host` or `host:port`) used to discover this client's public addresses.
+
+Domain names are resolved using [`domain_resolver`](/configuration/shared/dial/#domain_resolver) from Dial Fields.
+
+#### realm.http_client
+
+HTTP client used to talk to the realm.
+
+See [HTTP Client](/configuration/shared/http-client/) for details.
+
### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/outbound/hysteria2.zh.md b/docs/configuration/outbound/hysteria2.zh.md
index bc77f4ec92..07ec96ce11 100644
--- a/docs/configuration/outbound/hysteria2.zh.md
+++ b/docs/configuration/outbound/hysteria2.zh.md
@@ -1,3 +1,10 @@
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [hop_interval_max](#hop_interval_max)
+ :material-plus: [bbr_profile](#bbr_profile)
+ :material-plus: [realm](#realm)
+ :material-alert: [obfs](#obfstype)
+
!!! quote "sing-box 1.11.0 中的更改"
:material-plus: [server_ports](#server_ports)
@@ -16,6 +23,7 @@
"2080:3000"
],
"hop_interval": "",
+ "hop_interval_max": "",
"up_mbps": 100,
"down_mbps": 100,
"obfs": {
@@ -25,8 +33,19 @@
"password": "goofy_ahh_password",
"network": "tcp",
"tls": {},
+
+ ... // QUIC 字段
+
+ "bbr_profile": "",
"brutal_debug": false,
-
+ "realm": {
+ "server_url": "https://realm.example.com",
+ "token": "",
+ "realm_id": "",
+ "stun_servers": [],
+ "http_client": {}
+ },
+
... // 拨号字段
}
```
@@ -49,6 +68,8 @@
服务器地址。
+与 `realm` 冲突。
+
#### server_port
==必填==
@@ -57,13 +78,15 @@
如果设置了 `server_ports`,则忽略此项。
+与 `realm` 冲突。
+
#### server_ports
!!! question "自 sing-box 1.11.0 起"
服务器端口范围列表。
-与 `server_port` 冲突。
+与 `server_port` 和 `realm` 冲突。
#### hop_interval
@@ -73,6 +96,14 @@
默认使用 `30s`。
+#### hop_interval_max
+
+!!! question "自 sing-box 1.14.0 起"
+
+最大端口跳跃间隔,用于随机化。
+
+如果设置,实际跳跃间隔将在 `hop_interval` 和 `hop_interval_max` 之间随机选择。
+
#### up_mbps, down_mbps
最大带宽。
@@ -81,13 +112,29 @@
#### obfs.type
-QUIC 流量混淆器类型,仅可设为 `salamander`。
+QUIC 流量混淆器类型,可选 `salamander` `gecko`。
如果为空则禁用。
#### obfs.password
-QUIC 流量混淆器密码.
+QUIC 流量混淆器密码。
+
+#### obfs.min_packet_size
+
+!!! question "自 sing-box 1.14.0 起"
+
+最小线上数据包大小(字节)。仅限 Gecko。
+
+默认使用 `512`。
+
+#### obfs.max_packet_size
+
+!!! question "自 sing-box 1.14.0 起"
+
+最大线上数据包大小(字节)。仅限 Gecko。
+
+默认使用 `1200`。
#### password
@@ -107,10 +154,66 @@ QUIC 流量混淆器密码.
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#出站)。
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
+
+#### bbr_profile
+
+!!! question "自 sing-box 1.14.0 起"
+
+BBR 拥塞控制算法配置,可选 `conservative` `standard` `aggressive`。
+
+默认使用 `standard`。
+
#### brutal_debug
启用 Hysteria Brutal CC 的调试信息日志记录。
+#### realm
+
+!!! question "自 sing-box 1.14.0 起"
+
+通过 Hysteria Realm 会合服务连接 Hysteria2 服务器。
+
+出站从 realm 查询服务器当前的公网地址,执行 UDP 打洞,然后进行常规的 QUIC 握手。
+
+与 `server`、`server_port` 和 `server_ports` 冲突。
+
+TLS SNI 默认使用 `server_url` 中的主机名。需设置 `tls.server_name` 以匹配 Hysteria2 服务器证书覆盖的名字。
+
+会合服务参阅 [Hysteria Realm](/zh/configuration/service/hysteria-realm/)。
+
+#### realm.server_url
+
+==必填==
+
+Realm 会合服务 URL。
+
+#### realm.token
+
+Realm 的 Bearer 令牌,需与 realm 上配置的 `users[].token` 之一匹配。
+
+#### realm.realm_id
+
+==必填==
+
+目标 Hysteria2 服务器注册时使用的相同槽位标识符。
+
+#### realm.stun_servers
+
+==必填==
+
+用于发现本客户端公网地址的 STUN 服务器列表(`host` 或 `host:port`)。
+
+域名通过 [拨号字段](/zh/configuration/shared/dial/) 中的 [`domain_resolver`](/zh/configuration/shared/dial/#domain_resolver) 解析。
+
+#### realm.http_client
+
+与 realm 通信使用的 HTTP 客户端。
+
+参阅 [HTTP 客户端](/zh/configuration/shared/http-client/) 了解详情。
+
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/outbound/index.md b/docs/configuration/outbound/index.md
index 47b8a96a5c..6eab225702 100644
--- a/docs/configuration/outbound/index.md
+++ b/docs/configuration/outbound/index.md
@@ -22,6 +22,7 @@
| `socks` | [SOCKS](./socks/) |
| `http` | [HTTP](./http/) |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) |
+| `snell` | [Snell](./snell/) |
| `vmess` | [VMess](./vmess/) |
| `trojan` | [Trojan](./trojan/) |
| `wireguard` | [Wireguard](./wireguard/) |
@@ -30,6 +31,7 @@
| `shadowtls` | [ShadowTLS](./shadowtls/) |
| `tuic` | [TUIC](./tuic/) |
| `hysteria2` | [Hysteria2](./hysteria2/) |
+| `mieru` | [Mieru](./mieru/) |
| `anytls` | [AnyTLS](./anytls/) |
| `tor` | [Tor](./tor/) |
| `ssh` | [SSH](./ssh/) |
diff --git a/docs/configuration/outbound/index.zh.md b/docs/configuration/outbound/index.zh.md
index a1c4a7addc..7364dd03ce 100644
--- a/docs/configuration/outbound/index.zh.md
+++ b/docs/configuration/outbound/index.zh.md
@@ -22,6 +22,7 @@
| `socks` | [SOCKS](./socks/) |
| `http` | [HTTP](./http/) |
| `shadowsocks` | [Shadowsocks](./shadowsocks/) |
+| `snell` | [Snell](./snell/) |
| `vmess` | [VMess](./vmess/) |
| `trojan` | [Trojan](./trojan/) |
| `wireguard` | [Wireguard](./wireguard/) |
@@ -30,6 +31,7 @@
| `shadowtls` | [ShadowTLS](./shadowtls/) |
| `tuic` | [TUIC](./tuic/) |
| `hysteria2` | [Hysteria2](./hysteria2/) |
+| `mieru` | [Mieru](./mieru/) |
| `anytls` | [AnyTLS](./anytls/) |
| `tor` | [Tor](./tor/) |
| `ssh` | [SSH](./ssh/) |
diff --git a/docs/configuration/outbound/mieru.md b/docs/configuration/outbound/mieru.md
new file mode 100644
index 0000000000..135403f04d
--- /dev/null
+++ b/docs/configuration/outbound/mieru.md
@@ -0,0 +1,71 @@
+---
+icon: material/new-box
+---
+
+### Structure
+
+```json
+{
+ "type": "mieru",
+ "tag": "mieru-out",
+
+ "server": "127.0.0.1",
+ "server_port": 1080,
+ "server_ports": [
+ "9000-9010",
+ "9020-9030"
+ ],
+ "transport": "TCP",
+ "username": "asdf",
+ "password": "hjkl",
+ "multiplexing": "MULTIPLEXING_LOW",
+
+ ... // Dial Fields
+}
+```
+
+### Fields
+
+#### server
+
+==Required==
+
+The server address.
+
+#### server_port
+
+The server port.
+
+Must set at least one field between `server_port` and `server_ports`.
+
+#### server_ports
+
+Server port range list.
+
+Must set at least one field between `server_port` and `server_ports`.
+
+#### transport
+
+==Required==
+
+Transmission protocol. The only allowed value is `TCP`.
+
+#### username
+
+==Required==
+
+mieru user name.
+
+#### password
+
+==Required==
+
+mieru password.
+
+#### multiplexing
+
+Multiplexing level. Supported values are `MULTIPLEXING_OFF`, `MULTIPLEXING_LOW`, `MULTIPLEXING_MIDDLE`, `MULTIPLEXING_HIGH`. `MULTIPLEXING_OFF` disables multiplexing.
+
+### Dial Fields
+
+See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/outbound/mieru.zh.md b/docs/configuration/outbound/mieru.zh.md
new file mode 100644
index 0000000000..fe9b37b83b
--- /dev/null
+++ b/docs/configuration/outbound/mieru.zh.md
@@ -0,0 +1,71 @@
+---
+icon: material/new-box
+---
+
+### 结构
+
+```json
+{
+ "type": "mieru",
+ "tag": "mieru-out",
+
+ "server": "127.0.0.1",
+ "server_port": 1080,
+ "server_ports": [
+ "9000-9010",
+ "9020-9030"
+ ],
+ "transport": "TCP",
+ "username": "asdf",
+ "password": "hjkl",
+ "multiplexing": "MULTIPLEXING_LOW",
+
+ ... // 拨号字段
+}
+```
+
+### 字段
+
+#### server
+
+==必填==
+
+服务器地址。
+
+#### server_port
+
+服务器端口。
+
+必须填写 `server_port` 和 `server_ports` 中至少一项。
+
+#### server_ports
+
+服务器端口范围列表。
+
+必须填写 `server_port` 和 `server_ports` 中至少一项。
+
+#### transport
+
+==必填==
+
+通信协议。仅可设为 `TCP`。
+
+#### username
+
+==必填==
+
+mieru 用户名。
+
+#### password
+
+==必填==
+
+mieru 密码。
+
+#### multiplexing
+
+多路复用设置。可以设为 `MULTIPLEXING_OFF`,`MULTIPLEXING_LOW`,`MULTIPLEXING_MIDDLE`,`MULTIPLEXING_HIGH`。其中 `MULTIPLEXING_OFF` 会关闭多路复用功能。
+
+### 拨号字段
+
+参阅 [拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/outbound/snell.md b/docs/configuration/outbound/snell.md
new file mode 100644
index 0000000000..4faae9f2b9
--- /dev/null
+++ b/docs/configuration/outbound/snell.md
@@ -0,0 +1,91 @@
+### Structure
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-out",
+
+ "server": "127.0.0.1",
+ "server_port": 8388,
+ "psk": "my-pre-shared-key",
+ "version": 4,
+ "reuse": false,
+ "network": "",
+ "obfs_mode": "",
+ "obfs_host": "",
+
+ ... // Dial Fields
+}
+```
+
+### Fields
+
+#### server
+
+==Required==
+
+The server address.
+
+#### server_port
+
+==Required==
+
+The server port.
+
+#### psk
+
+==Required==
+
+The pre-shared key for authentication.
+
+#### version
+
+Snell protocol version. One of `1` `2` `3` `4` `5`.
+
+Defaults to `4`.
+
+| Version | TCP | UDP |
+|---------|-----|-----------------|
+| 1, 2 | ✔ | ✘ |
+| 3, 4 | ✔ | ✔ (UoT) |
+| 5 | ✔ | ✔ (QUIC proxy) |
+
+!!! note "QUIC Proxy Mode (v5)"
+ In v5, QUIC traffic uses a dedicated proxy path: the destination address
+ and the first QUIC Initial packet are encrypted by Snell; subsequent
+ packets are forwarded as-is (QUIC provides its own encryption).
+ Other UDP traffic falls back to the standard UDP-over-TCP tunnel.
+
+#### network
+
+Enabled network, one of `tcp` `udp`.
+
+Both are enabled by default for v3/v4/v5. For v1/v2 only TCP is enabled by default (no UDP support).
+
+UDP requires version `3` or above.
+
+#### reuse
+
+Enable connection reuse (Snell v4+ only). Reuses an existing TCP connection for
+multiple sequential requests, avoiding the overhead of a new TCP and encryption
+handshake for each request.
+
+Requires the server to support Snell v4 connection reuse.
+
+Defaults to `false`.
+
+#### obfs_mode
+
+Simple-obfs obfuscation mode.
+
+One of `http` `tls`, or empty to disable.
+
+#### obfs_host
+
+The obfuscation hostname used for HTTP/TLS obfuscation.
+
+Defaults to `bing.com` if not set.
+
+### Dial Fields
+
+See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/outbound/snell.zh.md b/docs/configuration/outbound/snell.zh.md
new file mode 100644
index 0000000000..ad5bde0337
--- /dev/null
+++ b/docs/configuration/outbound/snell.zh.md
@@ -0,0 +1,87 @@
+### 结构
+
+```json
+{
+ "type": "snell",
+ "tag": "snell-out",
+
+ "server": "127.0.0.1",
+ "server_port": 8388,
+ "psk": "my-pre-shared-key",
+ "version": 4,
+ "reuse": false,
+ "network": "",
+ "obfs_mode": "",
+ "obfs_host": "",
+
+ ... // 拨号字段
+}
+```
+
+### 字段
+
+#### server
+
+==必填==
+
+服务器地址。
+
+#### server_port
+
+==必填==
+
+服务器端口。
+
+#### psk
+
+==必填==
+
+用于身份验证的预共享密钥。
+
+#### version
+
+Snell 协议版本,可选 `1` `2` `3` `4` `5`。
+
+默认为 `4`。
+
+| 版本 | TCP | UDP |
+|--------|-----|------------------|
+| 1, 2 | ✔ | ✘ |
+| 3, 4 | ✔ | ✔(UDP over TCP) |
+| 5 | ✔ | ✔(QUIC 代理) |
+
+!!! note "QUIC 代理模式(v5)"
+ v5 的 QUIC 流量采用专用代理路径:目标地址和首个 QUIC Initial 包经 Snell 加密传输,
+ 后续包直接转发(QUIC 本身已加密)。其他 UDP 流量仍走标准 UDP over TCP 隧道。
+
+#### network
+
+启用的网络,可选 `tcp` `udp`。
+
+v3/v4/v5 默认两者均启用;v1/v2 默认仅 TCP(不支持 UDP)。
+
+UDP 需要版本 `3` 及以上。
+
+#### reuse
+
+启用连接复用(仅限 Snell v4+)。复用已有的 TCP 连接串行处理多个请求,避免每次请求都重新建立 TCP 连接和加密握手的开销。
+
+需要服务端支持 Snell v4 连接复用。
+
+默认为 `false`。
+
+#### obfs_mode
+
+simple-obfs 混淆模式。
+
+可选 `http` `tls`,留空则禁用混淆。
+
+#### obfs_host
+
+用于 HTTP/TLS 混淆的主机名。
+
+未设置时默认为 `bing.com`。
+
+### 拨号字段
+
+参阅 [拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/outbound/ssh.md b/docs/configuration/outbound/ssh.md
index 45ec72b2b5..8ef49b9cac 100644
--- a/docs/configuration/outbound/ssh.md
+++ b/docs/configuration/outbound/ssh.md
@@ -1,3 +1,9 @@
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [cipher](#cipher)
+ :material-plus: [mac](#mac)
+ :material-plus: [kex_algorithm](#kex_algorithm)
+
### Structure
```json
@@ -17,6 +23,9 @@
],
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
+ "cipher": [],
+ "mac": [],
+ "kex_algorithm": [],
... // Dial Fields
}
@@ -66,6 +75,24 @@ Host key algorithms.
Client version. Random version will be used if empty.
+#### cipher
+
+!!! question "Since sing-box 1.14.0"
+
+Allowed ciphers. Default values are used if empty.
+
+#### mac
+
+!!! question "Since sing-box 1.14.0"
+
+Allowed MAC algorithms. Default values are used if empty.
+
+#### kex_algorithm
+
+!!! question "Since sing-box 1.14.0"
+
+Allowed key exchange algorithms. Default values are used if empty.
+
### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/outbound/ssh.zh.md b/docs/configuration/outbound/ssh.zh.md
index e538e64aa8..cb2c0345e4 100644
--- a/docs/configuration/outbound/ssh.zh.md
+++ b/docs/configuration/outbound/ssh.zh.md
@@ -1,3 +1,9 @@
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [cipher](#cipher)
+ :material-plus: [mac](#mac)
+ :material-plus: [kex_algorithm](#kex_algorithm)
+
### 结构
```json
@@ -17,6 +23,9 @@
],
"host_key_algorithms": [],
"client_version": "SSH-2.0-OpenSSH_7.4p1",
+ "cipher": [],
+ "mac": [],
+ "kex_algorithm": [],
... // 拨号字段
}
@@ -66,6 +75,24 @@ SSH 用户, 默认使用 root。
客户端版本,默认使用随机值。
+#### cipher
+
+!!! question "自 sing-box 1.14.0 起"
+
+允许的加密算法。留空使用默认值。
+
+#### mac
+
+!!! question "自 sing-box 1.14.0 起"
+
+允许的 MAC 算法。留空使用默认值。
+
+#### kex_algorithm
+
+!!! question "自 sing-box 1.14.0 起"
+
+允许的密钥交换算法。留空使用默认值。
+
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/outbound/tuic.md b/docs/configuration/outbound/tuic.md
index 4f4ef4850d..3701e73dd1 100644
--- a/docs/configuration/outbound/tuic.md
+++ b/docs/configuration/outbound/tuic.md
@@ -16,7 +16,9 @@
"heartbeat": "10s",
"network": "tcp",
"tls": {},
-
+
+ ... // QUIC Fields
+
... // Dial Fields
}
```
@@ -91,6 +93,10 @@ Both is enabled by default.
TLS configuration, see [TLS](/configuration/shared/tls/#outbound).
+### QUIC Fields
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
### Dial Fields
See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/outbound/tuic.zh.md b/docs/configuration/outbound/tuic.zh.md
index 6d31d7bcb5..43df2cfc8a 100644
--- a/docs/configuration/outbound/tuic.zh.md
+++ b/docs/configuration/outbound/tuic.zh.md
@@ -16,7 +16,9 @@
"heartbeat": "10s",
"network": "tcp",
"tls": {},
-
+
+ ... // QUIC 字段
+
... // 拨号字段
}
```
@@ -99,6 +101,10 @@ UDP 包中继模式
TLS 配置, 参阅 [TLS](/zh/configuration/shared/tls/#出站)。
+### QUIC 字段
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
+
### 拨号字段
参阅 [拨号字段](/zh/configuration/shared/dial/)。
diff --git a/docs/configuration/route/index.md b/docs/configuration/route/index.md
index 1fc9bfd231..1255723f47 100644
--- a/docs/configuration/route/index.md
+++ b/docs/configuration/route/index.md
@@ -4,6 +4,12 @@ icon: material/alert-decagram
# Route
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [default_http_client](#default_http_client)
+ :material-plus: [find_neighbor](#find_neighbor)
+ :material-plus: [dhcp_lease_files](#dhcp_lease_files)
+
!!! quote "Changes in sing-box 1.12.0"
:material-plus: [default_domain_resolver](#default_domain_resolver)
@@ -35,6 +41,10 @@ icon: material/alert-decagram
"override_android_vpn": false,
"default_interface": "",
"default_mark": 0,
+ "find_process": false,
+ "find_neighbor": false,
+ "dhcp_lease_files": [],
+ "default_http_client": "",
"default_domain_resolver": "", // or {}
"default_network_strategy": "",
"default_network_type": [],
@@ -107,13 +117,53 @@ Set routing mark by default.
Takes no effect if `outbound.routing_mark` is set.
+#### find_process
+
+!!! quote ""
+
+ Only supported on Linux, Windows, and macOS.
+
+Enable process search for logging when no `process_name`, `process_path`, `package_name`, `user` or `user_id` rules exist.
+
+#### find_neighbor
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux and macOS.
+
+Enable neighbor resolution for logging when no `source_mac_address` or `source_hostname` rules exist.
+
+See [Neighbor Resolution](/configuration/shared/neighbor/) for setup.
+
+#### dhcp_lease_files
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux and macOS.
+
+Custom DHCP lease file paths for hostname and MAC address resolution.
+
+Automatically detected from common DHCP servers (dnsmasq, odhcpd, ISC dhcpd, Kea) if empty.
+
+#### default_http_client
+
+!!! question "Since sing-box 1.14.0"
+
+Tag of the default [HTTP Client](/configuration/shared/http-client/) used by remote rule-sets.
+
+If empty and `http_clients` is defined, the first HTTP client is used.
+
#### default_domain_resolver
!!! question "Since sing-box 1.12.0"
See [Dial Fields](/configuration/shared/dial/#domain_resolver) for details.
-Can be overrides by `outbound.domain_resolver`.
+Can be overridden by `outbound.domain_resolver`.
#### default_network_strategy
@@ -123,7 +173,7 @@ See [Dial Fields](/configuration/shared/dial/#network_strategy) for details.
Takes no effect if `outbound.bind_interface`, `outbound.inet4_bind_address` or `outbound.inet6_bind_address` is set.
-Can be overrides by `outbound.network_strategy`.
+Can be overridden by `outbound.network_strategy`.
Conflicts with `default_interface`.
diff --git a/docs/configuration/route/index.zh.md b/docs/configuration/route/index.zh.md
index 1a50d3e3b5..58d718df02 100644
--- a/docs/configuration/route/index.zh.md
+++ b/docs/configuration/route/index.zh.md
@@ -4,6 +4,12 @@ icon: material/alert-decagram
# 路由
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [default_http_client](#default_http_client)
+ :material-plus: [find_neighbor](#find_neighbor)
+ :material-plus: [dhcp_lease_files](#dhcp_lease_files)
+
!!! quote "sing-box 1.12.0 中的更改"
:material-plus: [default_domain_resolver](#default_domain_resolver)
@@ -37,6 +43,10 @@ icon: material/alert-decagram
"override_android_vpn": false,
"default_interface": "",
"default_mark": 0,
+ "find_process": false,
+ "find_neighbor": false,
+ "dhcp_lease_files": [],
+ "default_http_client": "",
"default_network_strategy": "",
"default_fallback_delay": ""
}
@@ -106,6 +116,46 @@ icon: material/alert-decagram
如果设置了 `outbound.routing_mark` 设置,则不生效。
+#### find_process
+
+!!! quote ""
+
+ 仅支持 Linux、Windows 和 macOS。
+
+在没有 `process_name`、`process_path`、`package_name`、`user` 或 `user_id` 规则时启用进程搜索以输出日志。
+
+#### find_neighbor
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux 和 macOS。
+
+在没有 `source_mac_address` 或 `source_hostname` 规则时启用邻居解析以输出日志。
+
+参阅 [邻居解析](/configuration/shared/neighbor/) 了解设置方法。
+
+#### dhcp_lease_files
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux 和 macOS。
+
+用于主机名和 MAC 地址解析的自定义 DHCP 租约文件路径。
+
+为空时自动从常见 DHCP 服务器(dnsmasq、odhcpd、ISC dhcpd、Kea)检测。
+
+#### default_http_client
+
+!!! question "自 sing-box 1.14.0 起"
+
+远程规则集使用的默认 [HTTP 客户端](/zh/configuration/shared/http-client/) 的标签。
+
+如果为空且 `http_clients` 已定义,将使用第一个 HTTP 客户端。
+
#### default_domain_resolver
!!! question "自 sing-box 1.12.0 起"
diff --git a/docs/configuration/route/rule.md b/docs/configuration/route/rule.md
index 925187261c..97bbe37606 100644
--- a/docs/configuration/route/rule.md
+++ b/docs/configuration/route/rule.md
@@ -2,6 +2,12 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [source_mac_address](#source_mac_address)
+ :material-plus: [source_hostname](#source_hostname)
+ :material-plus: [package_name_regex](#package_name_regex)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [interface_address](#interface_address)
@@ -124,6 +130,9 @@ icon: material/new-box
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"user": [
"sekai"
],
@@ -159,6 +168,12 @@ icon: material/new-box
"tailscale",
"wireguard"
],
+ "source_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "source_hostname": [
+ "my-device"
+ ],
"rule_set": [
"geoip-cn",
"geosite-cn"
@@ -343,6 +358,12 @@ Match process path using regular expression.
Match android package name.
+#### package_name_regex
+
+!!! question "Since sing-box 1.14.0"
+
+Match android package name using regular expression.
+
#### user
!!! quote ""
@@ -449,6 +470,26 @@ Match specified outbounds' preferred routes.
| `tailscale` | Match MagicDNS domains and peers' allowed IPs |
| `wireguard` | Match peers's allowed IPs |
+#### source_mac_address
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux, macOS, or in graphical clients on Android and macOS. See [Neighbor Resolution](/configuration/shared/neighbor/) for setup.
+
+Match source device MAC address.
+
+#### source_hostname
+
+!!! question "Since sing-box 1.14.0"
+
+!!! quote ""
+
+ Only supported on Linux, macOS, or in graphical clients on Android and macOS. See [Neighbor Resolution](/configuration/shared/neighbor/) for setup.
+
+Match source device hostname from DHCP leases.
+
#### rule_set
!!! question "Since sing-box 1.8.0"
diff --git a/docs/configuration/route/rule.zh.md b/docs/configuration/route/rule.zh.md
index 53da4475f1..d55b565dd9 100644
--- a/docs/configuration/route/rule.zh.md
+++ b/docs/configuration/route/rule.zh.md
@@ -2,6 +2,12 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [source_mac_address](#source_mac_address)
+ :material-plus: [source_hostname](#source_hostname)
+ :material-plus: [package_name_regex](#package_name_regex)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [interface_address](#interface_address)
@@ -122,6 +128,9 @@ icon: material/new-box
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"user": [
"sekai"
],
@@ -157,6 +166,12 @@ icon: material/new-box
"tailscale",
"wireguard"
],
+ "source_mac_address": [
+ "00:11:22:33:44:55"
+ ],
+ "source_hostname": [
+ "my-device"
+ ],
"rule_set": [
"geoip-cn",
"geosite-cn"
@@ -341,6 +356,12 @@ icon: material/new-box
匹配 Android 应用包名。
+#### package_name_regex
+
+!!! question "自 sing-box 1.14.0 起"
+
+使用正则表达式匹配 Android 应用包名。
+
#### user
!!! quote ""
@@ -447,6 +468,26 @@ icon: material/new-box
| `tailscale` | 匹配 MagicDNS 域名和对端的 allowed IPs |
| `wireguard` | 匹配对端的 allowed IPs |
+#### source_mac_address
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux、macOS,或在 Android 和 macOS 图形客户端中支持。参阅 [邻居解析](/configuration/shared/neighbor/) 了解设置方法。
+
+匹配源设备 MAC 地址。
+
+#### source_hostname
+
+!!! question "自 sing-box 1.14.0 起"
+
+!!! quote ""
+
+ 仅支持 Linux、macOS,或在 Android 和 macOS 图形客户端中支持。参阅 [邻居解析](/configuration/shared/neighbor/) 了解设置方法。
+
+匹配源设备从 DHCP 租约获取的主机名。
+
#### rule_set
!!! question "自 sing-box 1.8.0 起"
diff --git a/docs/configuration/route/rule_action.md b/docs/configuration/route/rule_action.md
index 523ffec206..b362eefe58 100644
--- a/docs/configuration/route/rule_action.md
+++ b/docs/configuration/route/rule_action.md
@@ -7,6 +7,13 @@ icon: material/new-box
:material-plus: [bypass](#bypass)
:material-alert: [reject](#reject)
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [resolve.disable_optimistic_cache](#disable_optimistic_cache)
+ :material-plus: [resolve.timeout](#timeout)
+ :material-plus: [tls_spoof](#tls_spoof)
+ :material-plus: [tls_spoof_method](#tls_spoof_method)
+
!!! quote "Changes in sing-box 1.12.0"
:material-plus: [tls_fragment](#tls_fragment)
@@ -144,7 +151,9 @@ Not available when `method` is set to drop.
"udp_timeout": "",
"tls_fragment": false,
"tls_fragment_fallback_delay": "",
- "tls_record_fragment": ""
+ "tls_record_fragment": "",
+ "tls_spoof": "",
+ "tls_spoof_method": ""
}
```
@@ -243,6 +252,26 @@ The fallback value used when TLS segmentation cannot automatically determine the
Fragment TLS handshake into multiple TLS records to bypass firewalls.
+#### tls_spoof
+
+!!! question "Since sing-box 1.14.0"
+
+==Linux/macOS/Windows only, requires elevated privileges==
+
+Inject a forged TLS ClientHello carrying this SNI before the real one,
+to fool SNI-filtering middleboxes that permit specific hostnames.
+
+See outbound TLS [`spoof`](/configuration/shared/tls/#spoof) for details
+and required privileges.
+
+#### tls_spoof_method
+
+!!! question "Since sing-box 1.14.0"
+
+How the forged segment is rejected by the real server. See outbound TLS
+[`spoof_method`](/configuration/shared/tls/#spoof_method) for the full table
+of accepted values and platform notes.
+
### sniff
```json
@@ -279,7 +308,9 @@ Timeout for sniffing.
"server": "",
"strategy": "",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
@@ -302,12 +333,26 @@ DNS resolution strategy, available values are: `prefer_ipv4`, `prefer_ipv6`, `ip
Disable cache and save cache in this query.
+#### disable_optimistic_cache
+
+!!! question "Since sing-box 1.14.0"
+
+Disable optimistic DNS caching in this query.
+
#### rewrite_ttl
!!! question "Since sing-box 1.12.0"
Rewrite TTL in DNS responses.
+#### timeout
+
+!!! question "Since sing-box 1.14.0"
+
+Override the DNS query timeout for this lookup.
+
+Will override `dns.timeout`.
+
#### client_subnet
!!! question "Since sing-box 1.12.0"
@@ -316,4 +361,4 @@ Append a `edns0-subnet` OPT extra record with the specified IP prefix to every q
If value is an IP address instead of prefix, `/32` or `/128` will be appended automatically.
-Will overrides `dns.client_subnet`.
+Will override `dns.client_subnet`.
diff --git a/docs/configuration/route/rule_action.zh.md b/docs/configuration/route/rule_action.zh.md
index 16e1618082..3ef8d8d435 100644
--- a/docs/configuration/route/rule_action.zh.md
+++ b/docs/configuration/route/rule_action.zh.md
@@ -7,6 +7,13 @@ icon: material/new-box
:material-plus: [bypass](#bypass)
:material-alert: [reject](#reject)
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [resolve.disable_optimistic_cache](#disable_optimistic_cache)
+ :material-plus: [resolve.timeout](#timeout)
+ :material-plus: [tls_spoof](#tls_spoof)
+ :material-plus: [tls_spoof_method](#tls_spoof_method)
+
!!! quote "sing-box 1.12.0 中的更改"
:material-plus: [tls_fragment](#tls_fragment)
@@ -134,7 +141,12 @@ icon: material/new-box
"fallback_delay": "",
"udp_disable_domain_unmapping": false,
"udp_connect": false,
- "udp_timeout": ""
+ "udp_timeout": "",
+ "tls_fragment": false,
+ "tls_fragment_fallback_delay": "",
+ "tls_record_fragment": false,
+ "tls_spoof": "",
+ "tls_spoof_method": ""
}
```
@@ -232,6 +244,24 @@ UDP 连接超时时间。
通过分段 TLS 握手数据包到多个 TLS 记录来绕过防火墙检测。
+#### tls_spoof
+
+!!! question "自 sing-box 1.14.0 起"
+
+==仅 Linux/macOS/Windows,需要管理员权限==
+
+在真实 ClientHello 之前注入携带本字段所指定 SNI 的伪造 TLS ClientHello,
+用于欺骗仅放行特定主机名的 SNI 过滤中间盒。
+
+详情与所需权限参阅出站 TLS [`spoof`](/zh/configuration/shared/tls/#spoof)。
+
+#### tls_spoof_method
+
+!!! question "自 sing-box 1.14.0 起"
+
+控制伪造报文被真实服务器拒绝的方式。完整取值表与平台说明参阅出站 TLS
+[`spoof_method`](/zh/configuration/shared/tls/#spoof_method)。
+
### sniff
```json
@@ -268,7 +298,9 @@ UDP 连接超时时间。
"server": "",
"strategy": "",
"disable_cache": false,
+ "disable_optimistic_cache": false,
"rewrite_ttl": null,
+ "timeout": "",
"client_subnet": null
}
```
@@ -291,12 +323,26 @@ DNS 解析策略,可用值有:`prefer_ipv4`、`prefer_ipv6`、`ipv4_only`、
在此查询中禁用缓存。
+#### disable_optimistic_cache
+
+!!! question "自 sing-box 1.14.0 起"
+
+在此查询中禁用乐观 DNS 缓存。
+
#### rewrite_ttl
!!! question "自 sing-box 1.12.0 起"
重写 DNS 回应中的 TTL。
+#### timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+覆盖此查询的 DNS 查询超时时间。
+
+将覆盖 `dns.timeout`。
+
#### client_subnet
!!! question "自 sing-box 1.12.0 起"
diff --git a/docs/configuration/rule-set/headless-rule.md b/docs/configuration/rule-set/headless-rule.md
index 89cccd394e..81a5e9a0a4 100644
--- a/docs/configuration/rule-set/headless-rule.md
+++ b/docs/configuration/rule-set/headless-rule.md
@@ -2,6 +2,11 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [package_name_regex](#package_name_regex)
+ :material-alert: [query_type](#query_type)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [network_interface_address](#network_interface_address)
@@ -78,6 +83,9 @@ icon: material/new-box
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"network_type": [
"wifi"
],
@@ -125,6 +133,20 @@ icon: material/new-box
#### query_type
+!!! quote "Changes in sing-box 1.14.0"
+
+ When a DNS rule references this rule-set, this field now also applies
+ when the DNS rule is matched from an internal domain resolution that
+ does not target a specific DNS server. In earlier versions, only DNS
+ queries received from a client evaluated this field. See
+ [Migration](/migration/#ip_version-and-query_type-behavior-changes-in-dns-rules)
+ for the full list.
+
+ When a DNS rule references a rule-set containing this field, the DNS
+ rule is incompatible in the same DNS configuration with Legacy Address
+ Filter Fields in DNS rules, the Legacy `strategy` DNS rule action
+ option, and the Legacy `rule_set_ip_cidr_accept_empty` DNS rule item.
+
DNS query type. Values can be integers or type name strings.
#### network
@@ -205,6 +227,12 @@ Match process path using regular expression.
Match android package name.
+#### package_name_regex
+
+!!! question "Since sing-box 1.14.0"
+
+Match android package name using regular expression.
+
#### network_type
!!! question "Since sing-box 1.11.0"
diff --git a/docs/configuration/rule-set/headless-rule.zh.md b/docs/configuration/rule-set/headless-rule.zh.md
index f2b88631ac..ad78ffe449 100644
--- a/docs/configuration/rule-set/headless-rule.zh.md
+++ b/docs/configuration/rule-set/headless-rule.zh.md
@@ -2,6 +2,11 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [package_name_regex](#package_name_regex)
+ :material-alert: [query_type](#query_type)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [network_interface_address](#network_interface_address)
@@ -78,6 +83,9 @@ icon: material/new-box
"package_name": [
"com.termux"
],
+ "package_name_regex": [
+ "^com\\.termux.*"
+ ],
"network_type": [
"wifi"
],
@@ -125,6 +133,17 @@ icon: material/new-box
#### query_type
+!!! quote "sing-box 1.14.0 中的更改"
+
+ 当 DNS 规则引用此规则集时,此字段现在也会在 DNS 规则被未指定具体
+ DNS 服务器的内部域名解析匹配时生效。此前只有来自客户端的 DNS 查询
+ 才会评估此字段。完整列表参阅
+ [迁移指南](/zh/migration/#dns-规则中的-ip_version-和-query_type-行为更改)。
+
+ 当 DNS 规则引用了包含此字段的规则集时,该 DNS 规则在同一 DNS 配置中
+ 不能与旧版地址筛选字段 (DNS 规则)、旧版 DNS 规则动作 `strategy` 选项,
+ 或旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项共存。
+
DNS 查询类型。值可以为整数或者类型名称字符串。
#### network
@@ -201,6 +220,12 @@ DNS 查询类型。值可以为整数或者类型名称字符串。
匹配 Android 应用包名。
+#### package_name_regex
+
+!!! question "自 sing-box 1.14.0 起"
+
+使用正则表达式匹配 Android 应用包名。
+
#### network_type
!!! question "自 sing-box 1.11.0 起"
diff --git a/docs/configuration/rule-set/index.md b/docs/configuration/rule-set/index.md
index 73ec7b859f..c6d4a17c08 100644
--- a/docs/configuration/rule-set/index.md
+++ b/docs/configuration/rule-set/index.md
@@ -1,3 +1,8 @@
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [http_client](#http_client)
+ :material-delete-clock: [download_detour](#download_detour)
+
!!! quote "Changes in sing-box 1.10.0"
:material-plus: `type: inline`
@@ -43,8 +48,12 @@
"tag": "",
"format": "source", // or binary
"url": "",
- "download_detour": "", // optional
- "update_interval": "" // optional
+ "http_client": "", // or {}
+ "update_interval": "",
+
+ // Deprecated
+
+ "download_detour": ""
}
```
@@ -102,14 +111,26 @@ File path of rule-set.
Download URL of rule-set.
-#### download_detour
+#### http_client
-Tag of the outbound to download rule-set.
+!!! question "Since sing-box 1.14.0"
+
+HTTP Client for downloading rule-set.
-Default outbound will be used if empty.
+See [HTTP Client Fields](/configuration/shared/http-client/) for details.
+
+Default transport will be used if empty.
#### update_interval
Update interval of rule-set.
`1d` will be used if empty.
+
+#### download_detour
+
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ `download_detour` is deprecated in sing-box 1.14.0 and will be removed in sing-box 1.16.0, use `http_client` instead.
+
+Tag of the outbound to download rule-set.
diff --git a/docs/configuration/rule-set/index.zh.md b/docs/configuration/rule-set/index.zh.md
index eac519539c..2cd6f93793 100644
--- a/docs/configuration/rule-set/index.zh.md
+++ b/docs/configuration/rule-set/index.zh.md
@@ -1,3 +1,8 @@
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [http_client](#http_client)
+ :material-delete-clock: [download_detour](#download_detour)
+
!!! quote "sing-box 1.10.0 中的更改"
:material-plus: `type: inline`
@@ -43,8 +48,12 @@
"tag": "",
"format": "source", // or binary
"url": "",
- "download_detour": "", // 可选
- "update_interval": "" // 可选
+ "http_client": "", // 或 {}
+ "update_interval": "",
+
+ // 废弃的
+
+ "download_detour": ""
}
```
@@ -102,14 +111,26 @@
规则集的下载 URL。
-#### download_detour
+#### http_client
-用于下载规则集的出站的标签。
+!!! question "自 sing-box 1.14.0 起"
+
+用于下载规则集的 HTTP 客户端。
-如果为空,将使用默认出站。
+参阅 [HTTP 客户端字段](/zh/configuration/shared/http-client/) 了解详情。
+
+如果为空,将使用默认传输。
#### update_interval
规则集的更新间隔。
默认使用 `1d`。
+
+#### download_detour
+
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ `download_detour` 已在 sing-box 1.14.0 废弃且将在 sing-box 1.16.0 中被移除,请使用 `http_client` 代替。
+
+用于下载规则集的出站的标签。
diff --git a/docs/configuration/rule-set/source-format.md b/docs/configuration/rule-set/source-format.md
index 47d620b1c6..47e0e24553 100644
--- a/docs/configuration/rule-set/source-format.md
+++ b/docs/configuration/rule-set/source-format.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: version `5`
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: version `4`
@@ -41,6 +45,7 @@ Version of rule-set.
* 2: sing-box 1.10.0: Optimized memory usages of `domain_suffix` rules in binary rule-sets.
* 3: sing-box 1.11.0: Added `network_type`, `network_is_expensive` and `network_is_constrainted` rule items.
* 4: sing-box 1.13.0: Added `network_interface_address` and `default_interface_address` rule items.
+* 5: sing-box 1.14.0: Added `package_name_regex` rule item.
#### rules
diff --git a/docs/configuration/rule-set/source-format.zh.md b/docs/configuration/rule-set/source-format.zh.md
index 30c0679f6e..3f7108647b 100644
--- a/docs/configuration/rule-set/source-format.zh.md
+++ b/docs/configuration/rule-set/source-format.zh.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: version `5`
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: version `4`
@@ -41,6 +45,7 @@ icon: material/new-box
* 2: sing-box 1.10.0: 优化了二进制规则集中 `domain_suffix` 规则的内存使用。
* 3: sing-box 1.11.0: 添加了 `network_type`、 `network_is_expensive` 和 `network_is_constrainted` 规则项。
* 4: sing-box 1.13.0: 添加了 `network_interface_address` 和 `default_interface_address` 规则项。
+* 5: sing-box 1.14.0: 添加了 `package_name_regex` 规则项。
#### rules
diff --git a/docs/configuration/service/derp.md b/docs/configuration/service/derp.md
index 3d7443a313..2925db993e 100644
--- a/docs/configuration/service/derp.md
+++ b/docs/configuration/service/derp.md
@@ -58,9 +58,9 @@ Object format:
```json
{
- "url": "https://my-headscale.com/verify",
-
- ... // Dial Fields
+ "url": "",
+
+ ... // HTTP Client Fields
}
```
diff --git a/docs/configuration/service/derp.zh.md b/docs/configuration/service/derp.zh.md
index b22ff41345..01e2ac39fc 100644
--- a/docs/configuration/service/derp.zh.md
+++ b/docs/configuration/service/derp.zh.md
@@ -58,9 +58,9 @@ Derper 配置文件路径。
```json
{
- "url": "https://my-headscale.com/verify",
+ "url": "",
- ... // 拨号字段
+ ... // HTTP 客户端字段
}
```
diff --git a/docs/configuration/service/hysteria-realm.md b/docs/configuration/service/hysteria-realm.md
new file mode 100644
index 0000000000..0fe01f1e7c
--- /dev/null
+++ b/docs/configuration/service/hysteria-realm.md
@@ -0,0 +1,73 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+# Hysteria Realm
+
+Hysteria Realm is a rendezvous service for Hysteria2 NAT traversal.
+
+A Hysteria2 server behind NAT registers its STUN-discovered public addresses to a stable realm endpoint; clients query the realm to learn the server's current addresses and perform UDP hole-punching to establish a direct QUIC connection.
+
+The realm only carries control-plane signaling. Once hole-punching succeeds, all proxy traffic flows directly between client and server.
+
+### Structure
+
+```json
+{
+ "type": "hysteria-realm",
+
+ ... // Listen Fields
+
+ "tls": {},
+
+ ... // HTTP2 Fields
+
+ "users": [
+ {
+ "name": "",
+ "token": "",
+ "max_realms": 0
+ }
+ ]
+}
+```
+
+### Listen Fields
+
+See [Listen Fields](/configuration/shared/listen/) for details.
+
+### HTTP2 Fields
+
+See [HTTP2 Fields](/configuration/shared/http2/) for details.
+
+### Fields
+
+#### tls
+
+TLS configuration, see [TLS](/configuration/shared/tls/#inbound).
+
+When configured, the realm serves HTTP/2 over TLS; otherwise plain HTTP/1.1.
+
+#### users
+
+==Required==
+
+Authorized users.
+
+#### users.name
+
+==Required==
+
+Username, used in logs and as the quota key.
+
+#### users.token
+
+==Required==
+
+Bearer token presented by Hysteria2 inbounds and outbounds via `Authorization: Bearer `.
+
+#### users.max_realms
+
+Maximum number of realm slots this user may hold concurrently.
diff --git a/docs/configuration/service/hysteria-realm.zh.md b/docs/configuration/service/hysteria-realm.zh.md
new file mode 100644
index 0000000000..c01d744bf4
--- /dev/null
+++ b/docs/configuration/service/hysteria-realm.zh.md
@@ -0,0 +1,73 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+# Hysteria Realm
+
+Hysteria Realm 是用于 Hysteria2 NAT 穿透的会合服务。
+
+位于 NAT 后面的 Hysteria2 服务器将其通过 STUN 发现的公网地址注册到一个稳定的 realm 端点;客户端从 realm 查询服务器当前的地址并执行 UDP 打洞,以建立直连的 QUIC 连接。
+
+Realm 只承载控制信令。打洞成功后,所有代理流量在客户端和服务器之间直连传输。
+
+### 结构
+
+```json
+{
+ "type": "hysteria-realm",
+
+ ... // 监听字段
+
+ "tls": {},
+
+ ... // HTTP2 字段
+
+ "users": [
+ {
+ "name": "",
+ "token": "",
+ "max_realms": 0
+ }
+ ]
+}
+```
+
+### 监听字段
+
+参阅 [监听字段](/zh/configuration/shared/listen/) 了解详情。
+
+### HTTP2 字段
+
+参阅 [HTTP2 字段](/zh/configuration/shared/http2/) 了解详情。
+
+### 字段
+
+#### tls
+
+TLS 配置,参阅 [TLS](/zh/configuration/shared/tls/#入站)。
+
+配置后,realm 将通过 TLS 提供 HTTP/2 服务;否则提供明文 HTTP/1.1。
+
+#### users
+
+==必填==
+
+授权用户。
+
+#### users.name
+
+==必填==
+
+用户名,用于日志记录和配额键。
+
+#### users.token
+
+==必填==
+
+Hysteria2 入站和出站通过 `Authorization: Bearer ` 出示的 Bearer 令牌。
+
+#### users.max_realms
+
+此用户可同时持有的 realm 槽位数量上限。
diff --git a/docs/configuration/service/index.md b/docs/configuration/service/index.md
index de3583b2ba..dea66d9712 100644
--- a/docs/configuration/service/index.md
+++ b/docs/configuration/service/index.md
@@ -21,13 +21,14 @@ icon: material/new-box
### Fields
-| Type | Format |
-|------------|------------------------|
-| `ccm` | [CCM](./ccm) |
-| `derp` | [DERP](./derp) |
-| `ocm` | [OCM](./ocm) |
-| `resolved` | [Resolved](./resolved) |
-| `ssm-api` | [SSM API](./ssm-api) |
+| Type | Format |
+|-------------------|---------------------------------------|
+| `ccm` | [CCM](./ccm) |
+| `derp` | [DERP](./derp) |
+| `hysteria-realm` | [Hysteria Realm](./hysteria-realm) |
+| `ocm` | [OCM](./ocm) |
+| `resolved` | [Resolved](./resolved) |
+| `ssm-api` | [SSM API](./ssm-api) |
#### tag
diff --git a/docs/configuration/service/index.zh.md b/docs/configuration/service/index.zh.md
index a0d18cbba7..240dce2cd1 100644
--- a/docs/configuration/service/index.zh.md
+++ b/docs/configuration/service/index.zh.md
@@ -21,13 +21,14 @@ icon: material/new-box
### 字段
-| 类型 | 格式 |
-|-----------|------------------------|
-| `ccm` | [CCM](./ccm) |
-| `derp` | [DERP](./derp) |
-| `ocm` | [OCM](./ocm) |
-| `resolved`| [Resolved](./resolved) |
-| `ssm-api` | [SSM API](./ssm-api) |
+| 类型 | 格式 |
+|-------------------|---------------------------------------|
+| `ccm` | [CCM](./ccm) |
+| `derp` | [DERP](./derp) |
+| `hysteria-realm` | [Hysteria Realm](./hysteria-realm) |
+| `ocm` | [OCM](./ocm) |
+| `resolved` | [Resolved](./resolved) |
+| `ssm-api` | [SSM API](./ssm-api) |
#### tag
diff --git a/docs/configuration/shared/certificate-provider/acme.md b/docs/configuration/shared/certificate-provider/acme.md
new file mode 100644
index 0000000000..30a5ba8d6d
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/acme.md
@@ -0,0 +1,160 @@
+---
+icon: material/new-box
+---
+
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [account_key](#account_key)
+ :material-plus: [key_type](#key_type)
+ :material-plus: [profile](#profile)
+ :material-plus: [http_client](#http_client)
+
+# ACME
+
+!!! quote ""
+
+ `with_acme` build tag required.
+
+### Structure
+
+```json
+{
+ "type": "acme",
+ "tag": "",
+
+ "domain": [],
+ "data_directory": "",
+ "default_server_name": "",
+ "email": "",
+ "provider": "",
+ "account_key": "",
+ "disable_http_challenge": false,
+ "disable_tls_alpn_challenge": false,
+ "alternative_http_port": 0,
+ "alternative_tls_port": 0,
+ "external_account": {
+ "key_id": "",
+ "mac_key": ""
+ },
+ "dns01_challenge": {},
+ "key_type": "",
+ "profile": "",
+ "http_client": "" // or {}
+}
+```
+
+### Fields
+
+#### domain
+
+==Required==
+
+List of domains.
+
+#### data_directory
+
+The directory to store ACME data.
+
+`$XDG_DATA_HOME/certmagic|$HOME/.local/share/certmagic` will be used if empty.
+
+#### default_server_name
+
+Server name to use when choosing a certificate if the ClientHello's ServerName field is empty.
+
+#### email
+
+The email address to use when creating or selecting an existing ACME server account.
+
+#### provider
+
+The ACME CA provider to use.
+
+| Value | Provider |
+|-------------------------|---------------|
+| `letsencrypt (default)` | Let's Encrypt |
+| `zerossl` | ZeroSSL |
+| `https://...` | Custom |
+
+When `provider` is `zerossl`, sing-box will automatically request ZeroSSL EAB credentials if `email` is set and
+`external_account` is empty.
+
+When `provider` is `zerossl`, at least one of `external_account`, `email`, or `account_key` is required.
+
+#### account_key
+
+!!! question "Since sing-box 1.14.0"
+
+The PEM-encoded private key of an existing ACME account.
+
+#### disable_http_challenge
+
+Disable all HTTP challenges.
+
+#### disable_tls_alpn_challenge
+
+Disable all TLS-ALPN challenges
+
+#### alternative_http_port
+
+The alternate port to use for the ACME HTTP challenge; if non-empty, this port will be used instead of 80 to spin up a
+listener for the HTTP challenge.
+
+#### alternative_tls_port
+
+The alternate port to use for the ACME TLS-ALPN challenge; the system must forward 443 to this port for challenge to
+succeed.
+
+#### external_account
+
+EAB (External Account Binding) contains information necessary to bind or map an ACME account to some other account known
+by the CA.
+
+External account bindings are used to associate an ACME account with an existing account in a non-ACME system, such as
+a CA customer database.
+
+To enable ACME account binding, the CA operating the ACME server needs to provide the ACME client with a MAC key and a
+key identifier, using some mechanism outside of ACME. §7.3.4
+
+#### external_account.key_id
+
+The key identifier.
+
+#### external_account.mac_key
+
+The MAC key.
+
+#### dns01_challenge
+
+ACME DNS01 challenge field. If configured, other challenge methods will be disabled.
+
+See [DNS01 Challenge Fields](/configuration/shared/dns01_challenge/) for details.
+
+#### key_type
+
+!!! question "Since sing-box 1.14.0"
+
+The private key type to generate for new certificates.
+
+| Value | Type |
+|------------|---------|
+| `ed25519` | Ed25519 |
+| `p256` | P-256 |
+| `p384` | P-384 |
+| `rsa2048` | RSA |
+| `rsa4096` | RSA |
+
+#### profile
+
+!!! question "Since sing-box 1.14.0"
+
+The ACME profile to use for certificate issuance.
+
+When empty and `provider` is Let's Encrypt, `shortlived` will be used automatically if any domain is an IP address.
+
+#### http_client
+
+!!! question "Since sing-box 1.14.0"
+
+HTTP Client for all provider HTTP requests.
+
+See [HTTP Client Fields](/configuration/shared/http-client/) for details.
diff --git a/docs/configuration/shared/certificate-provider/acme.zh.md b/docs/configuration/shared/certificate-provider/acme.zh.md
new file mode 100644
index 0000000000..e01986d5bc
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/acme.zh.md
@@ -0,0 +1,157 @@
+---
+icon: material/new-box
+---
+
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [account_key](#account_key)
+ :material-plus: [key_type](#key_type)
+ :material-plus: [profile](#profile)
+ :material-plus: [http_client](#http_client)
+
+# ACME
+
+!!! quote ""
+
+ 需要 `with_acme` 构建标签。
+
+### 结构
+
+```json
+{
+ "type": "acme",
+ "tag": "",
+
+ "domain": [],
+ "data_directory": "",
+ "default_server_name": "",
+ "email": "",
+ "provider": "",
+ "account_key": "",
+ "disable_http_challenge": false,
+ "disable_tls_alpn_challenge": false,
+ "alternative_http_port": 0,
+ "alternative_tls_port": 0,
+ "external_account": {
+ "key_id": "",
+ "mac_key": ""
+ },
+ "dns01_challenge": {},
+ "key_type": "",
+ "profile": "",
+ "http_client": "" // 或 {}
+}
+```
+
+### 字段
+
+#### domain
+
+==必填==
+
+域名列表。
+
+#### data_directory
+
+ACME 数据存储目录。
+
+如果为空则使用 `$XDG_DATA_HOME/certmagic|$HOME/.local/share/certmagic`。
+
+#### default_server_name
+
+如果 ClientHello 的 ServerName 字段为空,则选择证书时要使用的服务器名称。
+
+#### email
+
+创建或选择现有 ACME 服务器帐户时使用的电子邮件地址。
+
+#### provider
+
+要使用的 ACME CA 提供商。
+
+| 值 | 提供商 |
+|--------------------|---------------|
+| `letsencrypt (默认)` | Let's Encrypt |
+| `zerossl` | ZeroSSL |
+| `https://...` | 自定义 |
+
+当 `provider` 为 `zerossl` 时,如果设置了 `email` 且未设置 `external_account`,
+sing-box 会自动向 ZeroSSL 请求 EAB 凭据。
+
+当 `provider` 为 `zerossl` 时,必须至少设置 `external_account`、`email` 或 `account_key` 之一。
+
+#### account_key
+
+!!! question "自 sing-box 1.14.0 起"
+
+现有 ACME 帐户的 PEM 编码私钥。
+
+#### disable_http_challenge
+
+禁用所有 HTTP 质询。
+
+#### disable_tls_alpn_challenge
+
+禁用所有 TLS-ALPN 质询。
+
+#### alternative_http_port
+
+用于 ACME HTTP 质询的备用端口;如果非空,将使用此端口而不是 80 来启动 HTTP 质询的侦听器。
+
+#### alternative_tls_port
+
+用于 ACME TLS-ALPN 质询的备用端口; 系统必须将 443 转发到此端口以使质询成功。
+
+#### external_account
+
+EAB(外部帐户绑定)包含将 ACME 帐户绑定或映射到 CA 已知的其他帐户所需的信息。
+
+外部帐户绑定用于将 ACME 帐户与非 ACME 系统中的现有帐户相关联,例如 CA 客户数据库。
+
+为了启用 ACME 帐户绑定,运行 ACME 服务器的 CA 需要使用 ACME 之外的某种机制向 ACME 客户端提供 MAC 密钥和密钥标识符。§7.3.4
+
+#### external_account.key_id
+
+密钥标识符。
+
+#### external_account.mac_key
+
+MAC 密钥。
+
+#### dns01_challenge
+
+ACME DNS01 质询字段。如果配置,将禁用其他质询方法。
+
+参阅 [DNS01 质询字段](/zh/configuration/shared/dns01_challenge/)。
+
+#### key_type
+
+!!! question "自 sing-box 1.14.0 起"
+
+为新证书生成的私钥类型。
+
+| 值 | 类型 |
+|-----------|----------|
+| `ed25519` | Ed25519 |
+| `p256` | P-256 |
+| `p384` | P-384 |
+| `rsa2048` | RSA |
+| `rsa4096` | RSA |
+
+#### profile
+
+!!! question "自 sing-box 1.14.0 起"
+
+用于证书签发的 ACME profile。
+
+当为空且 `provider` 为 Let's Encrypt 时,如果任意域名为 IP 地址,将自动使用 `shortlived`。
+
+#### http_client
+
+!!! question "自 sing-box 1.14.0 起"
+
+用于所有提供者 HTTP 请求的 HTTP 客户端。
+
+参阅 [HTTP 客户端字段](/zh/configuration/shared/http-client/) 了解详情。
+
+所有提供者 HTTP 请求将使用此出站。
diff --git a/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.md b/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.md
new file mode 100644
index 0000000000..506def982d
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.md
@@ -0,0 +1,82 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+# Cloudflare Origin CA
+
+### Structure
+
+```json
+{
+ "type": "cloudflare-origin-ca",
+ "tag": "",
+
+ "domain": [],
+ "data_directory": "",
+ "api_token": "",
+ "origin_ca_key": "",
+ "request_type": "",
+ "requested_validity": 0,
+ "http_client": "" // or {}
+}
+```
+
+### Fields
+
+#### domain
+
+==Required==
+
+List of domain names or wildcard domain names to include in the certificate.
+
+#### data_directory
+
+Root directory used to store the issued certificate, private key, and metadata.
+
+If empty, sing-box uses the same default data directory as the ACME certificate provider:
+`$XDG_DATA_HOME/certmagic` or `$HOME/.local/share/certmagic`.
+
+#### api_token
+
+Cloudflare API token used to create the certificate.
+
+Get or create one in [Cloudflare Dashboard > My Profile > API Tokens](https://dash.cloudflare.com/profile/api-tokens).
+
+Requires the `Zone / SSL and Certificates / Edit` permission.
+
+Conflict with `origin_ca_key`.
+
+#### origin_ca_key
+
+Cloudflare Origin CA Key.
+
+Get it in [Cloudflare Dashboard > My Profile > API Tokens > API Keys > Origin CA Key](https://dash.cloudflare.com/profile/api-tokens).
+
+Conflict with `api_token`.
+
+#### request_type
+
+The signature type to request from Cloudflare.
+
+| Value | Type |
+|----------------------|-------------|
+| `origin-rsa` | RSA |
+| `origin-ecc` | ECDSA P-256 |
+
+`origin-rsa` is used if empty.
+
+#### requested_validity
+
+The requested certificate validity in days.
+
+Available values: `7`, `30`, `90`, `365`, `730`, `1095`, `5475`.
+
+`5475` days (15 years) is used if empty.
+
+#### http_client
+
+HTTP Client for all provider HTTP requests.
+
+See [HTTP Client Fields](/configuration/shared/http-client/) for details.
diff --git a/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.zh.md b/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.zh.md
new file mode 100644
index 0000000000..d526be56a9
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/cloudflare-origin-ca.zh.md
@@ -0,0 +1,82 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+# Cloudflare Origin CA
+
+### 结构
+
+```json
+{
+ "type": "cloudflare-origin-ca",
+ "tag": "",
+
+ "domain": [],
+ "data_directory": "",
+ "api_token": "",
+ "origin_ca_key": "",
+ "request_type": "",
+ "requested_validity": 0,
+ "http_client": "" // 或 {}
+}
+```
+
+### 字段
+
+#### domain
+
+==必填==
+
+要写入证书的域名或通配符域名列表。
+
+#### data_directory
+
+保存签发证书、私钥和元数据的根目录。
+
+如果为空,sing-box 会使用与 ACME 证书提供者相同的默认数据目录:
+`$XDG_DATA_HOME/certmagic` 或 `$HOME/.local/share/certmagic`。
+
+#### api_token
+
+用于创建证书的 Cloudflare API Token。
+
+可在 [Cloudflare Dashboard > My Profile > API Tokens](https://dash.cloudflare.com/profile/api-tokens) 获取或创建。
+
+需要 `Zone / SSL and Certificates / Edit` 权限。
+
+与 `origin_ca_key` 冲突。
+
+#### origin_ca_key
+
+Cloudflare Origin CA Key。
+
+可在 [Cloudflare Dashboard > My Profile > API Tokens > API Keys > Origin CA Key](https://dash.cloudflare.com/profile/api-tokens) 获取。
+
+与 `api_token` 冲突。
+
+#### request_type
+
+向 Cloudflare 请求的签名类型。
+
+| 值 | 类型 |
+|----------------------|-------------|
+| `origin-rsa` | RSA |
+| `origin-ecc` | ECDSA P-256 |
+
+如果为空,使用 `origin-rsa`。
+
+#### requested_validity
+
+请求的证书有效期,单位为天。
+
+可用值:`7`、`30`、`90`、`365`、`730`、`1095`、`5475`。
+
+如果为空,使用 `5475` 天(15 年)。
+
+#### http_client
+
+用于所有提供者 HTTP 请求的 HTTP 客户端。
+
+参阅 [HTTP 客户端字段](/zh/configuration/shared/http-client/) 了解详情。
diff --git a/docs/configuration/shared/certificate-provider/index.md b/docs/configuration/shared/certificate-provider/index.md
new file mode 100644
index 0000000000..c493550aaa
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/index.md
@@ -0,0 +1,32 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+# Certificate Provider
+
+### Structure
+
+```json
+{
+ "certificate_providers": [
+ {
+ "type": "",
+ "tag": ""
+ }
+ ]
+}
+```
+
+### Fields
+
+| Type | Format |
+|--------|------------------|
+| `acme` | [ACME](/configuration/shared/certificate-provider/acme) |
+| `tailscale` | [Tailscale](/configuration/shared/certificate-provider/tailscale) |
+| `cloudflare-origin-ca` | [Cloudflare Origin CA](/configuration/shared/certificate-provider/cloudflare-origin-ca) |
+
+#### tag
+
+The tag of the certificate provider.
diff --git a/docs/configuration/shared/certificate-provider/index.zh.md b/docs/configuration/shared/certificate-provider/index.zh.md
new file mode 100644
index 0000000000..2df4b36387
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/index.zh.md
@@ -0,0 +1,32 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+# 证书提供者
+
+### 结构
+
+```json
+{
+ "certificate_providers": [
+ {
+ "type": "",
+ "tag": ""
+ }
+ ]
+}
+```
+
+### 字段
+
+| 类型 | 格式 |
+|--------|------------------|
+| `acme` | [ACME](/zh/configuration/shared/certificate-provider/acme) |
+| `tailscale` | [Tailscale](/zh/configuration/shared/certificate-provider/tailscale) |
+| `cloudflare-origin-ca` | [Cloudflare Origin CA](/zh/configuration/shared/certificate-provider/cloudflare-origin-ca) |
+
+#### tag
+
+证书提供者的标签。
diff --git a/docs/configuration/shared/certificate-provider/tailscale.md b/docs/configuration/shared/certificate-provider/tailscale.md
new file mode 100644
index 0000000000..045f2c5ec5
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/tailscale.md
@@ -0,0 +1,27 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+# Tailscale
+
+### Structure
+
+```json
+{
+ "type": "tailscale",
+ "tag": "ts-cert",
+ "endpoint": "ts-ep"
+}
+```
+
+### Fields
+
+#### endpoint
+
+==Required==
+
+The tag of the [Tailscale endpoint](/configuration/endpoint/tailscale/) to reuse.
+
+[MagicDNS and HTTPS](https://tailscale.com/kb/1153/enabling-https) must be enabled in the Tailscale admin console.
diff --git a/docs/configuration/shared/certificate-provider/tailscale.zh.md b/docs/configuration/shared/certificate-provider/tailscale.zh.md
new file mode 100644
index 0000000000..1987da5084
--- /dev/null
+++ b/docs/configuration/shared/certificate-provider/tailscale.zh.md
@@ -0,0 +1,27 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+# Tailscale
+
+### 结构
+
+```json
+{
+ "type": "tailscale",
+ "tag": "ts-cert",
+ "endpoint": "ts-ep"
+}
+```
+
+### 字段
+
+#### endpoint
+
+==必填==
+
+要复用的 [Tailscale 端点](/zh/configuration/endpoint/tailscale/) 的标签。
+
+必须在 Tailscale 管理控制台中启用 [MagicDNS 和 HTTPS](https://tailscale.com/kb/1153/enabling-https)。
diff --git a/docs/configuration/shared/dial.md b/docs/configuration/shared/dial.md
index 306952fc4a..2ef2fbdb6e 100644
--- a/docs/configuration/shared/dial.md
+++ b/docs/configuration/shared/dial.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-alert: [domain_resolver](#domain_resolver)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [disable_tcp_keep_alive](#disable_tcp_keep_alive)
diff --git a/docs/configuration/shared/dial.zh.md b/docs/configuration/shared/dial.zh.md
index daf7f8e03c..24388fecfd 100644
--- a/docs/configuration/shared/dial.zh.md
+++ b/docs/configuration/shared/dial.zh.md
@@ -2,6 +2,10 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-alert: [domain_resolver](#domain_resolver)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [disable_tcp_keep_alive](#disable_tcp_keep_alive)
diff --git a/docs/configuration/shared/dns01_challenge.md b/docs/configuration/shared/dns01_challenge.md
index 8bdbfc97a7..0157cb4596 100644
--- a/docs/configuration/shared/dns01_challenge.md
+++ b/docs/configuration/shared/dns01_challenge.md
@@ -2,6 +2,14 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [ttl](#ttl)
+ :material-plus: [propagation_delay](#propagation_delay)
+ :material-plus: [propagation_timeout](#propagation_timeout)
+ :material-plus: [resolvers](#resolvers)
+ :material-plus: [override_domain](#override_domain)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [alidns.security_token](#security_token)
@@ -12,12 +20,57 @@ icon: material/new-box
```json
{
+ "ttl": "",
+ "propagation_delay": "",
+ "propagation_timeout": "",
+ "resolvers": [],
+ "override_domain": "",
"provider": "",
... // Provider Fields
}
```
+### Fields
+
+#### ttl
+
+!!! question "Since sing-box 1.14.0"
+
+The TTL of the temporary TXT record used for the DNS challenge.
+
+#### propagation_delay
+
+!!! question "Since sing-box 1.14.0"
+
+How long to wait after creating the challenge record before starting propagation checks.
+
+#### propagation_timeout
+
+!!! question "Since sing-box 1.14.0"
+
+The maximum time to wait for the challenge record to propagate.
+
+Set to `-1` to disable propagation checks.
+
+#### resolvers
+
+!!! question "Since sing-box 1.14.0"
+
+Preferred DNS resolvers to use for DNS propagation checks.
+
+#### override_domain
+
+!!! question "Since sing-box 1.14.0"
+
+Override the domain name used for the DNS challenge record.
+
+Useful when `_acme-challenge` is delegated to a different zone.
+
+#### provider
+
+The DNS provider. See below for provider-specific fields.
+
### Provider Fields
#### Alibaba Cloud DNS
diff --git a/docs/configuration/shared/dns01_challenge.zh.md b/docs/configuration/shared/dns01_challenge.zh.md
index e6919338cd..8c582bb544 100644
--- a/docs/configuration/shared/dns01_challenge.zh.md
+++ b/docs/configuration/shared/dns01_challenge.zh.md
@@ -2,6 +2,14 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [ttl](#ttl)
+ :material-plus: [propagation_delay](#propagation_delay)
+ :material-plus: [propagation_timeout](#propagation_timeout)
+ :material-plus: [resolvers](#resolvers)
+ :material-plus: [override_domain](#override_domain)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [alidns.security_token](#security_token)
@@ -12,12 +20,57 @@ icon: material/new-box
```json
{
+ "ttl": "",
+ "propagation_delay": "",
+ "propagation_timeout": "",
+ "resolvers": [],
+ "override_domain": "",
"provider": "",
... // 提供商字段
}
```
+### 字段
+
+#### ttl
+
+!!! question "自 sing-box 1.14.0 起"
+
+DNS 质询临时 TXT 记录的 TTL。
+
+#### propagation_delay
+
+!!! question "自 sing-box 1.14.0 起"
+
+创建质询记录后,在开始传播检查前要等待的时间。
+
+#### propagation_timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+等待质询记录传播完成的最长时间。
+
+设为 `-1` 可禁用传播检查。
+
+#### resolvers
+
+!!! question "自 sing-box 1.14.0 起"
+
+进行 DNS 传播检查时优先使用的 DNS 解析器。
+
+#### override_domain
+
+!!! question "自 sing-box 1.14.0 起"
+
+覆盖 DNS 质询记录使用的域名。
+
+适用于将 `_acme-challenge` 委托到其他 zone 的场景。
+
+#### provider
+
+DNS 提供商。提供商专有字段见下文。
+
### 提供商字段
#### Alibaba Cloud DNS
diff --git a/docs/configuration/shared/http-client.md b/docs/configuration/shared/http-client.md
new file mode 100644
index 0000000000..a0aa9d2308
--- /dev/null
+++ b/docs/configuration/shared/http-client.md
@@ -0,0 +1,114 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+### Structure
+
+A string or an object.
+
+When string, the tag of a shared [HTTP Client](/configuration/shared/http-client/) defined in top-level `http_clients`.
+
+When object:
+
+```json
+{
+ "engine": "",
+ "version": 0,
+ "disable_version_fallback": false,
+ "headers": {},
+
+ ... // HTTP2 Fields
+
+ "tls": {},
+
+ ... // Dial Fields
+}
+```
+
+### Fields
+
+#### engine
+
+HTTP engine to use.
+
+Values:
+
+* `go` (default)
+* `apple`
+
+`apple` uses NSURLSession, only available on Apple platforms.
+
+!!! warning ""
+
+ Experimental only: due to the high memory overhead of both CGO and Network.framework,
+ do not use in hot paths on iOS and tvOS.
+
+Supported fields:
+
+* `headers`
+* `tls.server_name` (must match request host)
+* `tls.insecure`
+* `tls.min_version` / `tls.max_version`
+* `tls.certificate` / `tls.certificate_path`
+* `tls.certificate_public_key_sha256`
+* Dial Fields
+
+Unsupported fields:
+
+* `version`
+* `disable_version_fallback`
+* HTTP2 Fields
+* QUIC Fields
+* `tls.engine`
+* `tls.alpn`
+* `tls.disable_sni`
+* `tls.cipher_suites`
+* `tls.curve_preferences`
+* `tls.client_certificate` / `tls.client_certificate_path` / `tls.client_key` / `tls.client_key_path`
+* `tls.fragment` / `tls.record_fragment`
+* `tls.kernel_tx` / `tls.kernel_rx`
+* `tls.ech`
+* `tls.utls`
+* `tls.reality`
+
+#### version
+
+HTTP version.
+
+Available values: `1`, `2`, `3`.
+
+`2` is used by default.
+
+When `3`, [HTTP2 Fields](#http2-fields) are replaced by [QUIC Fields](#quic-fields).
+
+#### disable_version_fallback
+
+Disable automatic fallback to lower HTTP version.
+
+#### headers
+
+Custom HTTP headers.
+
+`Host` header is used as request host.
+
+### HTTP2 Fields
+
+When `version` is `2` (default).
+
+See [HTTP2 Fields](/configuration/shared/http2/) for details.
+
+### QUIC Fields
+
+When `version` is `3`.
+
+See [QUIC Fields](/configuration/shared/quic/) for details.
+
+### TLS Fields
+
+See [TLS](/configuration/shared/tls/#outbound) for details.
+
+### Dial Fields
+
+See [Dial Fields](/configuration/shared/dial/) for details.
diff --git a/docs/configuration/shared/http-client.zh.md b/docs/configuration/shared/http-client.zh.md
new file mode 100644
index 0000000000..5c05968ad4
--- /dev/null
+++ b/docs/configuration/shared/http-client.zh.md
@@ -0,0 +1,114 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+### 结构
+
+字符串或对象。
+
+当为字符串时,为顶层 `http_clients` 中定义的共享 [HTTP 客户端](/zh/configuration/shared/http-client/) 的标签。
+
+当为对象时:
+
+```json
+{
+ "engine": "",
+ "version": 0,
+ "disable_version_fallback": false,
+ "headers": {},
+
+ ... // HTTP2 字段
+
+ "tls": {},
+
+ ... // 拨号字段
+}
+```
+
+### 字段
+
+#### engine
+
+要使用的 HTTP 引擎。
+
+可用值:
+
+* `go`(默认)
+* `apple`
+
+`apple` 使用 NSURLSession,仅在 Apple 平台可用。
+
+!!! warning ""
+
+ 仅供实验用途:由于 CGO 和 Network.framework 占用的内存都很多,
+ 不应在 iOS 和 tvOS 的热路径中使用。
+
+支持的字段:
+
+* `headers`
+* `tls.server_name`(必须与请求主机匹配)
+* `tls.insecure`
+* `tls.min_version` / `tls.max_version`
+* `tls.certificate` / `tls.certificate_path`
+* `tls.certificate_public_key_sha256`
+* 拨号字段
+
+不支持的字段:
+
+* `version`
+* `disable_version_fallback`
+* HTTP2 字段
+* QUIC 字段
+* `tls.engine`
+* `tls.alpn`
+* `tls.disable_sni`
+* `tls.cipher_suites`
+* `tls.curve_preferences`
+* `tls.client_certificate` / `tls.client_certificate_path` / `tls.client_key` / `tls.client_key_path`
+* `tls.fragment` / `tls.record_fragment`
+* `tls.kernel_tx` / `tls.kernel_rx`
+* `tls.ech`
+* `tls.utls`
+* `tls.reality`
+
+#### version
+
+HTTP 版本。
+
+可用值:`1`、`2`、`3`。
+
+默认使用 `2`。
+
+当为 `3` 时,[HTTP2 字段](#http2-字段) 替换为 [QUIC 字段](#quic-字段)。
+
+#### disable_version_fallback
+
+禁用自动回退到更低的 HTTP 版本。
+
+#### headers
+
+自定义 HTTP 标头。
+
+`Host` 标头用作请求主机。
+
+### HTTP2 字段
+
+当 `version` 为 `2`(默认)时。
+
+参阅 [HTTP2 字段](/zh/configuration/shared/http2/) 了解详情。
+
+### QUIC 字段
+
+当 `version` 为 `3` 时。
+
+参阅 [QUIC 字段](/zh/configuration/shared/quic/) 了解详情。
+
+### TLS 字段
+
+参阅 [TLS](/zh/configuration/shared/tls/#出站) 了解详情。
+
+### 拨号字段
+
+参阅 [拨号字段](/zh/configuration/shared/dial/) 了解详情。
diff --git a/docs/configuration/shared/http2.md b/docs/configuration/shared/http2.md
new file mode 100644
index 0000000000..e0e0afb473
--- /dev/null
+++ b/docs/configuration/shared/http2.md
@@ -0,0 +1,43 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+### Structure
+
+```json
+{
+ "idle_timeout": "",
+ "keep_alive_period": "",
+ "stream_receive_window": "",
+ "connection_receive_window": "",
+ "max_concurrent_streams": 0
+}
+```
+
+### Fields
+
+#### idle_timeout
+
+Idle connection timeout, in golang's Duration format.
+
+#### keep_alive_period
+
+Keep alive period, in golang's Duration format.
+
+#### stream_receive_window
+
+HTTP2 stream-level flow-control receive window size.
+
+Accepts memory size format, e.g. `"64 MB"`.
+
+#### connection_receive_window
+
+HTTP2 connection-level flow-control receive window size.
+
+Accepts memory size format, e.g. `"64 MB"`.
+
+#### max_concurrent_streams
+
+Maximum concurrent streams per connection.
diff --git a/docs/configuration/shared/http2.zh.md b/docs/configuration/shared/http2.zh.md
new file mode 100644
index 0000000000..344e865a55
--- /dev/null
+++ b/docs/configuration/shared/http2.zh.md
@@ -0,0 +1,43 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+### 结构
+
+```json
+{
+ "idle_timeout": "",
+ "keep_alive_period": "",
+ "stream_receive_window": "",
+ "connection_receive_window": "",
+ "max_concurrent_streams": 0
+}
+```
+
+### 字段
+
+#### idle_timeout
+
+空闲连接超时,采用 golang 的 Duration 格式。
+
+#### keep_alive_period
+
+Keep alive 周期,采用 golang 的 Duration 格式。
+
+#### stream_receive_window
+
+HTTP2 流级别流控接收窗口大小。
+
+接受内存大小格式,例如 `"64 MB"`。
+
+#### connection_receive_window
+
+HTTP2 连接级别流控接收窗口大小。
+
+接受内存大小格式,例如 `"64 MB"`。
+
+#### max_concurrent_streams
+
+每个连接的最大并发流数。
diff --git a/docs/configuration/shared/neighbor.md b/docs/configuration/shared/neighbor.md
new file mode 100644
index 0000000000..a0d5f36a7d
--- /dev/null
+++ b/docs/configuration/shared/neighbor.md
@@ -0,0 +1,51 @@
+---
+icon: material/lan
+---
+
+# Neighbor Resolution
+
+Match LAN devices by MAC address and hostname using
+[`source_mac_address`](/configuration/route/rule/#source_mac_address) and
+[`source_hostname`](/configuration/route/rule/#source_hostname) rule items.
+
+Neighbor resolution is automatically enabled when these rule items exist
+or when a [local DNS server](/configuration/dns/server/local/) sets
+[neighbor_domain](/configuration/dns/server/local/#neighbor_domain).
+Use [`route.find_neighbor`](/configuration/route/#find_neighbor) to force enable it for logging without rules.
+
+## Linux
+
+Works natively. No special setup required.
+
+Hostname resolution requires DHCP lease files,
+automatically detected from common DHCP servers (dnsmasq, odhcpd, ISC dhcpd, Kea).
+Custom paths can be set via [`route.dhcp_lease_files`](/configuration/route/#dhcp_lease_files).
+
+## Android
+
+!!! quote ""
+
+ Only supported in graphical clients.
+
+Requires Android 11 or above and ROOT.
+
+Must use [VPNHotspot](https://github.com/Mygod/VPNHotspot) to share the VPN connection.
+ROM built-in features like "Use VPN for connected devices" can share VPN
+but cannot provide MAC address or hostname information.
+
+Set **IP Masquerade Mode** to **None** in VPNHotspot settings.
+
+Only route/DNS rules are supported. TUN include/exclude routes are not supported.
+
+### Hostname Visibility
+
+Hostname is only visible in sing-box if it is visible in VPNHotspot.
+For Apple devices, change **Private Wi-Fi Address** from **Rotating** to **Fixed** in the Wi-Fi settings
+of the connected network. Non-Apple devices are always visible.
+
+## macOS
+
+Requires the standalone version (macOS system extension).
+The App Store version can share the VPN as a hotspot but does not support MAC address or hostname reading.
+
+See [VPN Hotspot](/manual/misc/vpn-hotspot/#macos) for Internet Sharing setup.
diff --git a/docs/configuration/shared/neighbor.zh.md b/docs/configuration/shared/neighbor.zh.md
new file mode 100644
index 0000000000..7f4065ecf4
--- /dev/null
+++ b/docs/configuration/shared/neighbor.zh.md
@@ -0,0 +1,49 @@
+---
+icon: material/lan
+---
+
+# 邻居解析
+
+通过
+[`source_mac_address`](/configuration/route/rule/#source_mac_address) 和
+[`source_hostname`](/configuration/route/rule/#source_hostname) 规则项匹配局域网设备的 MAC 地址和主机名。
+
+当这些规则项存在,或 [local DNS 服务器](/zh/configuration/dns/server/local/) 设置了 [neighbor_domain](/zh/configuration/dns/server/local/#neighbor_domain) 时,邻居解析自动启用。
+使用 [`route.find_neighbor`](/configuration/route/#find_neighbor) 可在没有规则时强制启用以输出日志。
+
+## Linux
+
+原生支持,无需特殊设置。
+
+主机名解析需要 DHCP 租约文件,
+自动从常见 DHCP 服务器(dnsmasq、odhcpd、ISC dhcpd、Kea)检测。
+可通过 [`route.dhcp_lease_files`](/configuration/route/#dhcp_lease_files) 设置自定义路径。
+
+## Android
+
+!!! quote ""
+
+ 仅在图形客户端中支持。
+
+需要 Android 11 或以上版本和 ROOT。
+
+必须使用 [VPNHotspot](https://github.com/Mygod/VPNHotspot) 共享 VPN 连接。
+ROM 自带的「通过 VPN 共享连接」等功能可以共享 VPN,
+但无法提供 MAC 地址或主机名信息。
+
+在 VPNHotspot 设置中将 **IP 遮掩模式** 设为 **无**。
+
+仅支持路由/DNS 规则。不支持 TUN 的 include/exclude 路由。
+
+### 设备可见性
+
+MAC 地址和主机名仅在 VPNHotspot 中可见时 sing-box 才能读取。
+对于 Apple 设备,需要在所连接网络的 Wi-Fi 设置中将**私有无线局域网地址**从**轮替**改为**固定**。
+非 Apple 设备始终可见。
+
+## macOS
+
+需要独立版本(macOS 系统扩展)。
+App Store 版本可以共享 VPN 热点但不支持 MAC 地址或主机名读取。
+
+参阅 [VPN 热点](/manual/misc/vpn-hotspot/#macos) 了解互联网共享设置。
diff --git a/docs/configuration/shared/quic.md b/docs/configuration/shared/quic.md
new file mode 100644
index 0000000000..485a8ff8d8
--- /dev/null
+++ b/docs/configuration/shared/quic.md
@@ -0,0 +1,30 @@
+---
+icon: material/new-box
+---
+
+!!! question "Since sing-box 1.14.0"
+
+### Structure
+
+```json
+{
+ "initial_packet_size": 0,
+ "disable_path_mtu_discovery": false,
+
+ ... // HTTP2 Fields
+}
+```
+
+### Fields
+
+#### initial_packet_size
+
+Initial QUIC packet size.
+
+#### disable_path_mtu_discovery
+
+Disable QUIC path MTU discovery.
+
+### HTTP2 Fields
+
+See [HTTP2 Fields](/configuration/shared/http2/) for details.
diff --git a/docs/configuration/shared/quic.zh.md b/docs/configuration/shared/quic.zh.md
new file mode 100644
index 0000000000..1e840e8f58
--- /dev/null
+++ b/docs/configuration/shared/quic.zh.md
@@ -0,0 +1,30 @@
+---
+icon: material/new-box
+---
+
+!!! question "自 sing-box 1.14.0 起"
+
+### 结构
+
+```json
+{
+ "initial_packet_size": 0,
+ "disable_path_mtu_discovery": false,
+
+ ... // HTTP2 字段
+}
+```
+
+### 字段
+
+#### initial_packet_size
+
+初始 QUIC 数据包大小。
+
+#### disable_path_mtu_discovery
+
+禁用 QUIC 路径 MTU 发现。
+
+### HTTP2 字段
+
+参阅 [HTTP2 字段](/zh/configuration/shared/http2/) 了解详情。
diff --git a/docs/configuration/shared/tls.md b/docs/configuration/shared/tls.md
index 73ceffccef..70e3b5c4fe 100644
--- a/docs/configuration/shared/tls.md
+++ b/docs/configuration/shared/tls.md
@@ -2,6 +2,15 @@
icon: material/new-box
---
+!!! quote "Changes in sing-box 1.14.0"
+
+ :material-plus: [certificate_provider](#certificate_provider)
+ :material-plus: [handshake_timeout](#handshake_timeout)
+ :material-plus: [spoof](#spoof)
+ :material-plus: [spoof_method](#spoof_method)
+ :material-plus: [engine](#engine)
+ :material-delete-clock: [acme](#acme-fields)
+
!!! quote "Changes in sing-box 1.13.0"
:material-plus: [kernel_tx](#kernel_tx)
@@ -49,6 +58,11 @@ icon: material/new-box
"key_path": "",
"kernel_tx": false,
"kernel_rx": false,
+ "handshake_timeout": "",
+ "certificate_provider": "",
+
+ // Deprecated
+
"acme": {
"domain": [],
"data_directory": "",
@@ -97,6 +111,7 @@ icon: material/new-box
```json
{
"enabled": true,
+ "engine": "",
"disable_sni": false,
"server_name": "",
"insecure": false,
@@ -115,6 +130,11 @@ icon: material/new-box
"fragment": false,
"fragment_fallback_delay": "",
"record_fragment": false,
+ "spoof": "",
+ "spoof_method": "",
+ "kernel_tx": false,
+ "kernel_rx": false,
+ "handshake_timeout": "",
"ech": {
"enabled": false,
"config": [],
@@ -174,6 +194,76 @@ Cipher suite values:
Enable TLS.
+#### engine
+
+!!! question "Since sing-box 1.14.0"
+
+==Client only==
+
+TLS engine to use.
+
+Values:
+
+* `go` (default)
+* `apple`
+* `windows`
+
+Supported fields:
+
+* `server_name`
+* `insecure`
+* `alpn`
+* `min_version`
+* `max_version`
+* `certificate` / `certificate_path`
+* `certificate_public_key_sha256`
+* `handshake_timeout`
+
+Unsupported fields:
+
+* `disable_sni`
+* `cipher_suites`
+* `curve_preferences`
+* `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
+* `fragment` / `record_fragment`
+* `kernel_tx` / `kernel_rx`
+* `ech`
+* `utls`
+* `reality`
+
+!!! note ""
+
+ `windows` uses Schannel via SSPI. Only available on Windows build 17763 or later (Windows 10 version 1809, Windows Server 2019, or newer).
+
+!!! note ""
+
+ TLS 1.3 is only negotiated on Windows 11 or Windows Server 2022 and newer. On older Windows versions, Schannel caps the connection at TLS 1.2 even when `max_version` is `1.3`.
+
+The default version range is TLS 1.2 to TLS 1.3, matching the `go` engine.
+
+Supported fields:
+
+* `server_name`
+* `insecure`
+* `alpn`
+* `min_version`
+* `max_version`
+* `certificate` / `certificate_path`
+* `certificate_public_key_sha256`
+* `handshake_timeout`
+
+Unsupported fields:
+
+* `disable_sni`
+* `cipher_suites`
+* `curve_preferences`
+* `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
+* `fragment` / `record_fragment`
+* `kernel_tx` / `kernel_rx`
+* `ech`
+* `utls`
+* `reality`
+
#### disable_sni
==Client only==
@@ -408,6 +498,26 @@ Enable kernel TLS transmit support.
Enable kernel TLS receive support.
+#### handshake_timeout
+
+!!! question "Since sing-box 1.14.0"
+
+TLS handshake timeout, in golang's Duration format.
+
+`15s` is used by default.
+
+#### certificate_provider
+
+!!! question "Since sing-box 1.14.0"
+
+==Server only==
+
+A string or an object.
+
+When string, the tag of a shared [Certificate Provider](/configuration/shared/certificate-provider/).
+
+When object, an inline certificate provider. See [Certificate Provider](/configuration/shared/certificate-provider/) for available types and fields.
+
## Custom TLS support
!!! info "QUIC support"
@@ -469,7 +579,7 @@ The ECH key and configuration can be generated by `sing-box generate ech-keypair
!!! failure "Deprecated in sing-box 1.12.0"
- ECH support has been migrated to use stdlib in sing-box 1.12.0, which does not come with support for PQ signature schemes, so `pq_signature_schemes_enabled` has been deprecated and no longer works.
+ `pq_signature_schemes_enabled` is deprecated in sing-box 1.12.0 and removed in sing-box 1.13.0.
Enable support for post-quantum peer certificate signature schemes.
@@ -477,7 +587,7 @@ Enable support for post-quantum peer certificate signature schemes.
!!! failure "Deprecated in sing-box 1.12.0"
- `dynamic_record_sizing_disabled` has nothing to do with ECH, was added by mistake, has been deprecated and no longer works.
+ `dynamic_record_sizing_disabled` is deprecated in sing-box 1.12.0 and removed in sing-box 1.13.0.
Disables adaptive sizing of TLS records.
@@ -564,8 +674,48 @@ The fallback value used when TLS segmentation cannot automatically determine the
Fragment TLS handshake into multiple TLS records to bypass firewalls.
+#### spoof
+
+!!! question "Since sing-box 1.14.0"
+
+==Client only, Linux/macOS/Windows only, requires elevated privileges==
+
+Inject a forged TLS ClientHello carrying a whitelisted SNI before the real one,
+to fool SNI-filtering middleboxes that permit specific hostnames.
+
+The forged segment is a copy of the real ClientHello with only the SNI value
+replaced by the value of this field, so TLS fingerprinting cannot distinguish
+it from the real one. The receiving server drops the forged segment
+(see `spoof_method`) while the middlebox treats it as a legitimate session.
+
+Requires raw-socket access (`CAP_NET_RAW` on Linux, root on macOS);
+on Linux, `CAP_NET_ADMIN` is additionally required because the send sequence
+number is read via `TCP_REPAIR`.
+On Windows, Administrator is required to install the embedded WinDivert kernel
+driver on first use. Windows on ARM64 is not supported.
+
+#### spoof_method
+
+!!! question "Since sing-box 1.14.0"
+
+==Client only==
+
+How the forged segment is rejected by the real server.
+
+| Value | Behavior |
+|----------------------------|----------------------------------------------------------------------------------------------------------------|
+| `wrong-sequence` (default) | The forged segment's TCP sequence number is placed before the server's receive window. |
+| `wrong-checksum` | The forged segment's TCP checksum is deliberately invalid. |
+| `wrong-ack` | The forged segment's TCP acknowledgment number is placed before the server's send window. |
+| `wrong-md5` | The forged segment carries a TCP-MD5 signature option, which the server rejects since no MD5 key is negotiated. |
+| `wrong-timestamp` | The forged segment carries a backdated TCP timestamp, which the server rejects as a PAWS replay. Linux/Windows only; not supported on macOS. |
+
### ACME Fields
+!!! failure "Deprecated in sing-box 1.14.0"
+
+ Inline ACME options are deprecated in sing-box 1.14.0 and will be removed in sing-box 1.16.0, check [Migration](/migration/#migrate-inline-acme-to-certificate-provider).
+
#### domain
List of domain.
@@ -677,4 +827,4 @@ A hexadecimal string with zero to eight digits.
The maximum time difference between the server and the client.
-Check disabled if empty.
\ No newline at end of file
+Check disabled if empty.
diff --git a/docs/configuration/shared/tls.zh.md b/docs/configuration/shared/tls.zh.md
index 0b47189bc6..40762c4f74 100644
--- a/docs/configuration/shared/tls.zh.md
+++ b/docs/configuration/shared/tls.zh.md
@@ -2,6 +2,15 @@
icon: material/new-box
---
+!!! quote "sing-box 1.14.0 中的更改"
+
+ :material-plus: [certificate_provider](#certificate_provider)
+ :material-plus: [handshake_timeout](#handshake_timeout)
+ :material-plus: [spoof](#spoof)
+ :material-plus: [spoof_method](#spoof_method)
+ :material-plus: [engine](#engine)
+ :material-delete-clock: [acme](#acme-字段)
+
!!! quote "sing-box 1.13.0 中的更改"
:material-plus: [kernel_tx](#kernel_tx)
@@ -49,6 +58,11 @@ icon: material/new-box
"key_path": "",
"kernel_tx": false,
"kernel_rx": false,
+ "handshake_timeout": "",
+ "certificate_provider": "",
+
+ // 废弃的
+
"acme": {
"domain": [],
"data_directory": "",
@@ -97,6 +111,7 @@ icon: material/new-box
```json
{
"enabled": true,
+ "engine": "",
"disable_sni": false,
"server_name": "",
"insecure": false,
@@ -115,6 +130,11 @@ icon: material/new-box
"fragment": false,
"fragment_fallback_delay": "",
"record_fragment": false,
+ "spoof": "",
+ "spoof_method": "",
+ "kernel_tx": false,
+ "kernel_rx": false,
+ "handshake_timeout": "",
"ech": {
"enabled": false,
"config": [],
@@ -174,6 +194,76 @@ TLS 版本值:
启用 TLS
+#### engine
+
+!!! question "自 sing-box 1.14.0 起"
+
+==仅客户端==
+
+要使用的 TLS 引擎。
+
+可用值:
+
+* `go`(默认)
+* `apple`
+* `windows`
+
+支持的字段:
+
+* `server_name`
+* `insecure`
+* `alpn`
+* `min_version`
+* `max_version`
+* `certificate` / `certificate_path`
+* `certificate_public_key_sha256`
+* `handshake_timeout`
+
+不支持的字段:
+
+* `disable_sni`
+* `cipher_suites`
+* `curve_preferences`
+* `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
+* `fragment` / `record_fragment`
+* `kernel_tx` / `kernel_rx`
+* `ech`
+* `utls`
+* `reality`
+
+!!! note ""
+
+ `windows` 通过 SSPI 使用 Schannel,仅在 Windows build 17763 及以上可用,包括 Windows 10 版本 1809、Windows Server 2019 及后续版本。
+
+!!! note ""
+
+ TLS 1.3 仅在 Windows 11 或 Windows Server 2022 及后续版本上协商。在更早的 Windows 版本上,即使 `max_version` 设为 `1.3`,Schannel 也会把连接上限固定在 TLS 1.2。
+
+默认版本范围为 TLS 1.2 到 TLS 1.3,与 `go` 引擎一致。证书验证在 Go 侧基于 Schannel 返回的证书链执行,默认使用系统证书存储。当设置了 `certificate` 或 `certificate_path` 时,这些根证书会替代系统存储。
+
+支持的字段:
+
+* `server_name`
+* `insecure`
+* `alpn`
+* `min_version`
+* `max_version`
+* `certificate` / `certificate_path`
+* `certificate_public_key_sha256`
+* `handshake_timeout`
+
+不支持的字段:
+
+* `disable_sni`
+* `cipher_suites`
+* `curve_preferences`
+* `client_certificate` / `client_certificate_path` / `client_key` / `client_key_path`
+* `fragment` / `record_fragment`
+* `kernel_tx` / `kernel_rx`
+* `ech`
+* `utls`
+* `reality`
+
#### disable_sni
==仅客户端==
@@ -407,6 +497,26 @@ echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/
启用内核 TLS 接收支持。
+#### handshake_timeout
+
+!!! question "自 sing-box 1.14.0 起"
+
+TLS 握手超时,采用 golang 的 Duration 格式。
+
+默认使用 `15s`。
+
+#### certificate_provider
+
+!!! question "自 sing-box 1.14.0 起"
+
+==仅服务器==
+
+字符串或对象。
+
+为字符串时,共享[证书提供者](/zh/configuration/shared/certificate-provider/)的标签。
+
+为对象时,内联的证书提供者。可用类型和字段参阅[证书提供者](/zh/configuration/shared/certificate-provider/)。
+
## 自定义 TLS 支持
!!! info "QUIC 支持"
@@ -465,7 +575,7 @@ ECH 密钥和配置可以通过 `sing-box generate ech-keypair` 生成。
!!! failure "已在 sing-box 1.12.0 废弃"
- ECH 支持已在 sing-box 1.12.0 迁移至使用标准库,但标准库不支持后量子对等证书签名方案,因此 `pq_signature_schemes_enabled` 已被弃用且不再工作。
+ `pq_signature_schemes_enabled` 已在 sing-box 1.12.0 废弃且已在 sing-box 1.13.0 中被移除。
启用对后量子对等证书签名方案的支持。
@@ -473,7 +583,7 @@ ECH 密钥和配置可以通过 `sing-box generate ech-keypair` 生成。
!!! failure "已在 sing-box 1.12.0 废弃"
- `dynamic_record_sizing_disabled` 与 ECH 无关,是错误添加的,现已弃用且不再工作。
+ `dynamic_record_sizing_disabled` 已在 sing-box 1.12.0 废弃且已在 sing-box 1.13.0 中被移除。
禁用 TLS 记录的自适应大小调整。
@@ -559,8 +669,46 @@ ECH 配置路径,PEM 格式。
将 TLS 握手分段为多个 TLS 记录以绕过防火墙。
+#### spoof
+
+!!! question "自 sing-box 1.14.0 起"
+
+==仅客户端,仅 Linux/macOS/Windows,需要提权==
+
+在真实 ClientHello 之前注入一个伪造的、携带白名单 SNI 的 TLS ClientHello,
+以欺骗基于 SNI 过滤的中间盒放行连接。
+
+伪造报文是真实 ClientHello 的副本,仅将 SNI 值替换为本字段的值,
+因此 TLS 指纹无法区分伪造与真实报文。真实服务器会丢弃伪造报文(见 `spoof_method`),
+而中间盒将该连接视为合法会话。
+
+需要原始套接字权限(Linux 上需 `CAP_NET_RAW`,macOS 上需 root);
+在 Linux 上还需 `CAP_NET_ADMIN`,因为需要通过 `TCP_REPAIR` 读取发送序列号。
+Windows 上首次使用时需要 Administrator 以安装内嵌的 WinDivert 内核驱动,
+不支持 Windows ARM64。
+
+#### spoof_method
+
+!!! question "自 sing-box 1.14.0 起"
+
+==仅客户端==
+
+控制伪造报文被真实服务器拒绝的方式。
+
+| 取值 | 行为 |
+|--------------------------|-------------------------------------------------------------------|
+| `wrong-sequence`(默认) | 伪造报文的 TCP 序列号位于服务器接收窗口之前。 |
+| `wrong-checksum` | 伪造报文的 TCP 校验和被故意设为无效。 |
+| `wrong-ack` | 伪造报文的 TCP 确认号位于服务器发送窗口之前。 |
+| `wrong-md5` | 伪造报文携带 TCP-MD5 签名选项,未协商 MD5 密钥的服务器将拒绝。 |
+| `wrong-timestamp` | 伪造报文携带回退的 TCP 时间戳,服务器按 PAWS 规则视为重放并拒绝。仅支持 Linux/Windows,不支持 macOS。 |
+
### ACME 字段
+!!! failure "已在 sing-box 1.14.0 废弃"
+
+ 内联 ACME 选项已在 sing-box 1.14.0 废弃且将在 sing-box 1.16.0 中被移除,参阅 [迁移指南](/zh/migration/#迁移内联-acme-到证书提供者)。
+
#### domain
域名列表。
diff --git a/docs/deprecated.md b/docs/deprecated.md
index 8e53bda6db..8e8498ae67 100644
--- a/docs/deprecated.md
+++ b/docs/deprecated.md
@@ -4,14 +4,74 @@ icon: material/delete-alert
# Deprecated Feature List
+## 1.14.0
+
+#### Legacy `download_detour` remote rule-set option
+
+Legacy `download_detour` remote rule-set option is deprecated,
+use `http_client` instead.
+
+Old field will be removed in sing-box 1.16.0.
+
+#### Implicit default HTTP client
+
+Implicit default HTTP client using the default outbound for remote rule-sets is deprecated.
+Configure `http_clients` and `route.default_http_client` explicitly.
+
+Old behavior will be removed in sing-box 1.16.0.
+
+#### Inline ACME options in TLS
+
+Inline ACME options (`tls.acme`) are deprecated
+and can be replaced by the ACME certificate provider,
+check [Migration](../migration/#migrate-inline-acme-to-certificate-provider).
+
+Old fields will be removed in sing-box 1.16.0.
+
+#### Legacy `strategy` DNS rule action option
+
+Legacy `strategy` DNS rule action option is deprecated.
+
+Old fields will be removed in sing-box 1.16.0.
+
+#### Legacy `rule_set_ip_cidr_accept_empty` DNS rule item
+
+Legacy `rule_set_ip_cidr_accept_empty` DNS rule item is deprecated,
+check [Migration](../migration/#migrate-address-filter-fields-to-response-matching).
+
+Old fields will be removed in sing-box 1.16.0.
+
+#### `independent_cache` DNS option
+
+`independent_cache` DNS option is deprecated.
+The DNS cache now always keys by transport, making this option unnecessary,
+check [Migration](../migration/#migrate-independent-dns-cache).
+
+Old fields will be removed in sing-box 1.16.0.
+
+#### `store_rdrc` cache file option
+
+`store_rdrc` cache file option is deprecated,
+check [Migration](../migration/#migrate-store-rdrc).
+
+Old fields will be removed in sing-box 1.16.0.
+
+#### Legacy Address Filter Fields in DNS rules
+
+Legacy Address Filter Fields (`ip_cidr`, `ip_is_private` without `match_response`)
+in DNS rules are deprecated,
+check [Migration](../migration/#migrate-address-filter-fields-to-response-matching).
+
+Old behavior will be removed in sing-box 1.16.0.
+
## 1.12.0
#### Legacy DNS server formats
DNS servers are refactored,
-check [Migration](../migration/#migrate-to-new-dns-servers).
+check [Migration](../migration/#migrate-to-new-dns-server-formats).
-Compatibility for old formats will be removed in sing-box 1.14.0.
+Old formats were removed in sing-box 1.14.0.
#### `outbound` DNS rule item
@@ -28,7 +88,7 @@ so `pq_signature_schemes_enabled` has been deprecated and no longer works.
Also, `dynamic_record_sizing_disabled` has nothing to do with ECH,
was added by mistake, has been deprecated and no longer works.
-These fields will be removed in sing-box 1.13.0.
+These fields were removed in sing-box 1.13.0.
## 1.11.0
@@ -38,7 +98,7 @@ Legacy special outbounds (`block` / `dns`) are deprecated
and can be replaced by rule actions,
check [Migration](../migration/#migrate-legacy-special-outbounds-to-rule-actions).
-Old fields will be removed in sing-box 1.13.0.
+Old fields were removed in sing-box 1.13.0.
#### Legacy inbound fields
@@ -46,7 +106,7 @@ Legacy inbound fields (`inbound.` are deprecated
and can be replaced by rule actions,
check [Migration](../migration/#migrate-legacy-inbound-fields-to-rule-actions).
-Old fields will be removed in sing-box 1.13.0.
+Old fields were removed in sing-box 1.13.0.
#### Destination override fields in direct outbound
@@ -54,18 +114,20 @@ Destination override fields (`override_address` / `override_port`) in direct out
and can be replaced by rule actions,
check [Migration](../migration/#migrate-destination-override-fields-to-route-options).
+Old fields were removed in sing-box 1.13.0.
+
#### WireGuard outbound
WireGuard outbound is deprecated and can be replaced by endpoint,
check [Migration](../migration/#migrate-wireguard-outbound-to-endpoint).
-Old outbound will be removed in sing-box 1.13.0.
+Old outbound was removed in sing-box 1.13.0.
#### GSO option in TUN
GSO has no advantages for transparent proxy scenarios, is deprecated and no longer works in TUN.
-Old fields will be removed in sing-box 1.13.0.
+Old fields were removed in sing-box 1.13.0.
## 1.10.0
@@ -75,12 +137,12 @@ Old fields will be removed in sing-box 1.13.0.
`inet4_route_address` and `inet6_route_address` are merged into `route_address`,
`inet4_route_exclude_address` and `inet6_route_exclude_address` are merged into `route_exclude_address`.
-Old fields will be removed in sing-box 1.12.0.
+Old fields were removed in sing-box 1.12.0.
#### Match source rule items are renamed
`rule_set_ipcidr_match_source` route and DNS rule items are renamed to
-`rule_set_ip_cidr_match_source` and will be remove in sing-box 1.11.0.
+`rule_set_ip_cidr_match_source` and were removed in sing-box 1.11.0.
#### Drop support for go1.18 and go1.19
@@ -95,7 +157,7 @@ check [Migration](/migration/#migrate-cache-file-from-clash-api-to-independent-o
#### GeoIP
-GeoIP is deprecated and will be removed in sing-box 1.12.0.
+GeoIP is deprecated and was removed in sing-box 1.12.0.
The maxmind GeoIP National Database, as an IP classification database,
is not entirely suitable for traffic bypassing,
@@ -106,7 +168,7 @@ check [Migration](/migration/#migrate-geoip-to-rule-sets).
#### Geosite
-Geosite is deprecated and will be removed in sing-box 1.12.0.
+Geosite is deprecated and was removed in sing-box 1.12.0.
Geosite, the `domain-list-community` project maintained by V2Ray as an early traffic bypassing solution,
suffers from a number of problems, including lack of maintenance, inaccurate rules, and difficult management.
diff --git a/docs/deprecated.zh.md b/docs/deprecated.zh.md
index 82b6db042f..887139bb66 100644
--- a/docs/deprecated.zh.md
+++ b/docs/deprecated.zh.md
@@ -4,12 +4,73 @@ icon: material/delete-alert
# 废弃功能列表
+## 1.14.0
+
+#### 旧版远程规则集 `download_detour` 选项
+
+旧版远程规则集 `download_detour` 选项已废弃,
+请使用 `http_client` 代替。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### 隐式默认 HTTP 客户端
+
+使用默认出站为远程规则集隐式创建默认 HTTP 客户端的行为已废弃。
+请显式配置 `http_clients` 和 `route.default_http_client`。
+
+旧行为将在 sing-box 1.16.0 中被移除。
+
+#### TLS 中的内联 ACME 选项
+
+TLS 中的内联 ACME 选项(`tls.acme`)已废弃,
+且可以通过 ACME 证书提供者替代,
+参阅 [迁移指南](/zh/migration/#迁移内联-acme-到证书提供者)。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### 旧版 DNS 规则动作 `strategy` 选项
+
+旧版 DNS 规则动作 `strategy` 选项已废弃。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### 旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项
+
+旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项已废弃,
+参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### `independent_cache` DNS 选项
+
+`independent_cache` DNS 选项已废弃。
+DNS 缓存现在始终按传输分离,使此选项不再需要,
+参阅[迁移指南](/zh/migration/#迁移-independent-dns-cache)。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### `store_rdrc` 缓存文件选项
+
+`store_rdrc` 缓存文件选项已废弃,
+参阅[迁移指南](/zh/migration/#迁移-store_rdrc)。
+
+旧字段将在 sing-box 1.16.0 中被移除。
+
+#### 旧版地址筛选字段 (DNS 规则)
+
+旧版地址筛选字段(不使用 `match_response` 的 `ip_cidr`、`ip_is_private`)已废弃,
+参阅[迁移指南](/zh/migration/#迁移地址筛选字段到响应匹配)。
+
+旧行为将在 sing-box 1.16.0 中被移除。
+
+## 1.12.0
+
#### 旧的 DNS 服务器格式
DNS 服务器已重构,
参阅 [迁移指南](/zh/migration/#迁移到新的-dns-服务器格式).
-对旧格式的兼容性将在 sing-box 1.14.0 中被移除。
+旧格式已在 sing-box 1.14.0 中被移除。
#### `outbound` DNS 规则项
@@ -24,7 +85,7 @@ ECH 支持已在 sing-box 1.12.0 迁移至使用标准库,但标准库不支
另外,`dynamic_record_sizing_disabled` 与 ECH 无关,是错误添加的,现已弃用且不再工作。
-相关字段将在 sing-box 1.13.0 中被移除。
+相关字段已在 sing-box 1.13.0 中被移除。
## 1.11.0
@@ -33,41 +94,41 @@ ECH 支持已在 sing-box 1.12.0 迁移至使用标准库,但标准库不支
旧的特殊出站(`block` / `dns`)已废弃且可以通过规则动作替代,
参阅 [迁移指南](/zh/migration/#迁移旧的特殊出站到规则动作)。
-旧字段将在 sing-box 1.13.0 中被移除。
+旧字段已在 sing-box 1.13.0 中被移除。
#### 旧的入站字段
旧的入站字段(`inbound.`)已废弃且可以通过规则动作替代,
参阅 [迁移指南](/zh/migration/#迁移旧的入站字段到规则动作)。
-旧字段将在 sing-box 1.13.0 中被移除。
+旧字段已在 sing-box 1.13.0 中被移除。
#### direct 出站中的目标地址覆盖字段
direct 出站中的目标地址覆盖字段(`override_address` / `override_port`)已废弃且可以通过规则动作替代,
参阅 [迁移指南](/zh/migration/#迁移-direct-出站中的目标地址覆盖字段到路由字段)。
-旧字段将在 sing-box 1.13.0 中被移除。
+旧字段已在 sing-box 1.13.0 中被移除。
#### WireGuard 出站
WireGuard 出站已废弃且可以通过端点替代,
参阅 [迁移指南](/zh/migration/#迁移-wireguard-出站到端点)。
-旧出站将在 sing-box 1.13.0 中被移除。
+旧出站已在 sing-box 1.13.0 中被移除。
#### TUN 的 GSO 字段
GSO 对透明代理场景没有优势,已废弃且在 TUN 中不再起作用。
-旧字段将在 sing-box 1.13.0 中被移除。
+旧字段已在 sing-box 1.13.0 中被移除。
## 1.10.0
#### Match source 规则项已重命名
`rule_set_ipcidr_match_source` 路由和 DNS 规则项已被重命名为
-`rule_set_ip_cidr_match_source` 且将在 sing-box 1.11.0 中被移除。
+`rule_set_ip_cidr_match_source` 且已在 sing-box 1.11.0 中被移除。
#### TUN 地址字段已合并
@@ -75,7 +136,7 @@ GSO 对透明代理场景没有优势,已废弃且在 TUN 中不再起作用
`inet4_route_address` 和 `inet6_route_address` 已合并为 `route_address`,
`inet4_route_exclude_address` 和 `inet6_route_exclude_address` 已合并为 `route_exclude_address`。
-旧字段将在 sing-box 1.11.0 中被移除。
+旧字段已在 sing-box 1.12.0 中被移除。
#### 移除对 go1.18 和 go1.19 的支持
@@ -90,7 +151,7 @@ Clash API 中的 `cache_file` 及相关功能已废弃且已迁移到独立的 `
#### GeoIP
-GeoIP 已废弃且将在 sing-box 1.12.0 中被移除。
+GeoIP 已废弃且已在 sing-box 1.12.0 中被移除。
maxmind GeoIP 国家数据库作为 IP 分类数据库,不完全适合流量绕过,
且现有的实现均存在内存使用大与管理困难的问题。
@@ -100,7 +161,7 @@ sing-box 1.8.0 引入了[规则集](/zh/configuration/rule-set/),
#### Geosite
-Geosite 已废弃且将在 sing-box 1.12.0 中被移除。
+Geosite 已废弃且已在 sing-box 1.12.0 中被移除。
Geosite,即由 V2Ray 维护的 domain-list-community 项目,作为早期流量绕过解决方案,
存在着包括缺少维护、规则不准确和管理困难内的大量问题。
diff --git a/docs/installation/build-from-source.md b/docs/installation/build-from-source.md
index 8152a89e22..48b53b178d 100644
--- a/docs/installation/build-from-source.md
+++ b/docs/installation/build-from-source.md
@@ -61,6 +61,7 @@ go build -tags "tag_a tag_b" ./cmd/sing-box
| `with_ccm` | :material-check: | Build with Claude Code Multiplexer service support. |
| `with_ocm` | :material-check: | Build with OpenAI Codex Multiplexer service support. |
| `with_naive_outbound` | :material-check: | Build with NaiveProxy outbound support, see [NaiveProxy outbound](/configuration/outbound/naive/). |
+| `with_cloudflared` | :material-check: | Build with Cloudflare Tunnel inbound support, see [Cloudflared inbound](/configuration/inbound/cloudflared/). |
| `badlinkname` | :material-check: | Enable `go:linkname` access to internal standard library functions. Required because the Go standard library does not expose many low-level APIs needed by this project, and reimplementing them externally is impractical. Used for kTLS (kernel TLS offload) and raw TLS record manipulation. |
| `tfogo_checklinkname0` | :material-check: | Companion to `badlinkname`. Go 1.23+ enforces `go:linkname` restrictions via the linker; this tag signals the build uses `-checklinkname=0` to bypass that enforcement. |
diff --git a/docs/installation/build-from-source.zh.md b/docs/installation/build-from-source.zh.md
index d6cd03b516..4ffebdc65d 100644
--- a/docs/installation/build-from-source.zh.md
+++ b/docs/installation/build-from-source.zh.md
@@ -65,6 +65,7 @@ go build -tags "tag_a tag_b" ./cmd/sing-box
| `with_ccm` | :material-check: | 构建 Claude Code Multiplexer 服务支持。 |
| `with_ocm` | :material-check: | 构建 OpenAI Codex Multiplexer 服务支持。 |
| `with_naive_outbound` | :material-check: | 构建 NaiveProxy 出站支持,参阅 [NaiveProxy 出站](/zh/configuration/outbound/naive/)。 |
+| `with_cloudflared` | :material-check: | 构建 Cloudflare Tunnel 入站支持,参阅 [Cloudflared 入站](/zh/configuration/inbound/cloudflared/)。 |
| `badlinkname` | :material-check: | 启用 `go:linkname` 以访问标准库内部函数。Go 标准库未提供本项目需要的许多底层 API,且在外部重新实现不切实际。用于 kTLS(内核 TLS 卸载)和原始 TLS 记录操作。 |
| `tfogo_checklinkname0` | :material-check: | `badlinkname` 的伴随标记。Go 1.23+ 链接器强制限制 `go:linkname` 使用;此标记表示构建使用 `-checklinkname=0` 以绕过该限制。 |
diff --git a/docs/migration.md b/docs/migration.md
index 86074ac712..be26827f03 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -2,6 +2,255 @@
icon: material/arrange-bring-forward
---
+## 1.14.0
+
+### Migrate inline ACME to certificate provider
+
+Inline ACME options in TLS are deprecated and can be replaced by certificate providers.
+
+Most `tls.acme` fields can be moved into the ACME certificate provider unchanged.
+See [ACME](/configuration/shared/certificate-provider/acme/) for fields newly added in sing-box 1.14.0.
+
+!!! info "References"
+
+ [TLS](/configuration/shared/tls/#certificate_provider) /
+ [Certificate Provider](/configuration/shared/certificate-provider/)
+
+=== ":material-card-remove: Deprecated"
+
+ ```json
+ {
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "acme": {
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ }
+ }
+ ]
+ }
+ ```
+
+=== ":material-card-multiple: Inline"
+
+ ```json
+ {
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "certificate_provider": {
+ "type": "acme",
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ }
+ }
+ ]
+ }
+ ```
+
+=== ":material-card-multiple: Shared"
+
+ ```json
+ {
+ "certificate_providers": [
+ {
+ "type": "acme",
+ "tag": "my-cert",
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ ],
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "certificate_provider": "my-cert"
+ }
+ }
+ ]
+ }
+ ```
+
+### Migrate address filter fields to response matching
+
+Legacy Address Filter Fields (`ip_cidr`, `ip_is_private` without `match_response`) in DNS rules are deprecated,
+along with the Legacy `rule_set_ip_cidr_accept_empty` DNS rule item. A DNS rule that references a rule-set
+containing only `ip_cidr` items (for example, a GeoIP rule-set) without `match_response` is also rejected
+at startup when legacy DNS mode is disabled.
+
+In sing-box 1.14.0, use the [`evaluate`](/configuration/dns/rule_action/#evaluate) action
+to fetch a DNS response, then match against it explicitly with `match_response`.
+
+!!! info "References"
+
+ [DNS Rule](/configuration/dns/rule/) /
+ [DNS Rule Action](/configuration/dns/rule_action/#evaluate)
+
+=== ":material-card-remove: Deprecated"
+
+ ```json
+ {
+ "dns": {
+ "rules": [
+ {
+ "rule_set": "geoip-cn",
+ "action": "route",
+ "server": "local"
+ },
+ {
+ "action": "route",
+ "server": "remote"
+ }
+ ]
+ }
+ }
+ ```
+
+=== ":material-card-multiple: New"
+
+ ```json
+ {
+ "dns": {
+ "rules": [
+ {
+ "action": "evaluate",
+ "server": "remote"
+ },
+ {
+ "match_response": true,
+ "rule_set": "geoip-cn",
+ "action": "route",
+ "server": "local"
+ },
+ {
+ "action": "route",
+ "server": "remote"
+ }
+ ]
+ }
+ }
+ ```
+
+### Migrate independent DNS cache
+
+The DNS cache now always keys by transport name, making `independent_cache` unnecessary.
+Simply remove the field.
+
+!!! info "References"
+
+ [DNS](/configuration/dns/)
+
+=== ":material-card-remove: Deprecated"
+
+ ```json
+ {
+ "dns": {
+ "independent_cache": true
+ }
+ }
+ ```
+
+=== ":material-card-multiple: New"
+
+ ```json
+ {
+ "dns": {}
+ }
+ ```
+
+### Migrate store_rdrc
+
+`store_rdrc` is deprecated and can be replaced by `store_dns`,
+which persists the full DNS cache to the cache file.
+
+!!! info "References"
+
+ [Cache File](/configuration/experimental/cache-file/)
+
+=== ":material-card-remove: Deprecated"
+
+ ```json
+ {
+ "experimental": {
+ "cache_file": {
+ "enabled": true,
+ "store_rdrc": true
+ }
+ }
+ }
+ ```
+
+=== ":material-card-multiple: New"
+
+ ```json
+ {
+ "experimental": {
+ "cache_file": {
+ "enabled": true,
+ "store_dns": true
+ }
+ }
+ }
+ ```
+
+### ip_version and query_type behavior changes in DNS rules
+
+In sing-box 1.14.0, the behavior of
+[`ip_version`](/configuration/dns/rule/#ip_version) and
+[`query_type`](/configuration/dns/rule/#query_type) in DNS rules, together with
+[`query_type`](/configuration/rule-set/headless-rule/#query_type) in referenced
+rule-sets, changes in two ways.
+
+First, these fields now take effect on every DNS rule evaluation. In earlier
+versions they were evaluated only for DNS queries received from a client
+(for example, from a DNS inbound or intercepted by `tun`), and were silently
+ignored when a DNS rule was matched from an internal domain resolution that
+did not target a specific DNS server. Such internal resolutions include:
+
+- The [`resolve`](/configuration/route/rule_action/#resolve) route rule
+ action without a `server` set.
+- ICMP traffic routed to a domain destination through a `direct` outbound.
+- A [WireGuard](/configuration/endpoint/wireguard/) or
+ [Tailscale](/configuration/endpoint/tailscale/) endpoint used as an
+ outbound, when resolving its own destination address.
+- A [SOCKS4](/configuration/outbound/socks/) outbound, which must resolve
+ the destination locally because the protocol has no in-protocol domain
+ support.
+- The [DERP](/configuration/service/derp/) `bootstrap-dns` endpoint and the
+ [`resolved`](/configuration/service/resolved/) service (when resolving a
+ hostname or an SRV target).
+
+Resolutions that target a specific DNS server — via
+[`domain_resolver`](/configuration/shared/dial/#domain_resolver) on a dial
+field, [`default_domain_resolver`](/configuration/route/#default_domain_resolver)
+in route options, or an explicit `server` on a DNS rule action or the
+`resolve` route rule action — do not go through DNS rule matching and are
+unaffected.
+
+Second, setting `ip_version` or `query_type` in a DNS rule, or referencing a
+rule-set containing `query_type`, is no longer compatible in the same DNS
+configuration with Legacy Address Filter Fields in DNS rules, the Legacy
+`strategy` DNS rule action option, or the Legacy `rule_set_ip_cidr_accept_empty`
+DNS rule item. Such a configuration will be rejected at startup. To combine
+these fields with address-based filtering, migrate to response matching via
+the [`evaluate`](/configuration/dns/rule_action/#evaluate) action and
+[`match_response`](/configuration/dns/rule/#match_response), see
+[Migrate address filter fields to response matching](#migrate-address-filter-fields-to-response-matching).
+
+!!! info "References"
+
+ [DNS Rule](/configuration/dns/rule/) /
+ [Headless Rule](/configuration/rule-set/headless-rule/) /
+ [Route Rule Action](/configuration/route/rule_action/#resolve)
+
## 1.12.0
### Migrate to new DNS server formats
diff --git a/docs/migration.zh.md b/docs/migration.zh.md
index c08be78f5c..4d003e1ecd 100644
--- a/docs/migration.zh.md
+++ b/docs/migration.zh.md
@@ -2,6 +2,246 @@
icon: material/arrange-bring-forward
---
+## 1.14.0
+
+### 迁移内联 ACME 到证书提供者
+
+TLS 中的内联 ACME 选项已废弃,且可以被证书提供者替代。
+
+`tls.acme` 的大多数字段都可以原样迁移到 ACME 证书提供者中。
+sing-box 1.14.0 新增字段参阅 [ACME](/zh/configuration/shared/certificate-provider/acme/) 页面。
+
+!!! info "参考"
+
+ [TLS](/zh/configuration/shared/tls/#certificate_provider) /
+ [证书提供者](/zh/configuration/shared/certificate-provider/)
+
+=== ":material-card-remove: 弃用的"
+
+ ```json
+ {
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "acme": {
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ }
+ }
+ ]
+ }
+ ```
+
+=== ":material-card-multiple: 内联"
+
+ ```json
+ {
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "certificate_provider": {
+ "type": "acme",
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ }
+ }
+ ]
+ }
+ ```
+
+=== ":material-card-multiple: 共享"
+
+ ```json
+ {
+ "certificate_providers": [
+ {
+ "type": "acme",
+ "tag": "my-cert",
+ "domain": ["example.com"],
+ "email": "admin@example.com"
+ }
+ ],
+ "inbounds": [
+ {
+ "type": "trojan",
+ "tls": {
+ "enabled": true,
+ "certificate_provider": "my-cert"
+ }
+ }
+ ]
+ }
+ ```
+
+### 迁移地址筛选字段到响应匹配
+
+旧版地址筛选字段(不使用 `match_response` 的 `ip_cidr`、`ip_is_private`)已废弃,
+旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项也已废弃。当旧版 DNS 模式被禁用时,
+引用仅包含 `ip_cidr` 项的规则集(例如 GeoIP 规则集)且未设置 `match_response` 的 DNS 规则
+也将在启动时被拒绝。
+
+在 sing-box 1.14.0 中,请使用 [`evaluate`](/zh/configuration/dns/rule_action/#evaluate) 动作
+获取 DNS 响应,然后通过 `match_response` 显式匹配。
+
+!!! info "参考"
+
+ [DNS 规则](/zh/configuration/dns/rule/) /
+ [DNS 规则动作](/zh/configuration/dns/rule_action/#evaluate)
+
+=== ":material-card-remove: 弃用的"
+
+ ```json
+ {
+ "dns": {
+ "rules": [
+ {
+ "rule_set": "geoip-cn",
+ "action": "route",
+ "server": "local"
+ },
+ {
+ "action": "route",
+ "server": "remote"
+ }
+ ]
+ }
+ }
+ ```
+
+=== ":material-card-multiple: 新的"
+
+ ```json
+ {
+ "dns": {
+ "rules": [
+ {
+ "action": "evaluate",
+ "server": "remote"
+ },
+ {
+ "match_response": true,
+ "rule_set": "geoip-cn",
+ "action": "route",
+ "server": "local"
+ },
+ {
+ "action": "route",
+ "server": "remote"
+ }
+ ]
+ }
+ }
+ ```
+
+### 迁移 independent DNS cache
+
+DNS 缓存现在始终按传输名称分离,使 `independent_cache` 不再需要。
+直接移除该字段即可。
+
+!!! info "参考"
+
+ [DNS](/zh/configuration/dns/)
+
+=== ":material-card-remove: 弃用的"
+
+ ```json
+ {
+ "dns": {
+ "independent_cache": true
+ }
+ }
+ ```
+
+=== ":material-card-multiple: 新的"
+
+ ```json
+ {
+ "dns": {}
+ }
+ ```
+
+### 迁移 store_rdrc
+
+`store_rdrc` 已废弃,且可以被 `store_dns` 替代,
+后者将完整的 DNS 缓存持久化到缓存文件中。
+
+!!! info "参考"
+
+ [缓存文件](/zh/configuration/experimental/cache-file/)
+
+=== ":material-card-remove: 弃用的"
+
+ ```json
+ {
+ "experimental": {
+ "cache_file": {
+ "enabled": true,
+ "store_rdrc": true
+ }
+ }
+ }
+ ```
+
+=== ":material-card-multiple: 新的"
+
+ ```json
+ {
+ "experimental": {
+ "cache_file": {
+ "enabled": true,
+ "store_dns": true
+ }
+ }
+ }
+ ```
+
+### DNS 规则中的 ip_version 和 query_type 行为更改
+
+在 sing-box 1.14.0 中,DNS 规则中的
+[`ip_version`](/zh/configuration/dns/rule/#ip_version) 和
+[`query_type`](/zh/configuration/dns/rule/#query_type),以及被引用规则集中的
+[`query_type`](/zh/configuration/rule-set/headless-rule/#query_type),
+行为有两项更改。
+
+其一,这些字段现在对每一次 DNS 规则评估都会生效。此前它们仅对来自客户端的 DNS 查询
+(例如来自 DNS 入站或被 `tun` 截获的查询)生效,当 DNS 规则被未指定具体 DNS 服务器的
+内部域名解析匹配时,会被静默忽略。此类内部解析包括:
+
+- 未设置 `server` 的 [`resolve`](/zh/configuration/route/rule_action/#resolve) 路由规则动作。
+- 通过 `direct` 出站路由到域名目标的 ICMP 流量。
+- 作为出站使用的 [WireGuard](/zh/configuration/endpoint/wireguard/) 或
+ [Tailscale](/zh/configuration/endpoint/tailscale/) 端点在解析自身目标地址时。
+- [SOCKS4](/zh/configuration/outbound/socks/) 出站,因为协议本身不支持域名,
+ 必须在本地解析目标。
+- [DERP](/zh/configuration/service/derp/) 的 `bootstrap-dns` 端点,以及
+ [`resolved`](/zh/configuration/service/resolved/) 服务在解析主机名或 SRV 目标时。
+
+通过拨号字段中的
+[`domain_resolver`](/zh/configuration/shared/dial/#domain_resolver)、
+路由选项中的 [`default_domain_resolver`](/zh/configuration/route/#default_domain_resolver),
+或 DNS 规则动作与 `resolve` 路由规则动作上显式的 `server` 指定具体 DNS 服务器的
+解析,不会经过 DNS 规则匹配,不受此次更改影响。
+
+其二,设置了 `ip_version` 或 `query_type` 的 DNS 规则,或引用了包含 `query_type` 的
+规则集的 DNS 规则,在同一 DNS 配置中不再能与旧版地址筛选字段 (DNS 规则)、旧版
+DNS 规则动作 `strategy` 选项,或旧版 `rule_set_ip_cidr_accept_empty` DNS 规则项共存。
+此类配置将在启动时被拒绝。如需将这些字段与基于地址的筛选组合,请通过
+[`evaluate`](/zh/configuration/dns/rule_action/#evaluate) 动作和
+[`match_response`](/zh/configuration/dns/rule/#match_response) 迁移到响应匹配,
+参阅 [迁移地址筛选字段到响应匹配](#迁移地址筛选字段到响应匹配)。
+
+!!! info "参考"
+
+ [DNS 规则](/zh/configuration/dns/rule/) /
+ [Headless 规则](/zh/configuration/rule-set/headless-rule/) /
+ [路由规则动作](/zh/configuration/route/rule_action/#resolve)
+
## 1.12.0
### 迁移到新的 DNS 服务器格式
diff --git a/examples/check.sh b/examples/check.sh
new file mode 100644
index 0000000000..a9bec06eb7
--- /dev/null
+++ b/examples/check.sh
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+set -uo pipefail
+
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+cd "$ROOT"
+
+BIN="$ROOT/sing-box"
+
+make
+
+passed=0
+failed=0
+skipped=0
+
+skip_mkcp() {
+ [[ "$1" == *"/mkcp/"* ]]
+}
+
+while IFS= read -r f; do
+ rel="${f#./}"
+ if skip_mkcp "$rel"; then
+ echo "SKIP $rel (mkcp transport not in this fork yet)"
+ skipped=$((skipped + 1))
+ continue
+ fi
+ if "$BIN" check -c "$f" >/dev/null 2>&1; then
+ echo "PASS $rel"
+ passed=$((passed + 1))
+ else
+ echo "FAIL $rel"
+ "$BIN" check -c "$f" 2>&1 | sed 's/^/ /'
+ failed=$((failed + 1))
+ fi
+done < <(find examples -name '*.json' | sort)
+
+echo "---"
+echo "Passed: $passed Failed: $failed Skipped: $skipped"
+exit "$failed"
diff --git a/experimental/cachefile/cache.go b/experimental/cachefile/cache.go
index e52dd3ed23..567ba02640 100644
--- a/experimental/cachefile/cache.go
+++ b/experimental/cachefile/cache.go
@@ -12,9 +12,11 @@ import (
"github.com/sagernet/bbolt"
bboltErrors "github.com/sagernet/bbolt/errors"
"github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
"github.com/sagernet/sing/service/filemanager"
)
@@ -30,6 +32,7 @@ var (
string(bucketMode),
string(bucketRuleSet),
string(bucketRDRC),
+ string(bucketDNSCache),
}
cacheIDDefault = []byte("default")
@@ -38,30 +41,45 @@ var (
var _ adapter.CacheFile = (*CacheFile)(nil)
type CacheFile struct {
- ctx context.Context
- path string
- cacheID []byte
- storeFakeIP bool
- storeRDRC bool
- rdrcTimeout time.Duration
- DB *bbolt.DB
- resetAccess sync.Mutex
- saveMetadataTimer *time.Timer
- saveFakeIPAccess sync.RWMutex
- saveDomain map[netip.Addr]string
- saveAddress4 map[string]netip.Addr
- saveAddress6 map[string]netip.Addr
- saveRDRCAccess sync.RWMutex
- saveRDRC map[saveRDRCCacheKey]bool
+ ctx context.Context
+ logger logger.Logger
+ path string
+ cacheID []byte
+ storeFakeIP bool
+ storeRDRC bool
+ storeWARPConfig bool
+ storeMASQUEConfig bool
+ storeDNS bool
+ disableExpire bool
+ rdrcTimeout time.Duration
+ optimisticTimeout time.Duration
+ DB *bbolt.DB
+ resetAccess sync.Mutex
+ saveMetadataTimer *time.Timer
+ saveFakeIPAccess sync.RWMutex
+ saveDomain map[netip.Addr]string
+ saveAddress4 map[string]netip.Addr
+ saveAddress6 map[string]netip.Addr
+ saveRDRCAccess sync.RWMutex
+ saveRDRC map[saveCacheKey]bool
+ saveDNSCacheAccess sync.RWMutex
+ saveDNSCache map[saveCacheKey]saveDNSCacheEntry
}
-type saveRDRCCacheKey struct {
+type saveCacheKey struct {
TransportName string
QuestionName string
QType uint16
}
-func New(ctx context.Context, options option.CacheFileOptions) *CacheFile {
+type saveDNSCacheEntry struct {
+ rawMessage []byte
+ expireAt time.Time
+ sequence uint64
+ saving bool
+}
+
+func New(ctx context.Context, logger logger.Logger, options option.CacheFileOptions) *CacheFile {
var path string
if options.Path != "" {
path = options.Path
@@ -72,6 +90,9 @@ func New(ctx context.Context, options option.CacheFileOptions) *CacheFile {
if options.CacheID != "" {
cacheIDBytes = append([]byte{0}, []byte(options.CacheID)...)
}
+ if options.StoreRDRC {
+ deprecated.Report(ctx, deprecated.OptionStoreRDRC)
+ }
var rdrcTimeout time.Duration
if options.StoreRDRC {
if options.RDRCTimeout > 0 {
@@ -82,15 +103,20 @@ func New(ctx context.Context, options option.CacheFileOptions) *CacheFile {
}
return &CacheFile{
ctx: ctx,
+ logger: logger,
path: filemanager.BasePath(ctx, path),
cacheID: cacheIDBytes,
- storeFakeIP: options.StoreFakeIP,
- storeRDRC: options.StoreRDRC,
+ storeFakeIP: options.StoreFakeIP,
+ storeRDRC: options.StoreRDRC,
+ storeWARPConfig: options.StoreWARPConfig,
+ storeMASQUEConfig: options.StoreMASQUEConfig,
+ storeDNS: options.StoreDNS,
rdrcTimeout: rdrcTimeout,
saveDomain: make(map[netip.Addr]string),
saveAddress4: make(map[string]netip.Addr),
saveAddress6: make(map[string]netip.Addr),
- saveRDRC: make(map[saveRDRCCacheKey]bool),
+ saveRDRC: make(map[saveCacheKey]bool),
+ saveDNSCache: make(map[saveCacheKey]saveDNSCacheEntry),
}
}
@@ -102,10 +128,44 @@ func (c *CacheFile) Dependencies() []string {
return nil
}
+func (c *CacheFile) SetOptimisticTimeout(timeout time.Duration) {
+ c.optimisticTimeout = timeout
+}
+
+func (c *CacheFile) SetDisableExpire(disableExpire bool) {
+ c.disableExpire = disableExpire
+}
+
func (c *CacheFile) Start(stage adapter.StartStage) error {
- if stage != adapter.StartStateInitialize {
- return nil
+ switch stage {
+ case adapter.StartStateInitialize:
+ return c.start()
+ case adapter.StartStateStart:
+ c.startCacheCleanup()
}
+ return nil
+}
+
+func (c *CacheFile) startCacheCleanup() {
+ if c.storeDNS {
+ c.clearRDRC()
+ c.cleanupDNSCache()
+ interval := c.optimisticTimeout / 2
+ if interval <= 0 {
+ interval = time.Hour
+ }
+ go c.loopCacheCleanup(interval, c.cleanupDNSCache)
+ } else if c.storeRDRC {
+ c.cleanupRDRC()
+ interval := c.rdrcTimeout / 2
+ if interval <= 0 {
+ interval = time.Hour
+ }
+ go c.loopCacheCleanup(interval, c.cleanupRDRC)
+ }
+}
+
+func (c *CacheFile) start() error {
const fileMode = 0o666
options := bbolt.Options{Timeout: time.Second}
var (
@@ -359,3 +419,19 @@ func (c *CacheFile) SaveRuleSet(tag string, set *adapter.SavedBinary) error {
return bucket.Put([]byte(tag), setBinary)
})
}
+
+func (c *CacheFile) StoreWARPConfig() bool {
+ return c.storeWARPConfig
+}
+
+func (c *CacheFile) StoreMASQUEConfig() bool {
+ return c.storeMASQUEConfig
+}
+
+func (c *CacheFile) LoadBinary(tag string) *adapter.SavedBinary {
+ return c.LoadRuleSet(tag)
+}
+
+func (c *CacheFile) SaveBinary(tag string, set *adapter.SavedBinary) error {
+ return c.SaveRuleSet(tag, set)
+}
diff --git a/experimental/cachefile/dns_cache.go b/experimental/cachefile/dns_cache.go
new file mode 100644
index 0000000000..55718c59a1
--- /dev/null
+++ b/experimental/cachefile/dns_cache.go
@@ -0,0 +1,299 @@
+package cachefile
+
+import (
+ "encoding/binary"
+ "time"
+
+ "github.com/sagernet/bbolt"
+ "github.com/sagernet/sing/common/buf"
+ "github.com/sagernet/sing/common/logger"
+)
+
+var bucketDNSCache = []byte("dns_cache")
+
+func (c *CacheFile) StoreDNS() bool {
+ return c.storeDNS
+}
+
+func (c *CacheFile) LoadDNSCache(transportName string, qName string, qType uint16) (rawMessage []byte, expireAt time.Time, loaded bool) {
+ c.saveDNSCacheAccess.RLock()
+ entry, cached := c.saveDNSCache[saveCacheKey{transportName, qName, qType}]
+ c.saveDNSCacheAccess.RUnlock()
+ if cached {
+ return entry.rawMessage, entry.expireAt, true
+ }
+ key := buf.Get(2 + len(qName))
+ binary.BigEndian.PutUint16(key, qType)
+ copy(key[2:], qName)
+ defer buf.Put(key)
+ err := c.view(func(tx *bbolt.Tx) error {
+ bucket := c.bucket(tx, bucketDNSCache)
+ if bucket == nil {
+ return nil
+ }
+ bucket = bucket.Bucket([]byte(transportName))
+ if bucket == nil {
+ return nil
+ }
+ content := bucket.Get(key)
+ if len(content) < 8 {
+ return nil
+ }
+ expireAt = time.Unix(int64(binary.BigEndian.Uint64(content[:8])), 0)
+ rawMessage = make([]byte, len(content)-8)
+ copy(rawMessage, content[8:])
+ loaded = true
+ return nil
+ })
+ if err != nil {
+ return nil, time.Time{}, false
+ }
+ return
+}
+
+func (c *CacheFile) SaveDNSCache(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time) error {
+ value := buf.Get(8 + len(rawMessage))
+ defer buf.Put(value)
+ binary.BigEndian.PutUint64(value[:8], uint64(expireAt.Unix()))
+ copy(value[8:], rawMessage)
+ return c.batch(func(tx *bbolt.Tx) error {
+ bucket, err := c.createBucket(tx, bucketDNSCache)
+ if err != nil {
+ return err
+ }
+ bucket, err = bucket.CreateBucketIfNotExists([]byte(transportName))
+ if err != nil {
+ return err
+ }
+ key := buf.Get(2 + len(qName))
+ binary.BigEndian.PutUint16(key, qType)
+ copy(key[2:], qName)
+ defer buf.Put(key)
+ return bucket.Put(key, value)
+ })
+}
+
+func (c *CacheFile) SaveDNSCacheAsync(transportName string, qName string, qType uint16, rawMessage []byte, expireAt time.Time, logger logger.Logger) {
+ saveKey := saveCacheKey{transportName, qName, qType}
+ if !c.queueDNSCacheSave(saveKey, rawMessage, expireAt) {
+ return
+ }
+ go c.flushPendingDNSCache(saveKey, logger)
+}
+
+func (c *CacheFile) queueDNSCacheSave(saveKey saveCacheKey, rawMessage []byte, expireAt time.Time) bool {
+ c.saveDNSCacheAccess.Lock()
+ defer c.saveDNSCacheAccess.Unlock()
+ entry := c.saveDNSCache[saveKey]
+ entry.rawMessage = append([]byte(nil), rawMessage...)
+ entry.expireAt = expireAt
+ entry.sequence++
+ startFlush := !entry.saving
+ entry.saving = true
+ c.saveDNSCache[saveKey] = entry
+ return startFlush
+}
+
+func (c *CacheFile) flushPendingDNSCache(saveKey saveCacheKey, logger logger.Logger) {
+ c.flushPendingDNSCacheWith(saveKey, logger, func(entry saveDNSCacheEntry) error {
+ return c.SaveDNSCache(saveKey.TransportName, saveKey.QuestionName, saveKey.QType, entry.rawMessage, entry.expireAt)
+ })
+}
+
+func (c *CacheFile) flushPendingDNSCacheWith(saveKey saveCacheKey, logger logger.Logger, save func(saveDNSCacheEntry) error) {
+ for {
+ c.saveDNSCacheAccess.RLock()
+ entry, loaded := c.saveDNSCache[saveKey]
+ c.saveDNSCacheAccess.RUnlock()
+ if !loaded {
+ return
+ }
+ err := save(entry)
+ if err != nil {
+ logger.Warn("save DNS cache: ", err)
+ }
+ c.saveDNSCacheAccess.Lock()
+ currentEntry, loaded := c.saveDNSCache[saveKey]
+ if !loaded {
+ c.saveDNSCacheAccess.Unlock()
+ return
+ }
+ if currentEntry.sequence != entry.sequence {
+ c.saveDNSCacheAccess.Unlock()
+ continue
+ }
+ delete(c.saveDNSCache, saveKey)
+ c.saveDNSCacheAccess.Unlock()
+ return
+ }
+}
+
+func (c *CacheFile) ClearDNSCache() error {
+ c.saveDNSCacheAccess.Lock()
+ clear(c.saveDNSCache)
+ c.saveDNSCacheAccess.Unlock()
+ return c.batch(func(tx *bbolt.Tx) error {
+ if c.cacheID == nil {
+ bucket := tx.Bucket(bucketDNSCache)
+ if bucket == nil {
+ return nil
+ }
+ return tx.DeleteBucket(bucketDNSCache)
+ }
+ bucket := tx.Bucket(c.cacheID)
+ if bucket == nil || bucket.Bucket(bucketDNSCache) == nil {
+ return nil
+ }
+ return bucket.DeleteBucket(bucketDNSCache)
+ })
+}
+
+func (c *CacheFile) loopCacheCleanup(interval time.Duration, cleanupFunc func()) {
+ ticker := time.NewTicker(interval)
+ defer ticker.Stop()
+ for {
+ select {
+ case <-c.ctx.Done():
+ return
+ case <-ticker.C:
+ cleanupFunc()
+ }
+ }
+}
+
+func (c *CacheFile) cleanupDNSCache() {
+ now := time.Now()
+ err := c.batch(func(tx *bbolt.Tx) error {
+ bucket := c.bucket(tx, bucketDNSCache)
+ if bucket == nil {
+ return nil
+ }
+ var emptyTransports [][]byte
+ err := bucket.ForEachBucket(func(transportName []byte) error {
+ transportBucket := bucket.Bucket(transportName)
+ if transportBucket == nil {
+ return nil
+ }
+ var expiredKeys [][]byte
+ err := transportBucket.ForEach(func(key, value []byte) error {
+ if len(value) < 8 {
+ expiredKeys = append(expiredKeys, append([]byte(nil), key...))
+ return nil
+ }
+ if c.disableExpire {
+ return nil
+ }
+ expireAt := time.Unix(int64(binary.BigEndian.Uint64(value[:8])), 0)
+ if now.After(expireAt.Add(c.optimisticTimeout)) {
+ expiredKeys = append(expiredKeys, append([]byte(nil), key...))
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ for _, key := range expiredKeys {
+ err = transportBucket.Delete(key)
+ if err != nil {
+ return err
+ }
+ }
+ first, _ := transportBucket.Cursor().First()
+ if first == nil {
+ emptyTransports = append(emptyTransports, append([]byte(nil), transportName...))
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ for _, name := range emptyTransports {
+ err = bucket.DeleteBucket(name)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ c.logger.Warn("cleanup DNS cache: ", err)
+ }
+}
+
+func (c *CacheFile) clearRDRC() {
+ c.saveRDRCAccess.Lock()
+ clear(c.saveRDRC)
+ c.saveRDRCAccess.Unlock()
+ err := c.batch(func(tx *bbolt.Tx) error {
+ if c.cacheID == nil {
+ if tx.Bucket(bucketRDRC) == nil {
+ return nil
+ }
+ return tx.DeleteBucket(bucketRDRC)
+ }
+ bucket := tx.Bucket(c.cacheID)
+ if bucket == nil || bucket.Bucket(bucketRDRC) == nil {
+ return nil
+ }
+ return bucket.DeleteBucket(bucketRDRC)
+ })
+ if err != nil {
+ c.logger.Warn("clear RDRC: ", err)
+ }
+}
+
+func (c *CacheFile) cleanupRDRC() {
+ now := time.Now()
+ err := c.batch(func(tx *bbolt.Tx) error {
+ bucket := c.bucket(tx, bucketRDRC)
+ if bucket == nil {
+ return nil
+ }
+ var emptyTransports [][]byte
+ err := bucket.ForEachBucket(func(transportName []byte) error {
+ transportBucket := bucket.Bucket(transportName)
+ if transportBucket == nil {
+ return nil
+ }
+ var expiredKeys [][]byte
+ err := transportBucket.ForEach(func(key, value []byte) error {
+ if len(value) < 8 {
+ expiredKeys = append(expiredKeys, append([]byte(nil), key...))
+ return nil
+ }
+ expiresAt := time.Unix(int64(binary.BigEndian.Uint64(value)), 0)
+ if now.After(expiresAt) {
+ expiredKeys = append(expiredKeys, append([]byte(nil), key...))
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ for _, key := range expiredKeys {
+ err = transportBucket.Delete(key)
+ if err != nil {
+ return err
+ }
+ }
+ first, _ := transportBucket.Cursor().First()
+ if first == nil {
+ emptyTransports = append(emptyTransports, append([]byte(nil), transportName...))
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ for _, name := range emptyTransports {
+ err = bucket.DeleteBucket(name)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ c.logger.Warn("cleanup RDRC: ", err)
+ }
+}
diff --git a/experimental/cachefile/fakeip.go b/experimental/cachefile/fakeip.go
index 7a4bd384f1..8fe0f1139c 100644
--- a/experimental/cachefile/fakeip.go
+++ b/experimental/cachefile/fakeip.go
@@ -23,7 +23,7 @@ var (
func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
var metadata adapter.FakeIPMetadata
- err := c.batch(func(tx *bbolt.Tx) error {
+ err := c.DB.Batch(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP)
if bucket == nil {
return os.ErrNotExist
@@ -45,7 +45,7 @@ func (c *CacheFile) FakeIPMetadata() *adapter.FakeIPMetadata {
}
func (c *CacheFile) FakeIPSaveMetadata(metadata *adapter.FakeIPMetadata) error {
- return c.batch(func(tx *bbolt.Tx) error {
+ return c.DB.Batch(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists(bucketFakeIP)
if err != nil {
return err
@@ -69,7 +69,7 @@ func (c *CacheFile) FakeIPSaveMetadataAsync(metadata *adapter.FakeIPMetadata) {
}
func (c *CacheFile) FakeIPStore(address netip.Addr, domain string) error {
- return c.batch(func(tx *bbolt.Tx) error {
+ return c.DB.Batch(func(tx *bbolt.Tx) error {
bucket, err := tx.CreateBucketIfNotExists(bucketFakeIP)
if err != nil {
return err
@@ -136,7 +136,7 @@ func (c *CacheFile) FakeIPLoad(address netip.Addr) (string, bool) {
return cachedDomain, true
}
var domain string
- _ = c.view(func(tx *bbolt.Tx) error {
+ _ = c.DB.View(func(tx *bbolt.Tx) error {
bucket := tx.Bucket(bucketFakeIP)
if bucket == nil {
return nil
@@ -163,7 +163,7 @@ func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bo
return cachedAddress, true
}
var address netip.Addr
- _ = c.view(func(tx *bbolt.Tx) error {
+ _ = c.DB.View(func(tx *bbolt.Tx) error {
var bucket *bbolt.Bucket
if isIPv6 {
bucket = tx.Bucket(bucketFakeIPDomain6)
@@ -180,7 +180,7 @@ func (c *CacheFile) FakeIPLoadDomain(domain string, isIPv6 bool) (netip.Addr, bo
}
func (c *CacheFile) FakeIPReset() error {
- return c.batch(func(tx *bbolt.Tx) error {
+ return c.DB.Batch(func(tx *bbolt.Tx) error {
err := tx.DeleteBucket(bucketFakeIP)
if err != nil {
return err
diff --git a/experimental/cachefile/rdrc.go b/experimental/cachefile/rdrc.go
index dde324c3c9..c02259c389 100644
--- a/experimental/cachefile/rdrc.go
+++ b/experimental/cachefile/rdrc.go
@@ -21,7 +21,7 @@ func (c *CacheFile) RDRCTimeout() time.Duration {
func (c *CacheFile) LoadRDRC(transportName string, qName string, qType uint16) (rejected bool) {
c.saveRDRCAccess.RLock()
- rejected, cached := c.saveRDRC[saveRDRCCacheKey{transportName, qName, qType}]
+ rejected, cached := c.saveRDRC[saveCacheKey{transportName, qName, qType}]
c.saveRDRCAccess.RUnlock()
if cached {
return
@@ -93,7 +93,7 @@ func (c *CacheFile) SaveRDRC(transportName string, qName string, qType uint16) e
}
func (c *CacheFile) SaveRDRCAsync(transportName string, qName string, qType uint16, logger logger.Logger) {
- saveKey := saveRDRCCacheKey{transportName, qName, qType}
+ saveKey := saveCacheKey{transportName, qName, qType}
c.saveRDRCAccess.Lock()
c.saveRDRC[saveKey] = true
c.saveRDRCAccess.Unlock()
diff --git a/experimental/clashapi/api_meta_group.go b/experimental/clashapi/api_meta_group.go
index 31dbdaf692..5f75ee0e32 100644
--- a/experimental/clashapi/api_meta_group.go
+++ b/experimental/clashapi/api_meta_group.go
@@ -84,6 +84,8 @@ func getGroupDelay(server *Server) func(w http.ResponseWriter, r *http.Request)
var result map[string]uint16
if urlTestGroup, isURLTestGroup := outboundGroup.(adapter.URLTestGroup); isURLTestGroup {
result, err = urlTestGroup.URLTest(ctx)
+ // } else if outboundGroup.Type() == C.TypeBalancer {
+ // result, err = monitoring.Balancer.URLTest(ctx)
} else {
outbounds := common.FilterNotNil(common.Map(outboundGroup.All(), func(it string) adapter.Outbound {
itOutbound, _ := server.outbound.Outbound(it)
diff --git a/experimental/clashapi/connections.go b/experimental/clashapi/connections.go
index 14274b311b..e60e6622f5 100644
--- a/experimental/clashapi/connections.go
+++ b/experimental/clashapi/connections.go
@@ -18,10 +18,10 @@ import (
"github.com/gofrs/uuid/v5"
)
-func connectionRouter(ctx context.Context, router adapter.Router, trafficManager *trafficontrol.Manager) http.Handler {
+func connectionRouter(ctx context.Context, network adapter.NetworkManager, trafficManager *trafficontrol.Manager) http.Handler {
r := chi.NewRouter()
r.Get("/", getConnections(ctx, trafficManager))
- r.Delete("/", closeAllConnections(router, trafficManager))
+ r.Delete("/", closeAllConnections(network, trafficManager))
r.Delete("/{id}", closeConnection(trafficManager))
return r
}
@@ -96,13 +96,13 @@ func closeConnection(trafficManager *trafficontrol.Manager) func(w http.Response
}
}
-func closeAllConnections(router adapter.Router, trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r *http.Request) {
+func closeAllConnections(network adapter.NetworkManager, trafficManager *trafficontrol.Manager) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
snapshot := trafficManager.Snapshot()
for _, c := range snapshot.Connections {
c.Close()
}
- router.ResetNetwork()
+ network.ResetNetwork()
render.NoContent(w, r)
}
}
diff --git a/experimental/clashapi/server.go b/experimental/clashapi/server.go
index 950dca0408..a41adcdf96 100644
--- a/experimental/clashapi/server.go
+++ b/experimental/clashapi/server.go
@@ -21,6 +21,7 @@ import (
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/cleanup"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
N "github.com/sagernet/sing/common/network"
@@ -42,6 +43,7 @@ var _ adapter.ClashServer = (*Server)(nil)
type Server struct {
ctx context.Context
+ network adapter.NetworkManager
router adapter.Router
dnsRouter adapter.DNSRouter
outbound adapter.OutboundManager
@@ -51,6 +53,7 @@ type Server struct {
trafficManager *trafficontrol.Manager
urlTestHistory adapter.URLTestHistoryStorage
logDebug bool
+ cleaner *cleanup.Cleaner
mode string
modeList []string
@@ -67,6 +70,7 @@ func NewServer(ctx context.Context, logFactory log.ObservableFactory, options op
chiRouter := chi.NewRouter()
s := &Server{
ctx: ctx,
+ network: service.FromContext[adapter.NetworkManager](ctx),
router: service.FromContext[adapter.Router](ctx),
dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
outbound: service.FromContext[adapter.OutboundManager](ctx),
@@ -82,6 +86,7 @@ func NewServer(ctx context.Context, logFactory log.ObservableFactory, options op
externalController: options.ExternalController != "",
externalUIDownloadURL: options.ExternalUIDownloadURL,
externalUIDownloadDetour: options.ExternalUIDownloadDetour,
+ cleaner: cleanup.Add(trafficManager.Clear),
}
s.urlTestHistory = service.FromContext[adapter.URLTestHistoryStorage](ctx)
if s.urlTestHistory == nil {
@@ -121,7 +126,7 @@ func NewServer(ctx context.Context, logFactory log.ObservableFactory, options op
r.Mount("/configs", configRouter(s, logFactory))
r.Mount("/proxies", proxyRouter(s, s.router))
r.Mount("/rules", ruleRouter(s.router))
- r.Mount("/connections", connectionRouter(s.ctx, s.router, trafficManager))
+ r.Mount("/connections", connectionRouter(s.ctx, s.network, trafficManager))
r.Mount("/providers/proxies", proxyProviderRouter())
r.Mount("/providers/rules", ruleProviderRouter())
r.Mount("/script", scriptRouter())
@@ -193,6 +198,7 @@ func (s *Server) Close() error {
common.PtrOrNil(s.httpServer),
s.trafficManager,
s.urlTestHistory,
+ common.PtrOrNil(s.cleaner),
)
}
diff --git a/experimental/clashapi/trafficontrol/manager.go b/experimental/clashapi/trafficontrol/manager.go
index 6763436d84..407ab37d26 100644
--- a/experimental/clashapi/trafficontrol/manager.go
+++ b/experimental/clashapi/trafficontrol/manager.go
@@ -36,9 +36,10 @@ type ConnectionEvent struct {
const closedConnectionsLimit = 1000
type Manager struct {
- uploadTotal atomic.Int64
- downloadTotal atomic.Int64
-
+ uploadTotal atomic.Int64
+ downloadTotal atomic.Int64
+ outboundUploadTotal sync.Map
+ outboundDownloadTotal sync.Map
connections compatible.Map[uuid.UUID, Tracker]
closedConnectionsAccess sync.Mutex
closedConnections list.List[TrackerMetadata]
@@ -99,10 +100,30 @@ func (m *Manager) PushDownloaded(size int64) {
m.downloadTotal.Add(size)
}
+func (m *Manager) PushOutboundUploaded(outbound string, size int64) {
+ v, _ := m.outboundUploadTotal.LoadOrStore(outbound, &atomic.Int64{})
+ v.(*atomic.Int64).Add(size)
+}
+
+func (m *Manager) PushOutboundDownloaded(outbound string, size int64) {
+ v, _ := m.outboundDownloadTotal.LoadOrStore(outbound, &atomic.Int64{})
+ v.(*atomic.Int64).Add(size)
+}
+
func (m *Manager) Total() (up int64, down int64) {
return m.uploadTotal.Load(), m.downloadTotal.Load()
}
+func (m *Manager) OutboundUsage(outbound string) (up int64, down int64) {
+ if vUp, ok := m.outboundUploadTotal.Load(outbound); ok {
+ up = vUp.(*atomic.Int64).Load()
+ }
+ if vDown, ok := m.outboundDownloadTotal.Load(outbound); ok {
+ down = vDown.(*atomic.Int64).Load()
+ }
+ return
+}
+
func (m *Manager) ConnectionsLen() int {
return m.connections.Len()
}
@@ -162,6 +183,20 @@ func (m *Manager) Snapshot() *Snapshot {
func (m *Manager) ResetStatistic() {
m.uploadTotal.Store(0)
m.downloadTotal.Store(0)
+ m.outboundUploadTotal.Range(func(key, value any) bool {
+ m.outboundUploadTotal.Delete(key)
+ return true
+ })
+ m.outboundDownloadTotal.Range(func(key, value any) bool {
+ m.outboundDownloadTotal.Delete(key)
+ return true
+ })
+}
+
+func (m *Manager) Clear() {
+ m.closedConnectionsAccess.Lock()
+ defer m.closedConnectionsAccess.Unlock()
+ m.closedConnections.Init()
}
type Snapshot struct {
diff --git a/experimental/clashapi/trafficontrol/tracker.go b/experimental/clashapi/trafficontrol/tracker.go
index f001b77b23..be83f4eb8d 100644
--- a/experimental/clashapi/trafficontrol/tracker.go
+++ b/experimental/clashapi/trafficontrol/tracker.go
@@ -5,14 +5,14 @@ import (
"sync/atomic"
"time"
+ "github.com/gofrs/uuid/v5"
"github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/bufio"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json"
N "github.com/sagernet/sing/common/network"
-
- "github.com/gofrs/uuid/v5"
)
type TrackerMetadata struct {
@@ -64,6 +64,12 @@ func (t TrackerMetadata) MarshalJSON() ([]byte, error) {
} else {
rule = "final"
}
+ chains := t.Chain
+ if t.OutboundType == C.TypeBalancer {
+ chains = make([]string, len(t.Chain)+1)
+ chains[0] = t.Metadata.GetRealOutbound()
+ copy(chains[1:], t.Chain)
+ }
return json.Marshal(map[string]any{
"id": t.ID,
"metadata": map[string]any{
@@ -126,11 +132,13 @@ func NewTCPTracker(conn net.Conn, manager *Manager, metadata adapter.InboundCont
outbound string
outboundType string
)
+
if matchOutbound != nil {
next = matchOutbound.Tag()
} else {
next = outboundManager.Default().Tag()
}
+
for {
detour, loaded := outboundManager.Outbound(next)
if !loaded {
@@ -151,9 +159,11 @@ func NewTCPTracker(conn net.Conn, manager *Manager, metadata adapter.InboundCont
ExtendedConn: bufio.NewCounterConn(conn, []N.CountFunc{func(n int64) {
upload.Add(n)
manager.PushUploaded(n)
+ manager.PushOutboundUploaded(outbound, n)
}}, []N.CountFunc{func(n int64) {
download.Add(n)
manager.PushDownloaded(n)
+ manager.PushOutboundDownloaded(outbound, n)
}}),
metadata: TrackerMetadata{
ID: id,
@@ -232,9 +242,11 @@ func NewUDPTracker(conn N.PacketConn, manager *Manager, metadata adapter.Inbound
PacketConn: bufio.NewCounterPacketConn(conn, []N.CountFunc{func(n int64) {
upload.Add(n)
manager.PushUploaded(n)
+ manager.PushOutboundUploaded(outbound, n)
}}, []N.CountFunc{func(n int64) {
download.Add(n)
manager.PushDownloaded(n)
+ manager.PushOutboundDownloaded(outbound, n)
}}),
metadata: TrackerMetadata{
ID: id,
diff --git a/experimental/deprecated/constants.go b/experimental/deprecated/constants.go
index 385105d383..106514caae 100644
--- a/experimental/deprecated/constants.go
+++ b/experimental/deprecated/constants.go
@@ -57,24 +57,6 @@ func (n Note) MessageWithLink() string {
}
}
-var OptionLegacyDNSTransport = Note{
- Name: "legacy-dns-transport",
- Description: "legacy DNS servers",
- DeprecatedVersion: "1.12.0",
- ScheduledVersion: "1.14.0",
- EnvName: "LEGACY_DNS_SERVERS",
- MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats",
-}
-
-var OptionLegacyDNSFakeIPOptions = Note{
- Name: "legacy-dns-fakeip-options",
- Description: "legacy DNS fakeip options",
- DeprecatedVersion: "1.12.0",
- ScheduledVersion: "1.14.0",
- EnvName: "LEGACY_DNS_FAKEIP_OPTIONS",
- MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats",
-}
-
var OptionOutboundDNSRuleItem = Note{
Name: "outbound-dns-rule-item",
Description: "outbound DNS rule item",
@@ -102,10 +84,95 @@ var OptionLegacyDomainStrategyOptions = Note{
MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-domain-strategy-options",
}
+var OptionInlineACME = Note{
+ Name: "inline-acme-options",
+ Description: "inline ACME options in TLS",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "INLINE_ACME_OPTIONS",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-inline-acme-to-certificate-provider",
+}
+
+var OptionLegacyRuleSetDownloadDetour = Note{
+ Name: "legacy-rule-set-download-detour",
+ Description: "legacy `download_detour` remote rule-set option",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "LEGACY_RULE_SET_DOWNLOAD_DETOUR",
+}
+
+var OptionLegacyTailscaleEndpointDialer = Note{
+ Name: "legacy-tailscale-endpoint-dialer",
+ Description: "legacy dialer options in Tailscale endpoint",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "LEGACY_TAILSCALE_ENDPOINT_DIALER",
+}
+
+var OptionRuleSetIPCIDRAcceptEmpty = Note{
+ Name: "dns-rule-rule-set-ip-cidr-accept-empty",
+ Description: "Legacy `rule_set_ip_cidr_accept_empty` DNS rule item",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "DNS_RULE_RULE_SET_IP_CIDR_ACCEPT_EMPTY",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-address-filter-fields-to-response-matching",
+}
+
+var OptionLegacyDNSAddressFilter = Note{
+ Name: "legacy-dns-address-filter",
+ Description: "Legacy Address Filter Fields in DNS rules",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "LEGACY_DNS_ADDRESS_FILTER",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-address-filter-fields-to-response-matching",
+}
+
+var OptionLegacyDNSRuleStrategy = Note{
+ Name: "legacy-dns-rule-strategy",
+ Description: "Legacy `strategy` DNS rule action option",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "LEGACY_DNS_RULE_STRATEGY",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-dns-rule-action-strategy-to-rule-items",
+}
+
+var OptionIndependentDNSCache = Note{
+ Name: "independent-dns-cache",
+ Description: "`independent_cache` DNS option",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "INDEPENDENT_DNS_CACHE",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-independent-dns-cache",
+}
+
+var OptionStoreRDRC = Note{
+ Name: "store-rdrc",
+ Description: "`store_rdrc` cache file option",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "STORE_RDRC",
+ MigrationLink: "https://sing-box.sagernet.org/migration/#migrate-store-rdrc",
+}
+
+var OptionImplicitDefaultHTTPClient = Note{
+ Name: "implicit-default-http-client",
+ Description: "implicit default HTTP client using default outbound for remote rule-sets",
+ DeprecatedVersion: "1.14.0",
+ ScheduledVersion: "1.16.0",
+ EnvName: "IMPLICIT_DEFAULT_HTTP_CLIENT",
+}
+
var Options = []Note{
- OptionLegacyDNSTransport,
- OptionLegacyDNSFakeIPOptions,
OptionOutboundDNSRuleItem,
OptionMissingDomainResolver,
OptionLegacyDomainStrategyOptions,
+ OptionInlineACME,
+ OptionLegacyRuleSetDownloadDetour,
+ OptionLegacyTailscaleEndpointDialer,
+ OptionRuleSetIPCIDRAcceptEmpty,
+ OptionLegacyDNSAddressFilter,
+ OptionLegacyDNSRuleStrategy,
+ OptionIndependentDNSCache,
+ OptionStoreRDRC,
+ OptionImplicitDefaultHTTPClient,
}
diff --git a/experimental/deprecated/stderr.go b/experimental/deprecated/stderr.go
index 0dfb935409..a999baea85 100644
--- a/experimental/deprecated/stderr.go
+++ b/experimental/deprecated/stderr.go
@@ -3,11 +3,13 @@ package deprecated
import (
"os"
"strconv"
+ "sync"
"github.com/sagernet/sing/common/logger"
)
type stderrManager struct {
+ access sync.Mutex
logger logger.Logger
reported map[string]bool
}
@@ -20,6 +22,8 @@ func NewStderrManager(logger logger.Logger) Manager {
}
func (f *stderrManager) ReportDeprecated(feature Note) {
+ f.access.Lock()
+ defer f.access.Unlock()
if f.reported[feature.Name] {
return
}
diff --git a/experimental/libbox/command.go b/experimental/libbox/command.go
index e3af6a1961..8a43bc9545 100644
--- a/experimental/libbox/command.go
+++ b/experimental/libbox/command.go
@@ -6,4 +6,5 @@ const (
CommandGroup
CommandClashMode
CommandConnections
+ CommandOutbounds
)
diff --git a/experimental/libbox/command_client.go b/experimental/libbox/command_client.go
index 2f347bdd58..9624c2e21e 100644
--- a/experimental/libbox/command_client.go
+++ b/experimental/libbox/command_client.go
@@ -2,6 +2,7 @@ package libbox
import (
"context"
+ "io"
"net"
"os"
"path/filepath"
@@ -14,8 +15,10 @@ import (
E "github.com/sagernet/sing/common/exceptions"
"google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
)
@@ -47,6 +50,7 @@ type CommandClientHandler interface {
WriteLogs(messageList LogIterator)
WriteStatus(message *StatusMessage)
WriteGroups(message OutboundGroupIterator)
+ WriteOutbounds(message OutboundGroupItemIterator)
InitializeClashMode(modeList StringIterator, currentMode string)
UpdateClashMode(newMode string)
WriteConnectionEvents(events *ConnectionEvents)
@@ -113,7 +117,7 @@ func dialTarget() (string, func(context.Context, string) (net.Conn, error)) {
return "passthrough:///xpc", func(ctx context.Context, _ string) (net.Conn, error) {
fileDescriptor, err := sXPCDialer.DialXPC()
if err != nil {
- return nil, err
+ return nil, E.Cause(err, "dial xpc")
}
return networkConnectionFromFileDescriptor(fileDescriptor)
}
@@ -162,7 +166,7 @@ func (c *CommandClient) dialWithRetry(target string, contextDialer func(context.
if err != nil {
lastError = err
if !retryDial {
- return nil, nil, err
+ return nil, nil, E.Cause(err, "create command client")
}
time.Sleep(commandClientDialDelay(attempt))
continue
@@ -182,7 +186,7 @@ func (c *CommandClient) dialWithRetry(target string, contextDialer func(context.
if connection != nil {
connection.Close()
}
- return nil, nil, lastError
+ return nil, nil, E.Cause(lastError, "probe command server")
}
func (c *CommandClient) Connect() error {
@@ -243,6 +247,8 @@ func (c *CommandClient) dispatchCommands() error {
go c.handleClashModeStream()
case CommandConnections:
go c.handleConnectionsStream()
+ case CommandOutbounds:
+ go c.handleOutboundsStream()
default:
return E.New("unknown command: ", command)
}
@@ -259,11 +265,11 @@ func (c *CommandClient) Disconnect() error {
return common.Close(common.PtrOrNil(c.grpcConn))
}
-func (c *CommandClient) getClientForCall() (daemon.StartedServiceClient, error) {
+func (c *CommandClient) getClientForCall() (daemon.StartedServiceClient, context.Context, error) {
c.clientMutex.RLock()
if c.grpcClient != nil {
defer c.clientMutex.RUnlock()
- return c.grpcClient, nil
+ return c.grpcClient, c.ctx, nil
}
c.clientMutex.RUnlock()
@@ -271,20 +277,20 @@ func (c *CommandClient) getClientForCall() (daemon.StartedServiceClient, error)
defer c.clientMutex.Unlock()
if c.grpcClient != nil {
- return c.grpcClient, nil
+ return c.grpcClient, c.ctx, nil
}
target, contextDialer := dialTarget()
connection, client, err := c.dialWithRetry(target, contextDialer, true)
if err != nil {
- return nil, err
+ return nil, nil, E.Cause(err, "get command client")
}
c.grpcConn = connection
c.grpcClient = client
if c.ctx == nil {
c.ctx, c.cancel = context.WithCancel(context.Background())
}
- return c.grpcClient, nil
+ return c.grpcClient, c.ctx, nil
}
func (c *CommandClient) closeConnection() {
@@ -297,8 +303,8 @@ func (c *CommandClient) closeConnection() {
}
}
-func callWithResult[T any](c *CommandClient, call func(client daemon.StartedServiceClient) (T, error)) (T, error) {
- client, err := c.getClientForCall()
+func callWithResult[T any](c *CommandClient, call func(ctx context.Context, client daemon.StartedServiceClient) (T, error)) (T, error) {
+ client, ctx, err := c.getClientForCall()
if err != nil {
var zero T
return zero, err
@@ -306,7 +312,7 @@ func callWithResult[T any](c *CommandClient, call func(client daemon.StartedServ
if c.standalone {
defer c.closeConnection()
}
- return call(client)
+ return call(ctx, client)
}
func (c *CommandClient) getStreamContext() (daemon.StartedServiceClient, context.Context) {
@@ -319,19 +325,19 @@ func (c *CommandClient) handleLogStream() {
client, ctx := c.getStreamContext()
stream, err := client.SubscribeLog(ctx, &emptypb.Empty{})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "subscribe log").Error())
return
}
defaultLogLevel, err := client.GetDefaultLogLevel(ctx, &emptypb.Empty{})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "get default log level").Error())
return
}
c.handler.SetDefaultLogLevel(int32(defaultLogLevel.Level))
for {
logMessage, err := stream.Recv()
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "log stream recv").Error())
return
}
if logMessage.Reset_ {
@@ -356,14 +362,14 @@ func (c *CommandClient) handleStatusStream() {
Interval: interval,
})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "subscribe status").Error())
return
}
for {
status, err := stream.Recv()
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "status stream recv").Error())
return
}
c.handler.WriteStatus(statusMessageFromGRPC(status))
@@ -375,14 +381,14 @@ func (c *CommandClient) handleGroupStream() {
stream, err := client.SubscribeGroups(ctx, &emptypb.Empty{})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "subscribe groups").Error())
return
}
for {
groups, err := stream.Recv()
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "groups stream recv").Error())
return
}
c.handler.WriteGroups(outboundGroupIteratorFromGRPC(groups))
@@ -394,7 +400,7 @@ func (c *CommandClient) handleClashModeStream() {
modeStatus, err := client.GetClashModeStatus(ctx, &emptypb.Empty{})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "get clash mode status").Error())
return
}
@@ -402,13 +408,13 @@ func (c *CommandClient) handleClashModeStream() {
go func() {
c.handler.InitializeClashMode(newIterator(modeStatus.ModeList), modeStatus.CurrentMode)
if len(modeStatus.ModeList) == 0 {
- c.handler.Disconnected(os.ErrInvalid.Error())
+ c.handler.Disconnected(E.Cause(os.ErrInvalid, "empty clash mode list").Error())
}
}()
} else {
c.handler.InitializeClashMode(newIterator(modeStatus.ModeList), modeStatus.CurrentMode)
if len(modeStatus.ModeList) == 0 {
- c.handler.Disconnected(os.ErrInvalid.Error())
+ c.handler.Disconnected(E.Cause(os.ErrInvalid, "empty clash mode list").Error())
return
}
}
@@ -419,14 +425,14 @@ func (c *CommandClient) handleClashModeStream() {
stream, err := client.SubscribeClashMode(ctx, &emptypb.Empty{})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "subscribe clash mode").Error())
return
}
for {
mode, err := stream.Recv()
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "clash mode stream recv").Error())
return
}
c.handler.UpdateClashMode(mode.Mode)
@@ -441,14 +447,14 @@ func (c *CommandClient) handleConnectionsStream() {
Interval: interval,
})
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "subscribe connections").Error())
return
}
for {
events, err := stream.Recv()
if err != nil {
- c.handler.Disconnected(err.Error())
+ c.handler.Disconnected(E.Cause(err, "connections stream recv").Error())
return
}
libboxEvents := connectionEventsFromGRPC(events)
@@ -456,101 +462,183 @@ func (c *CommandClient) handleConnectionsStream() {
}
}
+func (c *CommandClient) handleOutboundsStream() {
+ client, ctx := c.getStreamContext()
+
+ stream, err := client.SubscribeOutbounds(ctx, &emptypb.Empty{})
+ if err != nil {
+ c.handler.Disconnected(E.Cause(err, "subscribe outbounds").Error())
+ return
+ }
+
+ for {
+ list, err := stream.Recv()
+ if err != nil {
+ c.handler.Disconnected(E.Cause(err, "outbounds stream recv").Error())
+ return
+ }
+ c.handler.WriteOutbounds(outboundGroupItemListFromGRPC(list))
+ }
+}
+
func (c *CommandClient) SelectOutbound(groupTag string, outboundTag string) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.SelectOutbound(context.Background(), &daemon.SelectOutboundRequest{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.SelectOutbound(ctx, &daemon.SelectOutboundRequest{
GroupTag: groupTag,
OutboundTag: outboundTag,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "select outbound")
+ }
+ return nil
}
func (c *CommandClient) URLTest(groupTag string) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.URLTest(context.Background(), &daemon.URLTestRequest{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.URLTest(ctx, &daemon.URLTestRequest{
OutboundTag: groupTag,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "url test")
+ }
+ return nil
}
func (c *CommandClient) SetClashMode(newMode string) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.SetClashMode(context.Background(), &daemon.ClashMode{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.SetClashMode(ctx, &daemon.ClashMode{
Mode: newMode,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "set clash mode")
+ }
+ return nil
}
func (c *CommandClient) CloseConnection(connId string) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.CloseConnection(context.Background(), &daemon.CloseConnectionRequest{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.CloseConnection(ctx, &daemon.CloseConnectionRequest{
Id: connId,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "close connection")
+ }
+ return nil
}
func (c *CommandClient) CloseConnections() error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.CloseAllConnections(context.Background(), &emptypb.Empty{})
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.CloseAllConnections(ctx, &emptypb.Empty{})
})
- return err
+ if err != nil {
+ return E.Cause(err, "close all connections")
+ }
+ return nil
}
func (c *CommandClient) ServiceReload() error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.ReloadService(context.Background(), &emptypb.Empty{})
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.ReloadService(ctx, &emptypb.Empty{})
})
- return err
+ if err != nil {
+ return E.Cause(err, "reload service")
+ }
+ return nil
}
func (c *CommandClient) ServiceClose() error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.StopService(context.Background(), &emptypb.Empty{})
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.StopService(ctx, &emptypb.Empty{})
})
- return err
+ if err != nil {
+ return E.Cause(err, "stop service")
+ }
+ return nil
}
func (c *CommandClient) ClearLogs() error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.ClearLogs(context.Background(), &emptypb.Empty{})
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.ClearLogs(ctx, &emptypb.Empty{})
})
- return err
+ if err != nil {
+ return E.Cause(err, "clear logs")
+ }
+ return nil
}
func (c *CommandClient) GetSystemProxyStatus() (*SystemProxyStatus, error) {
- return callWithResult(c, func(client daemon.StartedServiceClient) (*SystemProxyStatus, error) {
- status, err := client.GetSystemProxyStatus(context.Background(), &emptypb.Empty{})
+ return callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*SystemProxyStatus, error) {
+ status, err := client.GetSystemProxyStatus(ctx, &emptypb.Empty{})
if err != nil {
- return nil, err
+ return nil, E.Cause(err, "get system proxy status")
}
return systemProxyStatusFromGRPC(status), nil
})
}
func (c *CommandClient) SetSystemProxyEnabled(isEnabled bool) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.SetSystemProxyEnabled(context.Background(), &daemon.SetSystemProxyEnabledRequest{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.SetSystemProxyEnabled(ctx, &daemon.SetSystemProxyEnabledRequest{
Enabled: isEnabled,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "set system proxy enabled")
+ }
+ return nil
+}
+
+func (c *CommandClient) TriggerGoCrash() error {
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.TriggerDebugCrash(ctx, &daemon.DebugCrashRequest{
+ Type: daemon.DebugCrashRequest_GO,
+ })
+ })
+ if err != nil {
+ return E.Cause(err, "trigger debug crash")
+ }
+ return nil
+}
+
+func (c *CommandClient) TriggerNativeCrash() error {
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.TriggerDebugCrash(ctx, &daemon.DebugCrashRequest{
+ Type: daemon.DebugCrashRequest_NATIVE,
+ })
+ })
+ if err != nil {
+ return E.Cause(err, "trigger native crash")
+ }
+ return nil
+}
+
+func (c *CommandClient) TriggerOOMReport() error {
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.TriggerOOMReport(ctx, &emptypb.Empty{})
+ })
+ if err != nil {
+ return E.Cause(err, "trigger oom report")
+ }
+ return nil
}
func (c *CommandClient) GetDeprecatedNotes() (DeprecatedNoteIterator, error) {
- return callWithResult(c, func(client daemon.StartedServiceClient) (DeprecatedNoteIterator, error) {
- warnings, err := client.GetDeprecatedWarnings(context.Background(), &emptypb.Empty{})
+ return callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (DeprecatedNoteIterator, error) {
+ warnings, err := client.GetDeprecatedWarnings(ctx, &emptypb.Empty{})
if err != nil {
- return nil, err
+ return nil, E.Cause(err, "get deprecated warnings")
}
var notes []*DeprecatedNote
for _, warning := range warnings.Warnings {
notes = append(notes, &DeprecatedNote{
- Description: warning.Message,
- MigrationLink: warning.MigrationLink,
+ Description: warning.Description,
+ DeprecatedVersion: warning.DeprecatedVersion,
+ ScheduledVersion: warning.ScheduledVersion,
+ MigrationLink: warning.MigrationLink,
})
}
return newIterator(notes), nil
@@ -558,21 +646,414 @@ func (c *CommandClient) GetDeprecatedNotes() (DeprecatedNoteIterator, error) {
}
func (c *CommandClient) GetStartedAt() (int64, error) {
- return callWithResult(c, func(client daemon.StartedServiceClient) (int64, error) {
- startedAt, err := client.GetStartedAt(context.Background(), &emptypb.Empty{})
+ return callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (int64, error) {
+ startedAt, err := client.GetStartedAt(ctx, &emptypb.Empty{})
if err != nil {
- return 0, err
+ return 0, E.Cause(err, "get started at")
}
return startedAt.StartedAt, nil
})
}
func (c *CommandClient) SetGroupExpand(groupTag string, isExpand bool) error {
- _, err := callWithResult(c, func(client daemon.StartedServiceClient) (*emptypb.Empty, error) {
- return client.SetGroupExpand(context.Background(), &daemon.SetGroupExpandRequest{
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.SetGroupExpand(ctx, &daemon.SetGroupExpandRequest{
GroupTag: groupTag,
IsExpand: isExpand,
})
})
- return err
+ if err != nil {
+ return E.Cause(err, "set group expand")
+ }
+ return nil
+}
+
+func (c *CommandClient) StartNetworkQualityTest(configURL string, outboundTag string, serial bool, maxRuntimeSeconds int32, http3 bool, handler NetworkQualityTestHandler) (*NetworkQualityTestSession, error) {
+ client, parentCtx, err := c.getClientForCall()
+ if err != nil {
+ return nil, E.Cause(err, "start network quality test")
+ }
+
+ streamCtx, cancel := context.WithCancel(parentCtx)
+ session := &NetworkQualityTestSession{
+ streamSession: streamSession{
+ ctx: streamCtx,
+ cancel: cancel,
+ closeDone: make(chan struct{}),
+ },
+ }
+
+ failStart := func(cause error, message string) (*NetworkQualityTestSession, error) {
+ cancel()
+ if c.standalone {
+ c.closeConnection()
+ }
+ return nil, E.Cause(cause, message)
+ }
+
+ stream, err := client.StartNetworkQualityTest(streamCtx, &daemon.NetworkQualityTestRequest{
+ ConfigURL: configURL,
+ OutboundTag: outboundTag,
+ Serial: serial,
+ MaxRuntimeSeconds: maxRuntimeSeconds,
+ Http3: http3,
+ })
+ if err != nil {
+ return failStart(err, "start network quality test")
+ }
+
+ standalone := c.standalone
+ go func() {
+ defer func() {
+ close(session.closeDone)
+ if standalone {
+ c.closeConnection()
+ }
+ }()
+ for {
+ event, recvErr := stream.Recv()
+ if recvErr != nil {
+ if session.ctx.Err() != nil {
+ return
+ }
+ handler.OnError(E.Cause(recvErr, "network quality test recv").Error())
+ return
+ }
+ if event.IsFinal {
+ if event.Error != "" {
+ handler.OnError(event.Error)
+ } else {
+ handler.OnResult(&NetworkQualityResult{
+ DownloadCapacity: event.DownloadCapacity,
+ UploadCapacity: event.UploadCapacity,
+ DownloadRPM: event.DownloadRPM,
+ UploadRPM: event.UploadRPM,
+ IdleLatencyMs: event.IdleLatencyMs,
+ DownloadCapacityAccuracy: event.DownloadCapacityAccuracy,
+ UploadCapacityAccuracy: event.UploadCapacityAccuracy,
+ DownloadRPMAccuracy: event.DownloadRPMAccuracy,
+ UploadRPMAccuracy: event.UploadRPMAccuracy,
+ })
+ }
+ return
+ }
+ handler.OnProgress(networkQualityProgressFromGRPC(event))
+ }
+ }()
+
+ return session, nil
+}
+
+func (c *CommandClient) StartSTUNTest(server string, outboundTag string, handler STUNTestHandler) (*STUNTestSession, error) {
+ client, parentCtx, err := c.getClientForCall()
+ if err != nil {
+ return nil, E.Cause(err, "start stun test")
+ }
+
+ streamCtx, cancel := context.WithCancel(parentCtx)
+ session := &STUNTestSession{
+ streamSession: streamSession{
+ ctx: streamCtx,
+ cancel: cancel,
+ closeDone: make(chan struct{}),
+ },
+ }
+
+ failStart := func(cause error, message string) (*STUNTestSession, error) {
+ cancel()
+ if c.standalone {
+ c.closeConnection()
+ }
+ return nil, E.Cause(cause, message)
+ }
+
+ stream, err := client.StartSTUNTest(streamCtx, &daemon.STUNTestRequest{
+ Server: server,
+ OutboundTag: outboundTag,
+ })
+ if err != nil {
+ return failStart(err, "start stun test")
+ }
+
+ standalone := c.standalone
+ go func() {
+ defer func() {
+ close(session.closeDone)
+ if standalone {
+ c.closeConnection()
+ }
+ }()
+ for {
+ event, recvErr := stream.Recv()
+ if recvErr != nil {
+ if session.ctx.Err() != nil {
+ return
+ }
+ handler.OnError(E.Cause(recvErr, "stun test recv").Error())
+ return
+ }
+ if event.IsFinal {
+ if event.Error != "" {
+ handler.OnError(event.Error)
+ } else {
+ handler.OnResult(&STUNTestResult{
+ ExternalAddr: event.ExternalAddr,
+ LatencyMs: event.LatencyMs,
+ NATMapping: event.NatMapping,
+ NATFiltering: event.NatFiltering,
+ NATTypeSupported: event.NatTypeSupported,
+ })
+ }
+ return
+ }
+ handler.OnProgress(stunTestProgressFromGRPC(event))
+ }
+ }()
+
+ return session, nil
+}
+
+func (c *CommandClient) SubscribeTailscaleStatus(handler TailscaleStatusHandler) (*TailscaleStatusSubscription, error) {
+ client, parentCtx, err := c.getClientForCall()
+ if err != nil {
+ return nil, E.Cause(err, "subscribe tailscale status")
+ }
+
+ streamCtx, cancel := context.WithCancel(parentCtx)
+ session := &TailscaleStatusSubscription{
+ streamSession: streamSession{
+ ctx: streamCtx,
+ cancel: cancel,
+ closeDone: make(chan struct{}),
+ },
+ }
+
+ failStart := func(cause error, message string) (*TailscaleStatusSubscription, error) {
+ cancel()
+ if c.standalone {
+ c.closeConnection()
+ }
+ return nil, E.Cause(cause, message)
+ }
+
+ stream, err := client.SubscribeTailscaleStatus(streamCtx, &emptypb.Empty{})
+ if err != nil {
+ return failStart(err, "subscribe tailscale status")
+ }
+
+ standalone := c.standalone
+ go func() {
+ defer func() {
+ close(session.closeDone)
+ if standalone {
+ c.closeConnection()
+ }
+ }()
+ for {
+ event, recvErr := stream.Recv()
+ if recvErr != nil {
+ if session.ctx.Err() != nil {
+ return
+ }
+ if status.Code(recvErr) == codes.NotFound || status.Code(recvErr) == codes.Unavailable {
+ return
+ }
+ handler.OnError(E.Cause(recvErr, "tailscale status recv").Error())
+ return
+ }
+ handler.OnStatusUpdate(tailscaleStatusUpdateFromGRPC(event))
+ }
+ }()
+
+ return session, nil
+}
+
+func (c *CommandClient) SetTailscaleExitNode(endpointTag string, stableID string) error {
+ _, err := callWithResult(c, func(ctx context.Context, client daemon.StartedServiceClient) (*emptypb.Empty, error) {
+ return client.SetTailscaleExitNode(ctx, &daemon.SetTailscaleExitNodeRequest{
+ EndpointTag: endpointTag,
+ StableID: stableID,
+ })
+ })
+ if err != nil {
+ return E.Cause(err, "set tailscale exit node")
+ }
+ return nil
+}
+
+func (c *CommandClient) StartTailscalePing(endpointTag string, peerIP string, handler TailscalePingHandler) (*TailscalePingSession, error) {
+ client, parentCtx, err := c.getClientForCall()
+ if err != nil {
+ return nil, E.Cause(err, "start tailscale ping")
+ }
+
+ streamCtx, cancel := context.WithCancel(parentCtx)
+ session := &TailscalePingSession{
+ streamSession: streamSession{
+ ctx: streamCtx,
+ cancel: cancel,
+ closeDone: make(chan struct{}),
+ },
+ }
+
+ failStart := func(cause error, message string) (*TailscalePingSession, error) {
+ cancel()
+ if c.standalone {
+ c.closeConnection()
+ }
+ return nil, E.Cause(cause, message)
+ }
+
+ stream, err := client.StartTailscalePing(streamCtx, &daemon.TailscalePingRequest{
+ EndpointTag: endpointTag,
+ PeerIP: peerIP,
+ })
+ if err != nil {
+ return failStart(err, "start tailscale ping")
+ }
+
+ standalone := c.standalone
+ go func() {
+ defer func() {
+ close(session.closeDone)
+ if standalone {
+ c.closeConnection()
+ }
+ }()
+ for {
+ event, recvErr := stream.Recv()
+ if recvErr != nil {
+ if session.ctx.Err() != nil {
+ return
+ }
+ handler.OnError(E.Cause(recvErr, "tailscale ping recv").Error())
+ return
+ }
+ handler.OnPingResult(tailscalePingResultFromGRPC(event))
+ }
+ }()
+
+ return session, nil
+}
+
+func (c *CommandClient) StartTailscaleSSHSession(opts *TailscaleSSHOptions, handler TailscaleSSHHandler) (*TailscaleSSHSession, error) {
+ client, parentCtx, err := c.getClientForCall()
+ if err != nil {
+ return nil, E.Cause(err, "start tailscale ssh session")
+ }
+
+ streamCtx, cancel := context.WithCancel(parentCtx)
+ failStart := func(cause error, message string) (*TailscaleSSHSession, error) {
+ cancel()
+ if c.standalone {
+ c.closeConnection()
+ }
+ return nil, E.Cause(cause, message)
+ }
+
+ stream, err := client.StartTailscaleSSHSession(streamCtx)
+ if err != nil {
+ return failStart(err, "start tailscale ssh session")
+ }
+
+ sendErr := stream.Send(&daemon.TailscaleSSHClientMessage{
+ Message: &daemon.TailscaleSSHClientMessage_Start{Start: &daemon.TailscaleSSHStart{
+ EndpointTag: opts.EndpointTag,
+ PeerAddress: opts.PeerAddress,
+ Username: opts.Username,
+ TerminalType: opts.TerminalType,
+ Columns: opts.Columns,
+ Rows: opts.Rows,
+ WidthPixels: opts.WidthPixels,
+ HeightPixels: opts.HeightPixels,
+ HostKeys: iteratorToArray[string](opts.HostKeys),
+ ForwardAgent: opts.ForwardAgent,
+ }},
+ })
+ if sendErr != nil {
+ return failStart(sendErr, "send tailscale ssh start")
+ }
+
+ session := &TailscaleSSHSession{
+ stream: stream,
+ inputCh: make(chan []byte, 8),
+ resizeCh: make(chan tailscaleSSHResize, 1),
+ ctx: streamCtx,
+ cancel: cancel,
+ closeDone: make(chan struct{}),
+ }
+
+ session.wg.Add(1)
+ go func() {
+ defer session.wg.Done()
+ for {
+ select {
+ case <-streamCtx.Done():
+ return
+ case data := <-session.inputCh:
+ sendErr := stream.Send(&daemon.TailscaleSSHClientMessage{
+ Message: &daemon.TailscaleSSHClientMessage_Input{Input: &daemon.TailscaleSSHInput{Data: data}},
+ })
+ if sendErr != nil {
+ cancel()
+ return
+ }
+ case resize := <-session.resizeCh:
+ sendErr := stream.Send(&daemon.TailscaleSSHClientMessage{
+ Message: &daemon.TailscaleSSHClientMessage_Resize{Resize: &daemon.TailscaleSSHResize{
+ Columns: resize.columns,
+ Rows: resize.rows,
+ WidthPixels: resize.widthPixels,
+ HeightPixels: resize.heightPixels,
+ }},
+ })
+ if sendErr != nil {
+ cancel()
+ return
+ }
+ }
+ }
+ }()
+
+ session.wg.Add(1)
+ go func() {
+ defer session.wg.Done()
+ for {
+ msg, recvErr := stream.Recv()
+ if recvErr == io.EOF {
+ cancel()
+ return
+ }
+ if recvErr != nil {
+ handler.OnError(E.Cause(recvErr, "tailscale ssh recv").Error())
+ cancel()
+ return
+ }
+ switch payload := msg.GetMessage().(type) {
+ case *daemon.TailscaleSSHServerMessage_AuthBanner:
+ handler.OnAuthBanner(payload.AuthBanner.Message)
+ case *daemon.TailscaleSSHServerMessage_Ready:
+ handler.OnReady()
+ case *daemon.TailscaleSSHServerMessage_Output:
+ handler.OnOutput(payload.Output.Data)
+ case *daemon.TailscaleSSHServerMessage_Exit:
+ handler.OnExit(payload.Exit.ExitCode, payload.Exit.Signal, payload.Exit.ErrorMessage)
+ cancel()
+ return
+ case *daemon.TailscaleSSHServerMessage_Error:
+ handler.OnError(payload.Error.Message)
+ }
+ }
+ }()
+
+ standalone := c.standalone
+ go func() {
+ session.wg.Wait()
+ close(session.closeDone)
+ if standalone {
+ c.closeConnection()
+ }
+ }()
+
+ return session, nil
}
diff --git a/experimental/libbox/command_server.go b/experimental/libbox/command_server.go
index 7eca119487..a67b010e61 100644
--- a/experimental/libbox/command_server.go
+++ b/experimental/libbox/command_server.go
@@ -39,7 +39,9 @@ type CommandServerHandler interface {
ServiceReload() error
GetSystemProxyStatus() (*SystemProxyStatus, error)
SetSystemProxyEnabled(enabled bool) error
+ TriggerNativeCrash() error
WriteDebugMessage(message string)
+ ConnectSSHAgent() (int32, error)
}
func NewCommandServer(handler CommandServerHandler, platformInterface PlatformInterface) (*CommandServer, error) {
@@ -57,10 +59,12 @@ func NewCommandServer(handler CommandServerHandler, platformInterface PlatformIn
server.StartedService = daemon.NewStartedService(daemon.ServiceOptions{
Context: ctx,
// Platform: platformWrapper,
- Handler: (*platformHandler)(server),
- Debug: sDebug,
- LogMaxLines: sLogMaxLines,
- OOMKiller: memoryLimitEnabled,
+ Handler: (*platformHandler)(server),
+ Debug: sDebug,
+ LogMaxLines: sLogMaxLines,
+ OOMKillerEnabled: sOOMKillerEnabled,
+ OOMKillerDisabled: sOOMKillerDisabled,
+ OOMMemoryLimit: uint64(sOOMMemoryLimit),
// WorkingDirectory: sWorkingPath,
// TempDirectory: sTempPath,
// UserID: sUserID,
@@ -170,11 +174,16 @@ type OverrideOptions struct {
}
func (s *CommandServer) StartOrReloadService(configContent string, options *OverrideOptions) error {
- return s.StartedService.StartOrReloadService(configContent, &daemon.OverrideOptions{
+ saveConfigSnapshot(configContent)
+ err := s.StartedService.StartOrReloadService(configContent, &daemon.OverrideOptions{
AutoRedirect: options.AutoRedirect,
IncludePackage: iteratorToArray(options.IncludePackage),
ExcludePackage: iteratorToArray(options.ExcludePackage),
})
+ if err != nil {
+ return E.Cause(err, "start or reload service")
+ }
+ return nil
}
func (s *CommandServer) CloseService() error {
@@ -235,7 +244,7 @@ func (s *CommandServer) ResetNetwork() {
if instance == nil || instance.Box() == nil {
return
}
- instance.Box().Router().ResetNetwork()
+ instance.Box().Network().ResetNetwork()
}
func (s *CommandServer) UpdateWIFIState() {
@@ -259,7 +268,7 @@ func (h *platformHandler) ServiceReload() error {
func (h *platformHandler) SystemProxyStatus() (*daemon.SystemProxyStatus, error) {
status, err := (*CommandServer)(h).handler.GetSystemProxyStatus()
if err != nil {
- return nil, err
+ return nil, E.Cause(err, "get system proxy status")
}
return &daemon.SystemProxyStatus{
Enabled: status.Enabled,
@@ -271,6 +280,14 @@ func (h *platformHandler) SetSystemProxyEnabled(enabled bool) error {
return (*CommandServer)(h).handler.SetSystemProxyEnabled(enabled)
}
+func (h *platformHandler) TriggerNativeCrash() error {
+ return (*CommandServer)(h).handler.TriggerNativeCrash()
+}
+
func (h *platformHandler) WriteDebugMessage(message string) {
(*CommandServer)(h).handler.WriteDebugMessage(message)
}
+
+func (h *platformHandler) ConnectSSHAgent() (int32, error) {
+ return (*CommandServer)(h).handler.ConnectSSHAgent()
+}
diff --git a/experimental/libbox/command_types.go b/experimental/libbox/command_types.go
index b811aaf460..5be81a2283 100644
--- a/experimental/libbox/command_types.go
+++ b/experimental/libbox/command_types.go
@@ -1,14 +1,31 @@
package libbox
import (
+ "context"
"slices"
"strings"
+ "sync"
"time"
"github.com/sagernet/sing-box/daemon"
M "github.com/sagernet/sing/common/metadata"
)
+type streamSession struct {
+ ctx context.Context
+ cancel context.CancelFunc
+ closeOnce sync.Once
+ closeDone chan struct{}
+}
+
+func (s *streamSession) Close() error {
+ s.closeOnce.Do(func() {
+ s.cancel()
+ })
+ <-s.closeDone
+ return nil
+}
+
type StatusMessage struct {
Memory int64
Goroutines int32
@@ -339,6 +356,22 @@ func outboundGroupIteratorFromGRPC(groups *daemon.Groups) OutboundGroupIterator
return newIterator(libboxGroups)
}
+func outboundGroupItemListFromGRPC(list *daemon.OutboundList) OutboundGroupItemIterator {
+ if list == nil || len(list.Outbounds) == 0 {
+ return newIterator([]*OutboundGroupItem{})
+ }
+ var items []*OutboundGroupItem
+ for _, ob := range list.Outbounds {
+ items = append(items, &OutboundGroupItem{
+ Tag: ob.Tag,
+ Type: ob.Type,
+ URLTestTime: ob.UrlTestTime,
+ URLTestDelay: ob.UrlTestDelay,
+ })
+ }
+ return newIterator(items)
+}
+
func connectionFromGRPC(conn *daemon.Connection) Connection {
var processInfo *ProcessInfo
if conn.ProcessInfo != nil {
diff --git a/experimental/libbox/command_types_nq.go b/experimental/libbox/command_types_nq.go
new file mode 100644
index 0000000000..17d53ff64e
--- /dev/null
+++ b/experimental/libbox/command_types_nq.go
@@ -0,0 +1,55 @@
+package libbox
+
+import "github.com/sagernet/sing-box/daemon"
+
+type NetworkQualityProgress struct {
+ Phase int32
+ DownloadCapacity int64
+ UploadCapacity int64
+ DownloadRPM int32
+ UploadRPM int32
+ IdleLatencyMs int32
+ ElapsedMs int64
+ DownloadCapacityAccuracy int32
+ UploadCapacityAccuracy int32
+ DownloadRPMAccuracy int32
+ UploadRPMAccuracy int32
+}
+
+type NetworkQualityResult struct {
+ DownloadCapacity int64
+ UploadCapacity int64
+ DownloadRPM int32
+ UploadRPM int32
+ IdleLatencyMs int32
+ DownloadCapacityAccuracy int32
+ UploadCapacityAccuracy int32
+ DownloadRPMAccuracy int32
+ UploadRPMAccuracy int32
+}
+
+type NetworkQualityTestHandler interface {
+ OnProgress(progress *NetworkQualityProgress)
+ OnResult(result *NetworkQualityResult)
+ OnError(message string)
+}
+
+type NetworkQualityTestSession struct {
+ streamSession
+}
+
+func networkQualityProgressFromGRPC(event *daemon.NetworkQualityTestProgress) *NetworkQualityProgress {
+ return &NetworkQualityProgress{
+ Phase: event.Phase,
+ DownloadCapacity: event.DownloadCapacity,
+ UploadCapacity: event.UploadCapacity,
+ DownloadRPM: event.DownloadRPM,
+ UploadRPM: event.UploadRPM,
+ IdleLatencyMs: event.IdleLatencyMs,
+ ElapsedMs: event.ElapsedMs,
+ DownloadCapacityAccuracy: event.DownloadCapacityAccuracy,
+ UploadCapacityAccuracy: event.UploadCapacityAccuracy,
+ DownloadRPMAccuracy: event.DownloadRPMAccuracy,
+ UploadRPMAccuracy: event.UploadRPMAccuracy,
+ }
+}
diff --git a/experimental/libbox/command_types_stun.go b/experimental/libbox/command_types_stun.go
new file mode 100644
index 0000000000..f3ba169053
--- /dev/null
+++ b/experimental/libbox/command_types_stun.go
@@ -0,0 +1,39 @@
+package libbox
+
+import "github.com/sagernet/sing-box/daemon"
+
+type STUNTestProgress struct {
+ Phase int32
+ ExternalAddr string
+ LatencyMs int32
+ NATMapping int32
+ NATFiltering int32
+}
+
+type STUNTestResult struct {
+ ExternalAddr string
+ LatencyMs int32
+ NATMapping int32
+ NATFiltering int32
+ NATTypeSupported bool
+}
+
+type STUNTestHandler interface {
+ OnProgress(progress *STUNTestProgress)
+ OnResult(result *STUNTestResult)
+ OnError(message string)
+}
+
+type STUNTestSession struct {
+ streamSession
+}
+
+func stunTestProgressFromGRPC(event *daemon.STUNTestProgress) *STUNTestProgress {
+ return &STUNTestProgress{
+ Phase: event.Phase,
+ ExternalAddr: event.ExternalAddr,
+ LatencyMs: event.LatencyMs,
+ NATMapping: event.NatMapping,
+ NATFiltering: event.NatFiltering,
+ }
+}
diff --git a/experimental/libbox/command_types_tailscale.go b/experimental/libbox/command_types_tailscale.go
new file mode 100644
index 0000000000..ffb9b242f2
--- /dev/null
+++ b/experimental/libbox/command_types_tailscale.go
@@ -0,0 +1,154 @@
+package libbox
+
+import "github.com/sagernet/sing-box/daemon"
+
+type TailscaleStatusUpdate struct {
+ endpoints []*TailscaleEndpointStatus
+}
+
+func (u *TailscaleStatusUpdate) Endpoints() TailscaleEndpointStatusIterator {
+ return newIterator(u.endpoints)
+}
+
+type TailscaleEndpointStatusIterator interface {
+ Next() *TailscaleEndpointStatus
+ HasNext() bool
+}
+
+type TailscaleEndpointStatus struct {
+ EndpointTag string
+ BackendState string
+ AuthURL string
+ NetworkName string
+ MagicDNSSuffix string
+ Self *TailscalePeer
+ ExitNode *TailscalePeer
+ userGroups []*TailscaleUserGroup
+}
+
+func (s *TailscaleEndpointStatus) UserGroups() TailscaleUserGroupIterator {
+ return newIterator(s.userGroups)
+}
+
+type TailscaleUserGroupIterator interface {
+ Next() *TailscaleUserGroup
+ HasNext() bool
+}
+
+type TailscaleUserGroup struct {
+ UserID int64
+ LoginName string
+ DisplayName string
+ ProfilePicURL string
+ peers []*TailscalePeer
+}
+
+func (g *TailscaleUserGroup) Peers() TailscalePeerIterator {
+ return newIterator(g.peers)
+}
+
+type TailscalePeerIterator interface {
+ Next() *TailscalePeer
+ HasNext() bool
+}
+
+type TailscalePeer struct {
+ StableID string
+ HostName string
+ DNSName string
+ OS string
+ tailscaleIPs []string
+ sshHostKeys []string
+ Online bool
+ ExitNode bool
+ ExitNodeOption bool
+ ShareeNode bool
+ Expired bool
+ Active bool
+ RxBytes int64
+ TxBytes int64
+ KeyExpiry int64
+ LastSeen int64
+}
+
+func (p *TailscalePeer) TailscaleIPs() StringIterator {
+ return newIterator(p.tailscaleIPs)
+}
+
+func (p *TailscalePeer) SSHHostKeys() StringIterator {
+ return newIterator(p.sshHostKeys)
+}
+
+type TailscaleStatusHandler interface {
+ OnStatusUpdate(status *TailscaleStatusUpdate)
+ OnError(message string)
+}
+
+type TailscaleStatusSubscription struct {
+ streamSession
+}
+
+func tailscaleStatusUpdateFromGRPC(update *daemon.TailscaleStatusUpdate) *TailscaleStatusUpdate {
+ endpoints := make([]*TailscaleEndpointStatus, len(update.Endpoints))
+ for i, endpoint := range update.Endpoints {
+ endpoints[i] = tailscaleEndpointStatusFromGRPC(endpoint)
+ }
+ return &TailscaleStatusUpdate{endpoints: endpoints}
+}
+
+func tailscaleEndpointStatusFromGRPC(status *daemon.TailscaleEndpointStatus) *TailscaleEndpointStatus {
+ userGroups := make([]*TailscaleUserGroup, len(status.UserGroups))
+ for i, group := range status.UserGroups {
+ userGroups[i] = tailscaleUserGroupFromGRPC(group)
+ }
+ result := &TailscaleEndpointStatus{
+ EndpointTag: status.EndpointTag,
+ BackendState: status.BackendState,
+ AuthURL: status.AuthURL,
+ NetworkName: status.NetworkName,
+ MagicDNSSuffix: status.MagicDNSSuffix,
+ userGroups: userGroups,
+ }
+ if status.Self != nil {
+ result.Self = tailscalePeerFromGRPC(status.Self)
+ }
+ if status.ExitNode != nil {
+ result.ExitNode = tailscalePeerFromGRPC(status.ExitNode)
+ }
+ return result
+}
+
+func tailscaleUserGroupFromGRPC(group *daemon.TailscaleUserGroup) *TailscaleUserGroup {
+ peers := make([]*TailscalePeer, len(group.Peers))
+ for i, peer := range group.Peers {
+ peers[i] = tailscalePeerFromGRPC(peer)
+ }
+ return &TailscaleUserGroup{
+ UserID: group.UserID,
+ LoginName: group.LoginName,
+ DisplayName: group.DisplayName,
+ ProfilePicURL: group.ProfilePicURL,
+ peers: peers,
+ }
+}
+
+func tailscalePeerFromGRPC(peer *daemon.TailscalePeer) *TailscalePeer {
+ return &TailscalePeer{
+ StableID: peer.StableID,
+ HostName: peer.HostName,
+ DNSName: peer.DnsName,
+ OS: peer.Os,
+ tailscaleIPs: peer.TailscaleIPs,
+ sshHostKeys: peer.SshHostKeys,
+ Online: peer.Online,
+ ExitNode: peer.ExitNode,
+ ExitNodeOption: peer.ExitNodeOption,
+ ShareeNode: peer.ShareeNode,
+ Expired: peer.Expired,
+ Active: peer.Active,
+ RxBytes: peer.RxBytes,
+ TxBytes: peer.TxBytes,
+ KeyExpiry: peer.KeyExpiry,
+ LastSeen: peer.LastSeen,
+ }
+}
diff --git a/experimental/libbox/command_types_tailscale_ping.go b/experimental/libbox/command_types_tailscale_ping.go
new file mode 100644
index 0000000000..5b8ebc2f02
--- /dev/null
+++ b/experimental/libbox/command_types_tailscale_ping.go
@@ -0,0 +1,32 @@
+package libbox
+
+import "github.com/sagernet/sing-box/daemon"
+
+type TailscalePingResult struct {
+ LatencyMs float64
+ IsDirect bool
+ Endpoint string
+ DERPRegionID int32
+ DERPRegionCode string
+ Error string
+}
+
+type TailscalePingHandler interface {
+ OnPingResult(result *TailscalePingResult)
+ OnError(message string)
+}
+
+type TailscalePingSession struct {
+ streamSession
+}
+
+func tailscalePingResultFromGRPC(response *daemon.TailscalePingResponse) *TailscalePingResult {
+ return &TailscalePingResult{
+ LatencyMs: response.LatencyMs,
+ IsDirect: response.IsDirect,
+ Endpoint: response.Endpoint,
+ DERPRegionID: response.DerpRegionID,
+ DERPRegionCode: response.DerpRegionCode,
+ Error: response.Error,
+ }
+}
diff --git a/experimental/libbox/command_types_tailscale_ssh.go b/experimental/libbox/command_types_tailscale_ssh.go
new file mode 100644
index 0000000000..fd5754e01c
--- /dev/null
+++ b/experimental/libbox/command_types_tailscale_ssh.go
@@ -0,0 +1,82 @@
+package libbox
+
+import (
+ "bytes"
+ "context"
+ "os"
+ "sync"
+
+ "github.com/sagernet/sing-box/daemon"
+)
+
+type TailscaleSSHOptions struct {
+ EndpointTag string
+ PeerAddress string
+ Username string
+ TerminalType string
+ Columns int32
+ Rows int32
+ WidthPixels int32
+ HeightPixels int32
+ HostKeys StringIterator
+ ForwardAgent bool
+}
+
+type TailscaleSSHHandler interface {
+ OnReady()
+ OnOutput(data []byte)
+ OnAuthBanner(message string)
+ OnExit(exitCode int32, signal string, errorMessage string)
+ OnError(message string)
+}
+
+type tailscaleSSHResize struct {
+ columns int32
+ rows int32
+ widthPixels int32
+ heightPixels int32
+}
+
+type TailscaleSSHSession struct {
+ stream daemon.StartedService_StartTailscaleSSHSessionClient
+ inputCh chan []byte
+ resizeCh chan tailscaleSSHResize
+ ctx context.Context
+ cancel context.CancelFunc
+ wg sync.WaitGroup
+ closeOnce sync.Once
+ closeDone chan struct{}
+}
+
+func (s *TailscaleSSHSession) SendInput(data []byte) error {
+ select {
+ case <-s.ctx.Done():
+ return os.ErrClosed
+ case s.inputCh <- bytes.Clone(data):
+ return nil
+ }
+}
+
+func (s *TailscaleSSHSession) SendResize(columns int32, rows int32, widthPixels int32, heightPixels int32) error {
+ resize := tailscaleSSHResize{
+ columns: columns,
+ rows: rows,
+ widthPixels: widthPixels,
+ heightPixels: heightPixels,
+ }
+ select {
+ case s.resizeCh <- resize:
+ return nil
+ case <-s.ctx.Done():
+ return os.ErrClosed
+ }
+}
+
+func (s *TailscaleSSHSession) Close() error {
+ s.closeOnce.Do(func() {
+ s.cancel()
+ _ = s.stream.CloseSend()
+ })
+ <-s.closeDone
+ return nil
+}
diff --git a/experimental/libbox/config.go b/experimental/libbox/config.go
index b1676ab61b..e4200aef1f 100644
--- a/experimental/libbox/config.go
+++ b/experimental/libbox/config.go
@@ -13,6 +13,7 @@ import (
"github.com/sagernet/sing-box/include"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/service/oomkiller"
tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
@@ -23,7 +24,17 @@ import (
"github.com/sagernet/sing/service/filemanager"
)
+var sOOMReporter oomkiller.OOMReporter
+
+func BaseContext(platformInterface PlatformInterface) context.Context {
+ return baseContext(platformInterface)
+}
+
func baseContext(platformInterface PlatformInterface) context.Context {
+ return baseContextWithParent(context.Background(), platformInterface)
+}
+
+func baseContextWithParent(ctx context.Context, platformInterface PlatformInterface) context.Context {
dnsRegistry := include.DNSTransportRegistry()
if platformInterface != nil {
if localTransport := platformInterface.LocalDNSTransport(); localTransport != nil {
@@ -32,9 +43,11 @@ func baseContext(platformInterface PlatformInterface) context.Context {
})
}
}
- ctx := context.Background()
ctx = filemanager.WithDefault(ctx, sWorkingPath, sTempPath, sUserID, sGroupID)
- return box.Context(ctx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry(), dnsRegistry, include.ServiceRegistry())
+ if sOOMReporter != nil {
+ ctx = service.ContextWith[oomkiller.OOMReporter](ctx, sOOMReporter)
+ }
+ return box.Context(ctx, include.InboundRegistry(), include.OutboundRegistry(), include.EndpointRegistry(), dnsRegistry, include.ServiceRegistry(), include.CertificateProviderRegistry())
}
func parseConfig(ctx context.Context, configContent string) (option.Options, error) {
@@ -51,12 +64,20 @@ func CheckConfig(configContent string) error {
if err != nil {
return err
}
+ return CheckConfigOptions(&options)
+}
+
+func CheckConfigOptions(options *option.Options) error {
+ if options == nil {
+ return os.ErrInvalid
+ }
+ ctx := baseContext(nil)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
ctx = service.ContextWith[adapter.PlatformInterface](ctx, (*platformInterfaceStub)(nil))
instance, err := box.New(box.Options{
Context: ctx,
- Options: options,
+ Options: *options,
})
if err == nil {
instance.Close()
@@ -149,6 +170,18 @@ func (s *platformInterfaceStub) MyInterfaceAddress() []netip.Addr {
return nil
}
+func (s *platformInterfaceStub) UsePlatformNeighborResolver() bool {
+ return false
+}
+
+func (s *platformInterfaceStub) StartNeighborMonitor(listener adapter.NeighborUpdateListener) error {
+ return os.ErrInvalid
+}
+
+func (s *platformInterfaceStub) CloseNeighborMonitor(listener adapter.NeighborUpdateListener) error {
+ return nil
+}
+
func (s *platformInterfaceStub) UsePlatformLocalDNSTransport() bool {
return false
}
diff --git a/experimental/libbox/debug.go b/experimental/libbox/debug.go
new file mode 100644
index 0000000000..75942976f6
--- /dev/null
+++ b/experimental/libbox/debug.go
@@ -0,0 +1,12 @@
+package libbox
+
+import (
+ "time"
+ "unsafe"
+)
+
+func TriggerGoPanic() {
+ time.AfterFunc(200*time.Millisecond, func() {
+ *(*int)(unsafe.Pointer(uintptr(0))) = 0
+ })
+}
diff --git a/experimental/libbox/export.go b/experimental/libbox/export.go
new file mode 100644
index 0000000000..7aa17f6b55
--- /dev/null
+++ b/experimental/libbox/export.go
@@ -0,0 +1,44 @@
+package libbox
+
+import (
+ "context"
+ "math"
+ "runtime/debug"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/service/oomkiller"
+)
+
+func FromContext(ctx context.Context, platformInterface PlatformInterface) context.Context {
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ return baseContextWithParent(ctx, platformInterface)
+}
+
+func WrapPlatformInterface(platformInterface PlatformInterface) adapter.PlatformInterface {
+ if platformInterface == nil {
+ return nil
+ }
+ return &platformInterfaceWrapper{
+ iif: platformInterface,
+ useProcFS: platformInterface.UseProcFS(),
+ }
+}
+
+func SetMemoryLimit(enabled bool) {
+ if !enabled {
+ debug.SetMemoryLimit(math.MaxInt64)
+ return
+ }
+ limit := sOOMMemoryLimit
+ if limit == 0 && C.IsIos {
+ limit = oomkiller.DefaultAppleNetworkExtensionMemoryLimit
+ }
+ if limit > 0 {
+ debug.SetMemoryLimit(limit * 3 / 4)
+ } else {
+ debug.SetMemoryLimit(math.MaxInt64)
+ }
+}
diff --git a/experimental/libbox/internal/oomprofile/builder.go b/experimental/libbox/internal/oomprofile/builder.go
new file mode 100644
index 0000000000..9f95456f26
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/builder.go
@@ -0,0 +1,386 @@
+//go:build darwin || linux || windows
+
+package oomprofile
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+ "time"
+)
+
+const (
+ tagProfile_SampleType = 1
+ tagProfile_Sample = 2
+ tagProfile_Mapping = 3
+ tagProfile_Location = 4
+ tagProfile_Function = 5
+ tagProfile_StringTable = 6
+ tagProfile_TimeNanos = 9
+ tagProfile_PeriodType = 11
+ tagProfile_Period = 12
+ tagProfile_DefaultSampleType = 14
+
+ tagValueType_Type = 1
+ tagValueType_Unit = 2
+
+ tagSample_Location = 1
+ tagSample_Value = 2
+ tagSample_Label = 3
+
+ tagLabel_Key = 1
+ tagLabel_Str = 2
+ tagLabel_Num = 3
+
+ tagMapping_ID = 1
+ tagMapping_Start = 2
+ tagMapping_Limit = 3
+ tagMapping_Offset = 4
+ tagMapping_Filename = 5
+ tagMapping_BuildID = 6
+ tagMapping_HasFunctions = 7
+ tagMapping_HasFilenames = 8
+ tagMapping_HasLineNumbers = 9
+ tagMapping_HasInlineFrames = 10
+
+ tagLocation_ID = 1
+ tagLocation_MappingID = 2
+ tagLocation_Address = 3
+ tagLocation_Line = 4
+
+ tagLine_FunctionID = 1
+ tagLine_Line = 2
+
+ tagFunction_ID = 1
+ tagFunction_Name = 2
+ tagFunction_SystemName = 3
+ tagFunction_Filename = 4
+ tagFunction_StartLine = 5
+)
+
+type memMap struct {
+ start uintptr
+ end uintptr
+ offset uint64
+ file string
+ buildID string
+ funcs symbolizeFlag
+ fake bool
+}
+
+type symbolizeFlag uint8
+
+const (
+ lookupTried symbolizeFlag = 1 << iota
+ lookupFailed
+)
+
+func newProfileBuilder(w io.Writer) *profileBuilder {
+ builder := &profileBuilder{
+ start: time.Now(),
+ w: w,
+ strings: []string{""},
+ stringMap: map[string]int{"": 0},
+ locs: map[uintptr]locInfo{},
+ funcs: map[string]int{},
+ }
+ builder.readMapping()
+ return builder
+}
+
+func (b *profileBuilder) stringIndex(s string) int64 {
+ id, ok := b.stringMap[s]
+ if !ok {
+ id = len(b.strings)
+ b.strings = append(b.strings, s)
+ b.stringMap[s] = id
+ }
+ return int64(id)
+}
+
+func (b *profileBuilder) flush() {
+ const dataFlush = 4096
+ if b.err != nil || b.pb.nest != 0 || len(b.pb.data) <= dataFlush {
+ return
+ }
+
+ _, b.err = b.w.Write(b.pb.data)
+ b.pb.data = b.pb.data[:0]
+}
+
+func (b *profileBuilder) pbValueType(tag int, typ string, unit string) {
+ start := b.pb.startMessage()
+ b.pb.int64(tagValueType_Type, b.stringIndex(typ))
+ b.pb.int64(tagValueType_Unit, b.stringIndex(unit))
+ b.pb.endMessage(tag, start)
+}
+
+func (b *profileBuilder) pbSample(values []int64, locs []uint64, labels func()) {
+ start := b.pb.startMessage()
+ b.pb.int64s(tagSample_Value, values)
+ b.pb.uint64s(tagSample_Location, locs)
+ if labels != nil {
+ labels()
+ }
+ b.pb.endMessage(tagProfile_Sample, start)
+ b.flush()
+}
+
+func (b *profileBuilder) pbLabel(tag int, key string, str string, num int64) {
+ start := b.pb.startMessage()
+ b.pb.int64Opt(tagLabel_Key, b.stringIndex(key))
+ b.pb.int64Opt(tagLabel_Str, b.stringIndex(str))
+ b.pb.int64Opt(tagLabel_Num, num)
+ b.pb.endMessage(tag, start)
+}
+
+func (b *profileBuilder) pbLine(tag int, funcID uint64, line int64) {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagLine_FunctionID, funcID)
+ b.pb.int64Opt(tagLine_Line, line)
+ b.pb.endMessage(tag, start)
+}
+
+func (b *profileBuilder) pbMapping(tag int, id uint64, base uint64, limit uint64, offset uint64, file string, buildID string, hasFuncs bool) {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagMapping_ID, id)
+ b.pb.uint64Opt(tagMapping_Start, base)
+ b.pb.uint64Opt(tagMapping_Limit, limit)
+ b.pb.uint64Opt(tagMapping_Offset, offset)
+ b.pb.int64Opt(tagMapping_Filename, b.stringIndex(file))
+ b.pb.int64Opt(tagMapping_BuildID, b.stringIndex(buildID))
+ if hasFuncs {
+ b.pb.bool(tagMapping_HasFunctions, true)
+ }
+ b.pb.endMessage(tag, start)
+}
+
+func (b *profileBuilder) build() error {
+ if b.err != nil {
+ return b.err
+ }
+
+ b.pb.int64Opt(tagProfile_TimeNanos, b.start.UnixNano())
+ for i, mapping := range b.mem {
+ hasFunctions := mapping.funcs == lookupTried
+ b.pbMapping(tagProfile_Mapping, uint64(i+1), uint64(mapping.start), uint64(mapping.end), mapping.offset, mapping.file, mapping.buildID, hasFunctions)
+ }
+ b.pb.strings(tagProfile_StringTable, b.strings)
+ if b.err != nil {
+ return b.err
+ }
+ _, err := b.w.Write(b.pb.data)
+ return err
+}
+
+func allFrames(addr uintptr) ([]runtime.Frame, symbolizeFlag) {
+ frames := runtime.CallersFrames([]uintptr{addr})
+ frame, more := frames.Next()
+ if frame.Function == "runtime.goexit" {
+ return nil, 0
+ }
+
+ result := lookupTried
+ if frame.PC == 0 || frame.Function == "" || frame.File == "" || frame.Line == 0 {
+ result |= lookupFailed
+ }
+ if frame.PC == 0 {
+ frame.PC = addr - 1
+ }
+
+ ret := []runtime.Frame{frame}
+ for frame.Function != "runtime.goexit" && more {
+ frame, more = frames.Next()
+ ret = append(ret, frame)
+ }
+ return ret, result
+}
+
+type locInfo struct {
+ id uint64
+
+ pcs []uintptr
+
+ firstPCFrames []runtime.Frame
+ firstPCSymbolizeResult symbolizeFlag
+}
+
+func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) []uint64 {
+ b.deck.reset()
+ origStk := stk
+ stk = runtimeExpandFinalInlineFrame(stk)
+
+ for len(stk) > 0 {
+ addr := stk[0]
+ if loc, ok := b.locs[addr]; ok {
+ if len(b.deck.pcs) > 0 {
+ if b.deck.tryAdd(addr, loc.firstPCFrames, loc.firstPCSymbolizeResult) {
+ stk = stk[1:]
+ continue
+ }
+ }
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+ locs = append(locs, loc.id)
+ if len(loc.pcs) > len(stk) {
+ panic(fmt.Sprintf("stack too short to match cached location; stk = %#x, loc.pcs = %#x, original stk = %#x", stk, loc.pcs, origStk))
+ }
+ stk = stk[len(loc.pcs):]
+ continue
+ }
+
+ frames, symbolizeResult := allFrames(addr)
+ if len(frames) == 0 {
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+ stk = stk[1:]
+ continue
+ }
+
+ if b.deck.tryAdd(addr, frames, symbolizeResult) {
+ stk = stk[1:]
+ continue
+ }
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+
+ if loc, ok := b.locs[addr]; ok {
+ locs = append(locs, loc.id)
+ stk = stk[len(loc.pcs):]
+ } else {
+ b.deck.tryAdd(addr, frames, symbolizeResult)
+ stk = stk[1:]
+ }
+ }
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+ return locs
+}
+
+type pcDeck struct {
+ pcs []uintptr
+ frames []runtime.Frame
+ symbolizeResult symbolizeFlag
+
+ firstPCFrames int
+ firstPCSymbolizeResult symbolizeFlag
+}
+
+func (d *pcDeck) reset() {
+ d.pcs = d.pcs[:0]
+ d.frames = d.frames[:0]
+ d.symbolizeResult = 0
+ d.firstPCFrames = 0
+ d.firstPCSymbolizeResult = 0
+}
+
+func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symbolizeFlag) bool {
+ if existing := len(d.frames); existing > 0 {
+ newFrame := frames[0]
+ last := d.frames[existing-1]
+ if last.Func != nil {
+ return false
+ }
+ if last.Entry == 0 || newFrame.Entry == 0 {
+ return false
+ }
+ if last.Entry != newFrame.Entry {
+ return false
+ }
+ if runtimeFrameSymbolName(&last) == runtimeFrameSymbolName(&newFrame) {
+ return false
+ }
+ }
+
+ d.pcs = append(d.pcs, pc)
+ d.frames = append(d.frames, frames...)
+ d.symbolizeResult |= symbolizeResult
+ if len(d.pcs) == 1 {
+ d.firstPCFrames = len(d.frames)
+ d.firstPCSymbolizeResult = symbolizeResult
+ }
+ return true
+}
+
+func (b *profileBuilder) emitLocation() uint64 {
+ if len(b.deck.pcs) == 0 {
+ return 0
+ }
+ defer b.deck.reset()
+
+ addr := b.deck.pcs[0]
+ firstFrame := b.deck.frames[0]
+
+ type newFunc struct {
+ id uint64
+ name string
+ file string
+ startLine int64
+ }
+
+ newFuncs := make([]newFunc, 0, 8)
+ id := uint64(len(b.locs)) + 1
+ b.locs[addr] = locInfo{
+ id: id,
+ pcs: append([]uintptr{}, b.deck.pcs...),
+ firstPCFrames: append([]runtime.Frame{}, b.deck.frames[:b.deck.firstPCFrames]...),
+ firstPCSymbolizeResult: b.deck.firstPCSymbolizeResult,
+ }
+
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagLocation_ID, id)
+ b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC))
+ for _, frame := range b.deck.frames {
+ funcName := runtimeFrameSymbolName(&frame)
+ funcID := uint64(b.funcs[funcName])
+ if funcID == 0 {
+ funcID = uint64(len(b.funcs)) + 1
+ b.funcs[funcName] = int(funcID)
+ newFuncs = append(newFuncs, newFunc{
+ id: funcID,
+ name: funcName,
+ file: frame.File,
+ startLine: int64(runtimeFrameStartLine(&frame)),
+ })
+ }
+ b.pbLine(tagLocation_Line, funcID, int64(frame.Line))
+ }
+ for i := range b.mem {
+ if (b.mem[i].start <= addr && addr < b.mem[i].end) || b.mem[i].fake {
+ b.pb.uint64Opt(tagLocation_MappingID, uint64(i+1))
+ mapping := b.mem[i]
+ mapping.funcs |= b.deck.symbolizeResult
+ b.mem[i] = mapping
+ break
+ }
+ }
+ b.pb.endMessage(tagProfile_Location, start)
+
+ for _, fn := range newFuncs {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagFunction_ID, fn.id)
+ b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name))
+ b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name))
+ b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file))
+ b.pb.int64Opt(tagFunction_StartLine, fn.startLine)
+ b.pb.endMessage(tagProfile_Function, start)
+ }
+
+ b.flush()
+ return id
+}
+
+func (b *profileBuilder) addMappingEntry(lo uint64, hi uint64, offset uint64, file string, buildID string, fake bool) {
+ b.mem = append(b.mem, memMap{
+ start: uintptr(lo),
+ end: uintptr(hi),
+ offset: offset,
+ file: file,
+ buildID: buildID,
+ fake: fake,
+ })
+}
diff --git a/experimental/libbox/internal/oomprofile/defs_darwin_amd64.go b/experimental/libbox/internal/oomprofile/defs_darwin_amd64.go
new file mode 100644
index 0000000000..8a30074ca2
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/defs_darwin_amd64.go
@@ -0,0 +1,24 @@
+//go:build darwin && amd64
+
+package oomprofile
+
+type machVMRegionBasicInfoData struct {
+ Protection int32
+ MaxProtection int32
+ Inheritance uint32
+ Shared uint32
+ Reserved uint32
+ Offset [8]byte
+ Behavior int32
+ UserWiredCount uint16
+ PadCgo1 [2]byte
+}
+
+const (
+ _VM_PROT_READ = 0x1
+ _VM_PROT_EXECUTE = 0x4
+
+ _MACH_SEND_INVALID_DEST = 0x10000003
+
+ _MAXPATHLEN = 0x400
+)
diff --git a/experimental/libbox/internal/oomprofile/defs_darwin_arm64.go b/experimental/libbox/internal/oomprofile/defs_darwin_arm64.go
new file mode 100644
index 0000000000..2fd4659001
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/defs_darwin_arm64.go
@@ -0,0 +1,24 @@
+//go:build darwin && arm64
+
+package oomprofile
+
+type machVMRegionBasicInfoData struct {
+ Protection int32
+ MaxProtection int32
+ Inheritance uint32
+ Shared int32
+ Reserved int32
+ Offset [8]byte
+ Behavior int32
+ UserWiredCount uint16
+ PadCgo1 [2]byte
+}
+
+const (
+ _VM_PROT_READ = 0x1
+ _VM_PROT_EXECUTE = 0x4
+
+ _MACH_SEND_INVALID_DEST = 0x10000003
+
+ _MAXPATHLEN = 0x400
+)
diff --git a/experimental/libbox/internal/oomprofile/linkname.go b/experimental/libbox/internal/oomprofile/linkname.go
new file mode 100644
index 0000000000..f7ab271798
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/linkname.go
@@ -0,0 +1,46 @@
+//go:build darwin || linux || windows
+
+package oomprofile
+
+import (
+ "runtime"
+ _ "runtime/pprof"
+ "unsafe"
+ _ "unsafe"
+)
+
+//go:linkname runtimeMemProfileInternal runtime.pprof_memProfileInternal
+func runtimeMemProfileInternal(p []memProfileRecord, inuseZero bool) (n int, ok bool)
+
+//go:linkname runtimeBlockProfileInternal runtime.pprof_blockProfileInternal
+func runtimeBlockProfileInternal(p []blockProfileRecord) (n int, ok bool)
+
+//go:linkname runtimeMutexProfileInternal runtime.pprof_mutexProfileInternal
+func runtimeMutexProfileInternal(p []blockProfileRecord) (n int, ok bool)
+
+//go:linkname runtimeThreadCreateInternal runtime.pprof_threadCreateInternal
+func runtimeThreadCreateInternal(p []stackRecord) (n int, ok bool)
+
+//go:linkname runtimeGoroutineProfileWithLabels runtime.pprof_goroutineProfileWithLabels
+func runtimeGoroutineProfileWithLabels(p []stackRecord, labels []unsafe.Pointer) (n int, ok bool)
+
+//go:linkname runtimeCyclesPerSecond runtime/pprof.runtime_cyclesPerSecond
+func runtimeCyclesPerSecond() int64
+
+//go:linkname runtimeMakeProfStack runtime.pprof_makeProfStack
+func runtimeMakeProfStack() []uintptr
+
+//go:linkname runtimeFrameStartLine runtime/pprof.runtime_FrameStartLine
+func runtimeFrameStartLine(f *runtime.Frame) int
+
+//go:linkname runtimeFrameSymbolName runtime/pprof.runtime_FrameSymbolName
+func runtimeFrameSymbolName(f *runtime.Frame) string
+
+//go:linkname runtimeExpandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
+func runtimeExpandFinalInlineFrame(stk []uintptr) []uintptr
+
+//go:linkname stdParseProcSelfMaps runtime/pprof.parseProcSelfMaps
+func stdParseProcSelfMaps(data []byte, addMapping func(lo uint64, hi uint64, offset uint64, file string, buildID string))
+
+//go:linkname stdELFBuildID runtime/pprof.elfBuildID
+func stdELFBuildID(file string) (string, error)
diff --git a/experimental/libbox/internal/oomprofile/mapping_darwin.go b/experimental/libbox/internal/oomprofile/mapping_darwin.go
new file mode 100644
index 0000000000..a686a04857
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/mapping_darwin.go
@@ -0,0 +1,59 @@
+//go:build darwin
+
+package oomprofile
+
+import (
+ "encoding/binary"
+ "os"
+ "unsafe"
+ _ "unsafe"
+)
+
+func isExecutable(protection int32) bool {
+ return (protection&_VM_PROT_EXECUTE) != 0 && (protection&_VM_PROT_READ) != 0
+}
+
+func (b *profileBuilder) readMapping() {
+ added := machVMInfo(func(lo, hi, offset uint64, file, buildID string) {
+ b.addMappingEntry(lo, hi, offset, file, buildID, false)
+ })
+ if !added {
+ b.addMappingEntry(0, 0, 0, "", "", true)
+ }
+}
+
+func machVMInfo(addMapping func(lo uint64, hi uint64, off uint64, file string, buildID string)) bool {
+ added := false
+ addr := uint64(0x1)
+ for {
+ var regionSize uint64
+ var info machVMRegionBasicInfoData
+ kr := machVMRegion(&addr, ®ionSize, unsafe.Pointer(&info))
+ if kr != 0 {
+ if kr == _MACH_SEND_INVALID_DEST {
+ return true
+ }
+ return added
+ }
+ if isExecutable(info.Protection) {
+ addMapping(addr, addr+regionSize, binary.LittleEndian.Uint64(info.Offset[:]), regionFilename(addr), "")
+ added = true
+ }
+ addr += regionSize
+ }
+}
+
+func regionFilename(address uint64) string {
+ buf := make([]byte, _MAXPATHLEN)
+ n := procRegionFilename(os.Getpid(), address, unsafe.SliceData(buf), int64(cap(buf)))
+ if n == 0 {
+ return ""
+ }
+ return string(buf[:n])
+}
+
+//go:linkname machVMRegion runtime/pprof.mach_vm_region
+func machVMRegion(address *uint64, regionSize *uint64, info unsafe.Pointer) int32
+
+//go:linkname procRegionFilename runtime/pprof.proc_regionfilename
+func procRegionFilename(pid int, address uint64, buf *byte, buflen int64) int32
diff --git a/experimental/libbox/internal/oomprofile/mapping_linux.go b/experimental/libbox/internal/oomprofile/mapping_linux.go
new file mode 100644
index 0000000000..ddb2eaaaba
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/mapping_linux.go
@@ -0,0 +1,15 @@
+//go:build linux
+
+package oomprofile
+
+import "os"
+
+func (b *profileBuilder) readMapping() {
+ data, _ := os.ReadFile("/proc/self/maps")
+ stdParseProcSelfMaps(data, func(lo, hi, offset uint64, file, buildID string) {
+ b.addMappingEntry(lo, hi, offset, file, buildID, false)
+ })
+ if len(b.mem) == 0 {
+ b.addMappingEntry(0, 0, 0, "", "", true)
+ }
+}
diff --git a/experimental/libbox/internal/oomprofile/mapping_windows.go b/experimental/libbox/internal/oomprofile/mapping_windows.go
new file mode 100644
index 0000000000..68303d895d
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/mapping_windows.go
@@ -0,0 +1,58 @@
+//go:build windows
+
+package oomprofile
+
+import (
+ "errors"
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+func (b *profileBuilder) readMapping() {
+ snapshot, err := createModuleSnapshot()
+ if err != nil {
+ b.addMappingEntry(0, 0, 0, "", "", true)
+ return
+ }
+ defer windows.CloseHandle(snapshot)
+
+ var module windows.ModuleEntry32
+ module.Size = uint32(windows.SizeofModuleEntry32)
+ err = windows.Module32First(snapshot, &module)
+ if err != nil {
+ b.addMappingEntry(0, 0, 0, "", "", true)
+ return
+ }
+ for err == nil {
+ exe := windows.UTF16ToString(module.ExePath[:])
+ b.addMappingEntry(
+ uint64(module.ModBaseAddr),
+ uint64(module.ModBaseAddr)+uint64(module.ModBaseSize),
+ 0,
+ exe,
+ peBuildID(exe),
+ false,
+ )
+ err = windows.Module32Next(snapshot, &module)
+ }
+}
+
+func createModuleSnapshot() (windows.Handle, error) {
+ for {
+ snapshot, err := windows.CreateToolhelp32Snapshot(windows.TH32CS_SNAPMODULE|windows.TH32CS_SNAPMODULE32, uint32(windows.GetCurrentProcessId()))
+ var errno windows.Errno
+ if err != nil && errors.As(err, &errno) && errno == windows.ERROR_BAD_LENGTH {
+ continue
+ }
+ return snapshot, err
+ }
+}
+
+func peBuildID(file string) string {
+ info, err := os.Stat(file)
+ if err != nil {
+ return file
+ }
+ return file + info.ModTime().String()
+}
diff --git a/experimental/libbox/internal/oomprofile/oomprofile.go b/experimental/libbox/internal/oomprofile/oomprofile.go
new file mode 100644
index 0000000000..0728af8f47
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/oomprofile.go
@@ -0,0 +1,383 @@
+//go:build darwin || linux || windows
+
+package oomprofile
+
+import (
+ "fmt"
+ "io"
+ "math"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strings"
+ "time"
+ "unsafe"
+)
+
+type stackRecord struct {
+ Stack []uintptr
+}
+
+type memProfileRecord struct {
+ AllocBytes, FreeBytes int64
+ AllocObjects, FreeObjects int64
+ Stack []uintptr
+}
+
+func (r *memProfileRecord) InUseBytes() int64 {
+ return r.AllocBytes - r.FreeBytes
+}
+
+func (r *memProfileRecord) InUseObjects() int64 {
+ return r.AllocObjects - r.FreeObjects
+}
+
+type blockProfileRecord struct {
+ Count int64
+ Cycles int64
+ Stack []uintptr
+}
+
+type label struct {
+ key string
+ value string
+}
+
+type labelSet struct {
+ list []label
+}
+
+type labelMap struct {
+ labelSet
+}
+
+func WriteFile(destPath string, name string) (string, error) {
+ writer, ok := profileWriters[name]
+ if !ok {
+ return "", fmt.Errorf("unsupported profile %q", name)
+ }
+
+ filePath := filepath.Join(destPath, name+".pb")
+ file, err := os.Create(filePath)
+ if err != nil {
+ return "", err
+ }
+ defer file.Close()
+
+ if err := writer(file); err != nil {
+ _ = os.Remove(filePath)
+ return "", err
+ }
+ if err := file.Close(); err != nil {
+ _ = os.Remove(filePath)
+ return "", err
+ }
+ return filePath, nil
+}
+
+var profileWriters = map[string]func(io.Writer) error{
+ "allocs": writeAlloc,
+ "block": writeBlock,
+ "goroutine": writeGoroutine,
+ "heap": writeHeap,
+ "mutex": writeMutex,
+ "threadcreate": writeThreadCreate,
+}
+
+func writeHeap(w io.Writer) error {
+ return writeHeapInternal(w, "")
+}
+
+func writeAlloc(w io.Writer) error {
+ return writeHeapInternal(w, "alloc_space")
+}
+
+func writeHeapInternal(w io.Writer, defaultSampleType string) error {
+ var profile []memProfileRecord
+ n, _ := runtimeMemProfileInternal(nil, true)
+ var ok bool
+ for {
+ profile = make([]memProfileRecord, n+50)
+ n, ok = runtimeMemProfileInternal(profile, true)
+ if ok {
+ profile = profile[:n]
+ break
+ }
+ }
+ return writeHeapProto(w, profile, int64(runtime.MemProfileRate), defaultSampleType)
+}
+
+func writeGoroutine(w io.Writer) error {
+ return writeRuntimeProfile(w, "goroutine", runtimeGoroutineProfileWithLabels)
+}
+
+func writeThreadCreate(w io.Writer) error {
+ return writeRuntimeProfile(w, "threadcreate", func(p []stackRecord, _ []unsafe.Pointer) (int, bool) {
+ return runtimeThreadCreateInternal(p)
+ })
+}
+
+func writeRuntimeProfile(w io.Writer, name string, fetch func([]stackRecord, []unsafe.Pointer) (int, bool)) error {
+ var profile []stackRecord
+ var labels []unsafe.Pointer
+
+ n, _ := fetch(nil, nil)
+ var ok bool
+ for {
+ profile = make([]stackRecord, n+10)
+ labels = make([]unsafe.Pointer, n+10)
+ n, ok = fetch(profile, labels)
+ if ok {
+ profile = profile[:n]
+ labels = labels[:n]
+ break
+ }
+ }
+
+ return writeCountProfile(w, name, &runtimeProfile{profile, labels})
+}
+
+func writeBlock(w io.Writer) error {
+ return writeCycleProfile(w, "contentions", "delay", runtimeBlockProfileInternal)
+}
+
+func writeMutex(w io.Writer) error {
+ return writeCycleProfile(w, "contentions", "delay", runtimeMutexProfileInternal)
+}
+
+func writeCycleProfile(w io.Writer, countName string, cycleName string, fetch func([]blockProfileRecord) (int, bool)) error {
+ var profile []blockProfileRecord
+ n, _ := fetch(nil)
+ var ok bool
+ for {
+ profile = make([]blockProfileRecord, n+50)
+ n, ok = fetch(profile)
+ if ok {
+ profile = profile[:n]
+ break
+ }
+ }
+
+ sort.Slice(profile, func(i, j int) bool {
+ return profile[i].Cycles > profile[j].Cycles
+ })
+
+ builder := newProfileBuilder(w)
+ builder.pbValueType(tagProfile_PeriodType, countName, "count")
+ builder.pb.int64Opt(tagProfile_Period, 1)
+ builder.pbValueType(tagProfile_SampleType, countName, "count")
+ builder.pbValueType(tagProfile_SampleType, cycleName, "nanoseconds")
+
+ cpuGHz := float64(runtimeCyclesPerSecond()) / 1e9
+ values := []int64{0, 0}
+ var locs []uint64
+ expandedStack := runtimeMakeProfStack()
+ for _, record := range profile {
+ values[0] = record.Count
+ if cpuGHz > 0 {
+ values[1] = int64(float64(record.Cycles) / cpuGHz)
+ } else {
+ values[1] = 0
+ }
+ n := expandInlinedFrames(expandedStack, record.Stack)
+ locs = builder.appendLocsForStack(locs[:0], expandedStack[:n])
+ builder.pbSample(values, locs, nil)
+ }
+
+ return builder.build()
+}
+
+type countProfile interface {
+ Len() int
+ Stack(i int) []uintptr
+ Label(i int) *labelMap
+}
+
+type runtimeProfile struct {
+ stk []stackRecord
+ labels []unsafe.Pointer
+}
+
+func (p *runtimeProfile) Len() int {
+ return len(p.stk)
+}
+
+func (p *runtimeProfile) Stack(i int) []uintptr {
+ return p.stk[i].Stack
+}
+
+func (p *runtimeProfile) Label(i int) *labelMap {
+ return (*labelMap)(p.labels[i])
+}
+
+func writeCountProfile(w io.Writer, name string, profile countProfile) error {
+ var buf strings.Builder
+ key := func(stk []uintptr, labels *labelMap) string {
+ buf.Reset()
+ buf.WriteByte('@')
+ for _, pc := range stk {
+ fmt.Fprintf(&buf, " %#x", pc)
+ }
+ if labels != nil {
+ buf.WriteString("\n# labels:")
+ for _, label := range labels.list {
+ fmt.Fprintf(&buf, " %q:%q", label.key, label.value)
+ }
+ }
+ return buf.String()
+ }
+
+ counts := make(map[string]int)
+ index := make(map[string]int)
+ var keys []string
+ for i := 0; i < profile.Len(); i++ {
+ k := key(profile.Stack(i), profile.Label(i))
+ if counts[k] == 0 {
+ index[k] = i
+ keys = append(keys, k)
+ }
+ counts[k]++
+ }
+
+ sort.Sort(&keysByCount{keys: keys, count: counts})
+
+ builder := newProfileBuilder(w)
+ builder.pbValueType(tagProfile_PeriodType, name, "count")
+ builder.pb.int64Opt(tagProfile_Period, 1)
+ builder.pbValueType(tagProfile_SampleType, name, "count")
+
+ values := []int64{0}
+ var locs []uint64
+ for _, k := range keys {
+ values[0] = int64(counts[k])
+ idx := index[k]
+ locs = builder.appendLocsForStack(locs[:0], profile.Stack(idx))
+
+ var labels func()
+ if profile.Label(idx) != nil {
+ labels = func() {
+ for _, label := range profile.Label(idx).list {
+ builder.pbLabel(tagSample_Label, label.key, label.value, 0)
+ }
+ }
+ }
+ builder.pbSample(values, locs, labels)
+ }
+
+ return builder.build()
+}
+
+type keysByCount struct {
+ keys []string
+ count map[string]int
+}
+
+func (x *keysByCount) Len() int {
+ return len(x.keys)
+}
+
+func (x *keysByCount) Swap(i int, j int) {
+ x.keys[i], x.keys[j] = x.keys[j], x.keys[i]
+}
+
+func (x *keysByCount) Less(i int, j int) bool {
+ ki, kj := x.keys[i], x.keys[j]
+ ci, cj := x.count[ki], x.count[kj]
+ if ci != cj {
+ return ci > cj
+ }
+ return ki < kj
+}
+
+func expandInlinedFrames(dst []uintptr, pcs []uintptr) int {
+ frames := runtime.CallersFrames(pcs)
+ var n int
+ for n < len(dst) {
+ frame, more := frames.Next()
+ dst[n] = frame.PC + 1
+ n++
+ if !more {
+ break
+ }
+ }
+ return n
+}
+
+func writeHeapProto(w io.Writer, profile []memProfileRecord, rate int64, defaultSampleType string) error {
+ builder := newProfileBuilder(w)
+ builder.pbValueType(tagProfile_PeriodType, "space", "bytes")
+ builder.pb.int64Opt(tagProfile_Period, rate)
+ builder.pbValueType(tagProfile_SampleType, "alloc_objects", "count")
+ builder.pbValueType(tagProfile_SampleType, "alloc_space", "bytes")
+ builder.pbValueType(tagProfile_SampleType, "inuse_objects", "count")
+ builder.pbValueType(tagProfile_SampleType, "inuse_space", "bytes")
+ if defaultSampleType != "" {
+ builder.pb.int64Opt(tagProfile_DefaultSampleType, builder.stringIndex(defaultSampleType))
+ }
+
+ values := []int64{0, 0, 0, 0}
+ var locs []uint64
+ for _, record := range profile {
+ hideRuntime := true
+ for range 2 {
+ stk := record.Stack
+ if hideRuntime {
+ for i, addr := range stk {
+ if f := runtime.FuncForPC(addr); f != nil && (strings.HasPrefix(f.Name(), "runtime.") || strings.HasPrefix(f.Name(), "internal/runtime/")) {
+ continue
+ }
+ stk = stk[i:]
+ break
+ }
+ }
+ locs = builder.appendLocsForStack(locs[:0], stk)
+ if len(locs) > 0 {
+ break
+ }
+ hideRuntime = false
+ }
+
+ values[0], values[1] = scaleHeapSample(record.AllocObjects, record.AllocBytes, rate)
+ values[2], values[3] = scaleHeapSample(record.InUseObjects(), record.InUseBytes(), rate)
+
+ var blockSize int64
+ if record.AllocObjects > 0 {
+ blockSize = record.AllocBytes / record.AllocObjects
+ }
+ builder.pbSample(values, locs, func() {
+ if blockSize != 0 {
+ builder.pbLabel(tagSample_Label, "bytes", "", blockSize)
+ }
+ })
+ }
+
+ return builder.build()
+}
+
+func scaleHeapSample(count int64, size int64, rate int64) (int64, int64) {
+ if count == 0 || size == 0 {
+ return 0, 0
+ }
+ if rate <= 1 {
+ return count, size
+ }
+
+ avgSize := float64(size) / float64(count)
+ scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))
+ return int64(float64(count) * scale), int64(float64(size) * scale)
+}
+
+type profileBuilder struct {
+ start time.Time
+ w io.Writer
+ err error
+
+ pb protobuf
+ strings []string
+ stringMap map[string]int
+ locs map[uintptr]locInfo
+ funcs map[string]int
+ mem []memMap
+ deck pcDeck
+}
diff --git a/experimental/libbox/internal/oomprofile/protobuf.go b/experimental/libbox/internal/oomprofile/protobuf.go
new file mode 100644
index 0000000000..ed60df21c2
--- /dev/null
+++ b/experimental/libbox/internal/oomprofile/protobuf.go
@@ -0,0 +1,120 @@
+//go:build darwin || linux || windows
+
+package oomprofile
+
+type protobuf struct {
+ data []byte
+ tmp [16]byte
+ nest int
+}
+
+func (b *protobuf) varint(x uint64) {
+ for x >= 128 {
+ b.data = append(b.data, byte(x)|0x80)
+ x >>= 7
+ }
+ b.data = append(b.data, byte(x))
+}
+
+func (b *protobuf) length(tag int, length int) {
+ b.varint(uint64(tag)<<3 | 2)
+ b.varint(uint64(length))
+}
+
+func (b *protobuf) uint64(tag int, x uint64) {
+ b.varint(uint64(tag) << 3)
+ b.varint(x)
+}
+
+func (b *protobuf) uint64s(tag int, x []uint64) {
+ if len(x) > 2 {
+ n1 := len(b.data)
+ for _, u := range x {
+ b.varint(u)
+ }
+ n2 := len(b.data)
+ b.length(tag, n2-n1)
+ n3 := len(b.data)
+ copy(b.tmp[:], b.data[n2:n3])
+ copy(b.data[n1+(n3-n2):], b.data[n1:n2])
+ copy(b.data[n1:], b.tmp[:n3-n2])
+ return
+ }
+ for _, u := range x {
+ b.uint64(tag, u)
+ }
+}
+
+func (b *protobuf) uint64Opt(tag int, x uint64) {
+ if x == 0 {
+ return
+ }
+ b.uint64(tag, x)
+}
+
+func (b *protobuf) int64(tag int, x int64) {
+ b.uint64(tag, uint64(x))
+}
+
+func (b *protobuf) int64Opt(tag int, x int64) {
+ if x == 0 {
+ return
+ }
+ b.int64(tag, x)
+}
+
+func (b *protobuf) int64s(tag int, x []int64) {
+ if len(x) > 2 {
+ n1 := len(b.data)
+ for _, u := range x {
+ b.varint(uint64(u))
+ }
+ n2 := len(b.data)
+ b.length(tag, n2-n1)
+ n3 := len(b.data)
+ copy(b.tmp[:], b.data[n2:n3])
+ copy(b.data[n1+(n3-n2):], b.data[n1:n2])
+ copy(b.data[n1:], b.tmp[:n3-n2])
+ return
+ }
+ for _, u := range x {
+ b.int64(tag, u)
+ }
+}
+
+func (b *protobuf) bool(tag int, x bool) {
+ if x {
+ b.uint64(tag, 1)
+ } else {
+ b.uint64(tag, 0)
+ }
+}
+
+func (b *protobuf) string(tag int, x string) {
+ b.length(tag, len(x))
+ b.data = append(b.data, x...)
+}
+
+func (b *protobuf) strings(tag int, x []string) {
+ for _, s := range x {
+ b.string(tag, s)
+ }
+}
+
+type msgOffset int
+
+func (b *protobuf) startMessage() msgOffset {
+ b.nest++
+ return msgOffset(len(b.data))
+}
+
+func (b *protobuf) endMessage(tag int, start msgOffset) {
+ n1 := int(start)
+ n2 := len(b.data)
+ b.length(tag, n2-n1)
+ n3 := len(b.data)
+ copy(b.tmp[:], b.data[n2:n3])
+ copy(b.data[n1+(n3-n2):], b.data[n1:n2])
+ copy(b.data[n1:], b.tmp[:n3-n2])
+ b.nest--
+}
diff --git a/experimental/libbox/log.go b/experimental/libbox/log.go
index aa12f8f29d..9a3ebf707f 100644
--- a/experimental/libbox/log.go
+++ b/experimental/libbox/log.go
@@ -1,22 +1,80 @@
-//go:build darwin || linux
+//go:build darwin || linux || windows
package libbox
import (
+ "archive/zip"
+ "io"
+ "io/fs"
"os"
+ "path/filepath"
"runtime"
"runtime/debug"
+ "time"
)
-func RedirectStderr(path string) error {
- if stats, err := os.Stat(path); err == nil && stats.Size() > 0 {
- _ = os.Rename(path, path+".old")
+type crashReportMetadata struct {
+ reportMetadata
+ CrashedAt string `json:"crashedAt,omitempty"`
+ SignalName string `json:"signalName,omitempty"`
+ SignalCode string `json:"signalCode,omitempty"`
+ ExceptionName string `json:"exceptionName,omitempty"`
+ ExceptionReason string `json:"exceptionReason,omitempty"`
+}
+
+func archiveCrashReport(path string, crashReportsDir string) {
+ content, err := os.ReadFile(path)
+ if err != nil || len(content) == 0 {
+ return
+ }
+
+ info, _ := os.Stat(path)
+ crashTime := time.Now().UTC()
+ if info != nil {
+ crashTime = info.ModTime().UTC()
}
+
+ initReportDir(crashReportsDir)
+ destPath, err := nextAvailableReportPath(crashReportsDir, crashTime)
+ if err != nil {
+ return
+ }
+ initReportDir(destPath)
+
+ writeReportFile(destPath, "go.log", content)
+ metadata := crashReportMetadata{
+ reportMetadata: baseReportMetadata(),
+ CrashedAt: crashTime.Format(time.RFC3339),
+ }
+ writeReportMetadata(destPath, metadata)
+ os.Remove(path)
+ copyConfigSnapshot(destPath)
+}
+
+func configSnapshotPath() string {
+ return filepath.Join(sBasePath, "configuration.json")
+}
+
+func saveConfigSnapshot(configContent string) {
+ snapshotPath := configSnapshotPath()
+ os.WriteFile(snapshotPath, []byte(configContent), 0o666)
+ chownReport(snapshotPath)
+}
+
+func RedirectStderr(path string) error {
+ return redirectStderr(path)
+}
+
+func redirectStderr(path string) error {
+ crashReportsDir := filepath.Join(sWorkingPath, "crash_reports")
+ archiveCrashReport(path, crashReportsDir)
+ archiveCrashReport(path+".old", crashReportsDir)
+
outputFile, err := os.Create(path)
if err != nil {
return err
}
- if runtime.GOOS != "android" {
+ if runtime.GOOS != "android" && runtime.GOOS != "windows" {
err = outputFile.Chown(sUserID, sGroupID)
if err != nil {
outputFile.Close()
@@ -24,11 +82,88 @@ func RedirectStderr(path string) error {
return err
}
}
+
err = debug.SetCrashOutput(outputFile, debug.CrashOptions{})
if err != nil {
outputFile.Close()
os.Remove(outputFile.Name())
return err
}
- return outputFile.Close()
+ _ = outputFile.Close()
+ return nil
+}
+
+func CreateZipArchive(sourcePath string, destinationPath string) error {
+ sourceInfo, err := os.Stat(sourcePath)
+ if err != nil {
+ return err
+ }
+ if !sourceInfo.IsDir() {
+ return os.ErrInvalid
+ }
+
+ destinationFile, err := os.Create(destinationPath)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ _ = destinationFile.Close()
+ }()
+
+ zipWriter := zip.NewWriter(destinationFile)
+
+ rootName := filepath.Base(sourcePath)
+ err = filepath.WalkDir(sourcePath, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+
+ relativePath, err := filepath.Rel(sourcePath, path)
+ if err != nil {
+ return err
+ }
+ if relativePath == "." {
+ return nil
+ }
+
+ archivePath := filepath.ToSlash(filepath.Join(rootName, relativePath))
+ if d.IsDir() {
+ _, err = zipWriter.Create(archivePath + "/")
+ return err
+ }
+
+ fileInfo, err := d.Info()
+ if err != nil {
+ return err
+ }
+ header, err := zip.FileInfoHeader(fileInfo)
+ if err != nil {
+ return err
+ }
+ header.Name = archivePath
+ header.Method = zip.Deflate
+
+ writer, err := zipWriter.CreateHeader(header)
+ if err != nil {
+ return err
+ }
+
+ sourceFile, err := os.Open(path)
+ if err != nil {
+ return err
+ }
+
+ _, err = io.Copy(writer, sourceFile)
+ closeErr := sourceFile.Close()
+ if err != nil {
+ return err
+ }
+ return closeErr
+ })
+ if err != nil {
+ _ = zipWriter.Close()
+ return err
+ }
+
+ return zipWriter.Close()
}
diff --git a/experimental/libbox/memory.go b/experimental/libbox/memory.go
deleted file mode 100644
index b0b87f73f9..0000000000
--- a/experimental/libbox/memory.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package libbox
-
-import (
- "math"
- runtimeDebug "runtime/debug"
-
- C "github.com/sagernet/sing-box/constant"
-)
-
-var memoryLimitEnabled bool
-
-func SetMemoryLimit(enabled bool) {
- memoryLimitEnabled = enabled
- const memoryLimitGo = 45 * 1024 * 1024
- if enabled {
- runtimeDebug.SetGCPercent(10)
- if C.IsIos {
- runtimeDebug.SetMemoryLimit(memoryLimitGo)
- }
- } else {
- runtimeDebug.SetGCPercent(100)
- if C.IsIos {
- runtimeDebug.SetMemoryLimit(math.MaxInt64)
- }
- }
-}
diff --git a/experimental/libbox/neighbor.go b/experimental/libbox/neighbor.go
new file mode 100644
index 0000000000..b5cbe77962
--- /dev/null
+++ b/experimental/libbox/neighbor.go
@@ -0,0 +1,20 @@
+package libbox
+
+type NeighborEntry struct {
+ Address string
+ MacAddress string
+ Hostname string
+}
+
+type NeighborEntryIterator interface {
+ Next() *NeighborEntry
+ HasNext() bool
+}
+
+type NeighborSubscription struct {
+ done chan struct{}
+}
+
+func (s *NeighborSubscription) Close() {
+ close(s.done)
+}
diff --git a/experimental/libbox/neighbor_darwin.go b/experimental/libbox/neighbor_darwin.go
new file mode 100644
index 0000000000..d7484a69b4
--- /dev/null
+++ b/experimental/libbox/neighbor_darwin.go
@@ -0,0 +1,123 @@
+//go:build darwin
+
+package libbox
+
+import (
+ "net"
+ "net/netip"
+ "os"
+ "slices"
+ "time"
+
+ "github.com/sagernet/sing-box/route"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ xroute "golang.org/x/net/route"
+ "golang.org/x/sys/unix"
+)
+
+func SubscribeNeighborTable(listener NeighborUpdateListener) (*NeighborSubscription, error) {
+ entries, err := route.ReadNeighborEntries()
+ if err != nil {
+ return nil, E.Cause(err, "initial neighbor dump")
+ }
+ table := make(map[netip.Addr]net.HardwareAddr)
+ for _, entry := range entries {
+ table[entry.Address] = entry.MACAddress
+ }
+ listener.UpdateNeighborTable(tableToIterator(table))
+ routeSocket, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0)
+ if err != nil {
+ return nil, E.Cause(err, "open route socket")
+ }
+ err = unix.SetNonblock(routeSocket, true)
+ if err != nil {
+ unix.Close(routeSocket)
+ return nil, E.Cause(err, "set route socket nonblock")
+ }
+ subscription := &NeighborSubscription{
+ done: make(chan struct{}),
+ }
+ go subscription.loop(listener, routeSocket, table)
+ return subscription, nil
+}
+
+func (s *NeighborSubscription) loop(listener NeighborUpdateListener, routeSocket int, table map[netip.Addr]net.HardwareAddr) {
+ routeSocketFile := os.NewFile(uintptr(routeSocket), "route")
+ defer routeSocketFile.Close()
+ buffer := buf.NewPacket()
+ defer buffer.Release()
+ for {
+ select {
+ case <-s.done:
+ return
+ default:
+ }
+ tv := unix.NsecToTimeval(int64(3 * time.Second))
+ _ = unix.SetsockoptTimeval(routeSocket, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &tv)
+ n, err := routeSocketFile.Read(buffer.FreeBytes())
+ if err != nil {
+ if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
+ continue
+ }
+ select {
+ case <-s.done:
+ return
+ default:
+ }
+ continue
+ }
+ messages, err := xroute.ParseRIB(xroute.RIBTypeRoute, buffer.FreeBytes()[:n])
+ if err != nil {
+ continue
+ }
+ changed := false
+ for _, message := range messages {
+ routeMessage, isRouteMessage := message.(*xroute.RouteMessage)
+ if !isRouteMessage {
+ continue
+ }
+ if routeMessage.Flags&unix.RTF_LLINFO == 0 {
+ continue
+ }
+ address, mac, isDelete, ok := route.ParseRouteNeighborMessage(routeMessage)
+ if !ok {
+ continue
+ }
+ if isDelete {
+ if _, exists := table[address]; exists {
+ delete(table, address)
+ changed = true
+ }
+ } else {
+ existing, exists := table[address]
+ if !exists || !slices.Equal(existing, mac) {
+ table[address] = mac
+ changed = true
+ }
+ }
+ }
+ if changed {
+ listener.UpdateNeighborTable(tableToIterator(table))
+ }
+ }
+}
+
+func ReadBootpdLeases() NeighborEntryIterator {
+ leaseIPToMAC, ipToHostname, macToHostname := route.ReloadLeaseFiles([]string{"/var/db/dhcpd_leases"})
+ entries := make([]*NeighborEntry, 0, len(leaseIPToMAC))
+ for address, mac := range leaseIPToMAC {
+ entry := &NeighborEntry{
+ Address: address.String(),
+ MacAddress: mac.String(),
+ }
+ hostname, found := ipToHostname[address]
+ if !found {
+ hostname = macToHostname[mac.String()]
+ }
+ entry.Hostname = hostname
+ entries = append(entries, entry)
+ }
+ return &neighborEntryIterator{entries}
+}
diff --git a/experimental/libbox/neighbor_linux.go b/experimental/libbox/neighbor_linux.go
new file mode 100644
index 0000000000..ae10bdd2ee
--- /dev/null
+++ b/experimental/libbox/neighbor_linux.go
@@ -0,0 +1,88 @@
+//go:build linux
+
+package libbox
+
+import (
+ "net"
+ "net/netip"
+ "slices"
+ "time"
+
+ "github.com/sagernet/sing-box/route"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "github.com/mdlayher/netlink"
+ "golang.org/x/sys/unix"
+)
+
+func SubscribeNeighborTable(listener NeighborUpdateListener) (*NeighborSubscription, error) {
+ entries, err := route.ReadNeighborEntries()
+ if err != nil {
+ return nil, E.Cause(err, "initial neighbor dump")
+ }
+ table := make(map[netip.Addr]net.HardwareAddr)
+ for _, entry := range entries {
+ table[entry.Address] = entry.MACAddress
+ }
+ listener.UpdateNeighborTable(tableToIterator(table))
+ connection, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{
+ Groups: 1 << (unix.RTNLGRP_NEIGH - 1),
+ })
+ if err != nil {
+ return nil, E.Cause(err, "subscribe neighbor updates")
+ }
+ subscription := &NeighborSubscription{
+ done: make(chan struct{}),
+ }
+ go subscription.loop(listener, connection, table)
+ return subscription, nil
+}
+
+func (s *NeighborSubscription) loop(listener NeighborUpdateListener, connection *netlink.Conn, table map[netip.Addr]net.HardwareAddr) {
+ defer connection.Close()
+ for {
+ select {
+ case <-s.done:
+ return
+ default:
+ }
+ err := connection.SetReadDeadline(time.Now().Add(3 * time.Second))
+ if err != nil {
+ return
+ }
+ messages, err := connection.Receive()
+ if err != nil {
+ if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
+ continue
+ }
+ select {
+ case <-s.done:
+ return
+ default:
+ }
+ continue
+ }
+ changed := false
+ for _, message := range messages {
+ address, mac, isDelete, ok := route.ParseNeighborMessage(message)
+ if !ok {
+ continue
+ }
+ if isDelete {
+ if _, exists := table[address]; exists {
+ delete(table, address)
+ changed = true
+ }
+ } else {
+ existing, exists := table[address]
+ if !exists || !slices.Equal(existing, mac) {
+ table[address] = mac
+ changed = true
+ }
+ }
+ }
+ if changed {
+ listener.UpdateNeighborTable(tableToIterator(table))
+ }
+ }
+}
diff --git a/experimental/libbox/neighbor_stub.go b/experimental/libbox/neighbor_stub.go
new file mode 100644
index 0000000000..d465bc7bb0
--- /dev/null
+++ b/experimental/libbox/neighbor_stub.go
@@ -0,0 +1,9 @@
+//go:build !linux && !darwin
+
+package libbox
+
+import "os"
+
+func SubscribeNeighborTable(_ NeighborUpdateListener) (*NeighborSubscription, error) {
+ return nil, os.ErrInvalid
+}
diff --git a/experimental/libbox/neighbor_unix.go b/experimental/libbox/neighbor_unix.go
new file mode 100644
index 0000000000..c854d0f9a6
--- /dev/null
+++ b/experimental/libbox/neighbor_unix.go
@@ -0,0 +1,36 @@
+//go:build linux || darwin
+
+package libbox
+
+import (
+ "net"
+ "net/netip"
+)
+
+func tableToIterator(table map[netip.Addr]net.HardwareAddr) NeighborEntryIterator {
+ entries := make([]*NeighborEntry, 0, len(table))
+ for address, mac := range table {
+ entries = append(entries, &NeighborEntry{
+ Address: address.String(),
+ MacAddress: mac.String(),
+ })
+ }
+ return &neighborEntryIterator{entries}
+}
+
+type neighborEntryIterator struct {
+ entries []*NeighborEntry
+}
+
+func (i *neighborEntryIterator) HasNext() bool {
+ return len(i.entries) > 0
+}
+
+func (i *neighborEntryIterator) Next() *NeighborEntry {
+ if len(i.entries) == 0 {
+ return nil
+ }
+ entry := i.entries[0]
+ i.entries = i.entries[1:]
+ return entry
+}
diff --git a/experimental/libbox/networkquality.go b/experimental/libbox/networkquality.go
new file mode 100644
index 0000000000..fcbe6f3a66
--- /dev/null
+++ b/experimental/libbox/networkquality.go
@@ -0,0 +1,74 @@
+package libbox
+
+import (
+ "context"
+ "time"
+
+ "github.com/sagernet/sing-box/common/networkquality"
+)
+
+type NetworkQualityTest struct {
+ ctx context.Context
+ cancel context.CancelFunc
+}
+
+func NewNetworkQualityTest() *NetworkQualityTest {
+ ctx, cancel := context.WithCancel(context.Background())
+ return &NetworkQualityTest{ctx: ctx, cancel: cancel}
+}
+
+func (t *NetworkQualityTest) Start(configURL string, serial bool, maxRuntimeSeconds int32, http3 bool, handler NetworkQualityTestHandler) {
+ go func() {
+ httpClient := networkquality.NewHTTPClient(nil)
+ defer httpClient.CloseIdleConnections()
+
+ measurementClientFactory, err := networkquality.NewOptionalHTTP3Factory(nil, http3)
+ if err != nil {
+ handler.OnError(err.Error())
+ return
+ }
+
+ result, err := networkquality.Run(networkquality.Options{
+ ConfigURL: configURL,
+ HTTPClient: httpClient,
+ NewMeasurementClient: measurementClientFactory,
+ Serial: serial,
+ MaxRuntime: time.Duration(maxRuntimeSeconds) * time.Second,
+ Context: t.ctx,
+ OnProgress: func(p networkquality.Progress) {
+ handler.OnProgress(&NetworkQualityProgress{
+ Phase: int32(p.Phase),
+ DownloadCapacity: p.DownloadCapacity,
+ UploadCapacity: p.UploadCapacity,
+ DownloadRPM: p.DownloadRPM,
+ UploadRPM: p.UploadRPM,
+ IdleLatencyMs: p.IdleLatencyMs,
+ ElapsedMs: p.ElapsedMs,
+ DownloadCapacityAccuracy: int32(p.DownloadCapacityAccuracy),
+ UploadCapacityAccuracy: int32(p.UploadCapacityAccuracy),
+ DownloadRPMAccuracy: int32(p.DownloadRPMAccuracy),
+ UploadRPMAccuracy: int32(p.UploadRPMAccuracy),
+ })
+ },
+ })
+ if err != nil {
+ handler.OnError(err.Error())
+ return
+ }
+ handler.OnResult(&NetworkQualityResult{
+ DownloadCapacity: result.DownloadCapacity,
+ UploadCapacity: result.UploadCapacity,
+ DownloadRPM: result.DownloadRPM,
+ UploadRPM: result.UploadRPM,
+ IdleLatencyMs: result.IdleLatencyMs,
+ DownloadCapacityAccuracy: int32(result.DownloadCapacityAccuracy),
+ UploadCapacityAccuracy: int32(result.UploadCapacityAccuracy),
+ DownloadRPMAccuracy: int32(result.DownloadRPMAccuracy),
+ UploadRPMAccuracy: int32(result.UploadRPMAccuracy),
+ })
+ }()
+}
+
+func (t *NetworkQualityTest) Cancel() {
+ t.cancel()
+}
diff --git a/experimental/libbox/oom_report.go b/experimental/libbox/oom_report.go
new file mode 100644
index 0000000000..64afc4b523
--- /dev/null
+++ b/experimental/libbox/oom_report.go
@@ -0,0 +1,218 @@
+//go:build darwin || linux || windows
+
+package libbox
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "time"
+
+ "github.com/sagernet/sing-box/experimental/libbox/internal/oomprofile"
+ "github.com/sagernet/sing-box/service/oomkiller"
+ "github.com/sagernet/sing/common/byteformats"
+ "github.com/sagernet/sing/common/memory"
+)
+
+func init() {
+ sOOMReporter = &oomReporter{}
+}
+
+var oomReportProfiles = []string{
+ "allocs",
+ "block",
+ "goroutine",
+ "heap",
+ "mutex",
+ "threadcreate",
+}
+
+type oomReportMetadata struct {
+ reportMetadata
+ RecordedAt string `json:"recordedAt"`
+ MemoryUsage string `json:"memoryUsage"`
+ AvailableMemory string `json:"availableMemory,omitempty"`
+ // Heap
+ HeapAlloc string `json:"heapAlloc,omitempty"`
+ HeapObjects uint64 `json:"heapObjects,omitempty,string"`
+ HeapInuse string `json:"heapInuse,omitempty"`
+ HeapIdle string `json:"heapIdle,omitempty"`
+ HeapReleased string `json:"heapReleased,omitempty"`
+ HeapSys string `json:"heapSys,omitempty"`
+ // Stack
+ StackInuse string `json:"stackInuse,omitempty"`
+ StackSys string `json:"stackSys,omitempty"`
+ // Runtime metadata
+ MSpanInuse string `json:"mSpanInuse,omitempty"`
+ MSpanSys string `json:"mSpanSys,omitempty"`
+ MCacheSys string `json:"mCacheSys,omitempty"`
+ BuckHashSys string `json:"buckHashSys,omitempty"`
+ GCSys string `json:"gcSys,omitempty"`
+ OtherSys string `json:"otherSys,omitempty"`
+ Sys string `json:"sys,omitempty"`
+ // GC & runtime
+ TotalAlloc string `json:"totalAlloc,omitempty"`
+ NumGC uint32 `json:"numGC,omitempty,string"`
+ NumGoroutine int `json:"numGoroutine,omitempty,string"`
+ NextGC string `json:"nextGC,omitempty"`
+ LastGC string `json:"lastGC,omitempty"`
+}
+
+type oomReporter struct{}
+
+var _ oomkiller.OOMReporter = (*oomReporter)(nil)
+
+func (r *oomReporter) WriteReport(memoryUsage uint64) error {
+ draftPath := filepath.Join(sWorkingPath, "oom_draft")
+ draftInfo, err := os.Stat(draftPath)
+ if err != nil {
+ if !os.IsNotExist(err) {
+ return err
+ }
+ draftInfo = nil
+ }
+ reportsDir := filepath.Join(sWorkingPath, "oom_reports")
+ err = os.MkdirAll(reportsDir, 0o777)
+ if err != nil {
+ return err
+ }
+ chownReport(reportsDir)
+
+ destPath, err := nextAvailableReportPath(reportsDir, time.Now().UTC())
+ if err != nil {
+ return err
+ }
+ err = r.writeSnapshot(destPath, memoryUsage)
+ if err != nil {
+ return err
+ }
+ return discardDraftIfCurrent(draftPath, draftInfo)
+}
+
+func (r *oomReporter) WriteDraft(memoryUsage uint64) error {
+ draftPath := filepath.Join(sWorkingPath, "oom_draft")
+ os.RemoveAll(draftPath)
+ return r.writeSnapshot(draftPath, memoryUsage)
+}
+
+func (r *oomReporter) DiscardDraft() error {
+ draftPath := filepath.Join(sWorkingPath, "oom_draft")
+ return os.RemoveAll(draftPath)
+}
+
+func discardDraftIfCurrent(draftPath string, draftInfo os.FileInfo) error {
+ if draftInfo == nil {
+ return nil
+ }
+ currentInfo, err := os.Stat(draftPath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+ if !os.SameFile(draftInfo, currentInfo) {
+ return nil
+ }
+ return os.RemoveAll(draftPath)
+}
+
+func (r *oomReporter) writeSnapshot(destPath string, memoryUsage uint64) error {
+ now := time.Now().UTC()
+ err := os.MkdirAll(destPath, 0o777)
+ if err != nil {
+ return err
+ }
+ chownReport(destPath)
+
+ for _, name := range oomReportProfiles {
+ writeOOMProfile(destPath, name)
+ }
+
+ writeReportFile(destPath, "cmdline", []byte(strings.Join(os.Args, "\000")))
+
+ var memStats runtime.MemStats
+ runtime.ReadMemStats(&memStats)
+
+ metadata := oomReportMetadata{
+ reportMetadata: baseReportMetadata(),
+ RecordedAt: now.Format(time.RFC3339),
+ MemoryUsage: byteformats.FormatMemoryBytes(memoryUsage),
+ // Heap
+ HeapAlloc: byteformats.FormatMemoryBytes(memStats.HeapAlloc),
+ HeapObjects: memStats.HeapObjects,
+ HeapInuse: byteformats.FormatMemoryBytes(memStats.HeapInuse),
+ HeapIdle: byteformats.FormatMemoryBytes(memStats.HeapIdle),
+ HeapReleased: byteformats.FormatMemoryBytes(memStats.HeapReleased),
+ HeapSys: byteformats.FormatMemoryBytes(memStats.HeapSys),
+ // Stack
+ StackInuse: byteformats.FormatMemoryBytes(memStats.StackInuse),
+ StackSys: byteformats.FormatMemoryBytes(memStats.StackSys),
+ // Runtime metadata
+ MSpanInuse: byteformats.FormatMemoryBytes(memStats.MSpanInuse),
+ MSpanSys: byteformats.FormatMemoryBytes(memStats.MSpanSys),
+ MCacheSys: byteformats.FormatMemoryBytes(memStats.MCacheSys),
+ BuckHashSys: byteformats.FormatMemoryBytes(memStats.BuckHashSys),
+ GCSys: byteformats.FormatMemoryBytes(memStats.GCSys),
+ OtherSys: byteformats.FormatMemoryBytes(memStats.OtherSys),
+ Sys: byteformats.FormatMemoryBytes(memStats.Sys),
+ // GC & runtime
+ TotalAlloc: byteformats.FormatMemoryBytes(memStats.TotalAlloc),
+ NumGC: memStats.NumGC,
+ NumGoroutine: runtime.NumGoroutine(),
+ NextGC: byteformats.FormatMemoryBytes(memStats.NextGC),
+ }
+ if memStats.LastGC > 0 {
+ metadata.LastGC = time.Unix(0, int64(memStats.LastGC)).UTC().Format(time.RFC3339)
+ }
+ availableMemory := memory.Available()
+ if availableMemory > 0 {
+ metadata.AvailableMemory = byteformats.FormatMemoryBytes(availableMemory)
+ }
+ writeReportMetadata(destPath, metadata)
+ copyConfigSnapshot(destPath)
+
+ return nil
+}
+
+func writeOOMProfile(destPath string, name string) {
+ filePath, err := oomprofile.WriteFile(destPath, name)
+ if err != nil {
+ return
+ }
+ chownReport(filePath)
+}
+
+func promoteOOMDraftAt(workingPath string) {
+ draftPath := filepath.Join(workingPath, "oom_draft")
+ info, err := os.Stat(draftPath)
+ if err != nil || !info.IsDir() {
+ return
+ }
+ reportsDir := filepath.Join(workingPath, "oom_reports")
+ initReportDir(reportsDir)
+ destPath, err := nextAvailableReportPath(reportsDir, info.ModTime().UTC())
+ if err != nil {
+ os.RemoveAll(draftPath)
+ return
+ }
+ err = os.Rename(draftPath, destPath)
+ if err != nil {
+ os.RemoveAll(draftPath)
+ return
+ }
+ chownReport(destPath)
+}
+
+func promoteOOMDraft() {
+ promoteOOMDraftAt(sWorkingPath)
+}
+
+func PromoteOOMDraft() {
+ promoteOOMDraft()
+}
+
+func PromoteOOMDraftAt(workingPath string) {
+ promoteOOMDraftAt(workingPath)
+}
diff --git a/experimental/libbox/platform.go b/experimental/libbox/platform.go
index b82121b7ba..cd364862d9 100644
--- a/experimental/libbox/platform.go
+++ b/experimental/libbox/platform.go
@@ -18,6 +18,13 @@ type PlatformInterface interface {
SystemCertificates() StringIterator
ClearDNSCache()
SendNotification(notification *Notification) error
+ StartNeighborMonitor(listener NeighborUpdateListener) error
+ CloseNeighborMonitor(listener NeighborUpdateListener) error
+ RegisterMyInterface(name string)
+}
+
+type NeighborUpdateListener interface {
+ UpdateNeighborTable(entries NeighborEntryIterator)
}
type ConnectionOwner struct {
diff --git a/experimental/libbox/profile_import.go b/experimental/libbox/profile_import.go
index c337d015fd..17671e560f 100644
--- a/experimental/libbox/profile_import.go
+++ b/experimental/libbox/profile_import.go
@@ -5,7 +5,6 @@ import (
"bytes"
"compress/gzip"
"encoding/binary"
- "io"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/varbin"
@@ -36,7 +35,7 @@ type ErrorMessage struct {
func (e *ErrorMessage) Encode() []byte {
var buffer bytes.Buffer
buffer.WriteByte(MessageTypeError)
- writeString(&buffer, e.Message)
+ varbin.Write(&buffer, binary.BigEndian, e.Message)
return buffer.Bytes()
}
@@ -50,7 +49,7 @@ func DecodeErrorMessage(data []byte) (*ErrorMessage, error) {
return nil, E.New("invalid message")
}
var message ErrorMessage
- message.Message, err = readString(reader)
+ message.Message, err = varbin.ReadValue[string](reader, binary.BigEndian)
if err != nil {
return nil, err
}
@@ -88,7 +87,7 @@ func (e *ProfileEncoder) Encode() []byte {
binary.Write(&buffer, binary.BigEndian, uint16(len(e.profiles)))
for _, preview := range e.profiles {
binary.Write(&buffer, binary.BigEndian, preview.ProfileID)
- writeString(&buffer, preview.Name)
+ varbin.Write(&buffer, binary.BigEndian, preview.Name)
binary.Write(&buffer, binary.BigEndian, preview.Type)
}
return buffer.Bytes()
@@ -118,7 +117,7 @@ func (d *ProfileDecoder) Decode(data []byte) error {
if err != nil {
return err
}
- profile.Name, err = readString(reader)
+ profile.Name, err = varbin.ReadValue[string](reader, binary.BigEndian)
if err != nil {
return err
}
@@ -179,11 +178,11 @@ func (c *ProfileContent) Encode() []byte {
buffer.WriteByte(1)
gWriter := gzip.NewWriter(buffer)
writer := bufio.NewWriter(gWriter)
- writeStringBuffered(writer, c.Name)
+ varbin.Write(writer, binary.BigEndian, c.Name)
binary.Write(writer, binary.BigEndian, c.Type)
- writeStringBuffered(writer, c.Config)
+ varbin.Write(writer, binary.BigEndian, c.Config)
if c.Type != ProfileTypeLocal {
- writeStringBuffered(writer, c.RemotePath)
+ varbin.Write(writer, binary.BigEndian, c.RemotePath)
}
if c.Type == ProfileTypeRemote {
binary.Write(writer, binary.BigEndian, c.AutoUpdate)
@@ -215,7 +214,7 @@ func DecodeProfileContent(data []byte) (*ProfileContent, error) {
}
bReader := varbin.StubReader(gReader)
var content ProfileContent
- content.Name, err = readString(bReader)
+ content.Name, err = varbin.ReadValue[string](bReader, binary.BigEndian)
if err != nil {
return nil, err
}
@@ -223,12 +222,12 @@ func DecodeProfileContent(data []byte) (*ProfileContent, error) {
if err != nil {
return nil, err
}
- content.Config, err = readString(bReader)
+ content.Config, err = varbin.ReadValue[string](bReader, binary.BigEndian)
if err != nil {
return nil, err
}
if content.Type != ProfileTypeLocal {
- content.RemotePath, err = readString(bReader)
+ content.RemotePath, err = varbin.ReadValue[string](bReader, binary.BigEndian)
if err != nil {
return nil, err
}
@@ -251,28 +250,3 @@ func DecodeProfileContent(data []byte) (*ProfileContent, error) {
}
return &content, nil
}
-
-func readString(reader io.ByteReader) (string, error) {
- length, err := binary.ReadUvarint(reader)
- if err != nil {
- return "", err
- }
- buf := make([]byte, length)
- for i := range buf {
- buf[i], err = reader.ReadByte()
- if err != nil {
- return "", err
- }
- }
- return string(buf), nil
-}
-
-func writeString(buffer *bytes.Buffer, value string) {
- varbin.WriteUvarint(buffer, uint64(len(value)))
- buffer.WriteString(value)
-}
-
-func writeStringBuffered(writer *bufio.Writer, value string) {
- varbin.WriteUvarint(writer, uint64(len(value)))
- writer.WriteString(value)
-}
diff --git a/experimental/libbox/report.go b/experimental/libbox/report.go
new file mode 100644
index 0000000000..816dcac425
--- /dev/null
+++ b/experimental/libbox/report.go
@@ -0,0 +1,97 @@
+//go:build darwin || linux || windows
+
+package libbox
+
+import (
+ "bytes"
+ "encoding/json"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "time"
+
+ C "github.com/sagernet/sing-box/constant"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type reportMetadata struct {
+ Source string `json:"source,omitempty"`
+ BundleIdentifier string `json:"bundleIdentifier,omitempty"`
+ ProcessName string `json:"processName,omitempty"`
+ ProcessPath string `json:"processPath,omitempty"`
+ StartedAt string `json:"startedAt,omitempty"`
+ AppVersion string `json:"appVersion,omitempty"`
+ AppMarketingVersion string `json:"appMarketingVersion,omitempty"`
+ CoreVersion string `json:"coreVersion,omitempty"`
+ GoVersion string `json:"goVersion,omitempty"`
+}
+
+func baseReportMetadata() reportMetadata {
+ processPath, _ := os.Executable()
+ processName := filepath.Base(processPath)
+ if processName == "." {
+ processName = ""
+ }
+ return reportMetadata{
+ Source: sCrashReportSource,
+ ProcessName: processName,
+ ProcessPath: processPath,
+ CoreVersion: C.Version,
+ GoVersion: GoVersion(),
+ }
+}
+
+func writeReportFile(destPath string, name string, content []byte) {
+ filePath := filepath.Join(destPath, name)
+ os.WriteFile(filePath, content, 0o666)
+ chownReport(filePath)
+}
+
+func writeReportMetadata(destPath string, metadata any) {
+ data, err := json.Marshal(metadata)
+ if err != nil {
+ return
+ }
+ writeReportFile(destPath, "metadata.json", data)
+}
+
+func copyConfigSnapshot(destPath string) {
+ snapshotPath := configSnapshotPath()
+ content, err := os.ReadFile(snapshotPath)
+ if err != nil {
+ return
+ }
+ if len(bytes.TrimSpace(content)) == 0 {
+ return
+ }
+ writeReportFile(destPath, "configuration.json", content)
+}
+
+func initReportDir(path string) {
+ os.MkdirAll(path, 0o777)
+ chownReport(path)
+}
+
+func chownReport(path string) {
+ if runtime.GOOS != "android" && runtime.GOOS != "windows" {
+ os.Chown(path, sUserID, sGroupID)
+ }
+}
+
+func nextAvailableReportPath(reportsDir string, timestamp time.Time) (string, error) {
+ destName := timestamp.Format("2006-01-02T15-04-05")
+ destPath := filepath.Join(reportsDir, destName)
+ _, err := os.Stat(destPath)
+ if os.IsNotExist(err) {
+ return destPath, nil
+ }
+ for i := 1; i <= 1000; i++ {
+ suffixedPath := filepath.Join(reportsDir, destName+"-"+strconv.Itoa(i))
+ _, err = os.Stat(suffixedPath)
+ if os.IsNotExist(err) {
+ return suffixedPath, nil
+ }
+ }
+ return "", E.New("no available report path for ", destName)
+}
diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go
index 37fd56c980..0aaa51a556 100644
--- a/experimental/libbox/service.go
+++ b/experimental/libbox/service.go
@@ -80,6 +80,7 @@ func (w *platformInterfaceWrapper) OpenInterface(options *tun.Options, platformO
options.FileDescriptor = dupFd
w.myTunName = options.Name
w.myTunAddress = myTunAddress(options)
+ w.iif.RegisterMyInterface(options.Name)
return tun.New(*options)
}
@@ -234,6 +235,46 @@ func (w *platformInterfaceWrapper) SendNotification(notification *adapter.Notifi
return w.iif.SendNotification((*Notification)(notification))
}
+func (w *platformInterfaceWrapper) UsePlatformNeighborResolver() bool {
+ return true
+}
+
+func (w *platformInterfaceWrapper) StartNeighborMonitor(listener adapter.NeighborUpdateListener) error {
+ return w.iif.StartNeighborMonitor(&neighborUpdateListenerWrapper{listener: listener})
+}
+
+func (w *platformInterfaceWrapper) CloseNeighborMonitor(listener adapter.NeighborUpdateListener) error {
+ return w.iif.CloseNeighborMonitor(nil)
+}
+
+type neighborUpdateListenerWrapper struct {
+ listener adapter.NeighborUpdateListener
+}
+
+func (w *neighborUpdateListenerWrapper) UpdateNeighborTable(entries NeighborEntryIterator) {
+ var result []adapter.NeighborEntry
+ for entries.HasNext() {
+ entry := entries.Next()
+ if entry == nil {
+ continue
+ }
+ address, err := netip.ParseAddr(entry.Address)
+ if err != nil {
+ continue
+ }
+ macAddress, err := net.ParseMAC(entry.MacAddress)
+ if err != nil {
+ continue
+ }
+ result = append(result, adapter.NeighborEntry{
+ Address: address,
+ MACAddress: macAddress,
+ Hostname: entry.Hostname,
+ })
+ }
+ w.listener.UpdateNeighborTable(result)
+}
+
func AvailablePort(startPort int32) (int32, error) {
for port := int(startPort); ; port++ {
if port > 65535 {
diff --git a/experimental/libbox/setup.go b/experimental/libbox/setup.go
index 5063ce6db2..9f8aa03cf9 100644
--- a/experimental/libbox/setup.go
+++ b/experimental/libbox/setup.go
@@ -1,14 +1,23 @@
package libbox
import (
+ "math"
"os"
+ "path/filepath"
+ "runtime"
"runtime/debug"
+ "strings"
"time"
+ "github.com/sagernet/sing-box/common/networkquality"
+ "github.com/sagernet/sing-box/common/stun"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/experimental/locale"
"github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/service/oomkiller"
"github.com/sagernet/sing/common/byteformats"
+ E "github.com/sagernet/sing/common/exceptions"
)
var (
@@ -22,6 +31,10 @@ var (
sCommandServerSecret string
sLogMaxLines int
sDebug bool
+ sCrashReportSource string
+ sOOMKillerEnabled bool
+ sOOMKillerDisabled bool
+ sOOMMemoryLimit int64
)
func init() {
@@ -38,9 +51,13 @@ type SetupOptions struct {
CommandServerSecret string
LogMaxLines int
Debug bool
+ CrashReportSource string
+ OomKillerEnabled bool
+ OomKillerDisabled bool
+ OomMemoryLimit int64
}
-func Setup(options *SetupOptions) error {
+func applySetupOptions(options *SetupOptions) {
sBasePath = options.BasePath
sWorkingPath = options.WorkingPath
sTempPath = options.TempPath
@@ -56,20 +73,53 @@ func Setup(options *SetupOptions) error {
sCommandServerSecret = options.CommandServerSecret
sLogMaxLines = options.LogMaxLines
sDebug = options.Debug
+ sCrashReportSource = options.CrashReportSource
+ ReloadSetupOptions(options)
+}
+
+func ReloadSetupOptions(options *SetupOptions) {
+ sOOMKillerEnabled = options.OomKillerEnabled
+ sOOMKillerDisabled = options.OomKillerDisabled
+ sOOMMemoryLimit = options.OomMemoryLimit
+ if sOOMKillerEnabled {
+ if sOOMMemoryLimit == 0 && C.IsIos {
+ sOOMMemoryLimit = oomkiller.DefaultAppleNetworkExtensionMemoryLimit
+ }
+ if sOOMMemoryLimit > 0 {
+ debug.SetMemoryLimit(sOOMMemoryLimit * 3 / 4)
+ } else {
+ debug.SetMemoryLimit(math.MaxInt64)
+ }
+ } else {
+ debug.SetMemoryLimit(math.MaxInt64)
+ }
+}
+func Setup(options *SetupOptions) error {
+ applySetupOptions(options)
os.MkdirAll(sWorkingPath, 0o777)
os.MkdirAll(sTempPath, 0o777)
- return nil
+ return redirectStderr(filepath.Join(sWorkingPath, "CrashReport-"+sCrashReportSource+".log"))
}
-func SetLocale(localeId string) {
- locale.Set(localeId)
+func SetLocale(localeId string) error {
+ if strings.Contains(localeId, "@") {
+ localeId = strings.Split(localeId, "@")[0]
+ }
+ if !locale.Set(localeId) {
+ return E.New("unsupported locale: ", localeId)
+ }
+ return nil
}
func Version() string {
return C.Version
}
+func GoVersion() string {
+ return runtime.Version() + ", " + runtime.GOOS + "/" + runtime.GOARCH
+}
+
func FormatBytes(length int64) string {
return byteformats.FormatKBytes(uint64(length))
}
@@ -82,6 +132,60 @@ func FormatDuration(duration int64) string {
return log.FormatDuration(time.Duration(duration) * time.Millisecond)
}
+func FormatBitrate(bps int64) string {
+ return networkquality.FormatBitrate(bps)
+}
+
+const NetworkQualityDefaultConfigURL = networkquality.DefaultConfigURL
+
+const NetworkQualityDefaultMaxRuntimeSeconds = int32(networkquality.DefaultMaxRuntime / time.Second)
+
+const (
+ NetworkQualityAccuracyLow = int32(networkquality.AccuracyLow)
+ NetworkQualityAccuracyMedium = int32(networkquality.AccuracyMedium)
+ NetworkQualityAccuracyHigh = int32(networkquality.AccuracyHigh)
+)
+
+const (
+ NetworkQualityPhaseIdle = int32(networkquality.PhaseIdle)
+ NetworkQualityPhaseDownload = int32(networkquality.PhaseDownload)
+ NetworkQualityPhaseUpload = int32(networkquality.PhaseUpload)
+ NetworkQualityPhaseDone = int32(networkquality.PhaseDone)
+)
+
+const STUNDefaultServer = stun.DefaultServer
+
+const (
+ STUNPhaseBinding = int32(stun.PhaseBinding)
+ STUNPhaseNATMapping = int32(stun.PhaseNATMapping)
+ STUNPhaseNATFiltering = int32(stun.PhaseNATFiltering)
+ STUNPhaseDone = int32(stun.PhaseDone)
+)
+
+const (
+ NATMappingEndpointIndependent = int32(stun.NATMappingEndpointIndependent)
+ NATMappingAddressDependent = int32(stun.NATMappingAddressDependent)
+ NATMappingAddressAndPortDependent = int32(stun.NATMappingAddressAndPortDependent)
+)
+
+const (
+ NATFilteringEndpointIndependent = int32(stun.NATFilteringEndpointIndependent)
+ NATFilteringAddressDependent = int32(stun.NATFilteringAddressDependent)
+ NATFilteringAddressAndPortDependent = int32(stun.NATFilteringAddressAndPortDependent)
+)
+
+func FormatNATMapping(value int32) string {
+ return stun.NATMapping(value).String()
+}
+
+func FormatNATFiltering(value int32) string {
+ return stun.NATFiltering(value).String()
+}
+
+func FormatFQDN(fqdn string) string {
+ return dns.FqdnToDomain(fqdn)
+}
+
func ProxyDisplayType(proxyType string) string {
return C.ProxyDisplayName(proxyType)
}
diff --git a/experimental/libbox/signal_handler_darwin.go b/experimental/libbox/signal_handler_darwin.go
new file mode 100644
index 0000000000..a60ddd90fe
--- /dev/null
+++ b/experimental/libbox/signal_handler_darwin.go
@@ -0,0 +1,146 @@
+//go:build darwin && badlinkname
+
+package libbox
+
+/*
+#include
+#include
+#include
+
+static struct sigaction _go_sa[32];
+static struct sigaction _plcrash_sa[32];
+static int _saved = 0;
+
+static int _signals[] = {SIGSEGV, SIGBUS, SIGFPE, SIGILL, SIGTRAP};
+static const int _signal_count = sizeof(_signals) / sizeof(_signals[0]);
+
+static void _save_go_handlers(void) {
+ if (_saved) return;
+ for (int i = 0; i < _signal_count; i++)
+ sigaction(_signals[i], NULL, &_go_sa[_signals[i]]);
+ _saved = 1;
+}
+
+static void _combined_handler(int sig, siginfo_t *info, void *uap) {
+ // Step 1: PLCrashReporter writes .plcrash, resets all handlers to SIG_DFL,
+ // and calls raise(sig) which pends (signal is blocked, no SA_NODEFER).
+ if ((_plcrash_sa[sig].sa_flags & SA_SIGINFO) &&
+ (uintptr_t)_plcrash_sa[sig].sa_sigaction > 1)
+ _plcrash_sa[sig].sa_sigaction(sig, info, uap);
+
+ // SIGTRAP does not rely on sigreturn -> sigpanic. Once Go's trap trampoline
+ // is force-installed, we can chain into it directly after PLCrashReporter.
+ if (sig == SIGTRAP &&
+ (_go_sa[sig].sa_flags & SA_SIGINFO) &&
+ (uintptr_t)_go_sa[sig].sa_sigaction > 1) {
+ _go_sa[sig].sa_sigaction(sig, info, uap);
+ return;
+ }
+
+ // Step 2: Restore Go's handler via sigaction (overwrites PLCrashReporter's SIG_DFL).
+ // Do NOT call Go's handler directly — Go's preparePanic only modifies the
+ // ucontext and returns. The actual crash output is written by sigpanic, which
+ // only runs when the KERNEL restores the modified ucontext via sigreturn.
+ // A direct C function call has no sigreturn, so sigpanic would never execute.
+ sigaction(sig, &_go_sa[sig], NULL);
+
+ // Step 3: Return. The kernel restores the original ucontext and re-executes
+ // the faulting instruction. Two signals are now pending/imminent:
+ // a) PLCrashReporter's raise() (SI_USER) — Go's handler ignores it
+ // (sighandler: sigFromUser() → return).
+ // b) The re-executed fault (SEGV_MAPERR) — Go's handler processes it:
+ // preparePanic → kernel sigreturn → sigpanic → crash output written
+ // via debug.SetCrashOutput.
+}
+
+static void _reinstall_handlers(void) {
+ if (!_saved) return;
+ for (int i = 0; i < _signal_count; i++) {
+ int sig = _signals[i];
+ struct sigaction current;
+ sigaction(sig, NULL, ¤t);
+ // Only save the handler if it's not one of ours
+ if (current.sa_sigaction != _combined_handler) {
+ // If current handler is still Go's, PLCrashReporter wasn't installed
+ if ((current.sa_flags & SA_SIGINFO) &&
+ (uintptr_t)current.sa_sigaction > 1 &&
+ current.sa_sigaction == _go_sa[sig].sa_sigaction)
+ memset(&_plcrash_sa[sig], 0, sizeof(_plcrash_sa[sig]));
+ else
+ _plcrash_sa[sig] = current;
+ }
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = _combined_handler;
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ sigemptyset(&sa.sa_mask);
+ sigaction(sig, &sa, NULL);
+ }
+}
+*/
+import "C"
+
+import (
+ "reflect"
+ _ "unsafe"
+)
+
+const (
+ _sigtrap = 5
+ _nsig = 32
+)
+
+//go:linkname runtimeGetsig runtime.getsig
+func runtimeGetsig(i uint32) uintptr
+
+//go:linkname runtimeSetsig runtime.setsig
+func runtimeSetsig(i uint32, fn uintptr)
+
+//go:linkname runtimeCgoSigtramp runtime.cgoSigtramp
+func runtimeCgoSigtramp()
+
+//go:linkname runtimeFwdSig runtime.fwdSig
+var runtimeFwdSig [_nsig]uintptr
+
+//go:linkname runtimeHandlingSig runtime.handlingSig
+var runtimeHandlingSig [_nsig]uint32
+
+func forceGoSIGTRAPHandler() {
+ runtimeFwdSig[_sigtrap] = runtimeGetsig(_sigtrap)
+ runtimeHandlingSig[_sigtrap] = 1
+ runtimeSetsig(_sigtrap, reflect.ValueOf(runtimeCgoSigtramp).Pointer())
+}
+
+// PrepareCrashSignalHandlers captures Go's original synchronous signal handlers.
+//
+// In gomobile/c-archive embeddings, package init runs on the first Go entry.
+// That means a native crash reporter installed before the first Go call would
+// otherwise be captured as the "Go" handler and break handler restoration on
+// SIGSEGV. Go skips SIGTRAP in c-archive mode, so install its trap trampoline
+// before saving handlers. Call this before installing PLCrashReporter.
+func PrepareCrashSignalHandlers() {
+ forceGoSIGTRAPHandler()
+ C._save_go_handlers()
+}
+
+// ReinstallCrashSignalHandlers installs a combined signal handler that chains
+// PLCrashReporter (native crash report) and Go's runtime handler (Go crash log).
+//
+// Call PrepareCrashSignalHandlers before installing PLCrashReporter, then call
+// this after PLCrashReporter has been installed.
+//
+// Flow on SIGSEGV:
+// 1. Combined handler calls PLCrashReporter's saved handler → .plcrash written
+// 2. Combined handler restores Go's handler via sigaction
+// 3. Combined handler returns — kernel re-executes faulting instruction
+// 4. PLCrashReporter's pending raise() (SI_USER) is ignored by Go's handler
+// 5. Hardware fault → Go's handler → preparePanic → kernel sigreturn →
+// sigpanic → crash output via debug.SetCrashOutput
+//
+// Flow on SIGTRAP:
+// 1. PrepareCrashSignalHandlers force-installs Go's cgo trap trampoline
+// 2. Combined handler calls PLCrashReporter's saved handler → .plcrash written
+// 3. Combined handler directly calls the saved Go trap trampoline
+func ReinstallCrashSignalHandlers() {
+ C._reinstall_handlers()
+}
diff --git a/experimental/libbox/signal_handler_stub.go b/experimental/libbox/signal_handler_stub.go
new file mode 100644
index 0000000000..2ac68b869d
--- /dev/null
+++ b/experimental/libbox/signal_handler_stub.go
@@ -0,0 +1,7 @@
+//go:build !darwin || !badlinkname
+
+package libbox
+
+func PrepareCrashSignalHandlers() {}
+
+func ReinstallCrashSignalHandlers() {}
diff --git a/experimental/libbox/stun.go b/experimental/libbox/stun.go
new file mode 100644
index 0000000000..3f38815d79
--- /dev/null
+++ b/experimental/libbox/stun.go
@@ -0,0 +1,50 @@
+package libbox
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/common/stun"
+)
+
+type STUNTest struct {
+ ctx context.Context
+ cancel context.CancelFunc
+}
+
+func NewSTUNTest() *STUNTest {
+ ctx, cancel := context.WithCancel(context.Background())
+ return &STUNTest{ctx: ctx, cancel: cancel}
+}
+
+func (t *STUNTest) Start(server string, handler STUNTestHandler) {
+ go func() {
+ result, err := stun.Run(stun.Options{
+ Server: server,
+ Context: t.ctx,
+ OnProgress: func(p stun.Progress) {
+ handler.OnProgress(&STUNTestProgress{
+ Phase: int32(p.Phase),
+ ExternalAddr: p.ExternalAddr,
+ LatencyMs: p.LatencyMs,
+ NATMapping: int32(p.NATMapping),
+ NATFiltering: int32(p.NATFiltering),
+ })
+ },
+ })
+ if err != nil {
+ handler.OnError(err.Error())
+ return
+ }
+ handler.OnResult(&STUNTestResult{
+ ExternalAddr: result.ExternalAddr,
+ LatencyMs: result.LatencyMs,
+ NATMapping: int32(result.NATMapping),
+ NATFiltering: int32(result.NATFiltering),
+ NATTypeSupported: result.NATTypeSupported,
+ })
+ }()
+}
+
+func (t *STUNTest) Cancel() {
+ t.cancel()
+}
diff --git a/experimental/libbox/tun.go b/experimental/libbox/tun.go
index 84c6372aca..fef66b91c1 100644
--- a/experimental/libbox/tun.go
+++ b/experimental/libbox/tun.go
@@ -7,13 +7,19 @@ import (
"github.com/sagernet/sing-box/option"
tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
+)
+
+const (
+ DNSModeDisabled = tun.DNSModeDisabled
+ DNSModeNative = tun.DNSModeNative
+ DNSModeHijack = tun.DNSModeHijack
)
type TunOptions interface {
GetInet4Address() RoutePrefixIterator
GetInet6Address() RoutePrefixIterator
- GetDNSServerAddress() (*StringBox, error)
+ GetDNSMode() *StringBox
+ GetDNSServerAddress() (StringIterator, error)
GetMTU() int32
GetAutoRoute() bool
GetStrictRoute() bool
@@ -89,11 +95,16 @@ func (o *tunOptions) GetInet6Address() RoutePrefixIterator {
return mapRoutePrefix(o.Inet6Address)
}
-func (o *tunOptions) GetDNSServerAddress() (*StringBox, error) {
- if len(o.Inet4Address) == 0 || o.Inet4Address[0].Bits() == 32 {
- return nil, E.New("need one more IPv4 address for DNS hijacking")
+func (o *tunOptions) GetDNSMode() *StringBox {
+ return wrapString(o.Options.DNSMode)
+}
+
+func (o *tunOptions) GetDNSServerAddress() (StringIterator, error) {
+ dnsServers, err := o.Options.DNSServerAddress()
+ if err != nil {
+ return nil, err
}
- return wrapString(o.Inet4Address[0].Addr().Next().String()), nil
+ return newIterator(common.Map(dnsServers, netip.Addr.String)), nil
}
func (o *tunOptions) GetMTU() int32 {
diff --git a/go.mod b/go.mod
index 9d927ee03f..ae5e97465f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,60 +1,77 @@
module github.com/sagernet/sing-box
-go 1.24.7
+go 1.25.6
+
+require github.com/amnezia-vpn/amneziawg-go v0.2.17-0.20251219021448-449d7cffd4ad
require (
+ github.com/Diniboy1123/connect-ip-go v0.0.0-20260409225322-8d7bb0a858a2
+ github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760
github.com/anthropics/anthropic-sdk-go v1.26.0
github.com/anytls/sing-anytls v0.0.11
github.com/caddyserver/certmagic v0.25.2
+ github.com/caddyserver/zerossl v0.1.5
github.com/coder/websocket v1.8.14
github.com/cretz/bine v0.2.0
github.com/database64128/tfo-go/v2 v2.3.2
+ github.com/enfein/mieru/v3 v3.27.0
github.com/go-chi/chi/v5 v5.2.5
github.com/go-chi/render v1.0.3
github.com/godbus/dbus/v5 v5.2.2
github.com/gofrs/uuid/v5 v5.4.0
github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91
+ github.com/jsimonetti/rtnetlink v1.4.0
github.com/keybase/go-keychain v0.0.1
+ github.com/kianmhz/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c
github.com/libdns/acmedns v0.5.0
github.com/libdns/alidns v1.0.6
github.com/libdns/cloudflare v0.2.2
+ github.com/libdns/libdns v1.1.1
github.com/logrusorgru/aurora v2.0.3+incompatible
+ github.com/mdlayher/netlink v1.9.0
github.com/metacubex/utls v1.8.4
github.com/mholt/acmez/v3 v3.1.6
github.com/miekg/dns v1.1.72
+ github.com/net2share/vaydns v0.2.6
github.com/openai/openai-go/v3 v3.26.0
+ github.com/oschwald/geoip2-golang v1.9.0
github.com/oschwald/maxminddb-golang v1.13.1
+ github.com/pires/go-proxyproto v0.8.1
+ github.com/reF1nd/sing-snell v0.0.5
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/cors v1.2.1
- github.com/sagernet/cronet-go v0.0.0-20260513071958-2faf34666c2c
- github.com/sagernet/cronet-go/all v0.0.0-20260513071958-2faf34666c2c
- github.com/sagernet/fswatch v0.1.2
+ github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa
+ github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa
+ github.com/sagernet/fswatch v0.1.1
github.com/sagernet/gomobile v0.1.12
github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4
- github.com/sagernet/sing v0.8.10
+ github.com/sagernet/sing v0.8.11-0.20260514110501-905ad103a4df
+ github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9
github.com/sagernet/sing-mux v0.3.4
- github.com/sagernet/sing-quic v0.6.1
+ github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7
github.com/sagernet/sing-shadowsocks v0.2.8
github.com/sagernet/sing-shadowsocks2 v0.2.1
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
- github.com/sagernet/sing-tun v0.8.9
+ github.com/sagernet/sing-tun v0.8.10-0.20260519125758-eb58efc8915d
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1
github.com/sagernet/smux v1.5.50-sing-box-mod.1
github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7
- github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c
+ github.com/sagernet/wireguard-go v0.0.3
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854
+ github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
+ github.com/tidwall/gjson v1.18.0
github.com/vishvananda/netns v0.0.5
+ github.com/yosida95/uritemplate/v3 v3.0.2
go.uber.org/zap v1.27.1
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.48.0
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93
golang.org/x/mod v0.33.0
golang.org/x/net v0.50.0
- golang.org/x/sync v0.19.0
golang.org/x/sys v0.41.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10
google.golang.org/grpc v1.79.1
@@ -63,81 +80,158 @@ require (
)
require (
+ github.com/dunglas/httpsfv v1.0.2 // indirect
+ github.com/quic-go/quic-go v0.59.0 // indirect
+)
+
+require (
+ github.com/AdguardTeam/golibs v0.32.7 // indirect
+ github.com/ameshkov/dnscrypt/v2 v2.4.0
+ github.com/ameshkov/dnsstamps v1.0.3 // indirect
+ github.com/biter777/countries v1.7.5
+ github.com/tidwall/match v1.1.1 // indirect
+ github.com/tidwall/pretty v1.2.1 // indirect
+ golang.org/x/sync v0.19.0
+ golang.org/x/text v0.34.0 // indirect
+ golang.org/x/tools v0.42.0 // indirect
+)
+
+//replace github.com/sagernet/sing => ../sing
+
+require (
+ filippo.io/bigmod v0.0.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
+ filippo.io/keygen v0.0.0-20230306160926-5201437acf8e // indirect
+ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
+ github.com/Jigsaw-Code/outline-sdk v0.0.20 // indirect
+ github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7 // indirect
+ github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737 // indirect
+ github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464 // indirect
+ github.com/Psiphon-Labs/psiphon-tls v0.0.0-20250318183125-2a2fae2db378 // indirect
+ github.com/Psiphon-Labs/quic-go v0.0.0-20250527153145-79fe45fb83b1 // indirect
+ github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/akutz/memconn v0.1.0 // indirect
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
- github.com/andybalholm/brotli v1.1.0 // indirect
- github.com/caddyserver/zerossl v0.1.5 // indirect
+ github.com/andybalholm/brotli v1.2.0 // indirect
+ github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f // indirect
+ github.com/axiomhq/hyperloglog v0.2.6 // indirect
+ github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61 // indirect
+ github.com/bits-and-blooms/bitset v1.10.0 // indirect
+ github.com/bits-and-blooms/bloom/v3 v3.6.0 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
+ github.com/cespare/xxhash v1.1.0 // indirect
+ github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 // indirect
+ github.com/cloudflare/circl v1.6.1 // indirect
+ github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea // indirect
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
+ github.com/coreos/go-oidc/v3 v3.17.0 // indirect
github.com/database64128/netx-go v0.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect
+ github.com/dchest/siphash v1.2.3 // indirect
+ github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273 // indirect
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
- github.com/ebitengine/purego v0.10.0 // indirect
+ github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
+ github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect
+ github.com/ebitengine/purego v0.9.1 // indirect
github.com/florianl/go-nfqueue/v2 v2.0.2 // indirect
- github.com/fsnotify/fsnotify v1.9.0 // indirect
+ github.com/flynn/noise v1.1.0 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gaissmai/bart v0.18.0 // indirect
+ github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect
github.com/google/uuid v1.6.0 // indirect
+ github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
+ github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/jsimonetti/rtnetlink v1.4.0 // indirect
- github.com/klauspost/compress v1.18.0 // indirect
- github.com/klauspost/cpuid/v2 v2.3.0 // indirect
- github.com/libdns/libdns v1.1.1 // indirect
- github.com/mdlayher/netlink v1.9.0 // indirect
+ github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect
+ github.com/kamstrup/intmap v0.5.2 // indirect
+ github.com/klauspost/compress v1.18.3 // indirect
+ github.com/klauspost/cpuid/v2 v2.3.0
+ github.com/klauspost/reedsolomon v1.13.0 // indirect
+ github.com/libp2p/go-reuseport v0.4.0 // indirect
+ github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
+ github.com/mroth/weightedrand v1.0.0 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
+ github.com/philhofer/fwd v1.2.0 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
- github.com/pires/go-proxyproto v0.8.1 // indirect
+ github.com/pion/datachannel v1.5.5 // indirect
+ github.com/pion/dtls/v2 v2.2.7 // indirect
+ github.com/pion/ice/v2 v2.3.24 // indirect
+ github.com/pion/interceptor v0.1.25 // indirect
+ github.com/pion/logging v0.2.2 // indirect
+ github.com/pion/mdns v0.0.12 // indirect
+ github.com/pion/randutil v0.1.0 // indirect
+ github.com/pion/rtcp v1.2.12 // indirect
+ github.com/pion/rtp v1.8.5 // indirect
+ github.com/pion/sctp v1.8.16 // indirect
+ github.com/pion/sdp/v3 v3.0.9 // indirect
+ github.com/pion/srtp/v2 v2.0.18 // indirect
+ github.com/pion/stun v0.6.1 // indirect
+ github.com/pion/transport/v2 v2.2.4 // indirect
+ github.com/pion/turn/v2 v2.1.3 // indirect
+ github.com/pion/webrtc/v3 v3.2.40 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus-community/pro-bing v0.4.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
+ github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2 // indirect
+ github.com/refraction-networking/ed25519 v0.1.2 // indirect
+ github.com/refraction-networking/gotapdance v1.7.10 // indirect
+ github.com/refraction-networking/obfs4 v0.1.2 // indirect
+ github.com/refraction-networking/utls v1.8.2 // indirect
github.com/safchain/ethtool v0.3.0 // indirect
- github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260513071149-ade33496efb8 // indirect
- github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260513071149-ade33496efb8 // indirect
+ github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
github.com/sagernet/nftables v0.3.0-mod.2 // indirect
+ github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 // indirect
+ github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect
+ github.com/sirupsen/logrus v1.9.4 // indirect
github.com/spf13/pflag v1.0.9 // indirect
+ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect
@@ -145,24 +239,51 @@ require (
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect
github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc // indirect
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 // indirect
- github.com/tidwall/gjson v1.18.0 // indirect
- github.com/tidwall/match v1.1.1 // indirect
- github.com/tidwall/pretty v1.2.1 // indirect
+ github.com/things-go/go-socks5 v0.1.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
+ github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
+ github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 // indirect
+ github.com/wlynxg/anet v0.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
+ github.com/xtaci/kcp-go/v5 v5.6.70 // indirect
+ github.com/xtaci/smux v1.5.50 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
+ gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap/exp v0.3.0 // indirect
go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/term v0.40.0 // indirect
- golang.org/x/text v0.34.0 // indirect
- golang.org/x/time v0.11.0 // indirect
- golang.org/x/tools v0.42.0 // indirect
+ golang.org/x/time v0.14.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
+ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- lukechampine.com/blake3 v1.3.0 // indirect
+ gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
+ lukechampine.com/blake3 v1.4.1
+ tailscale.com v1.58.2 // indirect
+ zombiezen.com/go/capnproto2 v2.18.2+incompatible // indirect
)
+
+replace github.com/sagernet/sing-vmess => github.com/starifly/sing-vmess v0.2.7-mod.9
+
+replace github.com/Diniboy1123/connect-ip-go => github.com/shtorm-7/connect-ip-go v1.0.0-extended-1.0.0
+
+replace github.com/sagernet/sing-dns => github.com/shtorm-7/sing-dns v0.4.6-extended-1.0.0
+
+replace github.com/ameshkov/dnscrypt/v2 => github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0
+
+// replace github.com/sagernet/wireguard-go => github.com/hiddify/wireguard-go v0.0.0-20260207195137-b12022450359
+replace github.com/sagernet/wireguard-go => ./replace/wireguard-go
+
+replace github.com/sagernet/tailscale => ./replace/tailscale
+
+replace github.com/Psiphon-Labs/quic-go => ./replace/psiphon-quic-go
+
+replace github.com/Psiphon-Labs/psiphon-tls => ./replace/psiphon-tls
+
+replace github.com/net2share/vaydns => github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9
+
+replace github.com/kianmhz/GooseRelayVPN => github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c
diff --git a/go.sum b/go.sum
index 4ae93f7b99..614319a679 100644
--- a/go.sum
+++ b/go.sum
@@ -1,33 +1,94 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
code.pfad.fr/check v1.1.0 h1:GWvjdzhSEgHvEHe2uJujDcpmZoySKuHQNrZMfzfO0bE=
code.pfad.fr/check v1.1.0/go.mod h1:NiUH13DtYsb7xp5wll0U4SXx7KhXQVCtRgdC96IPfoM=
+filippo.io/bigmod v0.0.1 h1:OaEqDr3gEbofpnHbGqZweSL/bLMhy1pb54puiCDeuOA=
+filippo.io/bigmod v0.0.1/go.mod h1:KyzqAbH7bRH6MOuOF1TPfUjvLoi0mRF2bIyD2ouRNQI=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
+filippo.io/keygen v0.0.0-20230306160926-5201437acf8e h1:+xwUCyMiCWKWsI0RowhzB4sngpUdMHgU6lLuWJCX5Dg=
+filippo.io/keygen v0.0.0-20230306160926-5201437acf8e/go.mod h1:ZGSiF/b2hd6MRghF/cid0vXw8pXykRTmIu+JSPw/NCQ=
+github.com/AdguardTeam/golibs v0.32.7 h1:3dmGlAVgmvquCCwHsvEl58KKcRAK3z1UnjMnwSIeDH4=
+github.com/AdguardTeam/golibs v0.32.7/go.mod h1:bE8KV1zqTzgZjmjFyBJ9f9O5DEKO717r7e57j1HclJA=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/Jigsaw-Code/outline-sdk v0.0.20 h1:4ep7MK9lFmcyPIRIbn4xrP1VKdJNsqR6+iJEOHDKnNg=
+github.com/Jigsaw-Code/outline-sdk v0.0.20/go.mod h1:CFDKyGZA4zatKE4vMLe8TyQpZCyINOeRFbMAmYHxodw=
+github.com/Jigsaw-Code/outline-ss-server v1.8.0 h1:6h7CZsyl1vQLz3nvxmL9FbhDug4QxJ1YTxm534eye1E=
+github.com/Jigsaw-Code/outline-ss-server v1.8.0/go.mod h1:slnHH3OZsQmZx/DRKhxvvaGE/8+n3Lkd6363h1ev71E=
+github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/Psiphon-Inc/rotate-safe-writer v0.0.0-20210303140923-464a7a37606e h1:NPfqIbzmijrl0VclX2t8eO5EPBhqe47LLGKpRrcVjXk=
+github.com/Psiphon-Inc/rotate-safe-writer v0.0.0-20210303140923-464a7a37606e/go.mod h1:ZdY5pBfat/WVzw3eXbIf7N1nZN0XD5H5+X8ZMDWbCs4=
+github.com/Psiphon-Inc/uds-ipc v1.0.1 h1:K3Z0cS1XfzDdhxWTIwh/hiLrkRR83ZxUo2bqgBOGuZE=
+github.com/Psiphon-Inc/uds-ipc v1.0.1/go.mod h1:R8TGG+OXumorJdpAcSFE4SVTT2frMFEGY43Zc/44sNk=
+github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7 h1:Hx/NCZTnvoKZuIBwSmxE58KKoNLXIGG6hBJYN7pj9Ag=
+github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7/go.mod h1:alTtZBo3j4AWFvUrAH6F5ZaHcTj4G5Y01nHz8dkU6vU=
+github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737 h1:QTMy7Uc2Xc7fz6O/Khy1xi0VBND13GqzLUE2mHw6HUU=
+github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737/go.mod h1:Enj/Gszv2zCbuRbHbabmNvfO9EM+5kmaGj8CyjwNPlY=
+github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464 h1:VmnMMMheFXwLV0noxYhbJbLmkV4iaVW3xNnj6xcCNHo=
+github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464/go.mod h1:Pe5BqN2DdIdChorAXl6bDaQd/wghpCleJfid2NoSli0=
+github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760 h1:R4O6UNd88eb1s/txuBTg99U/BZrDOGQgJ4pSL2MRBEs=
+github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760/go.mod h1:FcBjozoGjC2I7ZID0lXFlVQcy/jx6irCzlPxapGebEY=
+github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d h1:PlKwrArEuQOVqEmThSs9KsXMiBduP8MSu9rlWmQ4jgE=
+github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d/go.mod h1:1vv0gVAzq9e2XYkW8HAKrmtuuZrBdDixQFx5H22KAjI=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A=
github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
-github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
-github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
+github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
+github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
+github.com/amnezia-vpn/amneziawg-go v0.2.17-0.20251219021448-449d7cffd4ad h1:O3bvp109FZxwf3lWDd5lxmQz8NwQJgvk1nd60vnXMgw=
+github.com/amnezia-vpn/amneziawg-go v0.2.17-0.20251219021448-449d7cffd4ad/go.mod h1:aMgOk9MuX0xI7b5TKAYp8pLM54RlXcOPzDvYw3YEO5A=
+github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
+github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/anthropics/anthropic-sdk-go v1.26.0 h1:oUTzFaUpAevfuELAP1sjL6CQJ9HHAfT7CoSYSac11PY=
github.com/anthropics/anthropic-sdk-go v1.26.0/go.mod h1:qUKmaW+uuPB64iy1l+4kOSvaLqPXnHTTBKH6RVZ7q5Q=
github.com/anytls/sing-anytls v0.0.11 h1:w8e9Uj1oP3m4zxkyZDewPk0EcQbvVxb7Nn+rapEx4fc=
github.com/anytls/sing-anytls v0.0.11/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
+github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f h1:SaJ6yqg936TshyeFZqQE+N+9hYkIeL9AMr7S4voCl10=
+github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
+github.com/axiomhq/hyperloglog v0.2.6 h1:sRhvvF3RIXWQgAXaTphLp4yJiX4S0IN3MWTaAgZoRJw=
+github.com/axiomhq/hyperloglog v0.2.6/go.mod h1:YjX/dQqCR/7QYX0g8mu8UZAjpIenz1FKM71UEsjFoTo=
+github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61 h1:BU+NxuoaYPIvvp8NNkNlLr8aA0utGyuunf4Q3LJ0bh0=
+github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
+github.com/biter777/countries v1.7.5 h1:MJ+n3+rSxWQdqVJU8eBy9RqcdH6ePPn4PJHocVWUa+Q=
+github.com/biter777/countries v1.7.5/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E=
+github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
+github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
+github.com/bits-and-blooms/bloom/v3 v3.6.0 h1:dTU0OVLJSoOhz9m68FTXMFfA39nR8U/nTCs1zb26mOI=
+github.com/bits-and-blooms/bloom/v3 v3.6.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg=
github.com/caddyserver/certmagic v0.25.2 h1:D7xcS7ggX/WEY54x0czj7ioTkmDWKIgxtIi2OcQclUc=
github.com/caddyserver/certmagic v0.25.2/go.mod h1:llW/CvsNmza8S6hmsuggsZeiX+uS27dkqY27wDIuBWg=
github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE=
github.com/caddyserver/zerossl v0.1.5/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 h1:a1zrFsLFac2xoM6zG1u72DWJwZG3ayttYLfmLbxVETk=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk=
github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
+github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
+github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea h1:9C2rdYRp8Vzwhm3sbFX0yYfB+70zKFRjn7cnPCucHSw=
+github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea/go.mod h1:MdyNkAe06D7xmJsf+MsLvbZKYNXuOHLKJrvw+x4LlcQ=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
+github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc=
+github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
@@ -36,20 +97,50 @@ github.com/database64128/netx-go v0.1.1/go.mod h1:LNlYVipaYkQArRFDNNJ02VkNV+My9A
github.com/database64128/tfo-go/v2 v2.3.2 h1:UhZMKiMq3swZGUiETkLBDzQnZBPSAeBMClpJGlnJ5Fw=
github.com/database64128/tfo-go/v2 v2.3.2/go.mod h1:GC3uB5oa4beGpCUbRb2ZOWP73bJJFmMyAVgQSO7r724=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk=
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ=
+github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
+github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
+github.com/deckarep/golang-set v0.0.0-20171013212420-1d4478f51bed h1:njG8LmGD6JCWJu4bwIKmkOHvch70UOEIqczl5vp7Gok=
+github.com/deckarep/golang-set v0.0.0-20171013212420-1d4478f51bed/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273 h1:45qZ7jowabqhyi3l9Ervox4dhQvLGB5BJPdC8w0a77k=
+github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
+github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
+github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
-github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
-github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
+github.com/dunglas/httpsfv v1.0.2 h1:iERDp/YAfnojSDJ7PW3dj1AReJz4MrwbECSSE59JWL0=
+github.com/dunglas/httpsfv v1.0.2/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
+github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
+github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
+github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d h1:rtM8HsT3NG37YPjz8sYSbUSdElP9lUsQENYzJDZDUBE=
+github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d h1:st1tmvy+4duoRj+RaeeJoECWCWM015fBtf/4aR+hhqk=
+github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/enfein/mieru/v3 v3.27.0 h1:+E/1TF7OfimS2h582atEXQxPtJMyvqUTFBJUgzn1rxg=
+github.com/enfein/mieru/v3 v3.27.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/florianl/go-nfqueue v1.1.1-0.20200829120558-a2f196e98ab0 h1:7ZJyJV4KiWBijCCzUPvVaqxsDxO36+KD0XKBdEN3I+8=
+github.com/florianl/go-nfqueue v1.1.1-0.20200829120558-a2f196e98ab0/go.mod h1:2z3Tfqwv2ueuK6h563xUHRcCh1mv38wS9EjiWiesk84=
github.com/florianl/go-nfqueue/v2 v2.0.2 h1:FL5lQTeetgpCvac1TRwSfgaXUn0YSO7WzGvWNIp3JPE=
github.com/florianl/go-nfqueue/v2 v2.0.2/go.mod h1:VA09+iPOT43OMoCKNfXHyzujQUty2xmzyCRkBOlmabc=
-github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
-github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
+github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
+github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
+github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo=
@@ -70,6 +161,12 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/gobwas/glob v0.2.4-0.20180402141543-f00a7392b439 h1:T6zlOdzrYuHf6HUKujm9bzkzbZ5Iv/xf6rs8BHZDpoI=
+github.com/gobwas/glob v0.2.4-0.20180402141543-f00a7392b439/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
@@ -78,38 +175,84 @@ github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0=
github.com/gofrs/uuid/v5 v5.4.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
+github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI=
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
+github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427 h1:xh96CCAZTX8LJPFoOVRgTwZbn2DvJl8fyCyivohhSIg=
+github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427/go.mod h1:PdjzaU/pJUo4jTIn2rcgMFs+HqBGl/sPJLr8BI0Xq/I=
+github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
+github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU=
github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo=
+github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c h1:9Zc0hJ14G+SNJvGxtaSCSsvGB/RdLltrgjgR//9zgTQ=
+github.com/hiddify/GooseRelayVPN v0.0.0-20260429125124-0e68c2a3ae4c/go.mod h1:LI/1qA7FDU3MumegfyFOHGZCXcOw6rjIk7NPXga3/pQ=
+github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e h1:GsHpSccRtSFe1l3hq0WtBjqsKjJdU+an2D+uCsXm+xk=
+github.com/hiddify/hmrd_multi_resolver_dns v0.0.0-20260429114007-8d809dc33d0e/go.mod h1:7u9Ece+I3gvMFzcpqhROWaykNUyoE21g/fYQMBasAWY=
+github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9 h1:KXnaABX8hHmkcL0jbL769hEIGI5+z/DajCrlO+Bkzcc=
+github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9/go.mod h1:+8kEfQsZJn7/4aIppVekrSuqhrKjGBIgnacTJkdAlS8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91 h1:u9i04mGE3iliBh0EFuWaKsmcwrLacqGmq1G3XoaM7gY=
github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91/go.mod h1:qfvBmyDNp+/liLEYWRvqny/PEz9hGe2Dz833eXILSmo=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
+github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8=
github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I=
github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E=
+github.com/kamstrup/intmap v0.5.2 h1:qnwBm1mh4XAnW9W9Ue9tZtTff8pS6+s6iKF6JRIV2Dk=
+github.com/kamstrup/intmap v0.5.2/go.mod h1:gWUVWHKzWj8xpJVFf5GC0O26bWmv3GqdnIX/LMT6Aq4=
github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=
github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=
-github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
-github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw=
+github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
+github.com/klauspost/reedsolomon v1.13.0 h1:E0Cmgf2kMuhZTj6eefnvpKC4/Q4jhCi9YIjcZjK4arc=
+github.com/klauspost/reedsolomon v1.13.0/go.mod h1:ggJT9lc71Vu+cSOPBlxGvBN6TfAS77qB4fp8vJ05NSA=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/letsencrypt/challtestsrv v1.4.2 h1:0ON3ldMhZyWlfVNYYpFuWRTmZNnyfiL9Hh5YzC3JVwU=
github.com/letsencrypt/challtestsrv v1.4.2/go.mod h1:GhqMqcSoeGpYd5zX5TgwA6er/1MbWzx/o7yuuVya+Wk=
github.com/letsencrypt/pebble/v2 v2.10.0 h1:Wq6gYXlsY6ubqI3hhxsTzdyotvfdjFBxuwYqCLCnj/U=
@@ -122,8 +265,14 @@ github.com/libdns/cloudflare v0.2.2 h1:XWHv+C1dDcApqazlh08Q6pjytYLgR2a+Y3xrXFu0v
github.com/libdns/cloudflare v0.2.2/go.mod h1:w9uTmRCDlAoafAsTPnn2nJ0XHK/eaUMh86DUk8BWi60=
github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U=
github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
+github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
+github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
+github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a h1:6SRny9FLB1eWasPyDUqBQnMi9NhXU01XIlB0ao89YoI=
+github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a/go.mod h1:TmeOqAKoDinfPfSohs14CO3VcEf7o+Bem6JiNe05yrQ=
github.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco=
github.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
@@ -136,24 +285,110 @@ github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
+github.com/mroth/weightedrand v1.0.0 h1:V8JeHChvl2MP1sAoXq4brElOcza+jxLkRuwvtQu8L3E=
+github.com/mroth/weightedrand v1.0.0/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
+github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
+github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
+github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/openai/openai-go/v3 v3.26.0 h1:bRt6H/ozMNt/dDkN4gobnLqaEGrRGBzmbVs0xxJEnQE=
github.com/openai/openai-go/v3 v3.26.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo=
+github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
+github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pebbe/zmq4 v1.2.10 h1:wQkqRZ3CZeABIeidr3e8uQZMMH5YAykA/WN0L5zkd1c=
+github.com/pebbe/zmq4 v1.2.10/go.mod h1:nqnPueOapVhE2wItZ0uOErngczsJdLOGkebMxaO8r48=
+github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
+github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
+github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
+github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
+github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
+github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
+github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
+github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc=
+github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y=
+github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
+github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
+github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
+github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
+github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
+github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
+github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
+github.com/pion/rtcp v1.2.12 h1:bKWiX93XKgDZENEXCijvHRU/wRifm6JV5DGcH6twtSM=
+github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
+github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/rtp v1.8.5 h1:uYzINfaK+9yWs7r537z/Rc1SvT8ILjBcmDOpJcTB+OU=
+github.com/pion/rtp v1.8.5/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
+github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=
+github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
+github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
+github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
+github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
+github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
+github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
+github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
+github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
+github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
+github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
+github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
+github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
+github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo=
+github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
+github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
+github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
+github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
+github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA=
+github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
+github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
+github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
+github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
+github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
+github.com/reF1nd/sing-snell v0.0.5 h1:UwbSB2GOz6flb/hBOvB978l4SRH/fdx7wmvug0IGlIg=
+github.com/reF1nd/sing-snell v0.0.5/go.mod h1:9GeHBibP7RGZFoj4lgen8Tp5MbfOezw8nYeL6GHS/XA=
+github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2 h1:m2ZH6WV69otVmBpWbk8et3MypHFsjcYXTNrknQKS/PY=
+github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2/go.mod h1:7KuAtYfSL0K0WpCScjN9YKiOZ4AQ/8IzSjUtVwWbSv8=
+github.com/refraction-networking/ed25519 v0.1.2 h1:08kJZUkAlY7a7cZGosl1teGytV+QEoNxPO7NnRvAB+g=
+github.com/refraction-networking/ed25519 v0.1.2/go.mod h1:nxYLUAYt/hmNpAh64PNSQ/tQ9gTIB89wCaGKJlRtZ9I=
+github.com/refraction-networking/gotapdance v1.7.10 h1:vPtvuihP95SqrnnpX//KI1PTqrXCvNnOQslrG4gxsRY=
+github.com/refraction-networking/gotapdance v1.7.10/go.mod h1:N7Xmt+/bLv+1VctiBHtsaL6YBknW2ox5LRLzPTISMzY=
+github.com/refraction-networking/obfs4 v0.1.2 h1:J842O4fGSkd2W8ogYj0KN6gqVVY+Cpqodw9qFGL7wVU=
+github.com/refraction-networking/obfs4 v0.1.2/go.mod h1:wAl/+gWiLsrcykJA3nKJHx89f5/gXGM8UKvty7+mvbM=
+github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo=
+github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0=
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1 h1:qi+ijeREa0yfAaO+NOcZ81gv4uzOfALUIdhkiIFvmG4=
@@ -162,70 +397,70 @@ github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkk
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
-github.com/sagernet/cronet-go v0.0.0-20260513071958-2faf34666c2c h1:JatMWK/reVa5Y+x3D3l49SVtHB/EQUEtQnAFTxPBNxY=
-github.com/sagernet/cronet-go v0.0.0-20260513071958-2faf34666c2c/go.mod h1:T/mwtrpC4JlWfScw73CmSBvHzIvc7BatQ1MhRr+cYNw=
-github.com/sagernet/cronet-go/all v0.0.0-20260513071958-2faf34666c2c h1:F/tL+VzLZ2F4SNZZze6SRSRL/jcX7LwIsuL1+hECiz0=
-github.com/sagernet/cronet-go/all v0.0.0-20260513071958-2faf34666c2c/go.mod h1:GGE1tBbFgHq8kV99AKX1JXFY+9FvgNSK/W6Z5j24Ihc=
-github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260513071149-ade33496efb8 h1:NCKxyAnEkwsEueAEbuuUUjs2FEZAIflr+WN3Mwbvsdg=
-github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260513071149-ade33496efb8/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
-github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260513071149-ade33496efb8 h1:o3AGm7/L/zAdBvPu0u1dFgDR/tH086qyuXZkjLNJ7/E=
-github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
-github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260513071149-ade33496efb8 h1:AeO8yHQj7aNj16fiJNU797alyuM3T+3VASnETHeV220=
-github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260513071149-ade33496efb8/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
-github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260513071149-ade33496efb8 h1:ZgW2/Qq/5Q6eTlW80QXLokU56kfjvbLJSEGYTkcG3hU=
-github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
-github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260513071149-ade33496efb8 h1:orYgvX5X9aUa+sRrAuuqA6PXiiBUI2D367ZJqan4lIU=
-github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
-github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260513071149-ade33496efb8 h1:2w1s3wEk7qW2w4IGwlJflxwXBM97UChNiqAErKpvHr0=
-github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
-github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260513071149-ade33496efb8 h1:22k6CB3d4gHT+SARUh2bgNyGU4QwYupcCdP8cGuwygY=
-github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260513071149-ade33496efb8/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0=
-github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260513071149-ade33496efb8 h1:PkJ5EaqLrv6bNR+MHx1/joJXoRcoYcV7JA4NtXbFQsc=
-github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
-github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260513071149-ade33496efb8 h1:V629H+OQ9yOR2d0Jkq5y42j5btpvoSWJbUaBH7FCGPI=
-github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260513071149-ade33496efb8/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo=
-github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260513071149-ade33496efb8 h1:gfObF5uoqJslCdMRRm2Yo+gmPJQPVlrci5Myrki0Kzk=
-github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260513071149-ade33496efb8/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
-github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260513071149-ade33496efb8 h1:JRPN0RBKvoOBEHezJh/54KD9ftWL7YadtcCgOf/vRnw=
-github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
-github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260513071149-ade33496efb8 h1:mM8gNdFlXSpjZFs9kgaMgW94oTRF8YdEEQgdOp/OEUA=
-github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
-github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260513071149-ade33496efb8 h1:ZtCH0fH07giTK6wqkenA9fdFYt7krjWiyOvC8z9nPwk=
-github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
-github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260513071149-ade33496efb8 h1:Uviqmw+Q4No9kCxJWJ5CYcq6PNHB9f0jQhd15j39+no=
-github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260513071149-ade33496efb8/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
-github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260513071149-ade33496efb8 h1:la4zRTE9zpZCmsixwzKT2LnHuo0e439EmGwOlB1An9Q=
-github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
-github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260513071149-ade33496efb8 h1:KodFGMqn+X2dqET0O3xww3iemAGmpoC8U4JW8gwt0x4=
-github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
-github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260513071149-ade33496efb8 h1:QTk1RXNLOIcorZYcF0rBrwLpCIZCKEA2Jr69eFrt8xg=
-github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
-github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260513071149-ade33496efb8 h1:SXqSlM/GjZFvNdUV3IvHq5gqHfW4iWlQHMGzEsgXGXE=
-github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:Wt5uFdU3tnmm8YzobYewwdF7Mt6SucRQg6xeTNWC3Tk=
-github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260513071149-ade33496efb8 h1:aAgLWpfESvy7rfDVH7ioOZQ7u2kmRsbUqJVrwJtkFWs=
-github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:lyIF6wKBLwWa5ZXaAKbAoewewl+yCHo2iYev39Mbj4E=
-github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260513071149-ade33496efb8 h1:oTLUyhLckc8TZQ8SRCapgTYyRbz1pBpIvzjMCLMPFu8=
-github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260513071149-ade33496efb8/go.mod h1:H46PnSTTZNcZokLLiDeMDaHiS1l14PH3tzWi0eykjD8=
-github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260513071149-ade33496efb8 h1:LHm/85Y3zN0kNgG+li5qHvP3dzvavEytCYzdLtrfrrg=
-github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260513071149-ade33496efb8/go.mod h1:RBhSUDAKWq7fswtV4nQUQhuaTLcX3ettR7teA7/yf2w=
-github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260513071149-ade33496efb8 h1:Pom5TSHV8Cln73uOgQlJ+JtmEu9xh+OuLHWq57dBaVg=
-github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:wRzoIOGG4xbpp3Gh3triLKwMwYriScXzFtunLYhY4w0=
-github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260513071149-ade33496efb8 h1:1pPcb15BonaFl4153tRo7zOJ7U2zD1vjH+5JipSfJ3g=
-github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:LNiZXmWil1OPwKCheqQjtakZlJuKGFz+iv2eGF76Hhs=
-github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260513071149-ade33496efb8 h1:3Dy4exYQ/IVJGcnTtvW3LmjfjDaxFgJT1hn/ALBpd2M=
-github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260513071149-ade33496efb8/go.mod h1:YFDGKTkpkJGc5+hnX/RYosZyTWg9h+68VB55fYRRLYc=
-github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260513071149-ade33496efb8 h1:mo9YMCYTGCRUiWNKtPVQb+qEetufxnch372xUOh9q3M=
-github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260513071149-ade33496efb8/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4=
-github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260513071149-ade33496efb8 h1:mhh3JEDDx68oKT4kfqKlWp5QTyzVR84OS/qgqHYIbq0=
-github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc=
-github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260513071149-ade33496efb8 h1:04KOo38hZojV3bJ5Vqwbpj48ZQy6o7aliYXLN/TNX6g=
-github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260513071149-ade33496efb8/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc=
-github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260513071149-ade33496efb8 h1:p535QakpDZEeBz/BfFZGZo0D+Pdn74TE8UTr6c6MSog=
-github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
-github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260513071149-ade33496efb8 h1:dovTyKHh3toBIUOS70P4Yx+3Baw6Gppsfy1sJbXoAy0=
-github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260513071149-ade33496efb8/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
-github.com/sagernet/fswatch v0.1.2 h1:/TT7k4mkce1qFPxamLO842WjqBgbTBiXP2mlUjp9PFk=
-github.com/sagernet/fswatch v0.1.2/go.mod h1:5BpGmpUQVd3Mc5r313HRpvADHRg3/rKn5QbwFteB880=
+github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa h1:7SehNSF1UHbLZa5dk+1rW1aperffJzl5r6TCJIXtAaY=
+github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw=
+github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa h1:ijk5v9N/akiMgqu734yMpv7Pk9F4Qmjh8Vfdcb4uJHE=
+github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa/go.mod h1:+FENo4+0AOvH9e3oY6/iO7yy7USNt61dgbnI5W0TDZ0=
+github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b h1:O+PkYT88ayVWESX5tqxeMeS9OnzC3ZTic8gYiPJNXT8=
+github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
+github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:o0MsgbsJwYkbqlbfaCvmAwb8/LAXeoSP8NE/aNvR/yY=
+github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
+github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b h1:JEQnc7cRMUahWJFtWY6n0hs1LE0KgyRv3pD0RWS8Yo8=
+github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
+github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:69+AKzuUW9hzw2nU79c2DWfuzrIZ3PJm1KAwXh+7xr0=
+github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
+github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:jp9FHUVTCJQ67Ecw3Inoct6/z1VTFXPtNYpXt47pa4E=
+github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
+github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WN3DZoECd2UbhmYQGpOA4jx4QBXiZuN1DvL/35NT61g=
+github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
+github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:H4RKicwrIa4PwTXZOmXOg85hiCrpeFja4daOlX180pE=
+github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0=
+github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:Rwi+Cu+Hgwj28F1lh837gGqSqn7oU8+r5i3UJyLPkKc=
+github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
+github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:v2wcnPX3gt0PngFYXjXYAiarFckwx3pVAP6ETSpbSWE=
+github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo=
+github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b h1:Bl0zZ3QZq6pPJMbQlYHDhhaGngVefRlFzxWc0p48eHo=
+github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
+github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b h1:vf+MbGv6RvvmXUNvganykBOnDIVXxy8XgtKOOqOcxtE=
+github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
+github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:2IAc1bVFYF+B6hof34ChQKVhw7LElBxEEx7S0n+7o78=
+github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
+github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b h1:NrJaiOS0VLmWTbUHhXDsLTqelmCW4y3xJqptPs4Sx0s=
+github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
+github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b h1:A+ubSkca1nl2cT8pYUqCo1O7M41suNrKpWhZKCM/aIQ=
+github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
+github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WrhGH5FDXlCAoXwN6N44yCMvy6EbIurmTmptkz3mmms=
+github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
+github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b h1:kgwB5p5e0gdVX5iYRE7VbZS/On4qnb4UKonkGPwhkDI=
+github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
+github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b h1:Z3dOeFlRIOeQhSh+mCYDHui1yR3S/Uw8eupczzBvxqw=
+github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
+github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b h1:LPi6jz1k11Q67hm3Pw6aaPJ/Z6e3VtNhzrRjr5/5AQo=
+github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:Wt5uFdU3tnmm8YzobYewwdF7Mt6SucRQg6xeTNWC3Tk=
+github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b h1:55sqihyfXWN7y7p7gOEgtUz9cm1mV3SDQ90/v6ROFaA=
+github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lyIF6wKBLwWa5ZXaAKbAoewewl+yCHo2iYev39Mbj4E=
+github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b h1:OTA1cbv5YIDVsYA8AAXHC4NgEc7b6pDiY+edujLWfJU=
+github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:H46PnSTTZNcZokLLiDeMDaHiS1l14PH3tzWi0eykjD8=
+github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b h1:B/rdD/1A+RgqUYUZcoGhLeMqijnBd1mUt8+5LhOH7j8=
+github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:RBhSUDAKWq7fswtV4nQUQhuaTLcX3ettR7teA7/yf2w=
+github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b h1:QFRWi6FucrODS4xQ8e9GYIzGSeMFO/DAMtTCVeJiCvM=
+github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:wRzoIOGG4xbpp3Gh3triLKwMwYriScXzFtunLYhY4w0=
+github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b h1:2WJjPKZHLNIB4D17c3o9S+SP9kb3Qh0D26oWlun1+pE=
+github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:LNiZXmWil1OPwKCheqQjtakZlJuKGFz+iv2eGF76Hhs=
+github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b h1:cUNTe4gNncRpYL28jzQf6qcJej40zzGQsH0o6CLUGws=
+github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:YFDGKTkpkJGc5+hnX/RYosZyTWg9h+68VB55fYRRLYc=
+github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:+sc1LJF0FjU2hVO5xBqqT+8qzoU08J2uHwxSle2m/Hw=
+github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4=
+github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:+D/uhFxllI/KTLpeNEl8dwF3omPGmUFbrqt5tJkAyp0=
+github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc=
+github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:nSUzzTUAZdqjGGckayk64sz+F0TGJPHvauTiAn27UKk=
+github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc=
+github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:PE/fYBiHzB52gnQMg0soBfQyJCzmWHti48kCe2TBt9w=
+github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
+github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:hy/3lPV11pKAAojDFnb95l9NpwOym6kME7FxS9p8sXs=
+github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
+github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
+github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
github.com/sagernet/gomobile v0.1.12 h1:XwzjZaclFF96deLqwAgK8gU3w0M2A8qxgDmhV+A0wjg=
github.com/sagernet/gomobile v0.1.12/go.mod h1:A8l3FlHi2D/+mfcd4HHvk5DGFPW/ShFb9jHP5VmSiDY=
github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1 h1:AzCE2RhBjLJ4WIWc/GejpNh+z30d5H1hwaB0nD9eY3o=
@@ -236,38 +471,65 @@ github.com/sagernet/nftables v0.3.0-mod.2 h1:ck2KMU02OxL1eDFgGaWYglMDpoOZ7OHzxje
github.com/sagernet/nftables v0.3.0-mod.2/go.mod h1:8kslHG4VvYNihcco+i6uxIX7qbT8A56T0y5q7U44ZaQ=
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 h1:6qvrUW79S+CrPwWz6cMePXohgjHoKxLo3c+MDhNwc3o=
github.com/sagernet/quic-go v0.59.0-sing-box-mod.4/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4=
-github.com/sagernet/sing v0.8.10 h1:V5VZffy8rm4dtBVKIpKa8vibRR2SiJprtu/10DFUalU=
-github.com/sagernet/sing v0.8.10/go.mod h1:olXxWQNqRW/l2Q6JI3b2Qmz8iQnIFlOeeH8bx6JhgUA=
+github.com/sagernet/sing v0.8.11-0.20260514110501-905ad103a4df h1:zSDw1g1JhIEqE/XPC3hW1wMdFPzbVgVJZiV86FAJoNQ=
+github.com/sagernet/sing v0.8.11-0.20260514110501-905ad103a4df/go.mod h1:olXxWQNqRW/l2Q6JI3b2Qmz8iQnIFlOeeH8bx6JhgUA=
+github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9 h1:wWJexq4V7ope1c4XYSqT/hydqd9omdtbDRvSZIOhjfY=
+github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9/go.mod h1:bH2NKX+NpDTY1Zkxfboxw6MXB/ZywaNLmrDJYgKMJ2Y=
github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s=
github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
-github.com/sagernet/sing-quic v0.6.1 h1:lx0tcm99wIA1RkyvILNzRSsMy1k7TTQYIhx71E/WBlw=
-github.com/sagernet/sing-quic v0.6.1/go.mod h1:K5bWvITOm4vE10fwLfrWpw27bCoVJ+tfQ79tOWg+Ko8=
+github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7 h1:hFLPJ21uNZSbRnzhOKz4Zv0b4F93mpDorWyN93BeRcM=
+github.com/sagernet/sing-quic v0.6.2-0.20260525051024-9467ede27fb7/go.mod h1:+oqD54aHel4ALKkp1hVXWCgLU/EjLojvm6AUzDfvj0I=
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI=
github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo=
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
-github.com/sagernet/sing-tun v0.8.9 h1:ixFKKUGdVcJl4wb0xbL36hobiw9l6DIH497EQf5ILpM=
-github.com/sagernet/sing-tun v0.8.9/go.mod h1:QvarqUtHfj1ULaRR+6kZOS/OoCE+pYGq67A5tyIy+dQ=
-github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o=
-github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY=
+github.com/sagernet/sing-tun v0.8.10-0.20260519125758-eb58efc8915d h1:7XmzSeoDAX01aPOKnvUbUHVUJ9fukjFDmBFh1hB4KQA=
+github.com/sagernet/sing-tun v0.8.10-0.20260519125758-eb58efc8915d/go.mod h1:QvarqUtHfj1ULaRR+6kZOS/OoCE+pYGq67A5tyIy+dQ=
github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478=
github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8=
-github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7 h1:8zc1Aph1+ElqF9/7aSPkO0o4vTd+AfQC+CO324mLWGg=
-github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc=
-github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c h1:f9cXNB+IOOPnR8DOLMTpr42jf7naxh5Un5Y09BBf5Cg=
-github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
+github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 h1:ML7ZNtcln5UBo5Wv7RIv9Xg3Pr5VuRCWLFXEwda54Y4=
+github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507/go.mod h1:DbI1gxrXI2jRGw7XGEUZQOOMd6PsnKzRrCKabvvMrwM=
+github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28=
+github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM=
+github.com/shirou/gopsutil/v4 v4.24.5 h1:gGsArG5K6vmsh5hcFOHaPm87UD003CaDMkAOweSQjhM=
+github.com/shirou/gopsutil/v4 v4.24.5/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shtorm-7/connect-ip-go v1.0.0-extended-1.0.0 h1:ws7BIsYLd31Wjifq88BYCHRVlgO+07iwil39s6ERba8=
+github.com/shtorm-7/connect-ip-go v1.0.0-extended-1.0.0/go.mod h1:mRwx4w32qQxsWB2kThuHpbo7iNjJiq1jYWubgqEPjHA=
+github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0 h1:e5s7RKBd2rIPR0StbvZ2vTVtJ5jDTsTk5wtIIapZTRg=
+github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0/go.mod h1:WpEFV2uhebXb8Jhes/5/fSdpmhGV8TL22RDaeWwV6hI=
+github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
+github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
+github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
+github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/starifly/sing-vmess v0.2.7-mod.9 h1:xobAmejSbBQ0A3f/EtJ9cJd3m6gK7dDPccPdeGz7tXY=
+github.com/starifly/sing-vmess v0.2.7-mod.9/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ=
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4=
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4=
@@ -284,6 +546,8 @@ github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:U
github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ=
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
+github.com/things-go/go-socks5 v0.1.1 h1:48hy9cHEXPKeG91G/g4n8zW4uynzPUQy/FkcrJ7r5AY=
+github.com/things-go/go-socks5 v0.1.1/go.mod h1:1YBHVYG7Oli5ae+Pwkp630cPAwY1pjUPmohO1n0Emg0=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
@@ -294,19 +558,48 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
+github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=
+github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
+github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
+github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
+github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
+github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
+github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 h1:9sreu9e9KOihf2Y0NbpyfWhd1XFDcL4GTkPYL4IvMrg=
+github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78/go.mod h1:HazXTRLhXFyq80TQp7PUXi6BKE6mS+ydEdzEqNBKopQ=
+github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
+github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xtaci/kcp-go/v5 v5.6.70 h1:AYX0QZl6PqmNj2IdYGZGuBfZuDUkUfl+eHYNijCqaO0=
+github.com/xtaci/kcp-go/v5 v5.6.70/go.mod h1:9O3D8WR+cyyUjGiTILYfg17vn72otWuXK2AFfqIe6CM=
+github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
+github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
+github.com/xtaci/smux v1.5.50 h1:y/1DlWQC9bnMeZzsyk4oL2hbLK6uVk4BKTz5BeQqUEA=
+github.com/xtaci/smux v1.5.50/go.mod h1:IGQ9QYrBphmb/4aTnLEcJby0TNr3NV+OslIOMrX825Q=
+github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
+github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
+github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
+github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
+gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 h1:rzdY78Ox2T+VlXcxGxELF+6VyUXlZBhmRqZu5etLm+c=
+gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0/go.mod h1:70bhd4JKW/+1HLfm+TMrgHJsUHG4coelMWwiVEJ2gAg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
@@ -319,8 +612,12 @@ go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2W
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
+go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
@@ -332,72 +629,178 @@ go4.org/mem v0.0.0-20240501181205-ae6ca9944745 h1:Tl++JLUCe4sxGu8cTpDzRLd3tN7US4
go4.org/mem v0.0.0-20240501181205-ae6ca9944745/go.mod h1:reUoABIJ9ikfM5sgtSF3Wushcza7+WeD01VB9Lirh3g=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
-golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
-golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
+golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU=
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10/go.mod h1:T97yPqesLiNrOYxkwmhMI0ZIlJDm+p0PMR8eRVeR5tQ=
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE=
+gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
-lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
-lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
+lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
+tailscale.com v1.58.2 h1:5trkhh/fpUn7f6TUcGUQYJ0GokdNNfNrjh9ONJhoc5A=
+tailscale.com v1.58.2/go.mod h1:faWR8XaXemnSKCDjHC7SAQzaagkUjA5x4jlLWiwxtuk=
+zombiezen.com/go/capnproto2 v2.18.2+incompatible h1:v3BD1zbruvffn7zjJUU5Pn8nZAB11bhZSQC4W+YnnKo=
+zombiezen.com/go/capnproto2 v2.18.2+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=
diff --git a/hiddify/ipinfo/freeipapi.go b/hiddify/ipinfo/freeipapi.go
new file mode 100644
index 0000000000..f119ff0d76
--- /dev/null
+++ b/hiddify/ipinfo/freeipapi.go
@@ -0,0 +1,52 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// FreeIpApiProvider struct and implementation.
+type FreeIpApiProvider struct {
+ BaseProvider
+}
+
+// NewFreeIpApiProvider initializes a new FreeIpApiProvider.
+func NewFreeIpApiProvider() *FreeIpApiProvider {
+ return &FreeIpApiProvider{
+ BaseProvider: BaseProvider{URL: "https://free.freeipapi.com/api/json/"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from freeipapi.com.
+func (p *FreeIpApiProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ipAddress"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["countryCode"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if region, ok := data["regionName"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["cityName"].(string); ok {
+ info.City = city
+ }
+ if latitude, ok := data["latitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["longitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+ if postalCode, ok := data["zipCode"].(string); ok {
+ info.PostalCode = postalCode
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/ipapico.go b/hiddify/ipinfo/ipapico.go
new file mode 100644
index 0000000000..0dcfe66c5f
--- /dev/null
+++ b/hiddify/ipinfo/ipapico.go
@@ -0,0 +1,62 @@
+package ipinfo
+
+import (
+ "context"
+ "strconv"
+ "strings"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// IpApiCoProvider struct and implementation.
+type IpApiCoProvider struct {
+ BaseProvider
+}
+
+func NewIpApiCoProvider() *IpApiCoProvider {
+ return &IpApiCoProvider{
+ BaseProvider: BaseProvider{URL: "https://ipapi.co/json/", UserAgent: "curl/8.7.1"},
+ }
+}
+
+func (p *IpApiCoProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["country_code"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if asnstr, ok := data["asn"].(string); ok {
+ if strings.HasPrefix(asnstr, "AS") {
+ if asn, ok := strconv.ParseInt(strings.TrimPrefix(asnstr, "AS"), 10, 64); ok == nil {
+ info.ASN = int(asn)
+ }
+ }
+ }
+ if org, ok := data["org"].(string); ok {
+ info.Org = org
+ }
+ if latitude, ok := data["latitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["longitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+
+ if postalCode, ok := data["postal"].(string); ok {
+ info.PostalCode = postalCode
+ }
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/ipapicom.go b/hiddify/ipinfo/ipapicom.go
new file mode 100644
index 0000000000..88bb3875a8
--- /dev/null
+++ b/hiddify/ipinfo/ipapicom.go
@@ -0,0 +1,63 @@
+package ipinfo
+
+import (
+ "context"
+ "strconv"
+ "strings"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+type IpApiProvider struct {
+ BaseProvider
+}
+
+// NewIpApiProvider initializes a new IpApiProvider.
+func NewIpApiProvider() *IpApiProvider {
+ return &IpApiProvider{
+ BaseProvider: BaseProvider{URL: "http://ip-api.com/json/"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from ip-api.com.
+func (p *IpApiProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if status, ok := data["status"].(string); ok && status == "success" {
+ if ip, ok := data["query"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["countryCode"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if zip, ok := data["zip"].(string); ok {
+ info.PostalCode = zip
+ }
+ if latitude, ok := data["lat"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["lon"].(float64); ok {
+ info.Longitude = longitude
+ }
+ if org, ok := data["org"].(string); ok {
+ info.Org = org
+ }
+ if asnStr, ok := data["as"].(string); ok && strings.HasPrefix(asnStr, "AS") {
+ if asn, err := strconv.ParseInt(strings.TrimPrefix(strings.Fields(asnStr)[0], "AS"), 10, 64); err == nil {
+ info.ASN = int(asn)
+ }
+ }
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/ipinfo.go b/hiddify/ipinfo/ipinfo.go
new file mode 100644
index 0000000000..d30c9d31b3
--- /dev/null
+++ b/hiddify/ipinfo/ipinfo.go
@@ -0,0 +1,223 @@
+package ipinfo
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "math/rand"
+ "net"
+ "net/http"
+ "net/url"
+
+ C "github.com/sagernet/sing-box/constant"
+
+ "github.com/sagernet/sing-box/log"
+
+ "time"
+
+ "github.com/sagernet/sing/common"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+var providers = []Provider{
+ NewFreeIpApiProvider(),
+ NewIpApiCoProvider(),
+ NewIpApiProvider(),
+ NewIpInfoIoProvider(),
+ NewIpSbProvider(),
+ NewIpWhoIsProvider(),
+ // NewCloudflareTraceProvider(),
+ NewCountryIsProvider(),
+ NewMyIPExpertProvider(),
+ NewMyIPioProvider(),
+ NewReallyFreeGeoIPProvider(),
+}
+
+var fallbackProviders = []Provider{
+ NewMyIPProvider(),
+ NewCountryIsProvider(),
+ // NewCloudflareTraceProvider(),
+}
+
+func GetAllIPCheckerDomainsDomains() []string {
+ var domains []string
+ for _, provider := range providers {
+ d, err := url.Parse(provider.GetName())
+ if err == nil {
+ if net.ParseIP(d.Hostname()) == nil {
+ domains = append(domains, d.Hostname())
+ }
+
+ }
+ }
+ return domains
+}
+
+// Provider interface for all IP providers.
+type Provider interface {
+ GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error)
+ GetName() string
+}
+
+// IpInfo stores the IP information from the API response.
+type IpInfo struct {
+ IP string `json:"ip"`
+ CountryCode string `json:"country_code"`
+ Region string `json:"region,omitempty"`
+ City string `json:"city,omitempty"`
+ ASN int `json:"asn,omitempty"`
+ Org string `json:"org,omitempty"`
+ Latitude float64 `json:"latitude,omitempty"`
+ Longitude float64 `json:"longitude,omitempty"`
+ PostalCode string `json:"postal_code,omitempty"`
+}
+
+func (ip *IpInfo) String() string {
+ return fmt.Sprintf("IP: %s, Country: %s, Region: %s, City: %s, ASN: %d, Org: %s, Latitude: %.6f, Longitude: %.6f, Postal Code: %s",
+ ip.IP, ip.CountryCode, ip.Region, ip.City, ip.ASN, ip.Org, ip.Latitude, ip.Longitude, ip.PostalCode)
+}
+
+// BaseProvider struct to handle common logic (HTTP request).
+type BaseProvider struct {
+ URL string
+ UserAgent string
+}
+
+func (p *BaseProvider) GetName() string {
+ return p.URL
+}
+
+// fetchData retrieves the data from the provider's URL with a custom user agent and dialer.
+func (p *BaseProvider) fetchData(ctx context.Context, detour N.Dialer) (map[string]interface{}, uint16, error) {
+ link := p.URL
+ linkURL, err := url.Parse(link)
+ if err != nil {
+ return nil, 65535, err
+ }
+ hostname := linkURL.Hostname()
+ port := linkURL.Port()
+ if port == "" {
+ switch linkURL.Scheme {
+ case "http":
+ port = "80"
+ case "https":
+ port = "443"
+ }
+ }
+
+ req, err := http.NewRequest(http.MethodGet, link, nil)
+ if err != nil {
+ return nil, 65535, err
+ }
+ if p.UserAgent == "" {
+ p.UserAgent = C.DefaultBrowserAgent
+ }
+ req.Header.Set("User-Agent", p.UserAgent)
+ start := time.Now()
+ var client http.Client
+ if detour != nil {
+ instance, err := detour.DialContext(ctx, "tcp", M.ParseSocksaddrHostPortStr(hostname, port))
+ if err != nil {
+ return nil, 65535, err
+ }
+ defer instance.Close()
+ if earlyConn, isEarlyConn := common.Cast[N.EarlyConn](instance); isEarlyConn && earlyConn.NeedHandshake() {
+ start = time.Now()
+ }
+
+ client = http.Client{
+ Transport: &http.Transport{
+ DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return instance, nil
+ },
+ },
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+ } else {
+ client = http.Client{
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ }
+ }
+ defer client.CloseIdleConnections()
+ resp, err := client.Do(req.WithContext(ctx))
+ if err != nil {
+ return nil, 65535, err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ return nil, 65535, fmt.Errorf("non-200 response from [%s]: %d", p.URL, resp.StatusCode)
+ }
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, 65535, fmt.Errorf("failed to read response from [%s]: %v", p.URL, err)
+ }
+ t := uint16(time.Since(start) / time.Millisecond)
+ var jsonResponse map[string]interface{}
+ err = json.Unmarshal(body, &jsonResponse)
+ if err != nil {
+ return nil, 65535, fmt.Errorf("failed to parse JSON from [%s]: %v", p.URL, err)
+ }
+
+ return jsonResponse, t, nil
+
+}
+
+// getCurrentIpInfo iterates over the providers to fetch and parse IP information.
+func GetIpInfo(logger log.Logger, ctx context.Context, detour N.Dialer) (*IpInfo, uint16, error) {
+ var lastErr error
+ startIndex := rand.Intn(len(providers))
+ for i := 0; i < len(providers); i++ {
+ select {
+ case <-ctx.Done():
+ return nil, 65535, ctx.Err()
+ default:
+ }
+ provider := providers[(i+startIndex)%len(providers)]
+ testCtx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
+ ipInfo, t, err := provider.GetIPInfo(testCtx, detour)
+ cancel()
+ if err != nil {
+ logger.Warn("Failed try ", i, " to get IP info: ", provider.GetName(), " ", err)
+ lastErr = err
+ continue
+ }
+ return ipInfo, t, nil
+ }
+ startIndex = rand.Intn(len(fallbackProviders))
+ for i := 0; i < len(fallbackProviders); i++ {
+ select {
+ case <-ctx.Done():
+ return nil, 65535, ctx.Err()
+ default:
+ }
+ provider := fallbackProviders[(i+startIndex)%len(fallbackProviders)]
+ testCtx, cancel := context.WithTimeout(ctx, C.TCPTimeout)
+ ipInfo, t, err := provider.GetIPInfo(testCtx, detour)
+ cancel()
+ if err != nil {
+ logger.Warn("Failed try ", i, " to get IP info: ", provider.GetName(), " ", err)
+ continue
+ }
+ return ipInfo, t, nil
+ }
+ return nil, 65535, fmt.Errorf("unable to retrieve IP info: %v", lastErr)
+}
+
+// func init() {
+// // Instantiate the providers.
+
+// for _, provider := range providers {
+// x, _, err := provider.GetIPInfo(context.Background(), nil)
+// fmt.Printf("%s: %++v\n%++v\n", provider, x, err)
+// }
+// // Get IP information.
+
+// os.Exit(0)
+// }
diff --git a/hiddify/ipinfo/ipinfoio.go b/hiddify/ipinfo/ipinfoio.go
new file mode 100644
index 0000000000..1749dc40a0
--- /dev/null
+++ b/hiddify/ipinfo/ipinfoio.go
@@ -0,0 +1,70 @@
+package ipinfo
+
+import (
+ "context"
+ "strconv"
+ "strings"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// IpInfoIoProvider struct and implementation.
+type IpInfoIoProvider struct {
+ BaseProvider
+}
+
+func NewIpInfoIoProvider() *IpInfoIoProvider {
+ return &IpInfoIoProvider{
+ BaseProvider: BaseProvider{URL: "http://ipinfo.io/json"},
+ }
+}
+
+func (p *IpInfoIoProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if country, ok := data["country"].(string); ok {
+ info.CountryCode = country
+ }
+ if loc, ok := data["loc"].(string); ok {
+ // Split loc into latitude and longitude
+ coords := strings.Split(loc, ",")
+ if len(coords) == 2 {
+ if latitude, err := strconv.ParseFloat(coords[0], 64); err == nil {
+ info.Latitude = latitude
+ }
+ if longitude, err := strconv.ParseFloat(coords[1], 64); err == nil {
+ info.Longitude = longitude
+ }
+ }
+ }
+ if org, ok := data["org"].(string); ok {
+ // Split the org string to extract ASN and Organization
+ orgParts := strings.SplitN(org, " ", 2) // Split into 2 parts
+ if len(orgParts) > 0 {
+ if strings.HasPrefix(orgParts[0], "AS") {
+ if asn, ok := strconv.ParseInt(strings.TrimPrefix(orgParts[0], "AS"), 10, 64); ok == nil {
+ info.ASN = int(asn)
+ }
+ }
+ }
+ info.Org = orgParts[len(orgParts)-1]
+ }
+ if postal, ok := data["postal"].(string); ok {
+ info.PostalCode = postal
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/ipsb.go b/hiddify/ipinfo/ipsb.go
new file mode 100644
index 0000000000..17c5a3dcd6
--- /dev/null
+++ b/hiddify/ipinfo/ipsb.go
@@ -0,0 +1,55 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// IpSbProvider struct and implementation.
+type IpSbProvider struct {
+ BaseProvider
+}
+
+func NewIpSbProvider() *IpSbProvider {
+ return &IpSbProvider{
+ BaseProvider: BaseProvider{URL: "https://api.ip.sb/geoip/"},
+ }
+}
+
+func (p *IpSbProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["country_code"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if asn, ok := data["asn"].(float64); ok {
+ info.ASN = int(asn)
+ }
+ if org, ok := data["asn_organization"].(string); ok {
+ info.Org = org
+ }
+ if latitude, ok := data["latitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["longitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+ if postalCode, ok := data["postal_code"].(string); ok {
+ info.PostalCode = postalCode
+ }
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/ipwhois.go b/hiddify/ipinfo/ipwhois.go
new file mode 100644
index 0000000000..509a36dcc5
--- /dev/null
+++ b/hiddify/ipinfo/ipwhois.go
@@ -0,0 +1,59 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// IpWhoIsProvider struct and implementation.
+type IpWhoIsProvider struct {
+ BaseProvider
+}
+
+func NewIpWhoIsProvider() *IpWhoIsProvider {
+ return &IpWhoIsProvider{
+ BaseProvider: BaseProvider{URL: "http://ipwho.is/"},
+ }
+}
+
+func (p *IpWhoIsProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["country_code"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+
+ if connection, ok := data["connection"].(map[string]interface{}); ok {
+ if asn, ok := connection["asn"].(float64); ok {
+ info.ASN = int(asn)
+ }
+ if org, ok := connection["org"].(string); ok {
+ info.Org = org
+ }
+ }
+
+ if latitude, ok := data["latitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["longitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+ if postalCode, ok := data["postal"].(string); ok {
+ info.PostalCode = postalCode
+ }
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/limited_cloudflare.go b/hiddify/ipinfo/limited_cloudflare.go
new file mode 100644
index 0000000000..b5c9affe2b
--- /dev/null
+++ b/hiddify/ipinfo/limited_cloudflare.go
@@ -0,0 +1,39 @@
+package ipinfo
+
+// // CloudflareTraceProvider struct and implementation.
+// type CloudflareTraceProvider struct {
+// BaseProvider
+// }
+
+// // NewCloudflareTraceProvider initializes a new CloudflareTraceProvider.
+// func NewCloudflareTraceProvider() *CloudflareTraceProvider {
+// return &CloudflareTraceProvider{
+// BaseProvider: BaseProvider{URL: "https://cloudflare.com/cdn-cgi/trace"},
+// }
+// }
+
+// // GetIPInfo fetches and parses IP information from Cloudflare's trace endpoint.
+// func (p *CloudflareTraceProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+// info := &IpInfo{}
+// data, t, err := p.fetchData(ctx, dialer)
+// if err != nil {
+// return nil, t, err
+// }
+
+// // Parse the plain text response.
+// for _, line := range strings.Split(string(data), "\n") {
+// parts := strings.SplitN(line, "=", 2)
+// if len(parts) != 2 {
+// continue
+// }
+// key, value := parts[0], parts[1]
+// switch key {
+// case "ip":
+// info.IP = value
+// case "loc":
+// info.CountryCode = value
+// }
+// }
+
+// return info, t, nil
+// }
diff --git a/hiddify/ipinfo/limited_countryis.go b/hiddify/ipinfo/limited_countryis.go
new file mode 100644
index 0000000000..a5bbdeddb5
--- /dev/null
+++ b/hiddify/ipinfo/limited_countryis.go
@@ -0,0 +1,37 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// CountryIsProvider struct and implementation.
+type CountryIsProvider struct {
+ BaseProvider
+}
+
+// NewCountryIsProvider initializes a new CountryIsProvider.
+func NewCountryIsProvider() *CountryIsProvider {
+ return &CountryIsProvider{
+ BaseProvider: BaseProvider{URL: "https://api.country.is/"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from country.is.
+func (p *CountryIsProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if country, ok := data["country"].(string); ok {
+ info.CountryCode = country
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/limited_myip.go b/hiddify/ipinfo/limited_myip.go
new file mode 100644
index 0000000000..84f9331894
--- /dev/null
+++ b/hiddify/ipinfo/limited_myip.go
@@ -0,0 +1,37 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// MyIPProvider struct and implementation.
+type MyIPProvider struct {
+ BaseProvider
+}
+
+// NewMyIPProvider initializes a new MyIPProvider.
+func NewMyIPProvider() *MyIPProvider {
+ return &MyIPProvider{
+ BaseProvider: BaseProvider{URL: "https://api.myip.com"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from api.myip.com.
+func (p *MyIPProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["cc"].(string); ok {
+ info.CountryCode = countryCode
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/myipexpert.go b/hiddify/ipinfo/myipexpert.go
new file mode 100644
index 0000000000..91b90f0e43
--- /dev/null
+++ b/hiddify/ipinfo/myipexpert.go
@@ -0,0 +1,66 @@
+package ipinfo
+
+import (
+ "context"
+ "strconv"
+ "strings"
+
+ "github.com/biter777/countries"
+ N "github.com/sagernet/sing/common/network"
+)
+
+// MyIPExpertProvider struct and implementation.
+type MyIPExpertProvider struct {
+ BaseProvider
+}
+
+// NewMyIPExpertProvider initializes a new MyIPExpertProvider.
+func NewMyIPExpertProvider() *MyIPExpertProvider {
+ return &MyIPExpertProvider{
+ BaseProvider: BaseProvider{URL: "https://myip.expert/api/"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from myip.expert.
+func (p *MyIPExpertProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["userIp"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["userCountryCode"].(string); ok {
+ country := countries.ByName(countryCode)
+
+ info.CountryCode = country.Alpha2()
+ }
+ if region, ok := data["userRegion"].(string); ok {
+ info.Region = region
+ }
+
+ if city, ok := data["userCity"].(string); ok {
+ info.City = city
+ }
+ if latitude, ok := data["userLatitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["userLongitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+ // if isp, ok := data["userIsp"].(string); ok {
+ // info.ISP = isp
+ // }
+ if org, ok := data["userOrg"].(string); ok {
+ info.Org = org
+ }
+ if userHost, ok := data["userHost"].(string); ok && strings.HasPrefix(userHost, "AS") {
+ if asn, err := strconv.ParseInt(strings.TrimPrefix(strings.Fields(userHost)[0], "AS"), 10, 64); err == nil {
+ info.ASN = int(asn)
+ }
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/myipio.go b/hiddify/ipinfo/myipio.go
new file mode 100644
index 0000000000..bdc757ed45
--- /dev/null
+++ b/hiddify/ipinfo/myipio.go
@@ -0,0 +1,63 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// MyIPioProvider struct and implementation.
+type MyIPioProvider struct {
+ BaseProvider
+}
+
+// NewMyIPioProvider initializes a new MyIPioProvider.
+func NewMyIPioProvider() *MyIPioProvider {
+ return &MyIPioProvider{
+ BaseProvider: BaseProvider{URL: "https://api.my-ip.io/v2/ip.json"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from api.my-ip.io.
+func (p *MyIPioProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if success, ok := data["success"].(bool); ok && success {
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if country, ok := data["country"].(map[string]interface{}); ok {
+ if code, ok := country["code"].(string); ok {
+ info.CountryCode = code
+ }
+ }
+ if region, ok := data["region"].(string); ok {
+ info.Region = region
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if location, ok := data["location"].(map[string]interface{}); ok {
+ if lat, ok := location["lat"].(float64); ok {
+ info.Latitude = lat
+ }
+ if lon, ok := location["lon"].(float64); ok {
+ info.Longitude = lon
+ }
+ }
+ if asn, ok := data["asn"].(map[string]interface{}); ok {
+ if asnNumber, ok := asn["number"].(float64); ok {
+ info.ASN = int(asnNumber)
+ }
+ if asnName, ok := asn["name"].(string); ok {
+ info.Org = asnName
+ }
+ }
+ }
+
+ return info, t, nil
+}
diff --git a/hiddify/ipinfo/realyfreegeoip.go b/hiddify/ipinfo/realyfreegeoip.go
new file mode 100644
index 0000000000..bcdc0cbcf4
--- /dev/null
+++ b/hiddify/ipinfo/realyfreegeoip.go
@@ -0,0 +1,52 @@
+package ipinfo
+
+import (
+ "context"
+
+ N "github.com/sagernet/sing/common/network"
+)
+
+// ReallyFreeGeoIPProvider struct and implementation.
+type ReallyFreeGeoIPProvider struct {
+ BaseProvider
+}
+
+// NewReallyFreeGeoIPProvider initializes a new ReallyFreeGeoIPProvider.
+func NewReallyFreeGeoIPProvider() *ReallyFreeGeoIPProvider {
+ return &ReallyFreeGeoIPProvider{
+ BaseProvider: BaseProvider{URL: "https://reallyfreegeoip.org/json/"},
+ }
+}
+
+// GetIPInfo fetches and parses IP information from reallyfreegeoip.org.
+func (p *ReallyFreeGeoIPProvider) GetIPInfo(ctx context.Context, dialer N.Dialer) (*IpInfo, uint16, error) {
+ info := &IpInfo{}
+ data, t, err := p.fetchData(ctx, dialer)
+ if err != nil {
+ return nil, t, err
+ }
+
+ if ip, ok := data["ip"].(string); ok {
+ info.IP = ip
+ }
+ if countryCode, ok := data["country_code"].(string); ok {
+ info.CountryCode = countryCode
+ }
+ if regionCode, ok := data["region_name"].(string); ok {
+ info.Region = regionCode
+ }
+ if city, ok := data["city"].(string); ok {
+ info.City = city
+ }
+ if zipCode, ok := data["zip_code"].(string); ok {
+ info.PostalCode = zipCode
+ }
+ if latitude, ok := data["latitude"].(float64); ok {
+ info.Latitude = latitude
+ }
+ if longitude, ok := data["longitude"].(float64); ok {
+ info.Longitude = longitude
+ }
+
+ return info, t, nil
+}
diff --git a/include/acme.go b/include/acme.go
new file mode 100644
index 0000000000..093fd50823
--- /dev/null
+++ b/include/acme.go
@@ -0,0 +1,12 @@
+//go:build with_acme
+
+package include
+
+import (
+ "github.com/sagernet/sing-box/adapter/certificate"
+ "github.com/sagernet/sing-box/service/acme"
+)
+
+func registerACMECertificateProvider(registry *certificate.Registry) {
+ acme.RegisterCertificateProvider(registry)
+}
diff --git a/include/acme_stub.go b/include/acme_stub.go
new file mode 100644
index 0000000000..bceab3d731
--- /dev/null
+++ b/include/acme_stub.go
@@ -0,0 +1,20 @@
+//go:build !with_acme
+
+package include
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func registerACMECertificateProvider(registry *certificate.Registry) {
+ certificate.Register[option.ACMECertificateProviderOptions](registry, C.TypeACME, func(ctx context.Context, logger log.ContextLogger, tag string, options option.ACMECertificateProviderOptions) (adapter.CertificateProviderService, error) {
+ return nil, E.New(`ACME is not included in this build, rebuild with -tags with_acme`)
+ })
+}
diff --git a/include/awg.go b/include/awg.go
new file mode 100644
index 0000000000..9e37665cb3
--- /dev/null
+++ b/include/awg.go
@@ -0,0 +1,12 @@
+//go:build with_awg
+
+package include
+
+import (
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/protocol/awg"
+)
+
+func registerAwgEndpoint(registry *endpoint.Registry) {
+ awg.RegisterEndpoint(registry)
+}
diff --git a/include/awg_stub.go b/include/awg_stub.go
new file mode 100644
index 0000000000..8c24fc6ff0
--- /dev/null
+++ b/include/awg_stub.go
@@ -0,0 +1,20 @@
+//go:build !with_awg
+
+package include
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func registerAwgEndpoint(registry *endpoint.Registry) {
+ endpoint.Register(registry, C.TypeAwg, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.AwgEndpointOptions) (adapter.Endpoint, error) {
+ return nil, E.New(`Awg is not included in this build, rebuild with -tags with_awg`)
+ })
+}
diff --git a/include/cloudflared.go b/include/cloudflared.go
new file mode 100644
index 0000000000..6320010825
--- /dev/null
+++ b/include/cloudflared.go
@@ -0,0 +1,12 @@
+//go:build with_cloudflared
+
+package include
+
+import (
+ "github.com/sagernet/sing-box/adapter/inbound"
+ "github.com/sagernet/sing-box/protocol/cloudflare"
+)
+
+func registerCloudflaredInbound(registry *inbound.Registry) {
+ cloudflare.RegisterInbound(registry)
+}
diff --git a/include/cloudflared_stub.go b/include/cloudflared_stub.go
new file mode 100644
index 0000000000..8f49aecc69
--- /dev/null
+++ b/include/cloudflared_stub.go
@@ -0,0 +1,20 @@
+//go:build !with_cloudflared
+
+package include
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func registerCloudflaredInbound(registry *inbound.Registry) {
+ inbound.Register[option.CloudflaredInboundOptions](registry, C.TypeCloudflared, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.CloudflaredInboundOptions) (adapter.Inbound, error) {
+ return nil, E.New(`Cloudflared is not included in this build, rebuild with -tags with_cloudflared`)
+ })
+}
diff --git a/include/masque.go b/include/masque.go
new file mode 100644
index 0000000000..fdd75d9883
--- /dev/null
+++ b/include/masque.go
@@ -0,0 +1,12 @@
+//go:build with_masque
+
+package include
+
+import (
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/protocol/masque"
+)
+
+func registerMASQUEOutbound(registry *outbound.Registry) {
+ masque.RegisterOutbound(registry)
+}
diff --git a/include/masque_stub.go b/include/masque_stub.go
new file mode 100644
index 0000000000..fc31da68f0
--- /dev/null
+++ b/include/masque_stub.go
@@ -0,0 +1,20 @@
+//go:build !with_masque
+
+package include
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func registerMASQUEOutbound(registry *outbound.Registry) {
+ outbound.Register[option.MASQUEOutboundOptions](registry, C.TypeMASQUE, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.MASQUEOutboundOptions) (adapter.Outbound, error) {
+ return nil, E.New(`MASQUE outbound is not included in this build, rebuild with -tags with_masque`)
+ })
+}
diff --git a/include/quic.go b/include/quic.go
index 6a3f301755..42182c299d 100644
--- a/include/quic.go
+++ b/include/quic.go
@@ -5,6 +5,7 @@ package include
import (
"github.com/sagernet/sing-box/adapter/inbound"
"github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/adapter/service"
"github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/dns/transport/quic"
"github.com/sagernet/sing-box/protocol/hysteria"
@@ -30,3 +31,7 @@ func registerQUICTransports(registry *dns.TransportRegistry) {
quic.RegisterTransport(registry)
quic.RegisterHTTP3Transport(registry)
}
+
+func registerQUICServices(registry *service.Registry) {
+ hysteria2.RegisterRealmService(registry)
+}
diff --git a/include/quic_stub.go b/include/quic_stub.go
index d2c03b98e4..b603cf48d0 100644
--- a/include/quic_stub.go
+++ b/include/quic_stub.go
@@ -10,6 +10,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/inbound"
"github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/adapter/service"
"github.com/sagernet/sing-box/common/listener"
"github.com/sagernet/sing-box/common/tls"
C "github.com/sagernet/sing-box/constant"
@@ -69,3 +70,9 @@ func registerQUICTransports(registry *dns.TransportRegistry) {
return nil, C.ErrQUICNotIncluded
})
}
+
+func registerQUICServices(registry *service.Registry) {
+ service.Register[option.HysteriaRealmServiceOptions](registry, C.TypeHysteriaRealm, func(ctx context.Context, logger log.ContextLogger, tag string, options option.HysteriaRealmServiceOptions) (adapter.Service, error) {
+ return nil, C.ErrQUICNotIncluded
+ })
+}
diff --git a/include/registry.go b/include/registry.go
index f090845b51..be39effed6 100644
--- a/include/registry.go
+++ b/include/registry.go
@@ -3,8 +3,9 @@ package include
import (
"context"
- "github.com/sagernet/sing-box"
+ box "github.com/sagernet/sing-box"
"github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/adapter/inbound"
"github.com/sagernet/sing-box/adapter/outbound"
@@ -15,32 +16,46 @@ import (
"github.com/sagernet/sing-box/dns/transport/fakeip"
"github.com/sagernet/sing-box/dns/transport/hosts"
"github.com/sagernet/sing-box/dns/transport/local"
+ "github.com/sagernet/sing-box/dns/transport/multi"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/anytls"
"github.com/sagernet/sing-box/protocol/block"
"github.com/sagernet/sing-box/protocol/direct"
"github.com/sagernet/sing-box/protocol/group"
+ "github.com/sagernet/sing-box/protocol/group/balancer"
+ "github.com/sagernet/sing-box/protocol/hiddify/dnstt"
+ "github.com/sagernet/sing-box/protocol/hiddify/gooserelay"
+ "github.com/sagernet/sing-box/protocol/hiddify/hinvalid"
+
+ "github.com/sagernet/sing-box/protocol/hiddify/xray"
"github.com/sagernet/sing-box/protocol/http"
+ "github.com/sagernet/sing-box/protocol/mieru"
"github.com/sagernet/sing-box/protocol/mixed"
"github.com/sagernet/sing-box/protocol/naive"
+ "github.com/sagernet/sing-box/protocol/psiphon"
"github.com/sagernet/sing-box/protocol/redirect"
"github.com/sagernet/sing-box/protocol/shadowsocks"
"github.com/sagernet/sing-box/protocol/shadowtls"
+ snellprotocol "github.com/sagernet/sing-box/protocol/snell"
"github.com/sagernet/sing-box/protocol/socks"
"github.com/sagernet/sing-box/protocol/ssh"
"github.com/sagernet/sing-box/protocol/tor"
"github.com/sagernet/sing-box/protocol/trojan"
"github.com/sagernet/sing-box/protocol/tun"
+ "github.com/sagernet/sing-box/protocol/firebasetunnel"
+ "github.com/sagernet/sing-box/protocol/tunnel"
"github.com/sagernet/sing-box/protocol/vless"
"github.com/sagernet/sing-box/protocol/vmess"
+ originca "github.com/sagernet/sing-box/service/origin_ca"
"github.com/sagernet/sing-box/service/resolved"
+ smartdnspool "github.com/sagernet/sing-box/service/smart_dns_pool"
"github.com/sagernet/sing-box/service/ssmapi"
E "github.com/sagernet/sing/common/exceptions"
)
func Context(ctx context.Context) context.Context {
- return box.Context(ctx, InboundRegistry(), OutboundRegistry(), EndpointRegistry(), DNSTransportRegistry(), ServiceRegistry())
+ return box.Context(ctx, InboundRegistry(), OutboundRegistry(), EndpointRegistry(), DNSTransportRegistry(), ServiceRegistry(), CertificateProviderRegistry())
}
func InboundRegistry() *inbound.Registry {
@@ -62,8 +77,13 @@ func InboundRegistry() *inbound.Registry {
shadowtls.RegisterInbound(registry)
vless.RegisterInbound(registry)
anytls.RegisterInbound(registry)
+ mieru.RegisterInbound(registry)
+ ssh.RegisterInbound(registry)
+ snellprotocol.RegisterInbound(registry)
+ firebasetunnel.RegisterInbound(registry)
registerQUICInbounds(registry)
+ registerCloudflaredInbound(registry)
registerStubForRemovedInbounds(registry)
return registry
@@ -89,8 +109,18 @@ func OutboundRegistry() *outbound.Registry {
ssh.RegisterOutbound(registry)
shadowtls.RegisterOutbound(registry)
vless.RegisterOutbound(registry)
+ psiphon.RegisterOutbound(registry)
+ mieru.RegisterOutbound(registry)
anytls.RegisterOutbound(registry)
-
+ hinvalid.RegisterOutbound(registry)
+ xray.RegisterOutbound(registry)
+ dnstt.RegisterOutbound(registry)
+ gooserelay.RegisterOutbound(registry)
+ firebasetunnel.RegisterOutbound(registry)
+ balancer.RegisterLoadBalance(registry)
+ snellprotocol.RegisterOutbound(registry)
+
+ registerMASQUEOutbound(registry)
registerQUICOutbounds(registry)
registerStubForRemovedOutbounds(registry)
@@ -100,8 +130,12 @@ func OutboundRegistry() *outbound.Registry {
func EndpointRegistry() *endpoint.Registry {
registry := endpoint.NewRegistry()
+ tunnel.RegisterServerEndpoint(registry)
+ tunnel.RegisterClientEndpoint(registry)
registerWireGuardEndpoint(registry)
+ registerWarpEndpoint(registry)
registerTailscaleEndpoint(registry)
+ registerAwgEndpoint(registry)
return registry
}
@@ -113,6 +147,9 @@ func DNSTransportRegistry() *dns.TransportRegistry {
transport.RegisterUDP(registry)
transport.RegisterTLS(registry)
transport.RegisterHTTPS(registry)
+ transport.RegisterSDNS(registry)
+
+ multi.RegisterTransport(registry) //H
hosts.RegisterTransport(registry)
local.RegisterTransport(registry)
fakeip.RegisterTransport(registry)
@@ -130,6 +167,7 @@ func ServiceRegistry() *service.Registry {
resolved.RegisterService(registry)
ssmapi.RegisterService(registry)
+ smartdnspool.RegisterService(registry) //H
registerDERPService(registry)
registerCCMService(registry)
@@ -139,6 +177,16 @@ func ServiceRegistry() *service.Registry {
return registry
}
+func CertificateProviderRegistry() *certificate.Registry {
+ registry := certificate.NewRegistry()
+
+ registerACMECertificateProvider(registry)
+ registerTailscaleCertificateProvider(registry)
+ originca.RegisterCertificateProvider(registry)
+
+ return registry
+}
+
func registerStubForRemovedInbounds(registry *inbound.Registry) {
inbound.Register[option.ShadowsocksInboundOptions](registry, C.TypeShadowsocksR, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (adapter.Inbound, error) {
return nil, E.New("ShadowsocksR is deprecated and removed in sing-box 1.6.0")
diff --git a/include/tailscale.go b/include/tailscale.go
index 1757283b07..6f85aaac14 100644
--- a/include/tailscale.go
+++ b/include/tailscale.go
@@ -3,6 +3,7 @@
package include
import (
+ "github.com/sagernet/sing-box/adapter/certificate"
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/adapter/service"
"github.com/sagernet/sing-box/dns"
@@ -18,6 +19,10 @@ func registerTailscaleTransport(registry *dns.TransportRegistry) {
tailscale.RegistryTransport(registry)
}
+func registerTailscaleCertificateProvider(registry *certificate.Registry) {
+ tailscale.RegisterCertificateProvider(registry)
+}
+
func registerDERPService(registry *service.Registry) {
derp.Register(registry)
}
diff --git a/include/tailscale_stub.go b/include/tailscale_stub.go
index 78398875f8..e6f97f1eab 100644
--- a/include/tailscale_stub.go
+++ b/include/tailscale_stub.go
@@ -6,6 +6,7 @@ import (
"context"
"github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/adapter/service"
C "github.com/sagernet/sing-box/constant"
@@ -27,6 +28,12 @@ func registerTailscaleTransport(registry *dns.TransportRegistry) {
})
}
+func registerTailscaleCertificateProvider(registry *certificate.Registry) {
+ certificate.Register[option.TailscaleCertificateProviderOptions](registry, C.TypeTailscale, func(ctx context.Context, logger log.ContextLogger, tag string, options option.TailscaleCertificateProviderOptions) (adapter.CertificateProviderService, error) {
+ return nil, E.New(`Tailscale is not included in this build, rebuild with -tags with_tailscale`)
+ })
+}
+
func registerDERPService(registry *service.Registry) {
service.Register[option.DERPServiceOptions](registry, C.TypeDERP, func(ctx context.Context, logger log.ContextLogger, tag string, options option.DERPServiceOptions) (adapter.Service, error) {
return nil, E.New(`DERP is not included in this build, rebuild with -tags with_tailscale`)
diff --git a/include/warp.go b/include/warp.go
new file mode 100644
index 0000000000..d636281b72
--- /dev/null
+++ b/include/warp.go
@@ -0,0 +1,12 @@
+//go:build with_wireguard
+
+package include
+
+import (
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/protocol/warp"
+)
+
+func registerWarpEndpoint(registry *endpoint.Registry) {
+ warp.RegisterWARPEndpoint(registry)
+}
diff --git a/include/warp_stub.go b/include/warp_stub.go
new file mode 100644
index 0000000000..b3769382b1
--- /dev/null
+++ b/include/warp_stub.go
@@ -0,0 +1,20 @@
+//go:build !with_wireguard
+
+package include
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func registerWarpEndpoint(registry *endpoint.Registry) {
+ endpoint.Register[option.WARPEndpointOptions](registry, C.TypeWARP, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WARPEndpointOptions) (adapter.Endpoint, error) {
+ return nil, E.New(`WARP is not included in this build, rebuild with -tags with_wireguard`)
+ })
+}
diff --git a/mkdocs.yml b/mkdocs.yml
index e295926610..d0836c1eb3 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -93,6 +93,7 @@ nav:
- HTTPS: configuration/dns/server/https.md
- HTTP3: configuration/dns/server/http3.md
- DHCP: configuration/dns/server/dhcp.md
+ - mDNS: configuration/dns/server/mdns.md
- FakeIP: configuration/dns/server/fakeip.md
- Tailscale: configuration/dns/server/tailscale.md
- Resolved: configuration/dns/server/resolved.md
@@ -122,6 +123,14 @@ nav:
- Listen Fields: configuration/shared/listen.md
- Dial Fields: configuration/shared/dial.md
- TLS: configuration/shared/tls.md
+ - HTTP Client: configuration/shared/http-client.md
+ - HTTP2 Fields: configuration/shared/http2.md
+ - QUIC Fields: configuration/shared/quic.md
+ - Certificate Provider:
+ - configuration/shared/certificate-provider/index.md
+ - ACME: configuration/shared/certificate-provider/acme.md
+ - Tailscale: configuration/shared/certificate-provider/tailscale.md
+ - Cloudflare Origin CA: configuration/shared/certificate-provider/cloudflare-origin-ca.md
- DNS01 Challenge Fields: configuration/shared/dns01_challenge.md
- Pre-match: configuration/shared/pre-match.md
- Multiplex: configuration/shared/multiplex.md
@@ -129,6 +138,7 @@ nav:
- UDP over TCP: configuration/shared/udp-over-tcp.md
- TCP Brutal: configuration/shared/tcp-brutal.md
- Wi-Fi State: configuration/shared/wifi-state.md
+ - Neighbor Resolution: configuration/shared/neighbor.md
- Endpoint:
- configuration/endpoint/index.md
- WireGuard: configuration/endpoint/wireguard.md
@@ -140,6 +150,7 @@ nav:
- SOCKS: configuration/inbound/socks.md
- HTTP: configuration/inbound/http.md
- Shadowsocks: configuration/inbound/shadowsocks.md
+ - Snell: configuration/inbound/snell.md
- VMess: configuration/inbound/vmess.md
- Trojan: configuration/inbound/trojan.md
- Naive: configuration/inbound/naive.md
@@ -152,6 +163,7 @@ nav:
- Tun: configuration/inbound/tun.md
- Redirect: configuration/inbound/redirect.md
- TProxy: configuration/inbound/tproxy.md
+ - Cloudflared: configuration/inbound/cloudflared.md
- Outbound:
- configuration/outbound/index.md
- Direct: configuration/outbound/direct.md
@@ -159,6 +171,7 @@ nav:
- SOCKS: configuration/outbound/socks.md
- HTTP: configuration/outbound/http.md
- Shadowsocks: configuration/outbound/shadowsocks.md
+ - Snell: configuration/outbound/snell.md
- VMess: configuration/outbound/vmess.md
- Trojan: configuration/outbound/trojan.md
- Naive: configuration/outbound/naive.md
@@ -181,6 +194,7 @@ nav:
- SSM API: configuration/service/ssm-api.md
- CCM: configuration/service/ccm.md
- OCM: configuration/service/ocm.md
+ - Hysteria Realm: configuration/service/hysteria-realm.md
markdown_extensions:
- toc:
slugify: !!python/object/apply:pymdownx.slugs.slugify
@@ -272,6 +286,7 @@ plugins:
Shared: 通用
Listen Fields: 监听字段
Dial Fields: 拨号字段
+ Certificate Provider Fields: 证书提供者字段
DNS01 Challenge Fields: DNS01 验证字段
Multiplex: 多路复用
V2Ray Transport: V2Ray 传输层
@@ -280,6 +295,7 @@ plugins:
Endpoint: 端点
Inbound: 入站
Outbound: 出站
+ Certificate Provider: 证书提供者
Manual: 手册
reconfigure_material: true
diff --git a/option/acme.go b/option/acme.go
new file mode 100644
index 0000000000..31efffce14
--- /dev/null
+++ b/option/acme.go
@@ -0,0 +1,107 @@
+package option
+
+import (
+ "strings"
+
+ C "github.com/sagernet/sing-box/constant"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badjson"
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type ACMECertificateProviderOptions struct {
+ Domain badoption.Listable[string] `json:"domain,omitempty"`
+ DataDirectory string `json:"data_directory,omitempty"`
+ DefaultServerName string `json:"default_server_name,omitempty"`
+ Email string `json:"email,omitempty"`
+ Provider string `json:"provider,omitempty"`
+ AccountKey string `json:"account_key,omitempty"`
+ DisableHTTPChallenge bool `json:"disable_http_challenge,omitempty"`
+ DisableTLSALPNChallenge bool `json:"disable_tls_alpn_challenge,omitempty"`
+ AlternativeHTTPPort uint16 `json:"alternative_http_port,omitempty"`
+ AlternativeTLSPort uint16 `json:"alternative_tls_port,omitempty"`
+ ExternalAccount *ACMEExternalAccountOptions `json:"external_account,omitempty"`
+ DNS01Challenge *ACMEProviderDNS01ChallengeOptions `json:"dns01_challenge,omitempty"`
+ KeyType ACMEKeyType `json:"key_type,omitempty"`
+ Profile string `json:"profile,omitempty"`
+ HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
+}
+
+type _ACMEProviderDNS01ChallengeOptions struct {
+ TTL badoption.Duration `json:"ttl,omitempty"`
+ PropagationDelay badoption.Duration `json:"propagation_delay,omitempty"`
+ PropagationTimeout badoption.Duration `json:"propagation_timeout,omitempty"`
+ Resolvers badoption.Listable[string] `json:"resolvers,omitempty"`
+ OverrideDomain string `json:"override_domain,omitempty"`
+ Provider string `json:"provider,omitempty"`
+ AliDNSOptions ACMEDNS01AliDNSOptions `json:"-"`
+ CloudflareOptions ACMEDNS01CloudflareOptions `json:"-"`
+ ACMEDNSOptions ACMEDNS01ACMEDNSOptions `json:"-"`
+}
+
+type ACMEProviderDNS01ChallengeOptions _ACMEProviderDNS01ChallengeOptions
+
+func (o ACMEProviderDNS01ChallengeOptions) MarshalJSON() ([]byte, error) {
+ var v any
+ switch o.Provider {
+ case C.DNSProviderAliDNS:
+ v = o.AliDNSOptions
+ case C.DNSProviderCloudflare:
+ v = o.CloudflareOptions
+ case C.DNSProviderACMEDNS:
+ v = o.ACMEDNSOptions
+ case "":
+ return nil, E.New("missing provider type")
+ default:
+ return nil, E.New("unknown provider type: ", o.Provider)
+ }
+ return badjson.MarshallObjects((_ACMEProviderDNS01ChallengeOptions)(o), v)
+}
+
+func (o *ACMEProviderDNS01ChallengeOptions) UnmarshalJSON(bytes []byte) error {
+ err := json.Unmarshal(bytes, (*_ACMEProviderDNS01ChallengeOptions)(o))
+ if err != nil {
+ return err
+ }
+ var v any
+ switch o.Provider {
+ case C.DNSProviderAliDNS:
+ v = &o.AliDNSOptions
+ case C.DNSProviderCloudflare:
+ v = &o.CloudflareOptions
+ case C.DNSProviderACMEDNS:
+ v = &o.ACMEDNSOptions
+ case "":
+ return E.New("missing provider type")
+ default:
+ return E.New("unknown provider type: ", o.Provider)
+ }
+ return badjson.UnmarshallExcluded(bytes, (*_ACMEProviderDNS01ChallengeOptions)(o), v)
+}
+
+type ACMEKeyType string
+
+const (
+ ACMEKeyTypeED25519 = ACMEKeyType("ed25519")
+ ACMEKeyTypeP256 = ACMEKeyType("p256")
+ ACMEKeyTypeP384 = ACMEKeyType("p384")
+ ACMEKeyTypeRSA2048 = ACMEKeyType("rsa2048")
+ ACMEKeyTypeRSA4096 = ACMEKeyType("rsa4096")
+)
+
+func (t *ACMEKeyType) UnmarshalJSON(data []byte) error {
+ var value string
+ err := json.Unmarshal(data, &value)
+ if err != nil {
+ return err
+ }
+ value = strings.ToLower(value)
+ switch ACMEKeyType(value) {
+ case "", ACMEKeyTypeED25519, ACMEKeyTypeP256, ACMEKeyTypeP384, ACMEKeyTypeRSA2048, ACMEKeyTypeRSA4096:
+ *t = ACMEKeyType(value)
+ default:
+ return E.New("unknown ACME key type: ", value)
+ }
+ return nil
+}
diff --git a/option/awg.go b/option/awg.go
new file mode 100644
index 0000000000..9216b85c01
--- /dev/null
+++ b/option/awg.go
@@ -0,0 +1,53 @@
+package option
+
+import (
+ "net/netip"
+
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type AwgEndpointOptions struct {
+ UseIntegratedTun bool `json:"useIntegratedTun"`
+ PrivateKey string `json:"private_key"`
+ Address badoption.Listable[netip.Prefix] `json:"address"`
+ MTU uint32 `json:"mtu,omitempty"`
+ ListenPort uint16 `json:"listen_port,omitempty"`
+ Awg AwgOptions `json:"awg,omitempty"`
+ Peers []AwgPeerOptions `json:"peers,omitempty"`
+ DialerOptions
+}
+
+type AwgOptions struct {
+ Jc int `json:"jc,omitempty"`
+ Jmin int `json:"jmin,omitempty"`
+ Jmax int `json:"jmax,omitempty"`
+ S1 int `json:"s1,omitempty"`
+ S2 int `json:"s2,omitempty"`
+ S3 int `json:"s3,omitempty"`
+ S4 int `json:"s4,omitempty"`
+ H1 string `json:"h1,omitempty"`
+ H2 string `json:"h2,omitempty"`
+ H3 string `json:"h3,omitempty"`
+ H4 string `json:"h4,omitempty"`
+ I1 string `json:"i1,omitempty"`
+ I2 string `json:"i2,omitempty"`
+ I3 string `json:"i3,omitempty"`
+ I4 string `json:"i4,omitempty"`
+ I5 string `json:"i5,omitempty"`
+}
+
+func (o *AwgOptions) IsAvailble() bool {
+ if o == nil {
+ return false
+ }
+ return o.Jc != 0 || o.Jmin != 0 || o.Jmax != 0 || o.S1 != 0 || o.S2 != 0 || o.S3 != 0 || o.S4 != 0 || o.H1 != "" || o.H2 != "" || o.H3 != "" || o.H4 != "" || o.I1 != "" || o.I2 != "" || o.I3 != "" || o.I4 != "" || o.I5 != ""
+}
+
+type AwgPeerOptions struct {
+ Address string `json:"address,omitempty"`
+ Port uint16 `json:"port,omitempty"`
+ PublicKey string `json:"public_key,omitempty"`
+ PresharedKey string `json:"preshared_key,omitempty"`
+ AllowedIPs badoption.Listable[netip.Prefix] `json:"allowed_ips,omitempty"`
+ PersistentKeepaliveInterval uint16 `json:"persistent_keepalive_interval,omitempty"`
+}
diff --git a/option/balancer.go b/option/balancer.go
new file mode 100644
index 0000000000..0c9e7ae4b6
--- /dev/null
+++ b/option/balancer.go
@@ -0,0 +1,13 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+type BalancerOutboundOptions struct {
+ Outbounds []string `json:"outbounds"`
+ Tolerance uint16 `json:"tolerance,omitempty"` //not implemented yet
+ InterruptExistConnections bool `json:"interrupt_exist_connections,omitempty"`
+ Strategy string `json:"strategy,omitempty"`
+ DelayAcceptableRatio float64 `json:"delay_acceptable_ratio,omitempty"`
+ TTL badoption.Duration `json:"ttl,omitempty"`
+ MaxRetry int `json:"max_retry,omitempty"` //not implemented yet
+}
diff --git a/option/certificate_provider.go b/option/certificate_provider.go
new file mode 100644
index 0000000000..a24abdc570
--- /dev/null
+++ b/option/certificate_provider.go
@@ -0,0 +1,100 @@
+package option
+
+import (
+ "context"
+
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badjson"
+ "github.com/sagernet/sing/service"
+)
+
+type CertificateProviderOptionsRegistry interface {
+ CreateOptions(providerType string) (any, bool)
+}
+
+type _CertificateProvider struct {
+ Type string `json:"type"`
+ Tag string `json:"tag,omitempty"`
+ Options any `json:"-"`
+}
+
+type CertificateProvider _CertificateProvider
+
+func (h *CertificateProvider) MarshalJSONContext(ctx context.Context) ([]byte, error) {
+ return badjson.MarshallObjectsContext(ctx, (*_CertificateProvider)(h), h.Options)
+}
+
+func (h *CertificateProvider) UnmarshalJSONContext(ctx context.Context, content []byte) error {
+ err := json.UnmarshalContext(ctx, content, (*_CertificateProvider)(h))
+ if err != nil {
+ return err
+ }
+ registry := service.FromContext[CertificateProviderOptionsRegistry](ctx)
+ if registry == nil {
+ return E.New("missing certificate provider options registry in context")
+ }
+ options, loaded := registry.CreateOptions(h.Type)
+ if !loaded {
+ return E.New("unknown certificate provider type: ", h.Type)
+ }
+ err = badjson.UnmarshallExcludedContext(ctx, content, (*_CertificateProvider)(h), options)
+ if err != nil {
+ return err
+ }
+ h.Options = options
+ return nil
+}
+
+type CertificateProviderOptions struct {
+ Tag string `json:"-"`
+ Type string `json:"-"`
+ Options any `json:"-"`
+}
+
+type _CertificateProviderInline struct {
+ Type string `json:"type"`
+}
+
+func (o *CertificateProviderOptions) MarshalJSONContext(ctx context.Context) ([]byte, error) {
+ if o.Tag != "" {
+ return json.Marshal(o.Tag)
+ }
+ return badjson.MarshallObjectsContext(ctx, _CertificateProviderInline{Type: o.Type}, o.Options)
+}
+
+func (o *CertificateProviderOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
+ if len(content) == 0 {
+ return E.New("empty certificate_provider value")
+ }
+ if content[0] == '"' {
+ return json.UnmarshalContext(ctx, content, &o.Tag)
+ }
+ var inline _CertificateProviderInline
+ err := json.UnmarshalContext(ctx, content, &inline)
+ if err != nil {
+ return err
+ }
+ o.Type = inline.Type
+ if o.Type == "" {
+ return E.New("missing certificate provider type")
+ }
+ registry := service.FromContext[CertificateProviderOptionsRegistry](ctx)
+ if registry == nil {
+ return E.New("missing certificate provider options registry in context")
+ }
+ options, loaded := registry.CreateOptions(o.Type)
+ if !loaded {
+ return E.New("unknown certificate provider type: ", o.Type)
+ }
+ err = badjson.UnmarshallExcludedContext(ctx, content, &inline, options)
+ if err != nil {
+ return err
+ }
+ o.Options = options
+ return nil
+}
+
+func (o *CertificateProviderOptions) IsShared() bool {
+ return o.Tag != ""
+}
diff --git a/option/cloudflare.go b/option/cloudflare.go
new file mode 100644
index 0000000000..6fbd08058a
--- /dev/null
+++ b/option/cloudflare.go
@@ -0,0 +1,9 @@
+package option
+
+type CloudflareProfile struct {
+ ID string `json:"id,omitempty"`
+ AuthToken string `json:"auth_token,omitempty"`
+ PrivateKey string `json:"private_key,omitempty"`
+ Recreate bool `json:"recreate,omitempty"`
+ Detour string `json:"detour,omitempty"`
+}
diff --git a/option/cloudflared.go b/option/cloudflared.go
new file mode 100644
index 0000000000..e94a20fefd
--- /dev/null
+++ b/option/cloudflared.go
@@ -0,0 +1,16 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+type CloudflaredInboundOptions struct {
+ Token string `json:"token,omitempty"`
+ HighAvailabilityConnections int `json:"ha_connections,omitempty"`
+ Protocol string `json:"protocol,omitempty"`
+ PostQuantum bool `json:"post_quantum,omitempty"`
+ EdgeIPVersion int `json:"edge_ip_version,omitempty"`
+ DatagramVersion string `json:"datagram_version,omitempty"`
+ GracePeriod badoption.Duration `json:"grace_period,omitempty"`
+ Region string `json:"region,omitempty"`
+ ControlDialer DialerOptions `json:"control_dialer,omitempty"`
+ TunnelDialer DialerOptions `json:"tunnel_dialer,omitempty"`
+}
diff --git a/option/dns.go b/option/dns.go
index b5ccf20804..8334de61f8 100644
--- a/option/dns.go
+++ b/option/dns.go
@@ -3,19 +3,14 @@ package option
import (
"context"
"net/netip"
- "net/url"
C "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/experimental/deprecated"
- "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/json/badjson"
"github.com/sagernet/sing/common/json/badoption"
M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/service"
-
- "github.com/miekg/dns"
)
type RawDNSOptions struct {
@@ -26,80 +21,29 @@ type RawDNSOptions struct {
DNSClientOptions
}
-type LegacyDNSOptions struct {
- FakeIP *LegacyDNSFakeIPOptions `json:"fakeip,omitempty"`
-}
-
type DNSOptions struct {
RawDNSOptions
- LegacyDNSOptions
}
-type contextKeyDontUpgrade struct{}
-
-func ContextWithDontUpgrade(ctx context.Context) context.Context {
- return context.WithValue(ctx, (*contextKeyDontUpgrade)(nil), true)
-}
+const (
+ legacyDNSFakeIPRemovedMessage = "legacy DNS fakeip options are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, checkout migration: https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats"
+ legacyDNSServerRemovedMessage = "legacy DNS server formats are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0, checkout migration: https://sing-box.sagernet.org/migration/#migrate-to-new-dns-server-formats"
+)
-func dontUpgradeFromContext(ctx context.Context) bool {
- return ctx.Value((*contextKeyDontUpgrade)(nil)) == true
+type removedLegacyDNSOptions struct {
+ FakeIP json.RawMessage `json:"fakeip,omitempty"`
}
func (o *DNSOptions) UnmarshalJSONContext(ctx context.Context, content []byte) error {
- err := json.UnmarshalContext(ctx, content, &o.LegacyDNSOptions)
+ var legacyOptions removedLegacyDNSOptions
+ err := json.UnmarshalContext(ctx, content, &legacyOptions)
if err != nil {
return err
}
- dontUpgrade := dontUpgradeFromContext(ctx)
- legacyOptions := o.LegacyDNSOptions
- if !dontUpgrade {
- if o.FakeIP != nil && o.FakeIP.Enabled {
- deprecated.Report(ctx, deprecated.OptionLegacyDNSFakeIPOptions)
- ctx = context.WithValue(ctx, (*LegacyDNSFakeIPOptions)(nil), o.FakeIP)
- }
- o.LegacyDNSOptions = LegacyDNSOptions{}
- }
- err = badjson.UnmarshallExcludedContext(ctx, content, legacyOptions, &o.RawDNSOptions)
- if err != nil {
- return err
- }
- if !dontUpgrade {
- rcodeMap := make(map[string]int)
- o.Servers = common.Filter(o.Servers, func(it DNSServerOptions) bool {
- if it.Type == C.DNSTypeLegacyRcode {
- rcodeMap[it.Tag] = it.Options.(int)
- return false
- }
- return true
- })
- if len(rcodeMap) > 0 {
- for i := 0; i < len(o.Rules); i++ {
- rewriteRcode(rcodeMap, &o.Rules[i])
- }
- }
- }
- return nil
-}
-
-func rewriteRcode(rcodeMap map[string]int, rule *DNSRule) {
- switch rule.Type {
- case C.RuleTypeDefault:
- rewriteRcodeAction(rcodeMap, &rule.DefaultOptions.DNSRuleAction)
- case C.RuleTypeLogical:
- rewriteRcodeAction(rcodeMap, &rule.LogicalOptions.DNSRuleAction)
- }
-}
-
-func rewriteRcodeAction(rcodeMap map[string]int, ruleAction *DNSRuleAction) {
- if ruleAction.Action != C.RuleActionTypeRoute {
- return
- }
- rcode, loaded := rcodeMap[ruleAction.RouteOptions.Server]
- if !loaded {
- return
+ if len(legacyOptions.FakeIP) != 0 {
+ return E.New(legacyDNSFakeIPRemovedMessage)
}
- ruleAction.Action = C.RuleActionTypePredefined
- ruleAction.PredefinedOptions.Rcode = common.Ptr(DNSRCode(rcode))
+ return badjson.UnmarshallExcludedContext(ctx, content, legacyOptions, &o.RawDNSOptions)
}
type DNSClientOptions struct {
@@ -108,13 +52,30 @@ type DNSClientOptions struct {
DisableExpire bool `json:"disable_expire,omitempty"`
IndependentCache bool `json:"independent_cache,omitempty"`
CacheCapacity uint32 `json:"cache_capacity,omitempty"`
+ Optimistic *OptimisticDNSOptions `json:"optimistic,omitempty"`
ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
}
-type LegacyDNSFakeIPOptions struct {
- Enabled bool `json:"enabled,omitempty"`
- Inet4Range *badoption.Prefix `json:"inet4_range,omitempty"`
- Inet6Range *badoption.Prefix `json:"inet6_range,omitempty"`
+type _OptimisticDNSOptions struct {
+ Enabled bool `json:"enabled,omitempty"`
+ Timeout badoption.Duration `json:"timeout,omitempty"`
+}
+
+type OptimisticDNSOptions _OptimisticDNSOptions
+
+func (o OptimisticDNSOptions) MarshalJSON() ([]byte, error) {
+ if o.Timeout == 0 {
+ return json.Marshal(o.Enabled)
+ }
+ return json.Marshal((_OptimisticDNSOptions)(o))
+}
+
+func (o *OptimisticDNSOptions) UnmarshalJSON(bytes []byte) error {
+ err := json.Unmarshal(bytes, &o.Enabled)
+ if err == nil {
+ return nil
+ }
+ return json.UnmarshalDisallowUnknownFields(bytes, (*_OptimisticDNSOptions)(o))
}
type DNSTransportOptionsRegistry interface {
@@ -129,10 +90,6 @@ type _DNSServerOptions struct {
type DNSServerOptions _DNSServerOptions
func (o *DNSServerOptions) MarshalJSONContext(ctx context.Context) ([]byte, error) {
- switch o.Type {
- case C.DNSTypeLegacy:
- o.Type = ""
- }
return badjson.MarshallObjectsContext(ctx, (*_DNSServerOptions)(o), o.Options)
}
@@ -148,9 +105,7 @@ func (o *DNSServerOptions) UnmarshalJSONContext(ctx context.Context, content []b
var options any
switch o.Type {
case "", C.DNSTypeLegacy:
- o.Type = C.DNSTypeLegacy
- options = new(LegacyDNSServerOptions)
- deprecated.Report(ctx, deprecated.OptionLegacyDNSTransport)
+ return E.New(legacyDNSServerRemovedMessage)
default:
var loaded bool
options, loaded = registry.CreateOptions(o.Type)
@@ -163,169 +118,6 @@ func (o *DNSServerOptions) UnmarshalJSONContext(ctx context.Context, content []b
return err
}
o.Options = options
- if o.Type == C.DNSTypeLegacy && !dontUpgradeFromContext(ctx) {
- err = o.Upgrade(ctx)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (o *DNSServerOptions) Upgrade(ctx context.Context) error {
- if o.Type != C.DNSTypeLegacy {
- return nil
- }
- options := o.Options.(*LegacyDNSServerOptions)
- serverURL, _ := url.Parse(options.Address)
- var serverType string
- if serverURL != nil && serverURL.Scheme != "" {
- serverType = serverURL.Scheme
- } else {
- switch options.Address {
- case "local", "fakeip":
- serverType = options.Address
- default:
- serverType = C.DNSTypeUDP
- }
- }
- remoteOptions := RemoteDNSServerOptions{
- RawLocalDNSServerOptions: RawLocalDNSServerOptions{
- DialerOptions: DialerOptions{
- Detour: options.Detour,
- DomainResolver: &DomainResolveOptions{
- Server: options.AddressResolver,
- Strategy: options.AddressStrategy,
- },
- FallbackDelay: options.AddressFallbackDelay,
- },
- Legacy: true,
- LegacyStrategy: options.Strategy,
- LegacyDefaultDialer: options.Detour == "",
- LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
- },
- LegacyAddressResolver: options.AddressResolver,
- LegacyAddressStrategy: options.AddressStrategy,
- LegacyAddressFallbackDelay: options.AddressFallbackDelay,
- }
- switch serverType {
- case C.DNSTypeLocal:
- o.Type = C.DNSTypeLocal
- o.Options = &LocalDNSServerOptions{
- RawLocalDNSServerOptions: remoteOptions.RawLocalDNSServerOptions,
- }
- case C.DNSTypeUDP:
- o.Type = C.DNSTypeUDP
- o.Options = &remoteOptions
- var serverAddr M.Socksaddr
- if serverURL == nil || serverURL.Scheme == "" {
- serverAddr = M.ParseSocksaddr(options.Address)
- } else {
- serverAddr = M.ParseSocksaddr(serverURL.Host)
- }
- if !serverAddr.IsValid() {
- return E.New("invalid server address")
- }
- remoteOptions.Server = serverAddr.AddrString()
- if serverAddr.Port != 0 && serverAddr.Port != 53 {
- remoteOptions.ServerPort = serverAddr.Port
- }
- case C.DNSTypeTCP:
- o.Type = C.DNSTypeTCP
- o.Options = &remoteOptions
- if serverURL == nil {
- return E.New("invalid server address")
- }
- serverAddr := M.ParseSocksaddr(serverURL.Host)
- if !serverAddr.IsValid() {
- return E.New("invalid server address")
- }
- remoteOptions.Server = serverAddr.AddrString()
- if serverAddr.Port != 0 && serverAddr.Port != 53 {
- remoteOptions.ServerPort = serverAddr.Port
- }
- case C.DNSTypeTLS, C.DNSTypeQUIC:
- o.Type = serverType
- if serverURL == nil {
- return E.New("invalid server address")
- }
- serverAddr := M.ParseSocksaddr(serverURL.Host)
- if !serverAddr.IsValid() {
- return E.New("invalid server address")
- }
- remoteOptions.Server = serverAddr.AddrString()
- if serverAddr.Port != 0 && serverAddr.Port != 853 {
- remoteOptions.ServerPort = serverAddr.Port
- }
- o.Options = &RemoteTLSDNSServerOptions{
- RemoteDNSServerOptions: remoteOptions,
- }
- case C.DNSTypeHTTPS, C.DNSTypeHTTP3:
- o.Type = serverType
- httpsOptions := RemoteHTTPSDNSServerOptions{
- RemoteTLSDNSServerOptions: RemoteTLSDNSServerOptions{
- RemoteDNSServerOptions: remoteOptions,
- },
- }
- o.Options = &httpsOptions
- if serverURL == nil {
- return E.New("invalid server address")
- }
- serverAddr := M.ParseSocksaddr(serverURL.Host)
- if !serverAddr.IsValid() {
- return E.New("invalid server address")
- }
- httpsOptions.Server = serverAddr.AddrString()
- if serverAddr.Port != 0 && serverAddr.Port != 443 {
- httpsOptions.ServerPort = serverAddr.Port
- }
- if serverURL.Path != "/dns-query" {
- httpsOptions.Path = serverURL.Path
- }
- case "rcode":
- var rcode int
- if serverURL == nil {
- return E.New("invalid server address")
- }
- switch serverURL.Host {
- case "success":
- rcode = dns.RcodeSuccess
- case "format_error":
- rcode = dns.RcodeFormatError
- case "server_failure":
- rcode = dns.RcodeServerFailure
- case "name_error":
- rcode = dns.RcodeNameError
- case "not_implemented":
- rcode = dns.RcodeNotImplemented
- case "refused":
- rcode = dns.RcodeRefused
- default:
- return E.New("unknown rcode: ", serverURL.Host)
- }
- o.Type = C.DNSTypeLegacyRcode
- o.Options = rcode
- case C.DNSTypeDHCP:
- o.Type = C.DNSTypeDHCP
- dhcpOptions := DHCPDNSServerOptions{}
- if serverURL == nil {
- return E.New("invalid server address")
- }
- if serverURL.Host != "" && serverURL.Host != "auto" {
- dhcpOptions.Interface = serverURL.Host
- }
- o.Options = &dhcpOptions
- case C.DNSTypeFakeIP:
- o.Type = C.DNSTypeFakeIP
- fakeipOptions := FakeIPDNSServerOptions{}
- if legacyOptions, loaded := ctx.Value((*LegacyDNSFakeIPOptions)(nil)).(*LegacyDNSFakeIPOptions); loaded {
- fakeipOptions.Inet4Range = legacyOptions.Inet4Range
- fakeipOptions.Inet6Range = legacyOptions.Inet6Range
- }
- o.Options = &fakeipOptions
- default:
- return E.New("unsupported DNS server scheme: ", serverType)
- }
return nil
}
@@ -350,16 +142,6 @@ func (o *DNSServerAddressOptions) ReplaceServerOptions(options ServerOptions) {
*o = DNSServerAddressOptions(options)
}
-type LegacyDNSServerOptions struct {
- Address string `json:"address"`
- AddressResolver string `json:"address_resolver,omitempty"`
- AddressStrategy DomainStrategy `json:"address_strategy,omitempty"`
- AddressFallbackDelay badoption.Duration `json:"address_fallback_delay,omitempty"`
- Strategy DomainStrategy `json:"strategy,omitempty"`
- Detour string `json:"detour,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
-}
-
type HostsDNSServerOptions struct {
Path badoption.Listable[string] `json:"path,omitempty"`
Predefined *badjson.TypedMap[string, badoption.Listable[netip.Addr]] `json:"predefined,omitempty"`
@@ -367,23 +149,17 @@ type HostsDNSServerOptions struct {
type RawLocalDNSServerOptions struct {
DialerOptions
- Legacy bool `json:"-"`
- LegacyStrategy DomainStrategy `json:"-"`
- LegacyDefaultDialer bool `json:"-"`
- LegacyClientSubnet netip.Prefix `json:"-"`
}
type LocalDNSServerOptions struct {
RawLocalDNSServerOptions
- PreferGo bool `json:"prefer_go,omitempty"`
+ PreferGo bool `json:"prefer_go,omitempty"`
+ NeighborDomain badoption.Listable[string] `json:"neighbor_domain,omitempty"`
}
type RemoteDNSServerOptions struct {
RawLocalDNSServerOptions
DNSServerAddressOptions
- LegacyAddressResolver string `json:"-"`
- LegacyAddressStrategy DomainStrategy `json:"-"`
- LegacyAddressFallbackDelay badoption.Duration `json:"-"`
}
type RemoteTLSDNSServerOptions struct {
@@ -407,3 +183,20 @@ type DHCPDNSServerOptions struct {
LocalDNSServerOptions
Interface string `json:"interface,omitempty"`
}
+
+type MDNSDNSServerOptions struct {
+ LocalDNSServerOptions
+ Interface badoption.Listable[string] `json:"interface,omitempty"`
+}
+
+type SDNSDNSServerOptions struct {
+ RemoteDNSServerOptions
+ Stamp string `json:"stamp"`
+}
+
+type MultiDNSServerOptions struct {
+ RawLocalDNSServerOptions
+ Servers []string `json:"servers,omitempty"`
+ Parallel bool `json:"parallel,omitempty"`
+ IgnoreRanges []badoption.Prefix `json:"ignore_ranges,omitempty"`
+}
diff --git a/option/dns_record.go b/option/dns_record.go
index fa72b61b73..f10e03d9b6 100644
--- a/option/dns_record.go
+++ b/option/dns_record.go
@@ -2,6 +2,7 @@ package option
import (
"encoding/base64"
+ "strings"
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
@@ -11,6 +12,8 @@ import (
"github.com/miekg/dns"
)
+const defaultDNSRecordTTL uint32 = 3600
+
type DNSRCode int
func (r DNSRCode) MarshalJSON() ([]byte, error) {
@@ -76,10 +79,13 @@ func (o *DNSRecordOptions) UnmarshalJSON(data []byte) error {
if err == nil {
return o.unmarshalBase64(binary)
}
- record, err := dns.NewRR(stringValue)
+ record, err := parseDNSRecord(stringValue)
if err != nil {
return err
}
+ if record == nil {
+ return E.New("empty DNS record")
+ }
if a, isA := record.(*dns.A); isA {
a.A = M.AddrFromIP(a.A).Unmap().AsSlice()
}
@@ -87,6 +93,16 @@ func (o *DNSRecordOptions) UnmarshalJSON(data []byte) error {
return nil
}
+func parseDNSRecord(stringValue string) (dns.RR, error) {
+ if len(stringValue) > 0 && stringValue[len(stringValue)-1] != '\n' {
+ stringValue += "\n"
+ }
+ parser := dns.NewZoneParser(strings.NewReader(stringValue), "", "")
+ parser.SetDefaultTTL(defaultDNSRecordTTL)
+ record, _ := parser.Next()
+ return record, parser.Err()
+}
+
func (o *DNSRecordOptions) unmarshalBase64(binary []byte) error {
record, _, err := dns.UnpackRR(binary, 0)
if err != nil {
@@ -100,3 +116,10 @@ func (o *DNSRecordOptions) unmarshalBase64(binary []byte) error {
func (o DNSRecordOptions) Build() dns.RR {
return o.RR
}
+
+func (o DNSRecordOptions) Match(record dns.RR) bool {
+ if o.RR == nil || record == nil {
+ return false
+ }
+ return dns.IsDuplicate(o.RR, record)
+}
diff --git a/option/dns_record_test.go b/option/dns_record_test.go
new file mode 100644
index 0000000000..759ef5fc5a
--- /dev/null
+++ b/option/dns_record_test.go
@@ -0,0 +1,40 @@
+package option
+
+import (
+ "testing"
+
+ "github.com/miekg/dns"
+ "github.com/stretchr/testify/require"
+)
+
+func mustRecordOptions(t *testing.T, record string) DNSRecordOptions {
+ t.Helper()
+ var value DNSRecordOptions
+ require.NoError(t, value.UnmarshalJSON([]byte(`"`+record+`"`)))
+ return value
+}
+
+func TestDNSRecordOptionsUnmarshalJSONRejectsRelativeNames(t *testing.T) {
+ t.Parallel()
+
+ for _, record := range []string{
+ "@ IN A 1.1.1.1",
+ "www IN CNAME example.com.",
+ "example.com. IN CNAME @",
+ "example.com. IN CNAME www",
+ } {
+ var value DNSRecordOptions
+ err := value.UnmarshalJSON([]byte(`"` + record + `"`))
+ require.Error(t, err)
+ }
+}
+
+func TestDNSRecordOptionsMatchIgnoresTTL(t *testing.T) {
+ t.Parallel()
+
+ expected := mustRecordOptions(t, "example.com. 600 IN A 1.1.1.1")
+ record, err := dns.NewRR("example.com. 60 IN A 1.1.1.1")
+ require.NoError(t, err)
+
+ require.True(t, expected.Match(record))
+}
diff --git a/option/dns_test.go b/option/dns_test.go
new file mode 100644
index 0000000000..4e7bf9a92b
--- /dev/null
+++ b/option/dns_test.go
@@ -0,0 +1,54 @@
+package option
+
+import (
+ "context"
+ "testing"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/service"
+
+ "github.com/stretchr/testify/require"
+)
+
+type stubDNSTransportOptionsRegistry struct{}
+
+func (stubDNSTransportOptionsRegistry) CreateOptions(transportType string) (any, bool) {
+ switch transportType {
+ case C.DNSTypeUDP:
+ return new(RemoteDNSServerOptions), true
+ case C.DNSTypeFakeIP:
+ return new(FakeIPDNSServerOptions), true
+ default:
+ return nil, false
+ }
+}
+
+func TestDNSOptionsRejectsLegacyFakeIPOptions(t *testing.T) {
+ t.Parallel()
+
+ ctx := service.ContextWith[DNSTransportOptionsRegistry](context.Background(), stubDNSTransportOptionsRegistry{})
+ var options DNSOptions
+ err := json.UnmarshalContext(ctx, []byte(`{
+ "fakeip": {
+ "enabled": true,
+ "inet4_range": "198.18.0.0/15"
+ }
+ }`), &options)
+ require.EqualError(t, err, legacyDNSFakeIPRemovedMessage)
+}
+
+func TestDNSServerOptionsRejectsLegacyFormats(t *testing.T) {
+ t.Parallel()
+
+ ctx := service.ContextWith[DNSTransportOptionsRegistry](context.Background(), stubDNSTransportOptionsRegistry{})
+ testCases := []string{
+ `{"address":"1.1.1.1"}`,
+ `{"type":"legacy","address":"1.1.1.1"}`,
+ }
+ for _, content := range testCases {
+ var options DNSServerOptions
+ err := json.UnmarshalContext(ctx, []byte(content), &options)
+ require.EqualError(t, err, legacyDNSServerRemovedMessage)
+ }
+}
diff --git a/option/dnstt.go b/option/dnstt.go
new file mode 100644
index 0000000000..29e0bd6168
--- /dev/null
+++ b/option/dnstt.go
@@ -0,0 +1,49 @@
+package option
+
+import (
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type DnsttOptions struct {
+ DialerOptions
+
+ PublicKey string `json:"pubkey,omitempty"`
+ Domain string `json:"domain,omitempty"`
+ PreTestDomain string `json:"pretest-domain,omitempty"`
+ PreTestRecordType string `json:"pretest-record-type,omitempty"`
+
+ RecordType string `json:"record-type,omitempty"`
+ UTLSClientHelloID string `json:"utls,omitempty"`
+
+ Resolvers []string `json:"resolvers,omitempty"`
+ DeprecatedTunnelPerResolver int `json:"tunnel-per-resolver,omitempty"`
+ SingleResolver bool `json:"single-resolver,omitempty"`
+
+ DnsttCompat bool `json:"dnstt-compat,omitempty"`
+ ClientIDSize *int `json:"clientid-size,omitempty"`
+ MaxQnameLen *int `json:"max-qname-len,omitempty"`
+ MaxNumLabels *int `json:"max-num-labels,omitempty"`
+ RPS *float64 `json:"rps,omitempty"`
+
+ MTU *int `json:"mtu,omitempty"`
+
+ IdleTimeout *badoption.Duration `json:"idle-timeout,omitempty"`
+ KeepAlive *badoption.Duration `json:"keepalive,omitempty"`
+ OpenStreamTimeout *badoption.Duration `json:"open-stream-timeout,omitempty"`
+ MaxStreams *int `json:"max-streams,omitempty"`
+ ReconnectMinDelay *badoption.Duration `json:"reconnect-min,omitempty"`
+ ReconnectMaxDelay *badoption.Duration `json:"reconnect-max,omitempty"`
+ SessionCheckInterval *badoption.Duration `json:"session-check-interval,omitempty"`
+ HandshakeTimeout *badoption.Duration `json:"handshake-timeout,omitempty"`
+
+ UdpAcceptErrors bool `json:"udp-accept-errors,omitempty"`
+ UdpSharedSocket bool `json:"udp-shared-socket,omitempty"`
+ UdpTimeout *badoption.Duration `json:"udp-timeout,omitempty"`
+ UdpWorkers *int `json:"udp-workers,omitempty"`
+
+ // SmartPool routes every resolver registered via the dnstt outbound's
+ // addResolver flow through an internal hmrd_multi_resolver_dns pool
+ // (deadline-aware failover, AIMD throttling, recovery probing) instead
+ // of using each resolver as its own tunnel.
+ SmartPool bool `json:"smart_pool,omitempty"`
+}
diff --git a/option/experimental.go b/option/experimental.go
index bf0df9e78c..102a06a4f0 100644
--- a/option/experimental.go
+++ b/option/experimental.go
@@ -1,21 +1,29 @@
package option
-import "github.com/sagernet/sing/common/json/badoption"
+import (
+ "github.com/sagernet/sing/common/json/badoption"
+)
type ExperimentalOptions struct {
- CacheFile *CacheFileOptions `json:"cache_file,omitempty"`
- ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
- V2RayAPI *V2RayAPIOptions `json:"v2ray_api,omitempty"`
- Debug *DebugOptions `json:"debug,omitempty"`
+ CacheFile *CacheFileOptions `json:"cache_file,omitempty"`
+ ClashAPI *ClashAPIOptions `json:"clash_api,omitempty"`
+ V2RayAPI *V2RayAPIOptions `json:"v2ray_api,omitempty"`
+ UnifiedDelay *UnifiedDelayOptions `json:"unified_delay,omitempty"`
+ Debug *DebugOptions `json:"debug,omitempty"`
+
+ Monitoring *MonitoringOptions `json:"monitoring,omitempty"`
}
type CacheFileOptions struct {
- Enabled bool `json:"enabled,omitempty"`
- Path string `json:"path,omitempty"`
- CacheID string `json:"cache_id,omitempty"`
- StoreFakeIP bool `json:"store_fakeip,omitempty"`
- StoreRDRC bool `json:"store_rdrc,omitempty"`
- RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"`
+ Enabled bool `json:"enabled,omitempty"`
+ Path string `json:"path,omitempty"`
+ CacheID string `json:"cache_id,omitempty"`
+ StoreFakeIP bool `json:"store_fakeip,omitempty"`
+ StoreRDRC bool `json:"store_rdrc,omitempty"`
+ StoreWARPConfig bool `json:"store_warp_config,omitempty"`
+ StoreMASQUEConfig bool `json:"store_masque_config,omitempty"`
+ RDRCTimeout badoption.Duration `json:"rdrc_timeout,omitempty"`
+ StoreDNS bool `json:"store_dns,omitempty"`
}
type ClashAPIOptions struct {
@@ -52,3 +60,7 @@ type V2RayStatsServiceOptions struct {
Outbounds []string `json:"outbounds,omitempty"`
Users []string `json:"users,omitempty"`
}
+
+type UnifiedDelayOptions struct {
+ Enabled bool `json:"enabled,omitempty"`
+}
diff --git a/option/firebasetunnel.go b/option/firebasetunnel.go
new file mode 100644
index 0000000000..dad5e57c32
--- /dev/null
+++ b/option/firebasetunnel.go
@@ -0,0 +1,46 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+// FirebaseTunnelUser identifies a client allowed to connect to the inbound.
+// If PSK is set, payload bytes are encrypted with AES-256-GCM keyed from it.
+type FirebaseTunnelUser struct {
+ Name string `json:"name"`
+ PSK string `json:"psk,omitempty"`
+}
+
+// FirebaseTunnelInboundOptions configures the server side of the Firebase Tunnel
+// protocol. It listens for pending sessions in the Firebase Realtime Database
+// and routes each one through the sing-box router, with per-user traffic
+// accounting handled automatically.
+type FirebaseTunnelInboundOptions struct {
+ FirebaseURLs badoption.Listable[string] `json:"firebase_urls"`
+ FirebaseSecret string `json:"firebase_secret,omitempty"`
+ FirebaseAuthToken string `json:"firebase_auth_token,omitempty"`
+ RetryLimit uint32 `json:"retry_limit,omitempty"`
+
+ Users []FirebaseTunnelUser `json:"users"`
+ PollInterval badoption.Duration `json:"poll_interval,omitempty"`
+ SessionTimeout badoption.Duration `json:"session_timeout,omitempty"`
+ MaxSessions int `json:"max_sessions,omitempty"`
+ MaxSessionsPerUser int `json:"max_sessions_per_user,omitempty"`
+ // MaxSessionsPerSecondPerUser rate-limits new session creation per user
+ // (token bucket). Zero → built-in default (5/s).
+ MaxSessionsPerSecondPerUser int `json:"max_sessions_per_second_per_user,omitempty"`
+}
+
+// FirebaseTunnelOutboundOptions configures the client side of the Firebase Tunnel
+// protocol. It dials by writing a session request to Firebase and waiting for the
+// server (inbound) to activate it.
+type FirebaseTunnelOutboundOptions struct {
+ FirebaseURLs badoption.Listable[string] `json:"firebase_urls"`
+ FirebaseSecret string `json:"firebase_secret,omitempty"`
+ FirebaseAuthToken string `json:"firebase_auth_token,omitempty"`
+ RetryLimit uint32 `json:"retry_limit,omitempty"`
+
+ User string `json:"user"`
+ PSK string `json:"psk,omitempty"`
+ BatchInterval badoption.Duration `json:"batch_interval,omitempty"`
+ BatchMaxBytes int `json:"batch_max_bytes,omitempty"`
+ ActivationTimeout badoption.Duration `json:"activation_timeout,omitempty"`
+}
diff --git a/option/fragment.go b/option/fragment.go
new file mode 100644
index 0000000000..f1b420b2e9
--- /dev/null
+++ b/option/fragment.go
@@ -0,0 +1,21 @@
+package option
+
+import (
+ "math/rand"
+)
+
+type TLSFragmentOptions struct {
+ Enabled bool `json:"enabled,omitempty"`
+ Size string `json:"size,omitempty"` // Fragment size in Bytes
+ Sleep string `json:"sleep,omitempty"` // Time to sleep between sending the fragments in milliseconds
+ Method string `json:"method,omitempty"` // Wether to fragment only clientHello or a range of TCP packets. Valid options: ['tlsHello', 'range']
+ Range string `json:"range,omitempty"` // Ra
+}
+
+func RandBetween(min int, max int) int {
+ if max == min {
+ return min
+ }
+ return rand.Intn(max-min+1) + min
+
+}
diff --git a/option/gooserelay.go b/option/gooserelay.go
new file mode 100644
index 0000000000..16cf007e70
--- /dev/null
+++ b/option/gooserelay.go
@@ -0,0 +1,19 @@
+package option
+
+import (
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type GooseRelayOptions struct {
+ DialerOptions
+
+ ScriptKeys []string `json:"script_keys,omitempty"`
+ TunnelKey string `json:"tunnel_key,omitempty"`
+ GoogleHost string `json:"google_host,omitempty"`
+ SNI []string `json:"sni,omitempty"`
+ DebugTiming bool `json:"debug_timing,omitempty"`
+
+ UDPOverTCP *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"`
+
+ HandshakeTimeout *badoption.Duration `json:"handshake_timeout,omitempty"`
+}
diff --git a/option/group.go b/option/group.go
index 02b3a5ecb9..979f1d31f5 100644
--- a/option/group.go
+++ b/option/group.go
@@ -11,6 +11,7 @@ type SelectorOutboundOptions struct {
type URLTestOutboundOptions struct {
Outbounds []string `json:"outbounds"`
URL string `json:"url,omitempty"`
+ URLs []string `json:"urls,omitempty"` //H
Interval badoption.Duration `json:"interval,omitempty"`
Tolerance uint16 `json:"tolerance,omitempty"`
IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
diff --git a/option/hinvalid.go b/option/hinvalid.go
new file mode 100644
index 0000000000..0d3c0d1496
--- /dev/null
+++ b/option/hinvalid.go
@@ -0,0 +1,6 @@
+package option
+
+type HInvalidOptions struct {
+ InvalidConfig any
+ Err error
+}
diff --git a/option/http.go b/option/http.go
new file mode 100644
index 0000000000..1a97270443
--- /dev/null
+++ b/option/http.go
@@ -0,0 +1,127 @@
+package option
+
+import (
+ "reflect"
+
+ "github.com/sagernet/sing/common/byteformats"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badjson"
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type HTTP2Options struct {
+ IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
+ KeepAlivePeriod badoption.Duration `json:"keep_alive_period,omitempty"`
+ StreamReceiveWindow byteformats.MemoryBytes `json:"stream_receive_window,omitempty"`
+ ConnectionReceiveWindow byteformats.MemoryBytes `json:"connection_receive_window,omitempty"`
+ MaxConcurrentStreams int `json:"max_concurrent_streams,omitempty"`
+}
+
+type QUICOptions struct {
+ HTTP2Options
+ InitialPacketSize int `json:"initial_packet_size,omitempty"`
+ DisablePathMTUDiscovery bool `json:"disable_path_mtu_discovery,omitempty"`
+}
+
+type _HTTPClientOptions struct {
+ Tag string `json:"tag,omitempty"`
+ Engine string `json:"engine,omitempty"`
+ Version int `json:"version,omitempty"`
+ DisableVersionFallback bool `json:"disable_version_fallback,omitempty"`
+ Headers badoption.HTTPHeader `json:"headers,omitempty"`
+ HTTP2Options HTTP2Options `json:"-"`
+ HTTP3Options QUICOptions `json:"-"`
+ DefaultOutbound bool `json:"-"`
+ DisableEmptyDirectCheck bool `json:"-"`
+ ResolveOnDetour bool `json:"-"`
+ DirectResolver bool `json:"-"`
+ OutboundTLSOptionsContainer
+ DialerOptions
+}
+
+type (
+ HTTPClient _HTTPClientOptions
+ HTTPClientOptions _HTTPClientOptions
+)
+
+func (h HTTPClient) Options() HTTPClientOptions {
+ options := HTTPClientOptions(h)
+ options.Tag = ""
+ return options
+}
+
+func (o HTTPClientOptions) IsEmpty() bool {
+ if o.Tag != "" {
+ return false
+ }
+ o.DefaultOutbound = false
+ o.ResolveOnDetour = false
+ o.DirectResolver = false
+ return reflect.ValueOf(_HTTPClientOptions(o)).IsZero()
+}
+
+func (o HTTPClientOptions) MarshalJSON() ([]byte, error) {
+ if o.Tag != "" {
+ return json.Marshal(o.Tag)
+ }
+ return badjson.MarshallObjects(_HTTPClientOptions(o), httpClientVariant(_HTTPClientOptions(o)))
+}
+
+func (o *HTTPClientOptions) UnmarshalJSON(content []byte) error {
+ if len(content) > 0 && content[0] == '"' {
+ *o = HTTPClientOptions{}
+ return json.Unmarshal(content, &o.Tag)
+ }
+ var options _HTTPClientOptions
+ err := json.Unmarshal(content, &options)
+ if err != nil {
+ return err
+ }
+ err = unmarshalHTTPClientVersionOptions(content, &options, &options)
+ if err != nil {
+ return err
+ }
+ options.Tag = ""
+ *o = HTTPClientOptions(options)
+ return nil
+}
+
+func (h HTTPClient) MarshalJSON() ([]byte, error) {
+ return badjson.MarshallObjects(_HTTPClientOptions(h), httpClientVariant(_HTTPClientOptions(h)))
+}
+
+func (h *HTTPClient) UnmarshalJSON(content []byte) error {
+ err := json.Unmarshal(content, (*_HTTPClientOptions)(h))
+ if err != nil {
+ return err
+ }
+ return unmarshalHTTPClientVersionOptions(content, (*_HTTPClientOptions)(h), (*_HTTPClientOptions)(h))
+}
+
+func unmarshalHTTPClientVersionOptions(content []byte, baseStruct any, options *_HTTPClientOptions) error {
+ switch options.Version {
+ case 1:
+ return json.UnmarshalDisallowUnknownFields(content, baseStruct)
+ case 0, 2:
+ options.Version = 2
+ return badjson.UnmarshallExcluded(content, baseStruct, &options.HTTP2Options)
+ case 3:
+ return badjson.UnmarshallExcluded(content, baseStruct, &options.HTTP3Options)
+ default:
+ return E.New("unknown HTTP version: ", options.Version)
+ }
+}
+
+func httpClientVariant(options _HTTPClientOptions) any {
+ switch options.Version {
+ case 1:
+ return nil
+ case 0, 2:
+ return options.HTTP2Options
+ case 3:
+ return options.HTTP3Options
+ default:
+ return nil
+ }
+}
diff --git a/option/hysteria.go b/option/hysteria.go
index 186759010e..f5ab87cec1 100644
--- a/option/hysteria.go
+++ b/option/hysteria.go
@@ -7,17 +7,22 @@ import (
type HysteriaInboundOptions struct {
ListenOptions
- Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
- UpMbps int `json:"up_mbps,omitempty"`
- Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
- DownMbps int `json:"down_mbps,omitempty"`
- Obfs string `json:"obfs,omitempty"`
- Users []HysteriaUser `json:"users,omitempty"`
- ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
- ReceiveWindowClient uint64 `json:"recv_window_client,omitempty"`
- MaxConnClient int `json:"max_conn_client,omitempty"`
- DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
+ Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
+ UpMbps int `json:"up_mbps,omitempty"`
+ Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
+ DownMbps int `json:"down_mbps,omitempty"`
+ Obfs string `json:"obfs,omitempty"`
+ Users []HysteriaUser `json:"users,omitempty"`
+ // Deprecated: use QUIC fields instead
+ ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
+ // Deprecated: use QUIC fields instead
+ ReceiveWindowClient uint64 `json:"recv_window_client,omitempty"`
+ // Deprecated: use QUIC fields instead
+ MaxConnClient int `json:"max_conn_client,omitempty"`
+ // Deprecated: use QUIC fields instead
+ DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
InboundTLSOptionsContainer
+ QUICOptions
}
type HysteriaUser struct {
@@ -29,18 +34,22 @@ type HysteriaUser struct {
type HysteriaOutboundOptions struct {
DialerOptions
ServerOptions
- ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
- HopInterval badoption.Duration `json:"hop_interval,omitempty"`
- Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
- UpMbps int `json:"up_mbps,omitempty"`
- Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
- DownMbps int `json:"down_mbps,omitempty"`
- Obfs string `json:"obfs,omitempty"`
- Auth []byte `json:"auth,omitempty"`
- AuthString string `json:"auth_str,omitempty"`
- ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
- ReceiveWindow uint64 `json:"recv_window,omitempty"`
- DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
- Network NetworkList `json:"network,omitempty"`
+ ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
+ HopInterval badoption.Duration `json:"hop_interval,omitempty"`
+ Up *byteformats.NetworkBytesCompat `json:"up,omitempty"`
+ UpMbps int `json:"up_mbps,omitempty"`
+ Down *byteformats.NetworkBytesCompat `json:"down,omitempty"`
+ DownMbps int `json:"down_mbps,omitempty"`
+ Obfs string `json:"obfs,omitempty"`
+ Auth []byte `json:"auth,omitempty"`
+ AuthString string `json:"auth_str,omitempty"`
+ // Deprecated: use QUIC fields instead
+ ReceiveWindowConn uint64 `json:"recv_window_conn,omitempty"`
+ // Deprecated: use QUIC fields instead
+ ReceiveWindow uint64 `json:"recv_window,omitempty"`
+ // Deprecated: use QUIC fields instead
+ DisableMTUDiscovery bool `json:"disable_mtu_discovery,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
OutboundTLSOptionsContainer
+ QUICOptions
}
diff --git a/option/hysteria2.go b/option/hysteria2.go
index a014513630..d20c0bd37b 100644
--- a/option/hysteria2.go
+++ b/option/hysteria2.go
@@ -18,13 +18,71 @@ type Hysteria2InboundOptions struct {
Users []Hysteria2User `json:"users,omitempty"`
IgnoreClientBandwidth bool `json:"ignore_client_bandwidth,omitempty"`
InboundTLSOptionsContainer
- Masquerade *Hysteria2Masquerade `json:"masquerade,omitempty"`
- BrutalDebug bool `json:"brutal_debug,omitempty"`
+ QUICOptions
+ Masquerade *Hysteria2Masquerade `json:"masquerade,omitempty"`
+ BBRProfile string `json:"bbr_profile,omitempty"`
+ BrutalDebug bool `json:"brutal_debug,omitempty"`
+ Realm *Hysteria2InboundRealm `json:"realm,omitempty"`
}
-type Hysteria2Obfs struct {
- Type string `json:"type,omitempty"`
- Password string `json:"password,omitempty"`
+type Hysteria2Realm struct {
+ ServerURL string `json:"server_url"`
+ Token string `json:"token,omitempty"`
+ RealmID string `json:"realm_id"`
+ STUNServers badoption.Listable[string] `json:"stun_servers"`
+ HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
+}
+
+type Hysteria2InboundRealm struct {
+ Hysteria2Realm
+ STUNDomainResolver *DomainResolveOptions `json:"stun_domain_resolver,omitempty"`
+}
+
+type Hysteria2ObfsGecko struct {
+ MinPacketSize int `json:"min_packet_size,omitempty"`
+ MaxPacketSize int `json:"max_packet_size,omitempty"`
+}
+
+type _Hysteria2Obfs struct {
+ Type string `json:"type,omitempty"`
+ Password string `json:"password,omitempty"`
+ GeckoOptions Hysteria2ObfsGecko `json:"-"`
+}
+
+type Hysteria2Obfs _Hysteria2Obfs
+
+func (o Hysteria2Obfs) MarshalJSON() ([]byte, error) {
+ var v any
+ switch o.Type {
+ case C.Hysteria2ObfsTypeSalamander:
+ case C.Hysteria2ObfsTypeGecko:
+ v = o.GeckoOptions
+ default:
+ return nil, E.New("unknown obfs type: ", o.Type)
+ }
+ if v == nil {
+ return json.Marshal((_Hysteria2Obfs)(o))
+ }
+ return badjson.MarshallObjects((_Hysteria2Obfs)(o), v)
+}
+
+func (o *Hysteria2Obfs) UnmarshalJSON(bytes []byte) error {
+ err := json.Unmarshal(bytes, (*_Hysteria2Obfs)(o))
+ if err != nil {
+ return err
+ }
+ var v any
+ switch o.Type {
+ case C.Hysteria2ObfsTypeSalamander:
+ case C.Hysteria2ObfsTypeGecko:
+ v = &o.GeckoOptions
+ default:
+ return E.New("unknown obfs type: ", o.Type)
+ }
+ if v == nil {
+ return nil
+ }
+ return badjson.UnmarshallExcluded(bytes, (*_Hysteria2Obfs)(o), v)
}
type Hysteria2User struct {
@@ -112,13 +170,30 @@ type Hysteria2MasqueradeString struct {
type Hysteria2OutboundOptions struct {
DialerOptions
ServerOptions
- ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
- HopInterval badoption.Duration `json:"hop_interval,omitempty"`
- UpMbps int `json:"up_mbps,omitempty"`
- DownMbps int `json:"down_mbps,omitempty"`
- Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
- Password string `json:"password,omitempty"`
- Network NetworkList `json:"network,omitempty"`
+ ServerPorts badoption.Listable[string] `json:"server_ports,omitempty"`
+ HopInterval badoption.Duration `json:"hop_interval,omitempty"`
+ HopIntervalMax badoption.Duration `json:"hop_interval_max,omitempty"`
+ UpMbps int `json:"up_mbps,omitempty"`
+ DownMbps int `json:"down_mbps,omitempty"`
+ Obfs *Hysteria2Obfs `json:"obfs,omitempty"`
+ Password string `json:"password,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
OutboundTLSOptionsContainer
- BrutalDebug bool `json:"brutal_debug,omitempty"`
+ QUICOptions
+ BBRProfile string `json:"bbr_profile,omitempty"`
+ BrutalDebug bool `json:"brutal_debug,omitempty"`
+ Realm *Hysteria2Realm `json:"realm,omitempty"`
+}
+
+type HysteriaRealmUser struct {
+ Name string `json:"name"`
+ Token string `json:"token"`
+ MaxRealms int `json:"max_realms,omitempty"`
+}
+
+type HysteriaRealmServiceOptions struct {
+ ListenOptions
+ InboundTLSOptionsContainer
+ HTTP2Options
+ Users []HysteriaRealmUser `json:"users"`
}
diff --git a/option/masque.go b/option/masque.go
new file mode 100644
index 0000000000..83fa849a6b
--- /dev/null
+++ b/option/masque.go
@@ -0,0 +1,32 @@
+package option
+
+import (
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type MASQUEOutboundOptions struct {
+ UseHTTP2 bool `json:"use_http2,omitempty"`
+ UseIPv6 bool `json:"use_ipv6,omitempty"`
+ Profile CloudflareProfile `json:"profile,omitempty"`
+ UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"`
+ UDPKeepalivePeriod badoption.Duration `json:"udp_keepalive_period,omitempty"`
+ UDPInitialPacketSize uint16 `json:"udp_initial_packet_size,omitempty"`
+ ReconnectDelay badoption.Duration `json:"reconnect_delay,omitempty"`
+ MASQUEOutboundTLSOptions
+ DialerOptions
+}
+
+type MASQUEOutboundTLSOptions struct {
+ Insecure bool `json:"insecure,omitempty"`
+ CipherSuites badoption.Listable[string] `json:"cipher_suites,omitempty"`
+ CurvePreferences badoption.Listable[CurvePreference] `json:"curve_preferences,omitempty"`
+ Fragment bool `json:"fragment,omitempty"`
+ FragmentFallbackDelay badoption.Duration `json:"fragment_fallback_delay,omitempty"`
+ RecordFragment bool `json:"record_fragment,omitempty"`
+ KernelTx bool `json:"kernel_tx,omitempty"`
+ KernelRx bool `json:"kernel_rx,omitempty"`
+}
+
+type MASQUEOutboundTLSOptionsContainer struct {
+ TLS *OutboundTLSOptions `json:"tls,omitempty"`
+}
diff --git a/option/mieru.go b/option/mieru.go
new file mode 100644
index 0000000000..5a7fdcfd27
--- /dev/null
+++ b/option/mieru.go
@@ -0,0 +1,30 @@
+package option
+
+type MieruOutboundOptions struct {
+ DialerOptions
+ ServerOptions
+ Network NetworkList `json:"network,omitempty"`
+ PortBindings []MieruPortBinding `json:"portBindings,omitempty"`
+ UserName string `json:"username,omitempty"`
+ Password string `json:"password,omitempty"`
+ Multiplexing string `json:"multiplexing,omitempty"`
+ HandshakeMode string `json:"handshake_mode,omitempty"`
+}
+
+type MieruInboundOptions struct {
+ ListenOptions
+ Users []MieruUser `json:"users,omitempty"`
+ PortBindings []MieruPortBinding `json:"portBindings,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
+}
+
+type MieruPortBinding struct {
+ Protocol string `json:"protocol,omitempty"`
+ PortRange string `json:"portRange,omitempty"`
+ Port uint16 `json:"port,omitempty"`
+}
+
+type MieruUser struct {
+ Name string `json:"username,omitempty"`
+ Password string `json:"password,omitempty"`
+}
diff --git a/option/monitoring.go b/option/monitoring.go
new file mode 100644
index 0000000000..4ff5cd0bf7
--- /dev/null
+++ b/option/monitoring.go
@@ -0,0 +1,12 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+type MonitoringOptions struct {
+ Interval badoption.Duration `json:"interval,omitempty"`
+ URLs []string `json:"urls,omitempty"` //H
+ Workers int `json:"workers,omitempty"`
+ DebounceWindow badoption.Duration `json:"debounce_window,omitempty"`
+ URLTestTimeout badoption.Duration `json:"url_test_timeout,omitempty"`
+ IdleTimeout badoption.Duration `json:"idle_timeout,omitempty"`
+}
diff --git a/option/oom_killer.go b/option/oom_killer.go
index 2032ed09ab..1183b502b7 100644
--- a/option/oom_killer.go
+++ b/option/oom_killer.go
@@ -6,9 +6,10 @@ import (
)
type OOMKillerServiceOptions struct {
- MemoryLimit *byteformats.MemoryBytes `json:"memory_limit,omitempty"`
- SafetyMargin *byteformats.MemoryBytes `json:"safety_margin,omitempty"`
- MinInterval badoption.Duration `json:"min_interval,omitempty"`
- MaxInterval badoption.Duration `json:"max_interval,omitempty"`
- ChecksBeforeLimit int `json:"checks_before_limit,omitempty"`
+ MemoryLimit *byteformats.MemoryBytes `json:"memory_limit,omitempty"`
+ SafetyMargin *byteformats.MemoryBytes `json:"safety_margin,omitempty"`
+ MinInterval badoption.Duration `json:"min_interval,omitempty"`
+ MaxInterval badoption.Duration `json:"max_interval,omitempty"`
+ KillerDisabled bool `json:"-"`
+ MemoryLimitOverride uint64 `json:"-"`
}
diff --git a/option/options.go b/option/options.go
index 8bebd48fc6..4e87852ac3 100644
--- a/option/options.go
+++ b/option/options.go
@@ -10,22 +10,29 @@ import (
)
type _Options struct {
- RawMessage json.RawMessage `json:"-"`
- Schema string `json:"$schema,omitempty"`
- Log *LogOptions `json:"log,omitempty"`
- DNS *DNSOptions `json:"dns,omitempty"`
- NTP *NTPOptions `json:"ntp,omitempty"`
- Certificate *CertificateOptions `json:"certificate,omitempty"`
- Endpoints []Endpoint `json:"endpoints,omitempty"`
- Inbounds []Inbound `json:"inbounds,omitempty"`
- Outbounds []Outbound `json:"outbounds,omitempty"`
- Route *RouteOptions `json:"route,omitempty"`
- Services []Service `json:"services,omitempty"`
- Experimental *ExperimentalOptions `json:"experimental,omitempty"`
+ RawMessage json.RawMessage `json:"-"`
+ CommentsSet *json.CommentSet `json:"-"`
+ Schema string `json:"$schema,omitempty"`
+ Log *LogOptions `json:"log,omitempty"`
+ DNS *DNSOptions `json:"dns,omitempty"`
+ NTP *NTPOptions `json:"ntp,omitempty"`
+ Certificate *CertificateOptions `json:"certificate,omitempty"`
+ CertificateProviders []CertificateProvider `json:"certificate_providers,omitempty"`
+ HTTPClients []HTTPClient `json:"http_clients,omitempty"`
+ Endpoints []Endpoint `json:"endpoints,omitempty"`
+ Inbounds []Inbound `json:"inbounds,omitempty"`
+ Outbounds []Outbound `json:"outbounds,omitempty"`
+ Route *RouteOptions `json:"route,omitempty"`
+ Services []Service `json:"services,omitempty"`
+ Experimental *ExperimentalOptions `json:"experimental,omitempty"`
}
type Options _Options
+func (o Options) MarshalJSONContext(ctx context.Context) ([]byte, error) {
+ return json.MarshalContext(ctx, (_Options)(o))
+}
+
func (o *Options) UnmarshalJSONContext(ctx context.Context, content []byte) error {
decoder := json.NewDecoderContext(ctx, bytes.NewReader(content))
decoder.DisallowUnknownFields()
@@ -37,6 +44,14 @@ func (o *Options) UnmarshalJSONContext(ctx context.Context, content []byte) erro
return checkOptions(o)
}
+func (o Options) Comments() *json.CommentSet {
+ return o.CommentsSet
+}
+
+func (o *Options) SetComments(comments *json.CommentSet) {
+ o.CommentsSet = comments
+}
+
type LogOptions struct {
Disabled bool `json:"disabled,omitempty"`
Level string `json:"level,omitempty"`
@@ -56,6 +71,43 @@ func checkOptions(options *Options) error {
if err != nil {
return err
}
+ err = checkCertificateProviders(options.CertificateProviders)
+ if err != nil {
+ return err
+ }
+ err = checkHTTPClients(options.HTTPClients)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func checkCertificateProviders(providers []CertificateProvider) error {
+ seen := make(map[string]bool)
+ for i, provider := range providers {
+ tag := provider.Tag
+ if tag == "" {
+ tag = F.ToString(i)
+ }
+ if seen[tag] {
+ return E.New("duplicate certificate provider tag: ", tag)
+ }
+ seen[tag] = true
+ }
+ return nil
+}
+
+func checkHTTPClients(clients []HTTPClient) error {
+ seen := make(map[string]bool)
+ for _, client := range clients {
+ if client.Tag == "" {
+ return E.New("missing http client tag")
+ }
+ if seen[client.Tag] {
+ return E.New("duplicate http client tag: ", client.Tag)
+ }
+ seen[client.Tag] = true
+ }
return nil
}
diff --git a/option/origin_ca.go b/option/origin_ca.go
new file mode 100644
index 0000000000..5a9f956af7
--- /dev/null
+++ b/option/origin_ca.go
@@ -0,0 +1,76 @@
+package option
+
+import (
+ "strings"
+
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+type CloudflareOriginCACertificateProviderOptions struct {
+ Domain badoption.Listable[string] `json:"domain,omitempty"`
+ DataDirectory string `json:"data_directory,omitempty"`
+ APIToken string `json:"api_token,omitempty"`
+ OriginCAKey string `json:"origin_ca_key,omitempty"`
+ RequestType CloudflareOriginCARequestType `json:"request_type,omitempty"`
+ RequestedValidity CloudflareOriginCARequestValidity `json:"requested_validity,omitempty"`
+ HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
+}
+
+type CloudflareOriginCARequestType string
+
+const (
+ CloudflareOriginCARequestTypeOriginRSA = CloudflareOriginCARequestType("origin-rsa")
+ CloudflareOriginCARequestTypeOriginECC = CloudflareOriginCARequestType("origin-ecc")
+)
+
+func (t *CloudflareOriginCARequestType) UnmarshalJSON(data []byte) error {
+ var value string
+ err := json.Unmarshal(data, &value)
+ if err != nil {
+ return err
+ }
+ value = strings.ToLower(value)
+ switch CloudflareOriginCARequestType(value) {
+ case "", CloudflareOriginCARequestTypeOriginRSA, CloudflareOriginCARequestTypeOriginECC:
+ *t = CloudflareOriginCARequestType(value)
+ default:
+ return E.New("unsupported Cloudflare Origin CA request type: ", value)
+ }
+ return nil
+}
+
+type CloudflareOriginCARequestValidity uint16
+
+const (
+ CloudflareOriginCARequestValidity7 = CloudflareOriginCARequestValidity(7)
+ CloudflareOriginCARequestValidity30 = CloudflareOriginCARequestValidity(30)
+ CloudflareOriginCARequestValidity90 = CloudflareOriginCARequestValidity(90)
+ CloudflareOriginCARequestValidity365 = CloudflareOriginCARequestValidity(365)
+ CloudflareOriginCARequestValidity730 = CloudflareOriginCARequestValidity(730)
+ CloudflareOriginCARequestValidity1095 = CloudflareOriginCARequestValidity(1095)
+ CloudflareOriginCARequestValidity5475 = CloudflareOriginCARequestValidity(5475)
+)
+
+func (v *CloudflareOriginCARequestValidity) UnmarshalJSON(data []byte) error {
+ var value uint16
+ err := json.Unmarshal(data, &value)
+ if err != nil {
+ return err
+ }
+ switch CloudflareOriginCARequestValidity(value) {
+ case 0,
+ CloudflareOriginCARequestValidity7,
+ CloudflareOriginCARequestValidity30,
+ CloudflareOriginCARequestValidity90,
+ CloudflareOriginCARequestValidity365,
+ CloudflareOriginCARequestValidity730,
+ CloudflareOriginCARequestValidity1095,
+ CloudflareOriginCARequestValidity5475:
+ *v = CloudflareOriginCARequestValidity(value)
+ default:
+ return E.New("unsupported Cloudflare Origin CA requested validity: ", value)
+ }
+ return nil
+}
diff --git a/option/outbound.go b/option/outbound.go
index 6676a3e923..aa32db8148 100644
--- a/option/outbound.go
+++ b/option/outbound.go
@@ -93,11 +93,13 @@ type DialerOptions struct {
}
type _DomainResolveOptions struct {
- Server string `json:"server"`
- Strategy DomainStrategy `json:"strategy,omitempty"`
- DisableCache bool `json:"disable_cache,omitempty"`
- RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
+ Server string `json:"server"`
+ Timeout badoption.Duration `json:"timeout,omitempty"`
+ Strategy DomainStrategy `json:"strategy,omitempty"`
+ DisableCache bool `json:"disable_cache,omitempty"`
+ DisableOptimisticCache bool `json:"disable_optimistic_cache,omitempty"`
+ RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
+ ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
}
type DomainResolveOptions _DomainResolveOptions
@@ -106,7 +108,9 @@ func (o DomainResolveOptions) MarshalJSON() ([]byte, error) {
if o.Server == "" {
return []byte("{}"), nil
} else if o.Strategy == DomainStrategy(C.DomainStrategyAsIS) &&
+ o.Timeout == 0 &&
!o.DisableCache &&
+ !o.DisableOptimisticCache &&
o.RewriteTTL == nil &&
o.ClientSubnet == nil {
return json.Marshal(o.Server)
diff --git a/option/psiphon.go b/option/psiphon.go
new file mode 100644
index 0000000000..16a1aa368e
--- /dev/null
+++ b/option/psiphon.go
@@ -0,0 +1,22 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+type PsiphonOutboundOptions struct {
+ Network NetworkList `json:"network,omitempty"`
+ DialerOptions
+
+ DataDirectory string `json:"data_directory,omitempty"`
+ EgressRegion string `json:"egress_region,omitempty"`
+ PropagationChannelID string `json:"propagation_channel_id,omitempty"`
+ SponsorID string `json:"sponsor_id,omitempty"`
+ NetworkID string `json:"network_id,omitempty"`
+ ClientPlatform string `json:"client_platform,omitempty"`
+ ClientVersion string `json:"client_version,omitempty"`
+ RemoteServerListURL string `json:"remote_server_list_url,omitempty"`
+ RemoteServerListDownloadFilename string `json:"remote_server_list_download_filename,omitempty"`
+ RemoteServerListSignaturePublicKey string `json:"remote_server_list_signature_public_key,omitempty"`
+ UpstreamProxyURL string `json:"upstream_proxy_url,omitempty"`
+ AllowDefaultDNSResolverWithBindToDevice *bool `json:"allow_default_dns_resolver_with_bind_to_device,omitempty"`
+ EstablishTunnelTimeout badoption.Duration `json:"establish_tunnel_timeout,omitempty"`
+}
diff --git a/option/route.go b/option/route.go
index f4b6539156..893be8ece2 100644
--- a/option/route.go
+++ b/option/route.go
@@ -9,6 +9,8 @@ type RouteOptions struct {
RuleSet []RuleSet `json:"rule_set,omitempty"`
Final string `json:"final,omitempty"`
FindProcess bool `json:"find_process,omitempty"`
+ FindNeighbor bool `json:"find_neighbor,omitempty"`
+ DHCPLeaseFiles badoption.Listable[string] `json:"dhcp_lease_files,omitempty"`
AutoDetectInterface bool `json:"auto_detect_interface,omitempty"`
OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
DefaultInterface string `json:"default_interface,omitempty"`
@@ -18,6 +20,7 @@ type RouteOptions struct {
DefaultNetworkType badoption.Listable[InterfaceType] `json:"default_network_type,omitempty"`
DefaultFallbackNetworkType badoption.Listable[InterfaceType] `json:"default_fallback_network_type,omitempty"`
DefaultFallbackDelay badoption.Duration `json:"default_fallback_delay,omitempty"`
+ DefaultHTTPClient string `json:"default_http_client,omitempty"`
}
type GeoIPOptions struct {
diff --git a/option/rule.go b/option/rule.go
index 3e7fd8771b..b83d2335df 100644
--- a/option/rule.go
+++ b/option/rule.go
@@ -1,6 +1,7 @@
package option
import (
+ "context"
"reflect"
C "github.com/sagernet/sing-box/constant"
@@ -33,26 +34,24 @@ func (r Rule) MarshalJSON() ([]byte, error) {
return badjson.MarshallObjects((_Rule)(r), v)
}
-func (r *Rule) UnmarshalJSON(bytes []byte) error {
- err := json.Unmarshal(bytes, (*_Rule)(r))
+func (r *Rule) UnmarshalJSONContext(ctx context.Context, bytes []byte) error {
+ err := json.UnmarshalContext(ctx, bytes, (*_Rule)(r))
+ if err != nil {
+ return err
+ }
+ payload, err := rulePayloadWithoutType(ctx, bytes)
if err != nil {
return err
}
- var v any
switch r.Type {
case "", C.RuleTypeDefault:
r.Type = C.RuleTypeDefault
- v = &r.DefaultOptions
+ return unmarshalDefaultRuleContext(ctx, payload, &r.DefaultOptions)
case C.RuleTypeLogical:
- v = &r.LogicalOptions
+ return unmarshalLogicalRuleContext(ctx, payload, &r.LogicalOptions)
default:
return E.New("unknown rule type: " + r.Type)
}
- err = badjson.UnmarshallExcluded(bytes, (*_Rule)(r), v)
- if err != nil {
- return err
- }
- return nil
}
func (r Rule) IsValid() bool {
@@ -92,6 +91,7 @@ type RawDefaultRule struct {
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
+ PackageNameRegex badoption.Listable[string] `json:"package_name_regex,omitempty"`
User badoption.Listable[string] `json:"user,omitempty"`
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
ClashMode string `json:"clash_mode,omitempty"`
@@ -103,6 +103,8 @@ type RawDefaultRule struct {
InterfaceAddress *badjson.TypedMap[string, badoption.Listable[*badoption.Prefixable]] `json:"interface_address,omitempty"`
NetworkInterfaceAddress *badjson.TypedMap[InterfaceType, badoption.Listable[*badoption.Prefixable]] `json:"network_interface_address,omitempty"`
DefaultInterfaceAddress badoption.Listable[*badoption.Prefixable] `json:"default_interface_address,omitempty"`
+ SourceMACAddress badoption.Listable[string] `json:"source_mac_address,omitempty"`
+ SourceHostname badoption.Listable[string] `json:"source_hostname,omitempty"`
PreferredBy badoption.Listable[string] `json:"preferred_by,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
@@ -110,6 +112,10 @@ type RawDefaultRule struct {
// Deprecated: renamed to rule_set_ip_cidr_match_source
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
+
+ TunnelSource badoption.Listable[string] `json:"tunnel_source,omitempty"` //E
+ TunnelDestination badoption.Listable[string] `json:"tunnel_destination,omitempty"` //E
+
}
type DefaultRule struct {
@@ -158,6 +164,64 @@ func (r *LogicalRule) UnmarshalJSON(data []byte) error {
return badjson.UnmarshallExcluded(data, &r.RawLogicalRule, &r.RuleAction)
}
+func rulePayloadWithoutType(ctx context.Context, data []byte) ([]byte, error) {
+ var content badjson.JSONObject
+ err := content.UnmarshalJSONContext(ctx, data)
+ if err != nil {
+ return nil, err
+ }
+ content.Remove("type")
+ return content.MarshalJSONContext(ctx)
+}
+
+func unmarshalDefaultRuleContext(ctx context.Context, data []byte, rule *DefaultRule) error {
+ rawAction, routeOptions, err := inspectRouteRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ err = rejectNestedRouteRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ depth := nestedRuleDepth(ctx)
+ err = json.UnmarshalContext(ctx, data, &rule.RawDefaultRule)
+ if err != nil {
+ return err
+ }
+ err = badjson.UnmarshallExcludedContext(ctx, data, &rule.RawDefaultRule, &rule.RuleAction)
+ if err != nil {
+ return err
+ }
+ if depth > 0 && rawAction == "" && routeOptions == (RouteActionOptions{}) {
+ rule.RuleAction = RuleAction{}
+ }
+ return nil
+}
+
+func unmarshalLogicalRuleContext(ctx context.Context, data []byte, rule *LogicalRule) error {
+ rawAction, routeOptions, err := inspectRouteRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ err = rejectNestedRouteRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ depth := nestedRuleDepth(ctx)
+ err = json.UnmarshalContext(nestedRuleChildContext(ctx), data, &rule.RawLogicalRule)
+ if err != nil {
+ return err
+ }
+ err = badjson.UnmarshallExcludedContext(ctx, data, &rule.RawLogicalRule, &rule.RuleAction)
+ if err != nil {
+ return err
+ }
+ if depth > 0 && rawAction == "" && routeOptions == (RouteActionOptions{}) {
+ rule.RuleAction = RuleAction{}
+ }
+ return nil
+}
+
func (r *LogicalRule) IsValid() bool {
return len(r.Rules) > 0 && common.All(r.Rules, Rule.IsValid)
}
diff --git a/option/rule_action.go b/option/rule_action.go
index 4310825520..a8ec576be7 100644
--- a/option/rule_action.go
+++ b/option/rule_action.go
@@ -115,6 +115,10 @@ func (r DNSRuleAction) MarshalJSON() ([]byte, error) {
case C.RuleActionTypeRoute:
r.Action = ""
v = r.RouteOptions
+ case C.RuleActionTypeEvaluate:
+ v = r.RouteOptions
+ case C.RuleActionTypeRespond:
+ v = nil
case C.RuleActionTypeRouteOptions:
v = r.RouteOptionsOptions
case C.RuleActionTypeReject:
@@ -124,6 +128,9 @@ func (r DNSRuleAction) MarshalJSON() ([]byte, error) {
default:
return nil, E.New("unknown DNS rule action: " + r.Action)
}
+ if v == nil {
+ return badjson.MarshallObjects((_DNSRuleAction)(r))
+ }
return badjson.MarshallObjects((_DNSRuleAction)(r), v)
}
@@ -137,6 +144,10 @@ func (r *DNSRuleAction) UnmarshalJSONContext(ctx context.Context, data []byte) e
case "", C.RuleActionTypeRoute:
r.Action = C.RuleActionTypeRoute
v = &r.RouteOptions
+ case C.RuleActionTypeEvaluate:
+ v = &r.RouteOptions
+ case C.RuleActionTypeRespond:
+ v = nil
case C.RuleActionTypeRouteOptions:
v = &r.RouteOptionsOptions
case C.RuleActionTypeReject:
@@ -146,6 +157,9 @@ func (r *DNSRuleAction) UnmarshalJSONContext(ctx context.Context, data []byte) e
default:
return E.New("unknown DNS rule action: " + r.Action)
}
+ if v == nil {
+ return json.UnmarshalDisallowUnknownFields(data, &_DNSRuleAction{})
+ }
return badjson.UnmarshallExcludedContext(ctx, data, (*_DNSRuleAction)(r), v)
}
@@ -155,8 +169,9 @@ type RouteActionOptions struct {
}
type RawRouteOptionsActionOptions struct {
- OverrideAddress string `json:"override_address,omitempty"`
- OverridePort uint16 `json:"override_port,omitempty"`
+ OverrideAddress string `json:"override_address,omitempty"`
+ OverridePort uint16 `json:"override_port,omitempty"`
+ OverrideTunnelDestination string `json:"override_tunnel_destination,omitempty"`
NetworkStrategy *NetworkStrategy `json:"network_strategy,omitempty"`
FallbackDelay uint32 `json:"fallback_delay,omitempty"`
@@ -187,18 +202,22 @@ func (r *RouteOptionsActionOptions) UnmarshalJSON(data []byte) error {
}
type DNSRouteActionOptions struct {
- Server string `json:"server,omitempty"`
- Strategy DomainStrategy `json:"strategy,omitempty"`
- DisableCache bool `json:"disable_cache,omitempty"`
- RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
+ Server string `json:"server,omitempty"`
+ Strategy DomainStrategy `json:"strategy,omitempty"`
+ DisableCache bool `json:"disable_cache,omitempty"`
+ DisableOptimisticCache bool `json:"disable_optimistic_cache,omitempty"`
+ RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
+ ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
+
+ BypassIfFailed bool `json:"bypass_if_failed,omitempty"` //H
}
type _DNSRouteOptionsActionOptions struct {
- Strategy DomainStrategy `json:"strategy,omitempty"`
- DisableCache bool `json:"disable_cache,omitempty"`
- RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
+ Strategy DomainStrategy `json:"strategy,omitempty"`
+ DisableCache bool `json:"disable_cache,omitempty"`
+ DisableOptimisticCache bool `json:"disable_optimistic_cache,omitempty"`
+ RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
+ ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
}
type DNSRouteOptionsActionOptions _DNSRouteOptionsActionOptions
@@ -307,11 +326,12 @@ type RouteActionSniff struct {
}
type RouteActionResolve struct {
- Server string `json:"server,omitempty"`
- Strategy DomainStrategy `json:"strategy,omitempty"`
- DisableCache bool `json:"disable_cache,omitempty"`
- RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
- ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
+ Server string `json:"server,omitempty"`
+ Strategy DomainStrategy `json:"strategy,omitempty"`
+ DisableCache bool `json:"disable_cache,omitempty"`
+ DisableOptimisticCache bool `json:"disable_optimistic_cache,omitempty"`
+ RewriteTTL *uint32 `json:"rewrite_ttl,omitempty"`
+ ClientSubnet *badoption.Prefixable `json:"client_subnet,omitempty"`
}
type DNSRouteActionPredefined struct {
diff --git a/option/rule_action_test.go b/option/rule_action_test.go
new file mode 100644
index 0000000000..0007cd36ed
--- /dev/null
+++ b/option/rule_action_test.go
@@ -0,0 +1,29 @@
+package option
+
+import (
+ "context"
+ "testing"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing/common/json"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestDNSRuleActionRespondUnmarshalJSON(t *testing.T) {
+ t.Parallel()
+
+ var action DNSRuleAction
+ err := json.UnmarshalContext(context.Background(), []byte(`{"action":"respond"}`), &action)
+ require.NoError(t, err)
+ require.Equal(t, C.RuleActionTypeRespond, action.Action)
+ require.Equal(t, DNSRouteActionOptions{}, action.RouteOptions)
+}
+
+func TestDNSRuleActionRespondRejectsUnknownFields(t *testing.T) {
+ t.Parallel()
+
+ var action DNSRuleAction
+ err := json.UnmarshalContext(context.Background(), []byte(`{"action":"respond","disable_cache":true}`), &action)
+ require.ErrorContains(t, err, "unknown field")
+}
diff --git a/option/rule_dns.go b/option/rule_dns.go
index dbc1657898..4834035315 100644
--- a/option/rule_dns.go
+++ b/option/rule_dns.go
@@ -35,7 +35,7 @@ func (r DNSRule) MarshalJSON() ([]byte, error) {
}
func (r *DNSRule) UnmarshalJSONContext(ctx context.Context, bytes []byte) error {
- err := json.Unmarshal(bytes, (*_DNSRule)(r))
+ err := json.UnmarshalContext(ctx, bytes, (*_DNSRule)(r))
if err != nil {
return err
}
@@ -78,12 +78,6 @@ type RawDefaultDNSRule struct {
DomainSuffix badoption.Listable[string] `json:"domain_suffix,omitempty"`
DomainKeyword badoption.Listable[string] `json:"domain_keyword,omitempty"`
DomainRegex badoption.Listable[string] `json:"domain_regex,omitempty"`
- Geosite badoption.Listable[string] `json:"geosite,omitempty"`
- SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
- GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
- IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
- IPIsPrivate bool `json:"ip_is_private,omitempty"`
- IPAcceptAny bool `json:"ip_accept_any,omitempty"`
SourceIPCIDR badoption.Listable[string] `json:"source_ip_cidr,omitempty"`
SourceIPIsPrivate bool `json:"source_ip_is_private,omitempty"`
SourcePort badoption.Listable[uint16] `json:"source_port,omitempty"`
@@ -94,6 +88,7 @@ type RawDefaultDNSRule struct {
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
+ PackageNameRegex badoption.Listable[string] `json:"package_name_regex,omitempty"`
User badoption.Listable[string] `json:"user,omitempty"`
UserID badoption.Listable[int32] `json:"user_id,omitempty"`
Outbound badoption.Listable[string] `json:"outbound,omitempty"`
@@ -106,11 +101,29 @@ type RawDefaultDNSRule struct {
InterfaceAddress *badjson.TypedMap[string, badoption.Listable[*badoption.Prefixable]] `json:"interface_address,omitempty"`
NetworkInterfaceAddress *badjson.TypedMap[InterfaceType, badoption.Listable[*badoption.Prefixable]] `json:"network_interface_address,omitempty"`
DefaultInterfaceAddress badoption.Listable[*badoption.Prefixable] `json:"default_interface_address,omitempty"`
+ SourceMACAddress badoption.Listable[string] `json:"source_mac_address,omitempty"`
+ SourceHostname badoption.Listable[string] `json:"source_hostname,omitempty"`
RuleSet badoption.Listable[string] `json:"rule_set,omitempty"`
RuleSetIPCIDRMatchSource bool `json:"rule_set_ip_cidr_match_source,omitempty"`
- RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
+ MatchResponse bool `json:"match_response,omitempty"`
+ IPCIDR badoption.Listable[string] `json:"ip_cidr,omitempty"`
+ IPIsPrivate bool `json:"ip_is_private,omitempty"`
+ IPAcceptAny bool `json:"ip_accept_any,omitempty"`
+ ResponseRcode *DNSRCode `json:"response_rcode,omitempty"`
+ ResponseAnswer badoption.Listable[DNSRecordOptions] `json:"response_answer,omitempty"`
+ ResponseNs badoption.Listable[DNSRecordOptions] `json:"response_ns,omitempty"`
+ ResponseExtra badoption.Listable[DNSRecordOptions] `json:"response_extra,omitempty"`
Invert bool `json:"invert,omitempty"`
+ TunnelSource badoption.Listable[string] `json:"tunnel_source,omitempty"` //E
+ TunnelDestination badoption.Listable[string] `json:"tunnel_destination,omitempty"` //E
+
+ // Deprecated: removed in sing-box 1.12.0
+ Geosite badoption.Listable[string] `json:"geosite,omitempty"`
+ SourceGeoIP badoption.Listable[string] `json:"source_geoip,omitempty"`
+ GeoIP badoption.Listable[string] `json:"geoip,omitempty"`
+ // Deprecated: removed in sing-box 1.11.0
+ RuleSetIPCIDRAcceptEmpty bool `json:"rule_set_ip_cidr_accept_empty,omitempty"`
// Deprecated: renamed to rule_set_ip_cidr_match_source
Deprecated_RulesetIPCIDRMatchSource bool `json:"rule_set_ipcidr_match_source,omitempty"`
}
@@ -125,11 +138,27 @@ func (r DefaultDNSRule) MarshalJSON() ([]byte, error) {
}
func (r *DefaultDNSRule) UnmarshalJSONContext(ctx context.Context, data []byte) error {
- err := json.UnmarshalContext(ctx, data, &r.RawDefaultDNSRule)
+ rawAction, routeOptions, err := inspectDNSRuleAction(ctx, data)
if err != nil {
return err
}
- return badjson.UnmarshallExcludedContext(ctx, data, &r.RawDefaultDNSRule, &r.DNSRuleAction)
+ err = rejectNestedDNSRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ depth := nestedRuleDepth(ctx)
+ err = json.UnmarshalContext(ctx, data, &r.RawDefaultDNSRule)
+ if err != nil {
+ return err
+ }
+ err = badjson.UnmarshallExcludedContext(ctx, data, &r.RawDefaultDNSRule, &r.DNSRuleAction)
+ if err != nil {
+ return err
+ }
+ if depth > 0 && rawAction == "" && routeOptions == (DNSRouteActionOptions{}) {
+ r.DNSRuleAction = DNSRuleAction{}
+ }
+ return nil
}
func (r DefaultDNSRule) IsValid() bool {
@@ -154,11 +183,27 @@ func (r LogicalDNSRule) MarshalJSON() ([]byte, error) {
}
func (r *LogicalDNSRule) UnmarshalJSONContext(ctx context.Context, data []byte) error {
- err := json.Unmarshal(data, &r.RawLogicalDNSRule)
+ rawAction, routeOptions, err := inspectDNSRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ err = rejectNestedDNSRuleAction(ctx, data)
+ if err != nil {
+ return err
+ }
+ depth := nestedRuleDepth(ctx)
+ err = json.UnmarshalContext(nestedRuleChildContext(ctx), data, &r.RawLogicalDNSRule)
if err != nil {
return err
}
- return badjson.UnmarshallExcludedContext(ctx, data, &r.RawLogicalDNSRule, &r.DNSRuleAction)
+ err = badjson.UnmarshallExcludedContext(ctx, data, &r.RawLogicalDNSRule, &r.DNSRuleAction)
+ if err != nil {
+ return err
+ }
+ if depth > 0 && rawAction == "" && routeOptions == (DNSRouteActionOptions{}) {
+ r.DNSRuleAction = DNSRuleAction{}
+ }
+ return nil
}
func (r *LogicalDNSRule) IsValid() bool {
diff --git a/option/rule_nested.go b/option/rule_nested.go
new file mode 100644
index 0000000000..a48c17ea39
--- /dev/null
+++ b/option/rule_nested.go
@@ -0,0 +1,129 @@
+package option
+
+import (
+ "context"
+ "reflect"
+ "slices"
+ "strings"
+
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badjson"
+)
+
+type nestedRuleDepthContextKey struct{}
+
+const (
+ RouteRuleActionNestedUnsupportedMessage = "rule action is not supported in nested rules"
+ DNSRuleActionNestedUnsupportedMessage = "DNS rule action is not supported in nested rules"
+)
+
+var (
+ routeRuleActionKeys = jsonFieldNames(reflect.TypeFor[_RuleAction](), reflect.TypeFor[RouteActionOptions]())
+ dnsRuleActionKeys = jsonFieldNames(reflect.TypeFor[_DNSRuleAction](), reflect.TypeFor[DNSRouteActionOptions]())
+)
+
+func nestedRuleChildContext(ctx context.Context) context.Context {
+ return context.WithValue(ctx, nestedRuleDepthContextKey{}, nestedRuleDepth(ctx)+1)
+}
+
+func rejectNestedRouteRuleAction(ctx context.Context, content []byte) error {
+ return rejectNestedRuleAction(ctx, content, routeRuleActionKeys, RouteRuleActionNestedUnsupportedMessage)
+}
+
+func rejectNestedDNSRuleAction(ctx context.Context, content []byte) error {
+ return rejectNestedRuleAction(ctx, content, dnsRuleActionKeys, DNSRuleActionNestedUnsupportedMessage)
+}
+
+func nestedRuleDepth(ctx context.Context) int {
+ depth, _ := ctx.Value(nestedRuleDepthContextKey{}).(int)
+ return depth
+}
+
+func rejectNestedRuleAction(ctx context.Context, content []byte, keys []string, message string) error {
+ if nestedRuleDepth(ctx) == 0 {
+ return nil
+ }
+ hasActionKey, err := hasAnyJSONKey(ctx, content, keys...)
+ if err != nil {
+ return err
+ }
+ if hasActionKey {
+ return E.New(message)
+ }
+ return nil
+}
+
+func hasAnyJSONKey(ctx context.Context, content []byte, keys ...string) (bool, error) {
+ var object badjson.JSONObject
+ err := object.UnmarshalJSONContext(ctx, content)
+ if err != nil {
+ return false, err
+ }
+ return slices.ContainsFunc(keys, object.ContainsKey), nil
+}
+
+func inspectRouteRuleAction(ctx context.Context, content []byte) (string, RouteActionOptions, error) {
+ var rawAction _RuleAction
+ err := json.UnmarshalContext(ctx, content, &rawAction)
+ if err != nil {
+ return "", RouteActionOptions{}, err
+ }
+ var routeOptions RouteActionOptions
+ err = json.UnmarshalContext(ctx, content, &routeOptions)
+ if err != nil {
+ return "", RouteActionOptions{}, err
+ }
+ return rawAction.Action, routeOptions, nil
+}
+
+func inspectDNSRuleAction(ctx context.Context, content []byte) (string, DNSRouteActionOptions, error) {
+ var rawAction _DNSRuleAction
+ err := json.UnmarshalContext(ctx, content, &rawAction)
+ if err != nil {
+ return "", DNSRouteActionOptions{}, err
+ }
+ var routeOptions DNSRouteActionOptions
+ err = json.UnmarshalContext(ctx, content, &routeOptions)
+ if err != nil {
+ return "", DNSRouteActionOptions{}, err
+ }
+ return rawAction.Action, routeOptions, nil
+}
+
+func jsonFieldNames(types ...reflect.Type) []string {
+ fieldMap := make(map[string]struct{})
+ for _, fieldType := range types {
+ appendJSONFieldNames(fieldMap, fieldType)
+ }
+ fieldNames := make([]string, 0, len(fieldMap))
+ for fieldName := range fieldMap {
+ fieldNames = append(fieldNames, fieldName)
+ }
+ return fieldNames
+}
+
+func appendJSONFieldNames(fieldMap map[string]struct{}, fieldType reflect.Type) {
+ for fieldType.Kind() == reflect.Pointer {
+ fieldType = fieldType.Elem()
+ }
+ if fieldType.Kind() != reflect.Struct {
+ return
+ }
+ for i := range fieldType.NumField() {
+ field := fieldType.Field(i)
+ tagValue := field.Tag.Get("json")
+ tagName, _, _ := strings.Cut(tagValue, ",")
+ if tagName == "-" {
+ continue
+ }
+ if field.Anonymous && tagName == "" {
+ appendJSONFieldNames(fieldMap, field.Type)
+ continue
+ }
+ if tagName == "" {
+ tagName = field.Name
+ }
+ fieldMap[tagName] = struct{}{}
+ }
+}
diff --git a/option/rule_nested_test.go b/option/rule_nested_test.go
new file mode 100644
index 0000000000..3b2ef2e5f0
--- /dev/null
+++ b/option/rule_nested_test.go
@@ -0,0 +1,68 @@
+package option
+
+import (
+ "context"
+ "testing"
+
+ "github.com/sagernet/sing/common/json"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestRuleRejectsNestedDefaultRuleAction(t *testing.T) {
+ t.Parallel()
+
+ var rule Rule
+ err := json.UnmarshalContext(context.Background(), []byte(`{
+ "type": "logical",
+ "mode": "and",
+ "rules": [
+ {"domain": "example.com", "outbound": "direct"}
+ ]
+ }`), &rule)
+ require.ErrorContains(t, err, RouteRuleActionNestedUnsupportedMessage)
+}
+
+func TestRuleLeavesUnknownNestedKeysToNormalValidation(t *testing.T) {
+ t.Parallel()
+
+ var rule Rule
+ err := json.UnmarshalContext(context.Background(), []byte(`{
+ "type": "logical",
+ "mode": "and",
+ "rules": [
+ {"domain": "example.com", "foo": "bar"}
+ ]
+ }`), &rule)
+ require.ErrorContains(t, err, "unknown field")
+ require.NotContains(t, err.Error(), RouteRuleActionNestedUnsupportedMessage)
+}
+
+func TestDNSRuleRejectsNestedDefaultRuleAction(t *testing.T) {
+ t.Parallel()
+
+ var rule DNSRule
+ err := json.UnmarshalContext(context.Background(), []byte(`{
+ "type": "logical",
+ "mode": "and",
+ "rules": [
+ {"domain": "example.com", "server": "default"}
+ ]
+ }`), &rule)
+ require.ErrorContains(t, err, DNSRuleActionNestedUnsupportedMessage)
+}
+
+func TestDNSRuleLeavesUnknownNestedKeysToNormalValidation(t *testing.T) {
+ t.Parallel()
+
+ var rule DNSRule
+ err := json.UnmarshalContext(context.Background(), []byte(`{
+ "type": "logical",
+ "mode": "and",
+ "rules": [
+ {"domain": "example.com", "foo": "bar"}
+ ]
+ }`), &rule)
+ require.ErrorContains(t, err, "unknown field")
+ require.NotContains(t, err.Error(), DNSRuleActionNestedUnsupportedMessage)
+}
diff --git a/option/rule_set.go b/option/rule_set.go
index b06342280b..18d8490339 100644
--- a/option/rule_set.go
+++ b/option/rule_set.go
@@ -122,8 +122,10 @@ type LocalRuleSet struct {
type RemoteRuleSet struct {
URL string `json:"url"`
- DownloadDetour string `json:"download_detour,omitempty"`
+ HTTPClient *HTTPClientOptions `json:"http_client,omitempty"`
UpdateInterval badoption.Duration `json:"update_interval,omitempty"`
+ // Deprecated: use http_client instead
+ DownloadDetour string `json:"download_detour,omitempty"`
}
type _HeadlessRule struct {
@@ -198,6 +200,7 @@ type DefaultHeadlessRule struct {
ProcessPath badoption.Listable[string] `json:"process_path,omitempty"`
ProcessPathRegex badoption.Listable[string] `json:"process_path_regex,omitempty"`
PackageName badoption.Listable[string] `json:"package_name,omitempty"`
+ PackageNameRegex badoption.Listable[string] `json:"package_name_regex,omitempty"`
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
NetworkIsExpensive bool `json:"network_is_expensive,omitempty"`
NetworkIsConstrained bool `json:"network_is_constrained,omitempty"`
@@ -214,6 +217,10 @@ type DefaultHeadlessRule struct {
AdGuardDomain badoption.Listable[string] `json:"-"`
AdGuardDomainMatcher *domain.AdGuardMatcher `json:"-"`
+
+ TunnelSource badoption.Listable[string] `json:"tunnel_source,omitempty"` //E
+ TunnelDestination badoption.Listable[string] `json:"tunnel_destination,omitempty"` //E
+
}
func (r DefaultHeadlessRule) IsValid() bool {
@@ -243,7 +250,7 @@ type PlainRuleSetCompat _PlainRuleSetCompat
func (r PlainRuleSetCompat) MarshalJSON() ([]byte, error) {
var v any
switch r.Version {
- case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4:
+ case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4, C.RuleSetVersion5:
v = r.Options
default:
return nil, E.New("unknown rule-set version: ", r.Version)
@@ -258,7 +265,7 @@ func (r *PlainRuleSetCompat) UnmarshalJSON(bytes []byte) error {
}
var v any
switch r.Version {
- case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4:
+ case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4, C.RuleSetVersion5:
v = &r.Options
case 0:
return E.New("missing rule-set version")
@@ -275,7 +282,7 @@ func (r *PlainRuleSetCompat) UnmarshalJSON(bytes []byte) error {
func (r PlainRuleSetCompat) Upgrade() (PlainRuleSet, error) {
switch r.Version {
- case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4:
+ case C.RuleSetVersion1, C.RuleSetVersion2, C.RuleSetVersion3, C.RuleSetVersion4, C.RuleSetVersion5:
default:
return PlainRuleSet{}, E.New("unknown rule-set version: " + F.ToString(r.Version))
}
diff --git a/option/shadowsocks.go b/option/shadowsocks.go
index 7cb656f367..cbb7cdf8c7 100644
--- a/option/shadowsocks.go
+++ b/option/shadowsocks.go
@@ -9,6 +9,8 @@ type ShadowsocksInboundOptions struct {
Destinations []ShadowsocksDestination `json:"destinations,omitempty"`
Multiplex *InboundMultiplexOptions `json:"multiplex,omitempty"`
Managed bool `json:"managed,omitempty"`
+ ObfsMode string `json:"obfs_mode,omitempty"`
+ ObfsHost string `json:"obfs_host,omitempty"`
}
type ShadowsocksUser struct {
diff --git a/option/smart_dns_pool.go b/option/smart_dns_pool.go
new file mode 100644
index 0000000000..400805d62b
--- /dev/null
+++ b/option/smart_dns_pool.go
@@ -0,0 +1,43 @@
+package option
+
+import (
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+// SmartDNSPoolUpstreamOptions describes one recursive resolver inside a
+// smart_dns_pool service. The smart pool carries adaptive AIMD throttling,
+// failover, and recovery probing across all upstreams configured here.
+type SmartDNSPoolUpstreamOptions struct {
+ // Type is one of "udp" | "tcp" | "tls" (DoT) | "https" (DoH).
+ Type string `json:"type"`
+ // Address is "host:port" for udp/tcp/tls, or a full https URL for DoH
+ // (e.g. https://cloudflare-dns.com/dns-query).
+ Address string `json:"address"`
+ // Weight is consulted by the "weighted" load_balance strategy. 0 means
+ // the upstream is a pure fallback (only reached when every weighted
+ // candidate is unavailable). Ignored by other strategies.
+ Weight int `json:"weight,omitempty"`
+ // Name is an optional friendly id surfaced in stats. Defaults to
+ // "://".
+ Name string `json:"name,omitempty"`
+}
+
+// SmartDNSPoolServiceOptions configures a `smart_dns_pool` service: a
+// local DNS server (UDP+TCP) that fans queries out to many recursive
+// upstream resolvers using github.com/hiddify/hmrd_multi_resolver_dns.
+//
+// Typical use: configure this with the recursive resolvers you want to
+// distribute load across, then point dnstt's `resolvers` at the local
+// listen address (e.g. udp://127.0.0.1:19876) instead of a fixed
+// `8.8.8.8` etc. dnstt sees a normal local resolver; the pool transparently
+// handles failover, AIMD rate-limit throttling, and recovery probing for
+// the real upstreams.
+type SmartDNSPoolServiceOptions struct {
+ ListenOptions
+ Upstreams []SmartDNSPoolUpstreamOptions `json:"upstreams"`
+ LoadBalance string `json:"load_balance,omitempty"` // "roundrobin" (default) | "weighted" | "lowest_latency"
+ Deadline badoption.Duration `json:"deadline,omitempty"` // overall query deadline; default 5s
+ PerAttempt badoption.Duration `json:"per_attempt,omitempty"` // per-resolver attempt cap; default 2s
+ ProbeInterval badoption.Duration `json:"probe_interval,omitempty"` // recovery probe cadence; default 5s
+ DownAfter int `json:"down_after,omitempty"` // consecutive failures before "down"; default 8
+}
diff --git a/option/snell.go b/option/snell.go
new file mode 100644
index 0000000000..82582fa916
--- /dev/null
+++ b/option/snell.go
@@ -0,0 +1,30 @@
+package option
+
+// SnellUser is one entry in a multi-user Snell inbound configuration.
+type SnellUser struct {
+ Name string `json:"name"`
+ PSK string `json:"psk"`
+}
+
+type SnellInboundOptions struct {
+ ListenOptions
+ // PSK is the pre-shared key for single-user mode.
+ // Mutually exclusive with Users.
+ PSK string `json:"psk,omitempty"`
+ Version int `json:"version,omitempty"`
+ // Users enables multi-user mode. When set, PSK must be empty.
+ Users []SnellUser `json:"users,omitempty"`
+ ObfsMode string `json:"obfs_mode,omitempty"`
+ ObfsHost string `json:"obfs_host,omitempty"`
+}
+
+type SnellOutboundOptions struct {
+ DialerOptions
+ ServerOptions
+ PSK string `json:"psk"`
+ Version int `json:"version,omitempty"`
+ Reuse bool `json:"reuse,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
+ ObfsMode string `json:"obfs_mode,omitempty"`
+ ObfsHost string `json:"obfs_host,omitempty"`
+}
diff --git a/option/ssh.go b/option/ssh.go
index 1c6ca6bb96..0ded3b36eb 100644
--- a/option/ssh.go
+++ b/option/ssh.go
@@ -13,4 +13,21 @@ type SSHOutboundOptions struct {
HostKey badoption.Listable[string] `json:"host_key,omitempty"`
HostKeyAlgorithms badoption.Listable[string] `json:"host_key_algorithms,omitempty"`
ClientVersion string `json:"client_version,omitempty"`
+ UDPOverTCP *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
+}
+
+type SSHInboundOptions struct {
+ ListenOptions
+ Users []SSHUser `json:"users,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
+ HostKey badoption.Listable[string] `json:"host_key,omitempty"`
+ HostKeyAlgorithms badoption.Listable[string] `json:"host_key_algorithms,omitempty"`
+ ServerVersion string `json:"server_version,omitempty"`
+}
+
+type SSHUser struct {
+ User string `json:"user,omitempty"`
+ Password string `json:"password,omitempty"`
+ PublicKey string `json:"public_key,omitempty"`
}
diff --git a/option/tailscale.go b/option/tailscale.go
index 68a143693e..a078e9aa88 100644
--- a/option/tailscale.go
+++ b/option/tailscale.go
@@ -3,18 +3,20 @@ package option
import (
"net/netip"
"net/url"
- "reflect"
"github.com/sagernet/sing/common/json"
+ "github.com/sagernet/sing/common/json/badjson"
"github.com/sagernet/sing/common/json/badoption"
M "github.com/sagernet/sing/common/metadata"
)
type TailscaleEndpointOptions struct {
+ // Deprecated: use control_http_client instead
DialerOptions
StateDirectory string `json:"state_directory,omitempty"`
AuthKey string `json:"auth_key,omitempty"`
ControlURL string `json:"control_url,omitempty"`
+ ControlHTTPClient *HTTPClientOptions `json:"control_http_client,omitempty"`
Ephemeral bool `json:"ephemeral,omitempty"`
Hostname string `json:"hostname,omitempty"`
AcceptRoutes bool `json:"accept_routes,omitempty"`
@@ -34,6 +36,11 @@ type TailscaleEndpointOptions struct {
type TailscaleDNSServerOptions struct {
Endpoint string `json:"endpoint,omitempty"`
AcceptDefaultResolvers bool `json:"accept_default_resolvers,omitempty"`
+ AcceptSearchDomain bool `json:"accept_search_domain,omitempty"`
+}
+
+type TailscaleCertificateProviderOptions struct {
+ Endpoint string `json:"endpoint,omitempty"`
}
type DERPServiceOptions struct {
@@ -49,9 +56,13 @@ type DERPServiceOptions struct {
STUN *DERPSTUNListenOptions `json:"stun,omitempty"`
}
-type _DERPVerifyClientURLOptions struct {
+type _DERPVerifyClientURLBase struct {
URL string `json:"url,omitempty"`
- DialerOptions
+}
+
+type _DERPVerifyClientURLOptions struct {
+ _DERPVerifyClientURLBase
+ HTTPClientOptions
}
type DERPVerifyClientURLOptions _DERPVerifyClientURLOptions
@@ -65,21 +76,32 @@ func (d DERPVerifyClientURLOptions) ServerIsDomain() bool {
}
func (d DERPVerifyClientURLOptions) MarshalJSON() ([]byte, error) {
- if reflect.DeepEqual(d, _DERPVerifyClientURLOptions{}) {
+ if d.URL != "" && d.HTTPClientOptions.IsEmpty() {
return json.Marshal(d.URL)
- } else {
- return json.Marshal(_DERPVerifyClientURLOptions(d))
}
+ return badjson.MarshallObjects(d._DERPVerifyClientURLBase, HTTPClient(d.HTTPClientOptions))
}
func (d *DERPVerifyClientURLOptions) UnmarshalJSON(bytes []byte) error {
var stringValue string
err := json.Unmarshal(bytes, &stringValue)
if err == nil {
- d.URL = stringValue
+ *d = DERPVerifyClientURLOptions{
+ _DERPVerifyClientURLBase: _DERPVerifyClientURLBase{URL: stringValue},
+ }
return nil
}
- return json.Unmarshal(bytes, (*_DERPVerifyClientURLOptions)(d))
+ err = json.Unmarshal(bytes, &d._DERPVerifyClientURLBase)
+ if err != nil {
+ return err
+ }
+ var client HTTPClient
+ err = badjson.UnmarshallExcluded(bytes, &d._DERPVerifyClientURLBase, &client)
+ if err != nil {
+ return err
+ }
+ d.HTTPClientOptions = HTTPClientOptions(client)
+ return nil
}
type DERPMeshOptions struct {
diff --git a/option/tls.go b/option/tls.go
index 60343a15f1..177dd27f07 100644
--- a/option/tls.go
+++ b/option/tls.go
@@ -28,9 +28,14 @@ type InboundTLSOptions struct {
KeyPath string `json:"key_path,omitempty"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
- ACME *InboundACMEOptions `json:"acme,omitempty"`
- ECH *InboundECHOptions `json:"ech,omitempty"`
- Reality *InboundRealityOptions `json:"reality,omitempty"`
+ HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
+ CertificateProvider *CertificateProviderOptions `json:"certificate_provider,omitempty"`
+
+ // Deprecated: use certificate_provider
+ ACME *InboundACMEOptions `json:"acme,omitempty"`
+
+ ECH *InboundECHOptions `json:"ech,omitempty"`
+ Reality *InboundRealityOptions `json:"reality,omitempty"`
}
type ClientAuthType tls.ClientAuthType
@@ -96,6 +101,7 @@ func (o *InboundTLSOptionsContainer) ReplaceInboundTLSOptions(options *InboundTL
type OutboundTLSOptions struct {
Enabled bool `json:"enabled,omitempty"`
+ Engine string `json:"engine,omitempty"`
DisableSNI bool `json:"disable_sni,omitempty"`
ServerName string `json:"server_name,omitempty"`
Insecure bool `json:"insecure,omitempty"`
@@ -114,11 +120,16 @@ type OutboundTLSOptions struct {
Fragment bool `json:"fragment,omitempty"`
FragmentFallbackDelay badoption.Duration `json:"fragment_fallback_delay,omitempty"`
RecordFragment bool `json:"record_fragment,omitempty"`
+ Spoof string `json:"spoof,omitempty"`
+ SpoofMethod string `json:"spoof_method,omitempty"`
KernelTx bool `json:"kernel_tx,omitempty"`
KernelRx bool `json:"kernel_rx,omitempty"`
+ HandshakeTimeout badoption.Duration `json:"handshake_timeout,omitempty"`
ECH *OutboundECHOptions `json:"ech,omitempty"`
UTLS *OutboundUTLSOptions `json:"utls,omitempty"`
Reality *OutboundRealityOptions `json:"reality,omitempty"`
+
+ TLSTricks *TLSTricksOptions `json:"tls_tricks,omitempty"` //H
}
type OutboundTLSOptionsContainer struct {
diff --git a/option/tls_acme.go b/option/tls_acme.go
index 6dd8fa7083..636abc6ece 100644
--- a/option/tls_acme.go
+++ b/option/tls_acme.go
@@ -20,6 +20,7 @@ type InboundACMEOptions struct {
AlternativeTLSPort uint16 `json:"alternative_tls_port,omitempty"`
ExternalAccount *ACMEExternalAccountOptions `json:"external_account,omitempty"`
DNS01Challenge *ACMEDNS01ChallengeOptions `json:"dns01_challenge,omitempty"`
+ Profile string `json:"profile,omitempty"`
}
type ACMEExternalAccountOptions struct {
diff --git a/option/tls_tricks.go b/option/tls_tricks.go
new file mode 100644
index 0000000000..e1c88664a2
--- /dev/null
+++ b/option/tls_tricks.go
@@ -0,0 +1,8 @@
+package option
+
+type TLSTricksOptions struct {
+ MixedCaseSNI bool `json:"mixedcase_sni,omitempty"`
+ PaddingMode string `json:"padding_mode,omitempty"`
+ PaddingSize string `json:"padding_size,omitempty"`
+ PaddingSNI string `json:"padding_sni,omitempty"`
+}
diff --git a/option/tuic.go b/option/tuic.go
index a9b739ec69..51cc0a5b96 100644
--- a/option/tuic.go
+++ b/option/tuic.go
@@ -10,6 +10,7 @@ type TUICInboundOptions struct {
ZeroRTTHandshake bool `json:"zero_rtt_handshake,omitempty"`
Heartbeat badoption.Duration `json:"heartbeat,omitempty"`
InboundTLSOptionsContainer
+ QUICOptions
}
type TUICUser struct {
@@ -30,4 +31,5 @@ type TUICOutboundOptions struct {
Heartbeat badoption.Duration `json:"heartbeat,omitempty"`
Network NetworkList `json:"network,omitempty"`
OutboundTLSOptionsContainer
+ QUICOptions
}
diff --git a/option/tun.go b/option/tun.go
index 72b6e456ba..379aa7c330 100644
--- a/option/tun.go
+++ b/option/tun.go
@@ -14,6 +14,8 @@ type TunInboundOptions struct {
InterfaceName string `json:"interface_name,omitempty"`
MTU uint32 `json:"mtu,omitempty"`
Address badoption.Listable[netip.Prefix] `json:"address,omitempty"`
+ DNSMode string `json:"dns_mode,omitempty"`
+ DNSAddress badoption.Listable[netip.Addr] `json:"dns_address,omitempty"`
AutoRoute bool `json:"auto_route,omitempty"`
IPRoute2TableIndex int `json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex int `json:"iproute2_rule_index,omitempty"`
@@ -39,6 +41,8 @@ type TunInboundOptions struct {
IncludeAndroidUser badoption.Listable[int] `json:"include_android_user,omitempty"`
IncludePackage badoption.Listable[string] `json:"include_package,omitempty"`
ExcludePackage badoption.Listable[string] `json:"exclude_package,omitempty"`
+ IncludeMACAddress badoption.Listable[string] `json:"include_mac_address,omitempty"`
+ ExcludeMACAddress badoption.Listable[string] `json:"exclude_mac_address,omitempty"`
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
Stack string `json:"stack,omitempty"`
Platform *TunPlatformOptions `json:"platform,omitempty"`
diff --git a/option/tunnel.go b/option/tunnel.go
new file mode 100644
index 0000000000..cc1df36b66
--- /dev/null
+++ b/option/tunnel.go
@@ -0,0 +1,21 @@
+package option
+
+import "github.com/sagernet/sing/common/json/badoption"
+
+type TunnelClientEndpointOptions struct {
+ UUID string `json:"uuid"`
+ Key string `json:"key"`
+ Outbound Outbound `json:"outbound"`
+}
+
+type TunnelServerEndpointOptions struct {
+ UUID string `json:"uuid"`
+ Users []TunnelUser `json:"users"`
+ Inbound Inbound `json:"inbound"`
+ ConnectTimeout badoption.Duration `json:"connect_timeout,omitempty"`
+}
+
+type TunnelUser struct {
+ UUID string `json:"uuid"`
+ Key string `json:"key"`
+}
diff --git a/option/v2ray_transport.go b/option/v2ray_transport.go
index 68c2385811..3e2f3c2e86 100644
--- a/option/v2ray_transport.go
+++ b/option/v2ray_transport.go
@@ -1,6 +1,11 @@
package option
import (
+ "net/http"
+ "strings"
+
+ Xbadoption "github.com/sagernet/sing-box/common/xray/json/badoption"
+ "github.com/sagernet/sing-box/common/xray/utils"
C "github.com/sagernet/sing-box/constant"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/json"
@@ -15,6 +20,8 @@ type _V2RayTransportOptions struct {
QUICOptions V2RayQUICOptions `json:"-"`
GRPCOptions V2RayGRPCOptions `json:"-"`
HTTPUpgradeOptions V2RayHTTPUpgradeOptions `json:"-"`
+ XHTTPOptions V2RayXHTTPOptions `json:"-"`
+ DNSTTOptions DnsttOptions `json:"-"`
}
type V2RayTransportOptions _V2RayTransportOptions
@@ -32,6 +39,8 @@ func (o V2RayTransportOptions) MarshalJSON() ([]byte, error) {
v = o.GRPCOptions
case C.V2RayTransportTypeHTTPUpgrade:
v = o.HTTPUpgradeOptions
+ case C.V2RayTransportTypeXHTTP:
+ v = o.XHTTPOptions
case "":
return nil, E.New("missing transport type")
default:
@@ -57,6 +66,8 @@ func (o *V2RayTransportOptions) UnmarshalJSON(bytes []byte) error {
v = &o.GRPCOptions
case C.V2RayTransportTypeHTTPUpgrade:
v = &o.HTTPUpgradeOptions
+ case C.V2RayTransportTypeXHTTP:
+ v = &o.XHTTPOptions
default:
return E.New("unknown transport type: " + o.Type)
}
@@ -98,3 +109,363 @@ type V2RayHTTPUpgradeOptions struct {
Path string `json:"path,omitempty"`
Headers badoption.HTTPHeader `json:"headers,omitempty"`
}
+
+type V2RayXHTTPBaseOptions struct {
+ Host string `json:"host,omitempty"`
+ Path string `json:"path,omitempty"`
+ Headers map[string]string `json:"headers,omitempty"`
+ DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
+ XPaddingBytes Xbadoption.Range `json:"x_padding_bytes"`
+ NoGRPCHeader bool `json:"no_grpc_header,omitempty"`
+ NoSSEHeader bool `json:"no_sse_header,omitempty"`
+ ScMaxEachPostBytes Xbadoption.Range `json:"sc_max_each_post_bytes"`
+ ScMinPostsIntervalMs Xbadoption.Range `json:"sc_min_posts_interval_ms"`
+ ScMaxBufferedPosts int64 `json:"sc_max_buffered_posts,omitempty"`
+ ScStreamUpServerSecs Xbadoption.Range `json:"sc_stream_up_server_secs"`
+ Xmux *V2RayXHTTPXmuxOptions `json:"xmux"`
+ XPaddingObfsMode bool `json:"x_padding_obfs_mode,omitempty"`
+ XPaddingKey string `json:"x_padding_key,omitempty"`
+ XPaddingHeader string `json:"x_padding_header,omitempty"`
+ XPaddingPlacement string `json:"x_padding_placement,omitempty"`
+ XPaddingMethod string `json:"x_padding_method,omitempty"`
+ UplinkHTTPMethod string `json:"uplink_http_method,omitempty"`
+ SessionPlacement string `json:"session_placement,omitempty"`
+ SessionKey string `json:"session_key,omitempty"`
+ SeqPlacement string `json:"seq_placement,omitempty"`
+ SeqKey string `json:"seq_key,omitempty"`
+ UplinkDataPlacement string `json:"uplink_data_placement,omitempty"`
+ UplinkDataKey string `json:"uplink_data_key,omitempty"`
+ UplinkChunkSize uint32 `json:"uplink_chunk_size,omitempty"`
+}
+
+type _V2RayXHTTPOptions struct {
+ Mode string `json:"mode"`
+ V2RayXHTTPBaseOptions
+ Download *V2RayXHTTPDownloadOptions `json:"download"`
+}
+
+type V2RayXHTTPOptions _V2RayXHTTPOptions
+
+type V2RayXHTTPDownloadOptions struct {
+ V2RayXHTTPBaseOptions
+ ServerOptions
+ OutboundTLSOptionsContainer
+ Detour string `json:"detour,omitempty"`
+}
+
+const (
+ PlacementQueryInHeader = "queryInHeader"
+ PlacementCookie = "cookie"
+ PlacementHeader = "header"
+ PlacementQuery = "query"
+ PlacementPath = "path"
+ PlacementBody = "body"
+)
+
+func (c V2RayXHTTPOptions) MarshalJSON() ([]byte, error) {
+ return json.Marshal((*_V2RayXHTTPOptions)(&c))
+}
+
+func (c *V2RayXHTTPOptions) UnmarshalJSON(bytes []byte) error {
+ err := json.Unmarshal(bytes, (*_V2RayXHTTPOptions)(c))
+ if err != nil {
+ return err
+ }
+ switch c.Mode {
+ case "":
+ c.Mode = "auto"
+ case "auto", "packet-up", "stream-up", "stream-one":
+ default:
+ return E.New("unsupported mode: " + c.Mode)
+ }
+ err = checkV2RayXHTTPBaseOptions(c.Mode, &c.V2RayXHTTPBaseOptions)
+ if err != nil {
+ return err
+ }
+ if c.Download != nil {
+ err = checkV2RayXHTTPBaseOptions(c.Mode, &c.Download.V2RayXHTTPBaseOptions)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func checkV2RayXHTTPBaseOptions(mode string, options *V2RayXHTTPBaseOptions) error {
+ // Priority (client): host > serverName > address
+ for k := range options.Headers {
+ if strings.ToLower(k) == "host" {
+ return E.New(`"headers" can't contain "host"`)
+ }
+ }
+ if options.XPaddingBytes.From <= 0 || options.XPaddingBytes.To <= 0 {
+ return E.New("xPaddingBytes cannot be disabled")
+ }
+ if options.XPaddingKey == "" {
+ options.XPaddingKey = "x_padding"
+ }
+ if options.XPaddingHeader == "" {
+ options.XPaddingHeader = "X-Padding"
+ }
+ switch options.XPaddingPlacement {
+ case "":
+ options.XPaddingPlacement = "queryInHeader"
+ case "cookie", "header", "query", "queryInHeader":
+ default:
+ return E.New("unsupported padding placement: " + options.XPaddingPlacement)
+ }
+ switch options.XPaddingMethod {
+ case "":
+ options.XPaddingMethod = "repeat-x"
+ case "repeat-x", "tokenish":
+ default:
+ return E.New("unsupported padding method: " + options.XPaddingMethod)
+ }
+ switch options.UplinkDataPlacement {
+ case "":
+ options.UplinkDataPlacement = "body"
+ case "body":
+ case "cookie", "header":
+ if mode != "packet-up" {
+ return E.New("UplinkDataPlacement can be " + options.UplinkDataPlacement + " only in packet-up mode")
+ }
+ default:
+ return E.New("unsupported uplink data placement: " + options.UplinkDataPlacement)
+ }
+ if options.UplinkHTTPMethod == "" {
+ options.UplinkHTTPMethod = "POST"
+ }
+ options.UplinkHTTPMethod = strings.ToUpper(options.UplinkHTTPMethod)
+ if options.UplinkHTTPMethod == "GET" && mode != "packet-up" {
+ return E.New("uplinkHTTPMethod can be GET only in packet-up mode")
+ }
+ switch options.SessionPlacement {
+ case "":
+ options.SessionPlacement = "path"
+ case "path", "cookie", "header", "query":
+ default:
+ return E.New("unsupported session placement: " + options.SessionPlacement)
+ }
+ switch options.SeqPlacement {
+ case "":
+ options.SeqPlacement = "path"
+ case "path":
+ case "cookie", "header", "query":
+ if options.SessionPlacement == "path" {
+ return E.New("SeqPlacement must be path when SessionPlacement is path")
+ }
+ default:
+ return E.New("unsupported seq placement: " + options.SeqPlacement)
+ }
+ if options.SessionPlacement != "path" && options.SessionKey == "" {
+ switch options.SessionPlacement {
+ case "cookie", "query":
+ options.SessionKey = "x_session"
+ case "header":
+ options.SessionKey = "X-Session"
+ }
+ }
+ if options.SeqPlacement != "path" && options.SeqKey == "" {
+ switch options.SeqPlacement {
+ case "cookie", "query":
+ options.SeqKey = "x_seq"
+ case "header":
+ options.SeqKey = "X-Seq"
+ }
+ }
+ if options.UplinkDataPlacement != "body" && options.UplinkDataKey == "" {
+ switch options.UplinkDataPlacement {
+ case "cookie":
+ options.UplinkDataKey = "x_data"
+ case "header":
+ options.UplinkDataKey = "X-Data"
+ }
+ }
+ if options.UplinkChunkSize == 0 {
+ switch options.UplinkDataPlacement {
+ case "cookie":
+ options.UplinkChunkSize = 3 * 1024 // 3KB
+ case "header":
+ options.UplinkChunkSize = 4 * 1024 // 4KB
+ }
+ } else if options.UplinkChunkSize < 64 {
+ options.UplinkChunkSize = 64
+ }
+ if options.Xmux == nil {
+ options.Xmux = &V2RayXHTTPXmuxOptions{}
+ options.Xmux.MaxConcurrency.From = 1
+ options.Xmux.MaxConcurrency.To = 1
+ options.Xmux.HMaxRequestTimes.From = 600
+ options.Xmux.HMaxRequestTimes.To = 900
+ options.Xmux.HMaxReusableSecs.From = 1800
+ options.Xmux.HMaxReusableSecs.To = 3000
+ } else if options.Xmux.MaxConnections.To > 0 && options.Xmux.MaxConcurrency.To > 0 {
+ return E.New("maxConnections cannot be specified together with maxConcurrency")
+ }
+ return nil
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedPath() string {
+ pathAndQuery := strings.SplitN(c.Path, "?", 2)
+ path := pathAndQuery[0]
+ if path == "" || path[0] != '/' {
+ path = "/" + path
+ }
+ if path[len(path)-1] != '/' {
+ path = path + "/"
+ }
+ return path
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedQuery() string {
+ pathAndQuery := strings.SplitN(c.Path, "?", 2)
+ query := ""
+ if len(pathAndQuery) > 1 {
+ query = pathAndQuery[1]
+ }
+ return query
+}
+
+func (c *V2RayXHTTPBaseOptions) GetRequestHeader() http.Header {
+ header := http.Header{}
+ for k, v := range c.Headers {
+ header.Add(k, v)
+ }
+ if header.Get("User-Agent") == "" {
+ header.Set("User-Agent", utils.ChromeUA)
+ }
+ return header
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedXPaddingBytes() Xbadoption.Range {
+ if c.XPaddingBytes.To == 0 {
+ return Xbadoption.Range{
+ From: 100,
+ To: 1000,
+ }
+ }
+ return c.XPaddingBytes
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedUplinkHTTPMethod() string {
+ if c.UplinkHTTPMethod == "" {
+ return "POST"
+ }
+ return c.UplinkHTTPMethod
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedScMaxEachPostBytes() Xbadoption.Range {
+ if c.ScMaxEachPostBytes.To == 0 {
+ return Xbadoption.Range{
+ From: 1000000,
+ To: 1000000,
+ }
+ }
+ return c.ScMaxEachPostBytes
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedScMinPostsIntervalMs() Xbadoption.Range {
+ if c.ScMinPostsIntervalMs.To == 0 {
+ return Xbadoption.Range{
+ From: 30,
+ To: 30,
+ }
+ }
+ return c.ScMinPostsIntervalMs
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedScMaxBufferedPosts() int {
+ if c.ScMaxBufferedPosts == 0 {
+ return 30
+ }
+
+ return int(c.ScMaxBufferedPosts)
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedScStreamUpServerSecs() Xbadoption.Range {
+ if c.ScStreamUpServerSecs.To == 0 {
+ return Xbadoption.Range{
+ From: 20,
+ To: 80,
+ }
+ }
+ return c.ScStreamUpServerSecs
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedSessionPlacement() string {
+ if c.SessionPlacement == "" {
+ return PlacementPath
+ }
+ return c.SessionPlacement
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedSeqPlacement() string {
+ if c.SeqPlacement == "" {
+ return PlacementPath
+ }
+ return c.SeqPlacement
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedUplinkDataPlacement() string {
+ if c.UplinkDataPlacement == "" {
+ return PlacementBody
+ }
+ return c.UplinkDataPlacement
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedSessionKey() string {
+ if c.SessionKey != "" {
+ return c.SessionKey
+ }
+ switch c.GetNormalizedSessionPlacement() {
+ case PlacementHeader:
+ return "X-Session"
+ case PlacementCookie, PlacementQuery:
+ return "x_session"
+ default:
+ return ""
+ }
+}
+
+func (c *V2RayXHTTPBaseOptions) GetNormalizedSeqKey() string {
+ if c.SeqKey != "" {
+ return c.SeqKey
+ }
+ switch c.GetNormalizedSeqPlacement() {
+ case PlacementHeader:
+ return "X-Seq"
+ case PlacementCookie, PlacementQuery:
+ return "x_seq"
+ default:
+ return ""
+ }
+}
+
+type V2RayXHTTPXmuxOptions struct {
+ MaxConcurrency Xbadoption.Range `json:"max_concurrency"`
+ MaxConnections Xbadoption.Range `json:"max_connections"`
+ CMaxReuseTimes Xbadoption.Range `json:"c_max_reuse_times"`
+ HMaxRequestTimes Xbadoption.Range `json:"h_max_request_times"`
+ HMaxReusableSecs Xbadoption.Range `json:"h_max_reusable_secs"`
+ HKeepAlivePeriod int64 `json:"h_keep_alive_period"`
+}
+
+func (m *V2RayXHTTPXmuxOptions) GetNormalizedMaxConcurrency() Xbadoption.Range {
+ return m.MaxConcurrency
+}
+
+func (m *V2RayXHTTPXmuxOptions) GetNormalizedMaxConnections() Xbadoption.Range {
+ return m.MaxConnections
+}
+
+func (m *V2RayXHTTPXmuxOptions) GetNormalizedCMaxReuseTimes() Xbadoption.Range {
+ return m.CMaxReuseTimes
+}
+
+func (m *V2RayXHTTPXmuxOptions) GetNormalizedHMaxRequestTimes() Xbadoption.Range {
+ return m.HMaxRequestTimes
+}
+
+func (m *V2RayXHTTPXmuxOptions) GetNormalizedHMaxReusableSecs() Xbadoption.Range {
+ return m.HMaxReusableSecs
+}
diff --git a/option/vless.go b/option/vless.go
index 5acf2aeed0..989bcc6502 100644
--- a/option/vless.go
+++ b/option/vless.go
@@ -2,7 +2,8 @@ package option
type VLESSInboundOptions struct {
ListenOptions
- Users []VLESSUser `json:"users,omitempty"`
+ Users []VLESSUser `json:"users,omitempty"`
+ Decryption string `json:"decryption,omitempty"`
InboundTLSOptionsContainer
Multiplex *InboundMultiplexOptions `json:"multiplex,omitempty"`
Transport *V2RayTransportOptions `json:"transport,omitempty"`
@@ -17,9 +18,10 @@ type VLESSUser struct {
type VLESSOutboundOptions struct {
DialerOptions
ServerOptions
- UUID string `json:"uuid"`
- Flow string `json:"flow,omitempty"`
- Network NetworkList `json:"network,omitempty"`
+ UUID string `json:"uuid"`
+ Flow string `json:"flow,omitempty"`
+ Encryption string `json:"encryption,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
OutboundTLSOptionsContainer
Multiplex *OutboundMultiplexOptions `json:"multiplex,omitempty"`
Transport *V2RayTransportOptions `json:"transport,omitempty"`
diff --git a/option/wireguard.go b/option/wireguard.go
index c86abd112a..7dcee2bd9c 100644
--- a/option/wireguard.go
+++ b/option/wireguard.go
@@ -3,20 +3,27 @@ package option
import (
"net/netip"
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common/json/badoption"
+ hiddify "github.com/sagernet/wireguard-go/hiddify"
)
type WireGuardEndpointOptions struct {
- System bool `json:"system,omitempty"`
- Name string `json:"name,omitempty"`
- MTU uint32 `json:"mtu,omitempty"`
- Address badoption.Listable[netip.Prefix] `json:"address"`
- PrivateKey string `json:"private_key"`
- ListenPort uint16 `json:"listen_port,omitempty"`
- Peers []WireGuardPeer `json:"peers,omitempty"`
- UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"`
- Workers int `json:"workers,omitempty"`
+ System bool `json:"system,omitempty"`
+ Name string `json:"name,omitempty"`
+ MTU uint32 `json:"mtu,omitempty"`
+ Address badoption.Listable[netip.Prefix] `json:"address"`
+ PrivateKey string `json:"private_key"`
+ ListenPort uint16 `json:"listen_port,omitempty"`
+ Peers []WireGuardPeer `json:"peers,omitempty"`
+ UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"`
+ Workers int `json:"workers,omitempty"`
+ PreallocatedBuffersPerPool uint32 `json:"preallocated_buffers_per_pool,omitempty"`
+ DisablePauses bool `json:"disable_pauses,omitempty"`
DialerOptions
+
+ Noise hiddify.NoiseOptions `json:"noise,omitempty"`
+ AWG *AwgOptions `json:"awg,omitempty"`
}
type WireGuardPeer struct {
@@ -28,3 +35,60 @@ type WireGuardPeer struct {
PersistentKeepaliveInterval uint16 `json:"persistent_keepalive_interval,omitempty"`
Reserved []uint8 `json:"reserved,omitempty"`
}
+
+type WARPEndpointOptions struct {
+ System bool `json:"system,omitempty"`
+ Name string `json:"name,omitempty"`
+ ListenPort uint16 `json:"listen_port,omitempty"`
+ UDPTimeout badoption.Duration `json:"udp_timeout,omitempty"`
+ Workers int `json:"workers,omitempty"`
+ PreallocatedBuffersPerPool uint32 `json:"preallocated_buffers_per_pool,omitempty"`
+ DisablePauses bool `json:"disable_pauses,omitempty"`
+ Profile WARPProfile `json:"profile,omitempty"`
+ DialerOptions
+
+ UniqueIdentifier string `json:"unique_identifier,omitempty"` //h
+ ServerOptions //H
+ Noise hiddify.NoiseOptions `json:"noise,omitempty"` //H
+ AWG *AwgOptions `json:"awg,omitempty"`
+ *C.WARPConfig //H
+ MTU uint32 `json:"mtu,omitempty"`
+}
+
+type WARPProfile struct {
+ ID string `json:"id,omitempty"`
+ PrivateKey string `json:"private_key,omitempty"`
+ AuthToken string `json:"auth_token,omitempty"`
+ Recreate bool `json:"recreate,omitempty"`
+ Detour string `json:"detour,omitempty"`
+ License string `json:"license,omitempty"`
+}
+
+type LegacyWireGuardOutboundOptions struct {
+ DialerOptions
+ SystemInterface bool `json:"system_interface,omitempty"`
+ GSO bool `json:"gso,omitempty"`
+ InterfaceName string `json:"interface_name,omitempty"`
+ LocalAddress badoption.Listable[netip.Prefix] `json:"local_address"`
+ PrivateKey string `json:"private_key"`
+ Peers []LegacyWireGuardPeer `json:"peers,omitempty"`
+ ServerOptions
+ PeerPublicKey string `json:"peer_public_key"`
+ PreSharedKey string `json:"pre_shared_key,omitempty"`
+ Reserved []uint8 `json:"reserved,omitempty"`
+ Workers int `json:"workers,omitempty"`
+ PreallocatedBuffersPerPool uint32 `json:"preallocated_buffers_per_pool,omitempty"`
+ DisablePauses bool `json:"disable_pauses,omitempty"`
+ MTU uint32 `json:"mtu,omitempty"`
+ Network NetworkList `json:"network,omitempty"`
+
+ Noise hiddify.NoiseOptions `json:"noise,omitempty"`
+}
+
+type LegacyWireGuardPeer struct {
+ ServerOptions
+ PublicKey string `json:"public_key,omitempty"`
+ PreSharedKey string `json:"pre_shared_key,omitempty"`
+ AllowedIPs badoption.Listable[netip.Prefix] `json:"allowed_ips,omitempty"`
+ Reserved []uint8 `json:"reserved,omitempty"`
+}
diff --git a/option/xray.go b/option/xray.go
new file mode 100644
index 0000000000..07fe023da3
--- /dev/null
+++ b/option/xray.go
@@ -0,0 +1,12 @@
+package option
+
+type XrayOutboundOptions struct {
+ DialerOptions
+ Network NetworkList `json:"network,omitempty"`
+ UDPOverTCP *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"`
+ XConfig *map[string]any `json:"xconfig,omitempty"`
+ XDebug bool `json:"xdebug,omitempty"`
+ DeprecatedXrayOutboundJson *map[string]any `json:"xray_outbound_raw,omitempty"`
+ DeprecatedFragment any `json:"xray_fragment,omitempty"`
+ DeprecatedLogLevel *string `json:"xray_loglevel,omitempty"`
+}
diff --git a/protocol/anytls/inbound.go b/protocol/anytls/inbound.go
index 52d773537a..e61e837a2a 100644
--- a/protocol/anytls/inbound.go
+++ b/protocol/anytls/inbound.go
@@ -96,7 +96,7 @@ func (h *Inbound) Close() error {
return common.Close(h.listener, h.tlsConfig)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
if h.tlsConfig != nil {
tlsConn, err := tls.ServerHandshake(ctx, conn, h.tlsConfig)
if err != nil {
diff --git a/protocol/awg/endpoint.go b/protocol/awg/endpoint.go
new file mode 100644
index 0000000000..14a0d02acf
--- /dev/null
+++ b/protocol/awg/endpoint.go
@@ -0,0 +1,348 @@
+package awg
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/hex"
+ "net"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/monitoring"
+ "github.com/sagernet/sing-box/constant"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/transport/awg"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/format"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+ "go4.org/netipx"
+)
+
+func RegisterEndpoint(registry *endpoint.Registry) {
+ endpoint.Register(registry, constant.TypeAwg, NewEndpoint)
+}
+
+type Endpoint struct {
+ *awg.Device
+ endpoint.Adapter
+ address []netip.Prefix
+ router adapter.Router
+ logger log.ContextLogger
+ dnsRouter adapter.DNSRouter
+ started bool
+ ctx context.Context
+}
+
+func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.AwgEndpointOptions) (adapter.Endpoint, error) {
+ if options.MTU == 0 {
+ options.MTU = 1408
+ }
+
+ options.UDPFragmentDefault = true
+ // Check if any peer has a domain address
+ remoteIsDomain := common.Any(options.Peers, func(peer option.AwgPeerOptions) bool {
+ return !M.ParseAddr(peer.Address).IsValid()
+ })
+ dial, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: remoteIsDomain,
+ ResolverOnDetour: true,
+ DirectOutbound: true,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ var allowedPrefixBuilder netipx.IPSetBuilder
+ var excludedPrefixBuilder netipx.IPSetBuilder
+ for _, peer := range options.Peers {
+ for _, prefix := range peer.AllowedIPs {
+ allowedPrefixBuilder.AddPrefix(prefix)
+ }
+
+ if addr, err := netip.ParseAddr(peer.Address); err == nil {
+ excludedPrefixBuilder.Add(addr)
+ }
+ }
+ allowedIps, err := allowedPrefixBuilder.IPSet()
+ if err != nil {
+ return nil, err
+ }
+ excludedIps, err := excludedPrefixBuilder.IPSet()
+ if err != nil {
+ return nil, err
+ }
+
+ // Create peer resolver function for domain endpoints
+ // Always use system resolver for peer endpoints because:
+ // 1. VPN server must be resolved before VPN tunnel is established
+ // 2. dnsRouter may not be fully initialized at this stage
+ var resolvePeer func(domain string) (netip.Addr, error)
+ if remoteIsDomain {
+ resolvePeer = func(domain string) (netip.Addr, error) {
+ addrs, lookupErr := net.DefaultResolver.LookupNetIP(ctx, "ip", domain)
+ if lookupErr != nil {
+ return netip.Addr{}, lookupErr
+ }
+ return addrs[0], nil
+ }
+ }
+
+ ipc, err := genIpcConfig(options, resolvePeer)
+ if err != nil {
+ return nil, err
+ }
+
+ logger.Debug("AWG IPC config:\n", ipc)
+
+ dev, err := awg.NewDevice(ctx, logger, dial, ipc, awg.DeviceOpts{
+ UseIntegratedTun: options.UseIntegratedTun,
+ Address: options.Address,
+ AllowedIps: allowedIps.Prefixes(),
+ ExcludedIps: excludedIps.Prefixes(),
+ MTU: options.MTU,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &Endpoint{
+ Device: dev,
+ Adapter: endpoint.NewAdapterWithDialerOptions("awg", tag, []string{N.NetworkTCP, N.NetworkUDP}, options.DialerOptions),
+ address: options.Address,
+ router: router,
+ logger: logger,
+ dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
+ ctx: ctx,
+ }, nil
+}
+
+func genIpcConfig(opts option.AwgEndpointOptions, resolvePeer func(domain string) (netip.Addr, error)) (string, error) {
+ privateKeyBytes, err := base64.StdEncoding.DecodeString(opts.PrivateKey)
+ if err != nil {
+ return "", err
+ }
+ s := "private_key=" + hex.EncodeToString(privateKeyBytes)
+ if opts.ListenPort != 0 {
+ s += "\nlisten_port=" + format.ToString(opts.ListenPort)
+ }
+ awg := opts.Awg
+ if awg.Jc != 0 {
+ s += "\njc=" + format.ToString(awg.Jc)
+ }
+ if awg.Jmin != 0 {
+ s += "\njmin=" + format.ToString(awg.Jmin)
+ }
+ if awg.Jmax != 0 {
+ s += "\njmax=" + format.ToString(awg.Jmax)
+ }
+ if awg.S1 != 0 {
+ s += "\ns1=" + format.ToString(awg.S1)
+ }
+ if awg.S2 != 0 {
+ s += "\ns2=" + format.ToString(awg.S2)
+ }
+ if awg.S3 != 0 {
+ s += "\ns3=" + format.ToString(awg.S3)
+ }
+ if awg.S4 != 0 {
+ s += "\ns4=" + format.ToString(awg.S4)
+ }
+ if awg.H1 != "" {
+ s += "\nh1=" + awg.H1
+ }
+ if awg.H2 != "" {
+ s += "\nh2=" + awg.H2
+ }
+ if awg.H3 != "" {
+ s += "\nh3=" + awg.H3
+ }
+ if awg.H4 != "" {
+ s += "\nh4=" + awg.H4
+ }
+ if awg.I1 != "" {
+ s += "\ni1=" + awg.I1
+ }
+ if awg.I2 != "" {
+ s += "\ni2=" + awg.I2
+ }
+ if awg.I3 != "" {
+ s += "\ni3=" + awg.I3
+ }
+ if awg.I4 != "" {
+ s += "\ni4=" + awg.I4
+ }
+ if awg.I5 != "" {
+ s += "\ni5=" + awg.I5
+ }
+
+ for _, peer := range opts.Peers {
+ publicKeyBytes, err := base64.StdEncoding.DecodeString(peer.PublicKey)
+ if err != nil {
+ return "", err
+ }
+ s += "\npublic_key=" + hex.EncodeToString(publicKeyBytes)
+ if peer.PresharedKey != "" {
+ presharedKeyBytes, err := base64.StdEncoding.DecodeString(peer.PresharedKey)
+ if err != nil {
+ return "", err
+ }
+ s += "\npreshared_key=" + hex.EncodeToString(presharedKeyBytes)
+ }
+ if peer.Address != "" && peer.Port != 0 {
+ // Resolve domain to IP if necessary
+ endpointAddr := peer.Address
+ if addr := M.ParseAddr(peer.Address); !addr.IsValid() {
+ // It's a domain, resolve it
+ if resolvePeer == nil {
+ return "", E.New("peer address is a domain but no resolver provided: ", peer.Address)
+ }
+ resolvedAddr, resolveErr := resolvePeer(peer.Address)
+ if resolveErr != nil {
+ return "", E.Cause(resolveErr, "resolve peer endpoint ", peer.Address)
+ }
+ endpointAddr = resolvedAddr.String()
+ }
+ s += "\nendpoint=" + endpointAddr + ":" + format.ToString(peer.Port)
+ }
+ if peer.PersistentKeepaliveInterval != 0 {
+ s += "\npersistent_keepalive_interval=" + format.ToString(peer.PersistentKeepaliveInterval)
+ }
+ for _, allowedIp := range peer.AllowedIPs {
+ s += "\nallowed_ip=" + allowedIp.String()
+ }
+ }
+ return s, nil
+}
+
+func (e *Endpoint) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Inbound = e.Tag()
+ metadata.InboundType = e.Type()
+ metadata.Source = source
+ metadata.Destination = destination
+ for _, addr := range e.address {
+ if addr.Contains(destination.Addr) {
+ metadata.OriginDestination = destination
+ if destination.Addr.Is4() {
+ metadata.Destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
+ } else {
+ metadata.Destination.Addr = netip.IPv6Loopback()
+ }
+ conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination)
+ }
+ }
+ e.logger.InfoContext(ctx, "inbound packet connection from ", source)
+ e.logger.InfoContext(ctx, "inbound packet connection to ", destination)
+ e.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
+}
+
+func (e *Endpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ switch network {
+ case N.NetworkTCP:
+ e.logger.InfoContext(ctx, "outbound connection to ", destination)
+ case N.NetworkUDP:
+ e.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ }
+ if destination.IsFqdn() {
+ destinationAddresses, err := e.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return N.DialSerial(ctx, e.Device, network, destination, destinationAddresses)
+ } else if !destination.Addr.IsValid() {
+ return nil, E.New("invalid destination: ", destination)
+ }
+ return e.Device.DialContext(ctx, network, destination)
+}
+
+func (e *Endpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ e.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ if destination.IsFqdn() {
+ destinationAddresses, err := e.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, err
+ }
+ packetConn, _, err := N.ListenSerial(ctx, e.Device, destination, destinationAddresses)
+ if err != nil {
+ return nil, err
+ }
+ return packetConn, nil
+ }
+ return e.Device.ListenPacket(ctx, destination)
+}
+
+func (w *Endpoint) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Inbound = w.Tag()
+ metadata.InboundType = w.Type()
+ metadata.Source = source
+ for _, addr := range w.address {
+ if addr.Contains(destination.Addr) {
+ metadata.OriginDestination = destination
+ if destination.Addr.Is4() {
+ destination.Addr = netip.AddrFrom4([4]uint8{127, 0, 0, 1})
+ } else {
+ destination.Addr = netip.IPv6Loopback()
+ }
+ break
+ }
+ }
+ metadata.Destination = destination
+ w.logger.InfoContext(ctx, "inbound connection from ", source)
+ w.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ w.router.RouteConnectionEx(ctx, conn, metadata, onClose)
+}
+
+func (o *Endpoint) Start(stage adapter.StartStage) error {
+ switch stage {
+ case adapter.StartStateStart:
+ return o.Device.Start(stage)
+ case adapter.StartStatePostStart:
+ go o.readyChecker()
+ }
+ return nil
+}
+
+func (w *Endpoint) readyChecker() {
+ for i := 0; i < 10; i++ {
+ if w.deviceReady() {
+ break
+ }
+ select {
+ case <-w.ctx.Done():
+ return
+ case <-time.After(time.Second):
+ }
+ }
+ w.started = true
+ if m := monitoring.Get(w.ctx); m != nil {
+ m.TestNow(w.Tag())
+ }
+}
+
+func (w *Endpoint) deviceReady() bool {
+ return w.Device != nil && w.Device.IsUnderLoad()
+}
+
+func (w *Endpoint) IsReady() bool {
+ return w.started || w.deviceReady()
+}
+
+func (w *Endpoint) DisplayType() string {
+ str := C.ProxyDisplayName(w.Type())
+ if !w.IsReady() {
+ str += " ⚠️ Connecting..."
+ }
+ return str
+}
diff --git a/protocol/cloudflare/inbound.go b/protocol/cloudflare/inbound.go
new file mode 100644
index 0000000000..f445ab956b
--- /dev/null
+++ b/protocol/cloudflare/inbound.go
@@ -0,0 +1,160 @@
+//go:build with_cloudflared
+
+package cloudflare
+
+import (
+ "context"
+ "net"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ boxDialer "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/route/rule"
+ cloudflared "github.com/sagernet/sing-cloudflared"
+ tun "github.com/sagernet/sing-tun"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/pipe"
+)
+
+func RegisterInbound(registry *inbound.Registry) {
+ inbound.Register[option.CloudflaredInboundOptions](registry, C.TypeCloudflared, NewInbound)
+}
+
+func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.CloudflaredInboundOptions) (adapter.Inbound, error) {
+ controlDialer, err := boxDialer.NewWithOptions(boxDialer.Options{
+ Context: ctx,
+ Options: options.ControlDialer,
+ RemoteIsDomain: true,
+ })
+ if err != nil {
+ return nil, E.Cause(err, "build cloudflared control dialer")
+ }
+ tunnelDialer, err := boxDialer.NewWithOptions(boxDialer.Options{
+ Context: ctx,
+ Options: options.TunnelDialer,
+ RemoteIsDomain: true,
+ })
+ if err != nil {
+ return nil, E.Cause(err, "build cloudflared tunnel dialer")
+ }
+
+ service, err := cloudflared.NewService(cloudflared.ServiceOptions{
+ Logger: logger,
+ ConnectionDialer: &routerDialer{router: router, tag: tag},
+ ControlDialer: controlDialer,
+ TunnelDialer: tunnelDialer,
+ ICMPHandler: &icmpRouterHandler{router: router, logger: logger, tag: tag},
+ ConnContext: func(connCtx context.Context) context.Context {
+ return adapter.WithContext(connCtx, &adapter.InboundContext{
+ Inbound: tag,
+ InboundType: C.TypeCloudflared,
+ })
+ },
+ Token: options.Token,
+ HAConnections: options.HighAvailabilityConnections,
+ Protocol: options.Protocol,
+ PostQuantum: options.PostQuantum,
+ EdgeIPVersion: options.EdgeIPVersion,
+ DatagramVersion: options.DatagramVersion,
+ GracePeriod: time.Duration(options.GracePeriod),
+ Region: options.Region,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return &Inbound{
+ Adapter: inbound.NewAdapter(C.TypeCloudflared, tag),
+ service: service,
+ }, nil
+}
+
+type Inbound struct {
+ inbound.Adapter
+ service *cloudflared.Service
+}
+
+func (i *Inbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ return i.service.Start()
+}
+
+func (i *Inbound) Close() error {
+ return i.service.Close()
+}
+
+type routerDialer struct {
+ router adapter.Router
+ tag string
+}
+
+func (d *routerDialer) newMetadata(network string, destination M.Socksaddr) adapter.InboundContext {
+ return adapter.InboundContext{
+ Inbound: d.tag,
+ InboundType: C.TypeCloudflared,
+ Network: network,
+ Destination: destination,
+ }
+}
+
+func (d *routerDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ input, output := pipe.Pipe()
+ go d.router.RouteConnectionEx(ctx, output, d.newMetadata(N.NetworkTCP, destination), N.OnceClose(func(it error) {
+ input.Close()
+ }))
+ return input, nil
+}
+
+func (d *routerDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ input, output := pipe.Pipe()
+ routerConn := bufio.NewUnbindPacketConn(output)
+ go d.router.RoutePacketConnectionEx(ctx, routerConn, d.newMetadata(N.NetworkUDP, destination), N.OnceClose(func(it error) {
+ input.Close()
+ }))
+ return bufio.NewUnbindPacketConn(input), nil
+}
+
+type icmpRouterHandler struct {
+ router adapter.Router
+ logger log.ContextLogger
+ tag string
+}
+
+func (h *icmpRouterHandler) RouteICMPConnection(ctx context.Context, session tun.DirectRouteSession, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
+ var ipVersion uint8
+ if session.Destination.Is4() {
+ ipVersion = 4
+ } else {
+ ipVersion = 6
+ }
+ destination := M.SocksaddrFrom(session.Destination, 0)
+ routeDestination, err := h.router.PreMatch(adapter.InboundContext{
+ Inbound: h.tag,
+ InboundType: C.TypeCloudflared,
+ IPVersion: ipVersion,
+ Network: N.NetworkICMP,
+ Source: M.SocksaddrFrom(session.Source, 0),
+ Destination: destination,
+ OriginDestination: destination,
+ }, routeContext, timeout, false)
+ if err != nil {
+ switch {
+ case rule.IsBypassed(err):
+ err = nil
+ case rule.IsRejected(err):
+ h.logger.Trace("reject ICMP connection from ", session.Source, " to ", session.Destination)
+ default:
+ h.logger.Warn(E.Cause(err, "link ICMP connection from ", session.Source, " to ", session.Destination))
+ }
+ }
+ return routeDestination, err
+}
diff --git a/protocol/direct/inbound.go b/protocol/direct/inbound.go
index 81353b6599..fcb4671d89 100644
--- a/protocol/direct/inbound.go
+++ b/protocol/direct/inbound.go
@@ -3,6 +3,7 @@ package direct
import (
"context"
"net"
+ "os"
"time"
"github.com/sagernet/sing-box/adapter"
@@ -80,11 +81,15 @@ func (i *Inbound) Close() error {
return i.listener.Close()
}
-func (i *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
+func (i *Inbound) NewPacket(buffer *buf.Buffer, source M.Socksaddr) {
i.udpNat.NewPacket([][]byte{buffer.Bytes()}, source, i.listener.UDPAddr(), nil)
}
-func (i *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (i *Inbound) NewPacketBatch(buffers []*buf.Buffer, sources []M.Socksaddr) {
+ i.udpNat.NewPacketBatch(buffers, sources, i.listener.UDPAddr(), nil)
+}
+
+func (i *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
metadata.Inbound = i.Tag()
metadata.InboundType = i.Type()
destination := metadata.OriginDestination
@@ -142,3 +147,31 @@ type directPacketWriter struct {
func (w *directPacketWriter) WritePacket(buffer *buf.Buffer, addr M.Socksaddr) error {
return w.writer.WritePacket(buffer, w.source)
}
+
+func (w *directPacketWriter) CreatePacketBatchWriter() (N.PacketBatchWriter, bool) {
+ writer, created := bufio.CreatePacketBatchWriter(w.writer)
+ if !created {
+ return nil, false
+ }
+ return &directPacketBatchWriter{
+ writer: writer,
+ source: w.source,
+ }, true
+}
+
+type directPacketBatchWriter struct {
+ writer N.PacketBatchWriter
+ source M.Socksaddr
+}
+
+func (w *directPacketBatchWriter) WritePacketBatch(buffers []*buf.Buffer, destinations []M.Socksaddr) error {
+ if len(buffers) == 0 || len(buffers) != len(destinations) {
+ buf.ReleaseMulti(buffers)
+ return os.ErrInvalid
+ }
+ sources := make([]M.Socksaddr, len(destinations))
+ for index := range sources {
+ sources[index] = w.source
+ }
+ return w.writer.WritePacketBatch(buffers, sources)
+}
diff --git a/protocol/dns/outbound.go b/protocol/dns/outbound.go
index 277d7454ea..747d578ea7 100644
--- a/protocol/dns/outbound.go
+++ b/protocol/dns/outbound.go
@@ -43,7 +43,7 @@ func (d *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
return nil, os.ErrInvalid
}
-func (d *Outbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (d *Outbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
metadata.Destination = M.Socksaddr{}
for {
conn.SetReadDeadline(time.Now().Add(C.DNSTimeout))
@@ -58,6 +58,6 @@ func (d *Outbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata
}
}
-func (d *Outbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (d *Outbound) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
NewDNSPacketConnection(ctx, d.router, conn, nil, metadata)
}
diff --git a/protocol/firebasetunnel/common.go b/protocol/firebasetunnel/common.go
new file mode 100644
index 0000000000..0168de27ee
--- /dev/null
+++ b/protocol/firebasetunnel/common.go
@@ -0,0 +1,88 @@
+package firebasetunnel
+
+import (
+ "context"
+ "net"
+ "time"
+
+ "github.com/sagernet/sing/common/logger"
+)
+
+// Timing / capacity defaults.
+const (
+ defaultBatchInterval = 50 * time.Millisecond
+ defaultBatchMaxBytes = 32 * 1024
+ defaultRetryLimit = 5
+ defaultActivationTimeout = 30 * time.Second
+ defaultS2CPollInterval = 150 * time.Millisecond
+ defaultReadBufSize = 32 * 1024
+ warnActivationAfter = 3 * time.Second
+
+ defaultPollInterval = 200 * time.Millisecond
+ defaultSessionTimeout = 300 * time.Second
+ defaultMaxSessions = 1000
+ defaultMaxSessionsPerUser = 50
+ defaultMaxSessionsPerSecondPerUser = 5
+ drainTimeout = 5 * time.Second
+)
+
+// userConfig holds per-user server-side settings derived from options at
+// construction time.
+type userConfig struct {
+ name string
+ key *[32]byte // nil → no PSK, HMAC-only integrity
+}
+
+// isTerminal reports whether s is a state that signals the session is ending.
+func isTerminal(s sessionState) bool {
+ return s == sessionStateClosing || s == sessionStateClosed
+}
+
+// drainInto reads all buffered data from ch and writes it to conn.
+func drainInto(ch <-chan []byte, conn net.Conn) error {
+ for {
+ select {
+ case data := <-ch:
+ if _, err := conn.Write(data); err != nil {
+ return err
+ }
+ default:
+ return nil
+ }
+ }
+}
+
+// copyToSender reads from conn in a loop and feeds each chunk to sender.
+func copyToSender(ctx context.Context, conn net.Conn, sender *chunkSender, lg logger.ContextLogger) {
+ buf := make([]byte, defaultReadBufSize)
+ for {
+ n, err := conn.Read(buf)
+ if n > 0 {
+ if feedErr := sender.feed(ctx, buf[:n]); feedErr != nil {
+ if lg != nil {
+ lg.WarnContext(ctx, "firebasetunnel: sender feed error: ", feedErr)
+ }
+ return
+ }
+ }
+ if err != nil {
+ return
+ }
+ }
+}
+
+// durationOr returns d if d > 0, otherwise fallback.
+func durationOr(d, fallback time.Duration) time.Duration {
+ if d > 0 {
+ return d
+ }
+ return fallback
+}
+
+// intOr returns v if v > 0, otherwise fallback.
+func intOr(v, fallback int) int {
+ if v > 0 {
+ return v
+ }
+ return fallback
+}
diff --git a/protocol/firebasetunnel/compress.go b/protocol/firebasetunnel/compress.go
new file mode 100644
index 0000000000..932bb10e41
--- /dev/null
+++ b/protocol/firebasetunnel/compress.go
@@ -0,0 +1,51 @@
+package firebasetunnel
+
+import (
+ "fmt"
+ "sync"
+
+ "github.com/klauspost/compress/zstd"
+)
+
+const compressionLevel = 3
+
+var (
+ zstdOnce sync.Once
+ zstdEncoder *zstd.Encoder
+ zstdDecoder *zstd.Decoder
+ zstdInitErr error
+)
+
+func initZstd() error {
+ zstdOnce.Do(func() {
+ var err error
+ zstdEncoder, err = zstd.NewWriter(nil, zstd.WithEncoderLevel(zstd.EncoderLevel(compressionLevel)))
+ if err != nil {
+ zstdInitErr = fmt.Errorf("firebasetunnel: zstd encoder init: %w", err)
+ return
+ }
+ zstdDecoder, err = zstd.NewReader(nil)
+ if err != nil {
+ zstdInitErr = fmt.Errorf("firebasetunnel: zstd decoder init: %w", err)
+ }
+ })
+ return zstdInitErr
+}
+
+func compressBytes(data []byte) []byte {
+ if err := initZstd(); err != nil {
+ return data
+ }
+ return zstdEncoder.EncodeAll(data, make([]byte, 0, len(data)))
+}
+
+func decompressBytes(data []byte) ([]byte, error) {
+ if err := initZstd(); err != nil {
+ return nil, err
+ }
+ out, err := zstdDecoder.DecodeAll(data, make([]byte, 0, len(data)*3))
+ if err != nil {
+ return nil, fmt.Errorf("firebasetunnel: zstd decompress: %w", err)
+ }
+ return out, nil
+}
diff --git a/protocol/firebasetunnel/compress_test.go b/protocol/firebasetunnel/compress_test.go
new file mode 100644
index 0000000000..8123674e51
--- /dev/null
+++ b/protocol/firebasetunnel/compress_test.go
@@ -0,0 +1,32 @@
+package firebasetunnel
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestCompressRoundTrip(t *testing.T) {
+ cases := [][]byte{
+ []byte(""),
+ []byte("hello world"),
+ bytes.Repeat([]byte("a"), 100000),
+ []byte{0x00, 0xff, 0x10, 0x20},
+ }
+ for _, data := range cases {
+ compressed := compressBytes(data)
+ out, err := decompressBytes(compressed)
+ if err != nil {
+ t.Fatalf("decompress: %v", err)
+ }
+ if !bytes.Equal(out, data) {
+ t.Fatalf("round trip mismatch: got %d bytes, want %d", len(out), len(data))
+ }
+ }
+}
+
+func TestDecompressInvalid(t *testing.T) {
+ _, err := decompressBytes([]byte("not zstd data"))
+ if err == nil {
+ t.Fatal("expected error decompressing invalid data")
+ }
+}
diff --git a/protocol/firebasetunnel/crypto.go b/protocol/firebasetunnel/crypto.go
new file mode 100644
index 0000000000..a44e5c2973
--- /dev/null
+++ b/protocol/firebasetunnel/crypto.go
@@ -0,0 +1,122 @@
+package firebasetunnel
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/rand"
+ "crypto/sha256"
+ "encoding/binary"
+ "fmt"
+ "io"
+)
+
+const hmacTagLen = 16
+
+// deriveKey turns an arbitrary-length PSK string into a 32-byte AES-256 key.
+// This is a simple SHA-256 KDF, sufficient for a pre-shared-secret use case
+// (not a password — operators are expected to provide a high-entropy PSK).
+func deriveKey(psk string) [32]byte {
+ return sha256.Sum256([]byte(psk))
+}
+
+// deriveHMACKey derives a 32-byte HMAC key from the raw Firebase secret.
+// Used for integrity verification on the unencrypted (no-PSK) path.
+func deriveHMACKey(secret string) []byte {
+ h := sha256.Sum256(append([]byte("hmac:"), []byte(secret)...))
+ return h[:]
+}
+
+// hmacTag returns a hmacTagLen-byte HMAC-SHA256 tag over payload, keyed by secretKey.
+func hmacTag(secretKey []byte, payload []byte) []byte {
+ mac := hmac.New(sha256.New, secretKey)
+ mac.Write(payload)
+ return mac.Sum(nil)[:hmacTagLen]
+}
+
+// appendHMACTag appends a hmacTagLen-byte HMAC tag to payload and returns
+// the combined slice (no allocation if capacity permits).
+func appendHMACTag(secretKey []byte, payload []byte) []byte {
+ tag := hmacTag(secretKey, payload)
+ return append(payload, tag...)
+}
+
+// verifyAndStripHMACTag verifies the hmacTagLen-byte tag appended to data
+// and returns the payload without the tag. Returns an error on mismatch —
+// treat as integrity failure / potential abuse signal.
+func verifyAndStripHMACTag(secretKey []byte, data []byte) ([]byte, error) {
+ if len(data) < hmacTagLen {
+ return nil, fmt.Errorf("firebasetunnel: HMAC tag missing (data too short)")
+ }
+ payload := data[:len(data)-hmacTagLen]
+ got := data[len(data)-hmacTagLen:]
+ expected := hmacTag(secretKey, payload)
+ if !hmac.Equal(got, expected) {
+ return nil, fmt.Errorf("firebasetunnel: HMAC verification failed — data integrity compromised")
+ }
+ return payload, nil
+}
+
+// encryptPayloadAAD encrypts data with AES-256-GCM under key, binding aad as
+// additional authenticated data. Nonce is prepended to the ciphertext.
+// If aad is nil, no additional data is bound (same as old encryptPayload).
+func encryptPayloadAAD(key [32]byte, data []byte, aad []byte) ([]byte, error) {
+ block, err := aes.NewCipher(key[:])
+ if err != nil {
+ return nil, err
+ }
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, err
+ }
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
+ return nil, err
+ }
+ return gcm.Seal(nonce, nonce, data, aad), nil
+}
+
+// decryptPayloadAAD reverses encryptPayloadAAD. aad must match what was
+// passed to encryptPayloadAAD exactly; mismatch causes an auth error.
+func decryptPayloadAAD(key [32]byte, data []byte, aad []byte) ([]byte, error) {
+ block, err := aes.NewCipher(key[:])
+ if err != nil {
+ return nil, err
+ }
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, err
+ }
+ if len(data) < gcm.NonceSize() {
+ return nil, fmt.Errorf("firebasetunnel: ciphertext too short")
+ }
+ nonce, ciphertext := data[:gcm.NonceSize()], data[gcm.NonceSize():]
+ return gcm.Open(nil, nonce, ciphertext, aad)
+}
+
+// encryptPayload encrypts with no additional authenticated data.
+// Kept for backward compatibility with existing tests.
+func encryptPayload(key [32]byte, data []byte) ([]byte, error) {
+ return encryptPayloadAAD(key, data, nil)
+}
+
+// decryptPayload decrypts with no additional authenticated data.
+// Kept for backward compatibility with existing tests.
+func decryptPayload(key [32]byte, data []byte) ([]byte, error) {
+ return decryptPayloadAAD(key, data, nil)
+}
+
+// chunkAAD builds the AEAD additional data for a chunk: encodes sessionID,
+// direction ("c2s"/"s2c"), and seq into a compact binary blob so that a chunk
+// from one session/direction/position cannot be replayed into another.
+func chunkAAD(sessionID, direction string, seq uint64) []byte {
+ seqBuf := make([]byte, 8)
+ binary.LittleEndian.PutUint64(seqBuf, seq)
+ aad := make([]byte, 0, len(sessionID)+1+len(direction)+1+8)
+ aad = append(aad, []byte(sessionID)...)
+ aad = append(aad, '/')
+ aad = append(aad, []byte(direction)...)
+ aad = append(aad, '/')
+ aad = append(aad, seqBuf...)
+ return aad
+}
diff --git a/protocol/firebasetunnel/crypto_test.go b/protocol/firebasetunnel/crypto_test.go
new file mode 100644
index 0000000000..547e77e2b1
--- /dev/null
+++ b/protocol/firebasetunnel/crypto_test.go
@@ -0,0 +1,58 @@
+package firebasetunnel
+
+import (
+ "bytes"
+ "testing"
+)
+
+func TestEncryptDecryptRoundTrip(t *testing.T) {
+ key := deriveKey("test-psk")
+ data := []byte("secret payload bytes")
+
+ ct, err := encryptPayload(key, data)
+ if err != nil {
+ t.Fatalf("encrypt: %v", err)
+ }
+ if bytes.Equal(ct, data) {
+ t.Fatal("ciphertext must not equal plaintext")
+ }
+
+ pt, err := decryptPayload(key, ct)
+ if err != nil {
+ t.Fatalf("decrypt: %v", err)
+ }
+ if !bytes.Equal(pt, data) {
+ t.Fatalf("decrypted mismatch: got %q want %q", pt, data)
+ }
+}
+
+func TestDecryptWrongKeyFails(t *testing.T) {
+ key := deriveKey("psk-a")
+ wrongKey := deriveKey("psk-b")
+ ct, err := encryptPayload(key, []byte("data"))
+ if err != nil {
+ t.Fatalf("encrypt: %v", err)
+ }
+ if _, err := decryptPayload(wrongKey, ct); err == nil {
+ t.Fatal("expected decrypt failure with wrong key")
+ }
+}
+
+func TestDecryptTruncatedFails(t *testing.T) {
+ key := deriveKey("psk")
+ if _, err := decryptPayload(key, []byte("x")); err == nil {
+ t.Fatal("expected error for truncated ciphertext")
+ }
+}
+
+func TestDeriveKeyDeterministic(t *testing.T) {
+ a := deriveKey("same-psk")
+ b := deriveKey("same-psk")
+ if a != b {
+ t.Fatal("deriveKey must be deterministic for the same input")
+ }
+ c := deriveKey("different-psk")
+ if a == c {
+ t.Fatal("deriveKey must differ for different input")
+ }
+}
diff --git a/protocol/firebasetunnel/endpoint_test.go b/protocol/firebasetunnel/endpoint_test.go
new file mode 100644
index 0000000000..e085b082b2
--- /dev/null
+++ b/protocol/firebasetunnel/endpoint_test.go
@@ -0,0 +1,150 @@
+package firebasetunnel
+
+import (
+ "context"
+ "io"
+ "net"
+ "testing"
+ "time"
+)
+
+// TestRelayRoundTrip exercises the full chunk relay pipeline end-to-end.
+// It uses the relay (server) and session (client) helpers directly against
+// the fakeFirebaseServer with SSE support.
+func TestRelayRoundTrip(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+
+ fb := newFirebaseClient(srv.URL, "relay-secret", "", 0, nil)
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ sessionID := "e2e-relay-test"
+ hmacKey := deriveHMACKey("relay-secret")
+
+ // server side: local↔remote pipe; inbound runRelay on remote end
+ serverLocal, serverRemote := net.Pipe()
+
+ inb := &Inbound{
+ fb: fb,
+ pollInterval: 20 * time.Millisecond,
+ sessionTimeout: 10 * time.Second,
+ }
+
+ serverDone := make(chan struct{})
+ go func() {
+ defer close(serverDone)
+ inb.runRelay(ctx, sessionID, serverRemote, nil, hmacKey)
+ }()
+
+ // client side: outbound runSession writes c2s, reads s2c
+ clientLocal, clientRemote := net.Pipe()
+
+ out := &Outbound{
+ fb: fb,
+ key: nil,
+ hmacKey: hmacKey,
+ batchInterval: 20 * time.Millisecond,
+ batchMaxBytes: defaultBatchMaxBytes,
+ }
+
+ clientDone := make(chan struct{})
+ go func() {
+ defer close(clientDone)
+ out.runSession(ctx, sessionID, clientRemote)
+ }()
+
+ // Echo goroutine on server's local end.
+ echoDone := make(chan struct{})
+ go func() {
+ defer close(echoDone)
+ io.Copy(serverLocal, serverLocal) //nolint:errcheck
+ }()
+
+ payload := []byte("hello end-to-end relay")
+
+ if _, err := clientLocal.Write(payload); err != nil {
+ t.Fatalf("client write: %v", err)
+ }
+
+ buf := make([]byte, len(payload))
+ clientLocal.SetReadDeadline(time.Now().Add(8 * time.Second))
+ n, err := io.ReadFull(clientLocal, buf)
+ if err != nil {
+ t.Fatalf("client read: %v (got %d bytes)", err, n)
+ }
+ if string(buf[:n]) != string(payload) {
+ t.Fatalf("round-trip mismatch: got %q want %q", buf[:n], payload)
+ }
+
+ clientLocal.Close()
+ serverLocal.Close()
+ <-clientDone
+ <-serverDone
+}
+
+// TestRelayEncryptedRoundTrip is the same as TestRelayRoundTrip but uses PSK encryption.
+func TestRelayEncryptedRoundTrip(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+
+ fb := newFirebaseClient(srv.URL, "relay-secret", "", 0, nil)
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
+
+ sessionID := "e2e-encrypted-relay-test"
+ psk := "e2e-psk"
+ key := deriveKey(psk)
+
+ serverLocal, serverRemote := net.Pipe()
+
+ inb := &Inbound{
+ fb: fb,
+ pollInterval: 20 * time.Millisecond,
+ sessionTimeout: 10 * time.Second,
+ }
+
+ serverDone := make(chan struct{})
+ go func() {
+ defer close(serverDone)
+ inb.runRelay(ctx, sessionID, serverRemote, &key, nil)
+ }()
+
+ clientLocal, clientRemote := net.Pipe()
+
+ out := &Outbound{
+ fb: fb,
+ key: &key,
+ hmacKey: nil,
+ batchInterval: 20 * time.Millisecond,
+ batchMaxBytes: defaultBatchMaxBytes,
+ }
+
+ clientDone := make(chan struct{})
+ go func() {
+ defer close(clientDone)
+ out.runSession(ctx, sessionID, clientRemote)
+ }()
+
+ go io.Copy(serverLocal, serverLocal) //nolint:errcheck
+
+ payload := []byte("encrypted end-to-end relay")
+ if _, err := clientLocal.Write(payload); err != nil {
+ t.Fatalf("client write: %v", err)
+ }
+
+ buf := make([]byte, len(payload))
+ clientLocal.SetReadDeadline(time.Now().Add(8 * time.Second))
+ n, err := io.ReadFull(clientLocal, buf)
+ if err != nil {
+ t.Fatalf("client read: %v (got %d bytes)", err, n)
+ }
+ if string(buf[:n]) != string(payload) {
+ t.Fatalf("round-trip mismatch: got %q want %q", buf[:n], payload)
+ }
+
+ clientLocal.Close()
+ serverLocal.Close()
+ <-clientDone
+ <-serverDone
+}
diff --git a/protocol/firebasetunnel/firebase.go b/protocol/firebasetunnel/firebase.go
new file mode 100644
index 0000000000..5599633186
--- /dev/null
+++ b/protocol/firebasetunnel/firebase.go
@@ -0,0 +1,250 @@
+package firebasetunnel
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/sagernet/sing-box/log"
+)
+
+// sseEvent is a parsed Server-Sent Event from Firebase's streaming endpoint.
+type sseEvent struct {
+ Event string
+ Data string
+}
+
+// firebaseClient is an async Firebase Realtime Database REST client.
+// Safe for concurrent use.
+//
+// Auth: if authToken is set, requests use ?access_token= (short-lived
+// Firebase Auth / service-account token, recommended). Otherwise secret is
+// used as ?auth= (legacy Database Secret: anyone holding it has
+// full read/write access to the entire Firebase project, not just this
+// tunnel's data).
+type firebaseClient struct {
+ baseURL string
+ secret string
+ authToken string
+ http *http.Client
+ retryLimit uint32
+ logger log.ContextLogger
+}
+
+func newFirebaseClient(baseURL, secret, authToken string, retryLimit uint32, logger log.ContextLogger) *firebaseClient {
+ transport := &http.Transport{
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ }
+ return &firebaseClient{
+ baseURL: strings.TrimRight(baseURL, "/"),
+ secret: secret,
+ authToken: authToken,
+ http: &http.Client{Timeout: 30 * time.Second, Transport: transport},
+ retryLimit: retryLimit,
+ logger: logger,
+ }
+}
+
+func (c *firebaseClient) authParam() string {
+ if c.authToken != "" {
+ return "access_token=" + c.authToken
+ }
+ return "auth=" + c.secret
+}
+
+func (c *firebaseClient) url(path string) string {
+ p := strings.TrimPrefix(path, "/")
+ return fmt.Sprintf("%s/%s.json?%s", c.baseURL, p, c.authParam())
+}
+
+func (c *firebaseClient) streamURL(path string) string {
+ p := strings.TrimPrefix(path, "/")
+ return fmt.Sprintf(`%s/%s.json?%s&orderBy="$key"`, c.baseURL, p, c.authParam())
+}
+
+func (c *firebaseClient) Get(ctx context.Context, path string, v interface{}) (bool, error) {
+ resp, err := c.doWithRetry(ctx, http.MethodGet, c.url(path), nil)
+ if err != nil {
+ return false, err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return false, fmt.Errorf("firebasetunnel: reading GET response from %s: %w", path, err)
+ }
+ if strings.TrimSpace(string(body)) == "null" {
+ return false, nil
+ }
+ if err := json.Unmarshal(body, v); err != nil {
+ return false, fmt.Errorf("firebasetunnel: decoding GET response from %s: %w", path, err)
+ }
+ return true, nil
+}
+
+func (c *firebaseClient) Put(ctx context.Context, path string, v interface{}) error {
+ body, err := json.Marshal(v)
+ if err != nil {
+ return fmt.Errorf("firebasetunnel: encoding PUT body for %s: %w", path, err)
+ }
+ resp, err := c.doWithRetry(ctx, http.MethodPut, c.url(path), body)
+ if err != nil {
+ return err
+ }
+ return resp.Body.Close()
+}
+
+func (c *firebaseClient) Delete(ctx context.Context, path string) error {
+ resp, err := c.doWithRetry(ctx, http.MethodDelete, c.url(path), nil)
+ if err != nil {
+ return err
+ }
+ return resp.Body.Close()
+}
+
+// doWithRetry issues an HTTP request with exponential backoff retry on
+// transient errors/status codes. Caller must close the returned response body.
+func (c *firebaseClient) doWithRetry(ctx context.Context, method, url string, body []byte) (*http.Response, error) {
+ delay := 200 * time.Millisecond
+ var lastErr error
+ for attempt := uint32(0); attempt <= c.retryLimit; attempt++ {
+ var reqBody io.Reader
+ if body != nil {
+ reqBody = bytes.NewReader(body)
+ }
+ req, err := http.NewRequestWithContext(ctx, method, url, reqBody)
+ if err != nil {
+ return nil, err
+ }
+ if body != nil {
+ req.Header.Set("Content-Type", "application/json")
+ }
+ resp, err := c.http.Do(req)
+ if err != nil {
+ lastErr = err
+ } else if resp.StatusCode >= 200 && resp.StatusCode < 300 {
+ return resp, nil
+ } else if resp.StatusCode == http.StatusNotFound && method == http.MethodDelete {
+ return resp, nil
+ } else {
+ resp.Body.Close()
+ if !shouldRetryStatus(resp.StatusCode) {
+ return nil, fmt.Errorf("firebasetunnel: %s %s failed with status %d", method, url, resp.StatusCode)
+ }
+ lastErr = fmt.Errorf("firebasetunnel: %s status %d", method, resp.StatusCode)
+ }
+ if c.logger != nil {
+ c.logger.WarnContext(ctx, "firebasetunnel: ", method, " attempt ", attempt, " failed: ", lastErr)
+ }
+ if attempt < c.retryLimit {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ case <-time.After(delay):
+ }
+ if delay < 10*time.Second {
+ delay *= 2
+ }
+ }
+ }
+ return nil, fmt.Errorf("firebasetunnel: %s %s failed after %d attempts: %w", method, url, c.retryLimit+1, lastErr)
+}
+
+func shouldRetryStatus(status int) bool {
+ switch status {
+ case http.StatusTooManyRequests, http.StatusInternalServerError, http.StatusBadGateway, http.StatusServiceUnavailable, http.StatusGatewayTimeout:
+ return true
+ }
+ return false
+}
+
+// listen opens a Server-Sent Events stream for path, reconnecting
+// automatically (with jittered backoff) on transient errors. Cancel ctx to
+// stop. Closes the returned channel only when ctx is done.
+func (c *firebaseClient) listen(ctx context.Context, path string) <-chan sseEvent {
+ ch := make(chan sseEvent, 256)
+ go c.listenLoop(ctx, path, ch)
+ return ch
+}
+
+func (c *firebaseClient) listenLoop(ctx context.Context, path string, ch chan<- sseEvent) {
+ defer close(ch)
+ u := c.streamURL(path)
+ consecutiveFailures := 0
+ for {
+ err := c.runSSELoop(ctx, u, ch)
+ if ctx.Err() != nil {
+ return
+ }
+ if err == nil {
+ consecutiveFailures = 0
+ continue
+ }
+ consecutiveFailures++
+ backoff := jitteredBackoff(consecutiveFailures)
+ if c.logger != nil {
+ c.logger.ErrorContext(ctx, "firebasetunnel: SSE stream error, reconnecting in ", backoff, ": ", err)
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(backoff):
+ }
+ }
+}
+
+func (c *firebaseClient) runSSELoop(ctx context.Context, url string, ch chan<- sseEvent) error {
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Accept", "text/event-stream")
+ req.Header.Set("Cache-Control", "no-cache")
+
+ resp, err := c.http.Do(req)
+ if err != nil {
+ return fmt.Errorf("firebasetunnel: SSE connect: %w", err)
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode < 200 || resp.StatusCode >= 300 {
+ return fmt.Errorf("firebasetunnel: SSE connect failed with status %d", resp.StatusCode)
+ }
+
+ scanner := bufio.NewScanner(resp.Body)
+ var currentEvent, currentData string
+ for scanner.Scan() {
+ line := scanner.Text()
+ switch {
+ case line == "":
+ if currentEvent != "" && currentData != "" {
+ select {
+ case ch <- sseEvent{Event: currentEvent, Data: currentData}:
+ case <-ctx.Done():
+ return nil
+ }
+ currentEvent, currentData = "", ""
+ }
+ case strings.HasPrefix(line, "event:"):
+ currentEvent = strings.TrimSpace(strings.TrimPrefix(line, "event:"))
+ case strings.HasPrefix(line, "data:"):
+ currentData = strings.TrimSpace(strings.TrimPrefix(line, "data:"))
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ if ctx.Err() != nil {
+ return nil
+ }
+ return fmt.Errorf("firebasetunnel: SSE read: %w", err)
+ }
+ if ctx.Err() != nil {
+ return nil
+ }
+ return fmt.Errorf("firebasetunnel: SSE stream ended unexpectedly")
+}
diff --git a/protocol/firebasetunnel/fuzz_test.go b/protocol/firebasetunnel/fuzz_test.go
new file mode 100644
index 0000000000..d730f8201a
--- /dev/null
+++ b/protocol/firebasetunnel/fuzz_test.go
@@ -0,0 +1,55 @@
+package firebasetunnel
+
+import (
+ "context"
+ "encoding/json"
+ "testing"
+)
+
+func FuzzIngestChunk(f *testing.F) {
+ f.Add([]byte(`{"seq":0,"timestamp":1000,"compressed":false,"data":"aGVsbG8="}`))
+ f.Add([]byte(`{"seq":0,"timestamp":1000,"compressed":true,"encrypted":false,"data":"aGVsbG8="}`))
+ f.Add([]byte(`{"seq":0,"has_hmac":true,"data":"aGVsbG8="}`))
+ f.Add([]byte(`{}`))
+ f.Fuzz(func(t *testing.T, data []byte) {
+ var c chunk
+ if err := json.Unmarshal(data, &c); err != nil {
+ return // invalid JSON — not a bug
+ }
+ receiver, _ := newChunkReceiver(nil, nil, "fuzz-session", "c2s")
+ // Must not panic regardless of input.
+ _, _ = receiver.ingest(context.Background(), c)
+ })
+}
+
+func FuzzParseSessionMetadata(f *testing.F) {
+ f.Add([]byte(`{"session_id":"abc","version":1,"target_host":"1.2.3.4","target_port":80,"created_at":1000,"state":"pending","user":"alice"}`))
+ f.Add([]byte(`{"state":"active"}`))
+ f.Add([]byte(`{}`))
+ f.Fuzz(func(t *testing.T, data []byte) {
+ var m sessionMetadata
+ _ = json.Unmarshal(data, &m)
+ // Verify field access doesn't panic.
+ _ = m.SessionID + m.User + string(m.State)
+ _ = m.TargetPort
+ _ = m.CreatedAt
+ })
+}
+
+func FuzzDecodeChunkPayload(f *testing.F) {
+ // Seed: valid base64, empty, random-looking.
+ f.Add([]byte("aGVsbG8="), false, false, false)
+ f.Add([]byte(""), false, false, false)
+ f.Add([]byte("AAAAAAAAAAAAAAAA"), true, false, false) // looks encrypted
+ f.Fuzz(func(t *testing.T, rawData []byte, encrypted, compressed, hasHMAC bool) {
+ c := chunk{
+ Seq: 0,
+ Encrypted: encrypted,
+ Compressed: compressed,
+ HasHMAC: hasHMAC,
+ Data: string(rawData),
+ }
+ // Must not panic; errors are expected for malformed inputs.
+ _, _ = decodeChunkPayload(c, nil, nil, "fuzz-session", "c2s")
+ })
+}
diff --git a/protocol/firebasetunnel/inbound.go b/protocol/firebasetunnel/inbound.go
new file mode 100644
index 0000000000..9630478cc9
--- /dev/null
+++ b/protocol/firebasetunnel/inbound.go
@@ -0,0 +1,403 @@
+package firebasetunnel
+
+import (
+ "context"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+)
+
+func RegisterInbound(registry *inbound.Registry) {
+ inbound.Register[option.FirebaseTunnelInboundOptions](registry, C.TypeFirebaseTunnelInbound, NewInbound)
+}
+
+// Inbound discovers pending Firebase Tunnel sessions and routes each one
+// through the sing-box router. Traffic accounting is handled automatically
+// by the router once metadata.User is set.
+type Inbound struct {
+ inbound.Adapter
+ ctx context.Context
+ logger logger.ContextLogger
+ router adapter.ConnectionRouterEx
+ fb *firebaseClient
+ hmacKey []byte // integrity key when no per-user PSK; nil otherwise
+
+ users map[string]userConfig
+ pollInterval time.Duration
+ sessionTimeout time.Duration
+
+ maxSessions int
+ maxSessionsPerUser int
+ sessionRate int
+
+ mu sync.Mutex
+ activeSessions int
+ perUserActive map[string]int
+ perUserBucket map[string]*tokenBucket
+
+ closing atomic.Bool
+ cancel context.CancelFunc
+}
+
+func NewInbound(ctx context.Context, router adapter.Router, lg log.ContextLogger, tag string, options option.FirebaseTunnelInboundOptions) (adapter.Inbound, error) {
+ if len(options.FirebaseURLs) == 0 {
+ return nil, E.New("firebase_urls is required")
+ }
+ if options.FirebaseSecret == "" && options.FirebaseAuthToken == "" {
+ return nil, E.New("one of firebase_secret or firebase_auth_token is required")
+ }
+ if len(options.Users) == 0 {
+ return nil, E.New("users must have at least one entry")
+ }
+
+ retryLimit := options.RetryLimit
+ if retryLimit == 0 {
+ retryLimit = defaultRetryLimit
+ }
+
+ users := make(map[string]userConfig, len(options.Users))
+ for _, u := range options.Users {
+ if u.Name == "" {
+ return nil, E.New("user name must not be empty")
+ }
+ uc := userConfig{name: u.Name}
+ if u.PSK != "" {
+ k := deriveKey(u.PSK)
+ uc.key = &k
+ }
+ users[u.Name] = uc
+ }
+
+ h := &Inbound{
+ Adapter: inbound.NewAdapter(C.TypeFirebaseTunnelInbound, tag),
+ ctx: ctx,
+ logger: lg,
+ router: router,
+ fb: newFirebaseClient(options.FirebaseURLs[0], options.FirebaseSecret, options.FirebaseAuthToken, retryLimit, lg),
+ users: users,
+ pollInterval: durationOr(time.Duration(options.PollInterval), defaultPollInterval),
+ sessionTimeout: durationOr(time.Duration(options.SessionTimeout), defaultSessionTimeout),
+ maxSessions: intOr(options.MaxSessions, defaultMaxSessions),
+ maxSessionsPerUser: intOr(options.MaxSessionsPerUser, defaultMaxSessionsPerUser),
+ sessionRate: intOr(options.MaxSessionsPerSecondPerUser, defaultMaxSessionsPerSecondPerUser),
+ perUserActive: make(map[string]int),
+ perUserBucket: make(map[string]*tokenBucket),
+ }
+
+ if options.FirebaseSecret != "" {
+ h.hmacKey = deriveHMACKey(options.FirebaseSecret)
+ }
+
+ return h, nil
+}
+
+func (h *Inbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStatePostStart {
+ return nil
+ }
+ ctx, cancel := context.WithCancel(h.ctx)
+ h.cancel = cancel
+ go h.loopWithRestart(ctx, h.pollLoop)
+ go h.loopWithRestart(ctx, h.gcLoop)
+ return nil
+}
+
+func (h *Inbound) Close() error {
+ h.closing.Store(true)
+ deadline := time.Now().Add(drainTimeout)
+ for time.Now().Before(deadline) {
+ h.mu.Lock()
+ active := h.activeSessions
+ h.mu.Unlock()
+ if active == 0 {
+ break
+ }
+ time.Sleep(100 * time.Millisecond)
+ }
+ if h.cancel != nil {
+ h.cancel()
+ }
+ return nil
+}
+
+// loopWithRestart runs fn(ctx) and restarts it on error after a 5-second
+// backoff. Stops when ctx is cancelled.
+func (h *Inbound) loopWithRestart(ctx context.Context, fn func(context.Context) error) {
+ for {
+ if ctx.Err() != nil {
+ return
+ }
+ if err := fn(ctx); err != nil {
+ h.logger.ErrorContext(ctx, "firebasetunnel: loop exited with error, restarting: ", err)
+ }
+ if ctx.Err() != nil {
+ return
+ }
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(5 * time.Second):
+ }
+ }
+}
+
+func (h *Inbound) pollLoop(ctx context.Context) error {
+ seen := make(map[string]struct{})
+ events := h.fb.listen(ctx, pathSessionsRoot())
+ ticker := time.NewTicker(h.pollInterval)
+ defer ticker.Stop()
+
+ dispatch := func() {
+ var raw map[string]sessionMetadata
+ if found, err := h.fb.Get(ctx, pathSessionsRoot(), &raw); err != nil || !found {
+ return
+ }
+ for id, meta := range raw {
+ if meta.State != sessionStatePending {
+ continue
+ }
+ if _, ok := seen[id]; ok {
+ continue
+ }
+ seen[id] = struct{}{}
+ meta.SessionID = id
+ go h.handleSession(ctx, meta)
+ }
+ }
+
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case _, ok := <-events:
+ if !ok {
+ events = h.fb.listen(ctx, pathSessionsRoot())
+ continue
+ }
+ dispatch()
+ case <-ticker.C:
+ dispatch()
+ }
+ }
+}
+
+func (h *Inbound) handleSession(ctx context.Context, meta sessionMetadata) {
+ sessionID := meta.SessionID
+
+ userCfg, ok := h.users[meta.User]
+ if !ok {
+ h.logger.WarnContext(ctx, "firebasetunnel: rejecting session ", sessionID, ": unknown user")
+ h.closeSession(ctx, sessionID)
+ return
+ }
+ if !h.acquireSessionSlot(meta.User) {
+ h.logger.WarnContext(ctx, "firebasetunnel: rejecting session ", sessionID, ": limit/rate exceeded for user ", meta.User)
+ h.closeSession(ctx, sessionID)
+ return
+ }
+ defer h.releaseSessionSlot(meta.User)
+
+ // Collision defense: re-read to verify CreatedAt hasn't changed.
+ var current sessionMetadata
+ if found, _ := h.fb.Get(ctx, pathMetadata(sessionID), ¤t); !found || current.CreatedAt != meta.CreatedAt {
+ h.logger.WarnContext(ctx, "firebasetunnel: session collision for ", sessionID, ", rejecting")
+ h.closeSession(ctx, sessionID)
+ return
+ }
+
+ destination := M.ParseSocksaddrHostPort(meta.TargetHost, meta.TargetPort)
+ inboundMeta := adapter.InboundContext{
+ Inbound: h.Tag(),
+ InboundType: C.TypeFirebaseTunnelInbound,
+ Destination: destination,
+ User: meta.User,
+ }
+
+ updated := meta
+ updated.State = sessionStateActive
+ if err := h.fb.Put(ctx, pathMetadata(sessionID), &updated); err != nil {
+ h.logger.WarnContext(ctx, "firebasetunnel: marking session active failed: ", err)
+ return
+ }
+
+ sessionKey := userCfg.key
+ sessionHMACKey := h.hmacKey
+ if sessionKey != nil {
+ sessionHMACKey = nil // AEAD covers integrity; HMAC not needed
+ }
+
+ local, remote := net.Pipe()
+
+ relayDone := make(chan struct{})
+ go func() {
+ defer close(relayDone)
+ h.runRelay(ctx, sessionID, remote, sessionKey, sessionHMACKey)
+ }()
+
+ // sing-box router handles routing, outbound selection, and traffic
+ // accounting automatically because metadata.User is already set.
+ h.router.RouteConnectionEx(ctx, local, inboundMeta, func(error) {})
+ <-relayDone
+
+ updated.State = sessionStateClosed
+ _ = h.fb.Put(context.Background(), pathMetadata(sessionID), &updated)
+ if err := h.fb.Delete(context.Background(), "sessions/"+sessionID); err != nil {
+ h.logger.WarnContext(ctx, "firebasetunnel: session cleanup failed: ", err)
+ }
+}
+
+func (h *Inbound) closeSession(ctx context.Context, sessionID string) {
+ _ = h.fb.Put(ctx, pathMetadata(sessionID), &sessionMetadata{SessionID: sessionID, State: sessionStateClosed})
+}
+
+func (h *Inbound) runRelay(ctx context.Context, sessionID string, conn net.Conn, key *[32]byte, hmacKey []byte) {
+ defer conn.Close()
+
+ relayCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ c2sDone := make(chan struct{})
+ go func() {
+ defer close(c2sDone)
+ h.runC2S(relayCtx, sessionID, conn, key, hmacKey)
+ }()
+
+ s2cDone := make(chan struct{})
+ go func() {
+ defer close(s2cDone)
+ sender := newChunkSender(relayCtx, pathS2C(sessionID), sessionID, "s2c",
+ h.fb, h.pollInterval, defaultReadBufSize, key, hmacKey, h.logger)
+ copyToSender(relayCtx, conn, sender, h.logger)
+ }()
+
+ select {
+ case <-c2sDone:
+ case <-s2cDone:
+ }
+ cancel()
+}
+
+func (h *Inbound) runC2S(ctx context.Context, sessionID string, conn net.Conn, key *[32]byte, hmacKey []byte) {
+ receiver, byteRx := newChunkReceiver(key, hmacKey, sessionID, "c2s")
+ var deliveredUpTo *uint64
+ c2sPath := pathC2S(sessionID)
+ ackPath := pathAcks(sessionID) + "/c2s_ack"
+ lastActivity := time.Now()
+
+ for {
+ if time.Since(lastActivity) > h.sessionTimeout {
+ h.logger.WarnContext(ctx, "firebasetunnel: session ", sessionID, " timed out")
+ return
+ }
+
+ var meta sessionMetadata
+ if found, err := h.fb.Get(ctx, pathMetadata(sessionID), &meta); err == nil && found && isTerminal(meta.State) {
+ return
+ }
+
+ chunks, err := fetchNewChunks(ctx, h.fb, c2sPath, deliveredUpTo)
+ if err != nil {
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(h.pollInterval):
+ continue
+ }
+ }
+ if len(chunks) > 0 {
+ lastActivity = time.Now()
+ }
+
+ for _, ck := range chunks {
+ newAck, err := receiver.ingest(ctx, ck)
+ if err != nil {
+ h.logger.WarnContext(ctx, "firebasetunnel: c2s ingest error (session ", sessionID, "): ", err)
+ return
+ }
+ if newAck == nil {
+ continue
+ }
+ deliveredUpTo = newAck
+ if err := drainInto(byteRx, conn); err != nil {
+ return
+ }
+ if err := updateAckAndCleanup(ctx, h.fb, ackPath, c2sPath, *newAck, h.logger); err != nil {
+ h.logger.WarnContext(ctx, "firebasetunnel: ack update failed: ", err)
+ }
+ }
+
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(h.pollInterval):
+ }
+ }
+}
+
+func (h *Inbound) gcLoop(ctx context.Context) error {
+ ticker := time.NewTicker(h.sessionTimeout / 2)
+ defer ticker.Stop()
+ const closedGrace = 10 * time.Second
+
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-ticker.C:
+ var raw map[string]sessionMetadata
+ if found, err := h.fb.Get(ctx, pathSessionsRoot(), &raw); err != nil || !found {
+ continue
+ }
+ now := nowMillis()
+ for id, meta := range raw {
+ age := time.Duration(now-meta.CreatedAt) * time.Millisecond
+ stale := (meta.State == sessionStatePending && age > h.sessionTimeout) ||
+ (isTerminal(meta.State) && age > h.sessionTimeout+closedGrace)
+ if stale {
+ if err := h.fb.Delete(ctx, "sessions/"+id); err != nil {
+ h.logger.WarnContext(ctx, "firebasetunnel: gc delete failed for ", id, ": ", err)
+ }
+ }
+ }
+ }
+ }
+}
+
+func (h *Inbound) acquireSessionSlot(user string) bool {
+ if h.closing.Load() {
+ return false
+ }
+ h.mu.Lock()
+ defer h.mu.Unlock()
+
+ bucket, ok := h.perUserBucket[user]
+ if !ok {
+ bucket = newTokenBucket(h.sessionRate, h.sessionRate)
+ h.perUserBucket[user] = bucket
+ }
+ if !bucket.take() || h.activeSessions >= h.maxSessions || h.perUserActive[user] >= h.maxSessionsPerUser {
+ return false
+ }
+ h.activeSessions++
+ h.perUserActive[user]++
+ return true
+}
+
+func (h *Inbound) releaseSessionSlot(user string) {
+ h.mu.Lock()
+ defer h.mu.Unlock()
+ h.activeSessions--
+ if h.perUserActive[user]--; h.perUserActive[user] == 0 {
+ delete(h.perUserActive, user)
+ }
+}
diff --git a/protocol/firebasetunnel/outbound.go b/protocol/firebasetunnel/outbound.go
new file mode 100644
index 0000000000..04b730ab0b
--- /dev/null
+++ b/protocol/firebasetunnel/outbound.go
@@ -0,0 +1,248 @@
+package firebasetunnel
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "os"
+ "time"
+
+ "github.com/google/uuid"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.FirebaseTunnelOutboundOptions](registry, C.TypeFirebaseTunnelOutbound, NewOutbound)
+}
+
+// Outbound dials through Firebase Realtime Database as a transport. It writes a
+// session request to Firebase and waits for the server to activate it, then
+// relays data through the session's chunk queues.
+type Outbound struct {
+ outbound.Adapter
+ ctx context.Context
+ logger logger.ContextLogger
+ fb *firebaseClient
+ key *[32]byte // nil → HMAC-only
+ hmacKey []byte
+ user string
+ batchInterval time.Duration
+ batchMaxBytes int
+ activationTimeout time.Duration
+}
+
+func NewOutbound(ctx context.Context, _ adapter.Router, lg log.ContextLogger, tag string, options option.FirebaseTunnelOutboundOptions) (adapter.Outbound, error) {
+ if len(options.FirebaseURLs) == 0 {
+ return nil, E.New("firebase_urls is required")
+ }
+ if options.FirebaseSecret == "" && options.FirebaseAuthToken == "" {
+ return nil, E.New("one of firebase_secret or firebase_auth_token is required")
+ }
+ if options.User == "" {
+ return nil, E.New("user is required")
+ }
+
+ retryLimit := options.RetryLimit
+ if retryLimit == 0 {
+ retryLimit = defaultRetryLimit
+ }
+
+ o := &Outbound{
+ Adapter: outbound.NewAdapter(C.TypeFirebaseTunnelOutbound, tag, []string{N.NetworkTCP}, nil),
+ ctx: ctx,
+ logger: lg,
+ fb: newFirebaseClient(options.FirebaseURLs[0], options.FirebaseSecret, options.FirebaseAuthToken, retryLimit, lg),
+ user: options.User,
+ batchInterval: durationOr(time.Duration(options.BatchInterval), defaultBatchInterval),
+ batchMaxBytes: intOr(options.BatchMaxBytes, defaultBatchMaxBytes),
+ activationTimeout: durationOr(time.Duration(options.ActivationTimeout), defaultActivationTimeout),
+ }
+
+ if options.PSK != "" {
+ k := deriveKey(options.PSK)
+ o.key = &k
+ } else if options.FirebaseSecret != "" {
+ o.hmacKey = deriveHMACKey(options.FirebaseSecret)
+ }
+
+ return o, nil
+}
+
+func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if network != N.NetworkTCP {
+ return nil, os.ErrInvalid
+ }
+
+ sessionID := uuid.New().String()
+ meta := sessionMetadata{
+ SessionID: sessionID,
+ Version: protocolVersion,
+ TargetHost: destination.AddrString(),
+ TargetPort: destination.Port,
+ CreatedAt: nowMillis(),
+ State: sessionStatePending,
+ User: o.user,
+ }
+ if err := o.fb.Put(ctx, pathMetadata(sessionID), &meta); err != nil {
+ return nil, fmt.Errorf("firebasetunnel: creating session: %w", err)
+ }
+
+ activateCtx, cancel := context.WithTimeout(ctx, o.activationTimeout)
+ defer cancel()
+ if err := o.waitForActive(activateCtx, sessionID); err != nil {
+ return nil, fmt.Errorf("firebasetunnel: session activation: %w", err)
+ }
+
+ local, remote := net.Pipe()
+ go o.runSession(ctx, sessionID, remote)
+ return local, nil
+}
+
+func (o *Outbound) ListenPacket(_ context.Context, _ M.Socksaddr) (net.PacketConn, error) {
+ return nil, os.ErrInvalid
+}
+
+func (o *Outbound) waitForActive(ctx context.Context, sessionID string) error {
+ path := pathMetadata(sessionID)
+ start := time.Now()
+ warned := false
+ consecutiveErrors := 0
+
+ for {
+ var meta sessionMetadata
+ found, err := o.fb.Get(ctx, path, &meta)
+ if err != nil {
+ consecutiveErrors++
+ o.logger.WarnContext(ctx, "firebasetunnel: poll error waiting for session ", sessionID, " to activate: ", err)
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(jitteredBackoff(consecutiveErrors)):
+ continue
+ }
+ }
+ consecutiveErrors = 0
+
+ if found {
+ switch meta.State {
+ case sessionStateActive:
+ return nil
+ case sessionStateClosed:
+ return E.New("server rejected session")
+ }
+ }
+
+ if !warned && time.Since(start) > warnActivationAfter {
+ warned = true
+ o.logger.WarnContext(ctx, "firebasetunnel: session ", sessionID, " still pending after ",
+ time.Since(start).Round(time.Second), " — server may be absent or overloaded")
+ }
+
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-time.After(250 * time.Millisecond):
+ }
+ }
+}
+
+func (o *Outbound) runSession(ctx context.Context, sessionID string, conn net.Conn) {
+ defer conn.Close()
+
+ sender := newChunkSender(ctx, pathC2S(sessionID), sessionID, "c2s",
+ o.fb, o.batchInterval, o.batchMaxBytes, o.key, o.hmacKey, o.logger)
+
+ relayCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ c2sDone := make(chan struct{})
+ go func() {
+ defer close(c2sDone)
+ copyToSender(relayCtx, conn, sender, o.logger)
+ _ = o.setSessionState(context.Background(), sessionID, sessionStateClosing)
+ }()
+
+ s2cDone := make(chan struct{})
+ go func() {
+ defer close(s2cDone)
+ o.runS2C(relayCtx, sessionID, conn)
+ }()
+
+ select {
+ case <-c2sDone:
+ case <-s2cDone:
+ }
+ cancel()
+
+ _ = o.setSessionState(context.Background(), sessionID, sessionStateClosed)
+ if err := o.fb.Delete(context.Background(), "sessions/"+sessionID); err != nil {
+ o.logger.WarnContext(ctx, "firebasetunnel: session cleanup failed: ", err)
+ }
+}
+
+func (o *Outbound) runS2C(ctx context.Context, sessionID string, conn net.Conn) {
+ receiver, byteRx := newChunkReceiver(o.key, o.hmacKey, sessionID, "s2c")
+ var deliveredUpTo *uint64
+ s2cPath := pathS2C(sessionID)
+ ackPath := pathAcks(sessionID) + "/s2c_ack"
+
+ for {
+ var meta sessionMetadata
+ if found, err := o.fb.Get(ctx, pathMetadata(sessionID), &meta); err == nil && found && isTerminal(meta.State) {
+ return
+ }
+
+ chunks, err := fetchNewChunks(ctx, o.fb, s2cPath, deliveredUpTo)
+ if err != nil {
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(defaultS2CPollInterval):
+ continue
+ }
+ }
+
+ for _, ck := range chunks {
+ newAck, err := receiver.ingest(ctx, ck)
+ if err != nil {
+ o.logger.WarnContext(ctx, "firebasetunnel: s2c ingest error: ", err)
+ return
+ }
+ if newAck == nil {
+ continue
+ }
+ deliveredUpTo = newAck
+ if err := drainInto(byteRx, conn); err != nil {
+ return
+ }
+ if err := updateAckAndCleanup(ctx, o.fb, ackPath, s2cPath, *newAck, o.logger); err != nil {
+ o.logger.WarnContext(ctx, "firebasetunnel: ack update failed: ", err)
+ }
+ }
+
+ select {
+ case <-ctx.Done():
+ return
+ case <-time.After(defaultS2CPollInterval):
+ }
+ }
+}
+
+func (o *Outbound) setSessionState(ctx context.Context, sessionID string, state sessionState) error {
+ path := pathMetadata(sessionID)
+ var meta sessionMetadata
+ found, err := o.fb.Get(ctx, path, &meta)
+ if err != nil || !found {
+ return err
+ }
+ meta.State = state
+ return o.fb.Put(ctx, path, &meta)
+}
diff --git a/protocol/firebasetunnel/protocol.go b/protocol/firebasetunnel/protocol.go
new file mode 100644
index 0000000000..7a71ce5174
--- /dev/null
+++ b/protocol/firebasetunnel/protocol.go
@@ -0,0 +1,97 @@
+// Package firebasetunnel implements a sing-box endpoint pair that relays
+// TCP byte streams through Firebase Realtime Database, adapted from
+// github.com/Hiddify2/Firebase-Tunnel (a single-star proof-of-concept with
+// no LICENSE; logic below is rewritten for sing-box rather than vendored).
+//
+// Database layout, keyed by an opaque per-session UUID:
+//
+// sessions/
+// {session_id}/
+// metadata/ - sessionMetadata (written by client on creation)
+// c2s/{seq}/ - chunk, client-to-server queue
+// s2c/{seq}/ - chunk, server-to-client queue
+// acks/
+// c2s_ack - uint64, highest consecutive seq the server processed
+// s2c_ack - uint64, highest consecutive seq the client processed
+//
+// Sequence numbers start at 0 and increase monotonically per direction per
+// session. Out-of-order chunks are buffered and only delivered once all
+// predecessors have arrived. Acknowledged chunks are deleted to bound
+// database growth.
+package firebasetunnel
+
+import (
+ "fmt"
+ "time"
+)
+
+const protocolVersion = 1
+
+type sessionState string
+
+const (
+ sessionStatePending sessionState = "pending"
+ sessionStateActive sessionState = "active"
+ sessionStateClosing sessionState = "closing"
+ sessionStateClosed sessionState = "closed"
+)
+
+// sessionMetadata is written by the client when a session is created. The
+// server reads it to know where to connect and which configured user the
+// session should be attributed to.
+type sessionMetadata struct {
+ SessionID string `json:"session_id"`
+ Version int `json:"version"`
+ TargetHost string `json:"target_host"`
+ TargetPort uint16 `json:"target_port"`
+ CreatedAt uint64 `json:"created_at"`
+ State sessionState `json:"state"`
+ // User is a self-reported accounting label, verified against the
+ // session's PSK (if configured) rather than trusted outright.
+ User string `json:"user,omitempty"`
+}
+
+// chunk is a single batched, optionally compressed, base64-encoded segment
+// of relayed bytes stored at sessions/{id}/c2s/{seq} or sessions/{id}/s2c/{seq}.
+type chunk struct {
+ Seq uint64 `json:"seq"`
+ Timestamp uint64 `json:"timestamp"`
+ Compressed bool `json:"compressed"`
+ // Encrypted indicates Data is AES-256-GCM ciphertext (nonce-prefixed, with
+ // session-ID+direction+seq as AEAD additional data) rather than a plain
+ // zstd/raw payload. Set only when the session's user has a PSK configured.
+ Encrypted bool `json:"encrypted,omitempty"`
+ // HasHMAC indicates that the last hmacTagLen bytes of the decoded Data are
+ // an HMAC-SHA256 tag over the payload, present on unencrypted chunks when
+ // the firebase_secret is set. Provides integrity without confidentiality.
+ HasHMAC bool `json:"has_hmac,omitempty"`
+ Data string `json:"data"`
+}
+
+func pathMetadata(sessionID string) string {
+ return "sessions/" + sessionID + "/metadata"
+}
+
+func pathC2S(sessionID string) string {
+ return "sessions/" + sessionID + "/c2s"
+}
+
+func pathS2C(sessionID string) string {
+ return "sessions/" + sessionID + "/s2c"
+}
+
+func pathAcks(sessionID string) string {
+ return "sessions/" + sessionID + "/acks"
+}
+
+func pathSessionsRoot() string {
+ return "sessions"
+}
+
+func pathChunk(queuePath string, seq uint64) string {
+ return fmt.Sprintf("%s/%d", queuePath, seq)
+}
+
+func nowMillis() uint64 {
+ return uint64(time.Now().UnixMilli())
+}
diff --git a/protocol/firebasetunnel/session.go b/protocol/firebasetunnel/session.go
new file mode 100644
index 0000000000..acf3649898
--- /dev/null
+++ b/protocol/firebasetunnel/session.go
@@ -0,0 +1,378 @@
+package firebasetunnel
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/log"
+)
+
+const compressMinBytes = 64
+
+// maxPendingBytes bounds in-memory buffering in chunkSender beyond the
+// channel's slot count, so a burst of large writes can't balloon memory
+// before backpressure kicks in.
+const maxPendingBytes = 8 * 1024 * 1024
+
+// maxChunkBytes is the maximum decoded payload size for a single chunk.
+// Rejects oversized chunks from malicious/buggy clients before allocating.
+const maxChunkBytes = 1 * 1024 * 1024 // 1 MiB
+
+// chunkSender accumulates outgoing bytes, batches/compresses/optionally
+// encrypts them, and writes them to Firebase as sequential chunk nodes.
+type chunkSender struct {
+ rawCh chan []byte
+ pending chanCounter
+}
+
+type chanCounter struct {
+ mu sync.Mutex
+ bytes int
+}
+
+func (c *chanCounter) add(n int) bool {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.bytes+n > maxPendingBytes {
+ return false
+ }
+ c.bytes += n
+ return true
+}
+
+func (c *chanCounter) sub(n int) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.bytes -= n
+}
+
+// newChunkSender creates a sender that flushes to queuePath on fb.
+// sessionID and direction ("c2s"/"s2c") are bound into AEAD additional data
+// when encrypting, so chunks cannot be replayed across sessions or directions.
+// hmacKey (non-nil) enables HMAC integrity tags on unencrypted chunks.
+func newChunkSender(ctx context.Context, queuePath, sessionID, direction string, fb *firebaseClient, batchInterval time.Duration, batchMaxBytes int, key *[32]byte, hmacKey []byte, logger log.ContextLogger) *chunkSender {
+ rawCh := make(chan []byte, 1024)
+ s := &chunkSender{rawCh: rawCh}
+ go s.flusherTask(ctx, queuePath, sessionID, direction, fb, batchInterval, batchMaxBytes, key, hmacKey, logger)
+ return s
+}
+
+// feed enqueues data for the next batch. Returns an error if the pending
+// byte budget is exceeded (caller should treat this as backpressure, not
+// retry indefinitely) or if ctx is done.
+func (s *chunkSender) feed(ctx context.Context, data []byte) error {
+ if !s.pending.add(len(data)) {
+ return fmt.Errorf("firebasetunnel: sender backpressure limit exceeded")
+ }
+ cp := make([]byte, len(data))
+ copy(cp, data)
+ select {
+ case s.rawCh <- cp:
+ return nil
+ case <-ctx.Done():
+ s.pending.sub(len(data))
+ return ctx.Err()
+ }
+}
+
+func (s *chunkSender) flusherTask(ctx context.Context, queuePath, sessionID, direction string, fb *firebaseClient, batchInterval time.Duration, batchMaxBytes int, key *[32]byte, hmacKey []byte, logger log.ContextLogger) {
+ buffer := make([]byte, 0, batchMaxBytes)
+ var seq uint64
+ ticker := time.NewTicker(batchInterval)
+ defer ticker.Stop()
+
+ flush := func(flushCtx context.Context) {
+ if len(buffer) == 0 {
+ return
+ }
+ n := len(buffer)
+ if err := flushBuffer(flushCtx, queuePath, sessionID, direction, fb, &buffer, &seq, key, hmacKey); err != nil && logger != nil {
+ logger.WarnContext(flushCtx, "firebasetunnel: flush error: ", err)
+ }
+ s.pending.sub(n)
+ }
+
+ for {
+ select {
+ case <-ticker.C:
+ flush(ctx)
+ case data, ok := <-s.rawCh:
+ if !ok {
+ flush(ctx)
+ return
+ }
+ buffer = append(buffer, data...)
+ if len(buffer) >= batchMaxBytes {
+ flush(ctx)
+ }
+ case <-ctx.Done():
+ flushCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ flush(flushCtx)
+ cancel()
+ return
+ }
+ }
+}
+
+func flushBuffer(ctx context.Context, queuePath, sessionID, direction string, fb *firebaseClient, buffer *[]byte, seq *uint64, key *[32]byte, hmacKey []byte) error {
+ raw := make([]byte, len(*buffer))
+ copy(raw, *buffer)
+ *buffer = (*buffer)[:0]
+
+ var payload []byte
+ compressed := false
+ if len(raw) >= compressMinBytes {
+ payload = compressBytes(raw)
+ compressed = true
+ } else {
+ payload = raw
+ }
+
+ encrypted := false
+ hasHMAC := false
+ if key != nil {
+ aad := chunkAAD(sessionID, direction, *seq)
+ enc, err := encryptPayloadAAD(*key, payload, aad)
+ if err != nil {
+ return fmt.Errorf("firebasetunnel: encrypting chunk seq=%d: %w", *seq, err)
+ }
+ payload = enc
+ encrypted = true
+ } else if len(hmacKey) > 0 {
+ payload = appendHMACTag(hmacKey, payload)
+ hasHMAC = true
+ }
+
+ c := chunk{
+ Seq: *seq,
+ Timestamp: nowMillis(),
+ Compressed: compressed,
+ Encrypted: encrypted,
+ HasHMAC: hasHMAC,
+ Data: base64.StdEncoding.EncodeToString(payload),
+ }
+ if err := fb.Put(ctx, pathChunk(queuePath, *seq), &c); err != nil {
+ return fmt.Errorf("firebasetunnel: writing chunk seq=%d: %w", *seq, err)
+ }
+ *seq++
+ return nil
+}
+
+// chunkReceiver reassembles an in-order byte stream from chunks that may
+// arrive out of order, buffering until contiguous, then delivering on the
+// channel returned by newChunkReceiver.
+type chunkReceiver struct {
+ mu sync.Mutex
+ pending map[uint64][]byte
+ nextSeq uint64
+ outCh chan []byte
+ ackPtr *uint64
+ key *[32]byte
+ hmacKey []byte
+ sessionID string
+ direction string
+}
+
+// newChunkReceiver creates a receiver for chunks arriving on sessionID/direction.
+// hmacKey (non-nil) enables HMAC verification on unencrypted chunks.
+func newChunkReceiver(key *[32]byte, hmacKey []byte, sessionID, direction string) (*chunkReceiver, <-chan []byte) {
+ outCh := make(chan []byte, 1024)
+ r := &chunkReceiver{
+ pending: make(map[uint64][]byte),
+ outCh: outCh,
+ key: key,
+ hmacKey: hmacKey,
+ sessionID: sessionID,
+ direction: direction,
+ }
+ return r, outCh
+}
+
+// ingest processes one chunk, returning the new ack pointer if it advanced.
+// Duplicate (already-delivered) chunks are silently ignored. Decrypt/HMAC
+// failures are returned as errors — callers should treat them as an
+// auth/abuse signal, not a transient fault.
+func (r *chunkReceiver) ingest(ctx context.Context, c chunk) (*uint64, error) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ if c.Seq < r.nextSeq {
+ return nil, nil
+ }
+
+ payload, err := decodeChunkPayload(c, r.key, r.hmacKey, r.sessionID, r.direction)
+ if err != nil {
+ return nil, err
+ }
+ r.pending[c.Seq] = payload
+
+ oldAck := r.ackPtr
+ for {
+ data, ok := r.pending[r.nextSeq]
+ if !ok {
+ break
+ }
+ delete(r.pending, r.nextSeq)
+ select {
+ case r.outCh <- data:
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+ ack := r.nextSeq
+ r.ackPtr = &ack
+ r.nextSeq++
+ }
+
+ if !ackEqual(r.ackPtr, oldAck) {
+ return r.ackPtr, nil
+ }
+ return nil, nil
+}
+
+func ackEqual(a, b *uint64) bool {
+ if a == nil && b == nil {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ return *a == *b
+}
+
+func decodeChunkPayload(c chunk, key *[32]byte, hmacKey []byte, sessionID, direction string) ([]byte, error) {
+ // Reject oversized chunks before any allocation.
+ if len(c.Data) > base64.StdEncoding.EncodedLen(maxChunkBytes) {
+ return nil, fmt.Errorf("firebasetunnel: chunk seq=%d exceeds max size cap", c.Seq)
+ }
+
+ decoded, err := base64.StdEncoding.DecodeString(c.Data)
+ if err != nil {
+ return nil, fmt.Errorf("firebasetunnel: base64-decoding chunk seq=%d: %w", c.Seq, err)
+ }
+ if c.Encrypted {
+ if key == nil {
+ return nil, fmt.Errorf("firebasetunnel: chunk seq=%d is encrypted but no key configured", c.Seq)
+ }
+ aad := chunkAAD(sessionID, direction, c.Seq)
+ decoded, err = decryptPayloadAAD(*key, decoded, aad)
+ if err != nil {
+ return nil, fmt.Errorf("firebasetunnel: decrypting chunk seq=%d: %w", c.Seq, err)
+ }
+ } else if c.HasHMAC {
+ if len(hmacKey) == 0 {
+ return nil, fmt.Errorf("firebasetunnel: chunk seq=%d has HMAC tag but no HMAC key configured", c.Seq)
+ }
+ decoded, err = verifyAndStripHMACTag(hmacKey, decoded)
+ if err != nil {
+ return nil, fmt.Errorf("firebasetunnel: chunk seq=%d: %w", c.Seq, err)
+ }
+ }
+ if c.Compressed {
+ decoded, err = decompressBytes(decoded)
+ if err != nil {
+ return nil, fmt.Errorf("firebasetunnel: decompressing chunk seq=%d: %w", c.Seq, err)
+ }
+ }
+ return decoded, nil
+}
+
+// fetchNewChunks reads all chunks from queuePath with seq > after, sorted
+// by seq. Firebase collapses integer-keyed objects into JSON arrays, so
+// both shapes are handled.
+func fetchNewChunks(ctx context.Context, fb *firebaseClient, queuePath string, after *uint64) ([]chunk, error) {
+ var raw interface{}
+ found, err := fb.Get(ctx, queuePath, &raw)
+ if err != nil {
+ return nil, err
+ }
+ if !found {
+ return nil, nil
+ }
+
+ var chunks []chunk
+ switch v := raw.(type) {
+ case map[string]interface{}:
+ for _, val := range v {
+ ck, err := interfaceToChunk(val)
+ if err != nil {
+ return nil, err
+ }
+ chunks = append(chunks, ck)
+ }
+ case []interface{}:
+ for _, val := range v {
+ if val == nil {
+ continue
+ }
+ ck, err := interfaceToChunk(val)
+ if err != nil {
+ return nil, err
+ }
+ chunks = append(chunks, ck)
+ }
+ default:
+ return nil, nil
+ }
+
+ if after != nil {
+ filtered := chunks[:0]
+ for _, ck := range chunks {
+ if ck.Seq > *after {
+ filtered = append(filtered, ck)
+ }
+ }
+ chunks = filtered
+ }
+
+ sortChunksBySeq(chunks)
+ return chunks, nil
+}
+
+func interfaceToChunk(v interface{}) (chunk, error) {
+ data, err := json.Marshal(v)
+ if err != nil {
+ return chunk{}, err
+ }
+ var ck chunk
+ if err := json.Unmarshal(data, &ck); err != nil {
+ return chunk{}, err
+ }
+ return ck, nil
+}
+
+func sortChunksBySeq(chunks []chunk) {
+ n := len(chunks)
+ for i := 1; i < n; i++ {
+ key := chunks[i]
+ j := i - 1
+ for j >= 0 && chunks[j].Seq > key.Seq {
+ chunks[j+1] = chunks[j]
+ j--
+ }
+ chunks[j+1] = key
+ }
+}
+
+// updateAckAndCleanup persists the new ack pointer and deletes all chunks
+// with seq <= ack from queuePath (best-effort, parallel deletes).
+func updateAckAndCleanup(ctx context.Context, fb *firebaseClient, ackFieldPath, queuePath string, ack uint64, logger log.ContextLogger) error {
+ if err := fb.Put(ctx, ackFieldPath, ack); err != nil {
+ return fmt.Errorf("firebasetunnel: updating ack: %w", err)
+ }
+ var wg sync.WaitGroup
+ for seq := uint64(0); seq <= ack; seq++ {
+ wg.Add(1)
+ go func(seq uint64) {
+ defer wg.Done()
+ if err := fb.Delete(ctx, pathChunk(queuePath, seq)); err != nil && logger != nil {
+ logger.WarnContext(ctx, "firebasetunnel: cleanup chunk seq=", seq, " failed: ", err)
+ }
+ }(seq)
+ }
+ wg.Wait()
+ return nil
+}
diff --git a/protocol/firebasetunnel/session_test.go b/protocol/firebasetunnel/session_test.go
new file mode 100644
index 0000000000..b5f31c8cbb
--- /dev/null
+++ b/protocol/firebasetunnel/session_test.go
@@ -0,0 +1,382 @@
+package firebasetunnel
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+)
+
+// fakeFirebaseServer is a minimal in-memory stand-in for the Firebase RTDB
+// REST API, sufficient for exercising chunkSender/chunkReceiver against a
+// real *firebaseClient without network access.
+type fakeFirebaseServer struct {
+ mu sync.Mutex
+ data map[string]json.RawMessage
+ listeners []chan struct{}
+}
+
+func newFakeFirebaseServer() *httptest.Server {
+ f := &fakeFirebaseServer{data: make(map[string]json.RawMessage)}
+ return httptest.NewServer(http.HandlerFunc(f.handle))
+}
+
+func (f *fakeFirebaseServer) notifyListeners() {
+ for _, ch := range f.listeners {
+ select {
+ case ch <- struct{}{}:
+ default:
+ }
+ }
+}
+
+func (f *fakeFirebaseServer) handle(w http.ResponseWriter, r *http.Request) {
+ path := strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/"), ".json")
+
+ // SSE streaming endpoint.
+ if r.Method == http.MethodGet && r.Header.Get("Accept") == "text/event-stream" {
+ notify := make(chan struct{}, 4)
+ f.mu.Lock()
+ f.listeners = append(f.listeners, notify)
+ // Send initial state.
+ snapshot, _ := json.Marshal(f.buildSnapshot())
+ f.mu.Unlock()
+
+ w.Header().Set("Content-Type", "text/event-stream")
+ w.Header().Set("Cache-Control", "no-cache")
+ flusher, ok := w.(http.Flusher)
+ if !ok {
+ http.Error(w, "streaming not supported", http.StatusInternalServerError)
+ return
+ }
+ // Firebase SSE format.
+ _, _ = w.Write([]byte("event: put\ndata: {\"path\":\"/\",\"data\":" + string(snapshot) + "}\n\n"))
+ flusher.Flush()
+
+ for {
+ select {
+ case <-notify:
+ f.mu.Lock()
+ snap, _ := json.Marshal(f.buildSnapshot())
+ f.mu.Unlock()
+ _, _ = w.Write([]byte("event: put\ndata: {\"path\":\"/\",\"data\":" + string(snap) + "}\n\n"))
+ flusher.Flush()
+ case <-r.Context().Done():
+ f.mu.Lock()
+ listeners := f.listeners[:0]
+ for _, ch := range f.listeners {
+ if ch != notify {
+ listeners = append(listeners, ch)
+ }
+ }
+ f.listeners = listeners
+ f.mu.Unlock()
+ return
+ }
+ }
+ }
+
+ f.mu.Lock()
+ defer f.mu.Unlock()
+
+ switch r.Method {
+ case http.MethodGet:
+ if v, ok := f.data[path]; ok {
+ w.Write(v)
+ return
+ }
+ w.Write([]byte("null"))
+ case http.MethodPut:
+ body := make([]byte, r.ContentLength)
+ r.Body.Read(body)
+ f.data[path] = json.RawMessage(body)
+ f.notifyListeners()
+ w.Write([]byte("{}"))
+ case http.MethodDelete:
+ delete(f.data, path)
+ w.Write([]byte("null"))
+ default:
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ }
+}
+
+// buildSnapshot returns the top-level "sessions" map for SSE payloads.
+// Must be called with f.mu held.
+func (f *fakeFirebaseServer) buildSnapshot() map[string]json.RawMessage {
+ out := make(map[string]json.RawMessage)
+ for k, v := range f.data {
+ out[k] = v
+ }
+ return out
+}
+
+func TestChunkSenderReceiverRoundTrip(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+
+ fb := newFirebaseClient(srv.URL, "test-secret", "", 0, nil)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ sessionID := "test-session"
+ queuePath := "sessions/" + sessionID + "/c2s"
+ sender := newChunkSender(ctx, queuePath, sessionID, "c2s", fb, 20*time.Millisecond, 1024, nil, nil, nil)
+
+ payload := []byte("hello firebase tunnel")
+ if err := sender.feed(ctx, payload); err != nil {
+ t.Fatalf("feed: %v", err)
+ }
+
+ // Wait for the flusher to write the chunk.
+ time.Sleep(100 * time.Millisecond)
+
+ chunks, err := fetchNewChunks(ctx, fb, queuePath, nil)
+ if err != nil {
+ t.Fatalf("fetchNewChunks: %v", err)
+ }
+ if len(chunks) != 1 {
+ t.Fatalf("expected 1 chunk, got %d", len(chunks))
+ }
+
+ receiver, byteRx := newChunkReceiver(nil, nil, sessionID, "c2s")
+ if _, err := receiver.ingest(ctx, chunks[0]); err != nil {
+ t.Fatalf("ingest: %v", err)
+ }
+
+ select {
+ case data := <-byteRx:
+ if string(data) != string(payload) {
+ t.Fatalf("got %q want %q", data, payload)
+ }
+ case <-time.After(time.Second):
+ t.Fatal("timed out waiting for reassembled bytes")
+ }
+}
+
+func TestChunkSenderEncrypted(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+
+ fb := newFirebaseClient(srv.URL, "test-secret", "", 0, nil)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ sessionID := "test-session-2"
+ key := deriveKey("shared-psk")
+ queuePath := "sessions/" + sessionID + "/c2s"
+ sender := newChunkSender(ctx, queuePath, sessionID, "c2s", fb, 20*time.Millisecond, 1024, &key, nil, nil)
+
+ payload := []byte("encrypted payload bytes")
+ if err := sender.feed(ctx, payload); err != nil {
+ t.Fatalf("feed: %v", err)
+ }
+ time.Sleep(100 * time.Millisecond)
+
+ chunks, err := fetchNewChunks(ctx, fb, queuePath, nil)
+ if err != nil {
+ t.Fatalf("fetchNewChunks: %v", err)
+ }
+ if len(chunks) != 1 || !chunks[0].Encrypted {
+ t.Fatalf("expected 1 encrypted chunk, got %+v", chunks)
+ }
+
+ // Wrong key must fail to decrypt.
+ wrongKey := deriveKey("wrong-psk")
+ receiverWrong, _ := newChunkReceiver(&wrongKey, nil, sessionID, "c2s")
+ if _, err := receiverWrong.ingest(ctx, chunks[0]); err == nil {
+ t.Fatal("expected ingest failure with wrong key")
+ }
+
+ // Correct key must succeed.
+ receiver, byteRx := newChunkReceiver(&key, nil, sessionID, "c2s")
+ if _, err := receiver.ingest(ctx, chunks[0]); err != nil {
+ t.Fatalf("ingest with correct key: %v", err)
+ }
+ select {
+ case data := <-byteRx:
+ if string(data) != string(payload) {
+ t.Fatalf("got %q want %q", data, payload)
+ }
+ case <-time.After(time.Second):
+ t.Fatal("timed out waiting for reassembled bytes")
+ }
+}
+
+func TestChunkSenderHMAC(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+
+ fb := newFirebaseClient(srv.URL, "test-secret", "", 0, nil)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ sessionID := "test-hmac"
+ hmacKey := deriveHMACKey("test-secret")
+ queuePath := "sessions/" + sessionID + "/c2s"
+ sender := newChunkSender(ctx, queuePath, sessionID, "c2s", fb, 20*time.Millisecond, 1024, nil, hmacKey, nil)
+
+ payload := []byte("hmac protected payload")
+ if err := sender.feed(ctx, payload); err != nil {
+ t.Fatalf("feed: %v", err)
+ }
+ time.Sleep(100 * time.Millisecond)
+
+ chunks, err := fetchNewChunks(ctx, fb, queuePath, nil)
+ if err != nil {
+ t.Fatalf("fetchNewChunks: %v", err)
+ }
+ if len(chunks) != 1 || !chunks[0].HasHMAC {
+ t.Fatalf("expected 1 HMAC chunk, got %+v", chunks)
+ }
+
+ // Wrong HMAC key must fail.
+ wrongHMACKey := deriveHMACKey("wrong-secret")
+ receiverWrong, _ := newChunkReceiver(nil, wrongHMACKey, sessionID, "c2s")
+ if _, err := receiverWrong.ingest(ctx, chunks[0]); err == nil {
+ t.Fatal("expected ingest failure with wrong HMAC key")
+ }
+
+ // Correct HMAC key must succeed.
+ receiver, byteRx := newChunkReceiver(nil, hmacKey, sessionID, "c2s")
+ if _, err := receiver.ingest(ctx, chunks[0]); err != nil {
+ t.Fatalf("ingest with correct hmac key: %v", err)
+ }
+ select {
+ case data := <-byteRx:
+ if string(data) != string(payload) {
+ t.Fatalf("got %q want %q", data, payload)
+ }
+ case <-time.After(time.Second):
+ t.Fatal("timed out waiting for reassembled bytes")
+ }
+}
+
+func TestChunkAADBinding(t *testing.T) {
+ // A chunk encrypted for session A / direction c2s / seq 0 must not decrypt
+ // if the receiver uses a different sessionID, direction, or seq.
+ key := deriveKey("binding-psk")
+ sessionID := "session-a"
+ payload := []byte("aad binding test")
+
+ aad := chunkAAD(sessionID, "c2s", 0)
+ ct, err := encryptPayloadAAD(key, payload, aad)
+ if err != nil {
+ t.Fatalf("encrypt: %v", err)
+ }
+
+ // Wrong session ID.
+ wrongAAD := chunkAAD("session-b", "c2s", 0)
+ if _, err := decryptPayloadAAD(key, ct, wrongAAD); err == nil {
+ t.Fatal("expected failure with wrong sessionID in AAD")
+ }
+
+ // Wrong direction.
+ wrongDir := chunkAAD(sessionID, "s2c", 0)
+ if _, err := decryptPayloadAAD(key, ct, wrongDir); err == nil {
+ t.Fatal("expected failure with wrong direction in AAD")
+ }
+
+ // Wrong seq.
+ wrongSeq := chunkAAD(sessionID, "c2s", 1)
+ if _, err := decryptPayloadAAD(key, ct, wrongSeq); err == nil {
+ t.Fatal("expected failure with wrong seq in AAD")
+ }
+
+ // Correct AAD must succeed.
+ pt, err := decryptPayloadAAD(key, ct, aad)
+ if err != nil {
+ t.Fatalf("correct AAD failed: %v", err)
+ }
+ if string(pt) != string(payload) {
+ t.Fatalf("got %q want %q", pt, payload)
+ }
+}
+
+func TestChunkReceiverOutOfOrder(t *testing.T) {
+ ctx := context.Background()
+ receiver, byteRx := newChunkReceiver(nil, nil, "sid", "c2s")
+
+ c1 := chunk{Seq: 1, Data: encodeRaw([]byte("b"))}
+ c0 := chunk{Seq: 0, Data: encodeRaw([]byte("a"))}
+
+ // Deliver seq=1 first; nothing should drain yet.
+ if _, err := receiver.ingest(ctx, c1); err != nil {
+ t.Fatalf("ingest c1: %v", err)
+ }
+ select {
+ case data := <-byteRx:
+ t.Fatalf("unexpected early delivery: %q", data)
+ default:
+ }
+
+ // Now deliver seq=0; both should drain in order.
+ if _, err := receiver.ingest(ctx, c0); err != nil {
+ t.Fatalf("ingest c0: %v", err)
+ }
+ first := <-byteRx
+ second := <-byteRx
+ if string(first) != "a" || string(second) != "b" {
+ t.Fatalf("got %q, %q; want a, b", first, second)
+ }
+}
+
+func TestChunkReceiverDuplicateIgnored(t *testing.T) {
+ ctx := context.Background()
+ receiver, byteRx := newChunkReceiver(nil, nil, "sid", "c2s")
+
+ c0 := chunk{Seq: 0, Data: encodeRaw([]byte("a"))}
+ if _, err := receiver.ingest(ctx, c0); err != nil {
+ t.Fatalf("ingest: %v", err)
+ }
+ <-byteRx
+
+ // Re-ingesting the same seq must not deliver again.
+ if _, err := receiver.ingest(ctx, c0); err != nil {
+ t.Fatalf("ingest duplicate: %v", err)
+ }
+ select {
+ case data := <-byteRx:
+ t.Fatalf("unexpected duplicate delivery: %q", data)
+ case <-time.After(50 * time.Millisecond):
+ }
+}
+
+func TestSenderBackpressure(t *testing.T) {
+ srv := newFakeFirebaseServer()
+ defer srv.Close()
+ fb := newFirebaseClient(srv.URL, "secret", "", 0, nil)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ // Long batch interval so nothing flushes during the test.
+ sender := newChunkSender(ctx, "sessions/x/c2s", "x", "c2s", fb, time.Hour, 1<<30, nil, nil, nil)
+
+ big := make([]byte, maxPendingBytes)
+ if err := sender.feed(ctx, big); err != nil {
+ t.Fatalf("first feed should succeed: %v", err)
+ }
+ if err := sender.feed(ctx, []byte("more")); err == nil {
+ t.Fatal("expected backpressure error once pending budget exceeded")
+ }
+}
+
+func TestChunkSizeCapRejected(t *testing.T) {
+ ctx := context.Background()
+ receiver, _ := newChunkReceiver(nil, nil, "sid", "c2s")
+
+ // Craft a chunk whose Data field exceeds the encoded size cap.
+ oversized := make([]byte, maxChunkBytes+1)
+ c := chunk{Seq: 0, Data: base64.StdEncoding.EncodeToString(oversized)}
+ if _, err := receiver.ingest(ctx, c); err == nil {
+ t.Fatal("expected error for oversized chunk")
+ }
+}
+
+func encodeRaw(data []byte) string {
+ return base64.StdEncoding.EncodeToString(data)
+}
diff --git a/protocol/firebasetunnel/util.go b/protocol/firebasetunnel/util.go
new file mode 100644
index 0000000000..9642655152
--- /dev/null
+++ b/protocol/firebasetunnel/util.go
@@ -0,0 +1,63 @@
+package firebasetunnel
+
+import (
+ "math/rand"
+ "sync"
+ "time"
+)
+
+// jitteredBackoff returns an exponential backoff duration (capped at 30s)
+// with +/-20% jitter, to avoid thundering-herd reconnects when many
+// sessions/instances share one Firebase project.
+func jitteredBackoff(attempt int) time.Duration {
+ base := 2 * time.Second
+ max := 30 * time.Second
+ d := base << uint(min(attempt-1, 4))
+ if d > max || d <= 0 {
+ d = max
+ }
+ jitter := time.Duration(rand.Int63n(int64(d) / 5)) // up to 20%
+ return d - jitter/2 + time.Duration(rand.Int63n(int64(jitter)+1))
+}
+
+// tokenBucket is a simple per-second refill rate limiter used to bound
+// session-creation rate per user.
+type tokenBucket struct {
+ mu sync.Mutex
+ tokens float64
+ maxTokens float64
+ refillRate float64 // tokens per second
+ last time.Time
+}
+
+func newTokenBucket(ratePerSecond, burst int) *tokenBucket {
+ if ratePerSecond <= 0 {
+ ratePerSecond = 1
+ }
+ if burst <= 0 {
+ burst = ratePerSecond
+ }
+ return &tokenBucket{
+ tokens: float64(burst),
+ maxTokens: float64(burst),
+ refillRate: float64(ratePerSecond),
+ last: time.Now(),
+ }
+}
+
+func (b *tokenBucket) take() bool {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ now := time.Now()
+ elapsed := now.Sub(b.last).Seconds()
+ b.last = now
+ b.tokens += elapsed * b.refillRate
+ if b.tokens > b.maxTokens {
+ b.tokens = b.maxTokens
+ }
+ if b.tokens < 1 {
+ return false
+ }
+ b.tokens--
+ return true
+}
diff --git a/protocol/group/balancer/balancer.go b/protocol/group/balancer/balancer.go
new file mode 100644
index 0000000000..e1a83553c9
--- /dev/null
+++ b/protocol/group/balancer/balancer.go
@@ -0,0 +1,239 @@
+package balancer
+
+import (
+ "context"
+ "net"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/interrupt"
+ "github.com/sagernet/sing-box/common/monitoring"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ tun "github.com/sagernet/sing-tun"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterLoadBalance(registry *outbound.Registry) {
+ outbound.Register[option.BalancerOutboundOptions](registry, C.TypeBalancer, NewLoadBalance)
+}
+
+var _ adapter.OutboundGroup = (*Balancer)(nil)
+
+const (
+ StrategyRoundRobin = "round-robin"
+ StrategyConsistentHashing = "consistent-hashing"
+ StrategyStickySessions = "sticky-sessions"
+ StrategyLowestDelay = "lowest-delay"
+)
+
+type Balancer struct {
+ outbound.Adapter
+ ctx context.Context
+ router adapter.Router
+ outbound adapter.OutboundManager
+ connection adapter.ConnectionManager
+ logger log.ContextLogger
+ tags []string
+ link string
+ interval time.Duration
+ tolerance uint16
+ idleTimeout time.Duration
+ strategyFn Strategy
+ options option.BalancerOutboundOptions
+ interruptExternalConnections bool
+
+ monitor *monitoring.OutboundMonitoring
+
+ availbleOutbounds []adapter.Outbound
+ close chan struct{}
+ interruptGroup *interrupt.Group
+}
+
+func NewLoadBalance(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.BalancerOutboundOptions) (adapter.Outbound, error) {
+ outbound := &Balancer{
+ Adapter: outbound.NewAdapter(C.TypeBalancer, tag, []string{N.NetworkTCP, N.NetworkUDP}, options.Outbounds),
+ ctx: ctx,
+ router: router,
+ outbound: service.FromContext[adapter.OutboundManager](ctx),
+ connection: service.FromContext[adapter.ConnectionManager](ctx),
+ logger: logger,
+ tags: options.Outbounds,
+ tolerance: options.Tolerance,
+ interruptExternalConnections: options.InterruptExistConnections,
+ options: options,
+ interruptGroup: interrupt.NewGroup(),
+ }
+ if len(outbound.tags) == 0 {
+ return nil, E.New("missing tags")
+ }
+
+ return outbound, nil
+}
+
+func (s *Balancer) Strategy() string {
+ return s.options.Strategy
+}
+
+func (s *Balancer) Start() error {
+ s.monitor = monitoring.Get(s.ctx)
+ s.logger.Info("starting load balance, monitoring enabled: ", s.monitor != nil)
+ outbounds := make([]adapter.Outbound, 0, len(s.tags))
+ for i, tag := range s.tags {
+ detour, loaded := s.outbound.Outbound(tag)
+ if !loaded {
+ return E.New("outbound ", i, " not found: ", tag)
+ }
+ outbounds = append(outbounds, detour)
+ }
+ switch s.options.Strategy {
+ case StrategyRoundRobin:
+ s.strategyFn = NewRoundRobin(outbounds, s.options)
+ case StrategyConsistentHashing:
+ s.strategyFn = NewConsistentHashing(outbounds, s.options)
+ case StrategyStickySessions:
+ s.strategyFn = NewStickySession(outbounds, s.options)
+ case StrategyLowestDelay:
+ s.strategyFn = NewLowestDelay(outbounds, s.options)
+ default:
+ return E.New("unknown load balance strategy: ", s.options.Strategy)
+ }
+
+ return nil
+}
+
+func (s *Balancer) PostStart() error {
+ go s.worker()
+
+ return nil
+}
+
+func (s *Balancer) worker() {
+ observer, err := s.monitor.SubscribeGroup(s.Tag())
+ if err != nil {
+ s.logger.Error("failed to observe monitoring group: ", err)
+ return
+ }
+ defer s.monitor.UnsubscribeGroup(s.Tag(), observer)
+
+ for {
+ select {
+ case <-s.close:
+ return
+
+ case <-s.ctx.Done():
+ return
+ case _, ok := <-observer:
+ if !ok {
+ return
+ }
+ outbounds := s.monitor.OutboundsHistory(s.Tag())
+ if s.strategyFn.UpdateOutboundsInfo(outbounds) {
+ s.interruptGroup.Interrupt(s.interruptExternalConnections)
+ }
+
+ }
+ }
+}
+func (s *Balancer) Close() error {
+ if s.close != nil {
+ close(s.close)
+ }
+ return nil
+}
+
+func (s *Balancer) Now() string {
+ if s.strategyFn == nil {
+ return ""
+ }
+ return s.strategyFn.Now()
+}
+
+func (s *Balancer) All() []string {
+ return s.tags
+}
+
+func (s *Balancer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ metadata := adapter.ContextFrom(ctx)
+ if metadata == nil {
+ metadata = &adapter.InboundContext{}
+ }
+ outbound := s.strategyFn.Select(*metadata, network, true)
+ if outbound == nil {
+ return nil, E.New("missing supported outbound")
+ }
+ if metadata != nil {
+ metadata.SetRealOutbound(outbound.Tag())
+ }
+
+ conn, err := outbound.DialContext(ctx, network, destination)
+ if err == nil {
+ return s.interruptGroup.NewConn(conn, interrupt.IsExternalConnectionFromContext(ctx)), nil
+ }
+ s.logger.ErrorContext(ctx, err)
+ s.monitor.InvalidateTest(outbound.Tag())
+
+ return nil, err
+}
+
+func (s *Balancer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ metadata := adapter.ContextFrom(ctx)
+ if metadata == nil {
+ metadata = &adapter.InboundContext{}
+ }
+ outbound := s.strategyFn.Select(*metadata, N.NetworkUDP, true)
+ if outbound == nil {
+ return nil, E.New("missing supported outbound")
+ }
+ if metadata != nil {
+ metadata.SetRealOutbound(outbound.Tag())
+ }
+
+ conn, err := outbound.ListenPacket(ctx, destination)
+ if err == nil {
+ return s.interruptGroup.NewPacketConn(conn, interrupt.IsExternalConnectionFromContext(ctx)), nil
+ }
+ s.logger.ErrorContext(ctx, err)
+ s.monitor.InvalidateTest(outbound.Tag())
+ return nil, err
+}
+
+func (s *Balancer) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ ctx = interrupt.ContextWithIsExternalConnection(ctx)
+ selected := s.strategyFn.Select(metadata, metadata.Network, true)
+ conn = s.interruptGroup.NewConn(conn, interrupt.IsExternalConnectionFromContext(ctx))
+ if outboundHandler, isHandler := selected.(adapter.ConnectionHandler); isHandler {
+ outboundHandler.NewConnection(ctx, conn, metadata, onClose)
+ } else {
+ s.connection.NewConnection(ctx, selected, conn, metadata, onClose)
+ }
+}
+
+func (s *Balancer) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ ctx = interrupt.ContextWithIsExternalConnection(ctx)
+ selected := s.strategyFn.Select(metadata, metadata.Network, true)
+ if selected == nil {
+ return
+ }
+ metadata.SetRealOutbound(selected.Tag())
+ conn = s.interruptGroup.NewSingPacketConn(conn, interrupt.IsExternalConnectionFromContext(ctx))
+ if outboundHandler, isHandler := selected.(adapter.PacketConnectionHandler); isHandler {
+ outboundHandler.NewPacketConnection(ctx, conn, metadata, onClose)
+ } else {
+ s.connection.NewPacketConnection(ctx, selected, conn, metadata, onClose)
+ }
+}
+
+func (s *Balancer) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
+ selected := s.strategyFn.Select(metadata, metadata.Network, true)
+ if selected == nil {
+ return nil, E.New(metadata.Network, " is not supported by outbound: ")
+ }
+ metadata.SetRealOutbound(selected.Tag())
+ return selected.(adapter.DirectRouteOutbound).NewDirectRouteConnection(metadata, routeContext, timeout)
+}
diff --git a/protocol/group/balancer/common.go b/protocol/group/balancer/common.go
new file mode 100644
index 0000000000..91439df205
--- /dev/null
+++ b/protocol/group/balancer/common.go
@@ -0,0 +1,183 @@
+package balancer
+
+import (
+ "fmt"
+ "math"
+ "net"
+ "net/netip"
+ "sort"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/monitoring"
+ "github.com/sagernet/sing/common"
+ N "github.com/sagernet/sing/common/network"
+ "golang.org/x/net/publicsuffix"
+)
+
+func getKey(metadata *adapter.InboundContext) string {
+ if metadata == nil {
+ return ""
+ }
+
+ var metadataHost string
+ if metadata.Destination.IsFqdn() {
+ metadataHost = metadata.Destination.Fqdn
+ } else {
+ metadataHost = metadata.Domain
+ }
+
+ if metadataHost != "" {
+ // ip host
+ if ip := net.ParseIP(metadataHost); ip != nil {
+ return metadataHost
+ }
+
+ if etld, err := publicsuffix.EffectiveTLDPlusOne(metadataHost); err == nil {
+ return etld
+ }
+ }
+
+ var destinationAddr netip.Addr
+ if len(metadata.DestinationAddresses) > 0 {
+ destinationAddr = metadata.DestinationAddresses[0]
+ } else {
+ destinationAddr = metadata.Destination.Addr
+ }
+
+ if !destinationAddr.IsValid() {
+ return ""
+ }
+
+ return destinationAddr.String()
+}
+
+func getKeyWithSrcAndDst(metadata *adapter.InboundContext) string {
+ dst := getKey(metadata)
+ src := ""
+ if metadata != nil {
+ src = metadata.Source.Addr.String()
+ }
+
+ return fmt.Sprintf("%s%s", src, dst)
+}
+
+func jumpHash(key uint64, buckets int32) int32 {
+ var b, j int64
+
+ for j < int64(buckets) {
+ b = j
+ key = key*2862933555777941757 + 1
+ j = int64(float64(b+1) * (float64(int64(1)<<31) / float64((key>>33)+1)))
+ }
+
+ return int32(b)
+}
+
+func getModifiedDelay(his *adapter.URLTestHistory) uint16 {
+ if his == nil {
+ return monitoring.TimeoutDelay
+ }
+ delay := his.Delay
+ if delay == 0 {
+ delay = monitoring.TimeoutDelay
+ }
+ if his.IsFromCache && delay < 20000 {
+ // if the history is from cache, we can not trust the delay
+ delay += 20000
+ }
+ return delay
+}
+func getTagDelay(tag string, history map[string]*adapter.URLTestHistory) uint16 {
+ if his, ok := history[tag]; ok && his != nil {
+ return getModifiedDelay(his)
+ }
+ return monitoring.TimeoutDelay
+}
+
+func filterOutbounds(outbounds []adapter.Outbound, network string) []adapter.Outbound {
+ res := []adapter.Outbound{}
+ for _, out := range outbounds {
+ if !common.Contains(out.Network(), network) {
+ continue
+ }
+ res = append(res, out)
+ }
+ if len(res) == 0 {
+ return outbounds
+ }
+ return res
+}
+func convertOutbounds(outbounds []adapter.Outbound) map[string][]adapter.Outbound {
+ return map[string][]adapter.Outbound{
+ N.NetworkTCP: filterOutbounds(outbounds, N.NetworkTCP),
+ N.NetworkUDP: filterOutbounds(outbounds, N.NetworkUDP),
+ }
+}
+
+func sortOutboundsByDelay(outbounds map[string][]adapter.Outbound, history map[string]*adapter.URLTestHistory) map[string][]adapter.Outbound {
+ res := map[string][]adapter.Outbound{}
+ for net, outs := range outbounds {
+ res[net] = append([]adapter.Outbound{}, outs...)
+ sort.SliceStable(res[net], func(i, j int) bool {
+ var delayi uint16 = getTagDelay(res[net][i].Tag(), history)
+ var delayj uint16 = getTagDelay(res[net][j].Tag(), history)
+ return delayi < delayj
+ })
+ }
+
+ return res
+}
+func getAcceptableIndex(sortedOutbounds map[string][]adapter.Outbound, history map[string]*adapter.URLTestHistory, delayAcceptableRatio float64) map[string]int {
+ res := map[string]int{}
+ for net, outs := range sortedOutbounds {
+ minDelay := getTagDelay(outs[0].Tag(), history)
+
+ maxAcceptableDelay := float64(math.Max(100, float64(minDelay))) * delayAcceptableRatio
+
+ maxAvailableIndex := 0
+ for i, outbound := range outs {
+ delay := getTagDelay(outbound.Tag(), history)
+ if delay <= uint16(maxAcceptableDelay) {
+ maxAvailableIndex = i
+ }
+ }
+ res[net] = maxAvailableIndex
+ }
+ return res
+
+}
+
+func getMinDelay(outbounds map[string][]adapter.Outbound, history map[string]*adapter.URLTestHistory) (map[string]adapter.Outbound, map[string]uint16) {
+ delays := map[string]uint16{}
+ bestOuts := map[string]adapter.Outbound{}
+ for net, outs := range outbounds {
+ minDelay := monitoring.TimeoutDelay
+ var minOut adapter.Outbound
+ for _, out := range outs {
+
+ d := getTagDelay(out.Tag(), history)
+ if d <= minDelay {
+ minDelay = d
+ minOut = out
+ }
+ }
+ delays[net] = minDelay
+ bestOuts[net] = minOut
+ }
+ return bestOuts, delays
+
+}
+
+func getDelayMap(history map[string]*adapter.URLTestHistory) map[string]uint16 {
+ delayMap := make(map[string]uint16)
+ for tag, his := range history {
+ if his != nil {
+ delayMap[tag] = his.Delay
+ } else {
+ delayMap[tag] = monitoring.TimeoutDelay
+ }
+ }
+
+ return delayMap
+
+}
diff --git a/protocol/group/balancer/consistent_hashing.go b/protocol/group/balancer/consistent_hashing.go
new file mode 100644
index 0000000000..11df8f1c07
--- /dev/null
+++ b/protocol/group/balancer/consistent_hashing.go
@@ -0,0 +1,86 @@
+package balancer
+
+import (
+ "math"
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/contrab/maphash"
+)
+
+type ConsistentHashing struct {
+ outbounds map[string][]adapter.Outbound
+ delays map[string]uint16
+ hash maphash.Hasher[string]
+ maxRetry int
+ maxAcceptableDelay map[string]uint16
+ mu sync.Mutex
+ delayAcceptableRatio float64
+}
+
+func NewConsistentHashing(outbounds []adapter.Outbound, options option.BalancerOutboundOptions) *ConsistentHashing {
+ cOutbounds := convertOutbounds(outbounds)
+
+ return &ConsistentHashing{
+ outbounds: cOutbounds,
+ hash: maphash.NewHasher[string](),
+ maxRetry: options.MaxRetry,
+ delayAcceptableRatio: options.DelayAcceptableRatio,
+ }
+}
+
+var _ Strategy = (*ConsistentHashing)(nil)
+
+func (s *ConsistentHashing) Now() string {
+ return ""
+}
+func (s *ConsistentHashing) UpdateOutboundsInfo(history map[string]*adapter.URLTestHistory) bool {
+ _, minDelay := getMinDelay(s.outbounds, history)
+ delayMap := getDelayMap(history)
+ res := map[string]uint16{}
+ for net, d := range minDelay {
+ acceptableDelay := uint16(math.Max(100, float64(d)) * s.delayAcceptableRatio)
+ res[net] = acceptableDelay
+ }
+ s.mu.Lock()
+ s.delays = delayMap
+ s.maxAcceptableDelay = res
+ s.mu.Unlock()
+ return true
+}
+func (g *ConsistentHashing) Select(metadata adapter.InboundContext, net string, touch bool) adapter.Outbound {
+ g.mu.Lock()
+ defer g.mu.Unlock()
+ if net != N.NetworkTCP && net != N.NetworkUDP {
+ net = N.NetworkTCP
+ }
+ key := g.hash.Hash(getKey(&metadata))
+ buckets := int32(len(g.outbounds[net]))
+ for i := 0; i < g.maxRetry; i, key = i+1, key+1 {
+ idx := jumpHash(key, buckets)
+ proxy := g.outbounds[net][idx]
+ if g.Alive(proxy, net) {
+ return proxy
+ }
+ }
+
+ // when availability is poor, traverse the entire list to get the available nodes
+ for _, proxy := range g.outbounds[net] {
+ if g.Alive(proxy, net) {
+ return proxy
+ }
+ }
+ idx := jumpHash(key, buckets)
+ return g.outbounds[net][idx]
+
+}
+
+func (s *ConsistentHashing) Alive(proxy adapter.Outbound, net string) bool {
+ if delay, ok := s.delays[proxy.Tag()]; ok {
+ return delay <= s.maxAcceptableDelay[net]
+ }
+ return false
+
+}
diff --git a/protocol/group/balancer/lowest_delay.go b/protocol/group/balancer/lowest_delay.go
new file mode 100644
index 0000000000..1ed6f61334
--- /dev/null
+++ b/protocol/group/balancer/lowest_delay.go
@@ -0,0 +1,58 @@
+package balancer
+
+import (
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+ N "github.com/sagernet/sing/common/network"
+)
+
+type LowestDelay struct {
+ outbounds map[string][]adapter.Outbound
+ udpOutbounds []adapter.Outbound
+ selectedOutbound map[string]adapter.Outbound
+
+ mu sync.Mutex
+}
+
+func NewLowestDelay(outbounds []adapter.Outbound, options option.BalancerOutboundOptions) *LowestDelay {
+ couts := convertOutbounds(outbounds)
+ return &LowestDelay{
+ outbounds: couts,
+ selectedOutbound: map[string]adapter.Outbound{
+ N.NetworkUDP: couts[N.NetworkUDP][0],
+ N.NetworkTCP: couts[N.NetworkTCP][0],
+ },
+ }
+}
+
+var _ Strategy = (*LowestDelay)(nil)
+
+func (s *LowestDelay) Now() string {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ return s.selectedOutbound[N.NetworkTCP].Tag()
+}
+func (s *LowestDelay) UpdateOutboundsInfo(history map[string]*adapter.URLTestHistory) bool {
+ min, _ := getMinDelay(s.outbounds, history)
+
+ s.mu.Lock()
+ changed := false
+ for net, out := range min {
+ changed = changed || out.Tag() != s.selectedOutbound[net].Tag()
+ }
+ s.selectedOutbound = min
+ s.mu.Unlock()
+ return changed
+}
+func (s *LowestDelay) Select(metadata adapter.InboundContext, net string, touch bool) adapter.Outbound {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if net != N.NetworkTCP && net != N.NetworkUDP {
+ net = N.NetworkTCP
+ }
+ return s.selectedOutbound[net]
+
+}
diff --git a/protocol/group/balancer/roundrobin.go b/protocol/group/balancer/roundrobin.go
new file mode 100644
index 0000000000..8a31080549
--- /dev/null
+++ b/protocol/group/balancer/roundrobin.go
@@ -0,0 +1,82 @@
+package balancer
+
+import (
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+ N "github.com/sagernet/sing/common/network"
+)
+
+var _ Strategy = (*RoundRobin)(nil)
+
+type RoundRobin struct {
+ outbounds map[string][]adapter.Outbound
+
+ sortedOutbounds map[string][]adapter.Outbound
+
+ maxAcceptableIndex map[string]int
+ idx map[string]int
+ mu sync.Mutex
+ delayAcceptableRatio float64
+}
+
+func NewRoundRobin(outbounds []adapter.Outbound, options option.BalancerOutboundOptions) *RoundRobin {
+ cOutbounds := convertOutbounds(outbounds)
+ acceptable := map[string]int{}
+ idx := map[string]int{}
+ for net, outs := range cOutbounds {
+ acceptable[net] = len(outs) - 1
+ idx[net] = 0
+ }
+ return &RoundRobin{
+ outbounds: cOutbounds,
+
+ sortedOutbounds: cOutbounds,
+ maxAcceptableIndex: acceptable,
+ delayAcceptableRatio: options.DelayAcceptableRatio,
+ idx: idx,
+ }
+}
+
+func (s *RoundRobin) Now() string {
+ // s.idxMutex.Lock()
+ // defer s.idxMutex.Unlock()
+ return ""
+}
+
+func (s *RoundRobin) UpdateOutboundsInfo(history map[string]*adapter.URLTestHistory) bool {
+ sortedOutbounds := sortOutboundsByDelay(s.outbounds, history)
+ acceptableIndex := getAcceptableIndex(sortedOutbounds, history, s.delayAcceptableRatio)
+
+ s.mu.Lock()
+ changed := false
+ for net, ix := range acceptableIndex {
+ changed = changed || ix != s.maxAcceptableIndex[net]
+ }
+
+ s.sortedOutbounds = sortedOutbounds
+ s.maxAcceptableIndex = acceptableIndex
+ s.mu.Unlock()
+ return changed
+}
+
+func (s *RoundRobin) Select(metadata adapter.InboundContext, net string, touch bool) adapter.Outbound {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if net != N.NetworkTCP && net != N.NetworkUDP {
+ net = N.NetworkTCP
+ }
+ i := 1
+ length := s.maxAcceptableIndex[net] + 1
+ if length == 0 {
+ return nil
+ }
+ id := (s.idx[net] + i) % length
+ proxy := s.sortedOutbounds[net][id]
+ if touch {
+ s.idx[net] = id
+ }
+ return proxy
+
+}
diff --git a/protocol/group/balancer/sticky_session.go b/protocol/group/balancer/sticky_session.go
new file mode 100644
index 0000000000..bf6f18459f
--- /dev/null
+++ b/protocol/group/balancer/sticky_session.go
@@ -0,0 +1,100 @@
+package balancer
+
+import (
+ "math"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/contrab/freelru"
+ "github.com/sagernet/sing/contrab/maphash"
+)
+
+type StickySession struct {
+ outbounds map[string][]adapter.Outbound
+ hash maphash.Hasher[string]
+ maxRetry int
+ delays map[string]uint16
+ maxAcceptableDelay map[string]uint16
+
+ mu sync.Mutex
+ delayAcceptableRatio float64
+ lruCache *freelru.ShardedLRU[uint64, int]
+}
+
+func NewStickySession(outbounds []adapter.Outbound, options option.BalancerOutboundOptions) *StickySession {
+ lruCache := common.Must1(freelru.NewSharded[uint64, int](1000, maphash.NewHasher[uint64]().Hash32))
+ lruCache.SetLifetime(options.TTL.Build())
+ cOutbounds := convertOutbounds(outbounds)
+ return &StickySession{
+ outbounds: cOutbounds,
+ lruCache: lruCache,
+ hash: maphash.NewHasher[string](),
+ maxRetry: options.MaxRetry,
+ delayAcceptableRatio: options.DelayAcceptableRatio,
+ }
+}
+
+var _ Strategy = (*StickySession)(nil)
+
+func (s *StickySession) Select(metadata adapter.InboundContext, net string, touch bool) adapter.Outbound {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ if net != N.NetworkTCP && net != N.NetworkUDP {
+ net = N.NetworkTCP
+ }
+ key := s.hash.Hash(getKeyWithSrcAndDst(&metadata))
+ length := len(s.outbounds[net])
+ idx, has := s.lruCache.Get(key)
+ if !has || idx >= length {
+ idx = int(jumpHash(key+uint64(time.Now().UnixNano()), int32(length)))
+ }
+
+ nowIdx := idx
+ for i := 1; i < s.maxRetry; i++ {
+ proxy := s.outbounds[net][nowIdx]
+ if s.Alive(proxy, net) {
+ if !has || nowIdx != idx {
+ s.lruCache.Add(key, nowIdx)
+ }
+
+ return proxy
+ } else {
+ nowIdx = int(jumpHash(key+uint64(time.Now().UnixNano()), int32(length)))
+ }
+ }
+
+ s.lruCache.Add(key, nowIdx)
+ return s.outbounds[net][nowIdx]
+
+}
+
+func (s *StickySession) Now() string {
+ return ""
+}
+func (s *StickySession) UpdateOutboundsInfo(history map[string]*adapter.URLTestHistory) bool {
+ _, minDelay := getMinDelay(s.outbounds, history)
+ delayMap := getDelayMap(history)
+ res := map[string]uint16{}
+ for net, d := range minDelay {
+ acceptableDelay := uint16(math.Max(100, float64(d)) * s.delayAcceptableRatio)
+ res[net] = acceptableDelay
+ }
+ s.mu.Lock()
+ s.delays = delayMap
+ s.maxAcceptableDelay = res
+ s.mu.Unlock()
+ return true
+}
+
+func (s *StickySession) Alive(proxy adapter.Outbound, net string) bool {
+ if delay, ok := s.delays[proxy.Tag()]; ok {
+ return delay <= s.maxAcceptableDelay[net]
+ }
+ return false
+
+}
diff --git a/protocol/group/balancer/strategy.go b/protocol/group/balancer/strategy.go
new file mode 100644
index 0000000000..b95d5ae45f
--- /dev/null
+++ b/protocol/group/balancer/strategy.go
@@ -0,0 +1,9 @@
+package balancer
+
+import "github.com/sagernet/sing-box/adapter"
+
+type Strategy interface {
+ UpdateOutboundsInfo(outbounds map[string]*adapter.URLTestHistory) (changed bool)
+ Select(metadata adapter.InboundContext, network string, touch bool) adapter.Outbound
+ Now() string
+}
diff --git a/protocol/group/selector.go b/protocol/group/selector.go
index f3f7377b61..85bea2b964 100644
--- a/protocol/group/selector.go
+++ b/protocol/group/selector.go
@@ -25,9 +25,9 @@ func RegisterSelector(registry *outbound.Registry) {
}
var (
- _ adapter.OutboundGroup = (*Selector)(nil)
- _ adapter.ConnectionHandlerEx = (*Selector)(nil)
- _ adapter.PacketConnectionHandlerEx = (*Selector)(nil)
+ _ adapter.OutboundGroup = (*Selector)(nil)
+ _ adapter.ConnectionHandler = (*Selector)(nil)
+ _ adapter.PacketConnectionHandler = (*Selector)(nil)
)
type Selector struct {
@@ -156,21 +156,21 @@ func (s *Selector) ListenPacket(ctx context.Context, destination M.Socksaddr) (n
return s.interruptGroup.NewPacketConn(conn, interrupt.IsExternalConnectionFromContext(ctx)), nil
}
-func (s *Selector) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (s *Selector) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
ctx = interrupt.ContextWithIsExternalConnection(ctx)
selected := s.selected.Load()
- if outboundHandler, isHandler := selected.(adapter.ConnectionHandlerEx); isHandler {
- outboundHandler.NewConnectionEx(ctx, conn, metadata, onClose)
+ if outboundHandler, isHandler := selected.(adapter.ConnectionHandler); isHandler {
+ outboundHandler.NewConnection(ctx, conn, metadata, onClose)
} else {
s.connection.NewConnection(ctx, selected, conn, metadata, onClose)
}
}
-func (s *Selector) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (s *Selector) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
ctx = interrupt.ContextWithIsExternalConnection(ctx)
selected := s.selected.Load()
- if outboundHandler, isHandler := selected.(adapter.PacketConnectionHandlerEx); isHandler {
- outboundHandler.NewPacketConnectionEx(ctx, conn, metadata, onClose)
+ if outboundHandler, isHandler := selected.(adapter.PacketConnectionHandler); isHandler {
+ outboundHandler.NewPacketConnection(ctx, conn, metadata, onClose)
} else {
s.connection.NewPacketConnection(ctx, selected, conn, metadata, onClose)
}
diff --git a/protocol/group/urltest.go b/protocol/group/urltest.go
index 730040f7b9..51fe3d0a47 100644
--- a/protocol/group/urltest.go
+++ b/protocol/group/urltest.go
@@ -159,12 +159,12 @@ func (s *URLTest) ListenPacket(ctx context.Context, destination M.Socksaddr) (ne
return nil, err
}
-func (s *URLTest) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (s *URLTest) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
ctx = interrupt.ContextWithIsExternalConnection(ctx)
s.connection.NewConnection(ctx, s, conn, metadata, onClose)
}
-func (s *URLTest) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (s *URLTest) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
ctx = interrupt.ContextWithIsExternalConnection(ctx)
s.connection.NewPacketConnection(ctx, s, conn, metadata, onClose)
}
diff --git a/protocol/group/urltest_helper.go b/protocol/group/urltest_helper.go
new file mode 100644
index 0000000000..5cfaca1df2
--- /dev/null
+++ b/protocol/group/urltest_helper.go
@@ -0,0 +1,317 @@
+package group
+
+// import (
+// "context"
+// "sync"
+// "time"
+
+// "github.com/sagernet/sing-box/log"
+
+// "github.com/sagernet/sing-box/adapter"
+// "github.com/sagernet/sing-box/common/urltest"
+// C "github.com/sagernet/sing-box/constant"
+// "github.com/sagernet/sing-box/hiddify/ipinfo"
+// "github.com/sagernet/sing/common"
+// "github.com/sagernet/sing/common/batch"
+// N "github.com/sagernet/sing/common/network"
+// )
+
+// const TimeoutDelay = 65535
+
+// func urltestTimeout(ctx context.Context, logger log.Logger, realTag string, outbound adapter.Outbound, url string, history adapter.URLTestHistoryStorage, timeout time.Duration) *adapter.URLTestHistory {
+// testCtx, cancel := context.WithTimeout(ctx, timeout)
+// defer cancel()
+// t, err := urltest.URLTest(testCtx, url, outbound)
+// if err != nil || t == 0 {
+// t = TimeoutDelay
+// }
+
+// his := &adapter.URLTestHistory{
+// Time: time.Now(),
+// Delay: t,
+// }
+// logger.Debug("outbound new ping ", realTag, " = ", his.Delay)
+// return his
+// }
+
+// func CheckOutbound(logger log.Logger, ctx context.Context, history adapter.URLTestHistoryStorage, router adapter.OutboundManager, url string, outbound adapter.Outbound, ipbatch *batch.Batch[any]) uint16 {
+// realTag := RealTag(outbound)
+// hisbefore := history.LoadURLTestHistory(realTag)
+// timeout := C.TCPTimeout
+// isTimeoutBefore := isTimeout(hisbefore)
+
+// if !isTimeoutBefore {
+// timeout = time.Duration(max(400, hisbefore.Delay)) * time.Millisecond * 5
+// logger.Debug("outbound is already connected ", realTag, " = ", hisbefore.Delay, " set timeout for new urltest to ", timeout)
+// }
+// his := urltestTimeout(ctx, logger, realTag, outbound, url, history, timeout)
+
+// // if outbound.Type() == C.TypeWireGuard && his.Delay > 1000 { // double check for wireguard
+// // his = urltestTimeout(ctx, logger, realTag, outbound, url, history, timeout)
+// // }
+// if isTimeout(his) && !isTimeoutBefore {
+// his = urltestTimeout(ctx, logger, realTag, outbound, url, history, C.TCPTimeout)
+// }
+// his = history.StoreURLTestHistory(realTag, his)
+// if !isTimeout(his) && his.IpInfo == nil {
+// if ipbatch == nil {
+// go CheckIP(logger, ctx, history, router, outbound)
+// } else {
+// ipbatch.Go(realTag+"ip", func() (any, error) {
+// select {
+// case <-ctx.Done():
+// return nil, ctx.Err()
+// default:
+// }
+// CheckIP(logger, ctx, history, router, outbound)
+// return "", nil
+// })
+// }
+// }
+
+// return his.Delay
+// }
+
+// func CheckIP(logger log.Logger, ctx context.Context, history adapter.URLTestHistoryStorage, router adapter.OutboundManager, outbound adapter.Outbound) {
+// if outbound == nil {
+// return
+// }
+// if history == nil {
+// return
+// }
+// realTag := RealTag(outbound)
+// detour, loaded := router.Outbound(realTag)
+// if !loaded {
+// return
+// }
+// his := history.LoadURLTestHistory(realTag)
+// if isTimeout(his) {
+// return
+// }
+// if his.IpInfo != nil {
+// // logger.Debug("ip already calculated ", fmt.Sprint(his.IpInfo))
+// return
+// }
+// newip, t, err := ipinfo.GetIpInfo(logger, ctx, detour)
+// if err != nil {
+// // g.logger.Debug("outbound ", realTag, " IP unavailable (", t, "ms): ", err)
+// // g.history.AddOnlyIpToHistory(realTag, &urltest.History{
+// // Time: time.Now(),
+// // Delay: TimeoutDelay,
+// // IpInfo: &ipinfo.IpInfo{},
+// // })
+// return
+// }
+// // g.logger.Trace("outbound ", realTag, " IP ", fmt.Sprint(newip), " (", t, "ms): ", err)
+// history.AddOnlyIpToHistory(realTag, &adapter.URLTestHistory{
+// Time: time.Now(),
+// Delay: t,
+// IpInfo: newip,
+// })
+// }
+
+// func isTimeout(history *adapter.URLTestHistory) bool {
+// return history == nil || history.Delay >= TimeoutDelay || history.Delay == 0
+// }
+
+// func (g *URLTestGroup) urlTestEx(ctx context.Context, force bool, force_check_even_previous_not_completed bool) (map[string]uint16, error) {
+// if t := g.selectedOutboundTCP; t != nil {
+// go g.urltestImp(t, nil)
+// }
+// if t := g.selectedOutboundUDP; t != nil && t != g.selectedOutboundTCP {
+// go g.urltestImp(t, nil)
+// }
+
+// if force_check_even_previous_not_completed && time.Since(g.lastForceRecheck) < 15*time.Second {
+// return make(map[string]uint16), nil
+// }
+
+// if g.checking.Swap(true) {
+// if !force_check_even_previous_not_completed {
+// return make(map[string]uint16), nil
+// }
+// if g.checkingEx.Swap(true) {
+// g.performUpdateCheck()
+// return make(map[string]uint16), nil
+// }
+// defer g.checkingEx.Store(false)
+// g.lastForceRecheck = time.Now()
+// }
+// defer g.checking.Store(false)
+
+// result, err := g.urlTestExImp(ctx, force, force_check_even_previous_not_completed)
+// if err != nil {
+// return nil, err
+// }
+// if !force_check_even_previous_not_completed && g.currentLinkIndex == 0 {
+// for i := 1; i < len(g.links); i++ {
+// result, err := g.urlTestExImp(ctx, force, force_check_even_previous_not_completed)
+// if err != nil {
+// return nil, err
+// }
+// if g.hasOneAvailableOutbound() {
+// g.currentLinkIndex = i
+// return result, nil
+// }
+
+// }
+// }
+// return result, nil
+// }
+// func (g *URLTestGroup) urlTestExImp(ctx context.Context, force bool, force_check_even_previous_not_completed bool) (map[string]uint16, error) {
+// result := make(map[string]uint16)
+// ipbatch, _ := batch.New(ctx, batch.WithConcurrencyNum[any](10))
+// b, _ := batch.New(ctx, batch.WithConcurrencyNum[any](10))
+// checked := make(map[string]bool)
+// var resultAccess sync.Mutex
+// for _, detour := range g.outbounds {
+// tag := detour.Tag()
+// realTag := RealTag(detour)
+// if checked[realTag] {
+// continue
+// }
+// history := g.history.LoadURLTestHistory(realTag)
+// if !force && !isTimeout(history) && time.Since(history.Time) < g.interval {
+// continue
+// }
+// checked[realTag] = true
+// p, loaded := g.outbound.Outbound(realTag)
+// if !loaded {
+// continue
+// }
+// b.Go(realTag, func() (any, error) {
+// select {
+// case <-ctx.Done():
+// return nil, ctx.Err()
+// default:
+// }
+// if !force_check_even_previous_not_completed && g.checkingEx.Load() {
+// return nil, nil
+// }
+// t := g.urltestImp(p, ipbatch)
+// resultAccess.Lock()
+// result[tag] = t
+// g.performOutboundUpdateCheck(detour)
+// resultAccess.Unlock()
+// return nil, nil
+// })
+// }
+// if err := WaitBatchesWithContext(ctx, b, ipbatch); err != nil {
+// return nil, err
+// }
+
+// g.performUpdateCheck()
+
+// return result, nil
+// }
+
+// func WaitBatchesWithContext(ctx context.Context, batches ...*batch.Batch[any]) error {
+// done := make(chan error, len(batches))
+
+// for _, b := range batches {
+// go func(b *batch.Batch[any]) {
+// done <- b.Wait()
+// }(b)
+// }
+
+// for i := 0; i < len(batches); i++ {
+// select {
+// case err := <-done:
+// if err != nil {
+// return err
+// }
+// case <-ctx.Done():
+// return ctx.Err()
+// }
+// }
+// return nil
+// }
+// func (g *URLTestGroup) urltestImp(outbound adapter.Outbound, ipbatch *batch.Batch[any]) uint16 {
+// return CheckOutbound(g.logger, g.ctx, g.history, g.outbound, g.links[g.currentLinkIndex], outbound, ipbatch)
+// }
+
+// func (g *URLTestGroup) hasOneAvailableOutbound() bool {
+// for _, detour := range g.outbounds {
+// if !common.Contains(detour.Network(), "tcp") {
+// continue
+// }
+// realTag := RealTag(detour)
+// history := g.history.LoadURLTestHistory(realTag)
+// if isTimeout(history) {
+// continue
+// }
+// g.logger.Debug("has one outbound ", realTag, " available: ", history.Delay, "ms")
+// return true
+// }
+// g.logger.Debug("no available outbound ")
+// return false
+// }
+
+// func (g *URLTestGroup) forceUpdateOutbound(tcp adapter.Outbound, udp adapter.Outbound) bool {
+// update := false
+// if tcp != nil && g.selectedOutboundTCP != tcp {
+// g.selectedOutboundTCP = tcp
+// // g.tcpConnectionFailureCount.Reset()
+// // go g.checkHistoryIp(g.selectedOutboundTCP)
+// update = true
+
+// }
+// if udp != nil && g.selectedOutboundUDP != udp {
+// g.selectedOutboundUDP = udp
+// // g.udpConnectionFailureCount.Reset()
+// update = true
+// }
+// if update {
+// g.interruptGroup.Interrupt(g.interruptExternalConnections)
+// }
+// return update
+// }
+// func (g *URLTestGroup) performOutboundUpdateCheck(outbound adapter.Outbound) {
+// tcpOutbound, shouldReselectTCP := g.getPreferredOutbound(outbound, g.selectedOutboundTCP, N.NetworkTCP)
+// udpOutbound, shouldReselectUDP := g.getPreferredOutbound(outbound, g.selectedOutboundUDP, N.NetworkUDP)
+// if shouldReselectTCP {
+// tcpOutbound, _ = g.Select(N.NetworkTCP)
+// }
+// if shouldReselectUDP {
+// udpOutbound, _ = g.Select(N.NetworkUDP)
+// }
+
+// g.forceUpdateOutbound(tcpOutbound, udpOutbound)
+// }
+
+// func (g *URLTestGroup) getPreferredOutbound(newOutbound, selectedOutbound adapter.Outbound, networkType string) (outbound adapter.Outbound, shouldReselect bool) {
+// if newOutbound == nil {
+// return nil, false
+// }
+
+// if !common.Contains(newOutbound.Network(), networkType) {
+// return nil, false
+// }
+
+// newHistory := g.history.LoadURLTestHistory(RealTag(newOutbound))
+// if isTimeout(newHistory) {
+// if newOutbound == selectedOutbound {
+// return nil, true
+// }
+// return nil, false
+// }
+
+// if selectedOutbound == nil {
+// return newOutbound, false
+// }
+
+// selectedHistory := g.history.LoadURLTestHistory(RealTag(selectedOutbound))
+// if isTimeout(selectedHistory) {
+// return newOutbound, false
+// }
+
+// if newHistory == nil || selectedHistory == nil {
+// return nil, false
+// }
+
+// if newHistory.Delay+g.tolerance < selectedHistory.Delay {
+// return newOutbound, false
+// }
+
+// return selectedOutbound, false
+// }
diff --git a/protocol/hiddify/dnstt/conn.go b/protocol/hiddify/dnstt/conn.go
new file mode 100644
index 0000000000..8dfe976662
--- /dev/null
+++ b/protocol/hiddify/dnstt/conn.go
@@ -0,0 +1,42 @@
+package dnstt
+
+import (
+ "bytes"
+ "net"
+)
+
+type LoggingConn struct {
+ net.Conn
+ rx bytes.Buffer
+ tx bytes.Buffer
+ outbound *Outbound
+ tunnel_index int
+}
+
+func (c *LoggingConn) Read(b []byte) (int, error) {
+ n, err := c.Conn.Read(b)
+ if n > 0 {
+ c.rx.Write(b[:n])
+ }
+ return n, err
+}
+
+func (c *LoggingConn) Write(b []byte) (int, error) {
+ if len(b) > 0 {
+ c.tx.Write(b)
+ }
+ return c.Conn.Write(b)
+}
+
+func (c *LoggingConn) Close() error {
+ c.outbound.logger.Info(c.outbound.Tag(), " Tunnel ", c.tunnel_index, " closing connection. TX bytes: ", c.tx.Len(), ", RX bytes: ", c.rx.Len())
+ // bs := c.rx.Bytes()
+
+ // fmt.Printf("TX bytes: \n%s\n", c.tx.String())
+ // if len(bs) > 0 {
+ // fmt.Printf("RX bytes: \n%s\n", c.tx.String())
+ // } else {
+ // fmt.Printf("RX bytes: %d \n", len(bs))
+ // }
+ return c.Conn.Close()
+}
diff --git a/protocol/hiddify/dnstt/dnstt_func.go b/protocol/hiddify/dnstt/dnstt_func.go
new file mode 100644
index 0000000000..c010cca716
--- /dev/null
+++ b/protocol/hiddify/dnstt/dnstt_func.go
@@ -0,0 +1,192 @@
+package dnstt
+
+import (
+ "context"
+ "math/rand"
+ "net"
+
+ "fmt"
+
+ dnstt "github.com/net2share/vaydns/client"
+ "github.com/sagernet/sing-box/common/monitoring"
+)
+
+func (c *Outbound) addResolver(resolver dnstt.Resolver) {
+ c.mu.Lock()
+ if c.mdMgr != nil {
+ // Smart pool mode: register the resolver as a multidns upstream.
+ // c.resolvers stays at the single virtual resolver set up in
+ // NewOutbound, so the existing tunnel keeps running — the pool
+ // rotates upstreams behind it. No need to invalidate
+ // c.mutlitunnel here (unlike the legacy path, which has to
+ // rebuild the tunnel when its resolver list changes).
+ _, _ = c.mdMgr.AddResolverURL(resolverURL(resolver))
+ } else {
+ // for i := 0; i < c.options.TunnelPerResolver; i++ {
+ c.resolvers = append(c.resolvers, resolver)
+ c.tunnels = append(c.tunnels, nil)
+ // }
+ c.mutlitunnel = nil
+ }
+ c.mu.Unlock()
+ if !c.IsReady() {
+ c.started = 1
+ c.logger.InfoContext(c.ctx, "initial resolver ", resolver.ResolverAddr)
+ monitoring.Get(c.ctx).TestNow(c.Tag())
+ }
+}
+
+// resolverURL renders a dnstt.Resolver as the URL form multidns parses.
+// UDP resolvers are bare host:port (multidns defaults to UDP/53); DoT gets
+// the "dot://" prefix; DoH is already a full https:// URL.
+func resolverURL(r dnstt.Resolver) string {
+ switch r.ResolverType {
+ case dnstt.ResolverTypeDOT:
+ return "dot://" + r.ResolverAddr
+ default:
+ return r.ResolverAddr
+ }
+}
+
+func (c *Outbound) openStreamImp(ctx context.Context) (net.Conn, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if t := c.mutlitunnel; t != nil {
+ return t.OpenStream()
+ }
+
+ if newtunnel, err := c.createDnsttTunnel(ctx, c.resolvers); err != nil {
+ return nil, err
+ } else {
+ c.mutlitunnel = newtunnel
+ return newtunnel.OpenStream()
+ }
+}
+func (c *Outbound) OpenStream(ctx context.Context) (net.Conn, error) {
+ var err error
+ var conn net.Conn
+ for range 3 {
+ conn, err = c.openStreamImp(ctx)
+ if err == nil {
+ return conn, nil
+ }
+ }
+ return nil, err
+}
+func (c *Outbound) OpenStreamSingleResolver(ctx context.Context) (net.Conn, error) {
+ // dnsttConfig := streamSettings.ProtocolSettings.(*Config)
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ // c.tunnel_index = (c.tunnel_index + 1) % len(c.tunnels)
+ var lasterr error
+ for i := 0; i < max(5, len(c.tunnels)); i++ {
+ tunnel_index := rand.Intn(len(c.resolvers)) // 0 <= x < n
+ tunnel := c.tunnels[tunnel_index]
+ if tunnel == nil {
+ if newtunnel, err := c.createDnsttTunnel(ctx, []dnstt.Resolver{c.resolvers[tunnel_index]}); err != nil {
+ lasterr = err
+ c.logger.DebugContext(ctx, "tunnel [", tunnel_index, "] failed resolver ", c.resolvers[tunnel_index].ResolverAddr)
+ } else {
+ c.tunnels[tunnel_index] = newtunnel
+ tunnel = newtunnel
+ c.logger.InfoContext(ctx, "tunnel [", tunnel_index, "] resolver ", c.resolvers[tunnel_index].ResolverAddr)
+
+ // return tunnel, nil
+ }
+ }
+ if tunnel != nil {
+ if conn, err := tunnel.OpenStream(); err == nil {
+ // return &LoggingConn{Conn: stream, outbound: h, tunnel_index: h.tunnel_index}, nil
+ return conn, nil
+ } else {
+ lasterr = err
+ }
+ tunnel.Close()
+ c.tunnels[tunnel_index] = nil
+ }
+ }
+ return nil, lasterr
+}
+func (c *Outbound) createDnsttTunnel(ctx context.Context, resolver []dnstt.Resolver) (*dnstt.Tunnel, error) {
+ tServer, err := dnstt.NewTunnelServer(c.options.Domain, c.options.PublicKey)
+ if err != nil {
+ return nil, fmt.Errorf("invalid tunnel server: %w", err)
+ }
+
+ if c.options.MTU != nil {
+ tServer.MTU = *c.options.MTU
+ }
+
+ tServer.DnsttCompat = c.options.DnsttCompat
+
+ if c.options.ClientIDSize != nil {
+ tServer.ClientIDSize = *c.options.ClientIDSize
+ }
+
+ if c.options.MaxNumLabels != nil {
+ tServer.MaxNumLabels = *c.options.MaxNumLabels
+ }
+ if c.options.RPS != nil {
+ tServer.RPS = *c.options.RPS
+ }
+ if c.options.MaxQnameLen != nil {
+ tServer.MaxQnameLen = *c.options.MaxQnameLen
+ }
+
+ tunnel, err := dnstt.NewTunnel(resolver, tServer)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create tunnel: %w", err)
+ }
+ if c.options.OpenStreamTimeout != nil {
+ tunnel.OpenStreamTimeout = c.options.OpenStreamTimeout.Build()
+ }
+ if c.options.MaxStreams != nil {
+ tunnel.MaxStreams = *c.options.MaxStreams
+ }
+ if c.options.ReconnectMinDelay != nil {
+ tunnel.ReconnectMinDelay = c.options.ReconnectMinDelay.Build()
+ }
+ if c.options.ReconnectMaxDelay != nil {
+ tunnel.ReconnectMaxDelay = c.options.ReconnectMaxDelay.Build()
+ }
+ if c.options.SessionCheckInterval != nil {
+ tunnel.SessionCheckInterval = c.options.SessionCheckInterval.Build()
+ }
+ if c.options.IdleTimeout != nil {
+ tunnel.IdleTimeout = c.options.IdleTimeout.Build()
+ }
+ if c.options.KeepAlive != nil {
+ tunnel.KeepAlive = c.options.KeepAlive.Build()
+ }
+ if c.options.HandshakeTimeout != nil {
+ tunnel.HandshakeTimeout = c.options.HandshakeTimeout.Build()
+ }
+
+ if err := tunnel.InitiateResolverConnection(); err != nil {
+ return nil, fmt.Errorf("failed to initiate connection to resolver: %w", err)
+ }
+
+ if err := tunnel.InitiateDNSPacketConn(tServer.Addr); err != nil {
+ return nil, fmt.Errorf("failed to initiate DNS packet connection: %w", err)
+ }
+
+ // c.logger.DebugContext(c.ctx, "effective MTU %d", tServer.MTU)
+
+ if err := tunnel.InitiateKCPConn(tServer.MTU); err != nil {
+ return nil, fmt.Errorf("failed to initiate KCP connection: %w", err)
+ }
+
+ // c.logger.DebugContext(c.ctx, "established KCP conn")
+ if err := tunnel.InitiateNoiseChannel(); err != nil {
+ // c.logger.WarnContext(c.ctx, "failed to establish Noise channel: %v", err)
+ return nil, fmt.Errorf("failed to initiate noise channel: %w", err)
+ }
+
+ // c.logger.DebugContext(c.ctx, "established Noise channel")
+
+ if err := tunnel.InitiateSmuxSession(); err != nil {
+ return nil, fmt.Errorf("failed to initiate smux session: %w", err)
+ }
+ // c.logger.DebugContext(c.ctx, "established smux session")
+ return tunnel, nil
+}
diff --git a/protocol/hiddify/dnstt/outbound.go b/protocol/hiddify/dnstt/outbound.go
new file mode 100644
index 0000000000..1715554936
--- /dev/null
+++ b/protocol/hiddify/dnstt/outbound.go
@@ -0,0 +1,179 @@
+package dnstt
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "sync"
+ "time"
+
+ multidns "github.com/hiddify/hmrd_multi_resolver_dns"
+ dnstt "github.com/net2share/vaydns/client"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json/badoption"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/uot"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.DnsttOptions](registry, C.TypeDNSTT, NewOutbound)
+ loadResolvers()
+}
+
+var _ adapter.Outbound = (*Outbound)(nil)
+
+type Outbound struct {
+ outbound.Adapter
+ dnsRouter adapter.DNSRouter
+ logger logger.ContextLogger
+ ctx context.Context
+
+ candidateResolvers []ResolverS
+ resolvers []dnstt.Resolver
+ tunnels []*dnstt.Tunnel
+ mutlitunnel *dnstt.Tunnel
+ mu sync.Mutex
+ cache adapter.CacheFile
+ uotClient *uot.Client
+ started int
+ resolve bool
+ tunnel_index int
+
+ mdMgr *multidns.Manager // smart pool, set when options.SmartPool
+
+ options option.DnsttOptions
+}
+
+func (c *Outbound) PreStart() error {
+ c.cache = service.FromContext[adapter.CacheFile](c.ctx)
+ return nil
+}
+
+func (h *Outbound) PostStart() error {
+ go h.startTestResolver()
+ return nil
+}
+
+func initDuration(d *badoption.Duration, defultDuration time.Duration) time.Duration {
+ b := d.Build()
+ if b <= 0 {
+ return defultDuration
+ }
+ return b
+}
+
+func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.DnsttOptions) (adapter.Outbound, error) {
+
+ // if options.TunnelPerResolver <= 0 {
+ // options.TunnelPerResolver = 4
+ // }
+
+ resolvers, err := getConfigResolvers(options)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(resolvers) == 0 {
+ return nil, E.New("at least one resolver is required")
+ }
+ if options.RecordType == "" {
+ options.RecordType = "txt"
+ }
+ if options.PublicKey == "" {
+ return nil, E.New("public key is required")
+ }
+
+ if options.Domain == "" {
+ return nil, E.New("domain is required")
+ }
+ if options.PreTestRecordType == "" {
+ options.PreTestRecordType = "a"
+ }
+ if options.PreTestDomain == "" {
+ options.PreTestDomain = "www.google.com"
+ }
+
+ out := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeDNSTT, tag, []string{N.NetworkTCP}, options.DialerOptions),
+ ctx: ctx,
+ logger: logger,
+
+ candidateResolvers: resolvers,
+ resolvers: make([]dnstt.Resolver, 0),
+ tunnels: make([]*dnstt.Tunnel, 0),
+
+ options: options,
+ }
+
+ if options.SmartPool {
+ mgr, addr, err := multidns.StartLocal(multidns.Options{})
+ if err != nil {
+ return nil, err
+ }
+ out.mdMgr = mgr
+ out.resolvers = []dnstt.Resolver{{ResolverType: dnstt.ResolverTypeUDP, ResolverAddr: addr}}
+ out.tunnels = []*dnstt.Tunnel{nil}
+ logger.InfoContext(ctx, "dnstt smart_pool listening on ", addr)
+ }
+
+ return out, nil
+
+}
+
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if !h.IsReady() {
+ return nil, E.New("outbound is not started")
+ }
+ if h.options.SingleResolver {
+ return h.OpenStreamSingleResolver(ctx)
+ }
+ return h.OpenStream(ctx)
+}
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ if !h.IsReady() {
+ return nil, E.New("outbound is not started")
+ }
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = h.Tag()
+ metadata.Destination = destination
+ if h.uotClient != nil {
+ h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
+ return h.uotClient.ListenPacket(ctx, destination)
+ }
+ return nil, E.New("UoT is not enabled for this outbound")
+}
+
+func (c *Outbound) IsReady() bool {
+ return c.started > 0
+}
+func (w *Outbound) DisplayType() string {
+ str := C.ProxyDisplayName(w.Type())
+ if w.started == 0 {
+ str += " ⚠️ Connecting..."
+ } else if w.started < 0 {
+ str += " ❌ Failed!"
+ } else {
+ str += fmt.Sprint(" ✔️ ", len(w.resolvers), " resolvers")
+ }
+ return str
+}
+
+func (c *Outbound) Close() error {
+ for _, t := range c.tunnels {
+ if t != nil {
+ t.Close()
+ }
+ }
+ if c.mdMgr != nil {
+ _ = c.mdMgr.Close()
+ }
+ return nil
+}
diff --git a/protocol/hiddify/dnstt/resolvers_by_country.json b/protocol/hiddify/dnstt/resolvers_by_country.json
new file mode 100644
index 0000000000..6c051612d3
--- /dev/null
+++ b/protocol/hiddify/dnstt/resolvers_by_country.json
@@ -0,0 +1,58696 @@
+{
+ "": [
+ "1.1.1.1",
+ "1.0.0.1",
+ "208.67.222.222",
+ "9.9.9.9",
+ "1.1.1.2",
+ "1.0.0.2",
+ "1.1.1.3",
+ "1.0.0.3",
+ "76.76.20.0",
+ "192.168.1.1",
+ "127.0.0.1"
+ ],
+ "AE": [
+ "94.183.150.73",
+ "94.183.150.75",
+ "94.183.150.115",
+ "94.183.150.229",
+ "94.183.162.195",
+ "94.183.164.37",
+ "94.183.164.49",
+ "94.183.172.174",
+ "94.183.172.182",
+ "94.183.173.6",
+ "94.183.175.157",
+ "185.215.234.253",
+ "194.146.239.49",
+ "194.146.239.72",
+ "194.146.239.73",
+ "217.60.255.67",
+ "217.60.255.231",
+ "217.60.255.233",
+ "217.60.255.234",
+ "217.60.255.235",
+ "217.60.255.236",
+ "217.60.255.237",
+ "217.60.255.238",
+ "94.183.150.71",
+ "94.183.150.80",
+ "94.183.150.85",
+ "94.183.150.86",
+ "94.183.150.122",
+ "94.183.162.8",
+ "94.183.172.3",
+ "94.183.172.103",
+ "94.183.172.253",
+ "94.183.175.24",
+ "94.183.175.25",
+ "138.128.224.53",
+ "138.128.225.53",
+ "185.215.235.253",
+ "194.146.239.28",
+ "194.146.239.32",
+ "194.146.239.35",
+ "194.146.239.39",
+ "194.146.239.40",
+ "194.146.239.41",
+ "194.146.239.44",
+ "194.146.239.57",
+ "194.146.239.58",
+ "194.146.239.60",
+ "194.146.239.65",
+ "194.146.239.68",
+ "194.146.239.70",
+ "194.146.239.77",
+ "194.146.239.78",
+ "194.146.239.79",
+ "194.146.239.111",
+ "194.146.239.124",
+ "194.146.239.154",
+ "194.146.239.155",
+ "194.146.239.165",
+ "194.146.239.171",
+ "194.146.239.173",
+ "194.146.239.178",
+ "194.146.239.194",
+ "194.146.239.197",
+ "194.146.239.200",
+ "217.60.15.187",
+ "217.60.236.60",
+ "80.244.11.2",
+ "94.183.172.67"
+ ],
+ "AF": [
+ "45.65.59.201",
+ "58.147.146.146",
+ "103.46.211.146",
+ "103.53.18.115",
+ "103.53.19.201",
+ "103.53.25.216",
+ "103.53.27.90",
+ "103.53.27.208",
+ "103.213.107.241",
+ "116.204.242.61",
+ "116.204.242.63",
+ "149.54.11.98",
+ "149.54.64.118",
+ "160.187.18.5",
+ "165.101.26.38",
+ "180.94.70.74",
+ "180.94.91.170",
+ "45.65.59.252"
+ ],
+ "AU": [
+ "94.103.125.157",
+ "94.103.125.158",
+ "45.86.87.148",
+ "45.86.87.186",
+ "45.86.87.227",
+ "87.236.166.3",
+ "188.253.2.67",
+ "188.253.2.115",
+ "188.253.2.147",
+ "188.253.2.210",
+ "188.253.2.241",
+ "188.253.2.250",
+ "188.253.3.136",
+ "188.253.3.185",
+ "45.86.87.11",
+ "45.86.87.150",
+ "45.86.87.242",
+ "87.236.166.137",
+ "185.129.111.248",
+ "188.253.2.6",
+ "188.253.2.16",
+ "188.253.2.19",
+ "188.253.2.22",
+ "188.253.2.24",
+ "188.253.2.25",
+ "188.253.2.30",
+ "188.253.2.31",
+ "188.253.2.33",
+ "188.253.2.37",
+ "188.253.2.38",
+ "188.253.2.42",
+ "188.253.2.50",
+ "188.253.2.52",
+ "188.253.2.53",
+ "188.253.2.56",
+ "188.253.2.57",
+ "188.253.2.58",
+ "188.253.2.63",
+ "188.253.2.64",
+ "188.253.2.65",
+ "188.253.2.68",
+ "188.253.2.70",
+ "188.253.2.76",
+ "188.253.2.79",
+ "188.253.2.85",
+ "188.253.2.88",
+ "188.253.2.92",
+ "188.253.2.95",
+ "188.253.2.98",
+ "188.253.2.99",
+ "188.253.2.112",
+ "188.253.2.120",
+ "188.253.2.122",
+ "188.253.2.123",
+ "188.253.2.124",
+ "188.253.2.125",
+ "188.253.2.136",
+ "188.253.2.138",
+ "188.253.2.146",
+ "188.253.2.150",
+ "188.253.2.156",
+ "188.253.2.165",
+ "188.253.2.166",
+ "188.253.2.171",
+ "188.253.2.174",
+ "188.253.2.180",
+ "188.253.2.184",
+ "188.253.2.186",
+ "188.253.2.188",
+ "188.253.2.189",
+ "188.253.2.191",
+ "188.253.2.198",
+ "188.253.2.200",
+ "188.253.2.206",
+ "188.253.2.207",
+ "188.253.2.211",
+ "188.253.2.214",
+ "188.253.2.220",
+ "188.253.2.245",
+ "188.253.2.248",
+ "188.253.2.249",
+ "188.253.2.251",
+ "188.253.3.7",
+ "188.253.3.17",
+ "188.253.3.18",
+ "188.253.3.34",
+ "188.253.3.35",
+ "188.253.3.37",
+ "188.253.3.38",
+ "188.253.3.39",
+ "188.253.3.43",
+ "188.253.3.50",
+ "188.253.3.54",
+ "188.253.3.59",
+ "188.253.3.60",
+ "188.253.3.61",
+ "188.253.3.69",
+ "188.253.3.74",
+ "188.253.3.77",
+ "188.253.3.78",
+ "188.253.3.79",
+ "188.253.3.89",
+ "188.253.3.104",
+ "188.253.3.124",
+ "188.253.3.125",
+ "188.253.3.127",
+ "188.253.3.130",
+ "188.253.3.137",
+ "188.253.3.148",
+ "188.253.3.149",
+ "188.253.3.188",
+ "188.253.3.194",
+ "188.253.3.195",
+ "188.253.3.196",
+ "188.253.3.197",
+ "188.253.3.198",
+ "188.253.3.226",
+ "188.253.3.250"
+ ],
+ "BF": [
+ "102.23.5.166",
+ "102.23.7.83"
+ ],
+ "BG": [
+ "185.82.216.236"
+ ],
+ "BR": [
+ "167.234.255.2"
+ ],
+ "CA": [
+ "76.76.2.0",
+ "76.76.10.0"
+ ],
+ "CH": [
+ "89.32.250.1",
+ "89.32.250.6",
+ "89.32.250.33",
+ "89.32.250.39",
+ "89.32.250.65",
+ "89.32.250.77",
+ "89.32.250.129",
+ "89.32.250.161",
+ "89.32.250.177",
+ "89.32.250.193",
+ "89.32.250.223",
+ "89.32.250.7",
+ "89.32.250.14",
+ "89.32.250.18",
+ "89.32.250.20",
+ "89.32.250.21",
+ "89.32.250.22",
+ "89.32.250.26",
+ "89.32.250.28",
+ "89.32.250.45",
+ "89.32.250.51",
+ "89.32.250.52",
+ "89.32.250.58",
+ "89.32.250.60",
+ "89.32.250.66",
+ "89.32.250.68",
+ "89.32.250.69",
+ "89.32.250.71",
+ "89.32.250.74",
+ "89.32.250.75",
+ "89.32.250.79",
+ "89.32.250.82",
+ "89.32.250.104",
+ "89.32.250.109",
+ "89.32.250.117",
+ "89.32.250.118",
+ "89.32.250.156",
+ "89.32.250.162",
+ "89.32.250.163",
+ "89.32.250.164",
+ "89.32.250.165",
+ "89.32.250.166",
+ "89.32.250.167",
+ "89.32.250.168",
+ "89.32.250.169",
+ "89.32.250.170",
+ "89.32.250.171",
+ "89.32.250.172",
+ "89.32.250.173",
+ "89.32.250.174",
+ "89.32.250.178",
+ "89.32.250.179",
+ "89.32.250.180",
+ "89.32.250.182",
+ "89.32.250.184",
+ "89.32.250.185",
+ "89.32.250.190",
+ "89.32.250.202",
+ "89.32.250.204",
+ "89.32.250.207",
+ "89.32.250.209",
+ "89.32.250.211",
+ "89.32.250.214",
+ "89.32.250.215",
+ "89.32.250.219",
+ "89.32.250.222",
+ "89.32.250.225",
+ "89.32.250.226",
+ "89.32.250.227",
+ "89.32.250.228",
+ "89.32.250.232",
+ "89.32.250.234",
+ "89.32.250.236",
+ "89.32.250.239",
+ "89.32.250.240",
+ "89.32.250.246",
+ "89.32.250.248",
+ "89.32.250.253",
+ "89.32.250.254"
+ ],
+ "CN": [
+ "223.5.5.5",
+ "223.6.6.6",
+ "180.76.76.76",
+ "119.29.29.29"
+ ],
+ "CY": [
+ "94.140.14.14",
+ "94.140.15.15",
+ "94.140.14.15",
+ "94.140.15.16",
+ "94.140.14.140",
+ "94.140.14.141"
+ ],
+ "DE": [
+ "84.200.69.80",
+ "84.200.70.40",
+ "168.119.88.234"
+ ],
+ "DK": [
+ "194.255.152.10",
+ "194.255.62.80",
+ "91.247.174.1"
+ ],
+ "ES": [
+ "109.69.8.51"
+ ],
+ "FI": [
+ "95.216.224.204",
+ "95.216.224.214",
+ "95.216.224.227",
+ "95.216.224.232",
+ "95.216.224.245"
+ ],
+ "FR": [
+ "163.172.141.219"
+ ],
+ "GB": [
+ "82.102.14.39",
+ "82.102.14.248",
+ "89.34.96.30",
+ "89.34.96.77",
+ "89.34.96.86",
+ "89.34.96.87",
+ "89.34.96.88",
+ "89.34.96.89",
+ "89.34.96.90",
+ "89.34.96.91",
+ "89.34.96.92",
+ "89.34.96.93",
+ "89.34.96.94",
+ "89.34.96.95",
+ "89.34.96.100",
+ "89.34.96.101",
+ "89.34.96.102",
+ "89.34.96.103",
+ "89.34.96.104",
+ "89.34.96.105",
+ "89.34.96.106",
+ "89.34.96.117",
+ "89.34.96.146",
+ "89.34.97.70",
+ "193.107.44.16",
+ "193.107.44.19",
+ "193.107.44.25",
+ "193.107.44.61",
+ "89.34.96.78",
+ "82.102.14.4",
+ "82.102.14.35",
+ "82.102.14.50",
+ "82.102.15.90",
+ "82.102.15.91",
+ "82.102.15.92",
+ "82.102.15.93",
+ "82.102.15.94",
+ "82.102.15.210",
+ "89.34.96.13",
+ "89.34.96.110",
+ "89.34.96.111",
+ "89.34.96.112",
+ "89.34.96.131",
+ "89.34.96.134",
+ "89.34.96.142",
+ "89.34.96.145",
+ "89.34.96.148",
+ "89.34.97.21"
+ ],
+ "GH": [
+ "102.22.27.125",
+ "102.22.31.74"
+ ],
+ "IR": [
+ "185.181.182.209",
+ "178.22.122.100",
+ "185.51.200.2",
+ "78.157.42.100",
+ "78.157.42.101",
+ "217.218.26.77",
+ "217.218.26.78",
+ "185.55.226.26",
+ "185.55.225.25",
+ "2.144.4.108",
+ "2.144.6.246",
+ "2.144.6.65",
+ "2.144.4.118",
+ "2.144.7.149",
+ "2.144.20.74",
+ "2.144.20.109",
+ "2.144.20.202",
+ "2.184.239.88",
+ "2.184.239.156",
+ "5.160.12.250",
+ "46.245.90.90",
+ "82.99.213.58",
+ "82.99.213.59",
+ "82.99.213.60",
+ "82.99.213.61",
+ "82.99.214.108",
+ "91.92.208.152",
+ "94.183.52.42",
+ "185.49.84.2",
+ "185.164.74.183",
+ "2.144.4.190",
+ "2.144.5.46",
+ "2.144.5.118",
+ "2.144.20.86",
+ "2.144.22.69",
+ "2.144.23.51",
+ "2.144.23.148",
+ "2.144.235.30",
+ "176.65.231.61",
+ "185.129.118.121",
+ "193.228.136.129",
+ "5.202.255.21",
+ "5.198.178.125",
+ "91.106.67.82",
+ "37.202.225.169",
+ "45.156.185.200",
+ "45.159.150.51",
+ "37.202.225.166",
+ "37.235.17.243",
+ "45.90.74.47",
+ "45.92.95.140",
+ "45.138.132.115",
+ "46.34.165.142",
+ "37.235.17.247",
+ "37.255.138.19",
+ "45.9.255.21",
+ "45.9.255.22",
+ "45.92.93.203",
+ "45.149.77.242",
+ "45.159.150.210",
+ "37.202.225.236",
+ "45.149.79.172",
+ "37.202.225.168",
+ "37.202.237.245",
+ "37.235.17.245",
+ "37.255.219.35",
+ "45.89.139.14",
+ "45.129.38.78",
+ "45.139.11.210",
+ "45.149.77.44",
+ "45.149.79.226",
+ "45.156.185.106",
+ "45.159.150.50",
+ "46.34.162.68",
+ "46.34.163.38",
+ "46.34.165.238",
+ "37.202.186.74",
+ "45.142.191.135",
+ "45.142.191.136",
+ "46.167.142.120",
+ "37.202.155.171",
+ "45.129.39.7",
+ "45.129.39.4",
+ "45.129.39.3",
+ "45.9.145.10",
+ "45.129.39.2",
+ "46.38.138.173",
+ "46.100.12.186",
+ "37.255.231.201",
+ "45.94.214.12",
+ "46.100.13.158",
+ "46.100.5.135",
+ "46.148.41.105",
+ "46.100.94.168",
+ "46.100.95.195",
+ "46.100.11.49",
+ "37.202.156.90",
+ "45.142.191.5",
+ "46.100.62.206",
+ "37.202.237.244",
+ "46.100.52.106",
+ "37.202.180.163",
+ "31.214.251.4",
+ "31.214.251.31",
+ "37.152.181.98",
+ "37.191.85.6",
+ "31.7.133.3",
+ "31.7.133.2",
+ "31.14.117.209",
+ "31.214.174.104",
+ "31.214.174.105",
+ "31.214.251.33",
+ "31.214.251.36",
+ "31.214.251.34",
+ "31.214.251.47",
+ "31.214.251.50",
+ "31.14.117.201",
+ "31.14.117.208",
+ "31.25.91.67",
+ "31.214.168.234",
+ "31.214.170.66",
+ "31.214.170.254",
+ "31.214.174.102",
+ "31.214.174.103",
+ "31.214.174.113",
+ "31.214.251.29",
+ "31.214.251.39",
+ "31.214.251.44",
+ "31.214.251.45",
+ "31.214.251.53",
+ "31.214.251.55",
+ "31.214.251.59",
+ "31.214.251.58",
+ "37.32.13.229",
+ "37.114.204.82",
+ "37.156.144.92",
+ "31.47.33.58",
+ "31.214.168.82",
+ "37.191.95.34",
+ "31.214.174.106",
+ "37.191.95.45",
+ "31.47.46.77",
+ "31.47.46.78",
+ "37.156.31.94",
+ "31.7.70.68",
+ "37.148.82.26",
+ "37.63.247.9",
+ "31.130.181.233",
+ "37.148.85.9",
+ "37.148.57.40",
+ "37.156.144.69",
+ "37.148.51.30",
+ "193.228.90.34",
+ "185.140.58.2",
+ "89.45.89.250",
+ "185.165.30.119",
+ "5.233.205.183",
+ "2.144.3.168",
+ "2.144.3.169",
+ "2.144.3.170",
+ "2.144.3.171",
+ "2.144.3.172",
+ "2.144.3.173",
+ "2.144.4.8",
+ "2.144.4.62",
+ "2.144.4.217",
+ "2.144.5.81",
+ "2.144.5.181",
+ "2.144.5.198",
+ "2.144.6.46",
+ "2.144.7.26",
+ "2.144.7.218",
+ "2.144.7.238",
+ "2.144.20.5",
+ "2.144.20.45",
+ "2.144.20.224",
+ "2.144.21.68",
+ "2.144.21.92",
+ "2.144.21.255",
+ "2.144.22.135",
+ "2.144.198.225",
+ "2.144.231.18",
+ "2.144.233.119",
+ "2.144.245.252",
+ "2.144.247.168",
+ "2.176.71.248",
+ "2.176.144.65",
+ "2.176.160.155",
+ "2.176.161.158",
+ "2.176.163.232",
+ "2.176.195.20",
+ "2.176.195.71",
+ "2.176.196.108",
+ "2.176.203.68",
+ "2.176.205.191",
+ "2.176.207.244",
+ "2.176.209.116",
+ "2.176.211.93",
+ "2.176.219.184",
+ "2.176.219.209",
+ "2.176.220.2",
+ "2.176.231.32",
+ "2.176.232.109",
+ "2.176.235.135",
+ "2.176.240.121",
+ "2.176.246.138",
+ "2.176.247.23",
+ "2.176.250.23",
+ "2.176.254.199",
+ "2.176.255.78",
+ "2.177.7.74",
+ "2.177.11.130",
+ "2.177.14.161",
+ "2.177.24.181",
+ "2.177.40.63",
+ "2.177.42.167",
+ "2.177.42.212",
+ "2.177.43.58",
+ "2.177.48.90",
+ "2.177.50.76",
+ "2.177.54.179",
+ "2.177.58.132",
+ "2.177.58.155",
+ "2.177.69.242",
+ "2.177.73.160",
+ "2.177.73.244",
+ "2.177.78.104",
+ "2.177.80.237",
+ "2.177.85.200",
+ "2.177.96.175",
+ "2.177.99.77",
+ "2.177.109.173",
+ "2.177.113.28",
+ "2.177.117.230",
+ "2.177.118.189",
+ "2.177.120.14",
+ "2.177.121.187",
+ "2.177.126.254",
+ "2.177.129.176",
+ "2.177.133.217",
+ "2.177.135.111",
+ "2.177.139.223",
+ "2.177.140.35",
+ "2.177.152.158",
+ "2.177.153.109",
+ "2.177.155.185",
+ "2.177.155.224",
+ "2.177.156.192",
+ "2.177.158.73",
+ "2.177.158.225",
+ "2.177.160.55",
+ "2.177.164.229",
+ "2.177.167.83",
+ "2.177.167.170",
+ "2.177.173.66",
+ "2.177.173.87",
+ "2.177.173.176",
+ "2.177.175.244",
+ "2.177.178.196",
+ "2.177.183.65",
+ "2.177.184.11",
+ "2.177.187.16",
+ "2.177.188.230",
+ "2.177.189.84",
+ "2.177.190.2",
+ "2.177.192.190",
+ "2.177.192.231",
+ "2.177.195.151",
+ "2.177.196.211",
+ "2.177.197.243",
+ "2.177.198.2",
+ "2.177.198.159",
+ "2.177.204.158",
+ "2.177.204.186",
+ "2.177.207.115",
+ "2.177.213.224",
+ "2.177.218.47",
+ "2.177.220.95",
+ "2.177.224.244",
+ "2.177.228.67",
+ "2.177.230.80",
+ "2.177.237.182",
+ "2.177.238.79",
+ "2.177.239.150",
+ "2.177.240.88",
+ "2.177.242.177",
+ "2.177.244.70",
+ "2.177.245.77",
+ "2.177.253.11",
+ "2.177.254.249",
+ "2.177.255.131",
+ "2.178.0.24",
+ "2.178.3.70",
+ "2.178.4.229",
+ "2.178.11.34",
+ "2.178.11.72",
+ "2.178.11.159",
+ "2.178.11.241",
+ "2.178.15.78",
+ "2.178.15.130",
+ "2.178.22.53",
+ "2.178.22.146",
+ "2.178.26.116",
+ "2.178.26.206",
+ "2.178.33.222",
+ "2.178.36.242",
+ "2.178.46.42",
+ "2.178.49.12",
+ "2.178.53.205",
+ "2.178.61.247",
+ "2.178.63.103",
+ "2.178.66.121",
+ "2.178.66.138",
+ "2.178.68.58",
+ "2.178.85.219",
+ "2.178.98.210",
+ "2.178.99.108",
+ "2.178.104.149",
+ "2.178.105.198",
+ "2.178.106.212",
+ "2.178.107.246",
+ "2.178.111.223",
+ "2.178.111.228",
+ "2.178.114.218",
+ "2.178.126.27",
+ "2.178.139.88",
+ "2.178.160.42",
+ "2.178.173.175",
+ "2.178.206.242",
+ "2.178.212.180",
+ "2.178.218.239",
+ "2.178.225.41",
+ "2.178.225.46",
+ "2.178.240.181",
+ "2.178.244.156",
+ "2.178.245.219",
+ "2.179.17.46",
+ "2.179.73.249",
+ "2.179.73.252",
+ "2.179.164.1",
+ "2.179.164.17",
+ "2.179.164.92",
+ "2.179.164.245",
+ "2.179.165.2",
+ "2.179.165.108",
+ "2.179.166.51",
+ "2.179.166.119",
+ "2.179.186.165",
+ "2.179.186.244",
+ "2.179.194.7",
+ "2.179.223.63",
+ "2.179.245.7",
+ "2.180.0.27",
+ "2.180.1.139",
+ "2.180.1.157",
+ "2.180.2.5",
+ "2.180.2.12",
+ "2.180.2.71",
+ "2.180.2.175",
+ "2.180.2.188",
+ "2.180.3.42",
+ "2.180.7.125",
+ "2.180.7.222",
+ "2.180.7.223",
+ "2.180.8.148",
+ "2.180.10.251",
+ "2.180.17.150",
+ "2.180.17.221",
+ "2.180.18.173",
+ "2.180.18.229",
+ "2.180.19.225",
+ "2.180.25.216",
+ "2.180.26.219",
+ "2.180.29.30",
+ "2.180.30.57",
+ "2.180.30.220",
+ "2.180.34.26",
+ "2.180.34.44",
+ "2.180.35.82",
+ "2.180.35.201",
+ "2.180.36.215",
+ "2.180.39.20",
+ "2.180.39.22",
+ "2.180.39.66",
+ "2.180.39.68",
+ "2.180.40.1",
+ "2.180.40.107",
+ "2.180.42.106",
+ "2.180.47.240",
+ "2.180.140.252",
+ "2.180.142.22",
+ "2.180.145.231",
+ "2.180.189.202",
+ "2.180.201.34",
+ "2.180.215.30",
+ "2.181.30.33",
+ "2.181.30.174",
+ "2.181.30.231",
+ "2.181.34.93",
+ "2.181.80.30",
+ "2.181.87.86",
+ "2.181.105.236",
+ "2.181.129.197",
+ "2.181.195.225",
+ "2.181.222.226",
+ "2.181.234.50",
+ "2.181.235.121",
+ "2.181.247.240",
+ "2.182.99.67",
+ "2.182.109.129",
+ "2.182.113.73",
+ "2.182.128.170",
+ "2.182.152.99",
+ "2.182.154.64",
+ "2.182.177.35",
+ "2.182.189.113",
+ "2.182.190.52",
+ "2.182.194.1",
+ "2.182.195.57",
+ "2.182.213.73",
+ "2.182.214.11",
+ "2.182.214.126",
+ "2.182.240.134",
+ "2.182.242.139",
+ "2.182.250.30",
+ "2.182.250.161",
+ "2.182.253.245",
+ "2.182.253.246",
+ "2.182.253.247",
+ "2.183.8.180",
+ "2.183.9.108",
+ "2.183.9.110",
+ "2.183.32.15",
+ "2.183.32.109",
+ "2.183.32.232",
+ "2.183.95.185",
+ "2.183.230.24",
+ "2.184.30.252",
+ "2.184.48.1",
+ "2.184.49.134",
+ "2.184.50.11",
+ "2.184.70.68",
+ "2.184.90.186",
+ "2.184.112.150",
+ "2.184.155.75",
+ "2.184.236.106",
+ "2.184.236.142",
+ "2.144.2.8",
+ "2.144.2.44",
+ "2.144.2.154",
+ "2.144.2.247",
+ "2.144.4.30",
+ "2.144.4.154",
+ "2.144.4.254",
+ "2.144.5.135",
+ "2.144.5.186",
+ "2.144.5.213",
+ "2.144.5.245",
+ "2.144.6.10",
+ "2.144.6.48",
+ "2.144.6.59",
+ "2.144.6.112",
+ "2.144.6.117",
+ "2.144.6.207",
+ "2.144.7.9",
+ "2.144.7.68",
+ "2.144.7.173",
+ "2.144.13.3",
+ "2.144.13.6",
+ "2.144.14.3",
+ "2.144.20.143",
+ "2.144.20.147",
+ "2.144.20.183",
+ "2.144.20.212",
+ "2.144.21.62",
+ "2.144.21.115",
+ "2.144.21.158",
+ "2.144.21.219",
+ "2.144.22.71",
+ "2.144.22.101",
+ "2.144.22.157",
+ "2.144.22.188",
+ "2.144.22.255",
+ "2.144.23.53",
+ "2.144.23.191",
+ "2.144.23.215",
+ "2.144.23.228",
+ "2.144.24.5",
+ "2.144.129.104",
+ "2.144.129.133",
+ "2.144.129.158",
+ "2.144.129.253",
+ "2.144.198.195",
+ "2.144.198.207",
+ "2.144.198.234",
+ "2.144.198.236",
+ "2.144.198.241",
+ "2.144.198.242",
+ "2.144.198.247",
+ "2.144.230.61",
+ "2.144.230.211",
+ "2.144.231.46",
+ "2.144.231.53",
+ "2.144.231.66",
+ "2.144.231.70",
+ "2.144.231.71",
+ "2.144.231.102",
+ "2.144.231.135",
+ "2.144.231.136",
+ "2.144.231.137",
+ "2.144.231.142",
+ "2.144.231.144",
+ "2.144.231.145",
+ "2.144.231.155",
+ "2.144.231.160",
+ "2.144.231.161",
+ "2.144.231.162",
+ "2.144.231.169",
+ "2.144.231.170",
+ "2.144.231.171",
+ "2.144.231.173",
+ "2.144.231.175",
+ "2.144.231.180",
+ "2.144.231.182",
+ "2.144.231.189",
+ "2.144.231.192",
+ "2.144.231.193",
+ "2.144.231.195",
+ "2.144.231.201",
+ "2.144.231.202",
+ "2.144.231.209",
+ "2.144.231.214",
+ "2.144.231.215",
+ "2.144.231.218",
+ "2.144.231.223",
+ "2.144.231.225",
+ "2.144.231.228",
+ "2.144.231.233",
+ "2.144.231.235",
+ "2.144.231.239",
+ "2.144.231.243",
+ "2.144.231.245",
+ "2.144.231.247",
+ "2.144.231.248",
+ "2.144.231.252",
+ "2.144.232.8",
+ "2.144.232.15",
+ "2.144.232.24",
+ "2.144.232.29",
+ "2.144.232.33",
+ "2.144.232.35",
+ "2.144.232.36",
+ "2.144.232.38",
+ "2.144.232.49",
+ "2.144.232.50",
+ "2.144.232.51",
+ "2.144.232.56",
+ "2.144.232.59",
+ "2.144.232.66",
+ "2.144.232.68",
+ "2.144.232.69",
+ "2.144.232.78",
+ "2.144.232.80",
+ "2.144.232.83",
+ "2.144.232.89",
+ "2.144.232.90",
+ "2.144.232.99",
+ "2.144.232.100",
+ "2.144.232.104",
+ "2.144.232.108",
+ "2.144.232.111",
+ "2.144.232.112",
+ "2.144.232.115",
+ "2.144.232.120",
+ "2.144.232.123",
+ "2.144.232.125",
+ "2.144.232.126",
+ "2.144.232.127",
+ "2.144.232.129",
+ "2.144.232.130",
+ "2.144.232.131",
+ "2.144.232.134",
+ "2.144.232.136",
+ "2.144.232.141",
+ "2.144.232.147",
+ "2.144.232.148",
+ "2.144.232.154",
+ "2.144.232.156",
+ "2.144.232.161",
+ "2.144.232.162",
+ "2.144.232.163",
+ "2.144.232.164",
+ "2.144.232.165",
+ "2.144.232.169",
+ "2.144.232.171",
+ "2.144.232.173",
+ "2.144.232.177",
+ "2.144.232.180",
+ "2.144.232.181",
+ "2.144.232.184",
+ "2.144.232.189",
+ "2.144.232.191",
+ "2.144.232.192",
+ "2.144.232.196",
+ "2.144.232.203",
+ "2.144.232.205",
+ "2.144.232.207",
+ "2.144.232.210",
+ "2.144.232.211",
+ "2.144.232.214",
+ "2.144.232.217",
+ "2.144.232.219",
+ "2.144.232.224",
+ "2.144.233.26",
+ "2.144.233.30",
+ "2.144.233.40",
+ "2.144.233.86",
+ "2.144.233.148",
+ "2.144.233.171",
+ "2.144.233.235",
+ "2.144.234.42",
+ "2.144.234.53",
+ "2.144.234.66",
+ "2.144.234.75",
+ "2.144.234.92",
+ "2.144.234.97",
+ "2.144.234.100",
+ "2.144.234.101",
+ "2.144.234.102",
+ "2.144.234.104",
+ "2.144.234.117",
+ "2.144.234.123",
+ "2.144.234.129",
+ "2.144.234.130",
+ "2.144.234.133",
+ "2.144.234.136",
+ "2.144.234.144",
+ "2.144.234.145",
+ "2.144.234.146",
+ "2.144.234.151",
+ "2.144.234.152",
+ "2.144.234.155",
+ "2.144.234.157",
+ "2.144.234.209",
+ "2.144.234.211",
+ "2.144.234.213",
+ "2.144.234.214",
+ "2.144.234.219",
+ "2.144.234.222",
+ "2.144.234.225",
+ "2.144.234.226",
+ "2.144.234.228",
+ "2.144.234.231",
+ "2.144.234.235",
+ "2.144.234.237",
+ "2.144.234.241",
+ "2.144.234.245",
+ "2.144.234.247",
+ "2.144.234.248",
+ "2.144.234.252",
+ "2.144.235.16",
+ "2.144.235.25",
+ "2.144.235.35",
+ "2.144.235.39",
+ "2.144.235.161",
+ "2.144.235.197",
+ "2.144.235.217",
+ "2.144.235.219",
+ "2.144.236.205",
+ "2.144.236.245",
+ "2.144.242.34",
+ "2.144.242.62",
+ "2.144.242.77",
+ "2.144.242.84",
+ "2.144.242.95",
+ "2.144.242.123",
+ "2.144.242.130",
+ "2.144.242.148",
+ "2.144.242.199",
+ "2.144.242.225",
+ "2.144.243.33",
+ "2.144.243.35",
+ "2.144.243.66",
+ "2.144.243.76",
+ "2.144.243.86",
+ "2.144.243.92",
+ "2.144.243.108",
+ "2.144.243.109",
+ "2.144.243.120",
+ "2.144.243.160",
+ "2.144.243.161",
+ "2.144.243.162",
+ "2.144.243.167",
+ "2.144.243.191",
+ "2.144.243.192",
+ "2.144.243.200",
+ "2.144.244.18",
+ "2.144.244.27",
+ "2.144.244.29",
+ "2.144.244.30",
+ "2.144.244.31",
+ "2.144.244.32",
+ "2.144.244.34",
+ "2.144.244.35",
+ "2.144.244.56",
+ "2.144.244.60",
+ "2.144.244.66",
+ "2.144.244.68",
+ "2.144.244.70",
+ "2.144.244.72",
+ "2.144.244.73",
+ "2.144.244.78",
+ "2.144.244.80",
+ "2.144.244.81",
+ "2.144.244.99",
+ "2.144.244.121",
+ "2.144.244.144",
+ "2.144.244.148",
+ "2.144.244.150",
+ "2.144.244.151",
+ "2.144.244.152",
+ "2.144.244.153",
+ "2.144.244.159",
+ "2.144.244.223",
+ "2.144.244.233",
+ "2.144.245.0",
+ "2.144.245.3",
+ "2.144.245.15",
+ "2.144.245.38",
+ "2.144.245.42",
+ "2.144.245.60",
+ "2.144.245.61",
+ "2.144.245.62",
+ "2.144.245.66",
+ "2.144.245.115",
+ "2.144.245.119",
+ "2.144.245.120",
+ "2.144.245.123",
+ "2.144.245.127",
+ "2.144.245.130",
+ "2.144.245.132",
+ "2.144.245.148",
+ "2.144.245.149",
+ "2.144.245.154",
+ "2.144.245.166",
+ "2.144.245.167",
+ "2.144.245.198",
+ "2.144.245.213",
+ "2.144.245.222",
+ "2.144.245.230",
+ "2.144.246.1",
+ "2.144.246.22",
+ "2.144.246.50",
+ "2.144.246.86",
+ "2.144.246.103",
+ "2.144.246.106",
+ "2.144.246.119",
+ "2.144.246.147",
+ "2.144.246.185",
+ "2.144.246.187",
+ "2.144.246.191",
+ "2.144.246.202",
+ "2.144.246.215",
+ "2.144.246.226",
+ "2.144.246.243",
+ "2.144.247.14",
+ "2.144.247.21",
+ "2.144.247.29",
+ "2.144.247.30",
+ "2.144.247.34",
+ "2.144.247.35",
+ "2.144.247.42",
+ "2.144.247.45",
+ "2.144.247.47",
+ "2.144.247.63",
+ "2.144.247.66",
+ "2.144.247.87",
+ "2.144.247.93",
+ "2.144.247.97",
+ "2.144.247.118",
+ "2.144.247.119",
+ "2.144.247.121",
+ "2.144.247.123",
+ "2.144.247.137",
+ "2.144.247.139",
+ "2.144.247.140",
+ "2.144.247.150",
+ "2.144.247.155",
+ "2.144.247.159",
+ "2.144.247.161",
+ "2.144.247.165",
+ "2.144.247.169",
+ "2.144.247.172",
+ "2.144.247.176",
+ "2.144.247.182",
+ "2.144.247.185",
+ "2.144.247.186",
+ "2.144.247.190",
+ "2.144.247.203",
+ "2.144.247.211",
+ "2.144.247.212",
+ "2.144.247.216",
+ "2.144.247.220",
+ "2.144.247.224",
+ "2.144.247.230",
+ "2.144.247.232",
+ "2.144.247.249",
+ "2.144.248.188",
+ "2.144.248.199",
+ "2.144.248.200",
+ "2.144.248.203",
+ "2.144.248.206",
+ "2.144.248.213",
+ "2.144.248.214",
+ "2.144.248.219",
+ "2.144.248.220",
+ "2.144.248.225",
+ "2.144.248.231",
+ "2.144.248.240",
+ "2.144.248.245",
+ "2.144.248.247",
+ "2.144.248.249",
+ "2.144.248.250",
+ "2.144.248.252",
+ "2.144.251.3",
+ "2.144.251.13",
+ "2.144.251.16",
+ "2.144.251.24",
+ "2.144.251.27",
+ "2.144.251.28",
+ "2.176.21.37",
+ "2.176.42.197",
+ "2.176.116.115",
+ "2.176.128.221",
+ "2.176.164.158",
+ "2.176.165.86",
+ "2.176.179.96",
+ "2.176.186.208",
+ "2.176.187.204",
+ "2.176.193.184",
+ "2.176.194.24",
+ "2.176.195.168",
+ "2.176.199.217",
+ "2.176.199.235",
+ "2.176.201.99",
+ "2.176.201.140",
+ "2.176.201.253",
+ "2.176.203.2",
+ "2.176.205.132",
+ "2.176.207.56",
+ "2.176.208.46",
+ "2.176.208.115",
+ "2.176.209.124",
+ "2.176.210.22",
+ "2.176.210.236",
+ "2.176.210.237",
+ "2.176.215.134",
+ "2.176.216.158",
+ "2.176.216.171",
+ "2.176.217.52",
+ "2.176.217.132",
+ "2.176.218.194",
+ "2.176.218.207",
+ "2.176.219.211",
+ "2.176.223.64",
+ "2.176.227.61",
+ "2.176.227.118",
+ "2.176.229.49",
+ "2.176.231.99",
+ "2.176.233.44",
+ "2.176.234.103",
+ "2.176.236.16",
+ "2.176.237.172",
+ "2.176.238.81",
+ "2.176.238.83",
+ "2.176.240.89",
+ "2.176.240.209",
+ "2.176.240.211",
+ "2.176.244.253",
+ "2.176.245.66",
+ "2.176.245.244",
+ "2.176.247.16",
+ "2.176.247.47",
+ "2.176.247.227",
+ "2.176.247.255",
+ "2.176.248.53",
+ "2.176.248.234",
+ "2.176.249.176",
+ "2.176.251.27",
+ "2.176.253.225",
+ "2.176.254.139",
+ "2.177.2.85",
+ "2.177.7.84",
+ "2.177.7.167",
+ "2.177.8.203",
+ "2.177.10.196",
+ "2.177.18.29",
+ "2.177.18.92",
+ "2.177.19.1",
+ "2.177.19.79",
+ "2.177.21.69",
+ "2.177.22.188",
+ "2.177.22.195",
+ "2.177.23.80",
+ "2.177.24.139",
+ "2.177.25.36",
+ "2.177.25.129",
+ "2.177.26.95",
+ "2.177.26.178",
+ "2.177.27.105",
+ "2.177.30.145",
+ "2.177.31.65",
+ "2.177.31.242",
+ "2.177.33.173",
+ "2.177.33.254",
+ "2.177.36.221",
+ "2.177.38.76",
+ "2.177.38.200",
+ "2.177.39.71",
+ "2.177.40.221",
+ "2.177.42.135",
+ "2.177.45.39",
+ "2.177.46.233",
+ "2.177.47.128",
+ "2.177.47.205",
+ "2.177.48.53",
+ "2.177.48.70",
+ "2.177.48.192",
+ "2.177.51.59",
+ "2.177.51.245",
+ "2.177.52.43",
+ "2.177.55.195",
+ "2.177.55.198",
+ "2.177.56.85",
+ "2.177.58.211",
+ "2.177.62.61",
+ "2.177.62.221",
+ "2.177.64.71",
+ "2.177.64.82",
+ "2.177.65.14",
+ "2.177.65.66",
+ "2.177.65.254",
+ "2.177.67.231",
+ "2.177.68.185",
+ "2.177.70.244",
+ "2.177.71.230",
+ "2.177.72.52",
+ "2.177.72.131",
+ "2.177.73.76",
+ "2.177.75.187",
+ "2.177.75.194",
+ "2.177.76.190",
+ "2.177.77.190",
+ "2.177.78.6",
+ "2.177.78.148",
+ "2.177.81.249",
+ "2.177.82.206",
+ "2.177.84.66",
+ "2.177.87.45",
+ "2.177.88.165",
+ "2.177.90.31",
+ "2.177.92.10",
+ "2.177.95.83",
+ "2.177.97.83",
+ "2.177.98.42",
+ "2.177.98.52",
+ "2.177.98.214",
+ "2.177.99.87",
+ "2.177.100.151",
+ "2.177.101.8",
+ "2.177.102.12",
+ "2.177.102.121",
+ "2.177.102.148",
+ "2.177.103.111",
+ "2.177.107.148",
+ "2.177.108.101",
+ "2.177.108.169",
+ "2.177.109.68",
+ "2.177.109.178",
+ "2.177.112.192",
+ "2.177.113.92",
+ "2.177.113.104",
+ "2.177.113.173",
+ "2.177.114.42",
+ "2.177.114.204",
+ "2.177.120.54",
+ "2.177.121.153",
+ "2.177.122.60",
+ "2.177.123.165",
+ "2.177.123.175",
+ "2.177.123.252",
+ "2.177.124.28",
+ "2.177.130.168",
+ "2.177.130.178",
+ "2.177.134.5",
+ "2.177.134.191",
+ "2.177.135.165",
+ "2.177.136.126",
+ "2.177.137.84",
+ "2.177.137.129",
+ "2.177.140.135",
+ "2.177.142.153",
+ "2.177.143.48",
+ "2.177.147.178",
+ "2.177.150.223",
+ "2.177.151.90",
+ "2.177.154.37",
+ "2.177.154.43",
+ "2.177.154.63",
+ "2.177.155.21",
+ "2.177.155.108",
+ "2.177.156.85",
+ "2.177.156.95",
+ "2.177.158.139",
+ "2.177.160.149",
+ "2.177.161.136",
+ "2.177.161.194",
+ "2.177.162.138",
+ "2.177.163.42",
+ "2.177.165.215",
+ "2.177.167.30",
+ "2.177.167.187",
+ "2.177.170.148",
+ "2.177.174.202",
+ "2.177.179.197",
+ "2.177.179.238",
+ "2.177.181.250",
+ "2.177.183.104",
+ "2.177.184.244",
+ "2.177.186.48",
+ "2.177.188.213",
+ "2.177.189.81",
+ "2.177.193.94",
+ "2.177.193.107",
+ "2.177.193.205",
+ "2.177.194.248",
+ "2.177.195.2",
+ "2.177.195.160",
+ "2.177.196.150",
+ "2.177.200.2",
+ "2.177.200.150",
+ "2.177.201.168",
+ "2.177.202.103",
+ "2.177.203.198",
+ "2.177.205.238",
+ "2.177.205.254",
+ "2.177.209.120",
+ "2.177.210.254",
+ "2.177.212.105",
+ "2.177.213.171",
+ "2.177.214.20",
+ "2.177.217.23",
+ "2.177.218.172",
+ "2.177.219.102",
+ "2.177.220.44",
+ "2.177.221.239",
+ "2.177.222.246",
+ "2.177.223.37",
+ "2.177.223.74",
+ "2.177.223.126",
+ "2.177.225.121",
+ "2.177.230.85",
+ "2.177.230.124",
+ "2.177.236.183",
+ "2.177.238.11",
+ "2.177.240.0",
+ "2.177.240.113",
+ "2.177.241.158",
+ "2.177.242.81",
+ "2.177.245.73",
+ "2.177.250.182",
+ "2.177.250.254",
+ "2.177.253.111",
+ "2.177.254.11",
+ "2.178.1.137",
+ "2.178.1.221",
+ "2.178.2.232",
+ "2.178.6.39",
+ "2.178.8.123",
+ "2.178.10.182",
+ "2.178.11.80",
+ "2.178.19.80",
+ "2.178.20.196",
+ "2.178.23.207",
+ "2.178.27.216",
+ "2.178.29.125",
+ "2.178.36.176",
+ "2.178.39.162",
+ "2.178.40.0",
+ "2.178.42.135",
+ "2.178.43.167",
+ "2.178.43.177",
+ "2.178.50.89",
+ "2.178.52.212",
+ "2.178.54.116",
+ "2.178.56.133",
+ "2.178.56.180",
+ "2.178.57.65",
+ "2.178.57.197",
+ "2.178.58.161",
+ "2.178.60.178",
+ "2.178.61.124",
+ "2.178.64.134",
+ "2.178.67.184",
+ "2.178.71.229",
+ "2.178.74.58",
+ "2.178.75.120",
+ "2.178.77.245",
+ "2.178.78.82",
+ "2.178.79.27",
+ "2.178.83.179",
+ "2.178.83.239",
+ "2.178.84.153",
+ "2.178.85.165",
+ "2.178.85.191",
+ "2.178.86.146",
+ "2.178.88.122",
+ "2.178.88.151",
+ "2.178.88.219",
+ "2.178.91.16",
+ "2.178.93.55",
+ "2.178.94.143",
+ "2.178.97.123",
+ "2.178.98.188",
+ "2.178.98.249",
+ "2.178.99.41",
+ "2.178.100.217",
+ "2.178.102.112",
+ "2.178.105.194",
+ "2.178.107.38",
+ "2.178.114.76",
+ "2.178.115.196",
+ "2.178.118.67",
+ "2.178.118.154",
+ "2.178.120.208",
+ "2.178.123.127",
+ "2.178.124.114",
+ "2.178.124.191",
+ "2.178.125.58",
+ "2.178.127.45",
+ "2.178.128.156",
+ "2.178.128.208",
+ "2.178.129.67",
+ "2.178.129.134",
+ "2.178.129.248",
+ "2.178.133.61",
+ "2.178.133.89",
+ "2.178.133.230",
+ "2.178.134.72",
+ "2.178.134.128",
+ "2.178.135.43",
+ "2.178.135.46",
+ "2.178.135.80",
+ "2.178.135.231",
+ "2.178.137.200",
+ "2.178.138.95",
+ "2.178.138.140",
+ "2.178.139.21",
+ "2.178.140.86",
+ "2.178.141.40",
+ "2.178.141.97",
+ "2.178.142.75",
+ "2.178.142.175",
+ "2.178.142.191",
+ "2.178.142.222",
+ "2.178.143.8",
+ "2.178.143.50",
+ "2.178.143.150",
+ "2.178.143.156",
+ "2.178.144.235",
+ "2.178.145.153",
+ "2.178.146.150",
+ "2.178.146.217",
+ "2.178.147.40",
+ "2.178.148.180",
+ "2.178.149.81",
+ "2.178.149.116",
+ "2.178.149.214",
+ "2.178.150.61",
+ "2.178.150.148",
+ "2.178.150.213",
+ "2.178.151.104",
+ "2.178.153.98",
+ "2.178.153.123",
+ "2.178.154.100",
+ "2.178.155.46",
+ "2.178.155.61",
+ "2.178.155.244",
+ "2.178.156.98",
+ "2.178.156.131",
+ "2.178.157.73",
+ "2.178.157.199",
+ "2.178.157.252",
+ "2.178.158.3",
+ "2.178.158.22",
+ "2.178.159.106",
+ "2.178.160.20",
+ "2.178.160.151",
+ "2.178.161.18",
+ "2.178.162.119",
+ "2.178.163.197",
+ "2.178.165.65",
+ "2.178.165.89",
+ "2.178.165.104",
+ "2.178.165.248",
+ "2.178.166.36",
+ "2.178.167.34",
+ "2.178.167.128",
+ "2.178.168.229",
+ "2.178.169.84",
+ "2.178.169.108",
+ "2.178.170.11",
+ "2.178.170.64",
+ "2.178.170.156",
+ "2.178.171.32",
+ "2.178.171.118",
+ "2.178.172.168",
+ "2.178.176.141",
+ "2.178.177.7",
+ "2.178.178.85",
+ "2.178.179.51",
+ "2.178.179.82",
+ "2.178.179.238",
+ "2.178.180.124",
+ "2.178.181.78",
+ "2.178.183.12",
+ "2.178.183.91",
+ "2.178.185.82",
+ "2.178.186.143",
+ "2.178.186.167",
+ "2.178.188.86",
+ "2.178.189.245",
+ "2.178.190.217",
+ "2.178.192.138",
+ "2.178.193.233",
+ "2.178.194.16",
+ "2.178.196.53",
+ "2.178.198.161",
+ "2.178.198.179",
+ "2.178.199.33",
+ "2.178.199.252",
+ "2.178.200.98",
+ "2.178.200.141",
+ "2.178.200.181",
+ "2.178.202.80",
+ "2.178.202.167",
+ "2.178.203.61",
+ "2.178.203.80",
+ "2.178.205.233",
+ "2.178.206.148",
+ "2.178.207.46",
+ "2.178.207.157",
+ "2.178.208.131",
+ "2.178.209.140",
+ "2.178.212.135",
+ "2.178.212.192",
+ "2.178.212.233",
+ "2.178.213.105",
+ "2.178.213.159",
+ "2.178.214.118",
+ "2.178.215.152",
+ "2.178.216.16",
+ "2.178.216.38",
+ "2.178.217.48",
+ "2.178.217.189",
+ "2.178.217.239",
+ "2.178.218.242",
+ "2.178.219.107",
+ "2.178.219.155",
+ "2.178.221.5",
+ "2.178.222.124",
+ "2.178.223.189",
+ "2.178.224.90",
+ "2.178.225.229",
+ "2.178.227.158",
+ "2.178.228.40",
+ "2.178.228.151",
+ "2.178.228.180",
+ "2.178.229.11",
+ "2.178.229.163",
+ "2.178.230.231",
+ "2.178.230.236",
+ "2.178.231.100",
+ "2.178.231.105",
+ "2.178.233.18",
+ "2.178.233.48",
+ "2.178.235.155",
+ "2.178.235.186",
+ "2.178.236.33",
+ "2.178.237.75",
+ "2.178.237.225",
+ "2.178.238.36",
+ "2.178.240.189",
+ "2.178.241.66",
+ "2.178.241.67",
+ "2.178.241.112",
+ "2.178.242.140",
+ "2.178.243.42",
+ "2.178.243.90",
+ "2.178.244.9",
+ "2.178.244.60",
+ "2.178.245.80",
+ "2.178.246.23",
+ "2.178.247.0",
+ "2.178.247.52",
+ "2.178.248.71",
+ "2.178.250.16",
+ "2.178.250.220",
+ "2.178.251.234",
+ "2.178.253.22",
+ "2.178.253.98",
+ "2.178.253.156",
+ "2.178.255.244",
+ "2.179.12.162",
+ "2.179.14.81",
+ "2.179.15.62",
+ "2.179.15.121",
+ "2.179.25.28",
+ "2.179.25.190",
+ "2.179.26.186",
+ "2.179.26.196",
+ "2.179.27.169",
+ "2.179.27.182",
+ "2.179.27.201",
+ "2.179.28.221",
+ "2.179.40.201",
+ "2.179.41.31",
+ "2.179.41.78",
+ "2.179.41.207",
+ "2.179.42.76",
+ "2.179.42.172",
+ "2.179.42.237",
+ "2.179.43.57",
+ "2.179.44.136",
+ "2.179.45.126",
+ "2.179.46.67",
+ "2.179.46.124",
+ "2.179.46.191",
+ "2.179.47.35",
+ "2.179.47.160",
+ "2.179.60.25",
+ "2.179.60.59",
+ "2.179.60.71",
+ "2.179.60.164",
+ "2.179.60.168",
+ "2.179.60.198",
+ "2.179.60.221",
+ "2.179.64.18",
+ "2.179.64.30",
+ "2.179.64.63",
+ "2.179.64.96",
+ "2.179.64.108",
+ "2.179.66.33",
+ "2.179.67.52",
+ "2.179.67.104",
+ "2.179.70.18",
+ "2.179.70.48",
+ "2.179.72.74",
+ "2.179.72.78",
+ "2.179.72.80",
+ "2.179.73.171",
+ "2.179.76.79",
+ "2.179.78.50",
+ "2.179.80.40",
+ "2.179.86.249",
+ "2.179.87.38",
+ "2.179.87.48",
+ "2.179.87.243",
+ "2.179.91.5",
+ "2.179.93.32",
+ "2.179.93.72",
+ "2.179.93.76",
+ "2.179.93.79",
+ "2.179.93.104",
+ "2.179.95.129",
+ "2.179.95.226",
+ "2.179.100.135",
+ "2.179.108.1",
+ "2.179.109.5",
+ "2.179.109.135",
+ "2.179.111.167",
+ "2.179.113.188",
+ "2.179.114.132",
+ "2.179.114.231",
+ "2.179.117.246",
+ "2.179.118.31",
+ "2.179.118.97",
+ "2.179.118.204",
+ "2.179.125.52",
+ "2.179.125.209",
+ "2.179.127.48",
+ "2.179.162.88",
+ "2.179.162.194",
+ "2.179.163.131",
+ "2.179.164.6",
+ "2.179.164.32",
+ "2.179.164.69",
+ "2.179.164.79",
+ "2.179.164.90",
+ "2.179.164.130",
+ "2.179.164.157",
+ "2.179.164.243",
+ "2.179.165.56",
+ "2.179.165.80",
+ "2.179.165.87",
+ "2.179.165.152",
+ "2.179.165.203",
+ "2.179.165.229",
+ "2.179.166.17",
+ "2.179.166.57",
+ "2.179.166.58",
+ "2.179.166.121",
+ "2.179.166.159",
+ "2.179.166.211",
+ "2.179.167.14",
+ "2.179.167.53",
+ "2.179.167.60",
+ "2.179.167.73",
+ "2.179.167.75",
+ "2.179.167.92",
+ "2.179.167.110",
+ "2.179.167.133",
+ "2.179.167.134",
+ "2.179.167.168",
+ "2.179.167.221",
+ "2.179.167.249",
+ "2.179.176.209",
+ "2.179.176.248",
+ "2.179.176.249",
+ "2.179.176.250",
+ "2.179.176.251",
+ "2.179.176.253",
+ "2.179.178.33",
+ "2.179.178.113",
+ "2.179.179.118",
+ "2.179.179.158",
+ "2.179.179.234",
+ "2.179.179.242",
+ "2.179.179.250",
+ "2.179.184.38",
+ "2.179.186.44",
+ "2.179.186.101",
+ "2.179.186.171",
+ "2.179.186.184",
+ "2.179.186.202",
+ "2.179.186.213",
+ "2.179.187.23",
+ "2.179.187.34",
+ "2.179.189.112",
+ "2.179.189.124",
+ "2.179.189.141",
+ "2.179.193.59",
+ "2.179.194.89",
+ "2.179.194.186",
+ "2.179.194.203",
+ "2.179.194.208",
+ "2.179.194.244",
+ "2.179.194.251",
+ "2.179.209.128",
+ "2.179.209.207",
+ "2.179.210.133",
+ "2.179.210.171",
+ "2.179.210.254",
+ "2.179.211.199",
+ "2.179.212.157",
+ "2.179.213.183",
+ "2.179.215.93",
+ "2.179.216.109",
+ "2.179.216.197",
+ "2.179.219.18",
+ "2.179.220.45",
+ "2.179.223.163",
+ "2.179.223.218",
+ "2.179.235.134",
+ "2.180.0.49",
+ "2.180.0.52",
+ "2.180.0.55",
+ "2.180.0.64",
+ "2.180.0.65",
+ "2.180.0.83",
+ "2.180.0.116",
+ "2.180.0.150",
+ "2.180.0.173",
+ "2.180.0.210",
+ "2.180.1.43",
+ "2.180.1.73",
+ "2.180.1.88",
+ "2.180.1.94",
+ "2.180.1.159",
+ "2.180.1.168",
+ "2.180.1.243",
+ "2.180.2.36",
+ "2.180.2.72",
+ "2.180.2.107",
+ "2.180.2.116",
+ "2.180.2.154",
+ "2.180.3.38",
+ "2.180.3.197",
+ "2.180.3.252",
+ "2.180.4.19",
+ "2.180.4.44",
+ "2.180.4.54",
+ "2.180.4.236",
+ "2.180.4.250",
+ "2.180.5.28",
+ "2.180.5.88",
+ "2.180.5.140",
+ "2.180.5.161",
+ "2.180.5.243",
+ "2.180.6.34",
+ "2.180.6.105",
+ "2.180.6.140",
+ "2.180.6.144",
+ "2.180.6.146",
+ "2.180.7.39",
+ "2.180.7.67",
+ "2.180.7.153",
+ "2.180.7.157",
+ "2.180.7.199",
+ "2.180.7.200",
+ "2.180.7.227",
+ "2.180.8.37",
+ "2.180.8.78",
+ "2.180.8.149",
+ "2.180.8.174",
+ "2.180.8.186",
+ "2.180.8.193",
+ "2.180.8.207",
+ "2.180.9.92",
+ "2.180.9.135",
+ "2.180.9.152",
+ "2.180.10.158",
+ "2.180.10.204",
+ "2.180.10.205",
+ "2.180.10.218",
+ "2.180.10.225",
+ "2.180.11.45",
+ "2.180.11.59",
+ "2.180.11.94",
+ "2.180.11.100",
+ "2.180.11.102",
+ "2.180.11.130",
+ "2.180.11.158",
+ "2.180.11.162",
+ "2.180.12.11",
+ "2.180.12.28",
+ "2.180.12.41",
+ "2.180.12.45",
+ "2.180.12.68",
+ "2.180.12.106",
+ "2.180.12.114",
+ "2.180.12.146",
+ "2.180.12.178",
+ "2.180.12.210",
+ "2.180.13.32",
+ "2.180.13.98",
+ "2.180.13.108",
+ "2.180.13.110",
+ "2.180.13.127",
+ "2.180.15.18",
+ "2.180.15.31",
+ "2.180.15.108",
+ "2.180.15.134",
+ "2.180.15.175",
+ "2.180.16.1",
+ "2.180.16.19",
+ "2.180.16.42",
+ "2.180.16.135",
+ "2.180.16.196",
+ "2.180.16.219",
+ "2.180.17.32",
+ "2.180.17.123",
+ "2.180.17.136",
+ "2.180.17.198",
+ "2.180.17.219",
+ "2.180.18.2",
+ "2.180.18.84",
+ "2.180.18.89",
+ "2.180.18.91",
+ "2.180.18.116",
+ "2.180.18.126",
+ "2.180.18.131",
+ "2.180.18.226",
+ "2.180.18.231",
+ "2.180.18.241",
+ "2.180.19.18",
+ "2.180.19.47",
+ "2.180.19.60",
+ "2.180.19.172",
+ "2.180.19.214",
+ "2.180.19.221",
+ "2.180.19.228",
+ "2.180.19.231",
+ "2.180.20.27",
+ "2.180.20.63",
+ "2.180.21.17",
+ "2.180.21.69",
+ "2.180.21.90",
+ "2.180.21.144",
+ "2.180.21.185",
+ "2.180.21.234",
+ "2.180.21.241",
+ "2.180.22.26",
+ "2.180.22.70",
+ "2.180.22.81",
+ "2.180.22.119",
+ "2.180.23.91",
+ "2.180.23.128",
+ "2.180.23.143",
+ "2.180.23.188",
+ "2.180.23.221",
+ "2.180.24.58",
+ "2.180.24.69",
+ "2.180.24.254",
+ "2.180.25.17",
+ "2.180.25.47",
+ "2.180.25.52",
+ "2.180.25.73",
+ "2.180.25.195",
+ "2.180.25.242",
+ "2.180.26.40",
+ "2.180.26.157",
+ "2.180.27.80",
+ "2.180.27.143",
+ "2.180.28.104",
+ "2.180.28.125",
+ "2.180.28.153",
+ "2.180.28.163",
+ "2.180.28.173",
+ "2.180.28.192",
+ "2.180.28.193",
+ "2.180.29.48",
+ "2.180.29.70",
+ "2.180.29.133",
+ "2.180.29.185",
+ "2.180.29.204",
+ "2.180.29.213",
+ "2.180.29.238",
+ "2.180.30.56",
+ "2.180.30.209",
+ "2.180.30.218",
+ "2.180.31.61",
+ "2.180.31.62",
+ "2.180.31.110",
+ "2.180.31.224",
+ "2.180.32.26",
+ "2.180.32.61",
+ "2.180.32.72",
+ "2.180.32.166",
+ "2.180.32.198",
+ "2.180.33.61",
+ "2.180.33.119",
+ "2.180.33.127",
+ "2.180.33.128",
+ "2.180.33.132",
+ "2.180.33.168",
+ "2.180.35.13",
+ "2.180.35.16",
+ "2.180.35.35",
+ "2.180.35.116",
+ "2.180.35.169",
+ "2.180.35.250",
+ "2.180.36.105",
+ "2.180.36.147",
+ "2.180.36.173",
+ "2.180.36.174",
+ "2.180.36.191",
+ "2.180.36.228",
+ "2.180.37.29",
+ "2.180.37.54",
+ "2.180.37.67",
+ "2.180.37.143",
+ "2.180.37.151",
+ "2.180.37.161",
+ "2.180.37.248",
+ "2.180.39.32",
+ "2.180.39.33",
+ "2.180.39.34",
+ "2.180.39.35",
+ "2.180.39.36",
+ "2.180.39.37",
+ "2.180.39.38",
+ "2.180.39.82",
+ "2.180.39.83",
+ "2.180.40.78",
+ "2.180.40.85",
+ "2.180.40.96",
+ "2.180.41.6",
+ "2.180.41.18",
+ "2.180.41.249",
+ "2.180.42.1",
+ "2.180.42.50",
+ "2.180.42.54",
+ "2.180.42.78",
+ "2.180.42.95",
+ "2.180.42.109",
+ "2.180.42.137",
+ "2.180.42.170",
+ "2.180.42.218",
+ "2.180.42.228",
+ "2.180.43.13",
+ "2.180.43.84",
+ "2.180.43.147",
+ "2.180.43.186",
+ "2.180.43.189",
+ "2.180.43.198",
+ "2.180.44.1",
+ "2.180.44.2",
+ "2.180.44.39",
+ "2.180.44.86",
+ "2.180.44.137",
+ "2.180.44.151",
+ "2.180.44.173",
+ "2.180.44.180",
+ "2.180.44.200",
+ "2.180.44.203",
+ "2.180.47.142",
+ "2.180.47.164",
+ "2.180.47.254",
+ "2.180.130.61",
+ "2.180.131.14",
+ "2.180.132.126",
+ "2.180.133.193",
+ "2.180.135.8",
+ "2.180.135.143",
+ "2.180.138.56",
+ "2.180.138.237",
+ "2.180.139.63",
+ "2.180.141.92",
+ "2.180.146.226",
+ "2.180.147.108",
+ "2.180.148.113",
+ "2.180.150.154",
+ "2.180.151.218",
+ "2.180.151.249",
+ "2.180.154.235",
+ "2.180.155.106",
+ "2.180.155.252",
+ "2.180.156.36",
+ "2.180.159.21",
+ "2.180.161.42",
+ "2.180.162.97",
+ "2.180.163.157",
+ "2.180.166.27",
+ "2.180.167.58",
+ "2.180.167.63",
+ "2.180.167.137",
+ "2.180.169.124",
+ "2.180.170.132",
+ "2.180.171.158",
+ "2.180.172.39",
+ "2.180.172.198",
+ "2.180.174.226",
+ "2.180.175.1",
+ "2.180.175.255",
+ "2.180.177.79",
+ "2.180.178.149",
+ "2.180.178.154",
+ "2.180.180.221",
+ "2.180.186.98",
+ "2.180.188.123",
+ "2.180.197.167",
+ "2.180.198.23",
+ "2.180.198.235",
+ "2.180.199.134",
+ "2.180.199.177",
+ "2.180.208.78",
+ "2.180.210.6",
+ "2.180.211.96",
+ "2.180.215.214",
+ "2.180.216.77",
+ "2.180.216.116",
+ "2.180.219.96",
+ "2.180.223.7",
+ "2.180.228.75",
+ "2.180.230.225",
+ "2.180.236.114",
+ "2.180.238.232",
+ "2.180.242.52",
+ "2.180.243.51",
+ "2.180.243.243",
+ "2.180.248.212",
+ "2.180.249.74",
+ "2.180.251.146",
+ "2.180.252.125",
+ "2.181.0.37",
+ "2.181.0.51",
+ "2.181.0.54",
+ "2.181.0.73",
+ "2.181.0.234",
+ "2.181.1.100",
+ "2.181.1.245",
+ "2.181.30.24",
+ "2.181.30.85",
+ "2.181.30.88",
+ "2.181.30.198",
+ "2.181.30.234",
+ "2.181.31.25",
+ "2.181.31.55",
+ "2.181.31.69",
+ "2.181.31.104",
+ "2.181.31.150",
+ "2.181.31.221",
+ "2.181.34.28",
+ "2.181.34.34",
+ "2.181.34.55",
+ "2.181.34.74",
+ "2.181.34.255",
+ "2.181.35.31",
+ "2.181.35.51",
+ "2.181.35.65",
+ "2.181.35.210",
+ "2.181.56.31",
+ "2.181.58.89",
+ "2.181.61.201",
+ "2.181.61.208",
+ "2.181.62.159",
+ "2.181.78.26",
+ "2.181.78.32",
+ "2.181.78.219",
+ "2.181.80.96",
+ "2.181.81.4",
+ "2.181.81.34",
+ "2.181.81.155",
+ "2.181.82.22",
+ "2.181.82.53",
+ "2.181.82.105",
+ "2.181.82.191",
+ "2.181.83.13",
+ "2.181.84.235",
+ "2.181.85.80",
+ "2.181.85.206",
+ "2.181.86.11",
+ "2.181.86.241",
+ "2.181.87.182",
+ "2.181.87.219",
+ "2.181.88.14",
+ "2.181.89.144",
+ "2.181.91.16",
+ "2.181.92.32",
+ "2.181.92.82",
+ "2.181.92.254",
+ "2.181.93.125",
+ "2.181.93.146",
+ "2.181.93.233",
+ "2.181.94.124",
+ "2.181.96.98",
+ "2.181.96.159",
+ "2.181.98.32",
+ "2.181.98.176",
+ "2.181.99.194",
+ "2.181.100.35",
+ "2.181.100.163",
+ "2.181.101.98",
+ "2.181.101.172",
+ "2.181.102.30",
+ "2.181.102.75",
+ "2.181.102.98",
+ "2.181.102.196",
+ "2.181.102.208",
+ "2.181.103.72",
+ "2.181.104.177",
+ "2.181.104.254",
+ "2.181.105.60",
+ "2.181.106.197",
+ "2.181.107.74",
+ "2.181.108.16",
+ "2.181.108.190",
+ "2.181.109.58",
+ "2.181.109.106",
+ "2.181.110.156",
+ "2.181.110.241",
+ "2.181.129.23",
+ "2.181.195.99",
+ "2.181.195.113",
+ "2.181.198.66",
+ "2.181.201.158",
+ "2.181.202.229",
+ "2.181.204.140",
+ "2.181.206.33",
+ "2.181.206.133",
+ "2.181.208.45",
+ "2.181.210.150",
+ "2.181.211.7",
+ "2.181.213.41",
+ "2.181.213.83",
+ "2.181.215.172",
+ "2.181.216.44",
+ "2.181.216.54",
+ "2.181.216.225",
+ "2.181.217.76",
+ "2.181.217.170",
+ "2.181.221.50",
+ "2.181.222.216",
+ "2.181.222.253",
+ "2.181.224.62",
+ "2.181.225.138",
+ "2.181.225.203",
+ "2.181.225.237",
+ "2.181.226.194",
+ "2.181.227.140",
+ "2.181.227.172",
+ "2.181.227.213",
+ "2.181.228.24",
+ "2.181.228.113",
+ "2.181.228.194",
+ "2.181.229.49",
+ "2.181.229.236",
+ "2.181.230.167",
+ "2.181.231.150",
+ "2.181.232.216",
+ "2.181.234.74",
+ "2.181.234.129",
+ "2.181.234.135",
+ "2.181.234.140",
+ "2.181.234.194",
+ "2.181.234.213",
+ "2.181.234.222",
+ "2.181.235.126",
+ "2.181.236.18",
+ "2.181.236.228",
+ "2.181.237.88",
+ "2.181.237.120",
+ "2.181.238.72",
+ "2.181.239.75",
+ "2.181.239.206",
+ "2.181.239.207",
+ "2.181.240.16",
+ "2.181.240.143",
+ "2.181.240.226",
+ "2.181.241.99",
+ "2.181.241.197",
+ "2.181.242.59",
+ "2.181.243.143",
+ "2.181.244.40",
+ "2.181.245.241",
+ "2.181.246.95",
+ "2.181.249.188",
+ "2.181.251.145",
+ "2.181.254.53",
+ "2.181.254.87",
+ "2.181.254.127",
+ "2.181.255.171",
+ "2.181.255.222",
+ "2.182.40.14",
+ "2.182.40.59",
+ "2.182.40.76",
+ "2.182.43.6",
+ "2.182.43.187",
+ "2.182.44.240",
+ "2.182.46.202",
+ "2.182.47.140",
+ "2.182.48.163",
+ "2.182.48.247",
+ "2.182.51.1",
+ "2.182.51.29",
+ "2.182.51.63",
+ "2.182.51.99",
+ "2.182.52.72",
+ "2.182.53.247",
+ "2.182.54.149",
+ "2.182.66.165",
+ "2.182.79.37",
+ "2.182.89.108",
+ "2.182.90.205",
+ "2.182.112.11",
+ "2.182.112.125",
+ "2.182.114.75",
+ "2.182.115.46",
+ "2.182.115.83",
+ "2.182.115.91",
+ "2.182.116.22",
+ "2.182.116.70",
+ "2.182.116.103",
+ "2.182.117.118",
+ "2.182.124.100",
+ "2.182.125.223",
+ "2.182.152.15",
+ "2.182.152.37",
+ "2.182.152.103",
+ "2.182.152.115",
+ "2.182.152.136",
+ "2.182.152.138",
+ "2.182.152.155",
+ "2.182.152.206",
+ "2.182.152.240",
+ "2.182.152.254",
+ "2.182.153.95",
+ "2.182.153.106",
+ "2.182.153.125",
+ "2.182.153.131",
+ "2.182.153.145",
+ "2.182.153.163",
+ "2.182.153.196",
+ "2.182.154.27",
+ "2.182.154.57",
+ "2.182.154.65",
+ "2.182.154.77",
+ "2.182.154.85",
+ "2.182.154.110",
+ "2.182.154.130",
+ "2.182.154.158",
+ "2.182.154.160",
+ "2.182.154.185",
+ "2.182.154.207",
+ "2.182.155.160",
+ "2.182.163.78",
+ "2.182.176.193",
+ "2.182.179.32",
+ "2.182.179.130",
+ "2.182.179.236",
+ "2.182.180.119",
+ "2.182.180.194",
+ "2.182.181.130",
+ "2.182.184.83",
+ "2.182.186.225",
+ "2.182.187.13",
+ "2.182.188.73",
+ "2.182.188.156",
+ "2.182.189.30",
+ "2.182.189.33",
+ "2.182.189.147",
+ "2.182.189.169",
+ "2.182.190.37",
+ "2.182.191.173",
+ "2.182.192.46",
+ "2.182.196.9",
+ "2.182.196.65",
+ "2.182.196.133",
+ "2.182.196.234",
+ "2.182.198.213",
+ "2.182.201.3",
+ "2.182.201.5",
+ "2.182.201.71",
+ "2.182.201.220",
+ "2.182.201.221",
+ "2.182.201.222",
+ "2.182.204.29",
+ "2.182.204.78",
+ "2.182.204.250",
+ "2.182.205.252",
+ "2.182.206.42",
+ "2.182.206.58",
+ "2.182.206.121",
+ "2.182.207.14",
+ "2.182.207.191",
+ "2.182.209.24",
+ "2.182.210.235",
+ "2.182.212.252",
+ "2.182.214.246",
+ "2.182.215.122",
+ "2.182.216.144",
+ "2.182.223.204",
+ "2.182.228.247",
+ "2.182.231.42",
+ "2.182.232.85",
+ "2.182.233.138",
+ "2.182.236.135",
+ "2.182.236.141",
+ "2.182.236.154",
+ "2.182.236.237",
+ "2.182.237.186",
+ "2.182.237.251",
+ "2.182.239.170",
+ "2.182.241.197",
+ "2.182.243.110",
+ "2.182.243.151",
+ "2.182.243.209",
+ "2.182.243.244",
+ "2.182.244.151",
+ "2.182.245.101",
+ "2.182.245.200",
+ "2.182.245.231",
+ "2.182.246.102",
+ "2.182.246.134",
+ "2.182.249.84",
+ "2.182.249.130",
+ "2.182.250.85",
+ "2.182.250.160",
+ "2.182.253.241",
+ "2.183.8.13",
+ "2.183.8.19",
+ "2.183.8.90",
+ "2.183.8.118",
+ "2.183.8.173",
+ "2.183.8.186",
+ "2.183.9.86",
+ "2.183.9.165",
+ "2.183.9.236",
+ "2.183.32.12",
+ "2.183.32.52",
+ "2.183.32.62",
+ "2.183.32.84",
+ "2.183.32.112",
+ "2.183.80.7",
+ "2.183.80.8",
+ "2.183.82.5",
+ "2.183.82.51",
+ "2.183.83.147",
+ "2.183.83.235",
+ "2.183.84.4",
+ "2.183.86.138",
+ "2.183.86.218",
+ "2.183.87.231",
+ "2.183.87.239",
+ "2.183.97.178",
+ "2.183.98.176",
+ "2.183.100.95",
+ "2.183.100.145",
+ "2.183.102.201",
+ "2.183.105.124",
+ "2.183.105.142",
+ "2.183.106.13",
+ "2.183.107.214",
+ "2.183.110.163",
+ "2.183.112.69",
+ "2.183.112.159",
+ "2.183.112.219",
+ "2.183.112.252",
+ "2.183.113.112",
+ "2.183.114.9",
+ "2.183.114.107",
+ "2.183.114.243",
+ "2.183.115.91",
+ "2.183.117.133",
+ "2.183.117.167",
+ "2.183.119.25",
+ "2.183.120.146",
+ "2.183.121.29",
+ "2.183.123.172",
+ "2.183.135.24",
+ "2.183.135.52",
+ "2.183.203.74",
+ "2.183.203.131",
+ "2.183.203.135",
+ "2.183.203.142",
+ "2.183.203.146",
+ "2.183.231.18",
+ "2.183.237.8",
+ "2.184.38.118",
+ "2.184.41.171",
+ "2.184.48.4",
+ "2.184.48.42",
+ "2.184.48.46",
+ "2.184.49.21",
+ "2.184.49.22",
+ "2.184.49.145",
+ "2.184.50.27",
+ "2.184.50.34",
+ "2.184.50.144",
+ "2.184.50.145",
+ "2.184.50.165",
+ "2.184.50.172",
+ "2.184.51.69",
+ "2.184.51.140",
+ "2.184.51.143",
+ "2.184.52.22",
+ "2.184.52.194",
+ "2.184.52.249",
+ "2.184.52.250",
+ "2.184.53.168",
+ "2.184.53.237",
+ "2.184.54.17",
+ "2.184.54.38",
+ "2.184.54.105",
+ "2.184.54.113",
+ "2.184.54.128",
+ "2.184.54.157",
+ "2.184.54.208",
+ "2.184.55.14",
+ "2.184.55.22",
+ "2.184.55.37",
+ "2.184.55.83",
+ "2.184.55.105",
+ "2.184.55.128",
+ "2.184.55.156",
+ "2.184.55.183",
+ "2.184.57.117",
+ "2.184.57.166",
+ "2.184.58.19",
+ "2.184.58.25",
+ "2.184.58.188",
+ "2.184.59.29",
+ "2.184.59.52",
+ "2.184.59.82",
+ "2.184.59.137",
+ "2.184.60.6",
+ "2.184.61.36",
+ "2.184.61.61",
+ "2.184.61.204",
+ "2.184.70.91",
+ "2.184.70.104",
+ "2.184.71.2",
+ "2.184.71.3",
+ "2.184.71.4",
+ "2.184.71.6",
+ "2.184.74.2",
+ "2.184.74.62",
+ "2.184.89.24",
+ "2.184.90.99",
+ "2.184.90.104",
+ "2.184.90.129",
+ "2.184.90.198",
+ "2.184.92.31",
+ "2.184.118.38",
+ "2.184.155.46",
+ "2.184.155.72",
+ "2.184.155.83",
+ "2.184.155.92",
+ "2.184.155.117",
+ "2.184.156.9",
+ "2.184.156.38",
+ "2.184.156.79",
+ "2.184.156.155",
+ "2.184.156.188",
+ "2.184.156.189",
+ "2.184.156.233",
+ "2.184.157.5",
+ "2.184.157.15",
+ "2.184.157.18",
+ "2.184.157.129",
+ "2.184.157.134",
+ "2.184.157.146",
+ "2.184.157.150",
+ "2.184.157.226",
+ "2.184.157.237",
+ "2.184.158.14",
+ "2.184.158.38",
+ "2.184.158.117",
+ "2.184.158.221",
+ "2.184.158.253",
+ "2.184.159.66",
+ "2.184.159.68",
+ "2.184.159.111",
+ "2.184.159.119",
+ "2.184.159.126",
+ "2.184.159.167",
+ "2.184.159.227",
+ "2.184.169.181",
+ "2.184.171.87",
+ "2.184.182.68",
+ "2.184.182.76",
+ "2.184.182.87",
+ "2.184.182.136",
+ "2.184.182.152",
+ "2.184.217.25",
+ "2.184.217.127",
+ "2.184.217.167",
+ "2.184.217.176",
+ "2.184.217.193",
+ "2.184.217.197",
+ "2.184.217.224",
+ "2.184.236.9",
+ "2.184.236.34",
+ "2.184.236.119",
+ "2.184.236.159",
+ "2.184.236.164",
+ "2.184.236.166",
+ "2.184.236.197",
+ "2.184.236.217",
+ "2.184.236.233",
+ "2.184.236.240",
+ "2.184.237.70",
+ "2.184.237.208",
+ "2.184.238.17",
+ "2.184.238.19",
+ "2.184.238.113",
+ "2.184.238.123",
+ "2.184.238.214",
+ "2.184.239.89",
+ "2.184.239.236",
+ "2.185.17.15",
+ "2.185.17.144",
+ "2.185.17.206",
+ "2.185.17.242",
+ "2.185.18.223",
+ "2.185.96.234",
+ "2.185.97.7",
+ "2.185.97.61",
+ "2.185.97.73",
+ "2.185.98.143",
+ "2.185.98.165",
+ "2.185.100.127",
+ "2.185.100.154",
+ "2.185.100.238",
+ "2.185.105.18",
+ "2.185.109.245",
+ "2.185.112.36",
+ "2.185.112.226",
+ "2.185.114.134",
+ "2.185.116.58",
+ "2.185.116.139",
+ "2.185.122.55",
+ "2.185.123.194",
+ "2.185.126.25",
+ "2.185.126.221",
+ "2.185.126.230",
+ "2.185.127.96",
+ "2.185.127.128",
+ "2.185.128.41",
+ "2.185.128.69",
+ "2.185.128.113",
+ "2.185.128.121",
+ "2.185.128.161",
+ "2.185.128.211",
+ "2.185.128.218",
+ "2.185.128.221",
+ "2.185.128.225",
+ "2.185.128.230",
+ "2.185.141.25",
+ "2.185.141.55",
+ "2.185.143.33",
+ "2.185.143.103",
+ "2.185.144.22",
+ "2.185.147.55",
+ "2.185.147.166",
+ "2.185.147.174",
+ "2.185.147.198",
+ "2.185.147.202",
+ "2.185.148.21",
+ "2.185.148.118",
+ "2.185.148.128",
+ "2.185.148.154",
+ "2.185.148.217",
+ "2.185.149.163",
+ "2.185.150.166",
+ "2.185.151.209",
+ "2.185.152.1",
+ "2.185.152.21",
+ "2.185.153.51",
+ "2.185.153.188",
+ "2.185.175.55",
+ "2.185.191.203",
+ "2.185.192.9",
+ "2.185.203.219",
+ "2.185.214.7",
+ "2.185.214.202",
+ "2.185.224.33",
+ "2.185.224.152",
+ "2.185.224.167",
+ "2.185.224.187",
+ "2.185.225.195",
+ "2.185.226.211",
+ "2.185.227.51",
+ "2.185.227.56",
+ "2.185.227.124",
+ "2.185.227.138",
+ "2.185.229.38",
+ "2.185.229.115",
+ "2.185.231.20",
+ "2.185.232.50",
+ "2.185.232.170",
+ "2.185.232.210",
+ "2.185.232.242",
+ "2.185.233.83",
+ "2.185.233.166",
+ "2.185.234.55",
+ "2.185.235.73",
+ "2.185.237.4",
+ "2.185.238.45",
+ "2.185.238.145",
+ "2.185.239.130",
+ "2.185.239.131",
+ "2.185.239.132",
+ "2.185.239.133",
+ "2.185.239.134",
+ "2.185.239.136",
+ "2.185.239.137",
+ "2.185.239.138",
+ "2.185.239.139",
+ "2.185.239.140",
+ "2.185.239.230",
+ "2.185.241.0",
+ "2.185.241.150",
+ "2.185.242.112",
+ "2.185.242.141",
+ "2.185.242.180",
+ "2.185.244.68",
+ "2.185.244.78",
+ "2.185.247.168",
+ "2.185.247.176",
+ "2.185.247.197",
+ "2.185.248.2",
+ "2.185.248.141",
+ "2.185.249.54",
+ "2.185.250.155",
+ "2.185.250.165",
+ "2.185.250.215",
+ "2.185.251.95",
+ "2.185.252.124",
+ "2.185.252.253",
+ "2.185.253.215",
+ "2.186.12.75",
+ "2.186.12.113",
+ "2.186.12.137",
+ "2.186.12.138",
+ "2.186.12.156",
+ "2.186.12.180",
+ "2.186.13.21",
+ "2.186.13.26",
+ "2.186.13.94",
+ "2.186.14.27",
+ "2.186.14.60",
+ "2.186.14.92",
+ "2.186.14.94",
+ "2.186.14.102",
+ "2.186.14.167",
+ "2.186.14.234",
+ "2.186.14.239",
+ "2.186.15.17",
+ "2.186.15.39",
+ "2.186.15.74",
+ "2.186.15.79",
+ "2.186.15.170",
+ "2.186.15.194",
+ "2.186.15.196",
+ "2.186.15.199",
+ "2.186.112.22",
+ "2.186.112.24",
+ "2.186.112.85",
+ "2.186.112.132",
+ "2.186.112.178",
+ "2.186.112.186",
+ "2.186.114.125",
+ "2.186.114.179",
+ "2.186.114.196",
+ "2.186.114.236",
+ "2.186.115.35",
+ "2.186.115.86",
+ "2.186.115.162",
+ "2.186.115.184",
+ "2.186.115.252",
+ "2.186.116.38",
+ "2.186.116.121",
+ "2.186.116.210",
+ "2.186.117.2",
+ "2.186.117.79",
+ "2.186.117.93",
+ "2.186.117.107",
+ "2.186.117.140",
+ "2.186.117.164",
+ "2.186.118.17",
+ "2.186.118.44",
+ "2.186.118.49",
+ "2.186.118.81",
+ "2.186.118.165",
+ "2.186.118.211",
+ "2.186.118.255",
+ "2.186.119.27",
+ "2.186.119.32",
+ "2.186.119.48",
+ "2.186.119.65",
+ "2.186.119.169",
+ "2.186.119.217",
+ "2.186.119.253",
+ "2.186.120.41",
+ "2.186.120.64",
+ "2.186.120.70",
+ "2.186.120.133",
+ "2.186.120.175",
+ "2.186.120.181",
+ "2.186.120.202",
+ "2.186.120.215",
+ "2.186.121.39",
+ "2.186.121.100",
+ "2.186.121.170",
+ "2.186.122.15",
+ "2.186.122.50",
+ "2.186.122.51",
+ "2.186.122.60",
+ "2.186.122.125",
+ "2.186.122.184",
+ "2.186.122.199",
+ "2.186.122.214",
+ "2.186.123.35",
+ "2.186.123.64",
+ "2.186.123.108",
+ "2.186.123.152",
+ "2.186.123.183",
+ "2.186.123.213",
+ "2.186.127.1",
+ "2.186.127.68",
+ "2.186.127.90",
+ "2.186.127.158",
+ "2.186.127.164",
+ "2.186.127.212",
+ "2.186.127.236",
+ "2.186.127.247",
+ "2.186.229.46",
+ "2.186.229.60",
+ "2.186.229.110",
+ "2.186.229.192",
+ "2.186.229.230",
+ "2.186.231.68",
+ "2.186.231.129",
+ "2.186.231.130",
+ "2.186.231.155",
+ "2.186.231.241",
+ "2.186.231.242",
+ "2.186.231.243",
+ "2.186.231.244",
+ "2.186.231.245",
+ "2.186.231.246",
+ "2.187.1.167",
+ "2.187.2.23",
+ "2.187.2.30",
+ "2.187.2.96",
+ "2.187.2.101",
+ "2.187.2.123",
+ "2.187.2.184",
+ "2.187.2.185",
+ "2.187.4.172",
+ "2.187.5.66",
+ "2.187.6.17",
+ "2.187.6.112",
+ "2.187.6.182",
+ "2.187.6.243",
+ "2.187.7.232",
+ "2.187.8.176",
+ "2.187.9.2",
+ "2.187.10.227",
+ "2.187.11.1",
+ "2.187.16.10",
+ "2.187.16.17",
+ "2.187.16.25",
+ "2.187.16.63",
+ "2.187.16.90",
+ "2.187.16.147",
+ "2.187.16.179",
+ "2.187.16.223",
+ "2.187.16.243",
+ "2.187.16.252",
+ "2.187.18.17",
+ "2.187.18.248",
+ "2.187.19.18",
+ "2.187.19.151",
+ "2.187.19.241",
+ "2.187.19.242",
+ "2.187.24.39",
+ "2.187.24.235",
+ "2.187.26.17",
+ "2.187.26.75",
+ "2.187.26.145",
+ "2.187.27.146",
+ "2.187.28.228",
+ "2.187.30.84",
+ "2.187.32.13",
+ "2.187.32.72",
+ "2.187.32.210",
+ "2.187.32.228",
+ "2.187.33.42",
+ "2.187.33.50",
+ "2.187.33.107",
+ "2.187.33.174",
+ "2.187.33.187",
+ "2.187.34.87",
+ "2.187.34.126",
+ "2.187.34.161",
+ "2.187.35.15",
+ "2.187.35.19",
+ "2.187.35.21",
+ "2.187.35.61",
+ "2.187.35.84",
+ "2.187.35.140",
+ "2.187.36.11",
+ "2.187.37.180",
+ "2.187.37.242",
+ "2.187.38.26",
+ "2.187.38.201",
+ "2.187.39.91",
+ "2.187.39.157",
+ "2.187.39.172",
+ "2.187.39.190",
+ "2.187.39.234",
+ "2.187.56.225",
+ "2.187.57.8",
+ "2.187.57.17",
+ "2.187.57.23",
+ "2.187.62.102",
+ "2.187.96.30",
+ "2.187.96.85",
+ "2.187.96.116",
+ "2.187.96.252",
+ "2.187.97.4",
+ "2.187.97.111",
+ "2.187.97.121",
+ "2.187.97.141",
+ "2.187.98.41",
+ "2.187.98.118",
+ "2.187.98.181",
+ "2.187.99.27",
+ "2.187.99.71",
+ "2.187.99.150",
+ "2.187.100.13",
+ "2.187.100.51",
+ "2.187.100.137",
+ "2.187.101.33",
+ "2.187.101.46",
+ "2.187.117.47",
+ "2.187.117.140",
+ "2.187.118.1",
+ "2.187.119.3",
+ "2.187.119.6",
+ "2.187.119.113",
+ "2.187.128.43",
+ "2.187.128.159",
+ "2.187.128.166",
+ "2.187.128.170",
+ "2.187.140.131",
+ "2.187.142.95",
+ "2.187.143.145",
+ "2.187.150.9",
+ "2.187.150.48",
+ "2.187.150.108",
+ "2.187.186.17",
+ "2.187.186.65",
+ "2.187.186.66",
+ "2.187.186.67",
+ "2.187.186.68",
+ "2.187.186.69",
+ "2.187.188.98",
+ "2.187.188.123",
+ "2.187.188.130",
+ "2.187.188.137",
+ "2.187.188.143",
+ "2.187.188.174",
+ "2.187.188.190",
+ "2.187.188.239",
+ "2.187.188.253",
+ "2.187.189.60",
+ "2.187.189.121",
+ "2.187.189.193",
+ "2.187.189.208",
+ "2.187.189.226",
+ "2.187.189.227",
+ "2.187.212.11",
+ "2.187.212.125",
+ "2.187.213.78",
+ "2.187.213.158",
+ "2.187.221.33",
+ "2.187.249.121",
+ "2.187.249.148",
+ "2.187.249.177",
+ "2.187.249.178",
+ "2.187.250.11",
+ "2.187.250.50",
+ "2.187.250.80",
+ "2.187.250.110",
+ "2.187.250.169",
+ "2.187.250.218",
+ "2.187.250.223",
+ "2.187.251.88",
+ "2.187.251.245",
+ "2.188.43.76",
+ "2.188.72.11",
+ "2.188.72.48",
+ "2.188.72.54",
+ "2.188.72.56",
+ "2.188.72.150",
+ "2.188.72.174",
+ "2.188.72.209",
+ "2.188.72.220",
+ "2.188.72.230",
+ "2.188.72.238",
+ "2.188.73.129",
+ "2.188.73.137",
+ "2.188.73.145",
+ "2.188.73.153",
+ "2.188.73.157",
+ "2.188.73.161",
+ "2.188.73.165",
+ "2.188.75.14",
+ "2.188.75.178",
+ "2.188.160.236",
+ "2.188.161.170",
+ "2.188.162.74",
+ "2.188.162.75",
+ "2.188.162.78",
+ "2.188.164.54",
+ "2.188.164.91",
+ "2.188.164.117",
+ "2.188.164.140",
+ "2.188.165.114",
+ "2.188.165.170",
+ "2.188.166.50",
+ "2.188.166.74",
+ "2.188.166.75",
+ "2.188.166.78",
+ "2.188.167.14",
+ "2.188.167.34",
+ "2.188.167.54",
+ "2.188.167.114",
+ "2.188.167.156",
+ "2.188.168.41",
+ "2.188.168.87",
+ "2.188.168.88",
+ "2.188.168.135",
+ "2.188.168.222",
+ "2.188.174.151",
+ "2.188.174.173",
+ "2.188.174.194",
+ "2.188.174.230",
+ "2.188.175.4",
+ "2.188.175.21",
+ "2.188.175.94",
+ "2.188.175.105",
+ "2.188.175.215",
+ "2.188.175.228",
+ "2.188.208.110",
+ "2.188.208.142",
+ "2.188.208.242",
+ "2.188.208.254",
+ "2.188.210.2",
+ "2.188.210.3",
+ "2.188.210.5",
+ "2.188.210.6",
+ "2.188.210.8",
+ "2.188.210.10",
+ "2.188.210.12",
+ "2.188.210.13",
+ "2.188.210.14",
+ "2.188.210.16",
+ "2.188.210.20",
+ "2.188.210.21",
+ "2.188.210.50",
+ "2.188.210.111",
+ "2.188.210.112",
+ "2.188.210.125",
+ "2.188.211.7",
+ "2.188.211.234",
+ "2.188.214.250",
+ "2.188.214.252",
+ "2.188.214.253",
+ "2.188.214.254",
+ "2.188.215.34",
+ "2.188.215.67",
+ "2.188.215.103",
+ "2.188.217.54",
+ "2.188.220.132",
+ "2.188.221.14",
+ "2.188.222.1",
+ "2.188.222.2",
+ "2.188.222.11",
+ "2.188.222.14",
+ "2.188.222.65",
+ "2.188.222.81",
+ "2.188.225.66",
+ "2.188.225.67",
+ "2.188.225.136",
+ "2.188.225.147",
+ "2.188.226.187",
+ "2.188.226.188",
+ "2.188.226.189",
+ "2.188.226.190",
+ "2.188.226.243",
+ "2.188.226.245",
+ "2.188.226.246",
+ "2.188.226.247",
+ "2.188.226.248",
+ "2.188.226.250",
+ "2.188.226.251",
+ "2.188.226.252",
+ "2.188.228.36",
+ "2.188.228.37",
+ "2.188.228.38",
+ "2.188.228.98",
+ "2.188.228.130",
+ "2.188.230.210",
+ "2.188.230.212",
+ "2.188.231.2",
+ "2.188.231.106",
+ "2.188.231.110",
+ "2.188.231.114",
+ "2.188.231.115",
+ "2.188.231.116",
+ "2.188.231.117",
+ "2.188.231.118",
+ "2.188.231.120",
+ "2.188.231.122",
+ "2.188.231.123",
+ "2.188.231.125",
+ "2.188.231.194",
+ "2.188.231.195",
+ "2.188.231.196",
+ "2.188.231.197",
+ "2.188.231.198",
+ "2.188.231.199",
+ "2.188.235.128",
+ "2.188.236.50",
+ "2.188.236.70",
+ "2.188.237.22",
+ "2.188.237.146",
+ "2.189.1.1",
+ "2.189.1.2",
+ "2.189.1.11",
+ "2.189.1.12",
+ "2.189.1.14",
+ "2.189.1.40",
+ "2.189.1.104",
+ "2.189.1.251",
+ "2.189.8.168",
+ "2.189.9.77",
+ "2.189.9.163",
+ "2.189.10.247",
+ "2.189.11.76",
+ "2.189.11.239",
+ "2.189.16.113",
+ "2.189.20.156",
+ "2.189.20.158",
+ "2.189.21.139",
+ "2.189.23.66",
+ "2.189.28.38",
+ "2.189.28.134",
+ "2.189.28.166",
+ "2.189.29.111",
+ "2.189.29.229",
+ "2.189.29.231",
+ "2.189.30.37",
+ "2.189.31.217",
+ "2.189.32.52",
+ "2.189.32.199",
+ "2.189.33.61",
+ "2.189.33.90",
+ "2.189.33.114",
+ "2.189.34.164",
+ "2.189.34.221",
+ "2.189.34.244",
+ "2.189.59.81",
+ "2.189.67.42",
+ "2.189.86.10",
+ "2.189.86.11",
+ "2.189.86.12",
+ "2.189.86.13",
+ "2.189.86.14",
+ "2.189.86.15",
+ "2.189.86.16",
+ "2.189.86.19",
+ "2.189.86.30",
+ "2.189.86.31",
+ "2.189.86.32",
+ "2.189.86.34",
+ "2.189.86.35",
+ "2.189.86.36",
+ "2.189.86.41",
+ "2.189.86.42",
+ "2.189.86.43",
+ "2.189.86.44",
+ "2.189.86.45",
+ "2.189.86.46",
+ "2.189.86.84",
+ "2.189.86.85",
+ "2.189.86.86",
+ "2.189.86.87",
+ "2.189.86.88",
+ "2.189.86.89",
+ "2.189.86.90",
+ "2.189.86.91",
+ "2.189.86.92",
+ "2.189.86.93",
+ "2.189.86.94",
+ "2.189.86.98",
+ "2.189.86.103",
+ "2.189.86.104",
+ "2.189.86.105",
+ "2.189.86.107",
+ "2.189.86.108",
+ "2.189.86.109",
+ "2.189.86.110",
+ "2.189.86.111",
+ "2.189.86.112",
+ "2.189.86.113",
+ "2.189.87.172",
+ "2.189.87.228",
+ "2.189.89.18",
+ "2.189.89.110",
+ "2.189.89.166",
+ "2.189.89.214",
+ "2.189.90.84",
+ "2.189.90.147",
+ "2.189.90.206",
+ "2.189.91.37",
+ "2.189.91.141",
+ "2.189.91.226",
+ "2.189.91.229",
+ "2.189.91.230",
+ "2.189.91.231",
+ "2.189.91.232",
+ "2.189.92.31",
+ "2.189.92.217",
+ "2.189.93.162",
+ "2.189.93.224",
+ "2.189.96.121",
+ "2.189.96.136",
+ "2.189.98.67",
+ "2.189.98.113",
+ "2.189.98.135",
+ "2.189.98.137",
+ "2.189.101.0",
+ "2.189.101.6",
+ "2.189.101.12",
+ "2.189.101.13",
+ "2.189.101.14",
+ "2.189.101.15",
+ "2.189.101.85",
+ "2.189.101.100",
+ "2.189.101.101",
+ "2.189.101.139",
+ "2.189.101.146",
+ "2.189.101.165",
+ "2.189.101.224",
+ "2.189.101.231",
+ "2.189.102.15",
+ "2.189.104.1",
+ "2.189.104.3",
+ "2.189.114.61",
+ "2.189.115.49",
+ "2.189.115.76",
+ "2.189.115.150",
+ "2.189.115.162",
+ "2.189.115.174",
+ "2.189.115.183",
+ "2.189.120.2",
+ "2.189.120.4",
+ "2.189.120.14",
+ "2.189.120.16",
+ "2.189.120.23",
+ "2.189.120.35",
+ "2.189.120.39",
+ "2.189.120.40",
+ "2.189.120.43",
+ "2.189.120.69",
+ "2.189.120.74",
+ "2.189.120.77",
+ "2.189.120.78",
+ "2.189.120.99",
+ "2.189.120.109",
+ "2.189.120.114",
+ "2.189.120.116",
+ "2.189.120.117",
+ "2.189.120.144",
+ "2.189.120.149",
+ "2.189.120.164",
+ "2.189.120.180",
+ "2.189.120.183",
+ "2.189.120.201",
+ "2.189.120.213",
+ "2.189.120.214",
+ "2.189.120.220",
+ "2.189.120.226",
+ "2.189.120.231",
+ "2.189.120.232",
+ "2.189.120.233",
+ "2.189.121.4",
+ "2.189.121.10",
+ "2.189.121.15",
+ "2.189.121.16",
+ "2.189.121.21",
+ "2.189.121.47",
+ "2.189.121.49",
+ "2.189.121.53",
+ "2.189.121.54",
+ "2.189.121.56",
+ "2.189.121.58",
+ "2.189.121.62",
+ "2.189.121.66",
+ "2.189.121.78",
+ "2.189.121.79",
+ "2.189.121.88",
+ "2.189.121.90",
+ "2.189.121.91",
+ "2.189.121.99",
+ "2.189.121.104",
+ "2.189.121.121",
+ "2.189.121.131",
+ "2.189.121.136",
+ "2.189.121.146",
+ "2.189.121.152",
+ "2.189.121.155",
+ "2.189.121.163",
+ "2.189.121.176",
+ "2.189.121.178",
+ "2.189.121.191",
+ "2.189.121.202",
+ "2.189.121.210",
+ "2.189.121.218",
+ "2.189.121.231",
+ "2.189.121.232",
+ "2.189.121.240",
+ "2.189.121.244",
+ "2.189.122.20",
+ "2.189.122.22",
+ "2.189.122.103",
+ "2.189.122.119",
+ "2.189.122.240",
+ "2.189.128.11",
+ "2.189.128.12",
+ "2.189.128.13",
+ "2.189.128.180",
+ "2.189.128.181",
+ "2.189.128.182",
+ "2.189.130.3",
+ "2.189.130.4",
+ "2.189.130.8",
+ "2.189.130.10",
+ "2.189.130.18",
+ "2.189.130.33",
+ "2.189.136.3",
+ "2.189.136.6",
+ "2.189.136.25",
+ "2.189.136.67",
+ "2.189.136.69",
+ "2.189.136.78",
+ "2.189.136.95",
+ "2.189.136.112",
+ "2.189.136.132",
+ "2.189.136.153",
+ "2.189.136.178",
+ "2.189.137.0",
+ "2.189.137.20",
+ "2.189.137.27",
+ "2.189.137.29",
+ "2.189.137.43",
+ "2.189.137.61",
+ "2.189.137.98",
+ "2.189.137.99",
+ "2.189.137.221",
+ "2.189.137.222",
+ "2.189.137.223",
+ "2.189.137.224",
+ "2.189.137.240",
+ "2.189.139.0",
+ "2.189.139.5",
+ "2.189.139.7",
+ "2.189.139.10",
+ "2.189.139.14",
+ "2.189.139.16",
+ "2.189.139.18",
+ "2.189.139.21",
+ "2.189.139.25",
+ "2.189.139.35",
+ "2.189.139.41",
+ "2.189.139.55",
+ "2.189.139.56",
+ "2.189.139.63",
+ "2.189.139.65",
+ "2.189.139.76",
+ "2.189.139.85",
+ "2.189.139.89",
+ "2.189.139.95",
+ "2.189.139.101",
+ "2.189.139.108",
+ "2.189.139.109",
+ "2.189.139.114",
+ "2.189.139.120",
+ "2.189.139.125",
+ "2.189.139.128",
+ "2.189.139.129",
+ "2.189.139.130",
+ "2.189.139.131",
+ "2.189.139.135",
+ "2.189.139.145",
+ "2.189.139.150",
+ "2.189.139.157",
+ "2.189.139.161",
+ "2.189.139.171",
+ "2.189.139.180",
+ "2.189.139.185",
+ "2.189.139.193",
+ "2.189.139.206",
+ "2.189.139.214",
+ "2.189.139.218",
+ "2.189.139.221",
+ "2.189.139.222",
+ "2.189.139.230",
+ "2.189.139.233",
+ "2.189.139.240",
+ "2.189.139.241",
+ "2.189.139.242",
+ "2.189.139.246",
+ "2.189.139.247",
+ "2.189.139.250",
+ "2.189.140.5",
+ "2.189.140.6",
+ "2.189.140.7",
+ "2.189.141.32",
+ "2.189.142.20",
+ "2.189.142.33",
+ "2.189.142.38",
+ "2.189.142.48",
+ "2.189.142.55",
+ "2.189.142.57",
+ "2.189.142.63",
+ "2.189.142.98",
+ "2.189.142.112",
+ "2.189.143.4",
+ "2.189.143.5",
+ "2.189.143.8",
+ "2.189.143.11",
+ "2.189.143.24",
+ "2.189.143.49",
+ "2.189.143.58",
+ "2.189.143.61",
+ "2.189.143.78",
+ "2.189.143.145",
+ "2.189.143.181",
+ "2.189.143.191",
+ "2.189.143.222",
+ "2.189.143.253",
+ "2.189.144.9",
+ "2.189.144.11",
+ "2.189.144.19",
+ "2.189.144.28",
+ "2.189.144.40",
+ "2.189.144.55",
+ "2.189.144.65",
+ "2.189.144.73",
+ "2.189.144.83",
+ "2.189.144.86",
+ "2.189.144.104",
+ "2.189.144.109",
+ "2.189.144.121",
+ "2.189.144.126",
+ "2.189.144.129",
+ "2.189.144.140",
+ "2.189.144.143",
+ "2.189.144.147",
+ "2.189.144.151",
+ "2.189.144.159",
+ "2.189.144.163",
+ "2.189.144.173",
+ "2.189.144.181",
+ "2.189.144.184",
+ "2.189.144.186",
+ "2.189.144.207",
+ "2.189.144.215",
+ "2.189.144.218",
+ "2.189.144.221",
+ "2.189.144.222",
+ "2.189.144.224",
+ "2.189.144.227",
+ "2.189.144.229",
+ "2.189.144.233",
+ "2.189.144.235",
+ "2.189.144.247",
+ "2.189.145.4",
+ "2.189.145.11",
+ "2.189.145.34",
+ "2.189.145.46",
+ "2.189.145.48",
+ "2.189.145.70",
+ "2.189.145.71",
+ "2.189.145.75",
+ "2.189.145.104",
+ "2.189.145.108",
+ "2.189.145.109",
+ "2.189.145.122",
+ "2.189.145.149",
+ "2.189.145.154",
+ "2.189.145.160",
+ "2.189.145.164",
+ "2.189.145.167",
+ "2.189.145.168",
+ "2.189.145.174",
+ "2.189.145.177",
+ "2.189.145.183",
+ "2.189.145.193",
+ "2.189.145.195",
+ "2.189.145.197",
+ "2.189.145.211",
+ "2.189.145.213",
+ "2.189.145.224",
+ "2.189.145.244",
+ "2.189.145.246",
+ "2.189.145.249",
+ "2.189.145.252",
+ "2.189.146.113",
+ "2.189.147.44",
+ "2.189.147.188",
+ "2.189.147.241",
+ "2.189.148.2",
+ "2.189.148.8",
+ "2.189.148.12",
+ "2.189.148.16",
+ "2.189.148.17",
+ "2.189.148.23",
+ "2.189.148.28",
+ "2.189.148.29",
+ "2.189.148.32",
+ "2.189.148.33",
+ "2.189.148.34",
+ "2.189.148.36",
+ "2.189.148.38",
+ "2.189.148.39",
+ "2.189.148.43",
+ "2.189.148.44",
+ "2.189.148.49",
+ "2.189.148.54",
+ "2.189.148.63",
+ "2.189.148.64",
+ "2.189.148.67",
+ "2.189.148.69",
+ "2.189.148.71",
+ "2.189.148.82",
+ "2.189.148.87",
+ "2.189.148.88",
+ "2.189.148.94",
+ "2.189.148.98",
+ "2.189.148.104",
+ "2.189.148.109",
+ "2.189.148.126",
+ "2.189.148.131",
+ "2.189.148.133",
+ "2.189.148.136",
+ "2.189.148.137",
+ "2.189.148.139",
+ "2.189.148.146",
+ "2.189.148.156",
+ "2.189.148.166",
+ "2.189.148.167",
+ "2.189.148.169",
+ "2.189.148.171",
+ "2.189.148.176",
+ "2.189.148.181",
+ "2.189.148.182",
+ "2.189.148.183",
+ "2.189.148.192",
+ "2.189.148.204",
+ "2.189.148.205",
+ "2.189.148.214",
+ "2.189.148.215",
+ "2.189.148.231",
+ "2.189.148.235",
+ "2.189.148.248",
+ "2.189.148.251",
+ "2.189.148.253",
+ "2.189.151.5",
+ "2.189.151.68",
+ "2.189.151.109",
+ "2.189.151.116",
+ "2.189.151.126",
+ "2.189.151.130",
+ "2.189.151.146",
+ "2.189.151.165",
+ "2.189.151.171",
+ "2.189.151.174",
+ "2.189.151.180",
+ "2.189.153.96",
+ "2.189.153.162",
+ "2.189.156.30",
+ "2.189.156.42",
+ "2.189.158.176",
+ "2.189.162.18",
+ "2.189.162.250",
+ "2.189.163.4",
+ "2.189.163.63",
+ "2.189.163.112",
+ "2.189.164.26",
+ "2.189.164.27",
+ "2.189.164.28",
+ "2.189.164.29",
+ "2.189.167.131",
+ "2.189.167.203",
+ "2.189.167.210",
+ "2.189.167.211",
+ "2.189.167.212",
+ "2.189.167.254",
+ "2.189.172.30",
+ "2.189.172.49",
+ "2.189.218.246",
+ "2.189.220.93",
+ "2.189.236.154",
+ "2.189.236.246",
+ "2.189.237.61",
+ "2.189.237.180",
+ "2.189.237.190",
+ "2.189.237.236",
+ "2.189.237.254",
+ "2.189.238.236",
+ "2.189.239.123",
+ "2.189.243.1",
+ "2.189.243.22",
+ "2.189.254.109",
+ "2.190.1.39",
+ "2.190.2.98",
+ "2.190.6.96",
+ "2.190.6.165",
+ "2.190.8.47",
+ "2.190.11.209",
+ "2.190.17.151",
+ "2.190.19.236",
+ "2.190.20.16",
+ "2.190.20.231",
+ "2.190.23.71",
+ "2.190.25.71",
+ "2.190.30.229",
+ "2.190.30.232",
+ "2.190.31.210",
+ "2.190.32.109",
+ "2.190.34.61",
+ "2.190.35.228",
+ "2.190.36.45",
+ "2.190.36.76",
+ "2.190.39.192",
+ "2.190.41.13",
+ "2.190.41.22",
+ "2.190.43.66",
+ "2.190.44.173",
+ "2.190.48.7",
+ "2.190.48.125",
+ "2.190.48.237",
+ "2.190.49.82",
+ "2.190.50.185",
+ "2.190.50.196",
+ "2.190.52.208",
+ "2.190.52.213",
+ "2.190.55.11",
+ "2.190.55.244",
+ "2.190.61.97",
+ "2.190.62.119",
+ "2.190.62.191",
+ "2.190.65.167",
+ "2.190.67.113",
+ "2.190.69.243",
+ "2.190.70.196",
+ "2.190.71.71",
+ "2.190.73.192",
+ "2.190.74.207",
+ "2.190.76.5",
+ "2.190.76.85",
+ "2.190.76.193",
+ "2.190.77.23",
+ "2.190.78.61",
+ "2.190.79.242",
+ "2.190.83.111",
+ "2.190.83.208",
+ "2.190.84.71",
+ "2.190.86.236",
+ "2.190.89.139",
+ "2.190.92.35",
+ "2.190.94.144",
+ "2.190.99.230",
+ "2.190.107.69",
+ "2.190.109.210",
+ "2.190.118.22",
+ "2.190.120.59",
+ "2.190.122.198",
+ "2.190.123.73",
+ "2.190.124.254",
+ "2.190.125.199",
+ "2.190.126.81",
+ "2.190.127.182",
+ "2.190.128.34",
+ "2.190.128.144",
+ "2.190.129.63",
+ "2.190.131.45",
+ "2.190.131.59",
+ "2.190.131.77",
+ "2.190.132.76",
+ "2.190.132.127",
+ "2.190.134.82",
+ "2.190.134.83",
+ "2.190.135.61",
+ "2.190.136.197",
+ "2.190.138.238",
+ "2.190.139.113",
+ "2.190.139.227",
+ "2.190.140.0",
+ "2.190.141.236",
+ "2.190.144.221",
+ "2.190.145.33",
+ "2.190.145.162",
+ "2.190.146.22",
+ "2.190.149.231",
+ "2.190.150.187",
+ "2.190.152.194",
+ "2.190.154.18",
+ "2.190.154.112",
+ "2.190.155.29",
+ "2.190.156.203",
+ "2.190.159.247",
+ "2.190.159.252",
+ "2.190.161.41",
+ "2.190.161.135",
+ "2.190.161.184",
+ "2.190.163.101",
+ "2.190.165.30",
+ "2.190.165.60",
+ "2.190.165.211",
+ "2.190.166.161",
+ "2.190.167.23",
+ "2.190.167.212",
+ "2.190.168.142",
+ "2.190.168.170",
+ "2.190.168.222",
+ "2.190.169.17",
+ "2.190.169.52",
+ "2.190.169.66",
+ "2.190.170.46",
+ "2.190.170.99",
+ "2.190.170.190",
+ "2.190.170.226",
+ "2.190.171.67",
+ "2.190.171.109",
+ "2.190.171.169",
+ "2.190.172.25",
+ "2.190.174.227",
+ "2.190.175.249",
+ "2.190.175.253",
+ "2.190.178.124",
+ "2.190.179.0",
+ "2.190.179.147",
+ "2.190.180.43",
+ "2.190.180.189",
+ "2.190.184.132",
+ "2.190.185.87",
+ "2.190.186.3",
+ "2.190.186.158",
+ "2.190.186.203",
+ "2.190.187.159",
+ "2.190.187.241",
+ "2.190.188.66",
+ "2.190.188.249",
+ "2.190.191.189",
+ "2.190.191.200",
+ "2.190.192.226",
+ "2.190.192.228",
+ "2.190.193.203",
+ "2.190.194.46",
+ "2.190.195.166",
+ "2.190.195.204",
+ "2.190.195.218",
+ "2.190.199.157",
+ "2.190.200.150",
+ "2.190.200.250",
+ "2.190.201.12",
+ "2.190.201.171",
+ "2.190.202.65",
+ "2.190.202.158",
+ "2.190.202.198",
+ "2.190.202.216",
+ "2.190.203.54",
+ "2.190.203.131",
+ "2.190.203.251",
+ "2.190.204.64",
+ "2.190.205.188",
+ "2.190.206.99",
+ "2.190.206.170",
+ "2.190.206.210",
+ "2.190.206.216",
+ "2.190.207.248",
+ "2.190.209.183",
+ "2.190.209.211",
+ "2.190.209.250",
+ "2.190.210.10",
+ "2.190.210.75",
+ "2.190.212.167",
+ "2.190.212.231",
+ "2.190.213.22",
+ "2.190.216.62",
+ "2.190.216.174",
+ "2.190.217.24",
+ "2.190.217.92",
+ "2.190.217.165",
+ "2.190.219.214",
+ "2.190.220.78",
+ "2.190.220.211",
+ "2.190.220.241",
+ "2.190.221.12",
+ "2.190.221.194",
+ "2.190.222.89",
+ "2.190.223.87",
+ "2.190.224.7",
+ "2.190.224.132",
+ "2.190.224.239",
+ "2.190.230.119",
+ "2.190.231.82",
+ "2.190.231.157",
+ "2.190.232.123",
+ "2.190.232.132",
+ "2.190.234.135",
+ "2.190.235.146",
+ "2.190.238.243",
+ "2.190.239.223",
+ "2.190.240.72",
+ "2.190.240.176",
+ "2.190.243.87",
+ "2.190.246.193",
+ "2.190.247.151",
+ "2.190.249.82",
+ "2.190.249.112",
+ "2.190.250.112",
+ "2.190.250.122",
+ "2.190.251.161",
+ "2.190.252.84",
+ "2.190.252.208",
+ "2.190.252.246",
+ "2.190.253.55",
+ "2.190.254.174",
+ "2.190.254.245",
+ "2.190.255.24",
+ "2.190.255.185",
+ "2.191.0.118",
+ "2.191.1.47",
+ "2.191.2.50",
+ "2.191.2.235",
+ "2.191.6.10",
+ "2.191.6.87",
+ "2.191.6.132",
+ "2.191.7.0",
+ "2.191.8.125",
+ "2.191.8.147",
+ "2.191.9.10",
+ "2.191.9.194",
+ "2.191.12.12",
+ "2.191.12.134",
+ "2.191.13.14",
+ "2.191.14.38",
+ "2.191.14.110",
+ "2.191.14.148",
+ "2.191.15.52",
+ "2.191.15.163",
+ "2.191.17.129",
+ "2.191.18.196",
+ "2.191.19.66",
+ "2.191.19.120",
+ "2.191.19.124",
+ "2.191.19.208",
+ "2.191.22.243",
+ "2.191.23.201",
+ "2.191.24.52",
+ "2.191.24.62",
+ "2.191.28.157",
+ "2.191.28.241",
+ "2.191.29.45",
+ "2.191.29.48",
+ "2.191.31.85",
+ "2.191.32.24",
+ "2.191.34.80",
+ "2.191.35.207",
+ "2.191.36.246",
+ "2.191.37.33",
+ "2.191.37.183",
+ "2.191.38.68",
+ "2.191.38.70",
+ "2.191.38.186",
+ "2.191.38.227",
+ "2.191.40.77",
+ "2.191.40.149",
+ "2.191.40.224",
+ "2.191.41.211",
+ "2.191.42.150",
+ "2.191.43.136",
+ "2.191.43.178",
+ "2.191.44.34",
+ "2.191.44.39",
+ "2.191.44.211",
+ "2.191.45.40",
+ "2.191.45.171",
+ "2.191.45.181",
+ "2.191.46.25",
+ "2.191.46.73",
+ "2.191.46.113",
+ "2.191.46.114",
+ "2.191.47.158",
+ "2.191.47.201",
+ "2.191.48.18",
+ "2.191.48.179",
+ "2.191.50.99",
+ "2.191.51.173",
+ "2.191.52.46",
+ "2.191.53.61",
+ "2.191.53.242",
+ "2.191.55.165",
+ "2.191.56.28",
+ "2.191.57.66",
+ "2.191.57.179",
+ "2.191.58.176",
+ "2.191.58.178",
+ "2.191.59.170",
+ "2.191.60.102",
+ "2.191.60.186",
+ "2.191.60.205",
+ "2.191.61.246",
+ "2.191.62.3",
+ "2.191.63.31",
+ "2.191.63.189",
+ "2.191.64.56",
+ "2.191.64.61",
+ "2.191.64.186",
+ "2.191.64.242",
+ "2.191.65.4",
+ "2.191.67.29",
+ "2.191.68.135",
+ "2.191.69.94",
+ "2.191.69.185",
+ "2.191.70.110",
+ "2.191.70.132",
+ "2.191.71.57",
+ "2.191.71.77",
+ "2.191.71.219",
+ "2.191.73.219",
+ "2.191.74.137",
+ "2.191.75.50",
+ "2.191.75.144",
+ "2.191.75.157",
+ "2.191.76.121",
+ "2.191.80.4",
+ "2.191.80.253",
+ "2.191.81.64",
+ "2.191.82.127",
+ "2.191.83.137",
+ "2.191.84.65",
+ "2.191.85.54",
+ "2.191.85.82",
+ "2.191.86.107",
+ "2.191.86.180",
+ "2.191.86.219",
+ "2.191.86.255",
+ "2.191.87.132",
+ "2.191.87.206",
+ "2.191.89.32",
+ "2.191.90.27",
+ "2.191.90.185",
+ "2.191.90.186",
+ "2.191.91.32",
+ "2.191.91.101",
+ "2.191.92.107",
+ "2.191.92.185",
+ "2.191.93.14",
+ "2.191.94.26",
+ "2.191.94.236",
+ "2.191.95.249",
+ "2.191.96.234",
+ "2.191.97.65",
+ "2.191.97.146",
+ "2.191.98.243",
+ "2.191.99.83",
+ "2.191.99.158",
+ "2.191.101.155",
+ "2.191.103.93",
+ "2.191.103.121",
+ "2.191.103.168",
+ "2.191.104.41",
+ "2.191.104.51",
+ "2.191.105.150",
+ "2.191.108.244",
+ "2.191.109.116",
+ "2.191.110.5",
+ "2.191.110.185",
+ "2.191.111.42",
+ "2.191.111.204",
+ "2.191.112.254",
+ "2.191.113.74",
+ "2.191.113.106",
+ "2.191.113.197",
+ "2.191.113.215",
+ "2.191.115.150",
+ "2.191.115.245",
+ "2.191.116.96",
+ "2.191.116.114",
+ "2.191.117.57",
+ "2.191.117.147",
+ "2.191.118.61",
+ "2.191.120.25",
+ "2.191.120.243",
+ "2.191.124.210",
+ "2.191.126.20",
+ "2.191.127.29",
+ "2.191.127.41",
+ "2.191.131.119",
+ "2.191.142.150",
+ "2.191.197.194",
+ "2.191.202.171",
+ "2.191.208.248",
+ "5.10.248.43",
+ "5.10.248.53",
+ "5.10.248.150",
+ "5.10.248.181",
+ "5.10.249.153",
+ "5.10.249.156",
+ "5.10.249.164",
+ "5.10.249.179",
+ "5.10.249.217",
+ "5.10.249.245",
+ "5.22.193.5",
+ "5.22.193.6",
+ "5.22.196.29",
+ "5.22.196.102",
+ "5.22.196.154",
+ "5.22.197.172",
+ "5.22.198.138",
+ "5.22.198.190",
+ "5.22.199.193",
+ "5.22.200.232",
+ "5.22.200.233",
+ "5.22.200.234",
+ "5.22.200.235",
+ "5.22.201.17",
+ "5.22.201.162",
+ "5.22.203.98",
+ "5.22.203.100",
+ "5.22.203.101",
+ "5.22.203.102",
+ "5.42.217.140",
+ "5.42.217.182",
+ "5.42.223.221",
+ "5.56.132.51",
+ "5.56.132.142",
+ "5.56.135.7",
+ "5.57.32.131",
+ "5.57.32.166",
+ "5.57.32.180",
+ "5.57.32.235",
+ "5.57.33.97",
+ "5.57.33.251",
+ "5.57.34.199",
+ "5.57.35.225",
+ "5.57.37.76",
+ "5.57.37.228",
+ "5.57.39.58",
+ "5.61.24.42",
+ "5.61.28.101",
+ "5.61.28.235",
+ "5.61.30.35",
+ "5.61.30.226",
+ "5.61.31.99",
+ "5.62.164.171",
+ "5.63.8.227",
+ "5.63.9.37",
+ "5.63.9.218",
+ "5.63.13.51",
+ "5.63.13.52",
+ "5.63.13.54",
+ "5.63.13.130",
+ "5.74.1.217",
+ "5.74.5.10",
+ "5.74.10.236",
+ "5.74.13.6",
+ "5.74.22.215",
+ "5.74.25.251",
+ "5.74.28.146",
+ "5.74.35.80",
+ "5.74.38.17",
+ "5.74.38.158",
+ "5.74.40.120",
+ "5.74.40.141",
+ "5.74.42.203",
+ "5.74.44.199",
+ "5.74.44.204",
+ "5.74.56.99",
+ "5.74.56.162",
+ "5.74.58.120",
+ "5.74.66.14",
+ "5.74.66.233",
+ "5.74.68.20",
+ "5.74.71.139",
+ "5.74.75.152",
+ "5.74.80.36",
+ "5.74.80.101",
+ "5.74.83.157",
+ "5.74.87.197",
+ "5.74.89.177",
+ "5.74.94.17",
+ "5.74.97.165",
+ "5.74.98.28",
+ "5.74.100.96",
+ "5.74.101.87",
+ "5.74.105.229",
+ "5.74.106.250",
+ "5.74.111.74",
+ "5.74.112.154",
+ "5.74.113.149",
+ "5.74.121.103",
+ "5.74.126.100",
+ "5.74.128.161",
+ "5.74.128.210",
+ "5.74.128.236",
+ "5.74.129.74",
+ "5.74.129.92",
+ "5.74.130.60",
+ "5.74.130.226",
+ "5.74.131.34",
+ "5.74.131.194",
+ "5.74.131.198",
+ "5.74.132.140",
+ "5.74.132.164",
+ "5.74.133.175",
+ "5.74.134.201",
+ "5.74.137.11",
+ "5.74.139.47",
+ "5.74.139.130",
+ "5.74.145.22",
+ "5.74.145.67",
+ "5.74.146.141",
+ "5.74.146.179",
+ "5.74.147.228",
+ "5.74.151.195",
+ "5.74.154.129",
+ "5.74.155.111",
+ "5.74.156.49",
+ "5.74.156.251",
+ "5.74.157.139",
+ "5.74.157.195",
+ "5.74.157.228",
+ "5.74.159.121",
+ "5.74.159.123",
+ "5.74.159.129",
+ "5.74.160.71",
+ "5.74.160.147",
+ "5.74.160.212",
+ "5.74.161.128",
+ "5.74.163.73",
+ "5.74.163.130",
+ "5.74.164.17",
+ "5.74.165.51",
+ "5.74.165.234",
+ "5.74.168.18",
+ "5.74.168.54",
+ "5.74.168.95",
+ "5.74.169.91",
+ "5.74.170.174",
+ "5.74.170.233",
+ "5.74.173.188",
+ "5.74.174.30",
+ "5.74.175.141",
+ "5.74.176.18",
+ "5.74.177.22",
+ "5.74.178.191",
+ "5.74.179.16",
+ "5.74.180.250",
+ "5.74.181.153",
+ "5.74.183.117",
+ "5.74.183.146",
+ "5.74.184.240",
+ "5.74.188.93",
+ "5.74.188.151",
+ "5.74.189.1",
+ "5.74.193.164",
+ "5.74.195.235",
+ "5.74.197.49",
+ "5.74.199.35",
+ "5.74.199.81",
+ "5.74.199.252",
+ "5.74.205.78",
+ "5.74.205.212",
+ "5.74.206.36",
+ "5.74.207.79",
+ "5.74.207.114",
+ "5.74.208.64",
+ "5.74.211.96",
+ "5.74.211.172",
+ "5.74.212.1",
+ "5.74.212.5",
+ "5.74.212.11",
+ "5.74.212.234",
+ "5.74.215.107",
+ "5.74.218.2",
+ "5.74.219.171",
+ "5.74.220.57",
+ "5.74.221.24",
+ "5.74.221.80",
+ "5.74.221.102",
+ "5.74.221.140",
+ "5.74.222.115",
+ "5.74.224.18",
+ "5.74.225.117",
+ "5.74.225.239",
+ "5.74.227.193",
+ "5.74.229.131",
+ "5.74.231.56",
+ "5.74.233.92",
+ "5.74.233.254",
+ "5.74.234.101",
+ "5.74.234.181",
+ "5.74.234.223",
+ "5.74.236.142",
+ "5.74.236.167",
+ "5.74.237.240",
+ "5.74.237.247",
+ "5.74.239.195",
+ "5.74.240.11",
+ "5.74.242.17",
+ "5.74.242.107",
+ "5.74.245.153",
+ "5.74.246.116",
+ "5.74.246.192",
+ "5.74.249.45",
+ "5.74.249.231",
+ "5.74.252.166",
+ "5.74.255.153",
+ "5.75.41.226",
+ "5.106.4.130",
+ "5.106.5.129",
+ "5.106.5.130",
+ "5.106.16.59",
+ "5.106.16.163",
+ "5.106.16.248",
+ "5.106.17.59",
+ "5.106.17.60",
+ "5.106.17.61",
+ "5.106.17.62",
+ "5.106.17.64",
+ "5.106.17.65",
+ "5.106.17.66",
+ "5.106.17.67",
+ "5.106.17.77",
+ "5.106.17.128",
+ "5.106.17.129",
+ "5.106.17.134",
+ "5.106.17.135",
+ "5.106.17.147",
+ "5.106.17.161",
+ "5.106.17.163",
+ "5.106.17.172",
+ "5.106.18.59",
+ "5.106.18.62",
+ "5.106.18.63",
+ "5.106.18.90",
+ "5.106.18.170",
+ "5.106.18.176",
+ "5.106.18.192",
+ "5.106.18.218",
+ "5.106.18.221",
+ "5.106.18.235",
+ "5.106.18.241",
+ "5.106.18.252",
+ "5.106.19.13",
+ "5.106.19.45",
+ "5.106.19.47",
+ "5.106.19.48",
+ "5.106.19.49",
+ "5.106.19.50",
+ "5.106.19.51",
+ "5.106.19.53",
+ "5.106.19.54",
+ "5.106.19.56",
+ "5.106.19.58",
+ "5.106.19.60",
+ "5.106.19.79",
+ "5.106.19.89",
+ "5.106.19.93",
+ "5.106.19.95",
+ "5.106.19.116",
+ "5.106.19.126",
+ "5.106.19.179",
+ "5.106.19.188",
+ "5.106.19.193",
+ "5.106.19.195",
+ "5.106.19.205",
+ "5.106.21.62",
+ "5.106.21.84",
+ "5.106.21.103",
+ "5.106.21.126",
+ "5.106.21.154",
+ "5.106.28.32",
+ "5.106.28.115",
+ "5.106.28.172",
+ "5.106.28.198",
+ "5.106.28.203",
+ "5.106.29.212",
+ "5.134.195.80",
+ "5.134.195.162",
+ "5.134.195.197",
+ "5.134.196.195",
+ "5.144.129.83",
+ "5.144.129.177",
+ "5.144.129.236",
+ "5.144.130.94",
+ "5.144.132.7",
+ "5.144.132.98",
+ "5.145.112.53",
+ "5.145.112.57",
+ "5.145.112.225",
+ "5.145.113.1",
+ "5.145.113.58",
+ "5.145.113.60",
+ "5.145.114.73",
+ "5.145.114.83",
+ "5.145.114.85",
+ "5.145.114.98",
+ "5.145.114.99",
+ "5.145.114.112",
+ "5.145.114.113",
+ "5.145.114.115",
+ "5.145.114.211",
+ "5.145.114.222",
+ "5.145.114.225",
+ "5.145.114.234",
+ "5.145.114.236",
+ "5.145.114.239",
+ "5.145.114.243",
+ "5.145.114.249",
+ "5.145.115.17",
+ "5.145.115.170",
+ "5.145.115.213",
+ "5.145.115.217",
+ "5.145.115.225",
+ "5.145.115.232",
+ "5.159.49.107",
+ "5.159.49.207",
+ "5.159.50.49",
+ "5.159.50.50",
+ "5.159.50.53",
+ "5.159.50.55",
+ "5.159.50.57",
+ "5.159.50.58",
+ "5.159.50.61",
+ "5.159.50.194",
+ "5.159.50.197",
+ "5.159.50.198",
+ "5.159.50.200",
+ "5.159.50.201",
+ "5.159.51.5",
+ "5.159.52.25",
+ "5.159.52.26",
+ "5.159.52.27",
+ "5.159.52.28",
+ "5.159.52.29",
+ "5.159.52.73",
+ "5.159.52.76",
+ "5.159.53.56",
+ "5.159.53.81",
+ "5.159.55.50",
+ "5.159.55.53",
+ "5.159.55.62",
+ "5.159.55.105",
+ "5.159.55.113",
+ "5.159.55.121",
+ "5.159.55.129",
+ "5.159.55.150",
+ "5.159.55.153",
+ "5.159.55.181",
+ "5.159.55.182",
+ "5.159.55.249",
+ "5.160.0.125",
+ "5.160.0.127",
+ "5.160.0.195",
+ "5.160.0.222",
+ "5.160.1.26",
+ "5.160.1.42",
+ "5.160.1.43",
+ "5.160.1.44",
+ "5.160.1.90",
+ "5.160.2.38",
+ "5.160.2.226",
+ "5.160.2.227",
+ "5.160.2.228",
+ "5.160.2.229",
+ "5.160.3.34",
+ "5.160.3.104",
+ "5.160.3.116",
+ "5.160.3.174",
+ "5.160.3.226",
+ "5.160.4.147",
+ "5.160.5.99",
+ "5.160.5.100",
+ "5.160.5.101",
+ "5.160.5.102",
+ "5.160.5.162",
+ "5.160.7.214",
+ "5.160.12.244",
+ "5.160.12.247",
+ "5.160.12.251",
+ "5.160.14.203",
+ "5.160.14.204",
+ "5.160.14.205",
+ "5.160.14.206",
+ "5.160.15.10",
+ "5.160.20.130",
+ "5.160.23.98",
+ "5.160.23.102",
+ "5.160.25.180",
+ "5.160.25.206",
+ "5.160.26.30",
+ "5.160.26.74",
+ "5.160.26.75",
+ "5.160.26.77",
+ "5.160.27.150",
+ "5.160.28.236",
+ "5.160.28.238",
+ "5.160.29.4",
+ "5.160.29.44",
+ "5.160.32.190",
+ "5.160.33.2",
+ "5.160.33.254",
+ "5.160.36.48",
+ "5.160.36.60",
+ "5.160.37.8",
+ "5.160.37.46",
+ "5.160.37.147",
+ "5.160.37.192",
+ "5.160.37.201",
+ "5.160.38.46",
+ "5.160.38.78",
+ "5.160.38.189",
+ "5.160.39.98",
+ "5.160.39.250",
+ "5.160.40.4",
+ "5.160.40.39",
+ "5.160.40.44",
+ "5.160.40.56",
+ "5.160.40.62",
+ "5.160.40.71",
+ "5.160.40.154",
+ "5.160.40.173",
+ "5.160.40.250",
+ "5.160.42.34",
+ "5.160.42.46",
+ "5.160.42.202",
+ "5.160.43.18",
+ "5.160.43.62",
+ "5.160.43.82",
+ "5.160.43.110",
+ "5.160.45.138",
+ "5.160.45.220",
+ "5.160.47.67",
+ "5.160.47.82",
+ "5.160.47.119",
+ "5.160.48.53",
+ "5.160.49.14",
+ "5.160.49.26",
+ "5.160.49.74",
+ "5.160.49.75",
+ "5.160.49.76",
+ "5.160.49.77",
+ "5.160.49.78",
+ "5.160.49.98",
+ "5.160.49.100",
+ "5.160.49.101",
+ "5.160.49.104",
+ "5.160.49.108",
+ "5.160.49.109",
+ "5.160.49.226",
+ "5.160.50.6",
+ "5.160.50.130",
+ "5.160.51.241",
+ "5.160.52.90",
+ "5.160.52.91",
+ "5.160.52.92",
+ "5.160.52.93",
+ "5.160.52.94",
+ "5.160.52.234",
+ "5.160.53.94",
+ "5.160.54.26",
+ "5.160.54.27",
+ "5.160.54.28",
+ "5.160.54.29",
+ "5.160.54.30",
+ "5.160.54.118",
+ "5.160.56.2",
+ "5.160.56.30",
+ "5.160.56.50",
+ "5.160.56.118",
+ "5.160.56.174",
+ "5.160.56.228",
+ "5.160.56.249",
+ "5.160.57.34",
+ "5.160.57.35",
+ "5.160.58.129",
+ "5.160.59.18",
+ "5.160.59.19",
+ "5.160.59.20",
+ "5.160.59.29",
+ "5.160.60.6",
+ "5.160.60.43",
+ "5.160.60.166",
+ "5.160.61.2",
+ "5.160.61.161",
+ "5.160.61.162",
+ "5.160.61.163",
+ "5.160.61.164",
+ "5.160.61.166",
+ "5.160.61.169",
+ "5.160.61.170",
+ "5.160.61.171",
+ "5.160.61.172",
+ "5.160.61.173",
+ "5.160.61.174",
+ "5.160.61.251",
+ "5.160.61.254",
+ "5.160.62.88",
+ "5.160.62.89",
+ "5.160.62.91",
+ "5.160.62.160",
+ "5.160.62.164",
+ "5.160.63.34",
+ "5.160.63.38",
+ "5.160.63.126",
+ "5.160.65.18",
+ "5.160.65.19",
+ "5.160.65.20",
+ "5.160.65.21",
+ "5.160.65.22",
+ "5.160.65.25",
+ "5.160.65.26",
+ "5.160.65.27",
+ "5.160.65.28",
+ "5.160.65.29",
+ "5.160.65.30",
+ "5.160.65.190",
+ "5.160.67.98",
+ "5.160.67.102",
+ "5.160.68.1",
+ "5.160.68.50",
+ "5.160.68.226",
+ "5.160.68.229",
+ "5.160.68.230",
+ "5.160.68.231",
+ "5.160.68.232",
+ "5.160.68.233",
+ "5.160.68.234",
+ "5.160.68.235",
+ "5.160.68.236",
+ "5.160.68.238",
+ "5.160.72.22",
+ "5.160.72.53",
+ "5.160.72.134",
+ "5.160.72.222",
+ "5.160.73.88",
+ "5.160.74.147",
+ "5.160.74.226",
+ "5.160.74.227",
+ "5.160.74.228",
+ "5.160.74.229",
+ "5.160.74.230",
+ "5.160.74.232",
+ "5.160.74.233",
+ "5.160.74.254",
+ "5.160.75.10",
+ "5.160.75.90",
+ "5.160.75.207",
+ "5.160.76.106",
+ "5.160.76.170",
+ "5.160.76.171",
+ "5.160.76.198",
+ "5.160.76.226",
+ "5.160.78.18",
+ "5.160.78.86",
+ "5.160.78.104",
+ "5.160.78.134",
+ "5.160.78.154",
+ "5.160.78.238",
+ "5.160.80.33",
+ "5.160.80.98",
+ "5.160.80.193",
+ "5.160.80.194",
+ "5.160.80.210",
+ "5.160.80.211",
+ "5.160.80.214",
+ "5.160.81.177",
+ "5.160.81.187",
+ "5.160.81.251",
+ "5.160.82.110",
+ "5.160.83.18",
+ "5.160.83.66",
+ "5.160.83.117",
+ "5.160.83.122",
+ "5.160.84.34",
+ "5.160.85.195",
+ "5.160.85.234",
+ "5.160.86.34",
+ "5.160.87.51",
+ "5.160.87.106",
+ "5.160.88.34",
+ "5.160.88.35",
+ "5.160.88.36",
+ "5.160.88.37",
+ "5.160.88.38",
+ "5.160.88.39",
+ "5.160.88.40",
+ "5.160.88.41",
+ "5.160.88.42",
+ "5.160.88.43",
+ "5.160.88.44",
+ "5.160.88.45",
+ "5.160.88.46",
+ "5.160.89.99",
+ "5.160.89.194",
+ "5.160.90.61",
+ "5.160.90.86",
+ "5.160.90.218",
+ "5.160.91.180",
+ "5.160.91.190",
+ "5.160.93.210",
+ "5.160.93.246",
+ "5.160.95.194",
+ "5.160.98.131",
+ "5.160.99.4",
+ "5.160.99.5",
+ "5.160.99.6",
+ "5.160.99.8",
+ "5.160.99.9",
+ "5.160.99.10",
+ "5.160.99.11",
+ "5.160.99.12",
+ "5.160.99.13",
+ "5.160.99.14",
+ "5.160.99.15",
+ "5.160.99.19",
+ "5.160.99.20",
+ "5.160.99.227",
+ "5.160.99.229",
+ "5.160.99.230",
+ "5.160.99.231",
+ "5.160.99.232",
+ "5.160.99.235",
+ "5.160.99.237",
+ "5.160.100.8",
+ "5.160.100.114",
+ "5.160.100.118",
+ "5.160.101.2",
+ "5.160.101.244",
+ "5.160.101.245",
+ "5.160.101.246",
+ "5.160.101.247",
+ "5.160.101.249",
+ "5.160.101.250",
+ "5.160.101.251",
+ "5.160.101.252",
+ "5.160.101.253",
+ "5.160.102.201",
+ "5.160.103.42",
+ "5.160.103.43",
+ "5.160.103.46",
+ "5.160.103.67",
+ "5.160.103.114",
+ "5.160.103.162",
+ "5.160.103.185",
+ "5.160.108.74",
+ "5.160.108.210",
+ "5.160.108.222",
+ "5.160.109.186",
+ "5.160.112.46",
+ "5.160.112.145",
+ "5.160.114.126",
+ "5.160.114.132",
+ "5.160.114.134",
+ "5.160.115.42",
+ "5.160.115.50",
+ "5.160.115.51",
+ "5.160.115.52",
+ "5.160.115.53",
+ "5.160.115.54",
+ "5.160.115.130",
+ "5.160.115.134",
+ "5.160.115.138",
+ "5.160.115.190",
+ "5.160.115.210",
+ "5.160.115.238",
+ "5.160.118.86",
+ "5.160.118.93",
+ "5.160.118.110",
+ "5.160.118.178",
+ "5.160.118.186",
+ "5.160.119.130",
+ "5.160.119.210",
+ "5.160.119.225",
+ "5.160.119.228",
+ "5.160.119.242",
+ "5.160.119.250",
+ "5.160.120.14",
+ "5.160.121.6",
+ "5.160.122.150",
+ "5.160.122.226",
+ "5.160.123.138",
+ "5.160.124.155",
+ "5.160.125.38",
+ "5.160.125.46",
+ "5.160.125.138",
+ "5.160.125.186",
+ "5.160.125.234",
+ "5.160.126.139",
+ "5.160.127.67",
+ "5.160.127.68",
+ "5.160.127.69",
+ "5.160.127.70",
+ "5.160.127.90",
+ "5.160.129.118",
+ "5.160.134.82",
+ "5.160.134.83",
+ "5.160.134.84",
+ "5.160.134.85",
+ "5.160.134.86",
+ "5.160.135.46",
+ "5.160.136.122",
+ "5.160.136.162",
+ "5.160.137.54",
+ "5.160.138.227",
+ "5.160.143.225",
+ "5.160.144.9",
+ "5.160.144.15",
+ "5.160.144.19",
+ "5.160.146.199",
+ "5.160.146.233",
+ "5.160.147.18",
+ "5.160.147.226",
+ "5.160.148.49",
+ "5.160.150.138",
+ "5.160.150.139",
+ "5.160.150.140",
+ "5.160.151.204",
+ "5.160.151.206",
+ "5.160.152.166",
+ "5.160.157.75",
+ "5.160.157.100",
+ "5.160.159.84",
+ "5.160.159.178",
+ "5.160.159.181",
+ "5.160.159.189",
+ "5.160.160.42",
+ "5.160.161.5",
+ "5.160.161.18",
+ "5.160.161.19",
+ "5.160.161.33",
+ "5.160.161.41",
+ "5.160.161.45",
+ "5.160.161.62",
+ "5.160.161.66",
+ "5.160.161.73",
+ "5.160.161.84",
+ "5.160.161.98",
+ "5.160.161.99",
+ "5.160.161.101",
+ "5.160.161.117",
+ "5.160.161.121",
+ "5.160.161.122",
+ "5.160.161.123",
+ "5.160.161.127",
+ "5.160.161.129",
+ "5.160.161.142",
+ "5.160.161.148",
+ "5.160.161.152",
+ "5.160.161.168",
+ "5.160.161.176",
+ "5.160.161.179",
+ "5.160.161.180",
+ "5.160.161.187",
+ "5.160.161.197",
+ "5.160.161.200",
+ "5.160.161.219",
+ "5.160.162.43",
+ "5.160.162.44",
+ "5.160.164.86",
+ "5.160.164.93",
+ "5.160.164.211",
+ "5.160.166.20",
+ "5.160.167.14",
+ "5.160.167.60",
+ "5.160.168.10",
+ "5.160.168.85",
+ "5.160.168.130",
+ "5.160.170.2",
+ "5.160.171.36",
+ "5.160.171.47",
+ "5.160.173.151",
+ "5.160.173.190",
+ "5.160.175.250",
+ "5.160.176.27",
+ "5.160.176.165",
+ "5.160.176.208",
+ "5.160.176.222",
+ "5.160.176.242",
+ "5.160.176.243",
+ "5.160.176.245",
+ "5.160.177.6",
+ "5.160.178.50",
+ "5.160.178.155",
+ "5.160.178.157",
+ "5.160.182.45",
+ "5.160.182.65",
+ "5.160.182.73",
+ "5.160.182.77",
+ "5.160.182.85",
+ "5.160.182.88",
+ "5.160.182.90",
+ "5.160.182.101",
+ "5.160.182.111",
+ "5.160.182.119",
+ "5.160.182.127",
+ "5.160.182.130",
+ "5.160.182.146",
+ "5.160.182.155",
+ "5.160.182.168",
+ "5.160.182.180",
+ "5.160.182.184",
+ "5.160.182.197",
+ "5.160.182.201",
+ "5.160.182.208",
+ "5.160.182.211",
+ "5.160.182.219",
+ "5.160.182.228",
+ "5.160.182.229",
+ "5.160.182.236",
+ "5.160.182.245",
+ "5.160.183.150",
+ "5.160.184.90",
+ "5.160.184.202",
+ "5.160.185.86",
+ "5.160.185.122",
+ "5.160.185.222",
+ "5.160.186.14",
+ "5.160.186.42",
+ "5.160.186.43",
+ "5.160.186.44",
+ "5.160.186.45",
+ "5.160.187.44",
+ "5.160.187.78",
+ "5.160.187.98",
+ "5.160.187.122",
+ "5.160.187.126",
+ "5.160.187.247",
+ "5.160.187.254",
+ "5.160.190.34",
+ "5.160.190.38",
+ "5.160.191.197",
+ "5.160.191.242",
+ "5.160.191.243",
+ "5.160.196.126",
+ "5.160.196.210",
+ "5.160.197.207",
+ "5.160.200.182",
+ "5.160.211.170",
+ "5.160.211.218",
+ "5.160.211.219",
+ "5.160.211.220",
+ "5.160.214.110",
+ "5.160.215.230",
+ "5.160.217.254",
+ "5.160.218.167",
+ "5.160.219.72",
+ "5.160.223.254",
+ "5.160.224.225",
+ "5.160.224.226",
+ "5.160.224.227",
+ "5.160.224.228",
+ "5.160.224.229",
+ "5.160.225.66",
+ "5.160.225.116",
+ "5.160.225.163",
+ "5.160.225.174",
+ "5.160.227.238",
+ "5.160.228.190",
+ "5.160.229.187",
+ "5.160.229.234",
+ "5.160.230.130",
+ "5.160.230.250",
+ "5.160.231.10",
+ "5.160.231.130",
+ "5.160.231.214",
+ "5.160.233.16",
+ "5.160.233.150",
+ "5.160.233.226",
+ "5.160.234.189",
+ "5.160.235.130",
+ "5.160.236.155",
+ "5.160.236.158",
+ "5.160.236.216",
+ "5.160.237.118",
+ "5.160.237.208",
+ "5.160.239.98",
+ "5.160.239.226",
+ "5.160.239.250",
+ "5.160.239.251",
+ "5.160.242.48",
+ "5.160.243.107",
+ "5.160.243.238",
+ "5.160.243.254",
+ "5.160.246.29",
+ "5.160.247.50",
+ "5.160.247.230",
+ "5.182.44.18",
+ "5.182.44.124",
+ "5.182.44.132",
+ "5.182.44.134",
+ "5.182.44.161",
+ "5.182.44.184",
+ "5.182.44.190",
+ "5.182.46.185",
+ "5.190.0.68",
+ "5.190.0.178",
+ "5.190.1.71",
+ "5.190.1.79",
+ "5.190.1.145",
+ "5.190.1.161",
+ "5.190.3.109",
+ "5.190.3.110",
+ "5.190.3.113",
+ "5.190.4.17",
+ "5.190.4.249",
+ "5.190.6.41",
+ "5.190.6.73",
+ "5.190.6.241",
+ "5.190.7.113",
+ "5.190.20.1",
+ "5.190.29.161",
+ "5.190.45.70",
+ "5.190.52.225",
+ "5.190.53.6",
+ "5.190.60.161",
+ "5.190.69.68",
+ "5.190.69.70",
+ "5.190.69.73",
+ "5.190.69.74",
+ "5.190.69.75",
+ "5.190.69.80",
+ "5.190.69.89",
+ "5.190.72.113",
+ "5.190.83.70",
+ "5.190.83.77",
+ "5.190.84.112",
+ "5.190.89.101",
+ "5.190.93.133",
+ "5.190.103.130",
+ "5.190.106.210",
+ "5.190.131.1",
+ "5.190.131.230",
+ "5.190.135.173",
+ "5.190.138.125",
+ "5.190.143.81",
+ "5.190.147.1",
+ "5.190.147.3",
+ "5.190.154.164",
+ "5.190.156.3",
+ "5.190.156.4",
+ "5.190.212.241",
+ "5.190.212.242",
+ "5.190.212.243",
+ "5.190.212.245",
+ "5.190.212.246",
+ "5.190.212.247",
+ "5.190.212.251",
+ "5.190.212.252",
+ "5.190.224.15",
+ "5.190.224.23",
+ "5.190.224.27",
+ "5.190.224.37",
+ "5.190.224.39",
+ "5.190.235.10",
+ "5.190.235.35",
+ "5.190.235.74",
+ "5.190.235.81",
+ "5.190.235.117",
+ "5.190.235.131",
+ "5.190.235.160",
+ "5.190.235.163",
+ "5.190.235.168",
+ "5.190.235.171",
+ "5.190.235.183",
+ "5.190.235.196",
+ "5.190.235.209",
+ "5.190.235.214",
+ "5.190.235.247",
+ "5.190.235.249",
+ "5.190.235.254",
+ "5.198.161.12",
+ "5.198.178.64",
+ "5.198.178.80",
+ "5.198.178.160",
+ "5.198.178.180",
+ "5.198.178.237",
+ "5.198.179.20",
+ "5.198.179.50",
+ "5.198.179.130",
+ "5.198.179.190",
+ "5.200.64.193",
+ "5.200.67.24",
+ "5.200.69.30",
+ "5.200.73.82",
+ "5.200.73.83",
+ "5.200.73.84",
+ "5.200.73.162",
+ "5.200.74.66",
+ "5.200.74.90",
+ "5.200.74.91",
+ "5.200.74.92",
+ "5.200.79.14",
+ "5.200.84.129",
+ "5.200.94.45",
+ "5.200.151.10",
+ "5.200.160.21",
+ "5.200.161.223",
+ "5.200.165.21",
+ "5.200.177.233",
+ "5.200.194.25",
+ "5.200.200.26",
+ "5.200.217.213",
+ "5.200.240.10",
+ "5.200.246.248",
+ "5.201.128.76",
+ "5.201.129.44",
+ "5.201.130.70",
+ "5.201.130.106",
+ "5.201.131.60",
+ "5.201.132.27",
+ "5.201.132.139",
+ "5.201.132.143",
+ "5.201.132.201",
+ "5.201.132.246",
+ "5.201.133.78",
+ "5.201.133.162",
+ "5.201.134.23",
+ "5.201.134.222",
+ "5.201.135.104",
+ "5.201.135.127",
+ "5.201.135.162",
+ "5.201.136.54",
+ "5.201.137.187",
+ "5.201.138.9",
+ "5.201.139.194",
+ "5.201.141.202",
+ "5.201.141.246",
+ "5.201.142.74",
+ "5.201.142.205",
+ "5.201.142.220",
+ "5.201.143.155",
+ "5.201.144.80",
+ "5.201.148.92",
+ "5.201.150.103",
+ "5.201.151.139",
+ "5.201.152.225",
+ "5.201.154.29",
+ "5.201.154.149",
+ "5.201.156.81",
+ "5.201.159.173",
+ "5.201.161.182",
+ "5.201.161.210",
+ "5.201.161.211",
+ "5.201.161.212",
+ "5.201.161.213",
+ "5.201.162.150",
+ "5.201.164.167",
+ "5.201.166.105",
+ "5.201.166.132",
+ "5.201.166.143",
+ "5.201.166.182",
+ "5.201.167.42",
+ "5.201.167.223",
+ "5.201.168.123",
+ "5.201.169.48",
+ "5.201.169.124",
+ "5.201.169.191",
+ "5.201.170.24",
+ "5.201.171.57",
+ "5.201.175.251",
+ "5.201.176.244",
+ "5.201.177.48",
+ "5.201.177.68",
+ "5.201.177.93",
+ "5.201.178.6",
+ "5.201.178.10",
+ "5.201.180.250",
+ "5.201.181.247",
+ "5.201.183.202",
+ "5.201.184.237",
+ "5.201.185.40",
+ "5.201.185.163",
+ "5.201.187.150",
+ "5.201.187.226",
+ "5.201.190.57",
+ "5.201.190.239",
+ "5.201.191.11",
+ "5.201.191.114",
+ "5.201.191.255",
+ "5.202.5.114",
+ "5.202.6.77",
+ "5.202.6.129",
+ "5.202.6.194",
+ "5.202.6.196",
+ "5.202.6.197",
+ "5.202.6.204",
+ "5.202.6.206",
+ "5.202.7.19",
+ "5.202.7.226",
+ "5.202.7.230",
+ "5.202.7.232",
+ "5.202.7.234",
+ "5.202.7.238",
+ "5.202.8.43",
+ "5.202.8.186",
+ "5.202.8.187",
+ "5.202.10.40",
+ "5.202.15.213",
+ "5.202.15.218",
+ "5.202.15.219",
+ "5.202.15.222",
+ "5.202.18.113",
+ "5.202.18.134",
+ "5.202.18.169",
+ "5.202.18.208",
+ "5.202.18.210",
+ "5.202.18.211",
+ "5.202.18.212",
+ "5.202.18.213",
+ "5.202.18.216",
+ "5.202.18.217",
+ "5.202.18.218",
+ "5.202.18.219",
+ "5.202.18.220",
+ "5.202.18.221",
+ "5.202.18.222",
+ "5.202.18.223",
+ "5.202.20.11",
+ "5.202.20.17",
+ "5.202.20.44",
+ "5.202.20.53",
+ "5.202.20.54",
+ "5.202.20.60",
+ "5.202.20.79",
+ "5.202.20.81",
+ "5.202.20.149",
+ "5.202.20.157",
+ "5.202.20.161",
+ "5.202.20.173",
+ "5.202.20.178",
+ "5.202.20.184",
+ "5.202.20.196",
+ "5.202.20.197",
+ "5.202.20.207",
+ "5.202.20.242",
+ "5.202.21.11",
+ "5.202.21.45",
+ "5.202.21.57",
+ "5.202.21.91",
+ "5.202.21.136",
+ "5.202.21.137",
+ "5.202.21.245",
+ "5.202.27.14",
+ "5.202.27.142",
+ "5.202.29.35",
+ "5.202.29.196",
+ "5.202.31.64",
+ "5.202.31.65",
+ "5.202.33.2",
+ "5.202.33.9",
+ "5.202.33.11",
+ "5.202.33.32",
+ "5.202.33.50",
+ "5.202.33.68",
+ "5.202.33.86",
+ "5.202.33.123",
+ "5.202.33.126",
+ "5.202.33.151",
+ "5.202.33.165",
+ "5.202.33.179",
+ "5.202.33.216",
+ "5.202.33.237",
+ "5.202.39.129",
+ "5.202.44.20",
+ "5.202.44.103",
+ "5.202.44.106",
+ "5.202.44.112",
+ "5.202.44.162",
+ "5.202.44.181",
+ "5.202.44.189",
+ "5.202.44.192",
+ "5.202.44.196",
+ "5.202.44.208",
+ "5.202.44.222",
+ "5.202.44.229",
+ "5.202.45.20",
+ "5.202.45.41",
+ "5.202.45.53",
+ "5.202.45.67",
+ "5.202.45.92",
+ "5.202.45.110",
+ "5.202.45.130",
+ "5.202.45.185",
+ "5.202.45.201",
+ "5.202.45.233",
+ "5.202.46.0",
+ "5.202.46.13",
+ "5.202.46.38",
+ "5.202.46.69",
+ "5.202.46.74",
+ "5.202.46.98",
+ "5.202.46.109",
+ "5.202.46.124",
+ "5.202.46.162",
+ "5.202.46.182",
+ "5.202.46.191",
+ "5.202.46.210",
+ "5.202.46.221",
+ "5.202.47.0",
+ "5.202.47.5",
+ "5.202.47.29",
+ "5.202.47.64",
+ "5.202.47.71",
+ "5.202.47.107",
+ "5.202.47.108",
+ "5.202.47.141",
+ "5.202.47.215",
+ "5.202.47.253",
+ "5.202.47.255",
+ "5.202.50.73",
+ "5.202.50.113",
+ "5.202.50.114",
+ "5.202.50.115",
+ "5.202.50.116",
+ "5.202.50.118",
+ "5.202.51.81",
+ "5.202.51.82",
+ "5.202.51.83",
+ "5.202.51.84",
+ "5.202.52.6",
+ "5.202.52.81",
+ "5.202.52.138",
+ "5.202.52.155",
+ "5.202.53.100",
+ "5.202.53.158",
+ "5.202.53.161",
+ "5.202.53.174",
+ "5.202.53.186",
+ "5.202.60.14",
+ "5.202.60.202",
+ "5.202.60.242",
+ "5.202.61.160",
+ "5.202.61.192",
+ "5.202.63.40",
+ "5.202.63.58",
+ "5.202.63.60",
+ "5.202.63.62",
+ "5.202.63.125",
+ "5.202.63.210",
+ "5.202.66.2",
+ "5.202.66.9",
+ "5.202.67.1",
+ "5.202.67.134",
+ "5.202.68.10",
+ "5.202.68.13",
+ "5.202.68.14",
+ "5.202.68.18",
+ "5.202.68.21",
+ "5.202.68.23",
+ "5.202.68.34",
+ "5.202.68.38",
+ "5.202.68.65",
+ "5.202.68.90",
+ "5.202.68.116",
+ "5.202.68.150",
+ "5.202.73.50",
+ "5.202.73.134",
+ "5.202.77.46",
+ "5.202.77.53",
+ "5.202.78.8",
+ "5.202.78.18",
+ "5.202.78.23",
+ "5.202.78.35",
+ "5.202.79.163",
+ "5.202.79.164",
+ "5.202.79.194",
+ "5.202.79.203",
+ "5.202.79.210",
+ "5.202.79.213",
+ "5.202.79.214",
+ "5.202.79.215",
+ "5.202.79.217",
+ "5.202.79.220",
+ "5.202.79.222",
+ "5.202.79.225",
+ "5.202.79.227",
+ "5.202.79.228",
+ "5.202.79.229",
+ "5.202.82.102",
+ "5.202.82.118",
+ "5.202.82.146",
+ "5.202.82.190",
+ "5.202.83.5",
+ "5.202.83.59",
+ "5.202.83.102",
+ "5.202.83.118",
+ "5.202.84.9",
+ "5.202.84.21",
+ "5.202.84.47",
+ "5.202.84.63",
+ "5.202.84.68",
+ "5.202.84.85",
+ "5.202.84.101",
+ "5.202.84.150",
+ "5.202.84.152",
+ "5.202.84.161",
+ "5.202.84.178",
+ "5.202.84.207",
+ "5.202.84.219",
+ "5.202.84.247",
+ "5.202.85.43",
+ "5.202.85.66",
+ "5.202.85.154",
+ "5.202.85.186",
+ "5.202.85.255",
+ "5.202.86.26",
+ "5.202.89.41",
+ "5.202.89.89",
+ "5.202.89.90",
+ "5.202.90.40",
+ "5.202.90.51",
+ "5.202.90.56",
+ "5.202.90.79",
+ "5.202.90.93",
+ "5.202.90.99",
+ "5.202.90.103",
+ "5.202.90.157",
+ "5.202.90.170",
+ "5.202.90.195",
+ "5.202.90.196",
+ "5.202.90.204",
+ "5.202.90.214",
+ "5.202.90.221",
+ "5.202.93.144",
+ "5.202.93.207",
+ "5.202.96.3",
+ "5.202.96.9",
+ "5.202.96.10",
+ "5.202.96.11",
+ "5.202.96.31",
+ "5.202.96.32",
+ "5.202.96.37",
+ "5.202.96.38",
+ "5.202.96.49",
+ "5.202.96.50",
+ "5.202.96.51",
+ "5.202.96.57",
+ "5.202.96.66",
+ "5.202.96.78",
+ "5.202.96.83",
+ "5.202.96.87",
+ "5.202.96.92",
+ "5.202.96.101",
+ "5.202.96.109",
+ "5.202.96.111",
+ "5.202.96.118",
+ "5.202.96.121",
+ "5.202.96.126",
+ "5.202.96.131",
+ "5.202.96.134",
+ "5.202.96.140",
+ "5.202.96.146",
+ "5.202.96.147",
+ "5.202.96.160",
+ "5.202.96.164",
+ "5.202.96.171",
+ "5.202.96.175",
+ "5.202.96.177",
+ "5.202.97.19",
+ "5.202.97.20",
+ "5.202.97.23",
+ "5.202.97.24",
+ "5.202.97.46",
+ "5.202.97.49",
+ "5.202.97.51",
+ "5.202.97.59",
+ "5.202.97.74",
+ "5.202.97.79",
+ "5.202.97.81",
+ "5.202.97.93",
+ "5.202.97.94",
+ "5.202.97.100",
+ "5.202.97.103",
+ "5.202.97.107",
+ "5.202.97.124",
+ "5.202.97.126",
+ "5.202.97.128",
+ "5.202.101.89",
+ "5.202.104.12",
+ "5.202.104.14",
+ "5.202.104.34",
+ "5.202.104.62",
+ "5.202.104.158",
+ "5.202.104.166",
+ "5.202.104.220",
+ "5.202.105.9",
+ "5.202.105.24",
+ "5.202.105.31",
+ "5.202.105.104",
+ "5.202.105.111",
+ "5.202.105.119",
+ "5.202.105.120",
+ "5.202.105.154",
+ "5.202.105.208",
+ "5.202.105.229",
+ "5.202.105.240",
+ "5.202.105.253",
+ "5.202.112.10",
+ "5.202.112.118",
+ "5.202.112.154",
+ "5.202.112.191",
+ "5.202.112.197",
+ "5.202.114.92",
+ "5.202.120.35",
+ "5.202.120.43",
+ "5.202.120.82",
+ "5.202.120.96",
+ "5.202.120.97",
+ "5.202.120.114",
+ "5.202.120.123",
+ "5.202.120.126",
+ "5.202.120.163",
+ "5.202.120.164",
+ "5.202.120.169",
+ "5.202.121.5",
+ "5.202.121.6",
+ "5.202.121.26",
+ "5.202.121.154",
+ "5.202.121.164",
+ "5.202.121.222",
+ "5.202.128.225",
+ "5.202.130.2",
+ "5.202.130.7",
+ "5.202.130.41",
+ "5.202.130.89",
+ "5.202.130.110",
+ "5.202.130.112",
+ "5.202.130.179",
+ "5.202.130.188",
+ "5.202.130.195",
+ "5.202.130.208",
+ "5.202.130.213",
+ "5.202.130.223",
+ "5.202.130.224",
+ "5.202.130.237",
+ "5.202.130.239",
+ "5.202.130.244",
+ "5.202.130.249",
+ "5.202.131.12",
+ "5.202.131.21",
+ "5.202.131.37",
+ "5.202.131.38",
+ "5.202.131.59",
+ "5.202.131.68",
+ "5.202.131.95",
+ "5.202.131.151",
+ "5.202.131.152",
+ "5.202.131.160",
+ "5.202.131.161",
+ "5.202.131.162",
+ "5.202.131.170",
+ "5.202.131.190",
+ "5.202.131.199",
+ "5.202.131.203",
+ "5.202.131.209",
+ "5.202.131.212",
+ "5.202.131.224",
+ "5.202.132.5",
+ "5.202.132.9",
+ "5.202.132.36",
+ "5.202.132.43",
+ "5.202.132.55",
+ "5.202.132.77",
+ "5.202.132.83",
+ "5.202.132.97",
+ "5.202.132.119",
+ "5.202.132.123",
+ "5.202.132.124",
+ "5.202.132.128",
+ "5.202.132.133",
+ "5.202.132.150",
+ "5.202.132.189",
+ "5.202.132.193",
+ "5.202.132.197",
+ "5.202.132.200",
+ "5.202.132.204",
+ "5.202.132.217",
+ "5.202.132.228",
+ "5.202.132.231",
+ "5.202.132.232",
+ "5.202.132.233",
+ "5.202.132.252",
+ "5.202.132.254",
+ "5.202.133.0",
+ "5.202.133.3",
+ "5.202.133.40",
+ "5.202.133.50",
+ "5.202.133.56",
+ "5.202.133.60",
+ "5.202.133.69",
+ "5.202.133.84",
+ "5.202.133.110",
+ "5.202.133.135",
+ "5.202.133.139",
+ "5.202.133.144",
+ "5.202.133.146",
+ "5.202.133.160",
+ "5.202.133.163",
+ "5.202.133.166",
+ "5.202.133.168",
+ "5.202.133.231",
+ "5.202.133.244",
+ "5.202.134.9",
+ "5.202.134.38",
+ "5.202.134.74",
+ "5.202.134.99",
+ "5.202.134.117",
+ "5.202.134.131",
+ "5.202.134.133",
+ "5.202.134.166",
+ "5.202.134.180",
+ "5.202.134.196",
+ "5.202.134.252",
+ "5.202.135.8",
+ "5.202.135.14",
+ "5.202.135.17",
+ "5.202.135.23",
+ "5.202.135.65",
+ "5.202.135.93",
+ "5.202.135.96",
+ "5.202.135.119",
+ "5.202.135.132",
+ "5.202.135.134",
+ "5.202.135.140",
+ "5.202.135.155",
+ "5.202.135.162",
+ "5.202.135.165",
+ "5.202.135.201",
+ "5.202.135.221",
+ "5.202.135.226",
+ "5.202.135.236",
+ "5.202.135.243",
+ "5.202.135.254",
+ "5.202.136.0",
+ "5.202.136.3",
+ "5.202.140.48",
+ "5.202.140.49",
+ "5.202.140.50",
+ "5.202.140.51",
+ "5.202.140.52",
+ "5.202.140.53",
+ "5.202.140.54",
+ "5.202.140.55",
+ "5.202.140.65",
+ "5.202.140.66",
+ "5.202.140.67",
+ "5.202.140.68",
+ "5.202.140.69",
+ "5.202.140.70",
+ "5.202.140.80",
+ "5.202.140.82",
+ "5.202.140.83",
+ "5.202.140.84",
+ "5.202.140.85",
+ "5.202.140.86",
+ "5.202.140.87",
+ "5.202.140.88",
+ "5.202.140.89",
+ "5.202.140.90",
+ "5.202.140.91",
+ "5.202.140.93",
+ "5.202.140.94",
+ "5.202.162.67",
+ "5.202.162.75",
+ "5.202.162.76",
+ "5.202.163.9",
+ "5.202.163.13",
+ "5.202.163.80",
+ "5.202.163.158",
+ "5.202.163.183",
+ "5.202.164.118",
+ "5.202.165.112",
+ "5.202.166.250",
+ "5.202.166.254",
+ "5.202.167.1",
+ "5.202.167.30",
+ "5.202.167.108",
+ "5.202.167.222",
+ "5.202.167.252",
+ "5.202.168.0",
+ "5.202.168.18",
+ "5.202.168.53",
+ "5.202.168.71",
+ "5.202.168.93",
+ "5.202.168.117",
+ "5.202.168.133",
+ "5.202.168.140",
+ "5.202.168.149",
+ "5.202.168.166",
+ "5.202.168.173",
+ "5.202.168.178",
+ "5.202.168.180",
+ "5.202.168.196",
+ "5.202.168.207",
+ "5.202.168.211",
+ "5.202.169.2",
+ "5.202.169.29",
+ "5.202.169.33",
+ "5.202.169.38",
+ "5.202.169.80",
+ "5.202.169.119",
+ "5.202.169.142",
+ "5.202.169.145",
+ "5.202.169.155",
+ "5.202.169.161",
+ "5.202.169.162",
+ "5.202.169.191",
+ "5.202.169.192",
+ "5.202.169.198",
+ "5.202.170.33",
+ "5.202.170.63",
+ "5.202.170.100",
+ "5.202.170.110",
+ "5.202.170.111",
+ "5.202.170.145",
+ "5.202.170.153",
+ "5.202.170.163",
+ "5.202.170.178",
+ "5.202.170.181",
+ "5.202.170.187",
+ "5.202.170.214",
+ "5.202.170.219",
+ "5.202.170.242",
+ "5.202.171.35",
+ "5.202.171.45",
+ "5.202.171.62",
+ "5.202.171.68",
+ "5.202.171.82",
+ "5.202.171.102",
+ "5.202.171.105",
+ "5.202.171.108",
+ "5.202.171.120",
+ "5.202.171.124",
+ "5.202.171.128",
+ "5.202.171.229",
+ "5.202.172.3",
+ "5.202.172.14",
+ "5.202.172.27",
+ "5.202.172.36",
+ "5.202.172.56",
+ "5.202.172.65",
+ "5.202.172.67",
+ "5.202.172.70",
+ "5.202.172.134",
+ "5.202.172.157",
+ "5.202.172.176",
+ "5.202.172.189",
+ "5.202.172.200",
+ "5.202.172.225",
+ "5.202.172.233",
+ "5.202.172.237",
+ "5.202.172.239",
+ "5.202.172.254",
+ "5.202.174.27",
+ "5.202.174.28",
+ "5.202.174.33",
+ "5.202.174.56",
+ "5.202.174.73",
+ "5.202.174.90",
+ "5.202.174.170",
+ "5.202.174.183",
+ "5.202.174.225",
+ "5.202.174.229",
+ "5.202.174.233",
+ "5.202.174.245",
+ "5.202.175.1",
+ "5.202.175.46",
+ "5.202.175.52",
+ "5.202.175.121",
+ "5.202.175.143",
+ "5.202.175.148",
+ "5.202.175.165",
+ "5.202.175.169",
+ "5.202.175.179",
+ "5.202.175.193",
+ "5.202.175.207",
+ "5.202.175.227",
+ "5.202.175.242",
+ "5.202.176.154",
+ "5.202.176.166",
+ "5.202.176.170",
+ "5.202.177.45",
+ "5.202.177.50",
+ "5.202.177.51",
+ "5.202.177.52",
+ "5.202.177.53",
+ "5.202.177.54",
+ "5.202.177.114",
+ "5.202.177.115",
+ "5.202.177.116",
+ "5.202.177.118",
+ "5.202.177.122",
+ "5.202.177.166",
+ "5.202.177.194",
+ "5.202.177.195",
+ "5.202.177.196",
+ "5.202.177.197",
+ "5.202.177.198",
+ "5.202.177.254",
+ "5.202.178.67",
+ "5.202.178.86",
+ "5.202.179.2",
+ "5.202.179.3",
+ "5.202.179.4",
+ "5.202.179.5",
+ "5.202.179.6",
+ "5.202.179.7",
+ "5.202.179.8",
+ "5.202.179.9",
+ "5.202.179.10",
+ "5.202.179.12",
+ "5.202.179.13",
+ "5.202.179.14",
+ "5.202.179.50",
+ "5.202.179.138",
+ "5.202.179.170",
+ "5.202.179.171",
+ "5.202.179.172",
+ "5.202.179.173",
+ "5.202.179.174",
+ "5.202.180.46",
+ "5.202.182.2",
+ "5.202.182.102",
+ "5.202.182.210",
+ "5.202.182.222",
+ "5.202.184.90",
+ "5.202.184.242",
+ "5.202.185.38",
+ "5.202.185.206",
+ "5.202.186.70",
+ "5.202.186.229",
+ "5.202.188.2",
+ "5.202.188.211",
+ "5.202.188.212",
+ "5.202.188.213",
+ "5.202.189.18",
+ "5.202.189.242",
+ "5.202.190.14",
+ "5.202.190.18",
+ "5.202.190.19",
+ "5.202.190.20",
+ "5.202.190.217",
+ "5.202.191.42",
+ "5.202.191.78",
+ "5.202.191.126",
+ "5.202.191.186",
+ "5.202.191.225",
+ "5.202.191.245",
+ "5.202.193.14",
+ "5.202.193.29",
+ "5.202.193.61",
+ "5.202.193.62",
+ "5.202.193.77",
+ "5.202.193.85",
+ "5.202.193.102",
+ "5.202.193.115",
+ "5.202.193.134",
+ "5.202.193.147",
+ "5.202.193.152",
+ "5.202.193.210",
+ "5.202.193.225",
+ "5.202.193.229",
+ "5.202.194.249",
+ "5.202.195.4",
+ "5.202.195.14",
+ "5.202.195.16",
+ "5.202.195.83",
+ "5.202.195.97",
+ "5.202.195.133",
+ "5.202.195.143",
+ "5.202.195.147",
+ "5.202.195.162",
+ "5.202.195.165",
+ "5.202.195.205",
+ "5.202.195.217",
+ "5.202.196.7",
+ "5.202.196.14",
+ "5.202.196.16",
+ "5.202.196.35",
+ "5.202.196.54",
+ "5.202.196.62",
+ "5.202.196.75",
+ "5.202.196.76",
+ "5.202.196.81",
+ "5.202.196.103",
+ "5.202.196.105",
+ "5.202.196.184",
+ "5.202.196.198",
+ "5.202.196.206",
+ "5.202.196.246",
+ "5.202.196.253",
+ "5.202.197.2",
+ "5.202.197.3",
+ "5.202.197.9",
+ "5.202.197.27",
+ "5.202.197.60",
+ "5.202.197.61",
+ "5.202.197.102",
+ "5.202.197.103",
+ "5.202.197.111",
+ "5.202.197.201",
+ "5.202.197.217",
+ "5.202.197.224",
+ "5.202.197.227",
+ "5.202.197.241",
+ "5.202.198.11",
+ "5.202.198.23",
+ "5.202.198.27",
+ "5.202.198.69",
+ "5.202.198.79",
+ "5.202.198.85",
+ "5.202.198.102",
+ "5.202.198.107",
+ "5.202.198.116",
+ "5.202.198.124",
+ "5.202.198.136",
+ "5.202.206.115",
+ "5.202.236.68",
+ "5.202.239.59",
+ "5.202.240.32",
+ "5.202.240.34",
+ "5.202.240.35",
+ "5.202.240.38",
+ "5.202.240.39",
+ "5.202.240.42",
+ "5.202.240.45",
+ "5.202.241.54",
+ "5.202.243.0",
+ "5.202.243.4",
+ "5.202.243.5",
+ "5.202.243.106",
+ "5.202.243.134",
+ "5.202.243.142",
+ "5.202.243.147",
+ "5.202.243.157",
+ "5.202.243.165",
+ "5.202.243.191",
+ "5.202.243.226",
+ "5.202.244.4",
+ "5.202.244.38",
+ "5.202.244.44",
+ "5.202.244.98",
+ "5.202.244.127",
+ "5.202.244.129",
+ "5.202.244.134",
+ "5.202.244.181",
+ "5.202.244.184",
+ "5.202.244.211",
+ "5.202.245.11",
+ "5.202.245.38",
+ "5.202.245.42",
+ "5.202.248.20",
+ "5.202.248.36",
+ "5.202.248.47",
+ "5.202.248.48",
+ "5.202.248.58",
+ "5.202.248.68",
+ "5.202.248.70",
+ "5.202.248.74",
+ "5.202.248.78",
+ "5.202.248.93",
+ "5.202.248.106",
+ "5.202.248.107",
+ "5.202.248.111",
+ "5.202.248.148",
+ "5.202.248.190",
+ "5.202.248.194",
+ "5.202.248.196",
+ "5.202.248.200",
+ "5.202.248.219",
+ "5.202.249.21",
+ "5.202.249.169",
+ "5.202.249.170",
+ "5.202.249.178",
+ "5.202.250.10",
+ "5.202.250.81",
+ "5.202.250.153",
+ "5.202.250.155",
+ "5.202.250.156",
+ "5.202.250.157",
+ "5.202.251.32",
+ "5.202.251.46",
+ "5.202.251.57",
+ "5.202.251.80",
+ "5.202.251.94",
+ "5.202.251.116",
+ "5.202.251.152",
+ "5.202.251.162",
+ "5.202.251.212",
+ "5.202.251.235",
+ "5.202.251.237",
+ "5.202.251.243",
+ "5.202.251.254",
+ "5.202.252.27",
+ "5.202.252.28",
+ "5.202.252.29",
+ "5.202.252.126",
+ "5.202.252.250",
+ "5.202.252.252",
+ "5.202.252.253",
+ "5.202.253.3",
+ "5.202.253.6",
+ "5.202.253.10",
+ "5.202.253.11",
+ "5.202.253.13",
+ "5.202.253.14",
+ "5.202.253.46",
+ "5.202.253.52",
+ "5.202.253.53",
+ "5.202.253.54",
+ "5.202.253.122",
+ "5.202.253.146",
+ "5.202.254.10",
+ "5.202.254.18",
+ "5.202.254.29",
+ "5.202.254.154",
+ "5.202.254.174",
+ "5.202.254.242",
+ "5.202.255.107",
+ "5.202.255.108",
+ "5.219.64.1",
+ "5.219.128.1",
+ "5.232.97.110",
+ "5.232.103.33",
+ "5.232.104.21",
+ "5.232.116.189",
+ "5.232.119.40",
+ "5.232.119.66",
+ "5.232.124.227",
+ "5.232.126.173",
+ "5.232.128.72",
+ "5.232.128.198",
+ "5.232.132.201",
+ "5.232.140.84",
+ "5.232.140.119",
+ "5.232.141.89",
+ "5.232.144.160",
+ "5.232.149.174",
+ "5.232.155.22",
+ "5.232.157.90",
+ "5.232.176.234",
+ "5.232.177.130",
+ "5.232.177.148",
+ "5.232.178.50",
+ "5.232.178.196",
+ "5.232.179.44",
+ "5.232.179.185",
+ "5.232.181.38",
+ "5.232.181.208",
+ "5.232.182.146",
+ "5.232.183.4",
+ "5.232.184.206",
+ "5.232.185.3",
+ "5.232.185.61",
+ "5.232.185.215",
+ "5.232.186.151",
+ "5.232.186.218",
+ "5.232.186.219",
+ "5.232.187.186",
+ "5.232.188.152",
+ "5.232.188.188",
+ "5.232.189.68",
+ "5.232.189.145",
+ "5.232.190.238",
+ "5.232.191.43",
+ "5.232.191.97",
+ "5.232.192.52",
+ "5.232.192.99",
+ "5.232.192.180",
+ "5.232.193.62",
+ "5.232.193.180",
+ "5.232.193.202",
+ "5.232.193.222",
+ "5.232.194.139",
+ "5.232.194.165",
+ "5.232.195.238",
+ "5.232.196.102",
+ "5.232.197.1",
+ "5.232.197.13",
+ "5.232.197.158",
+ "5.232.197.168",
+ "5.232.197.200",
+ "5.232.198.17",
+ "5.232.199.18",
+ "5.232.199.107",
+ "5.232.199.148",
+ "5.232.200.85",
+ "5.232.201.113",
+ "5.232.201.169",
+ "5.232.201.232",
+ "5.232.201.250",
+ "5.232.202.205",
+ "5.232.202.216",
+ "5.232.204.169",
+ "5.232.205.170",
+ "5.232.207.56",
+ "5.232.208.249",
+ "5.232.209.119",
+ "5.232.211.28",
+ "5.232.213.42",
+ "5.232.213.59",
+ "5.232.213.136",
+ "5.232.214.164",
+ "5.232.215.34",
+ "5.232.215.220",
+ "5.232.215.226",
+ "5.232.238.245",
+ "5.233.44.59",
+ "5.233.44.61",
+ "5.233.94.81",
+ "5.233.94.140",
+ "5.233.94.174",
+ "5.233.205.157",
+ "5.233.205.182",
+ "5.233.248.224",
+ "5.233.249.52",
+ "5.233.254.88",
+ "5.233.254.232",
+ "5.233.255.221",
+ "5.234.0.57",
+ "5.234.0.96",
+ "5.234.0.203",
+ "5.234.2.29",
+ "5.234.2.132",
+ "5.234.3.51",
+ "5.234.3.194",
+ "5.234.5.251",
+ "5.234.10.9",
+ "5.234.11.43",
+ "5.234.12.47",
+ "5.234.13.112",
+ "5.234.14.122",
+ "5.234.14.219",
+ "5.234.15.194",
+ "5.234.19.84",
+ "5.234.20.156",
+ "5.234.20.211",
+ "5.234.21.169",
+ "5.234.21.250",
+ "5.234.22.63",
+ "5.234.24.218",
+ "5.234.25.103",
+ "5.234.26.54",
+ "5.234.26.138",
+ "5.234.26.148",
+ "5.234.28.73",
+ "5.234.28.126",
+ "5.234.28.147",
+ "5.234.29.197",
+ "5.234.32.10",
+ "5.234.32.62",
+ "5.234.32.75",
+ "5.234.32.129",
+ "5.234.33.230",
+ "5.234.34.89",
+ "5.234.35.195",
+ "5.234.44.68",
+ "5.234.44.226",
+ "5.234.46.178",
+ "5.234.68.222",
+ "5.234.91.74",
+ "5.234.166.182",
+ "5.234.179.43",
+ "5.234.215.102",
+ "5.235.152.156",
+ "5.235.152.182",
+ "5.235.153.120",
+ "5.235.155.61",
+ "5.235.155.221",
+ "5.235.156.42",
+ "5.235.156.147",
+ "5.235.156.149",
+ "5.235.157.238",
+ "5.235.158.235",
+ "5.235.159.31",
+ "5.235.160.173",
+ "5.235.161.106",
+ "5.235.162.106",
+ "5.235.163.30",
+ "5.235.163.180",
+ "5.235.164.199",
+ "5.235.164.236",
+ "5.235.166.121",
+ "5.235.170.173",
+ "5.235.171.180",
+ "5.235.171.231",
+ "5.235.173.118",
+ "5.235.174.61",
+ "5.235.175.27",
+ "5.235.176.46",
+ "5.235.176.192",
+ "5.235.176.234",
+ "5.235.177.148",
+ "5.235.179.135",
+ "5.235.180.142",
+ "5.235.181.200",
+ "5.235.182.66",
+ "5.235.182.193",
+ "5.235.182.229",
+ "5.235.183.189",
+ "5.235.185.142",
+ "5.235.185.176",
+ "5.235.186.75",
+ "5.235.186.161",
+ "5.235.186.211",
+ "5.235.186.226",
+ "5.235.186.227",
+ "5.235.187.111",
+ "5.235.187.127",
+ "5.235.189.58",
+ "5.235.195.238",
+ "5.235.196.83",
+ "5.235.196.136",
+ "5.235.197.225",
+ "5.235.198.83",
+ "5.235.199.92",
+ "5.235.201.252",
+ "5.235.202.22",
+ "5.235.204.30",
+ "5.235.204.191",
+ "5.235.205.157",
+ "5.235.219.169",
+ "5.235.220.184",
+ "5.235.220.187",
+ "5.235.222.138",
+ "5.235.223.201",
+ "5.235.224.154",
+ "5.235.225.248",
+ "5.235.226.101",
+ "5.235.226.173",
+ "5.235.226.211",
+ "5.235.227.158",
+ "5.235.227.195",
+ "5.235.228.165",
+ "5.235.229.169",
+ "5.235.230.173",
+ "5.235.230.195",
+ "5.235.231.205",
+ "5.235.232.161",
+ "5.235.233.39",
+ "5.235.234.58",
+ "5.235.234.154",
+ "5.235.234.176",
+ "5.235.235.10",
+ "5.235.238.60",
+ "5.235.239.32",
+ "5.235.241.41",
+ "5.235.241.121",
+ "5.235.243.12",
+ "5.235.245.242",
+ "5.235.247.164",
+ "5.235.250.43",
+ "5.235.252.190",
+ "5.235.253.14",
+ "5.235.253.137",
+ "5.235.254.8",
+ "5.235.255.101",
+ "5.236.25.31",
+ "5.236.26.247",
+ "5.236.28.53",
+ "5.236.29.178",
+ "5.236.30.168",
+ "5.236.31.208",
+ "5.236.36.45",
+ "5.236.36.47",
+ "5.236.36.66",
+ "5.236.36.85",
+ "5.236.36.100",
+ "5.236.36.113",
+ "5.236.36.145",
+ "5.236.67.229",
+ "5.236.68.165",
+ "5.236.69.213",
+ "5.236.71.98",
+ "5.236.87.208",
+ "5.236.93.14",
+ "5.236.93.48",
+ "5.236.93.174",
+ "5.236.93.234",
+ "5.236.96.19",
+ "5.236.96.23",
+ "5.236.96.40",
+ "5.236.96.60",
+ "5.236.108.235",
+ "5.236.109.224",
+ "5.236.113.178",
+ "5.236.114.159",
+ "5.236.114.235",
+ "5.236.115.128",
+ "5.236.115.251",
+ "5.236.117.60",
+ "5.236.119.154",
+ "5.236.124.194",
+ "5.236.192.40",
+ "5.236.193.100",
+ "5.236.194.126",
+ "5.236.195.79",
+ "5.236.195.96",
+ "5.236.195.201",
+ "5.236.209.244",
+ "5.236.212.244",
+ "5.236.213.53",
+ "5.236.213.78",
+ "5.236.213.179",
+ "5.236.219.109",
+ "5.236.220.70",
+ "5.236.225.244",
+ "5.236.226.78",
+ "5.236.226.188",
+ "5.236.229.139",
+ "5.236.235.2",
+ "5.236.242.203",
+ "5.236.245.102",
+ "5.236.246.11",
+ "5.236.246.159",
+ "5.236.251.75",
+ "5.237.55.14",
+ "5.237.142.130",
+ "5.237.176.90",
+ "5.237.192.208",
+ "5.237.193.127",
+ "5.237.194.226",
+ "5.237.195.188",
+ "5.237.196.7",
+ "5.237.197.52",
+ "5.237.200.253",
+ "5.237.201.159",
+ "5.237.202.87",
+ "5.237.204.168",
+ "5.237.208.237",
+ "5.237.209.121",
+ "5.237.211.73",
+ "5.237.211.98",
+ "5.237.211.231",
+ "5.237.217.54",
+ "5.237.217.64",
+ "5.237.223.84",
+ "5.237.223.146",
+ "5.237.226.189",
+ "5.237.229.54",
+ "5.237.229.226",
+ "5.237.230.76",
+ "5.237.231.170",
+ "5.237.232.125",
+ "5.237.232.243",
+ "5.237.233.144",
+ "5.237.233.191",
+ "5.237.234.34",
+ "5.237.236.43",
+ "5.237.238.207",
+ "5.237.240.53",
+ "5.237.240.103",
+ "5.237.241.179",
+ "5.237.241.183",
+ "5.237.242.60",
+ "5.237.243.14",
+ "5.237.243.198",
+ "5.237.247.15",
+ "5.237.247.195",
+ "5.237.248.197",
+ "5.237.249.142",
+ "5.237.249.242",
+ "5.237.253.187",
+ "5.237.255.14",
+ "5.237.255.166",
+ "5.238.3.90",
+ "5.238.17.31",
+ "5.238.52.159",
+ "5.238.52.186",
+ "5.238.52.195",
+ "5.238.52.234",
+ "5.238.52.236",
+ "5.238.52.241",
+ "5.238.74.210",
+ "5.238.94.243",
+ "5.238.110.7",
+ "5.238.110.8",
+ "5.238.110.29",
+ "5.238.110.64",
+ "5.238.110.210",
+ "5.238.111.39",
+ "5.238.111.134",
+ "5.238.128.92",
+ "5.238.131.6",
+ "5.238.131.21",
+ "5.238.131.179",
+ "5.238.131.223",
+ "5.238.132.182",
+ "5.238.132.208",
+ "5.238.132.228",
+ "5.238.134.53",
+ "5.238.134.155",
+ "5.238.134.212",
+ "5.238.135.45",
+ "5.238.135.73",
+ "5.238.136.160",
+ "5.238.137.1",
+ "5.238.137.175",
+ "5.238.139.45",
+ "5.238.139.62",
+ "5.238.139.231",
+ "5.238.140.227",
+ "5.238.140.248",
+ "5.238.143.149",
+ "5.238.143.243",
+ "5.238.144.25",
+ "5.238.146.116",
+ "5.238.147.99",
+ "5.238.153.65",
+ "5.238.153.70",
+ "5.238.153.102",
+ "5.238.153.107",
+ "5.238.153.138",
+ "5.238.156.6",
+ "5.238.157.206",
+ "5.238.158.183",
+ "5.238.159.102",
+ "5.238.159.184",
+ "5.238.160.134",
+ "5.238.161.24",
+ "5.238.162.17",
+ "5.238.162.31",
+ "5.238.162.90",
+ "5.238.163.60",
+ "5.238.163.142",
+ "5.238.164.40",
+ "5.238.164.44",
+ "5.238.165.168",
+ "5.238.166.7",
+ "5.238.166.55",
+ "5.238.167.171",
+ "5.238.168.83",
+ "5.238.169.99",
+ "5.238.169.101",
+ "5.238.169.107",
+ "5.238.171.30",
+ "5.238.171.107",
+ "5.238.171.143",
+ "5.238.172.214",
+ "5.238.174.56",
+ "5.238.174.129",
+ "5.238.174.245",
+ "5.238.176.1",
+ "5.238.176.59",
+ "5.238.176.95",
+ "5.238.177.5",
+ "5.238.177.236",
+ "5.238.177.239",
+ "5.238.181.65",
+ "5.238.184.197",
+ "5.238.185.39",
+ "5.238.185.123",
+ "5.238.186.41",
+ "5.238.187.168",
+ "5.238.189.167",
+ "5.238.190.228",
+ "5.238.191.5",
+ "5.238.195.78",
+ "5.238.195.138",
+ "5.238.196.51",
+ "5.238.196.107",
+ "5.238.196.129",
+ "5.238.196.169",
+ "5.238.197.118",
+ "5.238.199.24",
+ "5.238.202.108",
+ "5.238.203.16",
+ "5.238.203.28",
+ "5.238.203.154",
+ "5.238.204.82",
+ "5.238.204.224",
+ "5.238.205.112",
+ "5.238.206.175",
+ "5.238.207.60",
+ "5.238.208.233",
+ "5.238.210.11",
+ "5.238.210.66",
+ "5.238.210.236",
+ "5.238.211.85",
+ "5.238.211.121",
+ "5.238.211.148",
+ "5.238.212.191",
+ "5.238.213.86",
+ "5.238.214.195",
+ "5.238.217.57",
+ "5.238.217.219",
+ "5.238.218.144",
+ "5.238.218.227",
+ "5.238.223.38",
+ "5.238.227.11",
+ "5.238.227.85",
+ "5.238.227.104",
+ "5.238.227.171",
+ "5.238.227.173",
+ "5.238.228.116",
+ "5.238.229.131",
+ "5.238.229.246",
+ "5.238.230.79",
+ "5.238.232.178",
+ "5.238.232.190",
+ "5.238.234.48",
+ "5.238.235.95",
+ "5.238.237.166",
+ "5.238.239.165",
+ "5.238.240.235",
+ "5.238.241.45",
+ "5.238.241.116",
+ "5.238.242.137",
+ "5.238.242.204",
+ "5.238.245.225",
+ "5.238.246.114",
+ "5.238.246.145",
+ "5.238.247.72",
+ "5.238.247.89",
+ "5.238.248.90",
+ "5.238.249.80",
+ "5.238.250.153",
+ "5.238.251.77",
+ "5.238.251.170",
+ "5.238.252.216",
+ "5.238.254.51",
+ "5.238.255.98",
+ "5.239.0.243",
+ "5.239.1.191",
+ "5.239.2.25",
+ "5.239.2.223",
+ "5.239.3.128",
+ "5.239.3.164",
+ "5.239.7.14",
+ "5.239.7.49",
+ "5.239.7.104",
+ "5.239.8.209",
+ "5.239.9.11",
+ "5.239.9.56",
+ "5.239.9.183",
+ "5.239.9.228",
+ "5.239.10.48",
+ "5.239.11.58",
+ "5.239.11.197",
+ "5.239.12.67",
+ "5.239.13.160",
+ "5.239.14.202",
+ "5.239.15.7",
+ "5.239.15.157",
+ "5.239.17.149",
+ "5.239.17.177",
+ "5.239.18.248",
+ "5.239.21.24",
+ "5.239.21.85",
+ "5.239.22.32",
+ "5.239.22.107",
+ "5.239.22.173",
+ "5.239.23.71",
+ "5.239.23.138",
+ "5.239.24.181",
+ "5.239.25.176",
+ "5.239.26.131",
+ "5.239.26.170",
+ "5.239.26.174",
+ "5.239.28.44",
+ "5.239.30.38",
+ "5.239.30.171",
+ "5.239.31.129",
+ "5.239.31.205",
+ "5.239.32.77",
+ "5.239.33.6",
+ "5.239.34.56",
+ "5.239.35.31",
+ "5.239.35.252",
+ "5.239.36.41",
+ "5.239.37.171",
+ "5.239.38.117",
+ "5.239.42.232",
+ "5.239.43.35",
+ "5.239.44.129",
+ "5.239.44.132",
+ "5.239.45.109",
+ "5.239.45.164",
+ "5.239.45.178",
+ "5.239.45.211",
+ "5.239.46.185",
+ "5.239.46.239",
+ "5.239.49.138",
+ "5.239.50.156",
+ "5.239.51.83",
+ "5.239.53.5",
+ "5.239.53.127",
+ "5.239.55.249",
+ "5.239.56.81",
+ "5.239.56.218",
+ "5.239.58.175",
+ "5.239.58.192",
+ "5.239.59.106",
+ "5.239.59.250",
+ "5.239.60.38",
+ "5.239.60.45",
+ "5.239.62.32",
+ "5.239.63.47",
+ "5.239.63.100",
+ "5.239.63.159",
+ "5.239.63.216",
+ "5.239.64.246",
+ "5.239.66.72",
+ "5.239.66.141",
+ "5.239.66.143",
+ "5.239.66.212",
+ "5.239.69.80",
+ "5.239.70.40",
+ "5.239.70.212",
+ "5.239.71.72",
+ "5.239.71.251",
+ "5.239.73.218",
+ "5.239.73.230",
+ "5.239.75.6",
+ "5.239.75.79",
+ "5.239.75.145",
+ "5.239.76.59",
+ "5.239.76.241",
+ "5.239.78.125",
+ "5.239.79.2",
+ "5.239.80.135",
+ "5.239.81.222",
+ "5.239.82.151",
+ "5.239.83.12",
+ "5.239.84.66",
+ "5.239.84.170",
+ "5.239.85.99",
+ "5.239.86.243",
+ "5.239.86.253",
+ "5.239.88.48",
+ "5.239.88.163",
+ "5.239.89.252",
+ "5.239.89.254",
+ "5.239.91.70",
+ "5.239.91.80",
+ "5.239.91.161",
+ "5.239.92.104",
+ "5.239.96.85",
+ "5.239.99.99",
+ "5.239.102.203",
+ "5.239.103.229",
+ "5.239.104.116",
+ "5.239.104.243",
+ "5.239.107.132",
+ "5.239.108.58",
+ "5.239.108.81",
+ "5.239.108.221",
+ "5.239.109.52",
+ "5.239.110.66",
+ "5.239.110.108",
+ "5.239.112.30",
+ "5.239.112.157",
+ "5.239.114.208",
+ "5.239.115.216",
+ "5.239.117.1",
+ "5.239.117.174",
+ "5.239.117.179",
+ "5.239.118.56",
+ "5.239.118.198",
+ "5.239.118.217",
+ "5.239.119.100",
+ "5.239.119.178",
+ "5.239.119.183",
+ "5.239.119.207",
+ "5.239.121.137",
+ "5.239.121.216",
+ "5.239.124.95",
+ "5.239.125.35",
+ "5.239.127.128",
+ "5.239.127.172",
+ "5.239.149.170",
+ "5.239.157.217",
+ "5.239.158.188",
+ "5.239.160.15",
+ "5.239.160.75",
+ "5.239.160.105",
+ "5.239.160.125",
+ "5.239.160.143",
+ "5.239.161.33",
+ "5.239.161.49",
+ "5.239.161.87",
+ "5.239.161.109",
+ "5.239.161.147",
+ "5.239.161.178",
+ "5.239.161.194",
+ "5.239.176.2",
+ "5.239.177.48",
+ "5.239.177.69",
+ "5.239.177.163",
+ "5.239.177.237",
+ "5.239.197.37",
+ "5.239.199.8",
+ "5.239.202.231",
+ "5.239.230.12",
+ "5.239.231.88",
+ "5.239.237.119",
+ "5.239.239.25",
+ "5.239.240.88",
+ "5.239.240.91",
+ "5.239.240.193",
+ "5.239.240.197",
+ "5.239.240.200",
+ "5.239.240.238",
+ "5.239.241.12",
+ "5.239.241.28",
+ "5.239.241.71",
+ "5.239.241.195",
+ "5.239.245.137",
+ "5.239.245.192",
+ "5.239.245.240",
+ "5.239.245.245",
+ "5.239.245.249",
+ "5.239.245.250",
+ "5.252.216.3",
+ "5.252.216.4",
+ "31.7.64.4",
+ "31.7.64.6",
+ "31.7.64.81",
+ "31.7.65.18",
+ "31.7.65.22",
+ "31.7.65.55",
+ "31.7.65.57",
+ "31.7.65.82",
+ "31.7.65.83",
+ "31.7.66.75",
+ "31.7.66.146",
+ "31.7.66.147",
+ "31.7.68.249",
+ "31.7.69.220",
+ "31.7.71.9",
+ "31.7.72.60",
+ "31.7.72.146",
+ "31.7.73.38",
+ "31.7.73.67",
+ "31.7.73.77",
+ "31.7.73.85",
+ "31.7.73.132",
+ "31.7.74.49",
+ "31.7.78.16",
+ "31.7.78.26",
+ "31.7.78.46",
+ "31.7.78.47",
+ "31.7.78.109",
+ "31.7.91.159",
+ "31.7.91.166",
+ "31.7.110.218",
+ "31.14.112.210",
+ "31.14.113.237",
+ "31.14.114.83",
+ "31.14.114.84",
+ "31.14.114.85",
+ "31.14.114.86",
+ "31.14.114.87",
+ "31.14.114.88",
+ "31.14.114.89",
+ "31.14.114.90",
+ "31.14.114.91",
+ "31.14.114.92",
+ "31.14.114.94",
+ "31.14.114.165",
+ "31.14.117.116",
+ "31.14.117.178",
+ "31.14.117.180",
+ "31.14.117.226",
+ "31.14.117.227",
+ "31.14.118.123",
+ "31.14.118.125",
+ "31.14.118.126",
+ "31.14.119.162",
+ "31.14.119.166",
+ "31.14.120.54",
+ "31.14.124.45",
+ "31.14.124.195",
+ "31.14.126.31",
+ "31.14.126.40",
+ "31.14.126.85",
+ "31.14.126.88",
+ "31.14.126.120",
+ "31.14.127.139",
+ "31.14.127.183",
+ "31.24.201.108",
+ "31.25.90.14",
+ "31.25.90.43",
+ "31.25.91.7",
+ "31.25.92.13",
+ "31.25.92.15",
+ "31.25.92.24",
+ "31.25.92.31",
+ "31.25.92.44",
+ "31.25.92.63",
+ "31.25.92.64",
+ "31.25.92.71",
+ "31.25.92.73",
+ "31.25.92.74",
+ "31.25.92.97",
+ "31.25.92.138",
+ "31.25.92.153",
+ "31.25.92.173",
+ "31.25.92.194",
+ "31.25.92.198",
+ "31.25.92.205",
+ "31.25.92.214",
+ "31.25.92.243",
+ "31.25.93.8",
+ "31.25.93.18",
+ "31.25.93.45",
+ "31.25.93.163",
+ "31.25.94.1",
+ "31.25.94.106",
+ "31.25.95.2",
+ "31.25.95.32",
+ "31.25.95.184",
+ "31.25.95.216",
+ "31.25.128.105",
+ "31.25.128.132",
+ "31.25.129.39",
+ "31.25.129.163",
+ "31.25.129.247",
+ "31.25.130.8",
+ "31.25.130.228",
+ "31.25.130.239",
+ "31.25.131.164",
+ "31.25.132.30",
+ "31.25.132.49",
+ "31.25.132.85",
+ "31.25.132.253",
+ "31.25.134.99",
+ "31.25.134.148",
+ "31.25.134.150",
+ "31.25.134.233",
+ "31.25.134.240",
+ "31.25.135.50",
+ "31.25.135.80",
+ "31.25.135.81",
+ "31.25.135.93",
+ "31.25.135.173",
+ "31.25.135.236",
+ "31.47.32.34",
+ "31.47.33.10",
+ "31.47.33.11",
+ "31.47.33.12",
+ "31.47.33.194",
+ "31.47.34.42",
+ "31.47.34.74",
+ "31.47.35.34",
+ "31.47.39.194",
+ "31.47.45.227",
+ "31.47.48.3",
+ "31.47.48.4",
+ "31.47.48.5",
+ "31.47.48.6",
+ "31.47.48.7",
+ "31.47.48.8",
+ "31.47.48.10",
+ "31.47.48.11",
+ "31.47.48.13",
+ "31.47.48.15",
+ "31.47.48.19",
+ "31.47.48.22",
+ "31.47.51.55",
+ "31.47.52.27",
+ "31.47.52.110",
+ "31.47.54.90",
+ "31.47.58.98",
+ "31.47.61.190",
+ "31.47.61.234",
+ "31.130.181.241",
+ "31.130.181.254",
+ "31.130.182.12",
+ "31.130.182.13",
+ "31.170.49.245",
+ "31.170.50.59",
+ "31.170.52.61",
+ "31.170.52.106",
+ "31.170.52.132",
+ "31.170.52.191",
+ "31.170.52.197",
+ "31.170.52.248",
+ "31.170.53.0",
+ "31.170.53.86",
+ "31.170.57.21",
+ "31.170.57.71",
+ "31.170.58.30",
+ "31.170.59.26",
+ "31.170.59.98",
+ "31.170.59.133",
+ "31.170.59.225",
+ "31.170.60.16",
+ "31.170.60.20",
+ "31.170.60.90",
+ "31.170.60.99",
+ "31.170.60.111",
+ "31.170.60.146",
+ "31.170.60.182",
+ "31.170.60.210",
+ "31.170.60.230",
+ "31.170.61.161",
+ "31.170.61.165",
+ "31.170.61.173",
+ "31.170.61.237",
+ "31.184.129.77",
+ "31.184.129.106",
+ "31.184.144.34",
+ "31.184.147.78",
+ "31.184.147.88",
+ "31.184.147.149",
+ "31.184.147.161",
+ "31.184.147.170",
+ "31.184.166.2",
+ "31.184.167.2",
+ "31.184.170.80",
+ "31.184.170.98",
+ "31.184.170.100",
+ "31.184.170.150",
+ "31.184.170.169",
+ "31.184.170.178",
+ "31.184.170.234",
+ "31.184.171.110",
+ "31.184.171.216",
+ "31.184.175.2",
+ "31.184.176.176",
+ "31.184.177.136",
+ "31.184.178.11",
+ "31.184.178.224",
+ "31.184.178.228",
+ "31.184.179.218",
+ "31.184.179.219",
+ "31.184.188.1",
+ "31.184.188.8",
+ "31.184.188.10",
+ "31.184.188.14",
+ "31.184.188.18",
+ "31.184.188.26",
+ "31.184.188.27",
+ "31.184.188.28",
+ "31.184.188.42",
+ "31.184.188.45",
+ "31.184.188.62",
+ "31.184.188.64",
+ "31.184.188.70",
+ "31.184.188.74",
+ "31.184.188.81",
+ "31.184.188.91",
+ "31.184.188.99",
+ "31.184.188.105",
+ "31.184.188.119",
+ "31.184.188.120",
+ "31.184.188.131",
+ "31.184.188.135",
+ "31.184.188.136",
+ "31.184.188.137",
+ "31.184.188.143",
+ "31.184.188.161",
+ "31.184.188.163",
+ "31.184.188.166",
+ "31.184.188.170",
+ "31.184.188.174",
+ "31.184.188.179",
+ "31.184.188.184",
+ "31.184.188.191",
+ "31.184.188.201",
+ "31.184.188.205",
+ "31.184.188.216",
+ "31.184.188.221",
+ "31.184.188.224",
+ "31.184.188.226",
+ "31.184.188.227",
+ "31.184.188.230",
+ "31.184.188.231",
+ "31.184.188.232",
+ "31.184.188.239",
+ "31.184.189.10",
+ "31.184.189.22",
+ "31.184.189.27",
+ "31.184.189.29",
+ "31.184.189.35",
+ "31.184.189.41",
+ "31.184.189.46",
+ "31.184.189.48",
+ "31.184.189.50",
+ "31.184.189.57",
+ "31.184.189.67",
+ "31.184.189.68",
+ "31.184.189.88",
+ "31.184.189.97",
+ "31.184.189.98",
+ "31.184.189.109",
+ "31.184.189.120",
+ "31.184.189.127",
+ "31.184.189.146",
+ "31.184.189.151",
+ "31.184.189.152",
+ "31.184.189.153",
+ "31.184.189.157",
+ "31.184.189.179",
+ "31.184.189.184",
+ "31.184.189.187",
+ "31.184.189.199",
+ "31.184.189.208",
+ "31.184.189.213",
+ "31.184.189.233",
+ "31.184.189.234",
+ "31.184.189.236",
+ "31.184.189.237",
+ "31.184.189.246",
+ "31.184.190.2",
+ "31.184.190.10",
+ "31.184.190.51",
+ "31.184.190.56",
+ "31.184.190.64",
+ "31.184.190.77",
+ "31.184.190.84",
+ "31.184.190.100",
+ "31.184.190.101",
+ "31.184.190.104",
+ "31.184.190.111",
+ "31.184.190.114",
+ "31.184.190.136",
+ "31.184.190.145",
+ "31.184.190.158",
+ "31.184.190.180",
+ "31.184.190.182",
+ "31.184.190.185",
+ "31.184.190.194",
+ "31.184.190.202",
+ "31.184.190.208",
+ "31.184.190.219",
+ "31.184.190.228",
+ "31.184.190.231",
+ "31.184.190.241",
+ "31.184.190.245",
+ "31.184.190.254",
+ "31.184.191.2",
+ "31.184.191.6",
+ "31.184.191.7",
+ "31.184.191.12",
+ "31.184.191.20",
+ "31.184.191.22",
+ "31.184.191.23",
+ "31.184.191.28",
+ "31.184.191.34",
+ "31.184.191.47",
+ "31.184.191.48",
+ "31.184.191.54",
+ "31.184.191.62",
+ "31.184.191.74",
+ "31.184.191.94",
+ "31.184.191.100",
+ "31.184.191.112",
+ "31.184.191.116",
+ "31.184.191.125",
+ "31.184.191.126",
+ "31.184.191.127",
+ "31.184.191.132",
+ "31.184.191.138",
+ "31.184.191.146",
+ "31.184.191.159",
+ "31.184.191.160",
+ "31.184.191.166",
+ "31.184.191.184",
+ "31.184.191.199",
+ "31.184.191.201",
+ "31.184.191.213",
+ "31.184.191.215",
+ "31.184.191.220",
+ "31.184.191.226",
+ "31.184.191.228",
+ "31.184.191.235",
+ "31.184.191.242",
+ "31.184.191.253",
+ "31.214.147.255",
+ "31.214.168.66",
+ "31.214.168.104",
+ "31.214.168.178",
+ "31.214.171.136",
+ "31.214.171.226",
+ "31.214.172.4",
+ "31.214.172.58",
+ "31.214.173.75",
+ "31.214.173.77",
+ "31.214.174.130",
+ "31.214.175.241",
+ "31.214.231.120",
+ "31.214.248.242",
+ "31.214.250.18",
+ "31.214.250.115",
+ "31.214.251.237",
+ "31.214.255.52",
+ "31.214.255.164",
+ "31.214.255.173",
+ "31.216.62.242",
+ "37.10.67.11",
+ "37.10.109.148",
+ "37.32.4.222",
+ "37.32.5.5",
+ "37.32.5.25",
+ "37.32.5.59",
+ "37.32.5.119",
+ "37.32.5.215",
+ "37.32.6.67",
+ "37.32.6.194",
+ "37.32.9.83",
+ "37.32.10.126",
+ "37.32.11.191",
+ "37.32.11.204",
+ "37.32.12.30",
+ "37.32.12.84",
+ "37.32.12.231",
+ "37.32.13.25",
+ "37.32.13.30",
+ "37.32.14.62",
+ "37.32.14.81",
+ "37.32.14.200",
+ "37.32.15.39",
+ "37.32.21.0",
+ "37.32.21.21",
+ "37.32.21.148",
+ "37.32.24.21",
+ "37.32.24.49",
+ "37.32.25.86",
+ "37.32.25.134",
+ "37.32.25.227",
+ "37.32.26.37",
+ "37.32.27.56",
+ "37.32.27.68",
+ "37.32.40.38",
+ "37.32.43.74",
+ "37.32.43.75",
+ "37.32.43.77",
+ "37.32.43.78",
+ "37.32.43.80",
+ "37.32.43.81",
+ "37.32.43.82",
+ "37.32.43.83",
+ "37.32.43.84",
+ "37.32.43.85",
+ "37.32.43.86",
+ "37.32.43.87",
+ "37.32.43.88",
+ "37.32.43.89",
+ "37.32.43.90",
+ "37.32.43.91",
+ "37.32.43.92",
+ "37.32.43.93",
+ "37.32.43.197",
+ "37.32.45.96",
+ "37.32.46.140",
+ "37.32.47.181",
+ "37.32.47.199",
+ "37.32.112.2",
+ "37.32.117.5",
+ "37.32.120.100",
+ "37.32.120.137",
+ "37.32.121.48",
+ "37.32.121.53",
+ "37.32.121.76",
+ "37.32.124.16",
+ "37.32.125.131",
+ "37.32.125.192",
+ "37.32.125.193",
+ "37.32.125.195",
+ "37.32.127.132",
+ "37.32.127.163",
+ "37.75.240.1",
+ "37.75.240.2",
+ "37.75.240.20",
+ "37.75.240.21",
+ "37.75.240.30",
+ "37.75.240.65",
+ "37.75.242.89",
+ "37.75.242.179",
+ "37.75.242.188",
+ "37.75.243.61",
+ "37.75.243.62",
+ "37.75.243.82",
+ "37.75.243.146",
+ "37.75.243.154",
+ "37.75.243.195",
+ "37.75.243.254",
+ "37.75.244.22",
+ "37.75.244.26",
+ "37.75.244.50",
+ "37.75.244.52",
+ "37.75.244.53",
+ "37.75.244.122",
+ "37.75.245.77",
+ "37.75.245.80",
+ "37.75.245.131",
+ "37.75.246.54",
+ "37.75.246.138",
+ "37.75.246.241",
+ "37.75.246.242",
+ "37.75.246.243",
+ "37.75.246.244",
+ "37.75.246.246",
+ "37.75.247.176",
+ "37.75.247.177",
+ "37.75.247.178",
+ "37.75.247.182",
+ "37.98.112.30",
+ "37.98.112.210",
+ "37.98.118.100",
+ "37.114.204.42",
+ "37.114.204.114",
+ "37.114.204.230",
+ "37.114.205.66",
+ "37.114.205.67",
+ "37.114.205.68",
+ "37.114.205.69",
+ "37.114.205.70",
+ "37.114.205.74",
+ "37.114.225.82",
+ "37.114.225.84",
+ "37.114.225.85",
+ "37.114.225.138",
+ "37.114.246.46",
+ "37.114.246.196",
+ "37.114.247.50",
+ "37.114.247.202",
+ "37.130.200.3",
+ "37.130.200.29",
+ "37.130.202.36",
+ "37.130.205.2",
+ "37.130.207.2",
+ "37.143.144.8",
+ "37.143.146.240",
+ "37.143.147.34",
+ "37.143.147.58",
+ "37.143.147.78",
+ "37.143.147.123",
+ "37.143.147.133",
+ "37.143.147.147",
+ "37.143.147.150",
+ "37.143.148.3",
+ "37.143.148.9",
+ "37.143.148.20",
+ "37.143.148.31",
+ "37.143.148.36",
+ "37.143.148.72",
+ "37.143.148.75",
+ "37.143.148.83",
+ "37.143.148.99",
+ "37.143.148.100",
+ "37.143.148.114",
+ "37.143.148.120",
+ "37.143.148.153",
+ "37.143.148.164",
+ "37.143.148.184",
+ "37.143.148.188",
+ "37.143.148.192",
+ "37.143.148.208",
+ "37.143.148.252",
+ "37.143.148.253",
+ "37.143.149.0",
+ "37.143.149.1",
+ "37.143.149.2",
+ "37.143.149.3",
+ "37.143.149.4",
+ "37.143.149.5",
+ "37.143.149.7",
+ "37.143.149.8",
+ "37.143.149.9",
+ "37.143.149.10",
+ "37.143.149.11",
+ "37.143.149.12",
+ "37.143.149.13",
+ "37.143.149.14",
+ "37.143.149.15",
+ "37.143.149.16",
+ "37.143.149.18",
+ "37.143.149.20",
+ "37.143.149.21",
+ "37.143.149.22",
+ "37.143.149.23",
+ "37.143.149.24",
+ "37.143.149.25",
+ "37.143.149.26",
+ "37.143.149.27",
+ "37.143.149.28",
+ "37.143.149.29",
+ "37.143.149.30",
+ "37.143.149.31",
+ "37.143.149.32",
+ "37.143.149.33",
+ "37.143.149.34",
+ "37.143.149.35",
+ "37.143.149.36",
+ "37.143.149.37",
+ "37.143.149.38",
+ "37.143.149.39",
+ "37.143.149.40",
+ "37.143.149.41",
+ "37.143.149.42",
+ "37.143.149.43",
+ "37.143.149.44",
+ "37.143.149.45",
+ "37.143.149.46",
+ "37.143.149.47",
+ "37.143.149.48",
+ "37.143.149.49",
+ "37.143.149.50",
+ "37.143.149.51",
+ "37.143.149.52",
+ "37.143.149.53",
+ "37.143.149.54",
+ "37.143.149.55",
+ "37.143.149.57",
+ "37.143.149.58",
+ "37.143.149.59",
+ "37.143.149.64",
+ "37.143.149.65",
+ "37.143.149.67",
+ "37.143.149.68",
+ "37.143.149.69",
+ "37.143.149.70",
+ "37.143.149.71",
+ "37.143.149.72",
+ "37.143.149.73",
+ "37.143.149.74",
+ "37.143.149.75",
+ "37.143.149.76",
+ "37.143.149.77",
+ "37.143.149.78",
+ "37.143.149.79",
+ "37.143.149.80",
+ "37.143.149.82",
+ "37.143.149.83",
+ "37.143.149.84",
+ "37.143.149.85",
+ "37.143.149.86",
+ "37.143.149.87",
+ "37.143.149.88",
+ "37.143.149.89",
+ "37.143.149.90",
+ "37.143.149.92",
+ "37.143.149.93",
+ "37.143.149.94",
+ "37.143.149.95",
+ "37.143.149.96",
+ "37.143.149.97",
+ "37.143.149.98",
+ "37.143.149.99",
+ "37.143.149.100",
+ "37.143.149.101",
+ "37.143.149.102",
+ "37.143.149.103",
+ "37.143.149.104",
+ "37.143.149.105",
+ "37.143.149.106",
+ "37.143.149.107",
+ "37.143.149.108",
+ "37.143.149.109",
+ "37.143.149.110",
+ "37.143.149.111",
+ "37.143.149.112",
+ "37.143.149.113",
+ "37.143.149.114",
+ "37.143.149.116",
+ "37.143.149.117",
+ "37.143.149.118",
+ "37.143.149.119",
+ "37.143.149.120",
+ "37.143.149.121",
+ "37.143.149.122",
+ "37.143.149.123",
+ "37.143.149.124",
+ "37.143.149.125",
+ "37.143.149.126",
+ "37.143.149.127",
+ "37.143.151.40",
+ "37.143.151.78",
+ "37.143.151.82",
+ "37.143.151.89",
+ "37.143.151.108",
+ "37.143.151.157",
+ "37.143.151.162",
+ "37.143.151.192",
+ "37.143.151.210",
+ "37.143.151.219",
+ "37.148.0.4",
+ "37.148.0.8",
+ "37.148.0.22",
+ "37.148.0.32",
+ "37.148.0.55",
+ "37.148.0.60",
+ "37.148.0.73",
+ "37.148.0.77",
+ "37.148.0.80",
+ "37.148.0.82",
+ "37.148.0.88",
+ "37.148.0.99",
+ "37.148.0.103",
+ "37.148.0.200",
+ "37.148.0.215",
+ "37.148.0.220",
+ "37.148.0.225",
+ "37.148.0.238",
+ "37.148.0.246",
+ "37.148.1.27",
+ "37.148.1.28",
+ "37.148.1.30",
+ "37.148.1.33",
+ "37.148.1.56",
+ "37.148.1.60",
+ "37.148.1.66",
+ "37.148.1.87",
+ "37.148.1.115",
+ "37.148.1.116",
+ "37.148.1.128",
+ "37.148.1.134",
+ "37.148.1.150",
+ "37.148.1.154",
+ "37.148.1.161",
+ "37.148.1.173",
+ "37.148.1.186",
+ "37.148.1.223",
+ "37.148.1.226",
+ "37.148.1.228",
+ "37.148.1.239",
+ "37.148.2.13",
+ "37.148.2.14",
+ "37.148.2.15",
+ "37.148.2.52",
+ "37.148.2.54",
+ "37.148.2.63",
+ "37.148.2.96",
+ "37.148.2.98",
+ "37.148.2.107",
+ "37.148.2.108",
+ "37.148.2.114",
+ "37.148.2.116",
+ "37.148.2.125",
+ "37.148.2.127",
+ "37.148.2.147",
+ "37.148.2.185",
+ "37.148.2.189",
+ "37.148.2.198",
+ "37.148.2.200",
+ "37.148.2.205",
+ "37.148.2.218",
+ "37.148.2.228",
+ "37.148.2.232",
+ "37.148.2.233",
+ "37.148.2.240",
+ "37.148.2.243",
+ "37.148.3.3",
+ "37.148.3.7",
+ "37.148.3.16",
+ "37.148.3.36",
+ "37.148.3.42",
+ "37.148.3.60",
+ "37.148.3.64",
+ "37.148.3.83",
+ "37.148.3.88",
+ "37.148.3.91",
+ "37.148.3.94",
+ "37.148.3.100",
+ "37.148.3.103",
+ "37.148.3.108",
+ "37.148.3.120",
+ "37.148.3.125",
+ "37.148.3.127",
+ "37.148.3.133",
+ "37.148.3.134",
+ "37.148.3.136",
+ "37.148.3.141",
+ "37.148.3.148",
+ "37.148.3.150",
+ "37.148.3.157",
+ "37.148.3.160",
+ "37.148.3.179",
+ "37.148.3.237",
+ "37.148.3.246",
+ "37.148.4.53",
+ "37.148.4.74",
+ "37.148.4.75",
+ "37.148.4.96",
+ "37.148.4.106",
+ "37.148.4.132",
+ "37.148.4.168",
+ "37.148.4.179",
+ "37.148.4.192",
+ "37.148.5.43",
+ "37.148.5.79",
+ "37.148.5.88",
+ "37.148.5.94",
+ "37.148.5.97",
+ "37.148.5.109",
+ "37.148.5.115",
+ "37.148.5.132",
+ "37.148.5.136",
+ "37.148.5.143",
+ "37.148.5.147",
+ "37.148.5.165",
+ "37.148.5.199",
+ "37.148.5.222",
+ "37.148.5.223",
+ "37.148.5.228",
+ "37.148.5.248",
+ "37.148.6.1",
+ "37.148.6.17",
+ "37.148.6.32",
+ "37.148.6.48",
+ "37.148.6.65",
+ "37.148.6.76",
+ "37.148.6.82",
+ "37.148.6.84",
+ "37.148.6.89",
+ "37.148.6.92",
+ "37.148.6.97",
+ "37.148.6.101",
+ "37.148.6.109",
+ "37.148.6.111",
+ "37.148.6.119",
+ "37.148.6.134",
+ "37.148.6.136",
+ "37.148.6.138",
+ "37.148.6.145",
+ "37.148.6.156",
+ "37.148.6.161",
+ "37.148.6.162",
+ "37.148.6.166",
+ "37.148.6.179",
+ "37.148.6.188",
+ "37.148.6.198",
+ "37.148.6.216",
+ "37.148.6.225",
+ "37.148.6.228",
+ "37.148.6.231",
+ "37.148.6.255",
+ "37.148.7.0",
+ "37.148.7.4",
+ "37.148.7.22",
+ "37.148.7.23",
+ "37.148.7.50",
+ "37.148.7.65",
+ "37.148.7.74",
+ "37.148.7.78",
+ "37.148.7.85",
+ "37.148.7.105",
+ "37.148.7.127",
+ "37.148.7.130",
+ "37.148.7.132",
+ "37.148.7.181",
+ "37.148.7.185",
+ "37.148.7.196",
+ "37.148.7.234",
+ "37.148.8.4",
+ "37.148.8.8",
+ "37.148.8.10",
+ "37.148.8.12",
+ "37.148.8.16",
+ "37.148.8.40",
+ "37.148.8.51",
+ "37.148.8.53",
+ "37.148.8.63",
+ "37.148.8.68",
+ "37.148.8.73",
+ "37.148.8.87",
+ "37.148.8.95",
+ "37.148.8.99",
+ "37.148.8.111",
+ "37.148.8.118",
+ "37.148.8.158",
+ "37.148.8.188",
+ "37.148.8.196",
+ "37.148.8.201",
+ "37.148.8.210",
+ "37.148.8.217",
+ "37.148.8.218",
+ "37.148.8.231",
+ "37.148.8.240",
+ "37.148.8.253",
+ "37.148.9.32",
+ "37.148.9.36",
+ "37.148.9.56",
+ "37.148.9.96",
+ "37.148.9.102",
+ "37.148.9.146",
+ "37.148.9.149",
+ "37.148.9.155",
+ "37.148.9.174",
+ "37.148.9.188",
+ "37.148.9.228",
+ "37.148.9.246",
+ "37.148.10.65",
+ "37.148.10.79",
+ "37.148.10.83",
+ "37.148.10.113",
+ "37.148.10.121",
+ "37.148.10.141",
+ "37.148.10.155",
+ "37.148.10.166",
+ "37.148.10.192",
+ "37.148.10.195",
+ "37.148.10.217",
+ "37.148.10.230",
+ "37.148.11.9",
+ "37.148.11.23",
+ "37.148.11.39",
+ "37.148.11.50",
+ "37.148.11.64",
+ "37.148.11.66",
+ "37.148.11.75",
+ "37.148.11.85",
+ "37.148.11.108",
+ "37.148.11.141",
+ "37.148.11.168",
+ "37.148.11.171",
+ "37.148.11.191",
+ "37.148.11.212",
+ "37.148.11.229",
+ "37.148.11.231",
+ "37.148.11.252",
+ "37.148.12.25",
+ "37.148.12.27",
+ "37.148.12.28",
+ "37.148.12.35",
+ "37.148.12.46",
+ "37.148.12.68",
+ "37.148.12.76",
+ "37.148.12.89",
+ "37.148.12.129",
+ "37.148.12.145",
+ "37.148.12.152",
+ "37.148.12.158",
+ "37.148.12.160",
+ "37.148.12.162",
+ "37.148.12.169",
+ "37.148.12.200",
+ "37.148.12.203",
+ "37.148.12.212",
+ "37.148.12.218",
+ "37.148.12.239",
+ "37.148.12.240",
+ "37.148.12.241",
+ "37.148.13.0",
+ "37.148.13.3",
+ "37.148.13.55",
+ "37.148.13.78",
+ "37.148.13.80",
+ "37.148.13.93",
+ "37.148.13.111",
+ "37.148.13.119",
+ "37.148.13.123",
+ "37.148.13.128",
+ "37.148.13.130",
+ "37.148.13.131",
+ "37.148.13.142",
+ "37.148.13.156",
+ "37.148.13.160",
+ "37.148.13.166",
+ "37.148.13.174",
+ "37.148.13.202",
+ "37.148.13.206",
+ "37.148.13.213",
+ "37.148.13.224",
+ "37.148.13.228",
+ "37.148.13.232",
+ "37.148.13.239",
+ "37.148.13.246",
+ "37.148.14.19",
+ "37.148.14.38",
+ "37.148.14.41",
+ "37.148.14.57",
+ "37.148.14.60",
+ "37.148.14.69",
+ "37.148.14.94",
+ "37.148.14.116",
+ "37.148.14.151",
+ "37.148.14.173",
+ "37.148.14.179",
+ "37.148.14.193",
+ "37.148.14.197",
+ "37.148.14.204",
+ "37.148.14.246",
+ "37.148.15.3",
+ "37.148.15.7",
+ "37.148.15.11",
+ "37.148.15.26",
+ "37.148.15.65",
+ "37.148.15.115",
+ "37.148.15.117",
+ "37.148.15.142",
+ "37.148.15.149",
+ "37.148.15.153",
+ "37.148.15.155",
+ "37.148.15.177",
+ "37.148.15.195",
+ "37.148.15.198",
+ "37.148.15.222",
+ "37.148.15.234",
+ "37.148.15.237",
+ "37.148.16.6",
+ "37.148.16.15",
+ "37.148.16.17",
+ "37.148.16.26",
+ "37.148.16.31",
+ "37.148.16.32",
+ "37.148.16.45",
+ "37.148.16.47",
+ "37.148.16.54",
+ "37.148.16.61",
+ "37.148.16.66",
+ "37.148.16.67",
+ "37.148.16.76",
+ "37.148.16.79",
+ "37.148.16.100",
+ "37.148.16.130",
+ "37.148.16.176",
+ "37.148.16.196",
+ "37.148.16.214",
+ "37.148.16.215",
+ "37.148.16.231",
+ "37.148.16.254",
+ "37.148.16.255",
+ "37.148.17.22",
+ "37.148.17.29",
+ "37.148.17.38",
+ "37.148.17.43",
+ "37.148.17.61",
+ "37.148.17.63",
+ "37.148.17.67",
+ "37.148.17.83",
+ "37.148.17.87",
+ "37.148.17.100",
+ "37.148.17.105",
+ "37.148.17.111",
+ "37.148.17.135",
+ "37.148.17.144",
+ "37.148.17.161",
+ "37.148.17.170",
+ "37.148.17.188",
+ "37.148.17.215",
+ "37.148.17.229",
+ "37.148.17.255",
+ "37.148.18.40",
+ "37.148.18.45",
+ "37.148.18.46",
+ "37.148.18.71",
+ "37.148.18.79",
+ "37.148.18.84",
+ "37.148.18.92",
+ "37.148.18.124",
+ "37.148.18.128",
+ "37.148.18.132",
+ "37.148.18.135",
+ "37.148.18.137",
+ "37.148.18.143",
+ "37.148.18.144",
+ "37.148.18.146",
+ "37.148.18.155",
+ "37.148.18.166",
+ "37.148.18.173",
+ "37.148.18.185",
+ "37.148.18.199",
+ "37.148.18.215",
+ "37.148.18.218",
+ "37.148.18.226",
+ "37.148.18.237",
+ "37.148.18.246",
+ "37.148.18.247",
+ "37.148.19.13",
+ "37.148.19.15",
+ "37.148.19.28",
+ "37.148.19.43",
+ "37.148.19.61",
+ "37.148.19.72",
+ "37.148.19.77",
+ "37.148.19.78",
+ "37.148.19.92",
+ "37.148.19.93",
+ "37.148.19.107",
+ "37.148.19.145",
+ "37.148.19.147",
+ "37.148.19.195",
+ "37.148.19.200",
+ "37.148.19.210",
+ "37.148.19.218",
+ "37.148.20.12",
+ "37.148.20.62",
+ "37.148.20.69",
+ "37.148.20.72",
+ "37.148.20.94",
+ "37.148.20.119",
+ "37.148.20.120",
+ "37.148.20.148",
+ "37.148.20.159",
+ "37.148.20.172",
+ "37.148.20.175",
+ "37.148.20.188",
+ "37.148.20.190",
+ "37.148.20.198",
+ "37.148.20.200",
+ "37.148.20.232",
+ "37.148.20.235",
+ "37.148.20.236",
+ "37.148.20.252",
+ "37.148.21.55",
+ "37.148.21.70",
+ "37.148.21.130",
+ "37.148.21.133",
+ "37.148.21.150",
+ "37.148.21.157",
+ "37.148.21.165",
+ "37.148.21.167",
+ "37.148.21.199",
+ "37.148.21.210",
+ "37.148.21.213",
+ "37.148.21.253",
+ "37.148.22.12",
+ "37.148.22.32",
+ "37.148.22.35",
+ "37.148.22.56",
+ "37.148.22.83",
+ "37.148.22.114",
+ "37.148.22.138",
+ "37.148.22.170",
+ "37.148.22.173",
+ "37.148.22.176",
+ "37.148.22.185",
+ "37.148.22.196",
+ "37.148.22.204",
+ "37.148.22.218",
+ "37.148.22.241",
+ "37.148.22.244",
+ "37.148.23.1",
+ "37.148.23.4",
+ "37.148.23.6",
+ "37.148.23.18",
+ "37.148.23.26",
+ "37.148.23.32",
+ "37.148.23.33",
+ "37.148.23.47",
+ "37.148.23.53",
+ "37.148.23.76",
+ "37.148.23.93",
+ "37.148.23.104",
+ "37.148.23.109",
+ "37.148.23.115",
+ "37.148.23.128",
+ "37.148.23.138",
+ "37.148.23.141",
+ "37.148.23.142",
+ "37.148.23.144",
+ "37.148.23.147",
+ "37.148.23.169",
+ "37.148.23.178",
+ "37.148.23.182",
+ "37.148.23.184",
+ "37.148.23.225",
+ "37.148.24.7",
+ "37.148.24.8",
+ "37.148.24.17",
+ "37.148.24.54",
+ "37.148.24.61",
+ "37.148.24.64",
+ "37.148.24.68",
+ "37.148.24.70",
+ "37.148.24.80",
+ "37.148.24.95",
+ "37.148.24.108",
+ "37.148.24.111",
+ "37.148.24.116",
+ "37.148.24.138",
+ "37.148.24.139",
+ "37.148.24.142",
+ "37.148.24.147",
+ "37.148.24.175",
+ "37.148.24.179",
+ "37.148.24.188",
+ "37.148.24.205",
+ "37.148.24.210",
+ "37.148.24.211",
+ "37.148.24.216",
+ "37.148.24.240",
+ "37.148.24.243",
+ "37.148.24.245",
+ "37.148.25.3",
+ "37.148.25.13",
+ "37.148.25.14",
+ "37.148.25.21",
+ "37.148.25.23",
+ "37.148.25.30",
+ "37.148.25.32",
+ "37.148.25.56",
+ "37.148.25.105",
+ "37.148.25.134",
+ "37.148.25.138",
+ "37.148.25.146",
+ "37.148.25.151",
+ "37.148.25.165",
+ "37.148.25.168",
+ "37.148.25.185",
+ "37.148.25.210",
+ "37.148.25.214",
+ "37.148.25.253",
+ "37.148.26.23",
+ "37.148.26.36",
+ "37.148.26.67",
+ "37.148.26.79",
+ "37.148.26.81",
+ "37.148.26.103",
+ "37.148.26.107",
+ "37.148.26.161",
+ "37.148.26.171",
+ "37.148.26.186",
+ "37.148.26.195",
+ "37.148.26.210",
+ "37.148.26.213",
+ "37.148.26.214",
+ "37.148.26.233",
+ "37.148.26.235",
+ "37.148.26.250",
+ "37.148.27.13",
+ "37.148.27.24",
+ "37.148.27.30",
+ "37.148.27.46",
+ "37.148.27.56",
+ "37.148.27.57",
+ "37.148.27.58",
+ "37.148.27.74",
+ "37.148.27.100",
+ "37.148.27.107",
+ "37.148.27.110",
+ "37.148.27.123",
+ "37.148.27.124",
+ "37.148.27.138",
+ "37.148.27.147",
+ "37.148.27.156",
+ "37.148.27.157",
+ "37.148.27.172",
+ "37.148.27.176",
+ "37.148.27.182",
+ "37.148.27.189",
+ "37.148.27.194",
+ "37.148.27.208",
+ "37.148.27.244",
+ "37.148.27.250",
+ "37.148.27.254",
+ "37.148.28.39",
+ "37.148.28.44",
+ "37.148.28.46",
+ "37.148.28.66",
+ "37.148.28.81",
+ "37.148.28.91",
+ "37.148.28.119",
+ "37.148.28.131",
+ "37.148.28.142",
+ "37.148.28.166",
+ "37.148.28.170",
+ "37.148.28.202",
+ "37.148.28.204",
+ "37.148.28.214",
+ "37.148.28.215",
+ "37.148.28.247",
+ "37.148.28.248",
+ "37.148.29.3",
+ "37.148.29.17",
+ "37.148.29.25",
+ "37.148.29.27",
+ "37.148.29.34",
+ "37.148.29.39",
+ "37.148.29.46",
+ "37.148.29.71",
+ "37.148.29.77",
+ "37.148.29.81",
+ "37.148.29.82",
+ "37.148.29.83",
+ "37.148.29.92",
+ "37.148.29.97",
+ "37.148.29.98",
+ "37.148.29.99",
+ "37.148.29.107",
+ "37.148.29.123",
+ "37.148.29.135",
+ "37.148.29.166",
+ "37.148.29.183",
+ "37.148.29.184",
+ "37.148.29.189",
+ "37.148.29.193",
+ "37.148.29.196",
+ "37.148.29.224",
+ "37.148.29.235",
+ "37.148.29.248",
+ "37.148.30.1",
+ "37.148.30.4",
+ "37.148.30.8",
+ "37.148.30.13",
+ "37.148.30.20",
+ "37.148.30.47",
+ "37.148.30.52",
+ "37.148.30.54",
+ "37.148.30.66",
+ "37.148.30.69",
+ "37.148.30.71",
+ "37.148.30.79",
+ "37.148.30.89",
+ "37.148.30.92",
+ "37.148.30.99",
+ "37.148.30.101",
+ "37.148.30.104",
+ "37.148.30.111",
+ "37.148.30.119",
+ "37.148.30.130",
+ "37.148.30.139",
+ "37.148.30.143",
+ "37.148.30.146",
+ "37.148.30.147",
+ "37.148.30.176",
+ "37.148.30.182",
+ "37.148.30.185",
+ "37.148.30.195",
+ "37.148.30.202",
+ "37.148.30.204",
+ "37.148.30.209",
+ "37.148.30.219",
+ "37.148.30.235",
+ "37.148.30.248",
+ "37.148.30.252",
+ "37.148.31.1",
+ "37.148.31.9",
+ "37.148.31.15",
+ "37.148.31.16",
+ "37.148.31.21",
+ "37.148.31.49",
+ "37.148.31.50",
+ "37.148.31.53",
+ "37.148.31.56",
+ "37.148.31.71",
+ "37.148.31.87",
+ "37.148.31.97",
+ "37.148.31.103",
+ "37.148.31.104",
+ "37.148.31.117",
+ "37.148.31.131",
+ "37.148.31.141",
+ "37.148.31.157",
+ "37.148.31.159",
+ "37.148.31.163",
+ "37.148.31.173",
+ "37.148.31.180",
+ "37.148.31.181",
+ "37.148.31.185",
+ "37.148.31.192",
+ "37.148.31.201",
+ "37.148.31.225",
+ "37.148.31.240",
+ "37.148.31.241",
+ "37.148.31.242",
+ "37.148.31.243",
+ "37.148.31.249",
+ "37.148.31.250",
+ "37.148.40.3",
+ "37.148.40.9",
+ "37.148.40.11",
+ "37.148.40.20",
+ "37.148.40.44",
+ "37.148.40.60",
+ "37.148.40.69",
+ "37.148.40.70",
+ "37.148.40.73",
+ "37.148.40.80",
+ "37.148.40.83",
+ "37.148.40.85",
+ "37.148.40.95",
+ "37.148.40.103",
+ "37.148.40.120",
+ "37.148.40.136",
+ "37.148.40.153",
+ "37.148.40.179",
+ "37.148.40.180",
+ "37.148.40.184",
+ "37.148.40.189",
+ "37.148.40.192",
+ "37.148.40.197",
+ "37.148.40.205",
+ "37.148.40.209",
+ "37.148.40.211",
+ "37.148.40.213",
+ "37.148.40.219",
+ "37.148.40.236",
+ "37.148.40.237",
+ "37.148.40.240",
+ "37.148.40.252",
+ "37.148.41.31",
+ "37.148.41.36",
+ "37.148.41.40",
+ "37.148.41.56",
+ "37.148.41.57",
+ "37.148.41.66",
+ "37.148.41.71",
+ "37.148.41.78",
+ "37.148.41.89",
+ "37.148.41.90",
+ "37.148.41.111",
+ "37.148.41.127",
+ "37.148.41.141",
+ "37.148.41.151",
+ "37.148.41.164",
+ "37.148.41.181",
+ "37.148.41.182",
+ "37.148.41.183",
+ "37.148.41.186",
+ "37.148.41.188",
+ "37.148.41.195",
+ "37.148.41.205",
+ "37.148.41.207",
+ "37.148.41.208",
+ "37.148.41.213",
+ "37.148.41.215",
+ "37.148.41.219",
+ "37.148.41.224",
+ "37.148.42.15",
+ "37.148.42.19",
+ "37.148.42.22",
+ "37.148.42.26",
+ "37.148.42.30",
+ "37.148.42.31",
+ "37.148.42.40",
+ "37.148.42.53",
+ "37.148.42.62",
+ "37.148.42.68",
+ "37.148.42.74",
+ "37.148.42.76",
+ "37.148.42.86",
+ "37.148.42.92",
+ "37.148.42.101",
+ "37.148.42.108",
+ "37.148.42.133",
+ "37.148.42.150",
+ "37.148.42.151",
+ "37.148.42.156",
+ "37.148.42.162",
+ "37.148.42.164",
+ "37.148.42.172",
+ "37.148.42.174",
+ "37.148.42.180",
+ "37.148.42.182",
+ "37.148.42.185",
+ "37.148.42.189",
+ "37.148.42.194",
+ "37.148.42.196",
+ "37.148.42.198",
+ "37.148.42.205",
+ "37.148.42.211",
+ "37.148.42.212",
+ "37.148.42.235",
+ "37.148.42.251",
+ "37.148.43.2",
+ "37.148.43.4",
+ "37.148.43.6",
+ "37.148.43.7",
+ "37.148.43.8",
+ "37.148.43.11",
+ "37.148.43.35",
+ "37.148.43.42",
+ "37.148.43.62",
+ "37.148.43.65",
+ "37.148.43.67",
+ "37.148.43.80",
+ "37.148.43.85",
+ "37.148.43.98",
+ "37.148.43.107",
+ "37.148.43.119",
+ "37.148.43.122",
+ "37.148.43.125",
+ "37.148.43.128",
+ "37.148.43.130",
+ "37.148.43.164",
+ "37.148.43.166",
+ "37.148.43.169",
+ "37.148.43.171",
+ "37.148.43.189",
+ "37.148.43.190",
+ "37.148.43.195",
+ "37.148.43.196",
+ "37.148.43.202",
+ "37.148.43.205",
+ "37.148.43.207",
+ "37.148.43.219",
+ "37.148.43.222",
+ "37.148.43.229",
+ "37.148.43.233",
+ "37.148.43.250",
+ "37.148.44.0",
+ "37.148.44.14",
+ "37.148.44.24",
+ "37.148.44.30",
+ "37.148.44.39",
+ "37.148.44.43",
+ "37.148.44.60",
+ "37.148.44.65",
+ "37.148.44.70",
+ "37.148.44.72",
+ "37.148.44.73",
+ "37.148.44.80",
+ "37.148.44.84",
+ "37.148.44.85",
+ "37.148.44.92",
+ "37.148.44.95",
+ "37.148.44.98",
+ "37.148.44.106",
+ "37.148.44.113",
+ "37.148.44.118",
+ "37.148.44.129",
+ "37.148.44.133",
+ "37.148.44.134",
+ "37.148.44.135",
+ "37.148.44.142",
+ "37.148.44.143",
+ "37.148.44.152",
+ "37.148.44.159",
+ "37.148.44.161",
+ "37.148.44.169",
+ "37.148.44.181",
+ "37.148.44.185",
+ "37.148.44.188",
+ "37.148.44.189",
+ "37.148.44.191",
+ "37.148.44.198",
+ "37.148.44.201",
+ "37.148.44.213",
+ "37.148.44.215",
+ "37.148.44.216",
+ "37.148.44.238",
+ "37.148.44.244",
+ "37.148.44.254",
+ "37.148.45.21",
+ "37.148.45.30",
+ "37.148.45.31",
+ "37.148.45.35",
+ "37.148.45.37",
+ "37.148.45.43",
+ "37.148.45.52",
+ "37.148.45.53",
+ "37.148.45.54",
+ "37.148.45.64",
+ "37.148.45.65",
+ "37.148.45.72",
+ "37.148.45.77",
+ "37.148.45.89",
+ "37.148.45.96",
+ "37.148.45.97",
+ "37.148.45.100",
+ "37.148.45.108",
+ "37.148.45.116",
+ "37.148.45.120",
+ "37.148.45.125",
+ "37.148.45.129",
+ "37.148.45.134",
+ "37.148.45.142",
+ "37.148.45.151",
+ "37.148.45.162",
+ "37.148.45.164",
+ "37.148.45.183",
+ "37.148.45.194",
+ "37.148.45.202",
+ "37.148.45.206",
+ "37.148.45.217",
+ "37.148.46.31",
+ "37.148.46.35",
+ "37.148.46.47",
+ "37.148.46.53",
+ "37.148.46.59",
+ "37.148.46.67",
+ "37.148.46.113",
+ "37.148.46.142",
+ "37.148.46.174",
+ "37.148.46.191",
+ "37.148.46.237",
+ "37.148.47.7",
+ "37.148.47.19",
+ "37.148.47.25",
+ "37.148.47.33",
+ "37.148.47.45",
+ "37.148.47.70",
+ "37.148.47.75",
+ "37.148.47.92",
+ "37.148.47.99",
+ "37.148.47.100",
+ "37.148.47.131",
+ "37.148.47.132",
+ "37.148.47.139",
+ "37.148.47.146",
+ "37.148.47.165",
+ "37.148.48.15",
+ "37.148.48.17",
+ "37.148.48.19",
+ "37.148.48.25",
+ "37.148.48.31",
+ "37.148.48.43",
+ "37.148.48.52",
+ "37.148.48.53",
+ "37.148.48.56",
+ "37.148.48.68",
+ "37.148.48.70",
+ "37.148.48.82",
+ "37.148.48.86",
+ "37.148.48.87",
+ "37.148.48.99",
+ "37.148.48.102",
+ "37.148.48.103",
+ "37.148.48.104",
+ "37.148.48.116",
+ "37.148.48.123",
+ "37.148.48.124",
+ "37.148.48.180",
+ "37.148.48.202",
+ "37.148.48.203",
+ "37.148.48.207",
+ "37.148.48.210",
+ "37.148.48.217",
+ "37.148.48.234",
+ "37.148.48.239",
+ "37.148.48.241",
+ "37.148.48.242",
+ "37.148.48.244",
+ "37.148.48.252",
+ "37.148.49.17",
+ "37.148.49.19",
+ "37.148.49.26",
+ "37.148.49.40",
+ "37.148.49.41",
+ "37.148.49.43",
+ "37.148.49.44",
+ "37.148.49.45",
+ "37.148.49.70",
+ "37.148.49.71",
+ "37.148.49.74",
+ "37.148.49.80",
+ "37.148.49.93",
+ "37.148.49.120",
+ "37.148.49.130",
+ "37.148.49.133",
+ "37.148.49.134",
+ "37.148.49.137",
+ "37.148.49.141",
+ "37.148.49.142",
+ "37.148.49.143",
+ "37.148.49.153",
+ "37.148.49.155",
+ "37.148.49.162",
+ "37.148.49.163",
+ "37.148.49.165",
+ "37.148.49.169",
+ "37.148.49.171",
+ "37.148.49.173",
+ "37.148.49.175",
+ "37.148.49.177",
+ "37.148.49.178",
+ "37.148.49.182",
+ "37.148.49.183",
+ "37.148.49.184",
+ "37.148.49.193",
+ "37.148.49.236",
+ "37.148.50.9",
+ "37.148.50.11",
+ "37.148.50.18",
+ "37.148.50.29",
+ "37.148.50.30",
+ "37.148.50.39",
+ "37.148.50.41",
+ "37.148.50.58",
+ "37.148.50.67",
+ "37.148.50.71",
+ "37.148.50.82",
+ "37.148.50.91",
+ "37.148.50.108",
+ "37.148.50.116",
+ "37.148.50.124",
+ "37.148.50.128",
+ "37.148.50.134",
+ "37.148.50.152",
+ "37.148.50.157",
+ "37.148.50.158",
+ "37.148.50.160",
+ "37.148.50.163",
+ "37.148.50.170",
+ "37.148.50.174",
+ "37.148.50.175",
+ "37.148.50.220",
+ "37.148.50.223",
+ "37.148.50.230",
+ "37.148.50.241",
+ "37.148.50.248",
+ "37.148.51.6",
+ "37.148.51.15",
+ "37.148.51.28",
+ "37.148.51.41",
+ "37.148.51.51",
+ "37.148.51.58",
+ "37.148.51.59",
+ "37.148.51.61",
+ "37.148.51.79",
+ "37.148.51.114",
+ "37.148.51.118",
+ "37.148.51.131",
+ "37.148.51.134",
+ "37.148.51.135",
+ "37.148.51.137",
+ "37.148.51.142",
+ "37.148.51.144",
+ "37.148.51.147",
+ "37.148.51.167",
+ "37.148.51.168",
+ "37.148.51.200",
+ "37.148.51.201",
+ "37.148.51.222",
+ "37.148.51.226",
+ "37.148.56.4",
+ "37.148.56.10",
+ "37.148.56.26",
+ "37.148.56.29",
+ "37.148.56.48",
+ "37.148.56.81",
+ "37.148.56.84",
+ "37.148.56.110",
+ "37.148.56.125",
+ "37.148.56.155",
+ "37.148.56.157",
+ "37.148.56.160",
+ "37.148.56.163",
+ "37.148.56.165",
+ "37.148.56.172",
+ "37.148.56.173",
+ "37.148.56.179",
+ "37.148.56.191",
+ "37.148.56.206",
+ "37.148.56.211",
+ "37.148.56.232",
+ "37.148.57.4",
+ "37.148.57.5",
+ "37.148.57.8",
+ "37.148.57.15",
+ "37.148.57.18",
+ "37.148.57.21",
+ "37.148.57.27",
+ "37.148.57.35",
+ "37.148.57.36",
+ "37.148.57.37",
+ "37.148.57.39",
+ "37.148.57.67",
+ "37.148.57.71",
+ "37.148.57.74",
+ "37.148.57.82",
+ "37.148.57.88",
+ "37.148.57.98",
+ "37.148.57.102",
+ "37.148.57.108",
+ "37.148.57.117",
+ "37.148.57.119",
+ "37.148.57.122",
+ "37.148.57.137",
+ "37.148.57.144",
+ "37.148.57.171",
+ "37.148.57.186",
+ "37.148.57.187",
+ "37.148.57.194",
+ "37.148.57.198",
+ "37.148.57.208",
+ "37.148.57.216",
+ "37.148.57.222",
+ "37.148.57.236",
+ "37.148.57.250",
+ "37.148.58.53",
+ "37.148.58.63",
+ "37.148.58.89",
+ "37.148.58.102",
+ "37.148.58.107",
+ "37.148.58.121",
+ "37.148.58.138",
+ "37.148.58.157",
+ "37.148.58.159",
+ "37.148.58.177",
+ "37.148.58.190",
+ "37.148.58.191",
+ "37.148.58.231",
+ "37.148.58.233",
+ "37.148.58.235",
+ "37.148.58.237",
+ "37.148.59.1",
+ "37.148.59.5",
+ "37.148.59.10",
+ "37.148.59.29",
+ "37.148.59.31",
+ "37.148.59.32",
+ "37.148.59.53",
+ "37.148.59.57",
+ "37.148.59.101",
+ "37.148.59.109",
+ "37.148.59.169",
+ "37.148.59.174",
+ "37.148.59.180",
+ "37.148.59.188",
+ "37.148.59.189",
+ "37.148.59.195",
+ "37.148.59.229",
+ "37.148.59.231",
+ "37.148.59.235",
+ "37.148.59.252",
+ "37.148.60.12",
+ "37.148.60.22",
+ "37.148.60.55",
+ "37.148.60.64",
+ "37.148.60.69",
+ "37.148.60.78",
+ "37.148.60.81",
+ "37.148.60.89",
+ "37.148.60.98",
+ "37.148.60.100",
+ "37.148.60.101",
+ "37.148.60.109",
+ "37.148.60.114",
+ "37.148.60.126",
+ "37.148.60.132",
+ "37.148.60.140",
+ "37.148.60.143",
+ "37.148.60.155",
+ "37.148.60.178",
+ "37.148.60.190",
+ "37.148.60.193",
+ "37.148.60.197",
+ "37.148.60.198",
+ "37.148.60.249",
+ "37.148.61.29",
+ "37.148.61.30",
+ "37.148.61.37",
+ "37.148.61.60",
+ "37.148.61.85",
+ "37.148.61.89",
+ "37.148.61.97",
+ "37.148.61.109",
+ "37.148.61.149",
+ "37.148.61.151",
+ "37.148.61.168",
+ "37.148.61.173",
+ "37.148.61.201",
+ "37.148.61.204",
+ "37.148.61.213",
+ "37.148.61.215",
+ "37.148.61.217",
+ "37.148.61.218",
+ "37.148.61.234",
+ "37.148.61.251",
+ "37.148.62.23",
+ "37.148.62.37",
+ "37.148.62.100",
+ "37.148.62.105",
+ "37.148.62.118",
+ "37.148.62.119",
+ "37.148.62.141",
+ "37.148.62.144",
+ "37.148.62.153",
+ "37.148.62.188",
+ "37.148.62.195",
+ "37.148.62.216",
+ "37.148.62.240",
+ "37.148.62.252",
+ "37.148.63.45",
+ "37.148.63.55",
+ "37.148.63.60",
+ "37.148.63.66",
+ "37.148.63.79",
+ "37.148.63.93",
+ "37.148.63.95",
+ "37.148.63.96",
+ "37.148.63.97",
+ "37.148.63.109",
+ "37.148.63.117",
+ "37.148.63.129",
+ "37.148.63.137",
+ "37.148.63.140",
+ "37.148.63.161",
+ "37.148.63.171",
+ "37.148.63.178",
+ "37.148.63.186",
+ "37.148.63.193",
+ "37.148.63.195",
+ "37.148.63.197",
+ "37.148.63.199",
+ "37.148.63.217",
+ "37.148.63.218",
+ "37.148.63.250",
+ "37.148.80.18",
+ "37.148.80.35",
+ "37.148.80.56",
+ "37.148.80.78",
+ "37.148.80.82",
+ "37.148.80.88",
+ "37.148.80.90",
+ "37.148.80.95",
+ "37.148.80.109",
+ "37.148.80.116",
+ "37.148.80.123",
+ "37.148.80.146",
+ "37.148.80.152",
+ "37.148.80.157",
+ "37.148.80.160",
+ "37.148.80.161",
+ "37.148.80.166",
+ "37.148.80.172",
+ "37.148.80.183",
+ "37.148.80.188",
+ "37.148.80.213",
+ "37.148.80.221",
+ "37.148.80.244",
+ "37.148.81.0",
+ "37.148.81.15",
+ "37.148.81.47",
+ "37.148.81.70",
+ "37.148.81.80",
+ "37.148.81.90",
+ "37.148.81.92",
+ "37.148.81.102",
+ "37.148.81.118",
+ "37.148.81.151",
+ "37.148.81.153",
+ "37.148.81.170",
+ "37.148.81.173",
+ "37.148.81.180",
+ "37.148.81.194",
+ "37.148.81.220",
+ "37.148.81.224",
+ "37.148.81.233",
+ "37.148.81.234",
+ "37.148.81.245",
+ "37.148.82.9",
+ "37.148.82.13",
+ "37.148.82.28",
+ "37.148.82.36",
+ "37.148.82.48",
+ "37.148.82.49",
+ "37.148.82.56",
+ "37.148.82.63",
+ "37.148.82.69",
+ "37.148.82.75",
+ "37.148.82.88",
+ "37.148.82.112",
+ "37.148.82.113",
+ "37.148.82.124",
+ "37.148.82.134",
+ "37.148.82.139",
+ "37.148.82.152",
+ "37.148.82.159",
+ "37.148.82.161",
+ "37.148.82.166",
+ "37.148.82.170",
+ "37.148.82.174",
+ "37.148.82.184",
+ "37.148.82.193",
+ "37.148.82.212",
+ "37.148.82.213",
+ "37.148.82.223",
+ "37.148.82.226",
+ "37.148.82.245",
+ "37.148.83.2",
+ "37.148.83.5",
+ "37.148.83.9",
+ "37.148.83.25",
+ "37.148.83.28",
+ "37.148.83.36",
+ "37.148.83.37",
+ "37.148.83.46",
+ "37.148.83.62",
+ "37.148.83.68",
+ "37.148.83.76",
+ "37.148.83.141",
+ "37.148.83.169",
+ "37.148.83.179",
+ "37.148.83.194",
+ "37.148.83.221",
+ "37.148.83.223",
+ "37.148.83.230",
+ "37.148.83.252",
+ "37.148.83.255",
+ "37.148.84.4",
+ "37.148.84.10",
+ "37.148.84.19",
+ "37.148.84.44",
+ "37.148.84.46",
+ "37.148.84.48",
+ "37.148.84.60",
+ "37.148.84.62",
+ "37.148.84.64",
+ "37.148.84.66",
+ "37.148.84.80",
+ "37.148.84.115",
+ "37.148.84.155",
+ "37.148.84.161",
+ "37.148.84.162",
+ "37.148.84.163",
+ "37.148.84.165",
+ "37.148.84.188",
+ "37.148.84.195",
+ "37.148.84.227",
+ "37.148.84.238",
+ "37.148.84.240",
+ "37.148.84.242",
+ "37.148.84.243",
+ "37.148.84.247",
+ "37.148.85.19",
+ "37.148.85.21",
+ "37.148.85.24",
+ "37.148.85.57",
+ "37.148.85.62",
+ "37.148.85.78",
+ "37.148.85.83",
+ "37.148.85.90",
+ "37.148.85.94",
+ "37.148.85.95",
+ "37.148.85.102",
+ "37.148.85.105",
+ "37.148.85.115",
+ "37.148.85.125",
+ "37.148.85.131",
+ "37.148.85.132",
+ "37.148.85.141",
+ "37.148.85.159",
+ "37.148.85.175",
+ "37.148.85.209",
+ "37.148.85.211",
+ "37.148.85.212",
+ "37.148.85.218",
+ "37.148.85.223",
+ "37.148.85.243",
+ "37.148.86.26",
+ "37.148.86.42",
+ "37.148.86.48",
+ "37.148.86.55",
+ "37.148.86.57",
+ "37.148.86.85",
+ "37.148.86.88",
+ "37.148.86.94",
+ "37.148.86.102",
+ "37.148.86.110",
+ "37.148.86.129",
+ "37.148.86.139",
+ "37.148.86.144",
+ "37.148.86.149",
+ "37.148.86.170",
+ "37.148.86.209",
+ "37.148.86.213",
+ "37.148.86.243",
+ "37.148.86.249",
+ "37.148.87.2",
+ "37.148.87.19",
+ "37.148.87.25",
+ "37.148.87.26",
+ "37.148.87.29",
+ "37.148.87.42",
+ "37.148.87.44",
+ "37.148.87.49",
+ "37.148.87.65",
+ "37.148.87.74",
+ "37.148.87.76",
+ "37.148.87.78",
+ "37.148.87.83",
+ "37.148.87.88",
+ "37.148.87.90",
+ "37.148.87.91",
+ "37.148.87.92",
+ "37.148.87.100",
+ "37.148.87.110",
+ "37.148.87.117",
+ "37.148.87.118",
+ "37.148.87.140",
+ "37.148.87.144",
+ "37.148.87.150",
+ "37.148.87.161",
+ "37.148.87.169",
+ "37.148.87.173",
+ "37.148.87.181",
+ "37.148.87.182",
+ "37.148.87.184",
+ "37.148.87.192",
+ "37.148.87.198",
+ "37.148.87.214",
+ "37.148.87.219",
+ "37.148.87.223",
+ "37.148.87.229",
+ "37.148.87.230",
+ "37.148.87.236",
+ "37.148.87.248",
+ "37.148.87.250",
+ "37.148.87.251",
+ "37.148.87.253",
+ "37.148.90.12",
+ "37.148.90.13",
+ "37.148.90.18",
+ "37.148.90.22",
+ "37.148.90.34",
+ "37.148.90.47",
+ "37.148.90.51",
+ "37.148.90.56",
+ "37.148.90.66",
+ "37.148.90.84",
+ "37.148.90.93",
+ "37.148.90.102",
+ "37.148.90.118",
+ "37.148.90.119",
+ "37.148.90.124",
+ "37.148.90.132",
+ "37.148.90.176",
+ "37.148.90.223",
+ "37.148.90.240",
+ "37.152.160.42",
+ "37.152.161.45",
+ "37.152.163.14",
+ "37.152.163.69",
+ "37.152.163.132",
+ "37.152.163.145",
+ "37.152.163.148",
+ "37.152.163.160",
+ "37.152.163.211",
+ "37.152.163.216",
+ "37.152.163.226",
+ "37.152.163.227",
+ "37.152.163.253",
+ "37.152.164.17",
+ "37.152.165.37",
+ "37.152.165.136",
+ "37.152.165.139",
+ "37.152.165.151",
+ "37.152.165.156",
+ "37.152.165.197",
+ "37.152.165.200",
+ "37.152.166.10",
+ "37.152.166.18",
+ "37.152.166.36",
+ "37.152.166.58",
+ "37.152.166.68",
+ "37.152.166.84",
+ "37.152.166.88",
+ "37.152.166.98",
+ "37.152.166.102",
+ "37.152.166.121",
+ "37.152.166.139",
+ "37.152.166.142",
+ "37.152.166.144",
+ "37.152.166.148",
+ "37.152.166.151",
+ "37.152.166.156",
+ "37.152.166.158",
+ "37.152.167.92",
+ "37.152.167.142",
+ "37.152.171.115",
+ "37.152.172.104",
+ "37.152.173.126",
+ "37.152.177.179",
+ "37.152.177.200",
+ "37.152.178.112",
+ "37.152.178.130",
+ "37.152.179.40",
+ "37.152.179.135",
+ "37.152.181.83",
+ "37.152.182.77",
+ "37.152.188.155",
+ "37.152.189.124",
+ "37.152.190.29",
+ "37.152.190.69",
+ "37.152.190.238",
+ "37.156.8.43",
+ "37.156.8.147",
+ "37.156.8.165",
+ "37.156.8.197",
+ "37.156.8.240",
+ "37.156.9.26",
+ "37.156.9.42",
+ "37.156.9.67",
+ "37.156.9.99",
+ "37.156.9.152",
+ "37.156.9.184",
+ "37.156.9.192",
+ "37.156.10.32",
+ "37.156.10.49",
+ "37.156.10.60",
+ "37.156.10.71",
+ "37.156.11.6",
+ "37.156.11.10",
+ "37.156.11.24",
+ "37.156.11.31",
+ "37.156.11.74",
+ "37.156.11.80",
+ "37.156.11.138",
+ "37.156.11.142",
+ "37.156.11.167",
+ "37.156.11.175",
+ "37.156.11.179",
+ "37.156.11.196",
+ "37.156.11.229",
+ "37.156.11.248",
+ "37.156.12.3",
+ "37.156.12.4",
+ "37.156.12.65",
+ "37.156.12.94",
+ "37.156.12.147",
+ "37.156.12.166",
+ "37.156.12.169",
+ "37.156.12.209",
+ "37.156.12.231",
+ "37.156.12.233",
+ "37.156.12.241",
+ "37.156.12.251",
+ "37.156.13.11",
+ "37.156.13.23",
+ "37.156.13.151",
+ "37.156.13.152",
+ "37.156.13.163",
+ "37.156.13.237",
+ "37.156.14.64",
+ "37.156.14.97",
+ "37.156.14.206",
+ "37.156.14.209",
+ "37.156.14.215",
+ "37.156.14.226",
+ "37.156.14.248",
+ "37.156.15.20",
+ "37.156.15.131",
+ "37.156.15.149",
+ "37.156.15.174",
+ "37.156.15.198",
+ "37.156.15.254",
+ "37.156.16.202",
+ "37.156.16.241",
+ "37.156.17.102",
+ "37.156.17.179",
+ "37.156.17.246",
+ "37.156.18.149",
+ "37.156.19.32",
+ "37.156.19.54",
+ "37.156.19.84",
+ "37.156.20.60",
+ "37.156.20.92",
+ "37.156.20.185",
+ "37.156.20.235",
+ "37.156.20.241",
+ "37.156.21.15",
+ "37.156.21.216",
+ "37.156.21.225",
+ "37.156.22.51",
+ "37.156.23.23",
+ "37.156.23.35",
+ "37.156.23.39",
+ "37.156.23.80",
+ "37.156.23.105",
+ "37.156.24.204",
+ "37.156.25.28",
+ "37.156.26.223",
+ "37.156.27.77",
+ "37.156.115.84",
+ "37.156.144.66",
+ "37.156.144.172",
+ "37.156.144.174",
+ "37.156.145.85",
+ "37.156.145.195",
+ "37.156.145.234",
+ "37.156.146.2",
+ "37.156.146.3",
+ "37.156.146.4",
+ "37.156.146.5",
+ "37.156.146.46",
+ "37.156.146.115",
+ "37.156.146.180",
+ "37.156.147.34",
+ "37.156.147.36",
+ "37.156.147.38",
+ "37.156.147.213",
+ "37.156.165.69",
+ "37.156.165.198",
+ "37.156.248.43",
+ "37.156.248.193",
+ "37.156.249.213",
+ "37.156.249.237",
+ "37.191.76.48",
+ "37.191.76.49",
+ "37.191.76.50",
+ "37.191.76.51",
+ "37.191.76.52",
+ "37.191.76.53",
+ "37.191.76.54",
+ "37.191.76.64",
+ "37.191.76.177",
+ "37.191.77.102",
+ "37.191.77.106",
+ "37.191.77.202",
+ "37.191.78.210",
+ "37.191.78.211",
+ "37.191.78.212",
+ "37.191.78.215",
+ "37.191.79.18",
+ "37.191.79.55",
+ "37.191.79.252",
+ "37.191.84.46",
+ "37.191.84.170",
+ "37.191.84.222",
+ "37.191.85.58",
+ "37.191.92.225",
+ "37.191.93.67",
+ "37.191.93.126",
+ "37.191.93.151",
+ "37.191.94.66",
+ "37.191.95.88",
+ "37.191.95.181",
+ "37.202.148.10",
+ "37.202.148.28",
+ "37.202.148.41",
+ "37.202.148.69",
+ "37.202.148.78",
+ "37.202.148.89",
+ "37.202.148.96",
+ "37.202.148.101",
+ "37.202.148.124",
+ "37.202.148.126",
+ "37.202.148.141",
+ "37.202.148.165",
+ "37.202.148.185",
+ "37.202.148.190",
+ "37.202.148.219",
+ "37.202.148.231",
+ "37.202.148.234",
+ "37.202.148.235",
+ "37.202.149.215",
+ "37.202.149.224",
+ "37.202.149.227",
+ "37.202.149.234",
+ "37.202.149.244",
+ "37.202.149.252",
+ "37.202.152.4",
+ "37.202.152.33",
+ "37.202.152.43",
+ "37.202.152.46",
+ "37.202.152.50",
+ "37.202.152.84",
+ "37.202.152.109",
+ "37.202.152.112",
+ "37.202.152.126",
+ "37.202.152.133",
+ "37.202.152.139",
+ "37.202.152.149",
+ "37.202.152.160",
+ "37.202.152.165",
+ "37.202.152.178",
+ "37.202.152.182",
+ "37.202.152.187",
+ "37.202.152.189",
+ "37.202.152.194",
+ "37.202.152.203",
+ "37.202.152.207",
+ "37.202.152.213",
+ "37.202.152.224",
+ "37.202.152.226",
+ "37.202.152.231",
+ "37.202.152.250",
+ "37.202.153.21",
+ "37.202.153.22",
+ "37.202.153.30",
+ "37.202.153.61",
+ "37.202.153.80",
+ "37.202.153.83",
+ "37.202.153.89",
+ "37.202.153.94",
+ "37.202.153.97",
+ "37.202.153.103",
+ "37.202.153.105",
+ "37.202.153.123",
+ "37.202.153.127",
+ "37.202.153.138",
+ "37.202.153.140",
+ "37.202.153.145",
+ "37.202.153.148",
+ "37.202.153.197",
+ "37.202.153.202",
+ "37.202.153.204",
+ "37.202.153.212",
+ "37.202.153.219",
+ "37.202.153.221",
+ "37.202.153.232",
+ "37.202.153.235",
+ "37.202.153.242",
+ "37.202.153.255",
+ "37.202.154.5",
+ "37.202.154.8",
+ "37.202.154.26",
+ "37.202.154.34",
+ "37.202.154.51",
+ "37.202.154.76",
+ "37.202.154.83",
+ "37.202.154.90",
+ "37.202.154.132",
+ "37.202.154.134",
+ "37.202.154.158",
+ "37.202.154.163",
+ "37.202.154.181",
+ "37.202.154.184",
+ "37.202.154.195",
+ "37.202.154.218",
+ "37.202.154.219",
+ "37.202.154.228",
+ "37.202.154.230",
+ "37.202.154.234",
+ "37.202.154.246",
+ "37.202.154.252",
+ "37.202.154.253",
+ "37.202.155.6",
+ "37.202.155.19",
+ "37.202.155.36",
+ "37.202.155.40",
+ "37.202.155.45",
+ "37.202.155.50",
+ "37.202.155.51",
+ "37.202.155.69",
+ "37.202.155.75",
+ "37.202.155.82",
+ "37.202.155.86",
+ "37.202.155.88",
+ "37.202.155.97",
+ "37.202.155.108",
+ "37.202.155.131",
+ "37.202.155.132",
+ "37.202.155.174",
+ "37.202.155.188",
+ "37.202.155.192",
+ "37.202.155.218",
+ "37.202.155.225",
+ "37.202.155.231",
+ "37.202.155.232",
+ "37.202.155.242",
+ "37.202.155.246",
+ "37.202.156.0",
+ "37.202.156.5",
+ "37.202.156.10",
+ "37.202.156.20",
+ "37.202.156.26",
+ "37.202.156.34",
+ "37.202.156.53",
+ "37.202.156.61",
+ "37.202.156.72",
+ "37.202.156.79",
+ "37.202.156.82",
+ "37.202.156.87",
+ "37.202.156.88",
+ "37.202.156.115",
+ "37.202.156.132",
+ "37.202.156.134",
+ "37.202.156.135",
+ "37.202.156.143",
+ "37.202.156.204",
+ "37.202.156.218",
+ "37.202.156.240",
+ "37.202.156.243",
+ "37.202.156.246",
+ "37.202.156.251",
+ "37.202.157.3",
+ "37.202.157.12",
+ "37.202.157.40",
+ "37.202.157.42",
+ "37.202.157.86",
+ "37.202.157.91",
+ "37.202.157.96",
+ "37.202.157.110",
+ "37.202.157.119",
+ "37.202.157.121",
+ "37.202.157.126",
+ "37.202.157.145",
+ "37.202.157.175",
+ "37.202.157.189",
+ "37.202.157.197",
+ "37.202.157.207",
+ "37.202.157.209",
+ "37.202.157.234",
+ "37.202.157.237",
+ "37.202.158.15",
+ "37.202.158.31",
+ "37.202.158.42",
+ "37.202.158.59",
+ "37.202.158.71",
+ "37.202.158.79",
+ "37.202.158.110",
+ "37.202.158.154",
+ "37.202.158.186",
+ "37.202.158.198",
+ "37.202.158.205",
+ "37.202.158.238",
+ "37.202.158.240",
+ "37.202.158.249",
+ "37.202.158.254",
+ "37.202.159.1",
+ "37.202.159.20",
+ "37.202.159.58",
+ "37.202.159.72",
+ "37.202.159.78",
+ "37.202.159.90",
+ "37.202.159.101",
+ "37.202.159.126",
+ "37.202.159.135",
+ "37.202.159.136",
+ "37.202.159.147",
+ "37.202.159.171",
+ "37.202.159.184",
+ "37.202.159.206",
+ "37.202.159.210",
+ "37.202.159.224",
+ "37.202.159.243",
+ "37.202.159.246",
+ "37.202.159.253",
+ "37.202.168.10",
+ "37.202.168.28",
+ "37.202.168.55",
+ "37.202.168.61",
+ "37.202.168.64",
+ "37.202.168.80",
+ "37.202.168.96",
+ "37.202.168.101",
+ "37.202.168.112",
+ "37.202.168.119",
+ "37.202.168.120",
+ "37.202.168.121",
+ "37.202.168.122",
+ "37.202.168.135",
+ "37.202.168.137",
+ "37.202.168.176",
+ "37.202.168.177",
+ "37.202.168.228",
+ "37.202.169.3",
+ "37.202.169.8",
+ "37.202.169.59",
+ "37.202.169.65",
+ "37.202.169.67",
+ "37.202.169.89",
+ "37.202.169.104",
+ "37.202.169.145",
+ "37.202.169.146",
+ "37.202.169.168",
+ "37.202.169.179",
+ "37.202.169.189",
+ "37.202.169.197",
+ "37.202.169.222",
+ "37.202.169.224",
+ "37.202.169.242",
+ "37.202.170.3",
+ "37.202.170.7",
+ "37.202.170.49",
+ "37.202.170.60",
+ "37.202.170.80",
+ "37.202.170.88",
+ "37.202.170.96",
+ "37.202.170.115",
+ "37.202.170.145",
+ "37.202.170.209",
+ "37.202.170.252",
+ "37.202.171.4",
+ "37.202.171.21",
+ "37.202.171.22",
+ "37.202.171.37",
+ "37.202.171.49",
+ "37.202.171.82",
+ "37.202.171.100",
+ "37.202.171.106",
+ "37.202.171.131",
+ "37.202.171.145",
+ "37.202.171.146",
+ "37.202.171.152",
+ "37.202.171.157",
+ "37.202.171.158",
+ "37.202.171.171",
+ "37.202.171.180",
+ "37.202.171.188",
+ "37.202.171.198",
+ "37.202.171.203",
+ "37.202.171.208",
+ "37.202.171.230",
+ "37.202.171.251",
+ "37.202.171.253",
+ "37.202.171.254",
+ "37.202.171.255",
+ "37.202.172.2",
+ "37.202.172.6",
+ "37.202.172.10",
+ "37.202.172.11",
+ "37.202.172.15",
+ "37.202.172.16",
+ "37.202.172.18",
+ "37.202.172.36",
+ "37.202.172.55",
+ "37.202.172.70",
+ "37.202.172.76",
+ "37.202.172.81",
+ "37.202.172.103",
+ "37.202.172.115",
+ "37.202.172.132",
+ "37.202.172.138",
+ "37.202.172.171",
+ "37.202.172.187",
+ "37.202.172.202",
+ "37.202.172.222",
+ "37.202.172.246",
+ "37.202.173.4",
+ "37.202.173.14",
+ "37.202.173.23",
+ "37.202.173.44",
+ "37.202.173.57",
+ "37.202.173.64",
+ "37.202.173.72",
+ "37.202.173.88",
+ "37.202.173.91",
+ "37.202.173.93",
+ "37.202.173.112",
+ "37.202.173.148",
+ "37.202.173.155",
+ "37.202.173.179",
+ "37.202.173.183",
+ "37.202.173.188",
+ "37.202.173.205",
+ "37.202.173.228",
+ "37.202.173.240",
+ "37.202.173.243",
+ "37.202.173.244",
+ "37.202.174.3",
+ "37.202.174.10",
+ "37.202.174.17",
+ "37.202.174.23",
+ "37.202.174.33",
+ "37.202.174.50",
+ "37.202.174.53",
+ "37.202.174.62",
+ "37.202.174.71",
+ "37.202.174.91",
+ "37.202.174.101",
+ "37.202.174.104",
+ "37.202.174.105",
+ "37.202.174.115",
+ "37.202.174.121",
+ "37.202.174.128",
+ "37.202.174.161",
+ "37.202.174.181",
+ "37.202.174.184",
+ "37.202.174.212",
+ "37.202.174.231",
+ "37.202.174.232",
+ "37.202.175.34",
+ "37.202.175.35",
+ "37.202.175.37",
+ "37.202.175.39",
+ "37.202.175.52",
+ "37.202.175.59",
+ "37.202.175.68",
+ "37.202.175.69",
+ "37.202.175.87",
+ "37.202.175.88",
+ "37.202.175.93",
+ "37.202.175.94",
+ "37.202.175.98",
+ "37.202.175.115",
+ "37.202.175.116",
+ "37.202.175.120",
+ "37.202.175.129",
+ "37.202.175.173",
+ "37.202.175.175",
+ "37.202.175.185",
+ "37.202.175.205",
+ "37.202.175.207",
+ "37.202.175.208",
+ "37.202.175.224",
+ "37.202.175.232",
+ "37.202.175.242",
+ "37.202.176.4",
+ "37.202.176.10",
+ "37.202.176.13",
+ "37.202.176.26",
+ "37.202.176.34",
+ "37.202.176.49",
+ "37.202.176.51",
+ "37.202.176.59",
+ "37.202.176.64",
+ "37.202.176.66",
+ "37.202.176.70",
+ "37.202.176.76",
+ "37.202.176.87",
+ "37.202.176.95",
+ "37.202.176.97",
+ "37.202.176.104",
+ "37.202.176.111",
+ "37.202.176.119",
+ "37.202.176.132",
+ "37.202.176.143",
+ "37.202.176.154",
+ "37.202.176.168",
+ "37.202.176.171",
+ "37.202.176.179",
+ "37.202.176.186",
+ "37.202.176.189",
+ "37.202.176.199",
+ "37.202.176.200",
+ "37.202.176.201",
+ "37.202.176.205",
+ "37.202.176.226",
+ "37.202.176.230",
+ "37.202.177.6",
+ "37.202.177.10",
+ "37.202.177.11",
+ "37.202.177.26",
+ "37.202.177.29",
+ "37.202.177.30",
+ "37.202.177.44",
+ "37.202.177.46",
+ "37.202.177.51",
+ "37.202.177.58",
+ "37.202.177.96",
+ "37.202.177.107",
+ "37.202.177.112",
+ "37.202.177.117",
+ "37.202.177.119",
+ "37.202.177.137",
+ "37.202.177.152",
+ "37.202.177.174",
+ "37.202.177.192",
+ "37.202.177.193",
+ "37.202.177.211",
+ "37.202.177.217",
+ "37.202.177.219",
+ "37.202.177.224",
+ "37.202.177.242",
+ "37.202.178.4",
+ "37.202.178.8",
+ "37.202.178.12",
+ "37.202.178.13",
+ "37.202.178.24",
+ "37.202.178.60",
+ "37.202.178.76",
+ "37.202.178.82",
+ "37.202.178.106",
+ "37.202.178.109",
+ "37.202.178.123",
+ "37.202.178.128",
+ "37.202.178.136",
+ "37.202.178.143",
+ "37.202.178.178",
+ "37.202.178.182",
+ "37.202.178.198",
+ "37.202.178.240",
+ "37.202.178.242",
+ "37.202.178.244",
+ "37.202.178.245",
+ "37.202.179.2",
+ "37.202.179.19",
+ "37.202.179.20",
+ "37.202.179.21",
+ "37.202.179.28",
+ "37.202.179.32",
+ "37.202.179.47",
+ "37.202.179.53",
+ "37.202.179.64",
+ "37.202.179.67",
+ "37.202.179.71",
+ "37.202.179.80",
+ "37.202.179.92",
+ "37.202.179.96",
+ "37.202.179.110",
+ "37.202.179.188",
+ "37.202.179.191",
+ "37.202.179.193",
+ "37.202.179.197",
+ "37.202.179.203",
+ "37.202.179.206",
+ "37.202.179.224",
+ "37.202.179.229",
+ "37.202.179.230",
+ "37.202.179.238",
+ "37.202.179.239",
+ "37.202.180.2",
+ "37.202.180.43",
+ "37.202.180.51",
+ "37.202.180.72",
+ "37.202.180.79",
+ "37.202.180.83",
+ "37.202.180.94",
+ "37.202.180.112",
+ "37.202.180.121",
+ "37.202.180.133",
+ "37.202.180.135",
+ "37.202.180.136",
+ "37.202.180.149",
+ "37.202.180.176",
+ "37.202.180.189",
+ "37.202.180.196",
+ "37.202.180.210",
+ "37.202.180.219",
+ "37.202.180.225",
+ "37.202.180.228",
+ "37.202.180.238",
+ "37.202.181.5",
+ "37.202.181.7",
+ "37.202.181.20",
+ "37.202.181.22",
+ "37.202.181.26",
+ "37.202.181.37",
+ "37.202.181.42",
+ "37.202.181.54",
+ "37.202.181.62",
+ "37.202.181.67",
+ "37.202.181.77",
+ "37.202.181.111",
+ "37.202.181.112",
+ "37.202.181.120",
+ "37.202.181.125",
+ "37.202.181.165",
+ "37.202.181.192",
+ "37.202.181.212",
+ "37.202.181.219",
+ "37.202.181.223",
+ "37.202.181.231",
+ "37.202.181.233",
+ "37.202.181.243",
+ "37.202.181.253",
+ "37.202.182.41",
+ "37.202.182.46",
+ "37.202.182.48",
+ "37.202.182.59",
+ "37.202.182.66",
+ "37.202.182.72",
+ "37.202.182.83",
+ "37.202.182.87",
+ "37.202.182.90",
+ "37.202.182.130",
+ "37.202.182.153",
+ "37.202.182.167",
+ "37.202.182.189",
+ "37.202.182.203",
+ "37.202.184.36",
+ "37.202.184.39",
+ "37.202.184.42",
+ "37.202.184.50",
+ "37.202.184.82",
+ "37.202.184.98",
+ "37.202.184.130",
+ "37.202.184.131",
+ "37.202.184.146",
+ "37.202.184.147",
+ "37.202.184.154",
+ "37.202.184.162",
+ "37.202.184.189",
+ "37.202.184.218",
+ "37.202.184.251",
+ "37.202.184.252",
+ "37.202.184.253",
+ "37.202.184.254",
+ "37.202.185.1",
+ "37.202.185.22",
+ "37.202.185.26",
+ "37.202.185.31",
+ "37.202.185.35",
+ "37.202.185.36",
+ "37.202.185.51",
+ "37.202.185.80",
+ "37.202.185.91",
+ "37.202.185.125",
+ "37.202.185.142",
+ "37.202.185.156",
+ "37.202.185.170",
+ "37.202.185.196",
+ "37.202.185.241",
+ "37.202.185.253",
+ "37.202.186.0",
+ "37.202.186.2",
+ "37.202.186.5",
+ "37.202.186.17",
+ "37.202.186.29",
+ "37.202.186.33",
+ "37.202.186.40",
+ "37.202.186.51",
+ "37.202.186.52",
+ "37.202.186.53",
+ "37.202.186.58",
+ "37.202.186.64",
+ "37.202.186.67",
+ "37.202.186.78",
+ "37.202.186.114",
+ "37.202.186.117",
+ "37.202.186.120",
+ "37.202.186.140",
+ "37.202.186.151",
+ "37.202.186.155",
+ "37.202.186.181",
+ "37.202.186.190",
+ "37.202.186.201",
+ "37.202.186.209",
+ "37.202.186.211",
+ "37.202.186.223",
+ "37.202.186.247",
+ "37.202.186.252",
+ "37.202.187.43",
+ "37.202.187.48",
+ "37.202.187.67",
+ "37.202.187.69",
+ "37.202.187.72",
+ "37.202.187.79",
+ "37.202.187.80",
+ "37.202.187.82",
+ "37.202.187.120",
+ "37.202.187.132",
+ "37.202.187.135",
+ "37.202.187.137",
+ "37.202.187.140",
+ "37.202.187.160",
+ "37.202.187.181",
+ "37.202.187.182",
+ "37.202.187.185",
+ "37.202.187.204",
+ "37.202.187.210",
+ "37.202.187.211",
+ "37.202.187.220",
+ "37.202.187.227",
+ "37.202.188.10",
+ "37.202.188.13",
+ "37.202.188.15",
+ "37.202.188.27",
+ "37.202.188.40",
+ "37.202.188.43",
+ "37.202.188.50",
+ "37.202.188.54",
+ "37.202.188.59",
+ "37.202.188.90",
+ "37.202.188.91",
+ "37.202.188.110",
+ "37.202.188.144",
+ "37.202.188.149",
+ "37.202.188.158",
+ "37.202.188.165",
+ "37.202.188.177",
+ "37.202.188.179",
+ "37.202.188.185",
+ "37.202.188.195",
+ "37.202.188.198",
+ "37.202.188.235",
+ "37.202.188.238",
+ "37.202.188.240",
+ "37.202.188.255",
+ "37.202.189.9",
+ "37.202.189.25",
+ "37.202.189.39",
+ "37.202.189.44",
+ "37.202.189.47",
+ "37.202.189.76",
+ "37.202.189.94",
+ "37.202.189.99",
+ "37.202.189.100",
+ "37.202.189.103",
+ "37.202.189.112",
+ "37.202.189.134",
+ "37.202.189.138",
+ "37.202.189.147",
+ "37.202.189.149",
+ "37.202.189.158",
+ "37.202.189.159",
+ "37.202.189.189",
+ "37.202.189.200",
+ "37.202.189.214",
+ "37.202.189.235",
+ "37.202.189.239",
+ "37.202.190.6",
+ "37.202.190.8",
+ "37.202.190.16",
+ "37.202.190.61",
+ "37.202.190.80",
+ "37.202.190.82",
+ "37.202.190.85",
+ "37.202.190.88",
+ "37.202.190.92",
+ "37.202.190.103",
+ "37.202.190.118",
+ "37.202.190.137",
+ "37.202.190.147",
+ "37.202.190.153",
+ "37.202.190.162",
+ "37.202.190.166",
+ "37.202.190.172",
+ "37.202.190.182",
+ "37.202.190.190",
+ "37.202.190.194",
+ "37.202.190.200",
+ "37.202.190.217",
+ "37.202.190.219",
+ "37.202.190.222",
+ "37.202.190.226",
+ "37.202.190.240",
+ "37.202.190.241",
+ "37.202.190.242",
+ "37.202.190.244",
+ "37.202.191.2",
+ "37.202.191.4",
+ "37.202.191.12",
+ "37.202.191.17",
+ "37.202.191.21",
+ "37.202.191.58",
+ "37.202.191.63",
+ "37.202.191.78",
+ "37.202.191.90",
+ "37.202.191.106",
+ "37.202.191.128",
+ "37.202.191.155",
+ "37.202.191.175",
+ "37.202.191.185",
+ "37.202.191.212",
+ "37.202.191.228",
+ "37.202.191.230",
+ "37.202.191.232",
+ "37.202.191.238",
+ "37.202.191.240",
+ "37.202.225.185",
+ "37.202.228.171",
+ "37.202.228.254",
+ "37.202.229.103",
+ "37.202.231.16",
+ "37.202.231.59",
+ "37.202.231.242",
+ "37.202.237.194",
+ "37.202.239.132",
+ "37.228.136.214",
+ "37.228.137.85",
+ "37.228.137.88",
+ "37.228.137.107",
+ "37.228.137.108",
+ "37.228.137.156",
+ "37.228.137.157",
+ "37.228.137.158",
+ "37.228.137.254",
+ "37.228.138.66",
+ "37.228.139.27",
+ "37.228.139.51",
+ "37.228.139.61",
+ "37.228.139.226",
+ "37.254.0.1",
+ "37.254.96.1",
+ "37.255.64.1",
+ "37.255.128.41",
+ "37.255.133.26",
+ "37.255.133.27",
+ "37.255.133.28",
+ "37.255.133.29",
+ "37.255.134.66",
+ "37.255.134.160",
+ "37.255.134.194",
+ "37.255.135.34",
+ "37.255.135.35",
+ "37.255.135.50",
+ "37.255.135.66",
+ "37.255.135.203",
+ "37.255.149.136",
+ "37.255.149.222",
+ "37.255.173.83",
+ "37.255.173.134",
+ "37.255.177.65",
+ "37.255.177.243",
+ "37.255.186.150",
+ "37.255.187.147",
+ "37.255.192.12",
+ "37.255.192.24",
+ "37.255.192.96",
+ "37.255.192.191",
+ "37.255.192.227",
+ "37.255.193.110",
+ "37.255.193.115",
+ "37.255.193.151",
+ "37.255.193.159",
+ "37.255.193.229",
+ "37.255.193.241",
+ "37.255.194.14",
+ "37.255.194.19",
+ "37.255.194.51",
+ "37.255.194.85",
+ "37.255.194.100",
+ "37.255.194.108",
+ "37.255.194.121",
+ "37.255.194.139",
+ "37.255.194.171",
+ "37.255.194.198",
+ "37.255.194.199",
+ "37.255.194.213",
+ "37.255.194.231",
+ "37.255.195.7",
+ "37.255.195.10",
+ "37.255.195.96",
+ "37.255.195.170",
+ "37.255.195.194",
+ "37.255.196.26",
+ "37.255.196.90",
+ "37.255.196.95",
+ "37.255.196.125",
+ "37.255.196.150",
+ "37.255.196.199",
+ "37.255.197.63",
+ "37.255.197.190",
+ "37.255.198.41",
+ "37.255.198.110",
+ "37.255.198.220",
+ "37.255.198.231",
+ "37.255.199.204",
+ "37.255.199.248",
+ "37.255.200.103",
+ "37.255.200.127",
+ "37.255.200.161",
+ "37.255.200.204",
+ "37.255.200.254",
+ "37.255.201.105",
+ "37.255.201.171",
+ "37.255.201.250",
+ "37.255.202.94",
+ "37.255.202.123",
+ "37.255.202.124",
+ "37.255.202.160",
+ "37.255.202.219",
+ "37.255.202.244",
+ "37.255.202.251",
+ "37.255.203.94",
+ "37.255.203.130",
+ "37.255.203.155",
+ "37.255.203.235",
+ "37.255.203.250",
+ "37.255.204.1",
+ "37.255.204.238",
+ "37.255.204.239",
+ "37.255.205.22",
+ "37.255.205.232",
+ "37.255.206.150",
+ "37.255.206.159",
+ "37.255.206.180",
+ "37.255.207.114",
+ "37.255.207.164",
+ "37.255.207.236",
+ "37.255.208.10",
+ "37.255.208.12",
+ "37.255.208.43",
+ "37.255.208.53",
+ "37.255.209.0",
+ "37.255.209.44",
+ "37.255.209.123",
+ "37.255.209.136",
+ "37.255.209.149",
+ "37.255.209.161",
+ "37.255.209.212",
+ "37.255.210.51",
+ "37.255.210.55",
+ "37.255.210.70",
+ "37.255.210.92",
+ "37.255.210.168",
+ "37.255.211.26",
+ "37.255.211.56",
+ "37.255.211.106",
+ "37.255.211.221",
+ "37.255.211.245",
+ "37.255.211.252",
+ "37.255.212.30",
+ "37.255.212.46",
+ "37.255.213.36",
+ "37.255.213.38",
+ "37.255.213.51",
+ "37.255.213.88",
+ "37.255.213.150",
+ "37.255.213.235",
+ "37.255.214.119",
+ "37.255.215.21",
+ "37.255.215.185",
+ "37.255.216.19",
+ "37.255.216.22",
+ "37.255.216.113",
+ "37.255.216.160",
+ "37.255.217.22",
+ "37.255.217.41",
+ "37.255.217.115",
+ "37.255.217.164",
+ "37.255.217.196",
+ "37.255.218.116",
+ "37.255.218.143",
+ "37.255.218.170",
+ "37.255.218.191",
+ "37.255.219.17",
+ "37.255.219.190",
+ "37.255.220.48",
+ "37.255.220.51",
+ "37.255.220.59",
+ "37.255.220.121",
+ "37.255.220.162",
+ "37.255.220.172",
+ "37.255.220.208",
+ "37.255.221.6",
+ "37.255.221.16",
+ "37.255.221.40",
+ "37.255.221.62",
+ "37.255.221.147",
+ "37.255.221.163",
+ "37.255.222.36",
+ "37.255.222.39",
+ "37.255.222.42",
+ "37.255.222.124",
+ "37.255.222.223",
+ "37.255.222.232",
+ "37.255.223.34",
+ "37.255.223.38",
+ "37.255.223.40",
+ "37.255.223.51",
+ "37.255.223.201",
+ "37.255.223.235",
+ "37.255.223.239",
+ "37.255.224.3",
+ "37.255.224.143",
+ "37.255.225.38",
+ "37.255.225.108",
+ "37.255.228.106",
+ "37.255.228.122",
+ "37.255.228.165",
+ "37.255.228.219",
+ "37.255.229.35",
+ "37.255.229.88",
+ "37.255.229.99",
+ "37.255.229.163",
+ "37.255.229.168",
+ "37.255.229.238",
+ "37.255.230.64",
+ "37.255.230.169",
+ "37.255.230.246",
+ "37.255.231.32",
+ "37.255.231.128",
+ "37.255.231.132",
+ "37.255.231.172",
+ "37.255.231.184",
+ "37.255.231.207",
+ "37.255.231.221",
+ "37.255.232.10",
+ "37.255.232.130",
+ "37.255.232.194",
+ "37.255.232.233",
+ "37.255.232.255",
+ "37.255.233.12",
+ "37.255.233.128",
+ "37.255.233.143",
+ "37.255.233.226",
+ "37.255.233.253",
+ "37.255.234.15",
+ "37.255.234.75",
+ "37.255.234.132",
+ "37.255.234.134",
+ "37.255.234.180",
+ "37.255.234.188",
+ "37.255.235.111",
+ "37.255.235.138",
+ "37.255.236.5",
+ "37.255.236.64",
+ "37.255.236.97",
+ "37.255.236.134",
+ "37.255.236.149",
+ "37.255.236.193",
+ "37.255.236.209",
+ "37.255.237.68",
+ "37.255.237.69",
+ "37.255.237.70",
+ "37.255.237.116",
+ "37.255.237.117",
+ "37.255.237.118",
+ "37.255.237.119",
+ "37.255.237.132",
+ "37.255.238.4",
+ "37.255.238.12",
+ "37.255.238.23",
+ "37.255.238.142",
+ "37.255.238.188",
+ "37.255.238.253",
+ "37.255.239.81",
+ "37.255.239.99",
+ "37.255.239.104",
+ "37.255.239.171",
+ "37.255.240.0",
+ "37.255.240.23",
+ "37.255.240.124",
+ "37.255.240.217",
+ "37.255.241.27",
+ "37.255.241.102",
+ "37.255.241.122",
+ "37.255.241.129",
+ "37.255.241.137",
+ "37.255.241.140",
+ "37.255.241.213",
+ "37.255.242.91",
+ "37.255.242.182",
+ "37.255.242.186",
+ "37.255.242.212",
+ "37.255.243.44",
+ "37.255.243.69",
+ "37.255.243.169",
+ "37.255.243.205",
+ "37.255.243.218",
+ "37.255.244.53",
+ "37.255.244.254",
+ "37.255.245.67",
+ "37.255.246.156",
+ "37.255.248.156",
+ "37.255.248.202",
+ "37.255.248.241",
+ "37.255.254.18",
+ "37.255.254.20",
+ "37.255.254.254",
+ "37.255.255.18",
+ "45.8.160.13",
+ "45.8.160.79",
+ "45.8.160.82",
+ "45.8.160.84",
+ "45.8.160.94",
+ "45.8.160.211",
+ "45.8.160.232",
+ "45.8.160.237",
+ "45.8.160.253",
+ "45.9.252.86",
+ "45.9.253.10",
+ "45.9.253.46",
+ "45.9.253.53",
+ "45.9.253.122",
+ "45.9.253.169",
+ "45.9.254.90",
+ "45.11.185.253",
+ "45.11.187.165",
+ "45.11.187.173",
+ "45.15.200.30",
+ "45.81.19.10",
+ "45.81.19.11",
+ "45.81.19.13",
+ "45.81.19.14",
+ "45.81.19.15",
+ "45.81.19.16",
+ "45.81.19.19",
+ "45.81.19.59",
+ "45.81.19.132",
+ "45.81.19.150",
+ "45.81.19.235",
+ "45.82.137.234",
+ "45.82.138.48",
+ "45.84.157.43",
+ "45.84.157.200",
+ "45.84.157.202",
+ "45.84.157.203",
+ "45.84.157.204",
+ "45.84.157.209",
+ "45.84.157.210",
+ "45.84.157.211",
+ "45.84.157.212",
+ "45.84.157.213",
+ "45.84.157.217",
+ "45.84.157.218",
+ "45.84.157.220",
+ "45.86.4.11",
+ "45.86.4.66",
+ "45.86.4.67",
+ "45.86.4.82",
+ "45.86.4.100",
+ "45.86.5.211",
+ "45.86.6.25",
+ "45.86.6.113",
+ "45.87.4.116",
+ "45.87.4.151",
+ "45.87.5.66",
+ "45.87.5.148",
+ "45.87.5.178",
+ "45.87.6.9",
+ "45.87.6.38",
+ "45.87.6.45",
+ "45.89.236.37",
+ "45.89.236.181",
+ "45.89.237.66",
+ "45.89.239.214",
+ "45.89.239.227",
+ "45.90.72.166",
+ "45.90.73.207",
+ "45.90.74.109",
+ "45.90.74.225",
+ "45.92.93.236",
+ "45.92.94.4",
+ "45.92.94.20",
+ "45.92.94.122",
+ "45.92.95.59",
+ "45.94.214.3",
+ "45.94.214.163",
+ "45.94.214.219",
+ "45.94.214.240",
+ "45.94.215.32",
+ "45.94.255.186",
+ "45.129.36.45",
+ "45.129.36.181",
+ "45.129.36.220",
+ "45.129.36.221",
+ "45.129.36.222",
+ "45.129.37.123",
+ "45.129.37.124",
+ "45.129.37.145",
+ "45.129.37.148",
+ "45.129.37.153",
+ "45.129.37.156",
+ "45.129.37.157",
+ "45.129.37.158",
+ "45.129.37.185",
+ "45.129.37.198",
+ "45.129.37.199",
+ "45.129.38.35",
+ "45.129.38.51",
+ "45.129.38.53",
+ "45.129.38.56",
+ "45.129.38.60",
+ "45.129.39.5",
+ "45.129.39.6",
+ "45.129.39.9",
+ "45.129.39.12",
+ "45.129.39.13",
+ "45.129.39.168",
+ "45.132.172.9",
+ "45.132.172.56",
+ "45.132.172.84",
+ "45.132.172.93",
+ "45.132.172.100",
+ "45.132.172.144",
+ "45.132.172.161",
+ "45.132.173.200",
+ "45.132.174.138",
+ "45.132.174.191",
+ "45.132.175.4",
+ "45.134.99.4",
+ "45.135.241.79",
+ "45.135.243.61",
+ "45.135.243.70",
+ "45.138.132.27",
+ "45.138.133.205",
+ "45.138.135.32",
+ "45.138.135.39",
+ "45.138.135.57",
+ "45.138.135.224",
+ "45.139.10.61",
+ "45.139.10.81",
+ "45.139.10.200",
+ "45.139.11.250",
+ "45.140.225.4",
+ "45.140.225.6",
+ "45.140.225.60",
+ "45.140.225.62",
+ "45.140.225.218",
+ "45.140.226.9",
+ "45.140.226.10",
+ "45.140.226.11",
+ "45.140.226.12",
+ "45.140.226.25",
+ "45.140.226.73",
+ "45.140.226.226",
+ "45.142.190.13",
+ "45.142.190.24",
+ "45.142.190.46",
+ "45.142.190.139",
+ "45.142.190.142",
+ "45.142.191.3",
+ "45.142.191.9",
+ "45.142.191.11",
+ "45.142.191.17",
+ "45.142.191.19",
+ "45.142.191.24",
+ "45.142.191.33",
+ "45.142.191.35",
+ "45.142.191.38",
+ "45.142.191.39",
+ "45.144.18.7",
+ "45.144.18.52",
+ "45.144.19.70",
+ "45.144.19.75",
+ "45.144.19.76",
+ "45.144.19.77",
+ "45.144.19.78",
+ "45.144.19.85",
+ "45.147.76.252",
+ "45.147.77.59",
+ "45.147.77.88",
+ "45.147.77.169",
+ "45.147.77.170",
+ "45.147.77.171",
+ "45.147.77.195",
+ "45.147.79.36",
+ "45.147.79.37",
+ "45.147.79.38",
+ "45.147.79.39",
+ "45.148.248.8",
+ "45.148.249.62",
+ "45.148.250.68",
+ "45.149.76.12",
+ "45.149.76.138",
+ "45.149.76.183",
+ "45.149.76.195",
+ "45.149.77.114",
+ "45.149.77.135",
+ "45.149.77.186",
+ "45.149.78.156",
+ "45.149.78.226",
+ "45.149.79.53",
+ "45.156.184.16",
+ "45.156.184.26",
+ "45.156.184.32",
+ "45.156.184.36",
+ "45.156.184.125",
+ "45.156.185.30",
+ "45.156.185.59",
+ "45.156.185.80",
+ "45.156.185.121",
+ "45.156.185.129",
+ "45.156.185.130",
+ "45.156.185.164",
+ "45.156.185.187",
+ "45.156.185.192",
+ "45.156.185.201",
+ "45.156.185.240",
+ "45.156.185.254",
+ "45.156.186.108",
+ "45.156.186.230",
+ "45.156.186.240",
+ "45.156.187.106",
+ "45.158.120.7",
+ "45.159.112.10",
+ "45.159.112.43",
+ "45.159.112.87",
+ "45.159.112.107",
+ "45.159.112.143",
+ "45.159.112.144",
+ "45.159.112.196",
+ "45.159.113.144",
+ "45.159.113.161",
+ "45.159.113.165",
+ "45.159.113.172",
+ "45.159.113.242",
+ "45.159.113.244",
+ "45.159.114.200",
+ "45.159.114.201",
+ "45.159.114.202",
+ "45.159.114.236",
+ "45.159.115.117",
+ "45.159.115.119",
+ "45.159.115.127",
+ "45.159.115.129",
+ "45.159.115.151",
+ "45.159.149.40",
+ "45.159.149.108",
+ "45.159.149.158",
+ "45.159.150.94",
+ "45.159.150.117",
+ "45.159.150.157",
+ "45.159.150.165",
+ "45.159.151.16",
+ "45.159.151.32",
+ "45.159.151.39",
+ "45.159.151.128",
+ "45.159.151.169",
+ "45.159.197.86",
+ "45.159.197.114",
+ "45.159.198.246",
+ "46.28.72.18",
+ "46.28.72.19",
+ "46.28.72.20",
+ "46.28.72.21",
+ "46.28.72.133",
+ "46.28.74.130",
+ "46.28.75.66",
+ "46.28.75.67",
+ "46.28.75.106",
+ "46.28.75.107",
+ "46.28.75.108",
+ "46.28.75.109",
+ "46.28.75.130",
+ "46.28.76.101",
+ "46.28.77.26",
+ "46.28.77.38",
+ "46.28.77.54",
+ "46.28.77.194",
+ "46.32.1.13",
+ "46.32.1.75",
+ "46.32.1.118",
+ "46.32.1.145",
+ "46.32.1.165",
+ "46.32.1.171",
+ "46.32.1.202",
+ "46.32.1.250",
+ "46.32.2.13",
+ "46.32.4.82",
+ "46.32.4.83",
+ "46.32.4.85",
+ "46.32.4.86",
+ "46.32.4.90",
+ "46.32.4.164",
+ "46.32.21.14",
+ "46.32.25.75",
+ "46.32.25.76",
+ "46.32.25.77",
+ "46.32.25.78",
+ "46.32.25.178",
+ "46.32.28.17",
+ "46.32.28.29",
+ "46.32.28.40",
+ "46.32.28.52",
+ "46.32.28.68",
+ "46.32.28.128",
+ "46.32.28.141",
+ "46.32.28.144",
+ "46.32.28.209",
+ "46.32.28.220",
+ "46.32.28.238",
+ "46.32.31.50",
+ "46.34.96.20",
+ "46.34.161.9",
+ "46.34.161.41",
+ "46.34.161.67",
+ "46.34.161.68",
+ "46.34.161.104",
+ "46.34.161.110",
+ "46.34.161.183",
+ "46.34.161.186",
+ "46.34.161.226",
+ "46.34.161.227",
+ "46.34.162.18",
+ "46.34.162.19",
+ "46.34.162.20",
+ "46.34.162.22",
+ "46.34.163.161",
+ "46.34.164.10",
+ "46.34.164.18",
+ "46.34.164.94",
+ "46.34.164.105",
+ "46.34.164.110",
+ "46.34.164.218",
+ "46.34.164.238",
+ "46.34.165.50",
+ "46.34.165.134",
+ "46.34.165.138",
+ "46.34.165.186",
+ "46.34.166.18",
+ "46.34.166.91",
+ "46.34.166.106",
+ "46.34.166.114",
+ "46.34.166.115",
+ "46.34.166.186",
+ "46.34.166.187",
+ "46.34.166.235",
+ "46.34.166.237",
+ "46.34.167.14",
+ "46.34.167.52",
+ "46.34.167.162",
+ "46.34.178.130",
+ "46.36.96.30",
+ "46.36.103.93",
+ "46.36.107.56",
+ "46.38.138.50",
+ "46.38.138.72",
+ "46.38.138.139",
+ "46.38.138.151",
+ "46.38.138.165",
+ "46.38.143.163",
+ "46.38.143.189",
+ "46.38.147.88",
+ "46.38.147.219",
+ "46.38.147.220",
+ "46.38.147.222",
+ "46.38.149.4",
+ "46.38.149.200",
+ "46.38.149.201",
+ "46.38.151.110",
+ "46.51.37.37",
+ "46.51.37.38",
+ "46.51.37.70",
+ "46.51.37.159",
+ "46.51.37.181",
+ "46.51.37.233",
+ "46.51.37.246",
+ "46.100.5.15",
+ "46.100.5.59",
+ "46.100.5.122",
+ "46.100.5.134",
+ "46.100.5.139",
+ "46.100.5.143",
+ "46.100.5.186",
+ "46.100.5.221",
+ "46.100.5.225",
+ "46.100.6.13",
+ "46.100.6.82",
+ "46.100.6.132",
+ "46.100.6.184",
+ "46.100.6.198",
+ "46.100.7.0",
+ "46.100.7.18",
+ "46.100.7.32",
+ "46.100.7.60",
+ "46.100.7.143",
+ "46.100.7.190",
+ "46.100.7.198",
+ "46.100.7.234",
+ "46.100.8.3",
+ "46.100.8.84",
+ "46.100.8.134",
+ "46.100.8.180",
+ "46.100.9.8",
+ "46.100.9.100",
+ "46.100.9.191",
+ "46.100.9.199",
+ "46.100.10.34",
+ "46.100.10.77",
+ "46.100.11.42",
+ "46.100.11.70",
+ "46.100.11.131",
+ "46.100.11.138",
+ "46.100.11.139",
+ "46.100.11.171",
+ "46.100.11.212",
+ "46.100.11.242",
+ "46.100.11.250",
+ "46.100.12.23",
+ "46.100.12.81",
+ "46.100.12.99",
+ "46.100.12.102",
+ "46.100.12.112",
+ "46.100.12.130",
+ "46.100.12.141",
+ "46.100.12.145",
+ "46.100.12.175",
+ "46.100.12.176",
+ "46.100.12.208",
+ "46.100.12.214",
+ "46.100.13.12",
+ "46.100.13.14",
+ "46.100.13.16",
+ "46.100.13.93",
+ "46.100.13.145",
+ "46.100.13.147",
+ "46.100.13.148",
+ "46.100.14.1",
+ "46.100.14.69",
+ "46.100.34.124",
+ "46.100.40.59",
+ "46.100.40.72",
+ "46.100.40.93",
+ "46.100.40.132",
+ "46.100.40.175",
+ "46.100.40.185",
+ "46.100.40.187",
+ "46.100.40.210",
+ "46.100.40.230",
+ "46.100.41.100",
+ "46.100.41.120",
+ "46.100.41.217",
+ "46.100.41.254",
+ "46.100.42.40",
+ "46.100.42.49",
+ "46.100.42.51",
+ "46.100.42.103",
+ "46.100.42.132",
+ "46.100.42.160",
+ "46.100.42.163",
+ "46.100.42.188",
+ "46.100.42.245",
+ "46.100.43.11",
+ "46.100.43.41",
+ "46.100.43.154",
+ "46.100.45.39",
+ "46.100.45.52",
+ "46.100.45.72",
+ "46.100.45.195",
+ "46.100.45.252",
+ "46.100.46.8",
+ "46.100.46.56",
+ "46.100.46.107",
+ "46.100.46.111",
+ "46.100.46.113",
+ "46.100.46.122",
+ "46.100.46.126",
+ "46.100.46.135",
+ "46.100.46.167",
+ "46.100.47.51",
+ "46.100.47.95",
+ "46.100.47.112",
+ "46.100.47.122",
+ "46.100.47.137",
+ "46.100.47.202",
+ "46.100.47.249",
+ "46.100.47.250",
+ "46.100.48.37",
+ "46.100.48.63",
+ "46.100.48.66",
+ "46.100.48.120",
+ "46.100.48.178",
+ "46.100.48.181",
+ "46.100.48.199",
+ "46.100.48.235",
+ "46.100.50.8",
+ "46.100.50.33",
+ "46.100.50.63",
+ "46.100.50.106",
+ "46.100.50.115",
+ "46.100.50.118",
+ "46.100.50.122",
+ "46.100.50.155",
+ "46.100.52.16",
+ "46.100.52.40",
+ "46.100.52.52",
+ "46.100.52.112",
+ "46.100.52.170",
+ "46.100.52.192",
+ "46.100.52.239",
+ "46.100.52.247",
+ "46.100.52.251",
+ "46.100.53.35",
+ "46.100.53.36",
+ "46.100.53.85",
+ "46.100.53.106",
+ "46.100.53.115",
+ "46.100.53.176",
+ "46.100.53.185",
+ "46.100.53.187",
+ "46.100.53.212",
+ "46.100.53.232",
+ "46.100.54.1",
+ "46.100.54.4",
+ "46.100.54.23",
+ "46.100.54.48",
+ "46.100.54.53",
+ "46.100.54.167",
+ "46.100.54.191",
+ "46.100.55.16",
+ "46.100.55.18",
+ "46.100.55.37",
+ "46.100.55.54",
+ "46.100.55.67",
+ "46.100.55.72",
+ "46.100.55.158",
+ "46.100.55.172",
+ "46.100.55.190",
+ "46.100.55.193",
+ "46.100.55.207",
+ "46.100.55.232",
+ "46.100.56.237",
+ "46.100.57.62",
+ "46.100.57.115",
+ "46.100.57.124",
+ "46.100.57.237",
+ "46.100.58.16",
+ "46.100.58.87",
+ "46.100.58.141",
+ "46.100.58.142",
+ "46.100.59.119",
+ "46.100.59.146",
+ "46.100.59.148",
+ "46.100.59.168",
+ "46.100.60.24",
+ "46.100.60.26",
+ "46.100.60.28",
+ "46.100.60.67",
+ "46.100.60.73",
+ "46.100.60.80",
+ "46.100.60.122",
+ "46.100.60.144",
+ "46.100.60.177",
+ "46.100.61.16",
+ "46.100.61.17",
+ "46.100.61.32",
+ "46.100.61.33",
+ "46.100.61.196",
+ "46.100.62.21",
+ "46.100.62.44",
+ "46.100.62.56",
+ "46.100.62.80",
+ "46.100.62.110",
+ "46.100.62.129",
+ "46.100.62.169",
+ "46.100.62.235",
+ "46.100.63.28",
+ "46.100.63.43",
+ "46.100.63.112",
+ "46.100.63.124",
+ "46.100.63.220",
+ "46.100.63.221",
+ "46.100.63.244",
+ "46.100.74.110",
+ "46.100.84.9",
+ "46.100.84.20",
+ "46.100.84.47",
+ "46.100.84.171",
+ "46.100.84.197",
+ "46.100.84.205",
+ "46.100.84.227",
+ "46.100.85.171",
+ "46.100.85.218",
+ "46.100.85.234",
+ "46.100.90.82",
+ "46.100.90.105",
+ "46.100.90.116",
+ "46.100.90.135",
+ "46.100.90.138",
+ "46.100.90.168",
+ "46.100.91.17",
+ "46.100.91.22",
+ "46.100.91.27",
+ "46.100.91.109",
+ "46.100.91.134",
+ "46.100.91.218",
+ "46.100.92.15",
+ "46.100.92.50",
+ "46.100.92.84",
+ "46.100.92.92",
+ "46.100.92.113",
+ "46.100.92.128",
+ "46.100.92.130",
+ "46.100.92.227",
+ "46.100.93.214",
+ "46.100.94.2",
+ "46.100.94.7",
+ "46.100.94.132",
+ "46.100.94.147",
+ "46.100.94.190",
+ "46.100.95.29",
+ "46.100.95.119",
+ "46.100.95.162",
+ "46.100.95.193",
+ "46.100.97.51",
+ "46.100.97.188",
+ "46.100.99.31",
+ "46.100.101.194",
+ "46.100.101.226",
+ "46.100.101.227",
+ "46.100.104.22",
+ "46.100.104.48",
+ "46.100.104.162",
+ "46.100.104.182",
+ "46.100.104.183",
+ "46.100.107.90",
+ "46.100.107.213",
+ "46.100.116.145",
+ "46.100.132.34",
+ "46.100.134.39",
+ "46.100.164.15",
+ "46.100.164.22",
+ "46.100.164.27",
+ "46.100.164.39",
+ "46.100.164.48",
+ "46.100.164.88",
+ "46.100.164.112",
+ "46.100.164.157",
+ "46.100.164.165",
+ "46.100.164.195",
+ "46.100.164.205",
+ "46.100.164.212",
+ "46.100.164.216",
+ "46.100.164.242",
+ "46.100.165.4",
+ "46.100.165.56",
+ "46.100.165.140",
+ "46.100.165.150",
+ "46.100.165.151",
+ "46.100.165.196",
+ "46.100.165.249",
+ "46.100.166.10",
+ "46.100.166.18",
+ "46.100.166.32",
+ "46.100.166.43",
+ "46.100.166.55",
+ "46.100.166.153",
+ "46.100.166.194",
+ "46.100.166.204",
+ "46.100.167.86",
+ "46.100.167.99",
+ "46.100.167.117",
+ "46.100.167.185",
+ "46.100.167.189",
+ "46.100.168.101",
+ "46.100.171.4",
+ "46.100.177.18",
+ "46.100.177.41",
+ "46.100.177.184",
+ "46.100.178.45",
+ "46.100.179.39",
+ "46.100.180.71",
+ "46.100.181.18",
+ "46.100.182.46",
+ "46.100.182.95",
+ "46.100.183.82",
+ "46.100.183.91",
+ "46.100.248.135",
+ "46.100.248.199",
+ "46.100.249.82",
+ "46.100.249.89",
+ "46.100.249.117",
+ "46.100.249.190",
+ "46.100.249.207",
+ "46.100.250.5",
+ "46.100.251.5",
+ "46.100.251.156",
+ "46.102.132.2",
+ "46.102.132.3",
+ "46.102.132.4",
+ "46.102.132.31",
+ "46.102.137.20",
+ "46.102.137.22",
+ "46.102.137.32",
+ "46.102.139.18",
+ "46.102.139.21",
+ "46.102.139.85",
+ "46.102.140.35",
+ "46.102.143.141",
+ "46.102.143.143",
+ "46.102.184.135",
+ "46.102.184.175",
+ "46.102.187.30",
+ "46.102.187.139",
+ "46.148.32.5",
+ "46.148.32.16",
+ "46.148.32.17",
+ "46.148.32.26",
+ "46.148.32.70",
+ "46.148.32.98",
+ "46.148.32.112",
+ "46.148.32.121",
+ "46.148.32.125",
+ "46.148.32.135",
+ "46.148.32.158",
+ "46.148.32.167",
+ "46.148.32.176",
+ "46.148.32.209",
+ "46.148.32.235",
+ "46.148.32.238",
+ "46.148.32.239",
+ "46.148.34.74",
+ "46.148.34.226",
+ "46.148.35.43",
+ "46.148.35.57",
+ "46.148.35.59",
+ "46.148.35.210",
+ "46.148.35.217",
+ "46.148.36.10",
+ "46.148.36.40",
+ "46.148.36.55",
+ "46.148.36.93",
+ "46.148.36.100",
+ "46.148.36.105",
+ "46.148.36.106",
+ "46.148.36.147",
+ "46.148.36.150",
+ "46.148.36.219",
+ "46.148.36.241",
+ "46.148.36.244",
+ "46.148.38.154",
+ "46.148.38.167",
+ "46.148.39.25",
+ "46.148.39.75",
+ "46.148.39.104",
+ "46.148.40.0",
+ "46.148.40.2",
+ "46.148.40.32",
+ "46.148.40.40",
+ "46.148.40.47",
+ "46.148.41.5",
+ "46.148.41.9",
+ "46.148.42.210",
+ "46.148.43.33",
+ "46.148.43.206",
+ "46.148.43.212",
+ "46.148.44.48",
+ "46.148.44.54",
+ "46.148.44.106",
+ "46.148.44.167",
+ "46.148.44.221",
+ "46.148.44.227",
+ "46.148.45.5",
+ "46.148.45.26",
+ "46.148.45.28",
+ "46.148.45.33",
+ "46.148.45.42",
+ "46.148.45.45",
+ "46.148.45.80",
+ "46.148.45.89",
+ "46.148.45.114",
+ "46.148.45.133",
+ "46.148.45.145",
+ "46.148.45.154",
+ "46.148.45.155",
+ "46.148.45.202",
+ "46.148.45.208",
+ "46.148.45.223",
+ "46.148.45.233",
+ "46.148.45.235",
+ "46.148.45.242",
+ "46.167.128.168",
+ "46.167.131.114",
+ "46.167.132.199",
+ "46.167.133.40",
+ "46.167.133.248",
+ "46.167.134.160",
+ "46.167.135.178",
+ "46.167.136.14",
+ "46.167.136.26",
+ "46.167.136.112",
+ "46.167.138.65",
+ "46.167.138.205",
+ "46.167.139.228",
+ "46.167.140.98",
+ "46.167.141.0",
+ "46.167.141.21",
+ "46.167.141.22",
+ "46.167.141.138",
+ "46.167.143.104",
+ "46.167.146.138",
+ "46.167.148.146",
+ "46.167.149.72",
+ "46.167.149.76",
+ "46.167.150.29",
+ "46.167.150.227",
+ "46.167.152.192",
+ "46.167.152.245",
+ "46.167.154.99",
+ "46.167.154.209",
+ "46.167.155.0",
+ "46.167.155.69",
+ "46.167.156.137",
+ "46.167.156.199",
+ "46.167.157.162",
+ "46.167.157.169",
+ "46.167.157.205",
+ "46.167.158.135",
+ "46.167.159.0",
+ "46.182.32.129",
+ "46.209.5.114",
+ "46.209.12.25",
+ "46.209.15.187",
+ "46.209.20.85",
+ "46.209.20.207",
+ "46.209.22.226",
+ "46.209.22.227",
+ "46.209.22.228",
+ "46.209.22.229",
+ "46.209.27.3",
+ "46.209.28.27",
+ "46.209.30.11",
+ "46.209.30.12",
+ "46.209.30.107",
+ "46.209.30.108",
+ "46.209.45.246",
+ "46.209.48.5",
+ "46.209.48.82",
+ "46.209.48.114",
+ "46.209.48.115",
+ "46.209.48.116",
+ "46.209.48.118",
+ "46.209.48.194",
+ "46.209.48.213",
+ "46.209.49.254",
+ "46.209.58.194",
+ "46.209.58.195",
+ "46.209.61.98",
+ "46.209.61.99",
+ "46.209.63.218",
+ "46.209.70.226",
+ "46.209.73.54",
+ "46.209.74.198",
+ "46.209.79.58",
+ "46.209.79.59",
+ "46.209.79.60",
+ "46.209.79.61",
+ "46.209.79.62",
+ "46.209.92.162",
+ "46.209.92.163",
+ "46.209.92.164",
+ "46.209.93.85",
+ "46.209.94.14",
+ "46.209.95.102",
+ "46.209.100.114",
+ "46.209.103.118",
+ "46.209.115.30",
+ "46.209.115.74",
+ "46.209.118.178",
+ "46.209.118.180",
+ "46.209.118.181",
+ "46.209.118.182",
+ "46.209.122.194",
+ "46.209.122.196",
+ "46.209.122.226",
+ "46.209.140.170",
+ "46.209.140.172",
+ "46.209.142.2",
+ "46.209.142.4",
+ "46.209.142.51",
+ "46.209.142.53",
+ "46.209.142.82",
+ "46.209.142.83",
+ "46.209.142.84",
+ "46.209.142.85",
+ "46.209.148.202",
+ "46.209.148.203",
+ "46.209.148.204",
+ "46.209.148.205",
+ "46.209.153.225",
+ "46.209.153.226",
+ "46.209.153.228",
+ "46.209.153.229",
+ "46.209.153.230",
+ "46.209.153.233",
+ "46.209.153.234",
+ "46.209.153.236",
+ "46.209.153.238",
+ "46.209.153.240",
+ "46.209.153.243",
+ "46.209.153.246",
+ "46.209.153.247",
+ "46.209.153.248",
+ "46.209.153.249",
+ "46.209.153.250",
+ "46.209.156.131",
+ "46.209.157.18",
+ "46.209.157.22",
+ "46.209.181.202",
+ "46.209.195.18",
+ "46.209.195.19",
+ "46.209.195.20",
+ "46.209.195.21",
+ "46.209.199.86",
+ "46.209.201.58",
+ "46.209.203.141",
+ "46.209.203.143",
+ "46.209.204.142",
+ "46.209.206.62",
+ "46.209.206.178",
+ "46.209.207.97",
+ "46.209.207.98",
+ "46.209.207.146",
+ "46.209.207.147",
+ "46.209.207.148",
+ "46.209.207.149",
+ "46.209.207.150",
+ "46.209.207.151",
+ "46.209.207.152",
+ "46.209.207.155",
+ "46.209.207.156",
+ "46.209.207.158",
+ "46.209.211.50",
+ "46.209.221.66",
+ "46.209.221.68",
+ "46.209.221.69",
+ "46.209.221.70",
+ "46.209.221.71",
+ "46.209.221.72",
+ "46.209.221.73",
+ "46.209.221.75",
+ "46.209.221.76",
+ "46.209.221.77",
+ "46.209.221.78",
+ "46.209.221.82",
+ "46.209.221.84",
+ "46.209.221.85",
+ "46.209.221.86",
+ "46.209.221.87",
+ "46.209.221.88",
+ "46.209.221.89",
+ "46.209.221.90",
+ "46.209.221.91",
+ "46.209.221.93",
+ "46.209.222.123",
+ "46.209.232.146",
+ "46.209.239.30",
+ "46.209.240.90",
+ "46.209.240.226",
+ "46.209.240.227",
+ "46.209.240.228",
+ "46.209.241.67",
+ "46.209.241.81",
+ "46.209.241.82",
+ "46.209.241.155",
+ "46.209.241.226",
+ "46.209.241.227",
+ "46.209.241.229",
+ "46.209.241.250",
+ "46.209.247.155",
+ "46.209.251.94",
+ "46.235.76.81",
+ "46.235.76.225",
+ "46.235.77.15",
+ "46.235.77.80",
+ "46.235.77.110",
+ "46.235.77.118",
+ "46.235.77.131",
+ "46.235.77.153",
+ "46.235.77.185",
+ "46.235.77.251",
+ "46.245.0.109",
+ "46.245.0.128",
+ "46.245.0.138",
+ "46.245.0.167",
+ "46.245.1.65",
+ "46.245.1.104",
+ "46.245.2.47",
+ "46.245.2.161",
+ "46.245.2.253",
+ "46.245.3.30",
+ "46.245.4.85",
+ "46.245.5.63",
+ "46.245.5.75",
+ "46.245.5.202",
+ "46.245.5.236",
+ "46.245.6.215",
+ "46.245.7.102",
+ "46.245.7.223",
+ "46.245.8.66",
+ "46.245.10.13",
+ "46.245.12.183",
+ "46.245.12.187",
+ "46.245.12.222",
+ "46.245.12.241",
+ "46.245.17.101",
+ "46.245.19.79",
+ "46.245.25.72",
+ "46.245.30.51",
+ "46.245.32.26",
+ "46.245.32.29",
+ "46.245.32.40",
+ "46.245.37.66",
+ "46.245.38.42",
+ "46.245.38.99",
+ "46.245.38.107",
+ "46.245.38.119",
+ "46.245.38.206",
+ "46.245.38.234",
+ "46.245.39.63",
+ "46.245.39.101",
+ "46.245.39.102",
+ "46.245.39.184",
+ "46.245.39.185",
+ "46.245.39.186",
+ "46.245.39.210",
+ "46.245.41.104",
+ "46.245.42.44",
+ "46.245.43.249",
+ "46.245.44.1",
+ "46.245.44.9",
+ "46.245.46.128",
+ "46.245.47.207",
+ "46.245.65.2",
+ "46.245.65.3",
+ "46.245.66.4",
+ "46.245.66.201",
+ "46.245.66.202",
+ "46.245.66.203",
+ "46.245.66.204",
+ "46.245.66.205",
+ "46.245.66.251",
+ "46.245.66.253",
+ "46.245.67.142",
+ "46.245.67.143",
+ "46.245.67.144",
+ "46.245.67.146",
+ "46.245.67.147",
+ "46.245.67.148",
+ "46.245.67.151",
+ "46.245.67.161",
+ "46.245.69.214",
+ "46.245.72.218",
+ "46.245.72.219",
+ "46.245.72.220",
+ "46.245.76.203",
+ "46.245.77.98",
+ "46.245.77.99",
+ "46.245.77.100",
+ "46.245.77.101",
+ "46.245.77.102",
+ "46.245.77.103",
+ "46.245.77.106",
+ "46.245.77.107",
+ "46.245.77.108",
+ "46.245.77.109",
+ "46.245.77.110",
+ "46.245.78.154",
+ "46.245.80.172",
+ "46.245.81.34",
+ "46.245.81.115",
+ "46.245.81.116",
+ "46.245.81.117",
+ "46.245.81.118",
+ "46.245.83.142",
+ "46.245.84.81",
+ "46.245.84.82",
+ "46.245.84.83",
+ "46.245.84.84",
+ "46.245.84.86",
+ "46.245.86.185",
+ "46.245.87.218",
+ "46.245.87.219",
+ "46.245.87.221",
+ "46.245.89.99",
+ "46.245.89.101",
+ "46.245.90.73",
+ "46.245.90.103",
+ "46.245.91.68",
+ "46.245.91.71",
+ "46.245.91.76",
+ "46.245.91.82",
+ "46.245.91.83",
+ "46.245.91.84",
+ "46.245.91.85",
+ "46.245.91.86",
+ "46.245.91.87",
+ "46.245.91.88",
+ "46.245.91.89",
+ "46.245.91.90",
+ "46.245.91.91",
+ "46.245.91.92",
+ "46.245.91.93",
+ "46.245.91.94",
+ "46.245.92.159",
+ "46.245.94.106",
+ "46.245.94.149",
+ "46.245.94.150",
+ "46.245.94.151",
+ "46.245.94.177",
+ "46.245.94.178",
+ "46.245.95.30",
+ "46.245.95.65",
+ "46.245.95.188",
+ "46.245.98.77",
+ "46.245.98.133",
+ "46.245.107.197",
+ "46.245.112.16",
+ "46.245.112.17",
+ "46.245.112.18",
+ "46.245.114.226",
+ "46.245.114.227",
+ "46.245.115.36",
+ "46.245.115.39",
+ "46.245.115.40",
+ "46.245.115.43",
+ "46.245.115.202",
+ "46.245.117.51",
+ "46.245.118.147",
+ "46.245.122.19",
+ "46.245.122.29",
+ "46.245.123.9",
+ "46.245.123.10",
+ "46.245.123.82",
+ "46.245.123.84",
+ "46.245.123.86",
+ "46.245.124.224",
+ "46.249.120.25",
+ "46.249.120.43",
+ "46.249.120.104",
+ "46.249.121.88",
+ "46.249.121.89",
+ "46.249.121.91",
+ "46.249.121.97",
+ "46.249.121.190",
+ "46.249.122.3",
+ "46.249.122.10",
+ "46.249.122.12",
+ "46.249.122.13",
+ "46.249.122.15",
+ "46.249.122.18",
+ "46.249.122.21",
+ "46.249.122.26",
+ "46.249.122.29",
+ "46.249.122.32",
+ "46.249.122.34",
+ "46.249.122.35",
+ "46.249.122.39",
+ "46.249.122.41",
+ "46.249.122.48",
+ "46.249.122.57",
+ "46.249.123.7",
+ "46.249.123.23",
+ "46.249.124.14",
+ "46.249.124.34",
+ "46.249.124.244",
+ "46.249.124.245",
+ "46.249.125.9",
+ "46.249.125.129",
+ "46.249.125.200",
+ "46.249.125.205",
+ "46.249.125.215",
+ "46.249.125.225",
+ "46.249.125.244",
+ "46.249.126.93",
+ "46.249.127.121",
+ "46.249.127.199",
+ "62.3.14.8",
+ "62.3.14.136",
+ "62.3.41.30",
+ "62.3.41.88",
+ "62.3.41.112",
+ "62.3.41.131",
+ "62.3.41.165",
+ "62.3.42.2",
+ "62.3.42.3",
+ "62.3.42.50",
+ "62.3.42.133",
+ "62.3.42.136",
+ "62.3.42.221",
+ "62.3.42.241",
+ "62.60.128.143",
+ "62.60.128.166",
+ "62.60.141.98",
+ "62.60.141.99",
+ "62.60.141.100",
+ "62.60.141.102",
+ "62.60.141.106",
+ "62.60.141.107",
+ "62.60.141.108",
+ "62.60.141.109",
+ "62.60.141.254",
+ "62.60.143.146",
+ "62.60.143.151",
+ "62.60.143.163",
+ "62.60.143.240",
+ "62.60.143.243",
+ "62.60.144.150",
+ "62.60.144.151",
+ "62.60.144.154",
+ "62.60.144.167",
+ "62.60.144.177",
+ "62.60.144.184",
+ "62.60.144.187",
+ "62.60.144.195",
+ "62.60.144.196",
+ "62.60.144.197",
+ "62.60.144.198",
+ "62.60.144.199",
+ "62.60.144.200",
+ "62.60.160.29",
+ "62.60.160.81",
+ "62.60.160.123",
+ "62.60.161.203",
+ "62.60.161.217",
+ "62.60.162.97",
+ "62.60.162.148",
+ "62.60.162.213",
+ "62.60.163.202",
+ "62.60.163.227",
+ "62.60.163.233",
+ "62.60.163.251",
+ "62.60.164.128",
+ "62.60.164.146",
+ "62.60.167.26",
+ "62.60.167.29",
+ "62.60.190.190",
+ "62.60.190.200",
+ "62.60.200.18",
+ "62.60.200.19",
+ "62.60.200.20",
+ "62.60.200.170",
+ "62.60.200.243",
+ "62.60.200.244",
+ "62.60.200.245",
+ "62.60.200.246",
+ "62.60.204.141",
+ "62.60.205.24",
+ "62.60.206.6",
+ "62.60.206.17",
+ "62.60.207.160",
+ "62.60.207.177",
+ "62.60.210.60",
+ "62.60.210.179",
+ "62.60.212.164",
+ "62.60.214.47",
+ "62.60.214.71",
+ "62.60.214.128",
+ "62.60.214.134",
+ "62.60.214.189",
+ "62.60.218.224",
+ "62.106.95.53",
+ "62.106.95.132",
+ "62.204.61.3",
+ "62.204.61.16",
+ "62.204.61.20",
+ "62.204.61.40",
+ "62.204.61.165",
+ "62.204.61.188",
+ "62.220.100.170",
+ "62.220.100.172",
+ "62.220.100.183",
+ "62.220.112.63",
+ "62.220.113.122",
+ "62.220.113.160",
+ "62.220.114.193",
+ "62.220.114.197",
+ "62.220.114.241",
+ "62.220.115.99",
+ "62.220.117.202",
+ "62.220.124.52",
+ "62.220.124.54",
+ "62.220.126.3",
+ "62.220.126.4",
+ "62.220.126.5",
+ "62.220.126.6",
+ "62.220.126.8",
+ "62.220.126.9",
+ "62.220.126.15",
+ "62.220.126.16",
+ "62.220.126.23",
+ "62.220.126.26",
+ "62.220.126.28",
+ "62.220.126.29",
+ "62.220.126.30",
+ "62.220.126.31",
+ "62.220.126.33",
+ "62.220.126.34",
+ "62.220.126.35",
+ "62.220.126.36",
+ "62.220.126.37",
+ "62.220.126.42",
+ "62.220.126.48",
+ "62.220.126.50",
+ "62.220.126.52",
+ "62.220.126.57",
+ "62.220.126.73",
+ "62.220.126.74",
+ "62.220.126.75",
+ "62.220.126.78",
+ "62.220.126.79",
+ "62.220.126.109",
+ "62.220.126.111",
+ "62.220.126.119",
+ "62.220.126.153",
+ "62.220.126.154",
+ "62.220.126.155",
+ "62.220.126.157",
+ "62.220.126.159",
+ "62.220.126.171",
+ "62.220.126.172",
+ "62.220.126.173",
+ "62.220.126.180",
+ "62.220.126.209",
+ "62.220.126.210",
+ "62.220.126.211",
+ "62.220.126.213",
+ "62.220.126.214",
+ "62.220.126.215",
+ "62.220.126.221",
+ "62.220.126.222",
+ "62.220.126.226",
+ "62.220.126.236",
+ "62.220.126.237",
+ "62.220.126.238",
+ "62.220.126.239",
+ "62.220.126.244",
+ "62.220.126.245",
+ "62.220.126.246",
+ "62.220.127.82",
+ "62.220.127.116",
+ "62.220.127.117",
+ "62.220.127.118",
+ "62.220.127.186",
+ "66.79.96.123",
+ "66.79.97.38",
+ "66.79.98.201",
+ "66.79.98.210",
+ "66.79.99.182",
+ "66.79.100.21",
+ "66.79.100.86",
+ "66.79.100.90",
+ "66.79.101.14",
+ "66.79.101.45",
+ "66.79.102.175",
+ "66.79.103.222",
+ "66.79.105.22",
+ "66.79.105.60",
+ "77.36.237.37",
+ "77.36.243.129",
+ "77.81.34.250",
+ "77.81.76.9",
+ "77.81.76.16",
+ "77.81.76.73",
+ "77.81.78.16",
+ "77.81.78.31",
+ "77.81.78.39",
+ "77.81.78.61",
+ "77.81.78.63",
+ "77.81.78.82",
+ "77.81.78.93",
+ "77.81.78.98",
+ "77.81.78.108",
+ "77.81.78.111",
+ "77.81.78.117",
+ "77.81.78.123",
+ "77.81.78.125",
+ "77.81.78.128",
+ "77.81.78.141",
+ "77.81.78.157",
+ "77.81.78.186",
+ "77.81.82.1",
+ "77.81.82.21",
+ "77.81.82.194",
+ "77.81.83.3",
+ "77.81.83.10",
+ "77.81.144.14",
+ "77.81.146.44",
+ "77.81.147.224",
+ "77.81.147.254",
+ "77.81.148.63",
+ "77.81.148.122",
+ "77.81.148.155",
+ "77.81.148.182",
+ "77.81.149.7",
+ "77.81.149.100",
+ "77.81.149.196",
+ "77.81.149.231",
+ "77.81.151.101",
+ "77.81.151.131",
+ "77.81.152.62",
+ "77.81.152.97",
+ "77.81.152.229",
+ "77.81.154.30",
+ "77.81.156.28",
+ "77.81.157.124",
+ "77.81.158.53",
+ "77.81.159.164",
+ "77.95.219.74",
+ "77.95.219.126",
+ "77.95.219.155",
+ "77.95.219.182",
+ "77.104.66.74",
+ "77.104.66.134",
+ "77.104.67.146",
+ "77.104.67.147",
+ "77.104.67.148",
+ "77.104.67.149",
+ "77.104.67.150",
+ "77.104.67.151",
+ "77.104.67.152",
+ "77.104.67.153",
+ "77.104.67.154",
+ "77.104.68.129",
+ "77.104.68.153",
+ "77.104.68.212",
+ "77.104.72.22",
+ "77.104.72.146",
+ "77.104.73.66",
+ "77.104.73.67",
+ "77.104.73.68",
+ "77.104.73.69",
+ "77.104.73.70",
+ "77.104.73.71",
+ "77.104.73.72",
+ "77.104.73.74",
+ "77.104.73.75",
+ "77.104.73.76",
+ "77.104.73.77",
+ "77.104.73.78",
+ "77.104.73.130",
+ "77.104.73.131",
+ "77.104.73.132",
+ "77.104.73.133",
+ "77.104.73.135",
+ "77.104.73.136",
+ "77.104.73.137",
+ "77.104.73.138",
+ "77.104.73.139",
+ "77.104.75.114",
+ "77.104.75.227",
+ "77.104.76.6",
+ "77.104.76.44",
+ "77.104.76.50",
+ "77.104.76.230",
+ "77.104.77.114",
+ "77.104.77.197",
+ "77.104.79.243",
+ "77.104.79.244",
+ "77.104.81.67",
+ "77.104.82.66",
+ "77.104.82.67",
+ "77.104.82.68",
+ "77.104.82.69",
+ "77.104.82.70",
+ "77.104.82.110",
+ "77.104.82.196",
+ "77.104.84.130",
+ "77.104.84.136",
+ "77.104.84.146",
+ "77.104.84.150",
+ "77.104.85.14",
+ "77.104.85.50",
+ "77.104.85.51",
+ "77.104.85.74",
+ "77.104.85.90",
+ "77.104.92.3",
+ "77.104.93.85",
+ "77.104.99.150",
+ "77.104.100.186",
+ "77.104.102.162",
+ "77.104.103.130",
+ "77.104.103.250",
+ "77.104.110.6",
+ "77.104.110.10",
+ "77.104.110.11",
+ "77.104.110.13",
+ "77.104.110.18",
+ "77.104.110.137",
+ "77.104.110.166",
+ "77.104.114.229",
+ "77.104.114.233",
+ "77.104.114.237",
+ "77.104.114.241",
+ "77.104.114.245",
+ "77.104.114.249",
+ "77.104.115.183",
+ "77.104.115.190",
+ "77.104.115.217",
+ "77.104.115.239",
+ "77.104.126.28",
+ "77.104.126.43",
+ "77.104.126.152",
+ "77.104.126.156",
+ "77.104.126.181",
+ "77.104.126.183",
+ "77.104.126.189",
+ "77.104.126.211",
+ "77.104.127.6",
+ "77.237.66.72",
+ "77.237.67.19",
+ "77.237.69.136",
+ "77.237.69.192",
+ "77.237.69.193",
+ "77.237.70.222",
+ "77.237.76.74",
+ "77.237.76.223",
+ "77.237.77.42",
+ "77.237.77.106",
+ "77.237.77.109",
+ "77.237.78.1",
+ "77.237.78.7",
+ "77.237.78.8",
+ "77.237.78.186",
+ "77.237.82.49",
+ "77.237.82.56",
+ "77.237.82.112",
+ "77.237.82.169",
+ "77.237.82.221",
+ "77.237.82.247",
+ "77.237.83.186",
+ "77.237.85.193",
+ "77.237.85.197",
+ "77.237.85.201",
+ "77.237.85.205",
+ "77.237.85.209",
+ "77.237.85.213",
+ "77.237.85.217",
+ "77.237.85.229",
+ "77.237.85.230",
+ "77.237.85.233",
+ "77.237.85.241",
+ "77.237.85.245",
+ "77.237.85.249",
+ "77.237.87.190",
+ "77.237.88.146",
+ "77.237.88.178",
+ "77.237.89.18",
+ "77.237.89.194",
+ "77.237.89.196",
+ "77.237.89.197",
+ "77.237.89.198",
+ "77.237.91.146",
+ "77.237.92.1",
+ "77.237.92.82",
+ "77.237.92.90",
+ "77.237.92.106",
+ "77.237.92.118",
+ "77.237.92.220",
+ "77.237.93.34",
+ "77.237.93.35",
+ "77.237.93.36",
+ "77.237.93.37",
+ "77.237.94.10",
+ "77.237.94.202",
+ "77.237.94.203",
+ "77.237.95.186",
+ "77.238.104.0",
+ "77.238.104.47",
+ "77.238.104.102",
+ "77.238.104.107",
+ "77.238.104.135",
+ "77.238.104.150",
+ "77.238.104.208",
+ "77.238.104.238",
+ "77.238.105.125",
+ "77.238.105.147",
+ "77.238.105.242",
+ "77.238.106.19",
+ "77.238.106.41",
+ "77.238.106.58",
+ "77.238.106.96",
+ "77.238.106.103",
+ "77.238.106.119",
+ "77.238.106.138",
+ "77.238.106.198",
+ "77.238.106.225",
+ "77.238.107.24",
+ "77.238.107.32",
+ "77.238.107.174",
+ "77.238.107.198",
+ "77.238.108.92",
+ "77.238.109.91",
+ "77.238.110.40",
+ "77.238.110.44",
+ "77.238.110.142",
+ "77.238.110.163",
+ "77.238.110.177",
+ "77.238.110.231",
+ "77.238.111.235",
+ "77.238.114.64",
+ "77.238.115.44",
+ "77.238.117.255",
+ "77.238.118.166",
+ "77.238.119.32",
+ "77.238.119.96",
+ "77.238.120.23",
+ "77.238.121.92",
+ "77.238.121.128",
+ "77.238.121.138",
+ "77.238.121.200",
+ "77.238.121.206",
+ "77.238.122.146",
+ "77.238.122.163",
+ "77.238.122.242",
+ "77.238.123.238",
+ "78.31.235.1",
+ "78.31.235.2",
+ "78.38.0.73",
+ "78.38.0.82",
+ "78.38.0.92",
+ "78.38.0.93",
+ "78.38.16.210",
+ "78.38.17.48",
+ "78.38.17.67",
+ "78.38.17.118",
+ "78.38.17.155",
+ "78.38.17.159",
+ "78.38.18.137",
+ "78.38.19.151",
+ "78.38.20.2",
+ "78.38.20.33",
+ "78.38.20.98",
+ "78.38.20.99",
+ "78.38.20.105",
+ "78.38.24.122",
+ "78.38.24.199",
+ "78.38.26.79",
+ "78.38.26.103",
+ "78.38.26.107",
+ "78.38.26.124",
+ "78.38.26.129",
+ "78.38.26.130",
+ "78.38.26.131",
+ "78.38.26.133",
+ "78.38.26.136",
+ "78.38.26.137",
+ "78.38.26.138",
+ "78.38.26.140",
+ "78.38.26.141",
+ "78.38.26.142",
+ "78.38.26.145",
+ "78.38.26.146",
+ "78.38.26.147",
+ "78.38.26.148",
+ "78.38.26.156",
+ "78.38.26.157",
+ "78.38.26.158",
+ "78.38.26.160",
+ "78.38.26.161",
+ "78.38.26.162",
+ "78.38.26.163",
+ "78.38.26.165",
+ "78.38.26.167",
+ "78.38.26.168",
+ "78.38.26.169",
+ "78.38.26.170",
+ "78.38.26.171",
+ "78.38.26.173",
+ "78.38.26.174",
+ "78.38.26.175",
+ "78.38.26.176",
+ "78.38.26.177",
+ "78.38.26.178",
+ "78.38.26.179",
+ "78.38.26.180",
+ "78.38.26.182",
+ "78.38.26.184",
+ "78.38.26.185",
+ "78.38.26.186",
+ "78.38.26.187",
+ "78.38.26.227",
+ "78.38.29.9",
+ "78.38.29.147",
+ "78.38.30.35",
+ "78.38.30.69",
+ "78.38.30.179",
+ "78.38.30.200",
+ "78.38.31.45",
+ "78.38.31.107",
+ "78.38.31.117",
+ "78.38.31.161",
+ "78.38.32.56",
+ "78.38.32.159",
+ "78.38.36.61",
+ "78.38.38.48",
+ "78.38.41.17",
+ "78.38.41.37",
+ "78.38.46.154",
+ "78.38.46.200",
+ "78.38.46.209",
+ "78.38.46.220",
+ "78.38.48.107",
+ "78.38.48.178",
+ "78.38.48.210",
+ "78.38.49.109",
+ "78.38.49.110",
+ "78.38.49.240",
+ "78.38.49.255",
+ "78.38.50.39",
+ "78.38.50.44",
+ "78.38.50.61",
+ "78.38.50.125",
+ "78.38.50.154",
+ "78.38.50.207",
+ "78.38.52.74",
+ "78.38.52.82",
+ "78.38.60.218",
+ "78.38.64.65",
+ "78.38.64.73",
+ "78.38.64.129",
+ "78.38.65.65",
+ "78.38.65.108",
+ "78.38.65.109",
+ "78.38.67.24",
+ "78.38.67.26",
+ "78.38.67.93",
+ "78.38.67.95",
+ "78.38.69.87",
+ "78.38.69.89",
+ "78.38.71.13",
+ "78.38.71.164",
+ "78.38.77.47",
+ "78.38.78.49",
+ "78.38.80.241",
+ "78.38.80.242",
+ "78.38.84.12",
+ "78.38.90.251",
+ "78.38.92.106",
+ "78.38.92.218",
+ "78.38.93.34",
+ "78.38.93.58",
+ "78.38.93.86",
+ "78.38.93.90",
+ "78.38.94.74",
+ "78.38.94.122",
+ "78.38.94.123",
+ "78.38.94.130",
+ "78.38.94.131",
+ "78.38.94.132",
+ "78.38.94.133",
+ "78.38.94.134",
+ "78.38.95.57",
+ "78.38.99.46",
+ "78.38.99.50",
+ "78.38.99.82",
+ "78.38.99.118",
+ "78.38.99.186",
+ "78.38.99.194",
+ "78.38.99.195",
+ "78.38.99.196",
+ "78.38.99.238",
+ "78.38.100.54",
+ "78.38.100.71",
+ "78.38.100.121",
+ "78.38.101.66",
+ "78.38.105.9",
+ "78.38.105.74",
+ "78.38.106.232",
+ "78.38.106.243",
+ "78.38.107.53",
+ "78.38.107.72",
+ "78.38.107.88",
+ "78.38.107.172",
+ "78.38.108.194",
+ "78.38.108.196",
+ "78.38.108.198",
+ "78.38.108.199",
+ "78.38.108.202",
+ "78.38.108.203",
+ "78.38.108.204",
+ "78.38.108.205",
+ "78.38.109.100",
+ "78.38.110.110",
+ "78.38.110.138",
+ "78.38.110.171",
+ "78.38.110.174",
+ "78.38.112.130",
+ "78.38.114.86",
+ "78.38.114.210",
+ "78.38.114.212",
+ "78.38.114.213",
+ "78.38.114.221",
+ "78.38.120.80",
+ "78.38.120.120",
+ "78.38.121.218",
+ "78.38.123.210",
+ "78.38.124.28",
+ "78.38.124.35",
+ "78.38.124.163",
+ "78.38.126.2",
+ "78.38.126.101",
+ "78.38.126.141",
+ "78.38.126.247",
+ "78.38.127.149",
+ "78.38.127.238",
+ "78.38.140.50",
+ "78.38.144.243",
+ "78.38.145.228",
+ "78.38.149.32",
+ "78.38.152.102",
+ "78.38.153.37",
+ "78.38.153.81",
+ "78.38.153.177",
+ "78.38.153.181",
+ "78.38.156.22",
+ "78.38.156.129",
+ "78.38.156.205",
+ "78.38.156.229",
+ "78.38.156.246",
+ "78.38.157.65",
+ "78.38.157.66",
+ "78.38.157.112",
+ "78.38.157.124",
+ "78.38.157.167",
+ "78.38.158.22",
+ "78.38.161.80",
+ "78.38.166.121",
+ "78.38.166.122",
+ "78.38.166.123",
+ "78.38.166.145",
+ "78.38.166.249",
+ "78.38.174.78",
+ "78.38.179.236",
+ "78.38.182.61",
+ "78.38.189.221",
+ "78.38.209.57",
+ "78.38.221.170",
+ "78.38.221.172",
+ "78.38.221.173",
+ "78.38.221.174",
+ "78.38.224.98",
+ "78.38.239.220",
+ "78.38.239.221",
+ "78.38.239.222",
+ "78.38.239.223",
+ "78.38.239.224",
+ "78.38.243.6",
+ "78.38.243.234",
+ "78.38.243.237",
+ "78.38.246.174",
+ "78.38.246.183",
+ "78.38.248.46",
+ "78.38.248.117",
+ "78.38.248.154",
+ "78.38.248.242",
+ "78.38.248.250",
+ "78.38.250.6",
+ "78.38.250.82",
+ "78.38.250.84",
+ "78.38.250.85",
+ "78.38.250.86",
+ "78.38.250.150",
+ "78.38.251.250",
+ "78.38.251.251",
+ "78.38.251.252",
+ "78.38.251.253",
+ "78.38.254.14",
+ "78.38.254.66",
+ "78.39.10.54",
+ "78.39.10.234",
+ "78.39.11.2",
+ "78.39.11.14",
+ "78.39.11.62",
+ "78.39.11.122",
+ "78.39.37.170",
+ "78.39.40.114",
+ "78.39.40.115",
+ "78.39.40.142",
+ "78.39.40.147",
+ "78.39.40.155",
+ "78.39.43.242",
+ "78.39.46.121",
+ "78.39.46.122",
+ "78.39.46.123",
+ "78.39.46.124",
+ "78.39.46.125",
+ "78.39.46.126",
+ "78.39.46.127",
+ "78.39.48.28",
+ "78.39.48.140",
+ "78.39.48.150",
+ "78.39.48.202",
+ "78.39.49.90",
+ "78.39.50.6",
+ "78.39.50.42",
+ "78.39.50.76",
+ "78.39.50.134",
+ "78.39.50.170",
+ "78.39.50.234",
+ "78.39.53.120",
+ "78.39.53.162",
+ "78.39.53.194",
+ "78.39.53.254",
+ "78.39.56.183",
+ "78.39.57.178",
+ "78.39.57.179",
+ "78.39.59.14",
+ "78.39.59.38",
+ "78.39.59.142",
+ "78.39.62.37",
+ "78.39.62.147",
+ "78.39.62.148",
+ "78.39.67.138",
+ "78.39.80.59",
+ "78.39.80.169",
+ "78.39.81.17",
+ "78.39.81.26",
+ "78.39.81.57",
+ "78.39.81.166",
+ "78.39.82.26",
+ "78.39.83.13",
+ "78.39.83.20",
+ "78.39.83.27",
+ "78.39.83.30",
+ "78.39.83.55",
+ "78.39.83.103",
+ "78.39.83.111",
+ "78.39.83.118",
+ "78.39.83.128",
+ "78.39.88.175",
+ "78.39.99.17",
+ "78.39.99.25",
+ "78.39.99.98",
+ "78.39.102.99",
+ "78.39.102.103",
+ "78.39.102.108",
+ "78.39.103.3",
+ "78.39.103.4",
+ "78.39.103.9",
+ "78.39.103.10",
+ "78.39.103.15",
+ "78.39.103.16",
+ "78.39.103.24",
+ "78.39.108.18",
+ "78.39.108.24",
+ "78.39.108.121",
+ "78.39.108.196",
+ "78.39.109.10",
+ "78.39.109.54",
+ "78.39.117.48",
+ "78.39.124.225",
+ "78.39.125.69",
+ "78.39.125.70",
+ "78.39.125.71",
+ "78.39.125.72",
+ "78.39.125.73",
+ "78.39.125.74",
+ "78.39.125.75",
+ "78.39.125.77",
+ "78.39.125.78",
+ "78.39.125.80",
+ "78.39.125.81",
+ "78.39.136.50",
+ "78.39.138.94",
+ "78.39.138.115",
+ "78.39.140.23",
+ "78.39.141.84",
+ "78.39.141.204",
+ "78.39.144.157",
+ "78.39.145.101",
+ "78.39.145.216",
+ "78.39.147.202",
+ "78.39.150.26",
+ "78.39.159.153",
+ "78.39.175.161",
+ "78.39.176.89",
+ "78.39.180.157",
+ "78.39.180.174",
+ "78.39.181.87",
+ "78.39.181.97",
+ "78.39.192.15",
+ "78.39.193.34",
+ "78.39.193.74",
+ "78.39.193.75",
+ "78.39.193.78",
+ "78.39.194.9",
+ "78.39.195.234",
+ "78.39.195.238",
+ "78.39.198.4",
+ "78.39.204.9",
+ "78.39.204.17",
+ "78.39.204.33",
+ "78.39.209.115",
+ "78.39.209.202",
+ "78.39.217.45",
+ "78.39.217.53",
+ "78.39.217.161",
+ "78.39.217.236",
+ "78.39.218.2",
+ "78.39.218.3",
+ "78.39.218.4",
+ "78.39.218.6",
+ "78.39.218.7",
+ "78.39.218.8",
+ "78.39.218.10",
+ "78.39.218.12",
+ "78.39.220.114",
+ "78.39.220.122",
+ "78.39.220.123",
+ "78.39.220.124",
+ "78.39.220.125",
+ "78.39.220.126",
+ "78.39.220.163",
+ "78.39.225.143",
+ "78.39.226.16",
+ "78.39.226.113",
+ "78.39.227.26",
+ "78.39.228.234",
+ "78.39.229.24",
+ "78.39.230.239",
+ "78.39.233.108",
+ "78.39.233.143",
+ "78.39.233.156",
+ "78.39.233.159",
+ "78.39.234.54",
+ "78.39.234.221",
+ "78.39.234.231",
+ "78.39.235.108",
+ "78.39.235.148",
+ "78.39.244.140",
+ "78.39.245.159",
+ "78.39.249.51",
+ "78.39.249.136",
+ "78.39.250.143",
+ "78.39.251.53",
+ "78.39.251.221",
+ "78.39.252.62",
+ "78.39.253.225",
+ "78.39.255.246",
+ "78.109.194.122",
+ "78.109.195.58",
+ "78.109.196.139",
+ "78.109.198.2",
+ "78.109.199.57",
+ "78.109.201.52",
+ "78.109.201.55",
+ "78.110.120.195",
+ "78.110.120.200",
+ "78.110.120.227",
+ "78.110.122.96",
+ "78.110.123.67",
+ "78.110.124.19",
+ "78.110.124.90",
+ "78.110.124.162",
+ "78.110.124.203",
+ "78.110.124.206",
+ "78.110.125.58",
+ "78.110.125.83",
+ "78.110.125.85",
+ "78.110.125.250",
+ "78.110.126.170",
+ "78.110.127.91",
+ "78.111.0.30",
+ "78.111.0.68",
+ "78.111.1.22",
+ "78.111.3.17",
+ "78.111.3.94",
+ "78.111.3.177",
+ "78.111.5.2",
+ "78.111.5.246",
+ "78.111.7.1",
+ "78.111.7.2",
+ "78.111.7.3",
+ "78.111.7.4",
+ "78.111.7.5",
+ "78.111.7.6",
+ "78.111.7.7",
+ "78.111.7.8",
+ "78.111.7.9",
+ "78.111.7.10",
+ "78.111.7.12",
+ "78.111.7.14",
+ "78.111.7.15",
+ "78.111.7.16",
+ "78.111.7.18",
+ "78.111.7.19",
+ "78.111.7.20",
+ "78.111.7.22",
+ "78.111.7.23",
+ "78.111.7.24",
+ "78.111.7.25",
+ "78.111.7.26",
+ "78.111.7.27",
+ "78.111.7.28",
+ "78.111.7.29",
+ "78.111.7.30",
+ "78.111.7.31",
+ "78.111.7.32",
+ "78.111.7.33",
+ "78.111.7.34",
+ "78.111.7.35",
+ "78.111.7.36",
+ "78.111.7.37",
+ "78.111.7.38",
+ "78.111.7.39",
+ "78.111.7.40",
+ "78.111.7.42",
+ "78.111.7.43",
+ "78.111.7.44",
+ "78.111.7.45",
+ "78.111.7.46",
+ "78.111.7.47",
+ "78.111.7.48",
+ "78.111.7.49",
+ "78.111.7.50",
+ "78.111.7.52",
+ "78.111.7.53",
+ "78.111.7.54",
+ "78.111.7.55",
+ "78.111.7.56",
+ "78.111.7.57",
+ "78.111.7.58",
+ "78.111.7.59",
+ "78.111.7.60",
+ "78.111.7.61",
+ "78.111.7.62",
+ "78.111.7.63",
+ "78.111.7.64",
+ "78.111.7.66",
+ "78.111.7.67",
+ "78.111.7.68",
+ "78.111.7.69",
+ "78.111.7.70",
+ "78.111.7.71",
+ "78.111.7.72",
+ "78.111.7.74",
+ "78.111.7.75",
+ "78.111.7.76",
+ "78.111.7.77",
+ "78.111.7.78",
+ "78.111.7.79",
+ "78.111.7.80",
+ "78.111.7.81",
+ "78.111.7.82",
+ "78.111.7.84",
+ "78.111.7.85",
+ "78.111.7.86",
+ "78.111.7.87",
+ "78.111.7.88",
+ "78.111.7.89",
+ "78.111.7.90",
+ "78.111.7.91",
+ "78.111.7.92",
+ "78.111.7.93",
+ "78.111.7.94",
+ "78.111.7.95",
+ "78.111.7.96",
+ "78.111.7.97",
+ "78.111.7.98",
+ "78.111.7.99",
+ "78.111.7.100",
+ "78.111.7.101",
+ "78.111.7.102",
+ "78.111.7.103",
+ "78.111.7.104",
+ "78.111.7.105",
+ "78.111.7.106",
+ "78.111.7.108",
+ "78.111.7.109",
+ "78.111.7.110",
+ "78.111.7.112",
+ "78.111.7.113",
+ "78.111.7.114",
+ "78.111.7.115",
+ "78.111.7.116",
+ "78.111.7.117",
+ "78.111.7.118",
+ "78.111.7.119",
+ "78.111.7.121",
+ "78.111.7.122",
+ "78.111.7.123",
+ "78.111.7.124",
+ "78.111.7.125",
+ "78.111.7.126",
+ "78.111.7.127",
+ "78.111.7.128",
+ "78.111.7.129",
+ "78.111.7.130",
+ "78.111.7.131",
+ "78.111.7.132",
+ "78.111.7.133",
+ "78.111.7.134",
+ "78.111.7.135",
+ "78.111.7.136",
+ "78.111.7.138",
+ "78.111.7.139",
+ "78.111.7.140",
+ "78.111.7.141",
+ "78.111.7.142",
+ "78.111.7.143",
+ "78.111.7.144",
+ "78.111.7.145",
+ "78.111.7.146",
+ "78.111.7.147",
+ "78.111.7.149",
+ "78.111.7.150",
+ "78.111.7.151",
+ "78.111.7.152",
+ "78.111.7.153",
+ "78.111.7.154",
+ "78.111.7.156",
+ "78.111.7.157",
+ "78.111.7.158",
+ "78.111.7.159",
+ "78.111.7.161",
+ "78.111.7.162",
+ "78.111.7.163",
+ "78.111.7.164",
+ "78.111.7.165",
+ "78.111.7.166",
+ "78.111.7.167",
+ "78.111.7.168",
+ "78.111.7.169",
+ "78.111.7.170",
+ "78.111.7.171",
+ "78.111.7.173",
+ "78.111.7.174",
+ "78.111.7.175",
+ "78.111.7.176",
+ "78.111.7.177",
+ "78.111.7.178",
+ "78.111.7.179",
+ "78.111.7.180",
+ "78.111.7.182",
+ "78.111.7.183",
+ "78.111.7.185",
+ "78.111.7.186",
+ "78.111.7.187",
+ "78.111.7.188",
+ "78.111.7.189",
+ "78.111.7.190",
+ "78.111.7.191",
+ "78.111.7.192",
+ "78.111.7.194",
+ "78.111.7.195",
+ "78.111.7.196",
+ "78.111.7.197",
+ "78.111.7.198",
+ "78.111.7.200",
+ "78.111.7.201",
+ "78.111.7.202",
+ "78.111.7.203",
+ "78.111.7.204",
+ "78.111.7.205",
+ "78.111.7.206",
+ "78.111.7.207",
+ "78.111.7.208",
+ "78.111.7.209",
+ "78.111.7.210",
+ "78.111.7.211",
+ "78.111.7.212",
+ "78.111.7.213",
+ "78.111.7.214",
+ "78.111.7.215",
+ "78.111.7.216",
+ "78.111.7.217",
+ "78.111.7.218",
+ "78.111.7.219",
+ "78.111.7.220",
+ "78.111.7.221",
+ "78.111.7.222",
+ "78.111.7.223",
+ "78.111.7.224",
+ "78.111.7.225",
+ "78.111.7.228",
+ "78.111.7.229",
+ "78.111.7.230",
+ "78.111.7.231",
+ "78.111.7.232",
+ "78.111.7.234",
+ "78.111.7.235",
+ "78.111.7.236",
+ "78.111.7.237",
+ "78.111.7.238",
+ "78.111.7.239",
+ "78.111.7.240",
+ "78.111.7.241",
+ "78.111.7.243",
+ "78.111.7.244",
+ "78.111.7.245",
+ "78.111.7.246",
+ "78.111.7.247",
+ "78.111.7.248",
+ "78.111.7.249",
+ "78.111.7.251",
+ "78.111.7.252",
+ "78.111.7.253",
+ "78.111.7.254",
+ "78.157.34.172",
+ "78.157.34.173",
+ "78.157.35.53",
+ "78.157.35.71",
+ "78.157.35.225",
+ "78.157.36.94",
+ "78.157.36.116",
+ "78.157.36.117",
+ "78.157.36.118",
+ "78.157.36.119",
+ "78.157.36.120",
+ "78.157.36.121",
+ "78.157.36.122",
+ "78.157.36.123",
+ "78.157.36.124",
+ "78.157.36.125",
+ "78.157.36.126",
+ "78.157.38.110",
+ "78.157.38.115",
+ "78.157.38.210",
+ "78.157.39.71",
+ "78.157.39.167",
+ "78.157.39.180",
+ "78.157.40.67",
+ "78.157.40.75",
+ "78.157.40.144",
+ "78.157.41.50",
+ "78.157.41.242",
+ "78.157.41.243",
+ "78.157.42.199",
+ "78.157.42.207",
+ "78.157.44.181",
+ "78.157.44.221",
+ "78.157.45.197",
+ "78.157.48.187",
+ "78.157.48.189",
+ "78.157.48.190",
+ "78.157.48.230",
+ "78.157.49.38",
+ "78.157.49.44",
+ "78.157.50.35",
+ "78.157.50.36",
+ "78.157.50.206",
+ "78.157.50.208",
+ "78.157.50.218",
+ "78.157.50.226",
+ "78.157.51.212",
+ "78.157.51.249",
+ "78.157.51.253",
+ "78.157.53.183",
+ "78.157.56.22",
+ "78.157.56.98",
+ "78.157.56.99",
+ "78.157.56.101",
+ "78.157.57.62",
+ "78.157.57.69",
+ "78.157.57.71",
+ "78.157.57.85",
+ "78.157.57.204",
+ "78.157.57.222",
+ "78.157.57.251",
+ "78.157.60.1",
+ "78.157.60.2",
+ "78.157.60.3",
+ "78.157.60.215",
+ "78.157.61.24",
+ "78.157.61.109",
+ "78.157.62.33",
+ "78.157.62.148",
+ "78.157.63.106",
+ "78.158.165.138",
+ "78.158.165.139",
+ "78.158.166.131",
+ "78.158.166.132",
+ "78.158.168.143",
+ "78.158.168.189",
+ "78.158.168.190",
+ "78.158.179.8",
+ "78.158.179.10",
+ "78.158.179.43",
+ "78.158.179.87",
+ "78.158.179.112",
+ "78.158.179.120",
+ "78.158.179.124",
+ "78.158.179.146",
+ "78.158.179.155",
+ "78.158.179.203",
+ "78.158.182.126",
+ "78.158.191.77",
+ "78.158.191.115",
+ "78.158.191.130",
+ "78.158.191.156",
+ "78.158.191.158",
+ "78.158.191.224",
+ "78.158.191.225",
+ "78.158.191.231",
+ "78.158.191.236",
+ "78.158.191.237",
+ "78.158.191.241",
+ "78.158.191.252",
+ "79.127.0.18",
+ "79.127.0.63",
+ "79.127.0.85",
+ "79.127.0.140",
+ "79.127.0.184",
+ "79.127.0.200",
+ "79.127.0.224",
+ "79.127.1.32",
+ "79.127.1.77",
+ "79.127.1.85",
+ "79.127.1.104",
+ "79.127.1.187",
+ "79.127.1.205",
+ "79.127.1.211",
+ "79.127.1.248",
+ "79.127.2.25",
+ "79.127.2.120",
+ "79.127.2.128",
+ "79.127.2.141",
+ "79.127.2.142",
+ "79.127.2.149",
+ "79.127.2.164",
+ "79.127.2.175",
+ "79.127.2.236",
+ "79.127.3.10",
+ "79.127.3.28",
+ "79.127.3.42",
+ "79.127.3.50",
+ "79.127.3.53",
+ "79.127.3.164",
+ "79.127.3.173",
+ "79.127.3.182",
+ "79.127.3.196",
+ "79.127.3.208",
+ "79.127.3.210",
+ "79.127.4.49",
+ "79.127.4.59",
+ "79.127.4.81",
+ "79.127.4.134",
+ "79.127.4.135",
+ "79.127.4.197",
+ "79.127.4.200",
+ "79.127.4.245",
+ "79.127.5.11",
+ "79.127.5.13",
+ "79.127.5.17",
+ "79.127.5.53",
+ "79.127.5.79",
+ "79.127.5.93",
+ "79.127.5.94",
+ "79.127.5.109",
+ "79.127.5.127",
+ "79.127.5.161",
+ "79.127.5.164",
+ "79.127.6.2",
+ "79.127.6.65",
+ "79.127.6.91",
+ "79.127.6.105",
+ "79.127.6.141",
+ "79.127.6.142",
+ "79.127.6.191",
+ "79.127.6.218",
+ "79.127.6.227",
+ "79.127.7.18",
+ "79.127.7.34",
+ "79.127.7.50",
+ "79.127.7.59",
+ "79.127.7.83",
+ "79.127.7.114",
+ "79.127.7.127",
+ "79.127.7.226",
+ "79.127.11.80",
+ "79.127.11.106",
+ "79.127.11.154",
+ "79.127.11.226",
+ "79.127.12.1",
+ "79.127.12.112",
+ "79.127.12.147",
+ "79.127.12.148",
+ "79.127.12.162",
+ "79.127.13.0",
+ "79.127.13.30",
+ "79.127.13.38",
+ "79.127.13.134",
+ "79.127.13.167",
+ "79.127.13.171",
+ "79.127.13.200",
+ "79.127.13.236",
+ "79.127.14.49",
+ "79.127.14.70",
+ "79.127.14.81",
+ "79.127.14.108",
+ "79.127.14.116",
+ "79.127.14.140",
+ "79.127.14.145",
+ "79.127.15.17",
+ "79.127.15.28",
+ "79.127.15.41",
+ "79.127.15.91",
+ "79.127.15.117",
+ "79.127.15.135",
+ "79.127.15.148",
+ "79.127.15.156",
+ "79.127.15.159",
+ "79.127.15.165",
+ "79.127.15.206",
+ "79.127.15.223",
+ "79.127.15.239",
+ "79.127.16.37",
+ "79.127.24.251",
+ "79.127.29.99",
+ "79.127.29.164",
+ "79.127.30.178",
+ "79.127.30.179",
+ "79.127.30.180",
+ "79.127.30.186",
+ "79.127.31.209",
+ "79.127.32.2",
+ "79.127.32.18",
+ "79.127.32.26",
+ "79.127.32.43",
+ "79.127.32.122",
+ "79.127.32.123",
+ "79.127.32.125",
+ "79.127.32.126",
+ "79.127.32.250",
+ "79.127.33.10",
+ "79.127.33.81",
+ "79.127.33.106",
+ "79.127.33.186",
+ "79.127.33.188",
+ "79.127.33.198",
+ "79.127.34.58",
+ "79.127.34.62",
+ "79.127.34.130",
+ "79.127.34.226",
+ "79.127.34.229",
+ "79.127.35.50",
+ "79.127.35.242",
+ "79.127.35.243",
+ "79.127.36.98",
+ "79.127.37.4",
+ "79.127.37.5",
+ "79.127.37.6",
+ "79.127.37.90",
+ "79.127.37.226",
+ "79.127.37.234",
+ "79.127.37.235",
+ "79.127.40.66",
+ "79.127.40.135",
+ "79.127.40.202",
+ "79.127.41.42",
+ "79.127.42.226",
+ "79.127.45.49",
+ "79.127.47.18",
+ "79.127.47.19",
+ "79.127.47.26",
+ "79.127.47.27",
+ "79.127.47.28",
+ "79.127.47.29",
+ "79.127.47.30",
+ "79.127.47.68",
+ "79.127.47.82",
+ "79.127.47.83",
+ "79.127.47.146",
+ "79.127.47.186",
+ "79.127.47.251",
+ "79.127.49.27",
+ "79.127.49.130",
+ "79.127.49.178",
+ "79.127.49.179",
+ "79.127.50.178",
+ "79.127.50.180",
+ "79.127.50.250",
+ "79.127.51.90",
+ "79.127.51.170",
+ "79.127.51.226",
+ "79.127.52.162",
+ "79.127.52.163",
+ "79.127.52.164",
+ "79.127.52.165",
+ "79.127.52.178",
+ "79.127.52.194",
+ "79.127.52.234",
+ "79.127.53.26",
+ "79.127.53.122",
+ "79.127.53.131",
+ "79.127.53.170",
+ "79.127.54.163",
+ "79.127.54.186",
+ "79.127.54.205",
+ "79.127.54.242",
+ "79.127.54.250",
+ "79.127.55.178",
+ "79.127.55.234",
+ "79.127.56.58",
+ "79.127.56.61",
+ "79.127.56.139",
+ "79.127.56.140",
+ "79.127.56.178",
+ "79.127.59.101",
+ "79.127.60.18",
+ "79.127.63.90",
+ "79.127.63.210",
+ "79.127.65.34",
+ "79.127.65.155",
+ "79.127.66.90",
+ "79.127.66.101",
+ "79.127.66.194",
+ "79.127.66.195",
+ "79.127.66.250",
+ "79.127.68.34",
+ "79.127.68.35",
+ "79.127.68.37",
+ "79.127.68.38",
+ "79.127.69.116",
+ "79.127.69.117",
+ "79.127.69.118",
+ "79.127.69.122",
+ "79.127.69.123",
+ "79.127.69.124",
+ "79.127.69.126",
+ "79.127.69.163",
+ "79.127.70.130",
+ "79.127.70.131",
+ "79.127.70.132",
+ "79.127.70.133",
+ "79.127.70.134",
+ "79.127.70.135",
+ "79.127.70.136",
+ "79.127.70.137",
+ "79.127.70.139",
+ "79.127.70.141",
+ "79.127.70.142",
+ "79.127.70.146",
+ "79.127.70.162",
+ "79.127.71.10",
+ "79.127.71.11",
+ "79.127.71.12",
+ "79.127.71.14",
+ "79.127.71.34",
+ "79.127.71.114",
+ "79.127.71.219",
+ "79.127.71.243",
+ "79.127.72.26",
+ "79.127.72.187",
+ "79.127.72.189",
+ "79.127.72.191",
+ "79.127.72.218",
+ "79.127.73.201",
+ "79.127.74.34",
+ "79.127.74.66",
+ "79.127.74.114",
+ "79.127.74.115",
+ "79.127.74.116",
+ "79.127.74.117",
+ "79.127.74.234",
+ "79.127.74.243",
+ "79.127.75.10",
+ "79.127.76.18",
+ "79.127.76.122",
+ "79.127.76.138",
+ "79.127.76.147",
+ "79.127.76.186",
+ "79.127.76.210",
+ "79.127.76.211",
+ "79.127.76.214",
+ "79.127.76.226",
+ "79.127.77.106",
+ "79.127.77.142",
+ "79.127.77.161",
+ "79.127.78.26",
+ "79.127.78.66",
+ "79.127.79.10",
+ "79.127.79.162",
+ "79.127.79.165",
+ "79.127.80.114",
+ "79.127.80.115",
+ "79.127.81.2",
+ "79.127.81.10",
+ "79.127.82.26",
+ "79.127.83.26",
+ "79.127.83.94",
+ "79.127.83.114",
+ "79.127.83.202",
+ "79.127.84.122",
+ "79.127.84.124",
+ "79.127.84.125",
+ "79.127.84.126",
+ "79.127.85.170",
+ "79.127.85.171",
+ "79.127.85.178",
+ "79.127.86.11",
+ "79.127.86.252",
+ "79.127.87.179",
+ "79.127.87.226",
+ "79.127.92.1",
+ "79.127.92.8",
+ "79.127.92.9",
+ "79.127.92.16",
+ "79.127.92.17",
+ "79.127.92.20",
+ "79.127.92.79",
+ "79.127.92.83",
+ "79.127.92.106",
+ "79.127.92.166",
+ "79.127.92.180",
+ "79.127.92.186",
+ "79.127.92.215",
+ "79.127.92.217",
+ "79.127.92.221",
+ "79.127.92.238",
+ "79.127.94.21",
+ "79.127.94.22",
+ "79.127.94.30",
+ "79.127.94.36",
+ "79.127.94.55",
+ "79.127.94.57",
+ "79.127.94.59",
+ "79.127.94.83",
+ "79.127.94.91",
+ "79.127.94.108",
+ "79.127.94.116",
+ "79.127.94.135",
+ "79.127.94.141",
+ "79.127.94.142",
+ "79.127.94.157",
+ "79.127.94.163",
+ "79.127.94.170",
+ "79.127.94.184",
+ "79.127.94.187",
+ "79.127.94.213",
+ "79.127.94.228",
+ "79.127.94.255",
+ "79.127.95.6",
+ "79.127.95.14",
+ "79.127.95.63",
+ "79.127.95.74",
+ "79.127.95.96",
+ "79.127.95.102",
+ "79.127.95.107",
+ "79.127.95.110",
+ "79.127.95.117",
+ "79.127.95.119",
+ "79.127.95.130",
+ "79.127.95.133",
+ "79.127.95.139",
+ "79.127.95.143",
+ "79.127.95.164",
+ "79.127.95.184",
+ "79.127.95.193",
+ "79.127.95.195",
+ "79.127.95.205",
+ "79.127.95.230",
+ "79.127.95.234",
+ "79.127.95.236",
+ "79.127.95.241",
+ "79.127.95.248",
+ "79.127.96.6",
+ "79.127.96.40",
+ "79.127.101.21",
+ "79.127.101.194",
+ "79.127.102.143",
+ "79.127.103.225",
+ "79.127.107.233",
+ "79.127.108.80",
+ "79.127.110.91",
+ "79.127.113.91",
+ "79.127.116.1",
+ "79.127.116.9",
+ "79.127.116.17",
+ "79.127.116.56",
+ "79.127.116.186",
+ "79.127.117.60",
+ "79.127.117.66",
+ "79.127.117.199",
+ "79.127.119.146",
+ "79.127.120.51",
+ "79.127.120.82",
+ "79.127.120.218",
+ "79.127.120.222",
+ "79.127.121.10",
+ "79.127.121.184",
+ "79.127.121.185",
+ "79.127.121.187",
+ "79.127.121.188",
+ "79.127.121.189",
+ "79.127.121.226",
+ "79.127.122.10",
+ "79.127.122.98",
+ "79.127.123.34",
+ "79.127.124.106",
+ "79.127.125.74",
+ "79.127.125.75",
+ "79.127.125.76",
+ "79.127.125.77",
+ "79.127.125.78",
+ "79.127.125.212",
+ "79.127.126.67",
+ "79.127.126.93",
+ "79.127.126.114",
+ "79.127.126.243",
+ "79.127.127.71",
+ "79.127.127.73",
+ "79.127.127.122",
+ "79.127.127.214",
+ "79.127.127.216",
+ "79.132.193.34",
+ "79.132.193.58",
+ "79.132.193.73",
+ "79.132.193.196",
+ "79.132.193.198",
+ "79.132.193.212",
+ "79.132.193.235",
+ "79.132.205.29",
+ "79.132.205.33",
+ "79.132.206.198",
+ "79.132.206.209",
+ "79.132.206.217",
+ "79.132.208.49",
+ "79.132.208.50",
+ "79.132.208.53",
+ "79.132.214.254",
+ "79.143.84.70",
+ "79.143.86.3",
+ "79.143.86.11",
+ "79.143.86.12",
+ "79.143.86.40",
+ "79.143.86.50",
+ "79.143.86.66",
+ "79.143.86.129",
+ "79.143.86.158",
+ "79.143.86.161",
+ "79.143.86.193",
+ "79.143.86.201",
+ "79.143.86.209",
+ "79.174.160.210",
+ "79.174.160.222",
+ "79.175.131.190",
+ "79.175.131.196",
+ "79.175.131.253",
+ "79.175.133.54",
+ "79.175.134.37",
+ "79.175.139.185",
+ "79.175.149.66",
+ "79.175.149.68",
+ "79.175.149.69",
+ "79.175.149.70",
+ "79.175.149.217",
+ "79.175.151.43",
+ "79.175.151.142",
+ "79.175.152.194",
+ "79.175.152.195",
+ "79.175.153.210",
+ "79.175.153.211",
+ "79.175.153.212",
+ "79.175.153.213",
+ "79.175.153.214",
+ "79.175.153.215",
+ "79.175.153.217",
+ "79.175.153.218",
+ "79.175.153.219",
+ "79.175.153.221",
+ "79.175.153.222",
+ "79.175.162.226",
+ "79.175.163.215",
+ "79.175.165.171",
+ "79.175.167.96",
+ "79.175.168.78",
+ "79.175.168.220",
+ "79.175.168.222",
+ "79.175.169.50",
+ "79.175.169.61",
+ "79.175.169.213",
+ "79.175.169.221",
+ "79.175.170.133",
+ "79.175.173.154",
+ "79.175.173.155",
+ "79.175.173.156",
+ "79.175.173.157",
+ "79.175.173.158",
+ "79.175.176.2",
+ "79.175.176.90",
+ "79.175.177.8",
+ "79.175.177.10",
+ "79.175.177.125",
+ "79.175.187.189",
+ "79.175.189.3",
+ "79.175.189.4",
+ "79.175.189.231",
+ "80.66.177.23",
+ "80.71.112.51",
+ "80.71.112.98",
+ "80.71.112.115",
+ "80.71.114.16",
+ "80.71.114.19",
+ "80.71.114.23",
+ "80.71.114.38",
+ "80.71.114.148",
+ "80.71.114.153",
+ "80.71.114.164",
+ "80.71.114.175",
+ "80.71.114.197",
+ "80.71.114.203",
+ "80.71.118.2",
+ "80.71.149.32",
+ "80.71.149.62",
+ "80.75.0.201",
+ "80.75.1.66",
+ "80.75.1.230",
+ "80.75.4.24",
+ "80.75.4.50",
+ "80.75.4.66",
+ "80.75.4.67",
+ "80.75.4.68",
+ "80.75.4.69",
+ "80.75.4.76",
+ "80.75.4.77",
+ "80.75.7.22",
+ "80.75.7.58",
+ "80.75.7.66",
+ "80.75.7.94",
+ "80.75.7.170",
+ "80.75.7.171",
+ "80.75.7.172",
+ "80.75.7.173",
+ "80.75.7.174",
+ "80.75.8.194",
+ "80.75.9.182",
+ "80.75.9.197",
+ "80.75.9.222",
+ "80.75.11.58",
+ "80.75.12.100",
+ "80.75.13.30",
+ "80.75.13.34",
+ "80.75.13.107",
+ "80.75.13.178",
+ "80.75.14.34",
+ "80.75.14.110",
+ "80.75.14.111",
+ "80.75.14.130",
+ "80.75.14.219",
+ "80.75.14.250",
+ "80.75.213.163",
+ "80.75.213.247",
+ "80.91.208.26",
+ "80.91.208.27",
+ "80.91.208.28",
+ "80.91.208.29",
+ "80.91.208.30",
+ "80.91.208.75",
+ "80.91.208.76",
+ "80.191.2.7",
+ "80.191.2.224",
+ "80.191.11.45",
+ "80.191.11.217",
+ "80.191.16.15",
+ "80.191.16.68",
+ "80.191.16.126",
+ "80.191.16.194",
+ "80.191.17.100",
+ "80.191.18.190",
+ "80.191.18.211",
+ "80.191.23.134",
+ "80.191.27.33",
+ "80.191.27.34",
+ "80.191.40.130",
+ "80.191.40.131",
+ "80.191.40.132",
+ "80.191.40.133",
+ "80.191.40.134",
+ "80.191.40.135",
+ "80.191.40.138",
+ "80.191.40.139",
+ "80.191.40.140",
+ "80.191.40.141",
+ "80.191.40.142",
+ "80.191.40.143",
+ "80.191.40.144",
+ "80.191.40.145",
+ "80.191.40.146",
+ "80.191.40.147",
+ "80.191.40.148",
+ "80.191.40.149",
+ "80.191.40.150",
+ "80.191.40.151",
+ "80.191.40.153",
+ "80.191.40.154",
+ "80.191.40.155",
+ "80.191.40.156",
+ "80.191.40.157",
+ "80.191.40.158",
+ "80.191.42.10",
+ "80.191.44.80",
+ "80.191.44.91",
+ "80.191.46.150",
+ "80.191.50.28",
+ "80.191.50.253",
+ "80.191.51.53",
+ "80.191.52.37",
+ "80.191.52.216",
+ "80.191.52.254",
+ "80.191.60.35",
+ "80.191.60.36",
+ "80.191.75.159",
+ "80.191.77.139",
+ "80.191.84.18",
+ "80.191.85.46",
+ "80.191.89.66",
+ "80.191.91.57",
+ "80.191.91.84",
+ "80.191.91.109",
+ "80.191.92.74",
+ "80.191.100.9",
+ "80.191.100.67",
+ "80.191.100.106",
+ "80.191.100.124",
+ "80.191.100.182",
+ "80.191.100.199",
+ "80.191.102.39",
+ "80.191.102.46",
+ "80.191.102.93",
+ "80.191.102.154",
+ "80.191.102.167",
+ "80.191.102.225",
+ "80.191.102.241",
+ "80.191.106.141",
+ "80.191.106.144",
+ "80.191.106.237",
+ "80.191.107.16",
+ "80.191.107.90",
+ "80.191.108.51",
+ "80.191.108.70",
+ "80.191.108.107",
+ "80.191.108.164",
+ "80.191.108.192",
+ "80.191.108.228",
+ "80.191.110.90",
+ "80.191.110.161",
+ "80.191.110.178",
+ "80.191.115.120",
+ "80.191.115.122",
+ "80.191.116.30",
+ "80.191.128.1",
+ "80.191.131.64",
+ "80.191.143.18",
+ "80.191.144.1",
+ "80.191.152.66",
+ "80.191.153.1",
+ "80.191.153.4",
+ "80.191.153.107",
+ "80.191.155.242",
+ "80.191.160.149",
+ "80.191.164.98",
+ "80.191.164.105",
+ "80.191.168.212",
+ "80.191.169.162",
+ "80.191.171.224",
+ "80.191.172.9",
+ "80.191.172.23",
+ "80.191.172.33",
+ "80.191.172.35",
+ "80.191.172.50",
+ "80.191.172.81",
+ "80.191.185.180",
+ "80.191.186.118",
+ "80.191.189.125",
+ "80.191.190.179",
+ "80.191.191.11",
+ "80.191.191.12",
+ "80.191.191.14",
+ "80.191.191.18",
+ "80.191.192.209",
+ "80.191.197.194",
+ "80.191.198.122",
+ "80.191.198.226",
+ "80.191.200.3",
+ "80.191.200.5",
+ "80.191.206.50",
+ "80.191.206.66",
+ "80.191.206.98",
+ "80.191.206.135",
+ "80.191.207.2",
+ "80.191.207.3",
+ "80.191.207.4",
+ "80.191.207.5",
+ "80.191.207.7",
+ "80.191.207.9",
+ "80.191.207.10",
+ "80.191.207.11",
+ "80.191.207.21",
+ "80.191.207.33",
+ "80.191.207.34",
+ "80.191.207.35",
+ "80.191.207.37",
+ "80.191.207.38",
+ "80.191.207.40",
+ "80.191.209.94",
+ "80.191.209.105",
+ "80.191.212.141",
+ "80.191.221.26",
+ "80.191.221.27",
+ "80.191.221.33",
+ "80.191.227.147",
+ "80.191.227.148",
+ "80.191.235.90",
+ "80.191.235.91",
+ "80.191.235.92",
+ "80.191.235.93",
+ "80.191.235.94",
+ "80.191.235.145",
+ "80.191.235.194",
+ "80.191.236.19",
+ "80.191.238.82",
+ "80.191.238.83",
+ "80.191.240.66",
+ "80.191.240.128",
+ "80.191.240.138",
+ "80.191.240.185",
+ "80.191.240.191",
+ "80.191.241.194",
+ "80.191.241.195",
+ "80.191.241.196",
+ "80.191.241.197",
+ "80.191.241.198",
+ "80.191.241.199",
+ "80.191.241.200",
+ "80.191.241.201",
+ "80.191.241.202",
+ "80.191.241.203",
+ "80.191.241.205",
+ "80.191.241.208",
+ "80.191.241.209",
+ "80.191.241.210",
+ "80.191.241.212",
+ "80.191.241.214",
+ "80.191.241.217",
+ "80.191.241.218",
+ "80.191.241.220",
+ "80.191.241.221",
+ "80.191.242.2",
+ "80.191.242.110",
+ "80.191.243.226",
+ "80.191.243.234",
+ "80.191.245.235",
+ "80.191.252.152",
+ "80.191.253.205",
+ "80.191.255.18",
+ "80.191.255.22",
+ "80.210.17.128",
+ "80.210.17.137",
+ "80.210.17.163",
+ "80.210.17.197",
+ "80.210.17.229",
+ "80.210.17.240",
+ "80.210.17.249",
+ "80.210.18.45",
+ "80.210.18.93",
+ "80.210.18.121",
+ "80.210.18.147",
+ "80.210.18.219",
+ "80.210.18.220",
+ "80.210.18.235",
+ "80.210.18.243",
+ "80.210.19.31",
+ "80.210.19.69",
+ "80.210.19.124",
+ "80.210.19.172",
+ "80.210.19.179",
+ "80.210.19.186",
+ "80.210.19.215",
+ "80.210.19.220",
+ "80.210.20.31",
+ "80.210.20.88",
+ "80.210.21.16",
+ "80.210.21.70",
+ "80.210.21.84",
+ "80.210.21.91",
+ "80.210.21.179",
+ "80.210.21.211",
+ "80.210.21.224",
+ "80.210.22.14",
+ "80.210.22.47",
+ "80.210.22.77",
+ "80.210.22.79",
+ "80.210.22.113",
+ "80.210.22.140",
+ "80.210.22.142",
+ "80.210.22.153",
+ "80.210.22.217",
+ "80.210.22.229",
+ "80.210.22.243",
+ "80.210.24.7",
+ "80.210.24.89",
+ "80.210.24.110",
+ "80.210.24.158",
+ "80.210.24.185",
+ "80.210.24.246",
+ "80.210.25.33",
+ "80.210.25.237",
+ "80.210.26.72",
+ "80.210.26.90",
+ "80.210.26.101",
+ "80.210.26.104",
+ "80.210.26.110",
+ "80.210.26.120",
+ "80.210.26.126",
+ "80.210.26.179",
+ "80.210.26.219",
+ "80.210.26.228",
+ "80.210.26.240",
+ "80.210.26.251",
+ "80.210.27.111",
+ "80.210.27.140",
+ "80.210.27.148",
+ "80.210.27.153",
+ "80.210.27.187",
+ "80.210.27.213",
+ "80.210.27.221",
+ "80.210.28.38",
+ "80.210.28.52",
+ "80.210.28.88",
+ "80.210.28.161",
+ "80.210.29.27",
+ "80.210.29.50",
+ "80.210.29.57",
+ "80.210.29.105",
+ "80.210.29.132",
+ "80.210.29.155",
+ "80.210.29.168",
+ "80.210.29.175",
+ "80.210.29.180",
+ "80.210.29.184",
+ "80.210.29.224",
+ "80.210.30.2",
+ "80.210.30.57",
+ "80.210.30.129",
+ "80.210.30.152",
+ "80.210.30.155",
+ "80.210.30.170",
+ "80.210.30.202",
+ "80.210.30.251",
+ "80.210.31.23",
+ "80.210.31.60",
+ "80.210.31.74",
+ "80.210.31.112",
+ "80.210.31.133",
+ "80.210.31.151",
+ "80.210.31.184",
+ "80.210.31.218",
+ "80.210.31.223",
+ "80.210.31.229",
+ "80.210.32.40",
+ "80.210.32.63",
+ "80.210.32.103",
+ "80.210.32.104",
+ "80.210.32.116",
+ "80.210.32.131",
+ "80.210.32.143",
+ "80.210.32.146",
+ "80.210.32.176",
+ "80.210.32.201",
+ "80.210.32.235",
+ "80.210.33.52",
+ "80.210.33.166",
+ "80.210.33.227",
+ "80.210.33.238",
+ "80.210.34.40",
+ "80.210.34.71",
+ "80.210.34.89",
+ "80.210.34.137",
+ "80.210.34.150",
+ "80.210.34.172",
+ "80.210.34.230",
+ "80.210.35.144",
+ "80.210.35.159",
+ "80.210.35.171",
+ "80.210.35.175",
+ "80.210.36.17",
+ "80.210.36.37",
+ "80.210.36.68",
+ "80.210.36.111",
+ "80.210.36.121",
+ "80.210.36.169",
+ "80.210.36.196",
+ "80.210.36.201",
+ "80.210.36.203",
+ "80.210.37.14",
+ "80.210.37.100",
+ "80.210.37.115",
+ "80.210.37.209",
+ "80.210.38.53",
+ "80.210.38.67",
+ "80.210.38.101",
+ "80.210.38.127",
+ "80.210.38.130",
+ "80.210.38.178",
+ "80.210.38.187",
+ "80.210.38.205",
+ "80.210.38.222",
+ "80.210.38.251",
+ "80.210.39.57",
+ "80.210.39.81",
+ "80.210.39.98",
+ "80.210.39.153",
+ "80.210.39.167",
+ "80.210.39.205",
+ "80.210.39.221",
+ "80.210.39.230",
+ "80.210.40.34",
+ "80.210.40.72",
+ "80.210.40.98",
+ "80.210.40.109",
+ "80.210.40.147",
+ "80.210.40.192",
+ "80.210.40.195",
+ "80.210.40.213",
+ "80.210.40.233",
+ "80.210.41.13",
+ "80.210.41.22",
+ "80.210.41.34",
+ "80.210.41.113",
+ "80.210.41.116",
+ "80.210.41.236",
+ "80.210.42.3",
+ "80.210.42.11",
+ "80.210.42.18",
+ "80.210.42.49",
+ "80.210.42.69",
+ "80.210.42.149",
+ "80.210.42.161",
+ "80.210.42.169",
+ "80.210.43.101",
+ "80.210.43.108",
+ "80.210.43.131",
+ "80.210.43.141",
+ "80.210.43.169",
+ "80.210.43.184",
+ "80.210.43.217",
+ "80.210.44.21",
+ "80.210.44.59",
+ "80.210.44.71",
+ "80.210.44.105",
+ "80.210.44.147",
+ "80.210.44.184",
+ "80.210.44.187",
+ "80.210.44.245",
+ "80.210.45.59",
+ "80.210.45.107",
+ "80.210.45.234",
+ "80.210.46.105",
+ "80.210.46.171",
+ "80.210.46.202",
+ "80.210.46.246",
+ "80.210.47.68",
+ "80.210.47.93",
+ "80.210.47.94",
+ "80.210.47.149",
+ "80.210.48.24",
+ "80.210.48.26",
+ "80.210.48.48",
+ "80.210.48.57",
+ "80.210.48.84",
+ "80.210.48.98",
+ "80.210.48.147",
+ "80.210.48.177",
+ "80.210.49.41",
+ "80.210.49.70",
+ "80.210.49.79",
+ "80.210.49.83",
+ "80.210.49.173",
+ "80.210.49.196",
+ "80.210.49.232",
+ "80.210.50.30",
+ "80.210.50.35",
+ "80.210.50.40",
+ "80.210.50.173",
+ "80.210.51.50",
+ "80.210.51.82",
+ "80.210.51.202",
+ "80.210.52.240",
+ "80.210.53.34",
+ "80.210.53.35",
+ "80.210.53.70",
+ "80.210.53.97",
+ "80.210.53.209",
+ "80.210.53.213",
+ "80.210.54.38",
+ "80.210.54.40",
+ "80.210.54.49",
+ "80.210.54.52",
+ "80.210.54.60",
+ "80.210.54.68",
+ "80.210.54.95",
+ "80.210.54.118",
+ "80.210.54.185",
+ "80.210.54.199",
+ "80.210.54.217",
+ "80.210.54.221",
+ "80.210.54.243",
+ "80.210.55.19",
+ "80.210.55.56",
+ "80.210.55.87",
+ "80.210.55.118",
+ "80.210.55.120",
+ "80.210.55.131",
+ "80.210.55.146",
+ "80.210.55.161",
+ "80.210.56.0",
+ "80.210.56.83",
+ "80.210.56.102",
+ "80.210.56.141",
+ "80.210.56.143",
+ "80.210.56.169",
+ "80.210.56.186",
+ "80.210.56.199",
+ "80.210.56.205",
+ "80.210.56.225",
+ "80.210.56.233",
+ "80.210.56.253",
+ "80.210.57.117",
+ "80.210.58.1",
+ "80.210.58.7",
+ "80.210.58.29",
+ "80.210.58.59",
+ "80.210.58.73",
+ "80.210.58.86",
+ "80.210.58.89",
+ "80.210.58.111",
+ "80.210.58.117",
+ "80.210.58.133",
+ "80.210.58.142",
+ "80.210.58.146",
+ "80.210.58.163",
+ "80.210.58.229",
+ "80.210.58.243",
+ "80.210.59.100",
+ "80.210.60.109",
+ "80.210.60.150",
+ "80.210.60.155",
+ "80.210.60.211",
+ "80.210.61.20",
+ "80.210.61.51",
+ "80.210.61.123",
+ "80.210.61.124",
+ "80.210.61.128",
+ "80.210.61.141",
+ "80.210.61.159",
+ "80.210.61.174",
+ "80.210.61.178",
+ "80.210.62.57",
+ "80.210.62.109",
+ "80.210.62.128",
+ "80.210.62.146",
+ "80.210.62.155",
+ "80.210.62.173",
+ "80.210.62.195",
+ "80.210.62.203",
+ "80.210.62.206",
+ "80.210.62.210",
+ "80.210.62.237",
+ "80.210.63.3",
+ "80.210.63.13",
+ "80.210.63.21",
+ "80.210.63.26",
+ "80.210.63.63",
+ "80.210.63.107",
+ "80.210.63.142",
+ "80.210.63.153",
+ "80.210.63.185",
+ "80.210.63.194",
+ "80.210.63.233",
+ "80.210.63.243",
+ "80.210.63.251",
+ "80.210.128.198",
+ "80.210.131.213",
+ "80.210.132.9",
+ "80.210.132.50",
+ "80.210.132.100",
+ "80.210.132.101",
+ "80.210.132.191",
+ "80.210.133.249",
+ "80.210.134.163",
+ "80.210.135.10",
+ "80.210.135.125",
+ "80.210.137.2",
+ "80.210.139.10",
+ "80.210.139.68",
+ "80.210.141.214",
+ "80.210.141.239",
+ "80.210.142.6",
+ "80.210.142.54",
+ "80.210.143.142",
+ "80.210.160.23",
+ "80.210.164.73",
+ "80.210.164.78",
+ "80.210.165.60",
+ "80.210.165.199",
+ "80.210.168.207",
+ "80.210.170.150",
+ "80.210.171.56",
+ "80.210.171.115",
+ "80.210.172.44",
+ "80.210.172.76",
+ "80.210.172.118",
+ "80.210.174.109",
+ "80.210.176.194",
+ "80.210.177.164",
+ "80.250.200.1",
+ "80.253.133.144",
+ "80.253.133.145",
+ "80.253.152.222",
+ "81.12.1.27",
+ "81.12.5.22",
+ "81.12.5.152",
+ "81.12.5.229",
+ "81.12.5.247",
+ "81.12.5.250",
+ "81.12.6.34",
+ "81.12.6.58",
+ "81.12.7.57",
+ "81.12.7.219",
+ "81.12.7.220",
+ "81.12.7.221",
+ "81.12.12.233",
+ "81.12.24.167",
+ "81.12.24.170",
+ "81.12.24.198",
+ "81.12.24.203",
+ "81.12.24.205",
+ "81.12.24.224",
+ "81.12.24.250",
+ "81.12.25.25",
+ "81.12.26.27",
+ "81.12.26.28",
+ "81.12.26.29",
+ "81.12.26.31",
+ "81.12.26.32",
+ "81.12.26.112",
+ "81.12.26.113",
+ "81.12.26.114",
+ "81.12.26.115",
+ "81.12.26.116",
+ "81.12.26.117",
+ "81.12.26.118",
+ "81.12.26.119",
+ "81.12.26.127",
+ "81.12.26.128",
+ "81.12.26.129",
+ "81.12.27.123",
+ "81.12.27.252",
+ "81.12.32.164",
+ "81.12.33.99",
+ "81.12.36.37",
+ "81.12.36.58",
+ "81.12.36.94",
+ "81.12.36.155",
+ "81.12.36.178",
+ "81.12.36.190",
+ "81.12.36.217",
+ "81.12.39.30",
+ "81.12.39.136",
+ "81.12.39.142",
+ "81.12.39.145",
+ "81.12.39.192",
+ "81.12.39.217",
+ "81.12.39.232",
+ "81.12.39.234",
+ "81.12.39.245",
+ "81.12.40.14",
+ "81.12.40.86",
+ "81.12.40.165",
+ "81.12.41.54",
+ "81.12.41.178",
+ "81.12.41.251",
+ "81.12.41.252",
+ "81.12.41.253",
+ "81.12.41.254",
+ "81.12.43.66",
+ "81.12.43.238",
+ "81.12.43.242",
+ "81.12.44.26",
+ "81.12.47.94",
+ "81.12.47.234",
+ "81.12.47.235",
+ "81.12.47.236",
+ "81.12.47.237",
+ "81.12.47.238",
+ "81.12.52.94",
+ "81.12.53.132",
+ "81.12.53.163",
+ "81.12.53.235",
+ "81.12.53.236",
+ "81.12.64.10",
+ "81.12.64.11",
+ "81.12.64.13",
+ "81.12.64.14",
+ "81.12.64.66",
+ "81.12.64.67",
+ "81.12.64.68",
+ "81.12.64.69",
+ "81.12.64.71",
+ "81.12.64.72",
+ "81.12.64.73",
+ "81.12.64.77",
+ "81.12.65.42",
+ "81.12.65.135",
+ "81.12.69.174",
+ "81.12.70.98",
+ "81.12.70.178",
+ "81.12.71.10",
+ "81.12.71.98",
+ "81.12.72.108",
+ "81.12.72.162",
+ "81.12.72.238",
+ "81.12.72.251",
+ "81.12.73.150",
+ "81.12.74.16",
+ "81.12.75.30",
+ "81.12.75.58",
+ "81.12.75.243",
+ "81.12.76.250",
+ "81.12.78.130",
+ "81.12.79.82",
+ "81.12.85.237",
+ "81.12.85.241",
+ "81.12.85.245",
+ "81.12.87.2",
+ "81.12.87.136",
+ "81.12.87.138",
+ "81.12.87.139",
+ "81.12.87.141",
+ "81.12.87.142",
+ "81.12.87.226",
+ "81.12.88.51",
+ "81.12.89.74",
+ "81.12.89.86",
+ "81.12.89.243",
+ "81.12.90.74",
+ "81.12.90.246",
+ "81.12.93.106",
+ "81.12.94.74",
+ "81.12.94.106",
+ "81.12.95.18",
+ "81.12.98.2",
+ "81.12.98.125",
+ "81.12.99.22",
+ "81.12.99.98",
+ "81.12.99.99",
+ "81.12.99.100",
+ "81.12.99.101",
+ "81.12.99.102",
+ "81.12.99.103",
+ "81.12.99.105",
+ "81.12.99.138",
+ "81.12.99.227",
+ "81.12.100.174",
+ "81.12.100.216",
+ "81.12.100.222",
+ "81.12.102.145",
+ "81.12.102.149",
+ "81.12.102.153",
+ "81.12.104.34",
+ "81.12.104.36",
+ "81.12.104.37",
+ "81.12.104.38",
+ "81.12.104.39",
+ "81.12.104.40",
+ "81.12.104.42",
+ "81.12.104.43",
+ "81.12.104.44",
+ "81.12.104.45",
+ "81.12.104.46",
+ "81.12.104.66",
+ "81.12.104.67",
+ "81.12.104.68",
+ "81.12.104.69",
+ "81.12.104.70",
+ "81.12.104.71",
+ "81.12.104.73",
+ "81.12.104.74",
+ "81.12.105.50",
+ "81.12.105.56",
+ "81.12.105.57",
+ "81.12.105.58",
+ "81.12.105.62",
+ "81.12.106.27",
+ "81.12.106.130",
+ "81.12.107.26",
+ "81.12.108.90",
+ "81.12.108.92",
+ "81.12.108.93",
+ "81.12.108.94",
+ "81.12.108.98",
+ "81.12.108.115",
+ "81.12.108.116",
+ "81.12.108.118",
+ "81.12.109.19",
+ "81.12.109.22",
+ "81.12.109.134",
+ "81.12.109.170",
+ "81.12.109.174",
+ "81.12.110.130",
+ "81.12.111.166",
+ "81.12.112.10",
+ "81.12.113.18",
+ "81.12.113.101",
+ "81.12.113.118",
+ "81.12.113.196",
+ "81.12.113.198",
+ "81.12.113.212",
+ "81.12.114.62",
+ "81.12.116.10",
+ "81.12.116.174",
+ "81.12.117.114",
+ "81.12.117.119",
+ "81.12.117.120",
+ "81.12.118.34",
+ "81.12.118.35",
+ "81.12.118.36",
+ "81.12.118.37",
+ "81.12.118.38",
+ "81.12.118.39",
+ "81.12.118.41",
+ "81.12.118.42",
+ "81.12.118.43",
+ "81.12.118.44",
+ "81.12.118.45",
+ "81.12.118.47",
+ "81.12.118.48",
+ "81.12.118.49",
+ "81.12.118.50",
+ "81.12.118.51",
+ "81.12.118.52",
+ "81.12.118.53",
+ "81.12.118.57",
+ "81.12.118.58",
+ "81.12.118.59",
+ "81.12.118.60",
+ "81.12.118.61",
+ "81.12.118.62",
+ "81.12.118.210",
+ "81.12.118.211",
+ "81.12.118.212",
+ "81.12.118.213",
+ "81.12.119.114",
+ "81.12.119.138",
+ "81.12.119.214",
+ "81.12.120.26",
+ "81.12.120.62",
+ "81.12.120.132",
+ "81.12.120.220",
+ "81.12.120.222",
+ "81.12.120.234",
+ "81.12.120.235",
+ "81.12.120.236",
+ "81.12.121.19",
+ "81.12.122.118",
+ "81.12.123.66",
+ "81.12.124.33",
+ "81.12.124.105",
+ "81.12.124.114",
+ "81.12.125.130",
+ "81.12.125.146",
+ "81.12.125.148",
+ "81.12.125.152",
+ "81.12.125.153",
+ "81.12.125.156",
+ "81.12.127.54",
+ "81.16.112.6",
+ "81.16.112.154",
+ "81.16.112.213",
+ "81.16.112.215",
+ "81.16.113.82",
+ "81.16.113.85",
+ "81.16.113.88",
+ "81.16.113.110",
+ "81.16.113.118",
+ "81.16.113.122",
+ "81.16.113.165",
+ "81.16.114.84",
+ "81.16.114.86",
+ "81.16.114.127",
+ "81.16.114.134",
+ "81.16.114.155",
+ "81.16.116.18",
+ "81.16.116.89",
+ "81.16.116.92",
+ "81.16.116.97",
+ "81.16.116.211",
+ "81.16.116.220",
+ "81.16.116.228",
+ "81.16.116.233",
+ "81.16.117.127",
+ "81.16.117.129",
+ "81.16.117.205",
+ "81.16.118.109",
+ "81.16.118.156",
+ "81.16.119.27",
+ "81.16.119.55",
+ "81.16.119.78",
+ "81.16.119.196",
+ "81.16.119.229",
+ "81.16.120.60",
+ "81.16.120.93",
+ "81.16.120.119",
+ "81.16.120.122",
+ "81.16.120.236",
+ "81.16.121.93",
+ "81.16.121.114",
+ "81.16.121.115",
+ "81.16.121.178",
+ "81.16.121.221",
+ "81.16.121.226",
+ "81.16.122.194",
+ "81.16.122.212",
+ "81.16.123.3",
+ "81.16.123.248",
+ "81.16.124.33",
+ "81.16.124.54",
+ "81.16.124.67",
+ "81.16.124.71",
+ "81.16.124.72",
+ "81.16.124.80",
+ "81.16.124.147",
+ "81.16.124.148",
+ "81.16.124.184",
+ "81.16.124.243",
+ "81.16.125.8",
+ "81.16.125.9",
+ "81.16.125.21",
+ "81.16.125.46",
+ "81.16.125.181",
+ "81.16.125.190",
+ "81.16.125.194",
+ "81.16.125.213",
+ "81.16.125.221",
+ "81.16.126.44",
+ "81.16.126.67",
+ "81.16.126.81",
+ "81.16.126.92",
+ "81.16.126.137",
+ "81.16.126.144",
+ "81.16.126.196",
+ "81.16.127.47",
+ "81.16.127.72",
+ "81.16.127.94",
+ "81.16.127.112",
+ "81.16.127.155",
+ "81.16.127.160",
+ "81.16.127.186",
+ "81.16.127.189",
+ "81.16.127.192",
+ "81.16.127.199",
+ "81.16.127.204",
+ "81.16.127.205",
+ "81.16.127.254",
+ "81.28.36.146",
+ "81.28.43.30",
+ "81.28.43.162",
+ "81.28.47.2",
+ "81.28.50.2",
+ "81.28.57.2",
+ "81.28.60.102",
+ "81.28.252.58",
+ "81.28.252.59",
+ "81.28.252.136",
+ "81.28.252.171",
+ "81.28.252.243",
+ "81.28.253.103",
+ "81.28.253.144",
+ "81.28.253.157",
+ "81.28.253.175",
+ "81.29.248.22",
+ "81.29.248.38",
+ "81.29.248.109",
+ "81.29.248.202",
+ "81.29.249.86",
+ "81.29.249.190",
+ "81.29.249.242",
+ "81.29.249.246",
+ "81.29.255.170",
+ "81.29.255.218",
+ "81.31.250.2",
+ "81.31.250.5",
+ "81.31.250.6",
+ "81.31.250.11",
+ "81.31.250.13",
+ "81.31.250.15",
+ "81.31.250.18",
+ "81.31.250.21",
+ "81.31.250.130",
+ "81.31.250.146",
+ "81.31.250.147",
+ "81.31.250.232",
+ "81.31.250.250",
+ "81.90.145.19",
+ "81.90.145.37",
+ "81.90.145.76",
+ "81.90.145.94",
+ "81.90.145.116",
+ "81.90.145.120",
+ "81.90.146.66",
+ "81.90.148.106",
+ "81.90.149.178",
+ "81.90.149.234",
+ "81.90.149.254",
+ "81.90.152.38",
+ "81.90.152.86",
+ "81.90.154.178",
+ "81.90.154.179",
+ "81.90.154.180",
+ "81.90.154.181",
+ "81.90.154.182",
+ "81.90.154.183",
+ "81.90.154.184",
+ "81.90.154.186",
+ "81.90.154.187",
+ "81.90.154.188",
+ "81.90.154.190",
+ "81.90.157.82",
+ "81.90.158.110",
+ "81.90.159.158",
+ "81.91.129.228",
+ "81.91.132.20",
+ "81.91.136.134",
+ "81.91.137.34",
+ "81.91.138.3",
+ "81.91.138.67",
+ "81.91.138.114",
+ "81.91.138.182",
+ "81.91.139.18",
+ "81.91.144.116",
+ "81.91.145.2",
+ "81.91.145.7",
+ "81.91.145.66",
+ "81.91.145.78",
+ "81.91.145.192",
+ "81.91.145.193",
+ "81.91.145.194",
+ "81.91.145.195",
+ "81.91.146.30",
+ "81.91.146.138",
+ "81.91.146.202",
+ "81.91.146.203",
+ "81.91.146.214",
+ "81.91.147.30",
+ "81.91.150.66",
+ "81.91.150.190",
+ "81.91.152.6",
+ "81.91.152.70",
+ "81.91.152.86",
+ "81.91.153.2",
+ "81.91.153.10",
+ "81.91.153.26",
+ "81.91.153.210",
+ "81.91.153.211",
+ "81.91.153.234",
+ "81.91.154.69",
+ "81.91.154.82",
+ "81.91.154.230",
+ "81.91.155.2",
+ "81.91.155.22",
+ "81.91.156.67",
+ "81.91.156.134",
+ "81.91.156.150",
+ "81.91.157.6",
+ "81.91.157.50",
+ "81.91.157.51",
+ "81.91.157.134",
+ "81.91.158.126",
+ "81.91.158.130",
+ "81.91.158.132",
+ "81.91.158.133",
+ "81.91.158.218",
+ "81.91.159.34",
+ "81.91.159.82",
+ "81.91.159.106",
+ "81.91.159.170",
+ "81.91.159.234",
+ "81.163.0.33",
+ "81.163.0.79",
+ "81.163.0.96",
+ "81.163.0.97",
+ "81.163.0.110",
+ "81.163.0.117",
+ "81.163.0.138",
+ "81.163.1.66",
+ "81.163.1.105",
+ "81.163.1.106",
+ "81.163.1.107",
+ "81.163.1.108",
+ "81.163.1.109",
+ "81.163.1.180",
+ "81.163.3.1",
+ "81.163.3.2",
+ "81.163.4.85",
+ "81.163.6.30",
+ "81.163.6.107",
+ "81.163.7.49",
+ "81.163.7.57",
+ "81.163.7.71",
+ "82.99.194.34",
+ "82.99.194.106",
+ "82.99.194.197",
+ "82.99.195.82",
+ "82.99.195.110",
+ "82.99.195.114",
+ "82.99.201.162",
+ "82.99.201.163",
+ "82.99.201.164",
+ "82.99.201.166",
+ "82.99.201.180",
+ "82.99.201.182",
+ "82.99.202.157",
+ "82.99.202.209",
+ "82.99.202.210",
+ "82.99.202.218",
+ "82.99.202.225",
+ "82.99.202.227",
+ "82.99.204.1",
+ "82.99.204.18",
+ "82.99.204.21",
+ "82.99.204.249",
+ "82.99.206.98",
+ "82.99.206.99",
+ "82.99.206.191",
+ "82.99.213.62",
+ "82.99.213.206",
+ "82.99.214.106",
+ "82.99.214.107",
+ "82.99.214.109",
+ "82.99.214.110",
+ "82.99.230.170",
+ "82.99.247.45",
+ "82.99.248.106",
+ "82.99.248.114",
+ "82.99.248.214",
+ "82.99.249.230",
+ "82.99.250.178",
+ "82.99.250.228",
+ "82.99.252.247",
+ "82.99.253.81",
+ "82.99.254.250",
+ "83.97.72.1",
+ "83.97.72.50",
+ "83.97.72.254",
+ "83.147.193.5",
+ "83.150.193.79",
+ "84.47.225.198",
+ "84.47.226.106",
+ "84.47.226.108",
+ "84.47.226.111",
+ "84.47.226.242",
+ "84.47.227.194",
+ "84.47.236.57",
+ "84.47.236.59",
+ "84.47.236.74",
+ "84.47.236.112",
+ "84.47.236.113",
+ "84.47.236.200",
+ "84.47.239.21",
+ "84.241.0.3",
+ "84.241.0.62",
+ "84.241.0.119",
+ "84.241.0.123",
+ "84.241.0.156",
+ "84.241.0.223",
+ "84.241.0.226",
+ "84.241.0.232",
+ "84.241.1.36",
+ "84.241.1.71",
+ "84.241.1.76",
+ "84.241.1.99",
+ "84.241.1.119",
+ "84.241.1.203",
+ "84.241.1.248",
+ "84.241.1.254",
+ "84.241.2.85",
+ "84.241.2.90",
+ "84.241.2.198",
+ "84.241.2.206",
+ "84.241.2.235",
+ "84.241.3.50",
+ "84.241.3.98",
+ "84.241.3.105",
+ "84.241.3.137",
+ "84.241.3.149",
+ "84.241.3.199",
+ "84.241.3.235",
+ "84.241.4.8",
+ "84.241.4.33",
+ "84.241.4.68",
+ "84.241.4.86",
+ "84.241.4.140",
+ "84.241.4.192",
+ "84.241.5.18",
+ "84.241.5.20",
+ "84.241.5.45",
+ "84.241.5.52",
+ "84.241.5.79",
+ "84.241.5.94",
+ "84.241.5.140",
+ "84.241.5.176",
+ "84.241.5.253",
+ "84.241.6.19",
+ "84.241.6.72",
+ "84.241.6.105",
+ "84.241.6.150",
+ "84.241.6.165",
+ "84.241.6.197",
+ "84.241.6.236",
+ "84.241.6.248",
+ "84.241.7.8",
+ "84.241.7.46",
+ "84.241.7.48",
+ "84.241.7.61",
+ "84.241.7.136",
+ "84.241.7.233",
+ "84.241.8.39",
+ "84.241.8.50",
+ "84.241.8.225",
+ "84.241.8.238",
+ "84.241.9.7",
+ "84.241.9.51",
+ "84.241.9.69",
+ "84.241.9.79",
+ "84.241.9.96",
+ "84.241.9.105",
+ "84.241.9.108",
+ "84.241.9.115",
+ "84.241.9.171",
+ "84.241.9.191",
+ "84.241.9.200",
+ "84.241.9.223",
+ "84.241.9.233",
+ "84.241.9.234",
+ "84.241.9.236",
+ "84.241.10.57",
+ "84.241.10.70",
+ "84.241.10.99",
+ "84.241.10.131",
+ "84.241.10.164",
+ "84.241.10.193",
+ "84.241.10.212",
+ "84.241.10.216",
+ "84.241.11.10",
+ "84.241.11.26",
+ "84.241.11.61",
+ "84.241.11.66",
+ "84.241.11.73",
+ "84.241.11.138",
+ "84.241.11.144",
+ "84.241.11.145",
+ "84.241.11.172",
+ "84.241.11.190",
+ "84.241.11.211",
+ "84.241.12.24",
+ "84.241.12.49",
+ "84.241.12.69",
+ "84.241.12.104",
+ "84.241.12.112",
+ "84.241.12.138",
+ "84.241.12.153",
+ "84.241.12.165",
+ "84.241.12.197",
+ "84.241.13.93",
+ "84.241.13.133",
+ "84.241.13.136",
+ "84.241.13.171",
+ "84.241.13.210",
+ "84.241.13.235",
+ "84.241.13.241",
+ "84.241.14.30",
+ "84.241.14.50",
+ "84.241.14.126",
+ "84.241.14.157",
+ "84.241.14.198",
+ "84.241.14.239",
+ "84.241.15.2",
+ "84.241.15.6",
+ "84.241.15.56",
+ "84.241.15.75",
+ "84.241.15.127",
+ "84.241.15.147",
+ "84.241.15.161",
+ "84.241.15.189",
+ "84.241.15.203",
+ "84.241.15.208",
+ "84.241.15.220",
+ "84.241.15.230",
+ "84.241.15.253",
+ "84.241.15.254",
+ "84.241.16.13",
+ "84.241.16.17",
+ "84.241.16.44",
+ "84.241.16.54",
+ "84.241.16.66",
+ "84.241.16.126",
+ "84.241.16.165",
+ "84.241.16.195",
+ "84.241.16.219",
+ "84.241.16.222",
+ "84.241.16.232",
+ "84.241.18.90",
+ "84.241.18.108",
+ "84.241.18.161",
+ "84.241.18.185",
+ "84.241.18.195",
+ "84.241.18.197",
+ "84.241.18.246",
+ "84.241.19.9",
+ "84.241.19.22",
+ "84.241.19.52",
+ "84.241.19.111",
+ "84.241.19.115",
+ "84.241.19.134",
+ "84.241.19.172",
+ "84.241.19.186",
+ "84.241.19.229",
+ "84.241.20.91",
+ "84.241.21.48",
+ "84.241.21.127",
+ "84.241.21.213",
+ "84.241.21.216",
+ "84.241.21.245",
+ "84.241.22.38",
+ "84.241.22.52",
+ "84.241.22.61",
+ "84.241.22.94",
+ "84.241.22.157",
+ "84.241.22.245",
+ "84.241.23.238",
+ "84.241.24.10",
+ "84.241.24.55",
+ "84.241.24.58",
+ "84.241.24.59",
+ "84.241.24.132",
+ "84.241.24.204",
+ "84.241.24.207",
+ "84.241.24.233",
+ "84.241.24.249",
+ "84.241.24.254",
+ "84.241.25.4",
+ "84.241.25.30",
+ "84.241.25.79",
+ "84.241.25.124",
+ "84.241.25.131",
+ "84.241.25.178",
+ "84.241.25.187",
+ "84.241.25.200",
+ "84.241.25.205",
+ "84.241.25.239",
+ "84.241.25.244",
+ "84.241.26.9",
+ "84.241.26.29",
+ "84.241.26.34",
+ "84.241.26.40",
+ "84.241.26.58",
+ "84.241.26.65",
+ "84.241.26.98",
+ "84.241.26.100",
+ "84.241.26.149",
+ "84.241.26.240",
+ "84.241.27.13",
+ "84.241.27.86",
+ "84.241.27.124",
+ "84.241.27.145",
+ "84.241.27.180",
+ "84.241.27.189",
+ "84.241.28.10",
+ "84.241.28.27",
+ "84.241.28.36",
+ "84.241.28.49",
+ "84.241.28.80",
+ "84.241.28.85",
+ "84.241.28.101",
+ "84.241.29.26",
+ "84.241.29.70",
+ "84.241.29.119",
+ "84.241.29.129",
+ "84.241.29.194",
+ "84.241.29.206",
+ "84.241.29.228",
+ "84.241.30.13",
+ "84.241.30.33",
+ "84.241.30.57",
+ "84.241.30.96",
+ "84.241.30.103",
+ "84.241.30.111",
+ "84.241.30.190",
+ "84.241.30.224",
+ "84.241.31.0",
+ "84.241.31.7",
+ "84.241.31.53",
+ "84.241.31.90",
+ "84.241.31.100",
+ "84.241.32.19",
+ "84.241.32.78",
+ "84.241.32.89",
+ "84.241.32.203",
+ "84.241.32.254",
+ "84.241.33.19",
+ "84.241.33.183",
+ "84.241.34.132",
+ "84.241.35.0",
+ "84.241.35.155",
+ "84.241.36.15",
+ "84.241.36.86",
+ "84.241.36.104",
+ "84.241.36.116",
+ "84.241.36.138",
+ "84.241.36.150",
+ "84.241.37.79",
+ "84.241.37.202",
+ "84.241.37.211",
+ "84.241.37.234",
+ "84.241.38.130",
+ "84.241.38.131",
+ "84.241.38.177",
+ "84.241.40.188",
+ "84.241.41.21",
+ "84.241.41.131",
+ "84.241.41.197",
+ "84.241.41.225",
+ "84.241.42.178",
+ "84.241.43.18",
+ "84.241.43.118",
+ "84.241.43.119",
+ "84.241.44.96",
+ "84.241.44.106",
+ "84.241.44.211",
+ "84.241.44.245",
+ "84.241.45.14",
+ "84.241.45.183",
+ "84.241.45.194",
+ "84.241.46.127",
+ "84.241.46.177",
+ "84.241.47.6",
+ "84.241.47.109",
+ "84.241.47.190",
+ "84.241.47.244",
+ "84.241.51.38",
+ "84.241.51.93",
+ "84.241.53.153",
+ "84.241.53.175",
+ "84.241.53.190",
+ "84.241.53.243",
+ "84.241.54.101",
+ "84.241.55.13",
+ "84.241.55.14",
+ "84.241.55.30",
+ "84.241.55.57",
+ "84.241.55.234",
+ "84.241.55.250",
+ "84.241.56.80",
+ "84.241.59.241",
+ "84.241.59.249",
+ "84.241.59.251",
+ "84.241.59.252",
+ "84.241.59.253",
+ "84.241.59.254",
+ "84.241.60.21",
+ "84.241.60.253",
+ "84.241.61.1",
+ "84.241.61.193",
+ "84.241.63.25",
+ "85.9.65.241",
+ "85.9.65.242",
+ "85.9.71.126",
+ "85.9.71.233",
+ "85.9.79.217",
+ "85.9.85.111",
+ "85.9.85.113",
+ "85.9.86.54",
+ "85.9.86.239",
+ "85.9.86.254",
+ "85.9.86.255",
+ "85.9.87.53",
+ "85.9.87.54",
+ "85.9.87.62",
+ "85.9.87.102",
+ "85.9.87.121",
+ "85.9.91.25",
+ "85.9.91.211",
+ "85.9.92.36",
+ "85.9.94.166",
+ "85.9.94.182",
+ "85.9.94.208",
+ "85.9.94.238",
+ "85.9.95.234",
+ "85.9.97.10",
+ "85.9.97.179",
+ "85.9.97.209",
+ "85.9.105.36",
+ "85.9.105.39",
+ "85.9.105.40",
+ "85.9.105.42",
+ "85.9.105.43",
+ "85.9.105.44",
+ "85.9.105.45",
+ "85.9.105.202",
+ "85.9.105.204",
+ "85.9.105.205",
+ "85.9.107.178",
+ "85.9.107.179",
+ "85.9.107.180",
+ "85.9.107.187",
+ "85.9.107.226",
+ "85.9.108.169",
+ "85.9.109.55",
+ "85.9.111.9",
+ "85.9.111.11",
+ "85.9.111.12",
+ "85.9.111.15",
+ "85.9.111.17",
+ "85.9.111.18",
+ "85.9.111.22",
+ "85.9.111.124",
+ "85.9.113.235",
+ "85.9.113.237",
+ "85.9.113.238",
+ "85.9.113.239",
+ "85.9.113.240",
+ "85.9.113.242",
+ "85.9.113.244",
+ "85.9.114.84",
+ "85.9.119.237",
+ "85.9.119.255",
+ "85.9.121.33",
+ "85.9.123.72",
+ "85.9.123.252",
+ "85.9.124.89",
+ "85.9.124.111",
+ "85.9.124.233",
+ "85.9.124.245",
+ "85.9.125.68",
+ "85.15.1.115",
+ "85.15.1.120",
+ "85.15.1.188",
+ "85.15.3.5",
+ "85.15.45.187",
+ "85.15.47.176",
+ "85.15.47.236",
+ "85.133.130.99",
+ "85.133.130.114",
+ "85.133.130.132",
+ "85.133.133.102",
+ "85.133.133.104",
+ "85.133.133.109",
+ "85.133.133.111",
+ "85.133.133.138",
+ "85.133.133.148",
+ "85.133.133.161",
+ "85.133.133.162",
+ "85.133.133.165",
+ "85.133.133.173",
+ "85.133.133.192",
+ "85.133.133.199",
+ "85.133.133.201",
+ "85.133.133.214",
+ "85.133.133.225",
+ "85.133.133.235",
+ "85.133.133.239",
+ "85.133.134.5",
+ "85.133.134.28",
+ "85.133.134.30",
+ "85.133.134.40",
+ "85.133.134.53",
+ "85.133.134.63",
+ "85.133.134.71",
+ "85.133.134.72",
+ "85.133.134.78",
+ "85.133.134.87",
+ "85.133.134.112",
+ "85.133.134.118",
+ "85.133.134.122",
+ "85.133.134.129",
+ "85.133.134.138",
+ "85.133.134.142",
+ "85.133.134.152",
+ "85.133.134.173",
+ "85.133.134.175",
+ "85.133.134.184",
+ "85.133.134.186",
+ "85.133.134.189",
+ "85.133.134.195",
+ "85.133.134.204",
+ "85.133.134.211",
+ "85.133.134.242",
+ "85.133.135.146",
+ "85.133.135.190",
+ "85.133.136.242",
+ "85.133.137.190",
+ "85.133.138.10",
+ "85.133.138.53",
+ "85.133.138.99",
+ "85.133.138.101",
+ "85.133.138.130",
+ "85.133.138.154",
+ "85.133.138.168",
+ "85.133.138.178",
+ "85.133.138.187",
+ "85.133.138.188",
+ "85.133.138.209",
+ "85.133.139.34",
+ "85.133.139.45",
+ "85.133.139.79",
+ "85.133.139.81",
+ "85.133.139.83",
+ "85.133.139.88",
+ "85.133.139.104",
+ "85.133.139.114",
+ "85.133.139.120",
+ "85.133.139.121",
+ "85.133.139.130",
+ "85.133.139.132",
+ "85.133.139.183",
+ "85.133.139.187",
+ "85.133.139.198",
+ "85.133.139.199",
+ "85.133.139.207",
+ "85.133.139.210",
+ "85.133.139.215",
+ "85.133.139.219",
+ "85.133.139.237",
+ "85.133.139.240",
+ "85.133.145.37",
+ "85.133.145.159",
+ "85.133.149.42",
+ "85.133.152.3",
+ "85.133.152.25",
+ "85.133.152.27",
+ "85.133.152.34",
+ "85.133.152.49",
+ "85.133.152.57",
+ "85.133.152.80",
+ "85.133.152.87",
+ "85.133.152.90",
+ "85.133.152.103",
+ "85.133.152.123",
+ "85.133.152.136",
+ "85.133.152.137",
+ "85.133.152.146",
+ "85.133.152.152",
+ "85.133.152.155",
+ "85.133.152.172",
+ "85.133.152.184",
+ "85.133.152.185",
+ "85.133.152.198",
+ "85.133.152.217",
+ "85.133.152.221",
+ "85.133.152.222",
+ "85.133.152.227",
+ "85.133.152.232",
+ "85.133.152.236",
+ "85.133.152.238",
+ "85.133.152.244",
+ "85.133.152.252",
+ "85.133.153.171",
+ "85.133.154.130",
+ "85.133.154.154",
+ "85.133.154.155",
+ "85.133.154.190",
+ "85.133.155.130",
+ "85.133.155.131",
+ "85.133.155.132",
+ "85.133.155.133",
+ "85.133.155.134",
+ "85.133.155.162",
+ "85.133.156.179",
+ "85.133.157.4",
+ "85.133.157.26",
+ "85.133.157.47",
+ "85.133.157.72",
+ "85.133.157.79",
+ "85.133.157.86",
+ "85.133.157.90",
+ "85.133.157.93",
+ "85.133.157.103",
+ "85.133.157.106",
+ "85.133.157.112",
+ "85.133.157.113",
+ "85.133.157.128",
+ "85.133.157.129",
+ "85.133.157.152",
+ "85.133.157.153",
+ "85.133.157.157",
+ "85.133.157.174",
+ "85.133.157.175",
+ "85.133.157.180",
+ "85.133.157.197",
+ "85.133.157.217",
+ "85.133.157.240",
+ "85.133.158.122",
+ "85.133.158.195",
+ "85.133.158.196",
+ "85.133.158.198",
+ "85.133.158.201",
+ "85.133.160.180",
+ "85.133.160.226",
+ "85.133.161.24",
+ "85.133.161.56",
+ "85.133.161.87",
+ "85.133.161.202",
+ "85.133.162.16",
+ "85.133.162.17",
+ "85.133.162.19",
+ "85.133.162.44",
+ "85.133.162.95",
+ "85.133.162.140",
+ "85.133.162.151",
+ "85.133.162.172",
+ "85.133.162.182",
+ "85.133.163.2",
+ "85.133.163.31",
+ "85.133.163.85",
+ "85.133.163.94",
+ "85.133.163.114",
+ "85.133.163.158",
+ "85.133.167.62",
+ "85.133.167.107",
+ "85.133.167.108",
+ "85.133.167.246",
+ "85.133.168.130",
+ "85.133.168.202",
+ "85.133.171.34",
+ "85.133.171.35",
+ "85.133.171.36",
+ "85.133.171.37",
+ "85.133.171.38",
+ "85.133.171.178",
+ "85.133.172.3",
+ "85.133.172.68",
+ "85.133.172.84",
+ "85.133.172.102",
+ "85.133.172.118",
+ "85.133.172.129",
+ "85.133.172.144",
+ "85.133.172.158",
+ "85.133.172.162",
+ "85.133.172.164",
+ "85.133.172.172",
+ "85.133.172.180",
+ "85.133.172.206",
+ "85.133.172.211",
+ "85.133.172.213",
+ "85.133.172.217",
+ "85.133.172.218",
+ "85.133.172.228",
+ "85.133.172.244",
+ "85.133.173.66",
+ "85.133.173.90",
+ "85.133.173.98",
+ "85.133.175.18",
+ "85.133.175.110",
+ "85.133.175.199",
+ "85.133.176.13",
+ "85.133.176.127",
+ "85.133.178.30",
+ "85.133.179.46",
+ "85.133.179.189",
+ "85.133.180.170",
+ "85.133.181.26",
+ "85.133.181.102",
+ "85.133.181.118",
+ "85.133.181.190",
+ "85.133.182.12",
+ "85.133.182.17",
+ "85.133.182.23",
+ "85.133.182.27",
+ "85.133.182.36",
+ "85.133.182.40",
+ "85.133.182.42",
+ "85.133.182.52",
+ "85.133.182.75",
+ "85.133.182.86",
+ "85.133.182.88",
+ "85.133.182.98",
+ "85.133.182.106",
+ "85.133.182.110",
+ "85.133.182.116",
+ "85.133.182.121",
+ "85.133.182.125",
+ "85.133.182.134",
+ "85.133.182.141",
+ "85.133.182.158",
+ "85.133.182.193",
+ "85.133.182.205",
+ "85.133.182.217",
+ "85.133.182.222",
+ "85.133.182.236",
+ "85.133.182.240",
+ "85.133.182.241",
+ "85.133.182.246",
+ "85.133.183.62",
+ "85.133.183.106",
+ "85.133.183.110",
+ "85.133.183.182",
+ "85.133.183.186",
+ "85.133.184.51",
+ "85.133.184.158",
+ "85.133.185.26",
+ "85.133.185.102",
+ "85.133.185.106",
+ "85.133.185.110",
+ "85.133.185.130",
+ "85.133.185.150",
+ "85.133.186.26",
+ "85.133.186.149",
+ "85.133.186.178",
+ "85.133.186.179",
+ "85.133.186.180",
+ "85.133.186.181",
+ "85.133.186.182",
+ "85.133.186.190",
+ "85.133.187.59",
+ "85.133.187.178",
+ "85.133.188.218",
+ "85.133.189.147",
+ "85.133.189.222",
+ "85.133.190.40",
+ "85.133.190.171",
+ "85.133.190.172",
+ "85.133.190.173",
+ "85.133.190.174",
+ "85.133.191.198",
+ "85.133.193.36",
+ "85.133.193.41",
+ "85.133.193.54",
+ "85.133.193.72",
+ "85.133.193.74",
+ "85.133.193.114",
+ "85.133.193.136",
+ "85.133.197.203",
+ "85.133.202.86",
+ "85.133.205.212",
+ "85.133.212.234",
+ "85.133.212.251",
+ "85.133.216.14",
+ "85.133.216.41",
+ "85.133.217.68",
+ "85.133.225.160",
+ "85.133.225.162",
+ "85.133.225.172",
+ "85.133.225.187",
+ "85.133.229.115",
+ "85.133.229.120",
+ "85.133.229.129",
+ "85.133.229.210",
+ "85.133.237.26",
+ "85.133.237.93",
+ "85.133.240.33",
+ "85.133.240.35",
+ "85.133.240.38",
+ "85.133.240.41",
+ "85.133.240.44",
+ "85.133.240.48",
+ "85.133.240.59",
+ "85.133.240.60",
+ "85.133.240.61",
+ "85.133.240.62",
+ "85.133.240.151",
+ "85.133.240.155",
+ "85.133.240.156",
+ "85.133.240.157",
+ "85.133.240.159",
+ "85.133.240.161",
+ "85.133.240.165",
+ "85.133.240.166",
+ "85.133.240.167",
+ "85.133.240.171",
+ "85.133.240.173",
+ "85.133.240.174",
+ "85.133.240.175",
+ "85.133.240.176",
+ "85.133.240.178",
+ "85.133.240.179",
+ "85.133.240.180",
+ "85.133.240.181",
+ "85.133.240.183",
+ "85.133.240.184",
+ "85.133.240.185",
+ "85.133.240.186",
+ "85.133.240.188",
+ "85.133.240.189",
+ "85.133.240.197",
+ "85.133.240.199",
+ "85.133.240.203",
+ "85.133.240.204",
+ "85.133.240.205",
+ "85.133.240.206",
+ "85.133.240.207",
+ "85.133.240.208",
+ "85.133.240.210",
+ "85.133.240.212",
+ "85.133.241.116",
+ "85.133.241.138",
+ "85.133.241.188",
+ "85.133.253.101",
+ "85.133.253.118",
+ "85.133.253.119",
+ "85.133.254.71",
+ "85.185.4.19",
+ "85.185.4.20",
+ "85.185.4.62",
+ "85.185.4.146",
+ "85.185.4.218",
+ "85.185.4.219",
+ "85.185.6.1",
+ "85.185.6.2",
+ "85.185.6.3",
+ "85.185.6.4",
+ "85.185.6.5",
+ "85.185.6.6",
+ "85.185.6.8",
+ "85.185.6.9",
+ "85.185.6.10",
+ "85.185.6.11",
+ "85.185.6.12",
+ "85.185.6.13",
+ "85.185.6.209",
+ "85.185.8.75",
+ "85.185.13.35",
+ "85.185.13.41",
+ "85.185.13.161",
+ "85.185.14.41",
+ "85.185.17.124",
+ "85.185.20.185",
+ "85.185.20.226",
+ "85.185.21.78",
+ "85.185.22.114",
+ "85.185.28.141",
+ "85.185.29.6",
+ "85.185.29.30",
+ "85.185.29.90",
+ "85.185.29.178",
+ "85.185.41.85",
+ "85.185.41.87",
+ "85.185.41.104",
+ "85.185.41.123",
+ "85.185.42.106",
+ "85.185.52.176",
+ "85.185.54.229",
+ "85.185.55.245",
+ "85.185.55.252",
+ "85.185.56.80",
+ "85.185.57.27",
+ "85.185.58.20",
+ "85.185.60.200",
+ "85.185.62.57",
+ "85.185.62.72",
+ "85.185.62.196",
+ "85.185.64.8",
+ "85.185.64.61",
+ "85.185.64.89",
+ "85.185.64.90",
+ "85.185.64.91",
+ "85.185.64.92",
+ "85.185.64.93",
+ "85.185.64.205",
+ "85.185.64.219",
+ "85.185.66.81",
+ "85.185.66.179",
+ "85.185.66.193",
+ "85.185.66.216",
+ "85.185.66.225",
+ "85.185.67.38",
+ "85.185.67.43",
+ "85.185.67.165",
+ "85.185.67.177",
+ "85.185.67.178",
+ "85.185.75.11",
+ "85.185.75.38",
+ "85.185.75.187",
+ "85.185.75.210",
+ "85.185.75.211",
+ "85.185.75.212",
+ "85.185.76.130",
+ "85.185.76.131",
+ "85.185.76.132",
+ "85.185.76.133",
+ "85.185.76.134",
+ "85.185.76.138",
+ "85.185.76.142",
+ "85.185.76.194",
+ "85.185.81.82",
+ "85.185.81.99",
+ "85.185.84.194",
+ "85.185.84.226",
+ "85.185.86.211",
+ "85.185.88.133",
+ "85.185.88.137",
+ "85.185.88.139",
+ "85.185.93.114",
+ "85.185.95.185",
+ "85.185.104.17",
+ "85.185.105.101",
+ "85.185.105.104",
+ "85.185.105.217",
+ "85.185.106.20",
+ "85.185.110.226",
+ "85.185.110.252",
+ "85.185.123.6",
+ "85.185.128.1",
+ "85.185.130.136",
+ "85.185.138.2",
+ "85.185.138.5",
+ "85.185.138.6",
+ "85.185.138.18",
+ "85.185.138.28",
+ "85.185.138.29",
+ "85.185.138.30",
+ "85.185.138.58",
+ "85.185.138.122",
+ "85.185.138.154",
+ "85.185.138.158",
+ "85.185.138.178",
+ "85.185.138.182",
+ "85.185.138.186",
+ "85.185.138.218",
+ "85.185.138.226",
+ "85.185.139.46",
+ "85.185.140.67",
+ "85.185.149.18",
+ "85.185.149.24",
+ "85.185.149.30",
+ "85.185.158.146",
+ "85.185.159.74",
+ "85.185.159.76",
+ "85.185.159.77",
+ "85.185.161.214",
+ "85.185.161.227",
+ "85.185.161.240",
+ "85.185.164.111",
+ "85.185.165.124",
+ "85.185.165.125",
+ "85.185.165.126",
+ "85.185.165.127",
+ "85.185.166.138",
+ "85.185.169.42",
+ "85.185.170.2",
+ "85.185.185.10",
+ "85.185.190.141",
+ "85.185.198.135",
+ "85.185.201.16",
+ "85.185.201.19",
+ "85.185.202.98",
+ "85.185.202.178",
+ "85.185.202.242",
+ "85.185.206.193",
+ "85.185.206.222",
+ "85.185.207.178",
+ "85.185.216.106",
+ "85.185.218.11",
+ "85.185.218.15",
+ "85.185.218.102",
+ "85.185.218.127",
+ "85.185.222.240",
+ "85.185.229.9",
+ "85.185.229.84",
+ "85.185.229.90",
+ "85.185.229.163",
+ "85.185.232.42",
+ "85.185.235.43",
+ "85.185.235.59",
+ "85.185.235.188",
+ "85.185.235.190",
+ "85.185.235.235",
+ "85.185.236.131",
+ "85.185.236.154",
+ "85.185.237.58",
+ "85.185.237.82",
+ "85.185.237.83",
+ "85.185.237.84",
+ "85.185.237.85",
+ "85.185.239.26",
+ "85.185.239.178",
+ "85.185.239.179",
+ "85.185.239.180",
+ "85.185.239.181",
+ "85.185.239.182",
+ "85.185.239.202",
+ "85.185.241.106",
+ "85.185.241.107",
+ "85.185.241.170",
+ "85.185.241.171",
+ "85.185.241.172",
+ "85.185.241.173",
+ "85.185.241.236",
+ "85.185.244.115",
+ "85.185.244.178",
+ "85.185.244.194",
+ "85.185.244.242",
+ "85.185.246.18",
+ "85.185.246.218",
+ "85.185.247.68",
+ "85.185.247.138",
+ "85.185.249.66",
+ "85.185.249.67",
+ "85.185.251.1",
+ "85.185.251.57",
+ "85.185.251.89",
+ "85.185.251.177",
+ "85.185.251.178",
+ "85.185.251.193",
+ "85.185.251.218",
+ "85.185.252.10",
+ "85.185.253.160",
+ "85.185.254.15",
+ "85.185.255.8",
+ "85.185.255.20",
+ "85.185.255.36",
+ "85.185.255.133",
+ "85.198.0.113",
+ "85.198.2.5",
+ "85.198.24.54",
+ "85.198.24.166",
+ "85.198.25.50",
+ "85.198.25.66",
+ "85.198.25.93",
+ "85.198.25.98",
+ "85.198.25.99",
+ "85.198.25.100",
+ "85.198.25.101",
+ "85.198.25.102",
+ "85.198.25.146",
+ "85.198.25.147",
+ "85.198.25.234",
+ "85.198.26.82",
+ "85.198.26.177",
+ "85.198.26.250",
+ "85.198.27.86",
+ "85.198.28.10",
+ "85.198.28.27",
+ "85.198.28.38",
+ "85.198.28.112",
+ "85.198.28.123",
+ "85.198.28.125",
+ "85.198.28.197",
+ "85.198.28.198",
+ "85.198.29.33",
+ "85.198.29.55",
+ "85.198.29.56",
+ "85.198.29.127",
+ "85.198.29.161",
+ "85.198.30.3",
+ "85.198.30.4",
+ "85.198.30.15",
+ "85.198.30.31",
+ "85.198.30.52",
+ "85.198.30.60",
+ "85.198.30.70",
+ "85.198.30.84",
+ "85.198.30.123",
+ "85.198.30.213",
+ "85.198.30.224",
+ "85.198.30.244",
+ "85.198.30.254",
+ "85.198.31.18",
+ "85.198.31.35",
+ "85.198.31.40",
+ "85.198.31.146",
+ "85.198.31.169",
+ "85.198.31.183",
+ "85.198.31.192",
+ "85.198.31.232",
+ "85.204.30.148",
+ "85.204.30.192",
+ "85.204.76.71",
+ "85.204.76.222",
+ "85.204.77.105",
+ "85.204.77.153",
+ "85.204.77.217",
+ "85.204.80.224",
+ "85.204.83.87",
+ "85.204.83.145",
+ "85.204.84.122",
+ "85.204.85.173",
+ "85.204.87.34",
+ "85.204.87.94",
+ "85.204.88.117",
+ "85.204.88.234",
+ "85.204.90.40",
+ "85.204.91.128",
+ "85.204.91.149",
+ "85.204.92.246",
+ "85.204.93.198",
+ "85.204.104.181",
+ "85.204.104.218",
+ "85.204.104.238",
+ "85.204.105.43",
+ "85.204.105.122",
+ "85.204.105.169",
+ "85.204.105.215",
+ "85.204.105.253",
+ "85.204.128.134",
+ "85.204.128.252",
+ "85.204.129.59",
+ "85.204.130.34",
+ "85.204.211.136",
+ "85.204.211.220",
+ "85.204.213.50",
+ "85.204.213.86",
+ "85.204.213.169",
+ "85.204.215.106",
+ "85.204.215.153",
+ "85.204.217.165",
+ "85.204.218.216",
+ "85.204.219.79",
+ "85.204.219.135",
+ "85.204.220.90",
+ "85.204.223.114",
+ "85.208.253.12",
+ "85.208.253.25",
+ "85.208.253.43",
+ "85.208.253.62",
+ "85.208.253.119",
+ "85.208.253.144",
+ "85.208.253.152",
+ "85.208.253.232",
+ "85.208.253.243",
+ "85.208.254.61",
+ "85.208.254.63",
+ "85.208.254.152",
+ "85.208.254.209",
+ "85.208.254.213",
+ "86.104.32.106",
+ "86.104.81.59",
+ "86.104.96.213",
+ "86.104.96.253",
+ "86.104.104.116",
+ "86.104.104.176",
+ "86.104.107.7",
+ "86.104.110.81",
+ "86.104.243.225",
+ "86.104.244.130",
+ "86.104.244.136",
+ "86.104.244.176",
+ "86.104.244.225",
+ "86.104.244.241",
+ "86.105.44.36",
+ "86.105.47.48",
+ "86.105.47.82",
+ "86.105.47.235",
+ "86.106.142.1",
+ "86.106.142.44",
+ "86.106.142.117",
+ "86.107.1.133",
+ "86.107.8.2",
+ "86.107.8.18",
+ "86.107.8.75",
+ "86.107.14.14",
+ "86.107.14.21",
+ "86.107.14.45",
+ "86.107.14.48",
+ "86.107.14.54",
+ "86.107.14.62",
+ "86.107.14.69",
+ "86.107.14.77",
+ "86.107.14.87",
+ "86.107.14.102",
+ "86.107.14.103",
+ "86.107.14.122",
+ "86.107.14.152",
+ "86.107.14.156",
+ "86.107.14.160",
+ "86.107.14.165",
+ "86.107.14.170",
+ "86.107.14.181",
+ "86.107.14.189",
+ "86.107.14.191",
+ "86.107.14.204",
+ "86.107.14.219",
+ "86.107.14.234",
+ "86.107.14.236",
+ "86.107.14.243",
+ "86.107.14.244",
+ "86.107.14.251",
+ "86.107.15.4",
+ "86.107.15.14",
+ "86.107.15.16",
+ "86.107.15.22",
+ "86.107.15.32",
+ "86.107.15.35",
+ "86.107.15.56",
+ "86.107.15.62",
+ "86.107.15.90",
+ "86.107.15.91",
+ "86.107.15.123",
+ "86.107.15.127",
+ "86.107.15.198",
+ "86.107.15.201",
+ "86.107.15.212",
+ "86.107.15.215",
+ "86.107.15.221",
+ "86.107.15.228",
+ "86.107.15.236",
+ "86.107.15.249",
+ "86.107.15.254",
+ "86.107.144.227",
+ "86.107.146.168",
+ "86.107.147.238",
+ "86.107.150.6",
+ "86.107.150.35",
+ "86.107.151.171",
+ "86.107.151.172",
+ "86.107.152.190",
+ "86.107.152.194",
+ "86.107.152.248",
+ "86.107.153.163",
+ "86.107.153.179",
+ "86.107.157.155",
+ "86.107.157.232",
+ "86.107.158.161",
+ "86.107.158.181",
+ "86.107.159.246",
+ "86.109.45.154",
+ "86.109.45.186",
+ "86.109.45.187",
+ "86.109.45.188",
+ "86.109.54.134",
+ "87.107.6.17",
+ "87.107.6.23",
+ "87.107.6.36",
+ "87.107.6.59",
+ "87.107.6.60",
+ "87.107.6.84",
+ "87.107.6.97",
+ "87.107.6.202",
+ "87.107.8.85",
+ "87.107.8.87",
+ "87.107.8.88",
+ "87.107.8.89",
+ "87.107.8.166",
+ "87.107.9.170",
+ "87.107.9.171",
+ "87.107.9.173",
+ "87.107.10.74",
+ "87.107.10.241",
+ "87.107.11.91",
+ "87.107.11.93",
+ "87.107.12.221",
+ "87.107.16.30",
+ "87.107.16.214",
+ "87.107.16.222",
+ "87.107.17.222",
+ "87.107.18.2",
+ "87.107.18.14",
+ "87.107.18.22",
+ "87.107.18.66",
+ "87.107.18.82",
+ "87.107.19.14",
+ "87.107.19.68",
+ "87.107.19.104",
+ "87.107.19.196",
+ "87.107.19.198",
+ "87.107.28.90",
+ "87.107.29.158",
+ "87.107.30.6",
+ "87.107.30.86",
+ "87.107.30.166",
+ "87.107.38.230",
+ "87.107.44.2",
+ "87.107.48.7",
+ "87.107.48.26",
+ "87.107.48.63",
+ "87.107.48.66",
+ "87.107.48.81",
+ "87.107.48.124",
+ "87.107.48.144",
+ "87.107.48.159",
+ "87.107.48.173",
+ "87.107.48.184",
+ "87.107.48.229",
+ "87.107.48.233",
+ "87.107.49.19",
+ "87.107.49.88",
+ "87.107.49.106",
+ "87.107.49.163",
+ "87.107.49.173",
+ "87.107.49.195",
+ "87.107.49.220",
+ "87.107.52.99",
+ "87.107.52.235",
+ "87.107.54.69",
+ "87.107.54.228",
+ "87.107.54.233",
+ "87.107.55.56",
+ "87.107.55.134",
+ "87.107.55.203",
+ "87.107.68.38",
+ "87.107.68.43",
+ "87.107.68.49",
+ "87.107.68.87",
+ "87.107.73.116",
+ "87.107.74.34",
+ "87.107.74.36",
+ "87.107.74.37",
+ "87.107.75.32",
+ "87.107.77.18",
+ "87.107.77.94",
+ "87.107.78.18",
+ "87.107.78.130",
+ "87.107.78.178",
+ "87.107.78.242",
+ "87.107.78.246",
+ "87.107.79.62",
+ "87.107.79.152",
+ "87.107.82.201",
+ "87.107.82.213",
+ "87.107.83.18",
+ "87.107.83.64",
+ "87.107.83.77",
+ "87.107.83.120",
+ "87.107.83.238",
+ "87.107.83.240",
+ "87.107.87.5",
+ "87.107.87.118",
+ "87.107.94.3",
+ "87.107.95.138",
+ "87.107.100.160",
+ "87.107.101.13",
+ "87.107.101.26",
+ "87.107.101.61",
+ "87.107.101.63",
+ "87.107.101.70",
+ "87.107.101.72",
+ "87.107.101.88",
+ "87.107.101.97",
+ "87.107.101.99",
+ "87.107.101.100",
+ "87.107.101.101",
+ "87.107.101.251",
+ "87.107.102.195",
+ "87.107.102.227",
+ "87.107.103.226",
+ "87.107.103.250",
+ "87.107.104.8",
+ "87.107.104.177",
+ "87.107.104.214",
+ "87.107.105.27",
+ "87.107.105.31",
+ "87.107.108.185",
+ "87.107.108.208",
+ "87.107.108.221",
+ "87.107.109.107",
+ "87.107.110.10",
+ "87.107.110.22",
+ "87.107.110.138",
+ "87.107.111.178",
+ "87.107.111.180",
+ "87.107.111.181",
+ "87.107.111.182",
+ "87.107.111.202",
+ "87.107.111.203",
+ "87.107.111.204",
+ "87.107.111.206",
+ "87.107.121.85",
+ "87.107.124.117",
+ "87.107.124.124",
+ "87.107.132.35",
+ "87.107.135.242",
+ "87.107.136.42",
+ "87.107.137.50",
+ "87.107.137.82",
+ "87.107.137.250",
+ "87.107.137.251",
+ "87.107.138.50",
+ "87.107.138.52",
+ "87.107.138.53",
+ "87.107.138.58",
+ "87.107.138.70",
+ "87.107.138.151",
+ "87.107.138.226",
+ "87.107.139.218",
+ "87.107.139.220",
+ "87.107.139.222",
+ "87.107.139.254",
+ "87.107.141.1",
+ "87.107.141.37",
+ "87.107.141.79",
+ "87.107.141.95",
+ "87.107.141.105",
+ "87.107.141.113",
+ "87.107.142.18",
+ "87.107.143.4",
+ "87.107.143.12",
+ "87.107.143.15",
+ "87.107.143.19",
+ "87.107.143.21",
+ "87.107.143.29",
+ "87.107.143.130",
+ "87.107.143.131",
+ "87.107.143.132",
+ "87.107.143.133",
+ "87.107.143.134",
+ "87.107.143.135",
+ "87.107.143.136",
+ "87.107.143.137",
+ "87.107.143.138",
+ "87.107.143.139",
+ "87.107.143.140",
+ "87.107.143.141",
+ "87.107.143.142",
+ "87.107.144.54",
+ "87.107.144.62",
+ "87.107.144.217",
+ "87.107.146.29",
+ "87.107.146.39",
+ "87.107.146.141",
+ "87.107.146.243",
+ "87.107.152.35",
+ "87.107.152.211",
+ "87.107.152.212",
+ "87.107.152.214",
+ "87.107.152.246",
+ "87.107.153.116",
+ "87.107.154.27",
+ "87.107.154.69",
+ "87.107.154.174",
+ "87.107.155.82",
+ "87.107.155.238",
+ "87.107.164.15",
+ "87.107.164.28",
+ "87.107.164.29",
+ "87.107.164.65",
+ "87.107.164.179",
+ "87.107.164.215",
+ "87.107.165.65",
+ "87.107.165.135",
+ "87.107.166.6",
+ "87.107.166.122",
+ "87.107.166.150",
+ "87.107.167.67",
+ "87.107.167.92",
+ "87.107.167.182",
+ "87.107.167.183",
+ "87.107.167.185",
+ "87.107.167.186",
+ "87.107.174.43",
+ "87.107.174.114",
+ "87.107.174.134",
+ "87.107.174.139",
+ "87.107.184.98",
+ "87.107.185.204",
+ "87.107.185.216",
+ "87.236.38.233",
+ "87.236.39.134",
+ "87.236.209.21",
+ "87.236.209.173",
+ "87.236.209.229",
+ "87.236.210.54",
+ "87.236.210.126",
+ "87.236.211.5",
+ "87.236.211.11",
+ "87.236.211.70",
+ "87.236.211.75",
+ "87.236.211.119",
+ "87.236.211.220",
+ "87.236.211.222",
+ "87.236.212.82",
+ "87.236.212.132",
+ "87.236.212.146",
+ "87.236.212.178",
+ "87.236.213.20",
+ "87.236.213.33",
+ "87.236.213.97",
+ "87.236.213.129",
+ "87.236.213.161",
+ "87.236.213.249",
+ "87.236.214.20",
+ "87.236.214.47",
+ "87.236.214.129",
+ "87.236.214.225",
+ "87.236.214.249",
+ "87.236.215.169",
+ "87.236.215.170",
+ "87.236.215.227",
+ "87.247.168.101",
+ "87.247.168.190",
+ "87.247.170.156",
+ "87.247.171.4",
+ "87.247.171.74",
+ "87.247.174.146",
+ "87.247.174.214",
+ "87.247.176.68",
+ "87.247.176.242",
+ "87.247.176.252",
+ "87.247.176.254",
+ "87.248.130.28",
+ "87.248.130.42",
+ "87.248.130.91",
+ "87.248.130.133",
+ "87.248.130.186",
+ "87.248.137.243",
+ "87.248.138.33",
+ "87.248.138.162",
+ "87.248.138.163",
+ "87.248.138.164",
+ "87.248.138.165",
+ "87.248.138.166",
+ "87.248.139.186",
+ "87.248.139.236",
+ "87.248.139.237",
+ "87.248.140.6",
+ "87.248.140.65",
+ "87.248.140.123",
+ "87.248.140.171",
+ "87.248.140.195",
+ "87.248.140.197",
+ "87.248.141.133",
+ "87.248.141.142",
+ "87.248.141.144",
+ "87.248.141.152",
+ "87.248.141.196",
+ "87.248.141.211",
+ "87.248.145.145",
+ "87.248.147.154",
+ "87.248.147.155",
+ "87.248.150.118",
+ "87.248.151.5",
+ "87.248.151.38",
+ "87.248.151.59",
+ "87.248.151.117",
+ "87.248.151.124",
+ "87.248.152.44",
+ "87.248.152.189",
+ "87.248.153.230",
+ "87.248.154.31",
+ "87.248.154.89",
+ "87.248.154.103",
+ "87.248.154.113",
+ "87.248.154.129",
+ "87.248.154.194",
+ "87.248.154.207",
+ "87.248.155.14",
+ "87.248.155.79",
+ "87.248.155.81",
+ "87.248.155.245",
+ "87.248.156.62",
+ "87.248.156.134",
+ "87.248.156.195",
+ "88.135.38.143",
+ "88.135.38.146",
+ "88.135.38.147",
+ "88.135.38.148",
+ "88.135.38.149",
+ "88.135.38.150",
+ "88.135.38.151",
+ "88.135.39.29",
+ "88.135.68.2",
+ "88.135.68.15",
+ "88.135.68.96",
+ "88.135.75.148",
+ "88.135.75.201",
+ "88.218.16.58",
+ "88.218.16.123",
+ "88.218.16.124",
+ "89.32.197.12",
+ "89.32.197.30",
+ "89.32.197.51",
+ "89.32.197.52",
+ "89.32.197.87",
+ "89.32.197.111",
+ "89.32.197.182",
+ "89.32.197.214",
+ "89.32.248.1",
+ "89.32.248.36",
+ "89.32.248.65",
+ "89.32.248.73",
+ "89.32.248.81",
+ "89.32.248.129",
+ "89.32.248.130",
+ "89.32.248.134",
+ "89.32.248.137",
+ "89.32.248.145",
+ "89.32.248.161",
+ "89.32.248.162",
+ "89.32.248.163",
+ "89.32.248.194",
+ "89.32.248.201",
+ "89.32.248.203",
+ "89.32.248.209",
+ "89.32.248.225",
+ "89.32.249.1",
+ "89.32.249.65",
+ "89.32.249.97",
+ "89.32.249.129",
+ "89.32.249.145",
+ "89.32.249.153",
+ "89.32.249.161",
+ "89.32.249.193",
+ "89.32.251.1",
+ "89.32.251.17",
+ "89.32.251.33",
+ "89.32.251.41",
+ "89.32.251.65",
+ "89.32.251.95",
+ "89.32.251.107",
+ "89.32.251.129",
+ "89.32.251.161",
+ "89.33.18.10",
+ "89.33.18.18",
+ "89.33.18.20",
+ "89.33.18.21",
+ "89.33.18.29",
+ "89.33.18.42",
+ "89.33.18.50",
+ "89.33.18.52",
+ "89.33.18.54",
+ "89.33.18.55",
+ "89.33.18.61",
+ "89.33.18.68",
+ "89.33.18.70",
+ "89.33.18.84",
+ "89.33.18.93",
+ "89.33.18.99",
+ "89.33.18.101",
+ "89.33.18.104",
+ "89.33.18.106",
+ "89.33.18.111",
+ "89.33.18.114",
+ "89.33.18.142",
+ "89.33.18.145",
+ "89.33.18.150",
+ "89.33.18.153",
+ "89.33.18.157",
+ "89.33.18.160",
+ "89.33.18.168",
+ "89.33.18.174",
+ "89.33.18.186",
+ "89.33.18.189",
+ "89.33.18.190",
+ "89.33.18.191",
+ "89.33.18.192",
+ "89.33.18.193",
+ "89.33.18.206",
+ "89.33.18.212",
+ "89.33.18.225",
+ "89.33.18.231",
+ "89.33.18.235",
+ "89.33.18.242",
+ "89.33.18.246",
+ "89.33.18.249",
+ "89.33.18.251",
+ "89.33.19.13",
+ "89.33.19.14",
+ "89.33.19.30",
+ "89.33.19.31",
+ "89.33.19.45",
+ "89.33.19.49",
+ "89.33.19.50",
+ "89.33.19.51",
+ "89.33.19.62",
+ "89.33.19.65",
+ "89.33.19.67",
+ "89.33.19.68",
+ "89.33.19.73",
+ "89.33.19.94",
+ "89.33.19.99",
+ "89.33.19.107",
+ "89.33.19.112",
+ "89.33.19.117",
+ "89.33.19.118",
+ "89.33.19.119",
+ "89.33.19.125",
+ "89.33.19.126",
+ "89.33.19.130",
+ "89.33.19.141",
+ "89.33.19.152",
+ "89.33.19.156",
+ "89.33.19.165",
+ "89.33.19.169",
+ "89.33.19.170",
+ "89.33.19.173",
+ "89.33.19.176",
+ "89.33.19.179",
+ "89.33.19.182",
+ "89.33.19.190",
+ "89.33.19.197",
+ "89.33.19.200",
+ "89.33.19.207",
+ "89.33.19.209",
+ "89.33.19.216",
+ "89.33.19.218",
+ "89.33.19.220",
+ "89.33.19.227",
+ "89.33.19.229",
+ "89.33.19.231",
+ "89.33.19.235",
+ "89.33.19.236",
+ "89.33.19.239",
+ "89.33.19.240",
+ "89.33.19.244",
+ "89.33.19.246",
+ "89.33.19.251",
+ "89.33.129.167",
+ "89.33.129.170",
+ "89.33.205.167",
+ "89.33.234.12",
+ "89.33.240.41",
+ "89.34.21.101",
+ "89.34.169.18",
+ "89.34.169.108",
+ "89.34.169.116",
+ "89.34.169.222",
+ "89.34.176.58",
+ "89.34.176.66",
+ "89.34.176.105",
+ "89.34.176.185",
+ "89.34.177.113",
+ "89.34.200.91",
+ "89.34.200.94",
+ "89.34.200.117",
+ "89.34.201.120",
+ "89.34.254.147",
+ "89.35.58.51",
+ "89.35.132.69",
+ "89.35.132.78",
+ "89.35.132.122",
+ "89.35.133.153",
+ "89.35.133.210",
+ "89.35.133.223",
+ "89.35.133.237",
+ "89.36.226.24",
+ "89.36.226.29",
+ "89.37.1.10",
+ "89.37.1.58",
+ "89.37.1.59",
+ "89.37.1.60",
+ "89.37.1.61",
+ "89.37.1.62",
+ "89.37.1.115",
+ "89.37.3.182",
+ "89.37.4.54",
+ "89.37.9.118",
+ "89.37.11.210",
+ "89.37.12.84",
+ "89.37.13.250",
+ "89.37.15.11",
+ "89.37.15.12",
+ "89.37.15.34",
+ "89.37.15.90",
+ "89.37.15.91",
+ "89.37.15.92",
+ "89.37.103.14",
+ "89.37.103.30",
+ "89.37.103.65",
+ "89.37.103.81",
+ "89.37.103.103",
+ "89.37.146.97",
+ "89.37.147.29",
+ "89.37.148.152",
+ "89.37.148.159",
+ "89.37.148.182",
+ "89.37.153.246",
+ "89.37.155.233",
+ "89.37.198.147",
+ "89.37.199.125",
+ "89.37.199.209",
+ "89.37.219.29",
+ "89.37.219.30",
+ "89.37.219.51",
+ "89.37.219.220",
+ "89.37.241.17",
+ "89.37.242.36",
+ "89.37.242.162",
+ "89.37.245.11",
+ "89.37.245.55",
+ "89.37.246.36",
+ "89.37.247.74",
+ "89.37.248.10",
+ "89.37.248.120",
+ "89.37.249.127",
+ "89.37.250.29",
+ "89.37.250.157",
+ "89.37.251.210",
+ "89.37.252.31",
+ "89.37.253.74",
+ "89.37.253.85",
+ "89.37.253.125",
+ "89.37.253.130",
+ "89.37.253.240",
+ "89.37.254.33",
+ "89.37.254.83",
+ "89.37.255.217",
+ "89.38.81.43",
+ "89.38.81.101",
+ "89.38.82.199",
+ "89.38.83.102",
+ "89.38.84.75",
+ "89.38.84.110",
+ "89.38.85.197",
+ "89.38.86.67",
+ "89.38.87.69",
+ "89.38.87.96",
+ "89.38.87.192",
+ "89.38.88.198",
+ "89.38.89.20",
+ "89.38.89.32",
+ "89.38.89.171",
+ "89.38.90.62",
+ "89.38.90.169",
+ "89.38.91.21",
+ "89.38.92.26",
+ "89.38.92.163",
+ "89.38.93.89",
+ "89.38.93.111",
+ "89.38.94.189",
+ "89.38.94.214",
+ "89.38.95.197",
+ "89.38.102.107",
+ "89.38.102.227",
+ "89.38.102.251",
+ "89.38.103.22",
+ "89.38.103.58",
+ "89.38.103.81",
+ "89.38.103.139",
+ "89.38.103.166",
+ "89.38.103.219",
+ "89.38.246.58",
+ "89.39.208.9",
+ "89.39.208.17",
+ "89.39.208.21",
+ "89.39.208.25",
+ "89.39.208.33",
+ "89.39.208.39",
+ "89.39.208.73",
+ "89.39.208.77",
+ "89.39.208.81",
+ "89.39.208.97",
+ "89.39.208.105",
+ "89.39.208.113",
+ "89.39.208.126",
+ "89.39.208.129",
+ "89.39.208.133",
+ "89.39.208.145",
+ "89.39.208.171",
+ "89.39.208.177",
+ "89.39.208.182",
+ "89.40.78.162",
+ "89.40.78.189",
+ "89.40.78.208",
+ "89.40.78.219",
+ "89.40.79.27",
+ "89.40.79.53",
+ "89.40.79.71",
+ "89.40.79.117",
+ "89.40.79.123",
+ "89.40.79.185",
+ "89.40.79.211",
+ "89.40.79.226",
+ "89.40.106.17",
+ "89.40.106.139",
+ "89.40.107.24",
+ "89.40.107.223",
+ "89.40.107.244",
+ "89.40.159.148",
+ "89.40.246.2",
+ "89.40.246.135",
+ "89.40.246.212",
+ "89.40.247.10",
+ "89.40.247.138",
+ "89.40.247.154",
+ "89.41.40.56",
+ "89.41.40.106",
+ "89.41.40.171",
+ "89.41.41.83",
+ "89.41.42.52",
+ "89.41.42.193",
+ "89.41.42.230",
+ "89.41.42.234",
+ "89.41.43.48",
+ "89.41.43.64",
+ "89.41.43.135",
+ "89.41.43.163",
+ "89.42.44.211",
+ "89.42.96.21",
+ "89.42.96.80",
+ "89.42.96.167",
+ "89.42.97.57",
+ "89.42.100.11",
+ "89.42.100.28",
+ "89.42.100.50",
+ "89.42.100.56",
+ "89.42.101.45",
+ "89.42.101.182",
+ "89.42.102.130",
+ "89.42.102.184",
+ "89.42.103.21",
+ "89.42.103.160",
+ "89.42.103.237",
+ "89.42.136.30",
+ "89.42.136.114",
+ "89.42.136.115",
+ "89.42.136.116",
+ "89.42.136.218",
+ "89.42.138.122",
+ "89.42.139.89",
+ "89.42.150.51",
+ "89.42.151.230",
+ "89.42.197.6",
+ "89.42.197.17",
+ "89.42.197.18",
+ "89.42.197.21",
+ "89.42.197.25",
+ "89.42.197.78",
+ "89.42.198.4",
+ "89.42.198.12",
+ "89.42.198.21",
+ "89.42.198.30",
+ "89.42.198.31",
+ "89.42.198.43",
+ "89.42.198.57",
+ "89.42.198.73",
+ "89.42.198.86",
+ "89.42.198.110",
+ "89.42.198.116",
+ "89.42.198.131",
+ "89.42.198.180",
+ "89.42.198.216",
+ "89.42.199.59",
+ "89.42.199.212",
+ "89.42.208.1",
+ "89.42.208.65",
+ "89.42.208.97",
+ "89.42.208.112",
+ "89.42.208.129",
+ "89.42.208.145",
+ "89.42.208.153",
+ "89.42.208.161",
+ "89.42.208.177",
+ "89.42.208.193",
+ "89.42.208.209",
+ "89.42.208.211",
+ "89.42.208.217",
+ "89.42.208.225",
+ "89.42.208.233",
+ "89.42.208.241",
+ "89.42.209.18",
+ "89.42.209.32",
+ "89.42.209.55",
+ "89.42.209.65",
+ "89.42.209.85",
+ "89.42.209.90",
+ "89.42.209.97",
+ "89.42.209.129",
+ "89.42.209.145",
+ "89.42.209.149",
+ "89.42.209.161",
+ "89.42.209.177",
+ "89.42.209.185",
+ "89.42.209.193",
+ "89.42.209.201",
+ "89.42.209.225",
+ "89.42.209.233",
+ "89.42.209.249",
+ "89.42.209.253",
+ "89.42.210.1",
+ "89.42.210.18",
+ "89.42.210.56",
+ "89.42.210.59",
+ "89.42.210.129",
+ "89.42.210.161",
+ "89.42.210.193",
+ "89.42.210.209",
+ "89.42.210.233",
+ "89.42.210.241",
+ "89.42.210.242",
+ "89.42.210.249",
+ "89.42.211.1",
+ "89.42.211.17",
+ "89.42.211.33",
+ "89.42.211.97",
+ "89.42.211.113",
+ "89.42.211.129",
+ "89.42.211.161",
+ "89.42.211.193",
+ "89.42.211.225",
+ "89.42.211.233",
+ "89.43.2.90",
+ "89.43.3.78",
+ "89.43.3.224",
+ "89.43.7.205",
+ "89.43.11.226",
+ "89.43.13.7",
+ "89.43.36.175",
+ "89.43.144.185",
+ "89.43.216.15",
+ "89.43.217.102",
+ "89.43.222.45",
+ "89.43.222.109",
+ "89.43.223.216",
+ "89.43.226.5",
+ "89.43.227.38",
+ "89.43.227.44",
+ "89.43.229.90",
+ "89.43.230.171",
+ "89.43.230.207",
+ "89.43.231.200",
+ "89.44.112.4",
+ "89.44.112.6",
+ "89.44.112.7",
+ "89.44.112.8",
+ "89.44.112.9",
+ "89.44.118.4",
+ "89.44.118.20",
+ "89.44.118.21",
+ "89.44.129.129",
+ "89.44.129.255",
+ "89.44.130.118",
+ "89.44.132.3",
+ "89.44.134.62",
+ "89.44.176.34",
+ "89.44.176.246",
+ "89.44.177.25",
+ "89.44.177.66",
+ "89.44.179.14",
+ "89.44.179.172",
+ "89.44.179.254",
+ "89.44.180.39",
+ "89.44.183.233",
+ "89.44.240.59",
+ "89.44.240.200",
+ "89.44.240.220",
+ "89.45.56.19",
+ "89.45.56.25",
+ "89.45.56.35",
+ "89.45.56.52",
+ "89.45.56.74",
+ "89.45.56.78",
+ "89.45.56.82",
+ "89.45.56.86",
+ "89.45.56.111",
+ "89.45.56.113",
+ "89.45.56.122",
+ "89.45.56.125",
+ "89.45.56.140",
+ "89.45.56.179",
+ "89.45.56.186",
+ "89.45.89.1",
+ "89.45.89.90",
+ "89.45.89.248",
+ "89.45.89.249",
+ "89.45.89.251",
+ "89.45.89.252",
+ "89.45.89.253",
+ "89.45.89.254",
+ "89.45.115.201",
+ "89.46.60.49",
+ "89.46.61.219",
+ "89.46.94.24",
+ "89.46.94.71",
+ "89.46.94.197",
+ "89.46.94.202",
+ "89.46.94.231",
+ "89.46.95.220",
+ "89.46.95.222",
+ "89.46.216.5",
+ "89.46.216.13",
+ "89.46.216.14",
+ "89.46.216.41",
+ "89.46.216.208",
+ "89.46.218.17",
+ "89.46.218.41",
+ "89.46.218.145",
+ "89.46.219.1",
+ "89.46.219.4",
+ "89.46.219.33",
+ "89.46.219.34",
+ "89.46.219.36",
+ "89.46.219.37",
+ "89.46.219.38",
+ "89.46.219.40",
+ "89.46.219.41",
+ "89.46.219.42",
+ "89.46.219.44",
+ "89.46.219.45",
+ "89.46.219.46",
+ "89.47.196.131",
+ "89.47.196.137",
+ "89.47.196.143",
+ "89.47.199.106",
+ "89.47.199.158",
+ "89.47.199.230",
+ "89.47.201.38",
+ "89.47.202.101",
+ "89.144.132.178",
+ "89.144.133.130",
+ "89.144.133.136",
+ "89.144.133.193",
+ "89.144.135.118",
+ "89.144.137.200",
+ "89.144.139.180",
+ "89.144.139.181",
+ "89.144.140.81",
+ "89.144.141.129",
+ "89.144.143.162",
+ "89.144.143.163",
+ "89.144.143.165",
+ "89.144.149.93",
+ "89.144.151.82",
+ "89.144.151.88",
+ "89.144.152.1",
+ "89.144.152.2",
+ "89.144.153.48",
+ "89.144.155.82",
+ "89.144.157.164",
+ "89.144.160.25",
+ "89.144.169.244",
+ "89.144.172.248",
+ "89.144.173.180",
+ "89.144.174.181",
+ "89.144.174.248",
+ "89.144.175.220",
+ "89.144.180.65",
+ "89.144.183.65",
+ "89.144.183.241",
+ "89.144.184.9",
+ "89.144.185.201",
+ "89.144.186.10",
+ "89.144.187.121",
+ "89.144.188.168",
+ "89.144.189.72",
+ "89.165.0.138",
+ "89.165.3.242",
+ "89.165.7.118",
+ "89.165.40.10",
+ "89.165.44.194",
+ "89.165.45.194",
+ "89.165.56.12",
+ "89.165.64.8",
+ "89.219.64.56",
+ "89.219.64.250",
+ "89.219.66.253",
+ "89.219.67.35",
+ "89.219.67.204",
+ "89.219.68.206",
+ "89.219.68.251",
+ "89.219.69.245",
+ "89.219.70.146",
+ "89.219.70.157",
+ "89.219.71.200",
+ "89.219.72.72",
+ "89.219.72.195",
+ "89.219.74.112",
+ "89.219.75.26",
+ "89.219.76.119",
+ "89.219.78.58",
+ "89.219.81.228",
+ "89.219.84.28",
+ "89.219.86.59",
+ "89.219.86.83",
+ "89.219.86.161",
+ "89.219.88.197",
+ "89.219.89.194",
+ "89.219.90.152",
+ "89.219.91.179",
+ "89.219.91.185",
+ "89.219.91.252",
+ "89.219.93.59",
+ "89.219.93.170",
+ "89.219.94.38",
+ "89.219.94.79",
+ "89.219.95.230",
+ "89.219.100.4",
+ "89.219.100.20",
+ "89.219.100.47",
+ "89.219.105.68",
+ "89.219.107.184",
+ "89.219.108.107",
+ "89.219.108.139",
+ "89.219.108.250",
+ "89.219.111.145",
+ "89.219.112.154",
+ "89.219.114.134",
+ "89.219.115.186",
+ "89.219.117.58",
+ "89.219.118.20",
+ "89.219.118.67",
+ "89.219.119.157",
+ "89.219.120.250",
+ "89.219.122.59",
+ "89.219.124.202",
+ "89.219.125.162",
+ "89.219.194.91",
+ "89.219.194.254",
+ "89.219.195.206",
+ "89.219.200.100",
+ "89.219.202.212",
+ "89.219.203.130",
+ "89.219.207.174",
+ "89.219.208.238",
+ "89.219.209.174",
+ "89.219.218.83",
+ "89.219.221.97",
+ "89.219.221.160",
+ "89.219.225.235",
+ "89.219.226.15",
+ "89.219.229.89",
+ "89.219.236.121",
+ "89.219.243.103",
+ "89.219.245.17",
+ "89.219.246.98",
+ "89.219.246.103",
+ "89.219.247.62",
+ "89.219.252.29",
+ "89.219.252.79",
+ "89.219.255.238",
+ "89.221.84.84",
+ "89.221.84.88",
+ "89.221.85.56",
+ "89.221.85.110",
+ "89.221.85.122",
+ "89.221.85.137",
+ "89.221.85.140",
+ "89.221.85.142",
+ "89.221.85.217",
+ "89.221.86.76",
+ "89.221.86.171",
+ "89.221.86.173",
+ "89.221.86.202",
+ "89.221.86.213",
+ "89.235.79.11",
+ "89.235.79.12",
+ "89.235.79.14",
+ "89.235.79.17",
+ "89.235.79.179",
+ "89.235.93.201",
+ "89.235.95.206",
+ "89.235.96.26",
+ "89.235.99.208",
+ "89.235.104.1",
+ "89.235.112.1",
+ "89.235.116.213",
+ "91.92.114.105",
+ "91.92.114.198",
+ "91.92.114.239",
+ "91.92.121.13",
+ "91.92.121.59",
+ "91.92.121.77",
+ "91.92.121.115",
+ "91.92.121.122",
+ "91.92.121.157",
+ "91.92.122.4",
+ "91.92.122.22",
+ "91.92.122.90",
+ "91.92.122.95",
+ "91.92.122.138",
+ "91.92.122.144",
+ "91.92.122.219",
+ "91.92.123.159",
+ "91.92.123.214",
+ "91.92.124.1",
+ "91.92.124.40",
+ "91.92.124.81",
+ "91.92.124.90",
+ "91.92.124.147",
+ "91.92.124.172",
+ "91.92.124.220",
+ "91.92.124.248",
+ "91.92.125.160",
+ "91.92.125.219",
+ "91.92.125.243",
+ "91.92.126.4",
+ "91.92.126.48",
+ "91.92.126.49",
+ "91.92.126.71",
+ "91.92.126.85",
+ "91.92.126.97",
+ "91.92.126.117",
+ "91.92.126.123",
+ "91.92.126.238",
+ "91.92.127.14",
+ "91.92.127.37",
+ "91.92.127.53",
+ "91.92.127.75",
+ "91.92.127.105",
+ "91.92.127.145",
+ "91.92.127.167",
+ "91.92.127.191",
+ "91.92.127.228",
+ "91.92.129.59",
+ "91.92.129.87",
+ "91.92.129.162",
+ "91.92.129.188",
+ "91.92.129.216",
+ "91.92.130.4",
+ "91.92.130.49",
+ "91.92.130.111",
+ "91.92.130.112",
+ "91.92.130.148",
+ "91.92.130.157",
+ "91.92.130.168",
+ "91.92.130.197",
+ "91.92.130.202",
+ "91.92.130.231",
+ "91.92.131.57",
+ "91.92.131.107",
+ "91.92.131.115",
+ "91.92.131.135",
+ "91.92.131.151",
+ "91.92.131.155",
+ "91.92.131.166",
+ "91.92.131.168",
+ "91.92.131.196",
+ "91.92.131.199",
+ "91.92.131.201",
+ "91.92.131.204",
+ "91.92.131.208",
+ "91.92.131.218",
+ "91.92.131.248",
+ "91.92.132.17",
+ "91.92.133.8",
+ "91.92.133.75",
+ "91.92.133.80",
+ "91.92.133.83",
+ "91.92.133.87",
+ "91.92.133.89",
+ "91.92.133.97",
+ "91.92.133.121",
+ "91.92.133.135",
+ "91.92.133.145",
+ "91.92.133.158",
+ "91.92.133.195",
+ "91.92.149.37",
+ "91.92.151.37",
+ "91.92.156.9",
+ "91.92.157.82",
+ "91.92.158.66",
+ "91.92.158.72",
+ "91.92.159.114",
+ "91.92.159.131",
+ "91.92.159.241",
+ "91.92.164.17",
+ "91.92.164.200",
+ "91.92.165.41",
+ "91.92.165.51",
+ "91.92.166.52",
+ "91.92.166.201",
+ "91.92.167.216",
+ "91.92.180.19",
+ "91.92.180.30",
+ "91.92.180.36",
+ "91.92.180.72",
+ "91.92.180.80",
+ "91.92.180.87",
+ "91.92.180.106",
+ "91.92.180.109",
+ "91.92.180.125",
+ "91.92.180.127",
+ "91.92.180.131",
+ "91.92.180.139",
+ "91.92.180.182",
+ "91.92.180.216",
+ "91.92.180.230",
+ "91.92.180.253",
+ "91.92.181.44",
+ "91.92.181.61",
+ "91.92.181.113",
+ "91.92.181.138",
+ "91.92.181.142",
+ "91.92.181.205",
+ "91.92.182.57",
+ "91.92.182.77",
+ "91.92.182.120",
+ "91.92.182.150",
+ "91.92.182.181",
+ "91.92.182.200",
+ "91.92.182.251",
+ "91.92.183.23",
+ "91.92.183.70",
+ "91.92.183.106",
+ "91.92.183.172",
+ "91.92.185.29",
+ "91.92.185.70",
+ "91.92.185.92",
+ "91.92.186.17",
+ "91.92.186.108",
+ "91.92.186.132",
+ "91.92.186.154",
+ "91.92.186.167",
+ "91.92.186.214",
+ "91.92.186.225",
+ "91.92.187.10",
+ "91.92.187.30",
+ "91.92.188.38",
+ "91.92.188.142",
+ "91.92.188.218",
+ "91.92.188.223",
+ "91.92.189.39",
+ "91.92.189.183",
+ "91.92.190.18",
+ "91.92.190.87",
+ "91.92.190.126",
+ "91.92.190.168",
+ "91.92.190.190",
+ "91.92.190.193",
+ "91.92.190.215",
+ "91.92.191.30",
+ "91.92.191.36",
+ "91.92.191.81",
+ "91.92.191.167",
+ "91.92.191.168",
+ "91.92.191.177",
+ "91.92.191.178",
+ "91.92.191.221",
+ "91.92.192.17",
+ "91.92.204.27",
+ "91.92.204.130",
+ "91.92.204.165",
+ "91.92.204.178",
+ "91.92.204.194",
+ "91.92.204.211",
+ "91.92.205.179",
+ "91.92.205.208",
+ "91.92.206.34",
+ "91.92.206.90",
+ "91.92.207.152",
+ "91.92.207.195",
+ "91.92.207.221",
+ "91.92.207.228",
+ "91.92.207.238",
+ "91.92.208.3",
+ "91.92.208.10",
+ "91.92.208.21",
+ "91.92.208.38",
+ "91.92.208.43",
+ "91.92.208.51",
+ "91.92.208.63",
+ "91.92.208.108",
+ "91.92.208.149",
+ "91.92.208.173",
+ "91.92.208.192",
+ "91.92.208.205",
+ "91.92.208.229",
+ "91.92.208.245",
+ "91.92.209.2",
+ "91.92.209.5",
+ "91.92.209.9",
+ "91.92.209.27",
+ "91.92.209.32",
+ "91.92.209.38",
+ "91.92.209.43",
+ "91.92.209.45",
+ "91.92.209.75",
+ "91.92.209.115",
+ "91.92.209.165",
+ "91.92.209.167",
+ "91.92.209.173",
+ "91.92.209.192",
+ "91.92.209.194",
+ "91.92.209.247",
+ "91.92.210.135",
+ "91.92.211.24",
+ "91.92.211.55",
+ "91.92.211.66",
+ "91.92.211.77",
+ "91.92.211.78",
+ "91.92.211.81",
+ "91.92.211.108",
+ "91.92.211.135",
+ "91.92.211.151",
+ "91.92.211.160",
+ "91.92.211.174",
+ "91.92.211.218",
+ "91.92.211.232",
+ "91.92.211.245",
+ "91.92.211.250",
+ "91.92.211.253",
+ "91.92.212.33",
+ "91.92.212.69",
+ "91.92.212.157",
+ "91.92.212.167",
+ "91.92.212.171",
+ "91.92.212.194",
+ "91.92.212.240",
+ "91.92.212.246",
+ "91.92.213.37",
+ "91.92.213.82",
+ "91.92.213.148",
+ "91.92.214.41",
+ "91.92.214.46",
+ "91.92.214.65",
+ "91.92.214.85",
+ "91.92.214.93",
+ "91.92.214.104",
+ "91.92.214.143",
+ "91.92.214.188",
+ "91.92.214.190",
+ "91.92.214.202",
+ "91.92.214.211",
+ "91.92.214.218",
+ "91.92.214.236",
+ "91.92.214.242",
+ "91.92.215.0",
+ "91.92.215.10",
+ "91.92.215.13",
+ "91.92.215.25",
+ "91.92.215.48",
+ "91.92.215.74",
+ "91.92.215.81",
+ "91.92.215.98",
+ "91.92.215.106",
+ "91.92.215.129",
+ "91.92.215.132",
+ "91.92.215.231",
+ "91.92.231.55",
+ "91.92.231.92",
+ "91.92.231.112",
+ "91.92.231.203",
+ "91.106.64.25",
+ "91.106.64.49",
+ "91.106.64.94",
+ "91.106.66.32",
+ "91.106.66.173",
+ "91.106.67.85",
+ "91.106.67.252",
+ "91.106.68.164",
+ "91.106.70.14",
+ "91.106.70.206",
+ "91.106.70.213",
+ "91.106.72.95",
+ "91.106.74.77",
+ "91.106.76.129",
+ "91.106.83.25",
+ "91.106.83.26",
+ "91.106.83.193",
+ "91.106.84.20",
+ "91.106.84.25",
+ "91.106.85.2",
+ "91.106.85.5",
+ "91.106.85.6",
+ "91.106.85.19",
+ "91.106.85.22",
+ "91.106.85.33",
+ "91.106.85.34",
+ "91.106.85.35",
+ "91.106.85.36",
+ "91.106.85.37",
+ "91.106.85.38",
+ "91.106.85.39",
+ "91.106.85.41",
+ "91.106.85.42",
+ "91.106.85.44",
+ "91.106.85.45",
+ "91.106.85.46",
+ "91.106.85.47",
+ "91.106.91.55",
+ "91.106.91.69",
+ "91.106.91.85",
+ "91.106.91.192",
+ "91.106.91.232",
+ "91.106.92.139",
+ "91.106.94.145",
+ "91.106.95.130",
+ "91.108.128.114",
+ "91.108.128.174",
+ "91.108.129.98",
+ "91.108.129.99",
+ "91.108.129.100",
+ "91.108.129.101",
+ "91.108.129.122",
+ "91.108.130.112",
+ "91.108.131.9",
+ "91.108.131.10",
+ "91.108.138.41",
+ "91.108.140.3",
+ "91.108.140.4",
+ "91.108.140.5",
+ "91.108.145.15",
+ "91.108.145.68",
+ "91.108.150.2",
+ "91.108.150.24",
+ "91.108.150.41",
+ "91.108.152.6",
+ "91.108.155.44",
+ "91.108.155.194",
+ "91.108.155.195",
+ "91.108.155.198",
+ "91.108.155.210",
+ "91.108.155.244",
+ "91.185.148.110",
+ "91.186.193.222",
+ "91.199.9.18",
+ "91.199.9.117",
+ "91.199.9.118",
+ "91.199.9.232",
+ "91.199.9.234",
+ "91.199.18.5",
+ "91.199.18.20",
+ "91.199.18.37",
+ "91.199.18.39",
+ "91.199.18.68",
+ "91.199.18.69",
+ "91.199.18.70",
+ "91.199.18.71",
+ "91.199.18.242",
+ "91.199.18.243",
+ "91.199.18.255",
+ "91.199.27.177",
+ "91.199.27.178",
+ "91.199.27.211",
+ "91.199.27.214",
+ "91.199.27.240",
+ "91.199.27.241",
+ "91.199.30.254",
+ "91.199.215.34",
+ "91.199.215.238",
+ "91.206.177.2",
+ "91.206.177.3",
+ "91.207.205.3",
+ "91.207.205.7",
+ "91.208.163.195",
+ "91.212.174.20",
+ "91.212.174.32",
+ "91.212.174.78",
+ "91.212.174.246",
+ "91.212.252.48",
+ "91.220.113.36",
+ "91.220.113.121",
+ "91.220.113.247",
+ "91.221.241.243",
+ "91.222.196.8",
+ "91.222.196.9",
+ "91.222.196.53",
+ "91.222.197.22",
+ "91.222.197.25",
+ "91.222.198.42",
+ "91.222.198.43",
+ "91.223.116.150",
+ "91.223.116.173",
+ "91.223.116.176",
+ "91.223.116.179",
+ "91.223.116.238",
+ "91.223.146.17",
+ "91.224.20.253",
+ "91.224.176.0",
+ "91.224.176.9",
+ "91.227.86.244",
+ "91.227.246.49",
+ "91.227.246.132",
+ "91.227.246.150",
+ "91.227.246.167",
+ "91.227.246.168",
+ "91.227.246.197",
+ "91.227.246.224",
+ "91.227.246.225",
+ "91.228.132.5",
+ "91.232.72.30",
+ "91.232.72.70",
+ "91.234.39.76",
+ "91.234.39.98",
+ "91.234.39.193",
+ "91.234.39.231",
+ "91.236.168.144",
+ "91.236.168.168",
+ "91.236.169.161",
+ "91.236.169.162",
+ "91.236.169.163",
+ "91.236.169.164",
+ "91.236.169.165",
+ "91.236.169.166",
+ "91.236.169.167",
+ "91.236.169.168",
+ "91.236.169.169",
+ "91.236.169.170",
+ "91.237.255.130",
+ "91.237.255.224",
+ "91.240.60.65",
+ "91.240.60.66",
+ "91.240.60.230",
+ "91.240.61.17",
+ "91.240.61.45",
+ "91.240.61.164",
+ "91.240.61.165",
+ "91.240.61.166",
+ "91.240.61.217",
+ "91.240.61.230",
+ "91.240.61.238",
+ "91.240.61.240",
+ "91.240.61.248",
+ "91.240.61.254",
+ "91.240.63.15",
+ "91.240.63.25",
+ "91.240.63.59",
+ "91.240.63.129",
+ "91.240.63.214",
+ "91.241.20.98",
+ "91.241.20.181",
+ "91.241.20.182",
+ "91.241.20.183",
+ "91.241.20.193",
+ "91.241.21.17",
+ "91.241.21.66",
+ "91.241.21.82",
+ "91.241.21.116",
+ "91.241.21.117",
+ "91.241.21.118",
+ "91.241.21.119",
+ "91.241.21.137",
+ "91.241.21.139",
+ "91.241.21.140",
+ "91.241.21.142",
+ "91.241.21.237",
+ "91.242.44.2",
+ "91.242.44.96",
+ "91.242.44.253",
+ "91.242.45.14",
+ "91.242.45.37",
+ "91.242.45.249",
+ "91.243.127.222",
+ "91.243.160.13",
+ "91.243.160.62",
+ "91.243.160.90",
+ "91.243.160.104",
+ "91.243.160.123",
+ "91.243.160.144",
+ "91.243.160.180",
+ "91.243.160.211",
+ "91.243.161.6",
+ "91.243.161.35",
+ "91.243.161.44",
+ "91.243.161.77",
+ "91.243.161.124",
+ "91.243.161.164",
+ "91.243.161.180",
+ "91.243.161.188",
+ "91.243.162.90",
+ "91.243.164.4",
+ "91.243.164.87",
+ "91.243.164.132",
+ "91.243.164.183",
+ "91.243.164.188",
+ "91.243.164.203",
+ "91.243.164.227",
+ "91.243.164.241",
+ "91.243.165.43",
+ "91.243.165.48",
+ "91.243.165.59",
+ "91.243.165.143",
+ "91.243.165.192",
+ "91.243.165.196",
+ "91.243.165.245",
+ "91.243.168.44",
+ "91.243.168.106",
+ "91.243.168.140",
+ "91.243.168.251",
+ "91.243.170.15",
+ "91.243.170.211",
+ "91.243.170.212",
+ "91.243.170.213",
+ "91.243.170.214",
+ "91.243.171.169",
+ "91.243.171.173",
+ "91.243.171.193",
+ "91.243.171.198",
+ "91.243.172.27",
+ "91.243.172.67",
+ "91.243.172.123",
+ "91.243.172.165",
+ "91.243.172.218",
+ "91.243.172.247",
+ "91.243.175.129",
+ "91.243.175.145",
+ "91.245.228.241",
+ "91.245.229.2",
+ "91.245.230.16",
+ "91.245.230.17",
+ "91.245.230.25",
+ "91.245.231.3",
+ "91.246.31.108",
+ "91.247.66.10",
+ "91.247.66.46",
+ "91.247.66.53",
+ "91.247.66.66",
+ "91.247.66.68",
+ "91.247.66.90",
+ "91.247.66.95",
+ "91.247.66.97",
+ "91.247.66.113",
+ "91.247.66.138",
+ "91.247.66.152",
+ "91.247.66.156",
+ "91.247.66.157",
+ "91.247.66.162",
+ "91.247.66.163",
+ "91.247.66.164",
+ "91.247.66.178",
+ "91.247.66.193",
+ "91.247.66.201",
+ "91.247.66.206",
+ "91.247.66.218",
+ "91.247.66.235",
+ "91.247.66.249",
+ "91.247.67.222",
+ "91.247.67.237",
+ "91.247.67.244",
+ "91.247.67.247",
+ "91.247.171.167",
+ "91.247.171.183",
+ "92.42.207.4",
+ "92.43.162.37",
+ "92.43.162.95",
+ "92.43.163.134",
+ "92.43.163.179",
+ "92.114.19.11",
+ "92.114.26.73",
+ "92.114.26.125",
+ "92.114.29.91",
+ "92.114.29.246",
+ "92.114.29.247",
+ "92.114.30.127",
+ "92.114.48.60",
+ "92.114.48.97",
+ "92.114.48.140",
+ "92.114.48.157",
+ "92.114.48.171",
+ "92.114.48.207",
+ "92.114.48.210",
+ "92.114.49.78",
+ "92.114.49.154",
+ "92.114.49.196",
+ "92.114.49.243",
+ "92.114.49.246",
+ "92.119.57.85",
+ "92.242.192.176",
+ "92.242.192.178",
+ "92.242.198.74",
+ "92.242.198.202",
+ "92.242.198.203",
+ "92.242.198.204",
+ "92.242.198.206",
+ "92.242.198.254",
+ "92.242.202.130",
+ "92.242.202.186",
+ "92.242.202.187",
+ "92.242.202.188",
+ "92.242.202.189",
+ "92.242.202.190",
+ "92.242.204.66",
+ "92.242.204.67",
+ "92.242.204.68",
+ "92.242.204.69",
+ "92.242.204.70",
+ "92.242.204.71",
+ "92.242.204.75",
+ "92.242.204.150",
+ "92.242.206.224",
+ "92.242.207.43",
+ "92.242.207.68",
+ "92.242.212.50",
+ "92.242.212.51",
+ "92.242.212.99",
+ "92.242.217.169",
+ "92.242.217.174",
+ "92.242.219.202",
+ "92.242.219.203",
+ "92.242.219.204",
+ "92.242.219.205",
+ "92.242.219.213",
+ "92.242.220.181",
+ "92.242.220.188",
+ "92.242.223.10",
+ "92.242.223.178",
+ "92.246.144.10",
+ "92.246.144.58",
+ "92.246.144.59",
+ "92.246.144.130",
+ "92.246.144.225",
+ "92.246.145.96",
+ "92.246.145.164",
+ "92.246.145.165",
+ "92.246.145.166",
+ "92.246.146.12",
+ "92.246.146.22",
+ "92.246.146.46",
+ "92.246.146.74",
+ "92.246.146.81",
+ "92.246.146.89",
+ "92.246.146.110",
+ "92.246.146.141",
+ "92.246.146.151",
+ "92.246.146.202",
+ "92.246.147.96",
+ "92.246.147.212",
+ "92.246.147.225",
+ "92.249.56.18",
+ "92.249.56.28",
+ "93.113.224.82",
+ "93.113.227.2",
+ "93.113.233.3",
+ "93.113.233.4",
+ "93.113.234.70",
+ "93.113.234.74",
+ "93.113.236.13",
+ "93.113.236.14",
+ "93.113.236.15",
+ "93.113.236.17",
+ "93.114.104.1",
+ "93.114.104.45",
+ "93.114.104.91",
+ "93.114.104.133",
+ "93.114.104.139",
+ "93.114.104.154",
+ "93.114.104.185",
+ "93.114.104.200",
+ "93.114.105.11",
+ "93.114.105.57",
+ "93.114.105.69",
+ "93.114.105.88",
+ "93.114.105.93",
+ "93.114.105.145",
+ "93.114.105.153",
+ "93.114.105.200",
+ "93.114.105.233",
+ "93.114.106.51",
+ "93.114.106.94",
+ "93.114.106.187",
+ "93.114.106.188",
+ "93.114.106.203",
+ "93.114.108.15",
+ "93.114.108.58",
+ "93.114.108.62",
+ "93.114.108.138",
+ "93.114.108.140",
+ "93.114.108.234",
+ "93.114.108.241",
+ "93.114.109.56",
+ "93.114.109.77",
+ "93.114.109.82",
+ "93.114.109.137",
+ "93.114.109.140",
+ "93.114.109.158",
+ "93.114.109.204",
+ "93.114.110.11",
+ "93.114.110.92",
+ "93.114.110.123",
+ "93.114.110.166",
+ "93.114.110.193",
+ "93.114.110.196",
+ "93.114.110.218",
+ "93.114.110.224",
+ "93.114.111.49",
+ "93.114.111.125",
+ "93.114.111.147",
+ "93.114.111.216",
+ "93.114.111.244",
+ "93.115.120.4",
+ "93.115.120.98",
+ "93.115.120.168",
+ "93.115.120.181",
+ "93.115.120.231",
+ "93.115.121.0",
+ "93.115.121.62",
+ "93.115.121.68",
+ "93.115.121.79",
+ "93.115.121.106",
+ "93.115.121.161",
+ "93.115.121.223",
+ "93.115.121.229",
+ "93.115.122.8",
+ "93.115.122.104",
+ "93.115.122.144",
+ "93.115.122.171",
+ "93.115.123.15",
+ "93.115.123.240",
+ "93.115.124.114",
+ "93.115.124.131",
+ "93.115.124.189",
+ "93.115.124.191",
+ "93.115.124.200",
+ "93.115.124.230",
+ "93.115.124.236",
+ "93.115.125.21",
+ "93.115.125.53",
+ "93.115.125.106",
+ "93.115.125.123",
+ "93.115.125.125",
+ "93.115.125.157",
+ "93.115.125.158",
+ "93.115.125.171",
+ "93.115.125.179",
+ "93.115.125.221",
+ "93.115.125.252",
+ "93.115.126.1",
+ "93.115.126.157",
+ "93.115.126.183",
+ "93.115.126.223",
+ "93.115.126.224",
+ "93.115.126.244",
+ "93.115.127.71",
+ "93.115.127.75",
+ "93.115.127.119",
+ "93.115.127.220",
+ "93.115.144.1",
+ "93.115.144.4",
+ "93.115.144.13",
+ "93.115.144.40",
+ "93.115.144.45",
+ "93.115.144.50",
+ "93.115.144.62",
+ "93.115.144.81",
+ "93.115.144.88",
+ "93.115.144.121",
+ "93.115.144.130",
+ "93.115.144.134",
+ "93.115.144.137",
+ "93.115.144.159",
+ "93.115.144.167",
+ "93.115.144.193",
+ "93.115.144.195",
+ "93.115.144.210",
+ "93.115.144.214",
+ "93.115.144.220",
+ "93.115.144.234",
+ "93.115.144.246",
+ "93.115.145.22",
+ "93.115.145.25",
+ "93.115.145.30",
+ "93.115.145.71",
+ "93.115.145.83",
+ "93.115.145.94",
+ "93.115.145.105",
+ "93.115.145.125",
+ "93.115.145.141",
+ "93.115.145.185",
+ "93.115.145.198",
+ "93.115.145.229",
+ "93.115.145.239",
+ "93.115.146.4",
+ "93.115.146.17",
+ "93.115.146.52",
+ "93.115.146.53",
+ "93.115.146.74",
+ "93.115.146.81",
+ "93.115.146.178",
+ "93.115.146.215",
+ "93.115.146.219",
+ "93.115.146.234",
+ "93.115.146.237",
+ "93.115.147.71",
+ "93.115.147.113",
+ "93.115.147.115",
+ "93.115.147.122",
+ "93.115.147.126",
+ "93.115.147.189",
+ "93.115.147.215",
+ "93.115.147.218",
+ "93.115.147.225",
+ "93.115.147.230",
+ "93.115.148.16",
+ "93.115.148.27",
+ "93.115.148.29",
+ "93.115.148.47",
+ "93.115.148.64",
+ "93.115.148.66",
+ "93.115.148.82",
+ "93.115.148.102",
+ "93.115.148.129",
+ "93.115.148.136",
+ "93.115.148.156",
+ "93.115.148.165",
+ "93.115.148.186",
+ "93.115.148.189",
+ "93.115.148.207",
+ "93.115.148.211",
+ "93.115.148.237",
+ "93.115.148.248",
+ "93.115.149.8",
+ "93.115.149.10",
+ "93.115.149.29",
+ "93.115.149.49",
+ "93.115.149.54",
+ "93.115.149.57",
+ "93.115.149.58",
+ "93.115.149.75",
+ "93.115.149.86",
+ "93.115.149.92",
+ "93.115.149.136",
+ "93.115.149.166",
+ "93.115.149.173",
+ "93.115.149.178",
+ "93.115.149.198",
+ "93.115.149.207",
+ "93.115.149.230",
+ "93.115.150.30",
+ "93.115.151.130",
+ "93.115.151.131",
+ "93.115.151.132",
+ "93.115.151.133",
+ "93.115.151.136",
+ "93.115.151.137",
+ "93.115.151.139",
+ "93.115.151.140",
+ "93.115.151.141",
+ "93.115.151.143",
+ "93.115.151.144",
+ "93.115.151.148",
+ "93.115.151.153",
+ "93.115.151.155",
+ "93.115.151.157",
+ "93.115.151.158",
+ "93.115.151.160",
+ "93.115.151.161",
+ "93.115.151.162",
+ "93.115.151.163",
+ "93.115.151.164",
+ "93.115.151.166",
+ "93.115.151.170",
+ "93.115.151.180",
+ "93.115.151.181",
+ "93.115.151.182",
+ "93.115.151.183",
+ "93.115.151.184",
+ "93.115.151.185",
+ "93.115.151.186",
+ "93.115.151.188",
+ "93.115.151.189",
+ "93.115.151.190",
+ "93.117.0.57",
+ "93.117.0.248",
+ "93.117.4.197",
+ "93.117.7.237",
+ "93.117.10.108",
+ "93.117.11.67",
+ "93.117.13.70",
+ "93.117.14.55",
+ "93.117.16.212",
+ "93.117.19.20",
+ "93.117.20.234",
+ "93.117.23.104",
+ "93.117.23.251",
+ "93.117.24.200",
+ "93.117.28.7",
+ "93.117.28.137",
+ "93.117.31.137",
+ "93.117.33.30",
+ "93.117.33.209",
+ "93.117.33.239",
+ "93.117.34.68",
+ "93.117.35.213",
+ "93.117.36.21",
+ "93.117.36.179",
+ "93.117.37.169",
+ "93.117.38.3",
+ "93.117.39.183",
+ "93.117.40.249",
+ "93.117.42.5",
+ "93.117.42.113",
+ "93.117.42.253",
+ "93.117.43.51",
+ "93.117.43.72",
+ "93.117.44.18",
+ "93.117.44.23",
+ "93.117.44.93",
+ "93.117.44.135",
+ "93.117.46.170",
+ "93.117.46.171",
+ "93.117.46.214",
+ "93.117.97.109",
+ "93.117.127.70",
+ "93.117.127.73",
+ "93.117.127.91",
+ "93.117.127.107",
+ "93.117.127.164",
+ "93.117.127.218",
+ "93.118.96.24",
+ "93.118.96.35",
+ "93.118.96.68",
+ "93.118.96.188",
+ "93.118.96.210",
+ "93.118.97.33",
+ "93.118.97.63",
+ "93.118.97.88",
+ "93.118.97.92",
+ "93.118.97.121",
+ "93.118.97.135",
+ "93.118.97.147",
+ "93.118.98.13",
+ "93.118.98.90",
+ "93.118.98.119",
+ "93.118.98.244",
+ "93.118.99.20",
+ "93.118.99.31",
+ "93.118.99.74",
+ "93.118.99.150",
+ "93.118.100.139",
+ "93.118.100.158",
+ "93.118.101.10",
+ "93.118.101.25",
+ "93.118.101.48",
+ "93.118.101.94",
+ "93.118.101.129",
+ "93.118.101.139",
+ "93.118.101.153",
+ "93.118.101.154",
+ "93.118.101.155",
+ "93.118.101.179",
+ "93.118.101.232",
+ "93.118.101.243",
+ "93.118.102.6",
+ "93.118.103.45",
+ "93.118.103.208",
+ "93.118.105.62",
+ "93.118.105.139",
+ "93.118.105.144",
+ "93.118.105.170",
+ "93.118.105.178",
+ "93.118.106.95",
+ "93.118.106.99",
+ "93.118.106.182",
+ "93.118.107.84",
+ "93.118.108.18",
+ "93.118.108.32",
+ "93.118.108.90",
+ "93.118.108.146",
+ "93.118.108.177",
+ "93.118.108.216",
+ "93.118.108.225",
+ "93.118.108.232",
+ "93.118.109.52",
+ "93.118.109.58",
+ "93.118.109.61",
+ "93.118.109.82",
+ "93.118.109.117",
+ "93.118.109.127",
+ "93.118.109.140",
+ "93.118.109.167",
+ "93.118.109.200",
+ "93.118.110.10",
+ "93.118.110.24",
+ "93.118.110.43",
+ "93.118.110.73",
+ "93.118.110.100",
+ "93.118.110.156",
+ "93.118.110.190",
+ "93.118.110.215",
+ "93.118.110.216",
+ "93.118.110.231",
+ "93.118.110.235",
+ "93.118.111.49",
+ "93.118.111.64",
+ "93.118.111.109",
+ "93.118.112.17",
+ "93.118.112.19",
+ "93.118.112.31",
+ "93.118.112.46",
+ "93.118.112.62",
+ "93.118.112.102",
+ "93.118.112.145",
+ "93.118.112.161",
+ "93.118.112.191",
+ "93.118.112.236",
+ "93.118.113.23",
+ "93.118.113.133",
+ "93.118.113.152",
+ "93.118.113.224",
+ "93.118.114.59",
+ "93.118.114.127",
+ "93.118.114.138",
+ "93.118.114.165",
+ "93.118.114.196",
+ "93.118.114.240",
+ "93.118.115.13",
+ "93.118.115.43",
+ "93.118.115.45",
+ "93.118.115.108",
+ "93.118.115.112",
+ "93.118.115.131",
+ "93.118.115.138",
+ "93.118.115.143",
+ "93.118.115.171",
+ "93.118.115.207",
+ "93.118.115.216",
+ "93.118.115.234",
+ "93.118.115.236",
+ "93.118.115.240",
+ "93.118.116.33",
+ "93.118.116.37",
+ "93.118.116.66",
+ "93.118.116.127",
+ "93.118.116.138",
+ "93.118.116.174",
+ "93.118.116.239",
+ "93.118.116.247",
+ "93.118.117.31",
+ "93.118.117.50",
+ "93.118.117.97",
+ "93.118.117.122",
+ "93.118.117.129",
+ "93.118.117.177",
+ "93.118.119.87",
+ "93.118.119.110",
+ "93.118.119.117",
+ "93.118.119.169",
+ "93.118.119.223",
+ "93.118.120.5",
+ "93.118.120.93",
+ "93.118.120.119",
+ "93.118.120.133",
+ "93.118.120.139",
+ "93.118.120.148",
+ "93.118.120.207",
+ "93.118.120.214",
+ "93.118.121.32",
+ "93.118.122.17",
+ "93.118.122.34",
+ "93.118.122.126",
+ "93.118.122.154",
+ "93.118.123.9",
+ "93.118.123.11",
+ "93.118.123.70",
+ "93.118.123.83",
+ "93.118.123.101",
+ "93.118.123.121",
+ "93.118.123.155",
+ "93.118.123.176",
+ "93.118.123.177",
+ "93.118.123.196",
+ "93.118.123.211",
+ "93.118.123.218",
+ "93.118.123.229",
+ "93.118.124.38",
+ "93.118.124.182",
+ "93.118.124.254",
+ "93.118.125.5",
+ "93.118.125.28",
+ "93.118.125.34",
+ "93.118.125.143",
+ "93.118.125.201",
+ "93.118.125.205",
+ "93.118.126.23",
+ "93.118.126.41",
+ "93.118.126.100",
+ "93.118.126.107",
+ "93.118.126.170",
+ "93.118.126.205",
+ "93.118.126.229",
+ "93.118.126.251",
+ "93.118.127.10",
+ "93.118.127.49",
+ "93.118.127.54",
+ "93.118.127.60",
+ "93.118.127.182",
+ "93.118.127.206",
+ "93.118.127.230",
+ "93.118.127.249",
+ "93.118.128.27",
+ "93.118.128.37",
+ "93.118.128.38",
+ "93.118.128.56",
+ "93.118.128.66",
+ "93.118.128.101",
+ "93.118.128.104",
+ "93.118.128.124",
+ "93.118.129.28",
+ "93.118.129.96",
+ "93.118.129.191",
+ "93.118.130.149",
+ "93.118.130.183",
+ "93.118.130.185",
+ "93.118.130.243",
+ "93.118.131.12",
+ "93.118.131.106",
+ "93.118.132.12",
+ "93.118.132.41",
+ "93.118.132.213",
+ "93.118.133.12",
+ "93.118.133.69",
+ "93.118.133.170",
+ "93.118.133.198",
+ "93.118.133.212",
+ "93.118.134.13",
+ "93.118.135.61",
+ "93.118.135.97",
+ "93.118.135.103",
+ "93.118.135.170",
+ "93.118.135.225",
+ "93.118.136.25",
+ "93.118.136.36",
+ "93.118.136.44",
+ "93.118.136.83",
+ "93.118.136.169",
+ "93.118.136.203",
+ "93.118.136.207",
+ "93.118.136.232",
+ "93.118.137.14",
+ "93.118.137.38",
+ "93.118.137.49",
+ "93.118.137.65",
+ "93.118.137.91",
+ "93.118.137.98",
+ "93.118.137.221",
+ "93.118.138.36",
+ "93.118.138.52",
+ "93.118.138.73",
+ "93.118.138.88",
+ "93.118.138.114",
+ "93.118.138.223",
+ "93.118.138.246",
+ "93.118.139.36",
+ "93.118.139.84",
+ "93.118.139.90",
+ "93.118.139.97",
+ "93.118.139.130",
+ "93.118.139.144",
+ "93.118.139.145",
+ "93.118.139.151",
+ "93.118.139.155",
+ "93.118.139.210",
+ "93.118.139.246",
+ "93.118.140.18",
+ "93.118.140.56",
+ "93.118.140.70",
+ "93.118.140.102",
+ "93.118.140.148",
+ "93.118.140.152",
+ "93.118.140.196",
+ "93.118.140.209",
+ "93.118.140.211",
+ "93.118.140.224",
+ "93.118.140.225",
+ "93.118.141.27",
+ "93.118.141.188",
+ "93.118.141.201",
+ "93.118.141.232",
+ "93.118.141.252",
+ "93.118.142.209",
+ "93.118.142.222",
+ "93.118.143.2",
+ "93.118.143.9",
+ "93.118.143.64",
+ "93.118.143.67",
+ "93.118.143.86",
+ "93.118.143.89",
+ "93.118.143.95",
+ "93.118.143.97",
+ "93.118.143.111",
+ "93.118.143.112",
+ "93.118.143.143",
+ "93.118.143.155",
+ "93.118.143.195",
+ "93.118.143.211",
+ "93.118.143.226",
+ "93.118.143.231",
+ "93.118.144.0",
+ "93.118.144.16",
+ "93.118.144.41",
+ "93.118.144.74",
+ "93.118.144.114",
+ "93.118.144.119",
+ "93.118.144.124",
+ "93.118.144.141",
+ "93.118.144.168",
+ "93.118.144.228",
+ "93.118.144.242",
+ "93.118.145.25",
+ "93.118.145.213",
+ "93.118.145.245",
+ "93.118.145.248",
+ "93.118.146.59",
+ "93.118.146.88",
+ "93.118.146.176",
+ "93.118.146.253",
+ "93.118.147.14",
+ "93.118.147.158",
+ "93.118.147.176",
+ "93.118.147.180",
+ "93.118.147.193",
+ "93.118.148.1",
+ "93.118.148.7",
+ "93.118.148.26",
+ "93.118.148.30",
+ "93.118.148.34",
+ "93.118.148.70",
+ "93.118.148.118",
+ "93.118.148.140",
+ "93.118.148.189",
+ "93.118.148.199",
+ "93.118.149.228",
+ "93.118.150.42",
+ "93.118.151.217",
+ "93.118.151.236",
+ "93.118.151.249",
+ "93.118.152.46",
+ "93.118.152.81",
+ "93.118.152.168",
+ "93.118.152.177",
+ "93.118.152.247",
+ "93.118.152.253",
+ "93.118.153.92",
+ "93.118.153.104",
+ "93.118.153.108",
+ "93.118.153.109",
+ "93.118.153.110",
+ "93.118.153.119",
+ "93.118.153.126",
+ "93.118.153.131",
+ "93.118.153.137",
+ "93.118.153.157",
+ "93.118.153.229",
+ "93.118.153.252",
+ "93.118.154.12",
+ "93.118.154.56",
+ "93.118.154.174",
+ "93.118.154.188",
+ "93.118.154.205",
+ "93.118.154.225",
+ "93.118.154.226",
+ "93.118.155.66",
+ "93.118.155.69",
+ "93.118.155.100",
+ "93.118.155.109",
+ "93.118.156.42",
+ "93.118.156.46",
+ "93.118.156.78",
+ "93.118.156.149",
+ "93.118.156.176",
+ "93.118.157.57",
+ "93.118.157.146",
+ "93.118.157.210",
+ "93.118.157.223",
+ "93.118.158.0",
+ "93.118.158.20",
+ "93.118.158.37",
+ "93.118.158.78",
+ "93.118.158.92",
+ "93.118.158.166",
+ "93.118.158.172",
+ "93.118.158.204",
+ "93.118.159.64",
+ "93.118.159.114",
+ "93.118.159.149",
+ "93.118.159.200",
+ "93.118.160.27",
+ "93.118.160.109",
+ "93.118.160.123",
+ "93.118.160.175",
+ "93.118.160.189",
+ "93.118.160.213",
+ "93.118.161.8",
+ "93.118.161.30",
+ "93.118.161.39",
+ "93.118.161.69",
+ "93.118.161.71",
+ "93.118.161.168",
+ "93.118.161.225",
+ "93.118.161.228",
+ "93.118.161.233",
+ "93.118.162.13",
+ "93.118.162.161",
+ "93.118.163.9",
+ "93.118.163.140",
+ "93.118.163.146",
+ "93.118.163.230",
+ "93.118.163.252",
+ "93.118.164.28",
+ "93.118.164.41",
+ "93.118.164.59",
+ "93.118.164.183",
+ "93.118.164.199",
+ "93.118.165.55",
+ "93.118.165.136",
+ "93.118.165.182",
+ "93.118.166.36",
+ "93.118.166.62",
+ "93.118.166.73",
+ "93.118.166.131",
+ "93.118.166.150",
+ "93.118.166.193",
+ "93.118.166.235",
+ "93.118.166.245",
+ "93.118.167.33",
+ "93.118.167.58",
+ "93.118.167.64",
+ "93.118.167.147",
+ "93.118.167.152",
+ "93.118.167.176",
+ "93.118.167.208",
+ "93.118.167.219",
+ "93.118.167.223",
+ "93.118.167.236",
+ "93.118.180.129",
+ "93.118.180.245",
+ "93.118.181.27",
+ "93.118.181.112",
+ "93.118.181.114",
+ "93.118.181.149",
+ "93.118.181.225",
+ "93.118.181.238",
+ "93.118.182.9",
+ "93.118.182.21",
+ "93.118.182.35",
+ "93.118.182.63",
+ "93.118.183.167",
+ "93.118.183.188",
+ "93.119.54.205",
+ "93.126.2.252",
+ "93.126.3.22",
+ "93.126.3.98",
+ "93.126.3.229",
+ "93.126.4.73",
+ "93.126.5.81",
+ "93.126.5.94",
+ "93.126.5.106",
+ "93.126.5.127",
+ "93.126.6.39",
+ "93.126.6.61",
+ "93.126.7.168",
+ "93.126.8.121",
+ "93.126.9.1",
+ "93.126.9.2",
+ "93.126.9.3",
+ "93.126.9.10",
+ "93.126.9.57",
+ "93.126.9.86",
+ "93.126.9.153",
+ "93.126.9.166",
+ "93.126.9.186",
+ "93.126.9.233",
+ "93.126.9.234",
+ "93.126.9.235",
+ "93.126.9.236",
+ "93.126.9.237",
+ "93.126.9.238",
+ "93.126.10.17",
+ "93.126.10.70",
+ "93.126.11.234",
+ "93.126.12.22",
+ "93.126.12.254",
+ "93.126.13.84",
+ "93.126.13.132",
+ "93.126.15.129",
+ "93.126.17.130",
+ "93.126.19.246",
+ "93.126.20.107",
+ "93.126.21.4",
+ "93.126.21.57",
+ "93.126.21.58",
+ "93.126.21.117",
+ "93.126.25.33",
+ "93.126.29.14",
+ "93.126.29.44",
+ "93.126.29.53",
+ "93.126.29.64",
+ "93.126.29.96",
+ "93.126.29.108",
+ "93.126.29.109",
+ "93.126.31.140",
+ "93.126.31.161",
+ "93.126.34.81",
+ "93.126.40.7",
+ "93.126.40.17",
+ "93.126.40.18",
+ "93.126.40.19",
+ "93.126.40.22",
+ "93.126.40.23",
+ "93.126.40.24",
+ "93.126.40.30",
+ "93.126.40.67",
+ "93.126.40.68",
+ "93.126.40.69",
+ "93.126.40.70",
+ "93.126.40.71",
+ "93.126.40.72",
+ "93.126.40.73",
+ "93.126.40.76",
+ "93.126.41.0",
+ "93.126.41.1",
+ "93.126.41.2",
+ "93.126.41.3",
+ "93.126.41.4",
+ "93.126.41.6",
+ "93.126.41.7",
+ "93.126.41.8",
+ "93.126.41.9",
+ "93.126.41.11",
+ "93.126.41.12",
+ "93.126.41.13",
+ "93.126.41.14",
+ "93.126.41.15",
+ "93.126.41.16",
+ "93.126.41.17",
+ "93.126.41.18",
+ "93.126.41.19",
+ "93.126.41.20",
+ "93.126.41.23",
+ "93.126.41.24",
+ "93.126.41.26",
+ "93.126.41.27",
+ "93.126.41.28",
+ "93.126.41.29",
+ "93.126.41.30",
+ "93.126.41.31",
+ "93.126.41.34",
+ "93.126.41.35",
+ "93.126.41.36",
+ "93.126.41.37",
+ "93.126.41.38",
+ "93.126.41.39",
+ "93.126.41.40",
+ "93.126.41.41",
+ "93.126.41.42",
+ "93.126.41.44",
+ "93.126.41.45",
+ "93.126.41.46",
+ "93.126.41.47",
+ "93.126.41.48",
+ "93.126.41.49",
+ "93.126.41.50",
+ "93.126.41.51",
+ "93.126.41.52",
+ "93.126.41.53",
+ "93.126.41.55",
+ "93.126.41.56",
+ "93.126.41.57",
+ "93.126.41.58",
+ "93.126.41.60",
+ "93.126.41.61",
+ "93.126.41.62",
+ "93.126.41.63",
+ "93.126.41.64",
+ "93.126.41.65",
+ "93.126.41.66",
+ "93.126.41.67",
+ "93.126.41.68",
+ "93.126.41.69",
+ "93.126.41.70",
+ "93.126.41.71",
+ "93.126.41.72",
+ "93.126.41.73",
+ "93.126.41.74",
+ "93.126.41.76",
+ "93.126.41.77",
+ "93.126.41.78",
+ "93.126.41.80",
+ "93.126.41.81",
+ "93.126.41.82",
+ "93.126.41.83",
+ "93.126.41.84",
+ "93.126.41.85",
+ "93.126.41.86",
+ "93.126.41.87",
+ "93.126.41.88",
+ "93.126.41.89",
+ "93.126.41.90",
+ "93.126.41.91",
+ "93.126.41.92",
+ "93.126.41.93",
+ "93.126.41.95",
+ "93.126.41.96",
+ "93.126.41.97",
+ "93.126.41.99",
+ "93.126.41.100",
+ "93.126.41.101",
+ "93.126.41.102",
+ "93.126.41.103",
+ "93.126.41.104",
+ "93.126.41.105",
+ "93.126.41.106",
+ "93.126.41.107",
+ "93.126.41.108",
+ "93.126.41.109",
+ "93.126.41.110",
+ "93.126.41.111",
+ "93.126.41.112",
+ "93.126.41.113",
+ "93.126.41.114",
+ "93.126.41.115",
+ "93.126.41.116",
+ "93.126.41.117",
+ "93.126.41.118",
+ "93.126.41.119",
+ "93.126.41.120",
+ "93.126.41.121",
+ "93.126.41.122",
+ "93.126.41.123",
+ "93.126.41.124",
+ "93.126.41.125",
+ "93.126.41.126",
+ "93.126.41.127",
+ "93.126.41.128",
+ "93.126.41.129",
+ "93.126.41.130",
+ "93.126.41.131",
+ "93.126.41.132",
+ "93.126.41.133",
+ "93.126.41.134",
+ "93.126.41.135",
+ "93.126.41.136",
+ "93.126.41.137",
+ "93.126.41.138",
+ "93.126.41.139",
+ "93.126.41.140",
+ "93.126.41.141",
+ "93.126.41.142",
+ "93.126.41.143",
+ "93.126.41.144",
+ "93.126.41.145",
+ "93.126.41.147",
+ "93.126.41.148",
+ "93.126.41.149",
+ "93.126.41.150",
+ "93.126.41.151",
+ "93.126.41.153",
+ "93.126.41.154",
+ "93.126.41.155",
+ "93.126.41.156",
+ "93.126.41.157",
+ "93.126.41.158",
+ "93.126.41.159",
+ "93.126.41.160",
+ "93.126.41.161",
+ "93.126.41.163",
+ "93.126.41.164",
+ "93.126.41.165",
+ "93.126.41.166",
+ "93.126.41.167",
+ "93.126.41.168",
+ "93.126.41.169",
+ "93.126.41.170",
+ "93.126.41.171",
+ "93.126.41.172",
+ "93.126.41.173",
+ "93.126.41.174",
+ "93.126.41.175",
+ "93.126.41.176",
+ "93.126.41.177",
+ "93.126.41.178",
+ "93.126.41.179",
+ "93.126.41.180",
+ "93.126.41.181",
+ "93.126.41.182",
+ "93.126.41.183",
+ "93.126.41.184",
+ "93.126.41.185",
+ "93.126.41.186",
+ "93.126.41.187",
+ "93.126.41.188",
+ "93.126.41.189",
+ "93.126.41.190",
+ "93.126.41.192",
+ "93.126.41.193",
+ "93.126.41.194",
+ "93.126.41.195",
+ "93.126.41.196",
+ "93.126.41.198",
+ "93.126.41.200",
+ "93.126.41.201",
+ "93.126.41.202",
+ "93.126.41.203",
+ "93.126.41.204",
+ "93.126.41.205",
+ "93.126.41.207",
+ "93.126.41.208",
+ "93.126.41.210",
+ "93.126.41.211",
+ "93.126.41.212",
+ "93.126.41.213",
+ "93.126.41.214",
+ "93.126.41.215",
+ "93.126.41.216",
+ "93.126.41.217",
+ "93.126.41.218",
+ "93.126.41.219",
+ "93.126.41.220",
+ "93.126.41.221",
+ "93.126.41.222",
+ "93.126.41.223",
+ "93.126.41.225",
+ "93.126.41.226",
+ "93.126.41.227",
+ "93.126.41.228",
+ "93.126.41.229",
+ "93.126.41.230",
+ "93.126.41.231",
+ "93.126.41.232",
+ "93.126.41.233",
+ "93.126.41.234",
+ "93.126.41.235",
+ "93.126.41.236",
+ "93.126.41.237",
+ "93.126.41.238",
+ "93.126.41.239",
+ "93.126.44.161",
+ "93.126.44.162",
+ "93.126.44.163",
+ "93.126.44.164",
+ "93.126.44.165",
+ "93.126.44.166",
+ "93.126.44.167",
+ "93.126.44.169",
+ "93.126.44.170",
+ "93.126.49.151",
+ "93.126.51.142",
+ "93.126.51.144",
+ "93.126.51.179",
+ "93.126.57.4",
+ "93.126.58.43",
+ "93.126.58.69",
+ "93.126.58.245",
+ "94.74.128.169",
+ "94.74.128.185",
+ "94.74.128.251",
+ "94.74.129.52",
+ "94.74.130.172",
+ "94.74.132.135",
+ "94.74.133.174",
+ "94.74.133.178",
+ "94.74.135.180",
+ "94.74.136.120",
+ "94.74.136.145",
+ "94.74.136.187",
+ "94.74.136.240",
+ "94.74.138.44",
+ "94.74.138.54",
+ "94.74.138.123",
+ "94.74.138.124",
+ "94.74.138.146",
+ "94.74.138.174",
+ "94.74.138.201",
+ "94.74.138.210",
+ "94.74.138.226",
+ "94.74.139.44",
+ "94.74.139.149",
+ "94.74.139.168",
+ "94.74.139.216",
+ "94.74.139.252",
+ "94.74.141.70",
+ "94.74.141.176",
+ "94.74.142.165",
+ "94.74.144.14",
+ "94.74.144.25",
+ "94.74.144.31",
+ "94.74.144.166",
+ "94.74.145.2",
+ "94.74.145.28",
+ "94.74.145.110",
+ "94.74.146.192",
+ "94.74.146.200",
+ "94.74.146.251",
+ "94.74.149.5",
+ "94.74.149.71",
+ "94.74.150.75",
+ "94.74.150.184",
+ "94.74.151.34",
+ "94.74.160.61",
+ "94.74.160.86",
+ "94.74.160.88",
+ "94.74.161.41",
+ "94.74.161.51",
+ "94.74.161.101",
+ "94.74.161.166",
+ "94.74.161.169",
+ "94.74.161.237",
+ "94.74.161.251",
+ "94.74.163.22",
+ "94.74.163.185",
+ "94.74.163.186",
+ "94.74.165.190",
+ "94.74.166.42",
+ "94.74.166.99",
+ "94.74.167.161",
+ "94.74.168.200",
+ "94.74.168.201",
+ "94.74.168.202",
+ "94.74.168.203",
+ "94.74.168.206",
+ "94.74.169.9",
+ "94.74.169.10",
+ "94.74.169.29",
+ "94.74.169.30",
+ "94.74.172.64",
+ "94.74.172.104",
+ "94.74.172.155",
+ "94.74.172.173",
+ "94.74.174.73",
+ "94.74.174.122",
+ "94.74.174.232",
+ "94.74.174.235",
+ "94.74.175.55",
+ "94.74.177.157",
+ "94.74.177.220",
+ "94.74.178.235",
+ "94.74.179.219",
+ "94.74.180.242",
+ "94.74.183.30",
+ "94.74.183.32",
+ "94.74.183.196",
+ "94.74.186.1",
+ "94.74.186.9",
+ "94.74.186.53",
+ "94.74.186.103",
+ "94.74.186.187",
+ "94.74.188.48",
+ "94.74.188.53",
+ "94.74.188.151",
+ "94.74.188.199",
+ "94.74.188.210",
+ "94.74.190.92",
+ "94.101.128.11",
+ "94.101.128.124",
+ "94.101.128.174",
+ "94.101.129.174",
+ "94.101.131.160",
+ "94.101.131.176",
+ "94.101.132.45",
+ "94.101.133.28",
+ "94.101.133.133",
+ "94.101.133.192",
+ "94.101.140.10",
+ "94.101.177.11",
+ "94.101.177.92",
+ "94.101.178.227",
+ "94.101.179.5",
+ "94.101.179.22",
+ "94.101.179.216",
+ "94.101.180.83",
+ "94.101.180.180",
+ "94.101.184.113",
+ "94.101.185.66",
+ "94.101.185.103",
+ "94.101.185.253",
+ "94.101.186.9",
+ "94.101.186.145",
+ "94.101.187.203",
+ "94.139.180.63",
+ "94.139.180.84",
+ "94.139.180.131",
+ "94.139.182.140",
+ "94.139.183.152",
+ "94.139.183.153",
+ "94.139.191.205",
+ "94.139.191.216",
+ "94.182.0.43",
+ "94.182.0.131",
+ "94.182.0.152",
+ "94.182.0.217",
+ "94.182.1.188",
+ "94.182.1.195",
+ "94.182.1.227",
+ "94.182.2.14",
+ "94.182.2.48",
+ "94.182.2.99",
+ "94.182.2.110",
+ "94.182.2.126",
+ "94.182.2.174",
+ "94.182.2.193",
+ "94.182.2.245",
+ "94.182.10.166",
+ "94.182.16.81",
+ "94.182.16.82",
+ "94.182.16.83",
+ "94.182.16.84",
+ "94.182.16.85",
+ "94.182.16.86",
+ "94.182.16.87",
+ "94.182.16.88",
+ "94.182.16.90",
+ "94.182.17.163",
+ "94.182.18.5",
+ "94.182.18.26",
+ "94.182.18.46",
+ "94.182.18.118",
+ "94.182.18.137",
+ "94.182.18.150",
+ "94.182.18.162",
+ "94.182.18.191",
+ "94.182.18.207",
+ "94.182.18.208",
+ "94.182.18.210",
+ "94.182.18.225",
+ "94.182.18.248",
+ "94.182.18.251",
+ "94.182.19.97",
+ "94.182.20.8",
+ "94.182.20.22",
+ "94.182.22.18",
+ "94.182.22.20",
+ "94.182.22.24",
+ "94.182.22.26",
+ "94.182.22.31",
+ "94.182.26.26",
+ "94.182.26.28",
+ "94.182.26.58",
+ "94.182.26.82",
+ "94.182.27.58",
+ "94.182.27.101",
+ "94.182.27.102",
+ "94.182.27.103",
+ "94.182.27.107",
+ "94.182.27.142",
+ "94.182.27.230",
+ "94.182.31.3",
+ "94.182.31.13",
+ "94.182.31.25",
+ "94.182.31.37",
+ "94.182.31.57",
+ "94.182.31.61",
+ "94.182.31.68",
+ "94.182.31.73",
+ "94.182.31.91",
+ "94.182.31.98",
+ "94.182.31.106",
+ "94.182.31.112",
+ "94.182.31.119",
+ "94.182.31.123",
+ "94.182.31.126",
+ "94.182.31.130",
+ "94.182.31.143",
+ "94.182.31.148",
+ "94.182.31.165",
+ "94.182.31.175",
+ "94.182.31.180",
+ "94.182.31.183",
+ "94.182.31.187",
+ "94.182.34.59",
+ "94.182.35.22",
+ "94.182.35.86",
+ "94.182.35.150",
+ "94.182.35.167",
+ "94.182.35.187",
+ "94.182.35.201",
+ "94.182.35.210",
+ "94.182.35.246",
+ "94.182.35.247",
+ "94.182.35.253",
+ "94.182.36.26",
+ "94.182.36.121",
+ "94.182.36.134",
+ "94.182.36.182",
+ "94.182.36.192",
+ "94.182.36.202",
+ "94.182.36.214",
+ "94.182.36.225",
+ "94.182.36.231",
+ "94.182.36.251",
+ "94.182.37.9",
+ "94.182.37.113",
+ "94.182.37.163",
+ "94.182.37.213",
+ "94.182.37.234",
+ "94.182.38.2",
+ "94.182.38.74",
+ "94.182.38.88",
+ "94.182.38.89",
+ "94.182.38.90",
+ "94.182.38.91",
+ "94.182.38.113",
+ "94.182.39.195",
+ "94.182.39.224",
+ "94.182.39.225",
+ "94.182.39.226",
+ "94.182.39.227",
+ "94.182.39.228",
+ "94.182.39.229",
+ "94.182.39.231",
+ "94.182.39.232",
+ "94.182.39.233",
+ "94.182.39.234",
+ "94.182.39.235",
+ "94.182.39.236",
+ "94.182.39.237",
+ "94.182.39.238",
+ "94.182.39.239",
+ "94.182.42.7",
+ "94.182.42.8",
+ "94.182.43.2",
+ "94.182.43.30",
+ "94.182.43.86",
+ "94.182.44.157",
+ "94.182.44.174",
+ "94.182.46.46",
+ "94.182.46.197",
+ "94.182.47.138",
+ "94.182.48.4",
+ "94.182.48.11",
+ "94.182.48.14",
+ "94.182.48.49",
+ "94.182.48.50",
+ "94.182.48.69",
+ "94.182.48.70",
+ "94.182.48.71",
+ "94.182.49.6",
+ "94.182.49.54",
+ "94.182.49.106",
+ "94.182.49.113",
+ "94.182.49.227",
+ "94.182.49.232",
+ "94.182.49.240",
+ "94.182.50.49",
+ "94.182.50.50",
+ "94.182.50.51",
+ "94.182.50.52",
+ "94.182.50.53",
+ "94.182.50.54",
+ "94.182.50.55",
+ "94.182.50.60",
+ "94.182.50.62",
+ "94.182.50.66",
+ "94.182.50.67",
+ "94.182.50.69",
+ "94.182.50.70",
+ "94.182.50.73",
+ "94.182.50.74",
+ "94.182.50.78",
+ "94.182.50.94",
+ "94.182.50.129",
+ "94.182.50.147",
+ "94.182.52.49",
+ "94.182.52.50",
+ "94.182.52.68",
+ "94.182.52.72",
+ "94.182.52.91",
+ "94.182.52.92",
+ "94.182.53.66",
+ "94.182.53.94",
+ "94.182.53.161",
+ "94.182.53.162",
+ "94.182.53.178",
+ "94.182.53.186",
+ "94.182.53.189",
+ "94.182.53.237",
+ "94.182.53.246",
+ "94.182.54.2",
+ "94.182.54.7",
+ "94.182.54.12",
+ "94.182.54.38",
+ "94.182.54.77",
+ "94.182.54.200",
+ "94.182.54.202",
+ "94.182.54.204",
+ "94.182.54.207",
+ "94.182.54.218",
+ "94.182.56.6",
+ "94.182.56.20",
+ "94.182.56.33",
+ "94.182.56.58",
+ "94.182.56.60",
+ "94.182.56.254",
+ "94.182.62.1",
+ "94.182.83.203",
+ "94.182.83.215",
+ "94.182.85.86",
+ "94.182.87.148",
+ "94.182.87.213",
+ "94.182.87.221",
+ "94.182.91.212",
+ "94.182.92.46",
+ "94.182.92.87",
+ "94.182.95.178",
+ "94.182.104.157",
+ "94.182.110.254",
+ "94.182.129.67",
+ "94.182.134.138",
+ "94.182.136.21",
+ "94.182.136.107",
+ "94.182.136.163",
+ "94.182.137.91",
+ "94.182.146.6",
+ "94.182.146.7",
+ "94.182.146.92",
+ "94.182.149.69",
+ "94.182.149.80",
+ "94.182.150.184",
+ "94.182.155.132",
+ "94.182.155.135",
+ "94.182.155.200",
+ "94.182.156.116",
+ "94.182.156.188",
+ "94.182.157.184",
+ "94.182.168.168",
+ "94.182.168.220",
+ "94.182.169.56",
+ "94.182.169.113",
+ "94.182.170.150",
+ "94.182.170.196",
+ "94.182.170.242",
+ "94.182.172.195",
+ "94.182.172.201",
+ "94.182.172.252",
+ "94.182.175.3",
+ "94.182.175.29",
+ "94.182.175.30",
+ "94.182.175.57",
+ "94.182.176.141",
+ "94.182.176.143",
+ "94.182.176.144",
+ "94.182.178.96",
+ "94.182.178.106",
+ "94.182.178.139",
+ "94.182.180.141",
+ "94.182.183.154",
+ "94.182.186.227",
+ "94.182.186.228",
+ "94.182.192.4",
+ "94.182.192.30",
+ "94.182.192.31",
+ "94.182.192.46",
+ "94.182.192.50",
+ "94.182.192.57",
+ "94.182.192.79",
+ "94.182.192.85",
+ "94.182.192.107",
+ "94.182.192.120",
+ "94.182.192.139",
+ "94.182.192.169",
+ "94.182.192.170",
+ "94.182.192.173",
+ "94.182.192.192",
+ "94.182.192.228",
+ "94.182.192.231",
+ "94.182.192.248",
+ "94.182.192.253",
+ "94.182.193.3",
+ "94.182.193.12",
+ "94.182.193.36",
+ "94.182.193.40",
+ "94.182.193.44",
+ "94.182.193.52",
+ "94.182.193.76",
+ "94.182.193.78",
+ "94.182.193.93",
+ "94.182.193.98",
+ "94.182.193.106",
+ "94.182.193.112",
+ "94.182.193.113",
+ "94.182.193.140",
+ "94.182.193.141",
+ "94.182.193.155",
+ "94.182.193.171",
+ "94.182.193.175",
+ "94.182.193.183",
+ "94.182.193.184",
+ "94.182.193.186",
+ "94.182.193.189",
+ "94.182.193.230",
+ "94.182.193.235",
+ "94.182.193.238",
+ "94.182.193.243",
+ "94.182.193.244",
+ "94.182.194.73",
+ "94.182.194.74",
+ "94.182.194.83",
+ "94.182.194.98",
+ "94.182.194.120",
+ "94.182.194.149",
+ "94.182.194.151",
+ "94.182.194.181",
+ "94.182.194.184",
+ "94.182.194.185",
+ "94.182.194.195",
+ "94.182.194.198",
+ "94.182.194.206",
+ "94.182.194.227",
+ "94.182.194.231",
+ "94.182.195.14",
+ "94.182.195.58",
+ "94.182.195.61",
+ "94.182.195.160",
+ "94.182.196.62",
+ "94.182.196.82",
+ "94.182.196.238",
+ "94.182.197.62",
+ "94.182.197.142",
+ "94.182.197.153",
+ "94.182.197.154",
+ "94.182.197.174",
+ "94.182.197.198",
+ "94.182.198.6",
+ "94.182.198.30",
+ "94.182.198.34",
+ "94.182.198.78",
+ "94.182.198.194",
+ "94.182.198.214",
+ "94.182.198.238",
+ "94.182.199.106",
+ "94.182.199.226",
+ "94.182.199.246",
+ "94.182.199.250",
+ "94.182.201.9",
+ "94.182.201.25",
+ "94.182.201.58",
+ "94.182.201.59",
+ "94.182.201.115",
+ "94.182.202.91",
+ "94.182.202.185",
+ "94.182.202.216",
+ "94.182.202.217",
+ "94.182.203.114",
+ "94.182.203.115",
+ "94.182.203.116",
+ "94.182.203.117",
+ "94.182.203.178",
+ "94.182.209.2",
+ "94.182.211.62",
+ "94.182.211.250",
+ "94.182.211.251",
+ "94.182.214.179",
+ "94.182.214.180",
+ "94.182.214.181",
+ "94.182.214.183",
+ "94.182.214.184",
+ "94.182.214.186",
+ "94.182.214.187",
+ "94.182.214.188",
+ "94.182.214.190",
+ "94.182.216.1",
+ "94.182.216.2",
+ "94.182.219.26",
+ "94.182.219.54",
+ "94.182.219.129",
+ "94.182.219.154",
+ "94.182.219.162",
+ "94.182.219.246",
+ "94.182.219.247",
+ "94.182.220.6",
+ "94.182.225.139",
+ "94.182.225.152",
+ "94.182.225.164",
+ "94.182.225.175",
+ "94.182.225.183",
+ "94.182.225.231",
+ "94.182.225.233",
+ "94.182.225.238",
+ "94.182.225.254",
+ "94.182.227.48",
+ "94.182.227.93",
+ "94.182.227.139",
+ "94.182.227.177",
+ "94.182.250.3",
+ "94.182.250.4",
+ "94.182.250.5",
+ "94.182.250.50",
+ "94.182.251.115",
+ "94.182.251.125",
+ "94.182.251.151",
+ "94.182.253.71",
+ "94.182.253.135",
+ "94.182.254.5",
+ "94.182.254.117",
+ "94.182.254.121",
+ "94.182.254.122",
+ "94.182.255.139",
+ "94.182.255.200",
+ "94.183.0.37",
+ "94.183.0.46",
+ "94.183.0.54",
+ "94.183.0.85",
+ "94.183.0.97",
+ "94.183.0.125",
+ "94.183.0.167",
+ "94.183.0.241",
+ "94.183.1.21",
+ "94.183.1.50",
+ "94.183.1.98",
+ "94.183.1.229",
+ "94.183.1.246",
+ "94.183.2.47",
+ "94.183.2.151",
+ "94.183.2.211",
+ "94.183.3.130",
+ "94.183.3.150",
+ "94.183.3.196",
+ "94.183.5.95",
+ "94.183.6.186",
+ "94.183.6.229",
+ "94.183.6.245",
+ "94.183.7.129",
+ "94.183.7.199",
+ "94.183.7.207",
+ "94.183.11.9",
+ "94.183.11.29",
+ "94.183.11.36",
+ "94.183.11.87",
+ "94.183.11.100",
+ "94.183.11.160",
+ "94.183.13.233",
+ "94.183.14.202",
+ "94.183.15.43",
+ "94.183.15.64",
+ "94.183.15.245",
+ "94.183.16.15",
+ "94.183.16.45",
+ "94.183.17.128",
+ "94.183.17.141",
+ "94.183.18.36",
+ "94.183.20.50",
+ "94.183.20.147",
+ "94.183.21.119",
+ "94.183.22.114",
+ "94.183.23.1",
+ "94.183.23.2",
+ "94.183.23.163",
+ "94.183.23.207",
+ "94.183.24.57",
+ "94.183.24.98",
+ "94.183.26.10",
+ "94.183.26.122",
+ "94.183.26.130",
+ "94.183.26.132",
+ "94.183.27.72",
+ "94.183.27.83",
+ "94.183.27.96",
+ "94.183.27.154",
+ "94.183.27.159",
+ "94.183.27.223",
+ "94.183.27.235",
+ "94.183.28.24",
+ "94.183.28.60",
+ "94.183.28.85",
+ "94.183.28.92",
+ "94.183.28.102",
+ "94.183.28.111",
+ "94.183.28.141",
+ "94.183.28.159",
+ "94.183.28.195",
+ "94.183.28.235",
+ "94.183.29.4",
+ "94.183.29.100",
+ "94.183.29.112",
+ "94.183.29.113",
+ "94.183.29.137",
+ "94.183.29.167",
+ "94.183.29.187",
+ "94.183.30.36",
+ "94.183.30.38",
+ "94.183.30.42",
+ "94.183.30.43",
+ "94.183.30.46",
+ "94.183.30.65",
+ "94.183.30.78",
+ "94.183.30.88",
+ "94.183.30.107",
+ "94.183.30.116",
+ "94.183.30.117",
+ "94.183.30.128",
+ "94.183.30.161",
+ "94.183.30.164",
+ "94.183.30.167",
+ "94.183.30.170",
+ "94.183.30.171",
+ "94.183.30.199",
+ "94.183.30.202",
+ "94.183.30.204",
+ "94.183.30.212",
+ "94.183.30.216",
+ "94.183.31.23",
+ "94.183.31.63",
+ "94.183.31.73",
+ "94.183.31.124",
+ "94.183.31.156",
+ "94.183.31.202",
+ "94.183.31.205",
+ "94.183.32.25",
+ "94.183.32.86",
+ "94.183.33.78",
+ "94.183.33.240",
+ "94.183.34.55",
+ "94.183.34.98",
+ "94.183.34.232",
+ "94.183.35.74",
+ "94.183.35.226",
+ "94.183.37.2",
+ "94.183.37.76",
+ "94.183.38.141",
+ "94.183.40.253",
+ "94.183.42.107",
+ "94.183.44.111",
+ "94.183.46.108",
+ "94.183.46.116",
+ "94.183.48.10",
+ "94.183.48.15",
+ "94.183.49.6",
+ "94.183.49.21",
+ "94.183.49.41",
+ "94.183.49.47",
+ "94.183.49.130",
+ "94.183.49.206",
+ "94.183.50.97",
+ "94.183.50.174",
+ "94.183.50.187",
+ "94.183.50.231",
+ "94.183.51.95",
+ "94.183.51.144",
+ "94.183.51.165",
+ "94.183.51.215",
+ "94.183.52.51",
+ "94.183.52.67",
+ "94.183.52.94",
+ "94.183.52.215",
+ "94.183.52.227",
+ "94.183.53.29",
+ "94.183.53.99",
+ "94.183.53.113",
+ "94.183.53.133",
+ "94.183.56.163",
+ "94.183.56.191",
+ "94.183.56.229",
+ "94.183.56.251",
+ "94.183.57.45",
+ "94.183.57.66",
+ "94.183.57.215",
+ "94.183.58.29",
+ "94.183.58.79",
+ "94.183.58.188",
+ "94.183.58.198",
+ "94.183.59.32",
+ "94.183.59.75",
+ "94.183.59.104",
+ "94.183.59.114",
+ "94.183.59.197",
+ "94.183.59.245",
+ "94.183.60.19",
+ "94.183.60.28",
+ "94.183.61.126",
+ "94.183.61.145",
+ "94.183.61.218",
+ "94.183.62.125",
+ "94.183.62.141",
+ "94.183.62.222",
+ "94.183.63.68",
+ "94.183.67.57",
+ "94.183.67.84",
+ "94.183.68.106",
+ "94.183.70.115",
+ "94.183.70.140",
+ "94.183.72.99",
+ "94.183.72.116",
+ "94.183.72.164",
+ "94.183.72.187",
+ "94.183.72.243",
+ "94.183.73.76",
+ "94.183.73.77",
+ "94.183.73.78",
+ "94.183.73.111",
+ "94.183.73.214",
+ "94.183.73.218",
+ "94.183.73.246",
+ "94.183.74.15",
+ "94.183.74.58",
+ "94.183.74.78",
+ "94.183.74.101",
+ "94.183.74.184",
+ "94.183.75.49",
+ "94.183.78.74",
+ "94.183.80.22",
+ "94.183.82.7",
+ "94.183.82.216",
+ "94.183.83.1",
+ "94.183.83.19",
+ "94.183.83.115",
+ "94.183.83.183",
+ "94.183.83.211",
+ "94.183.83.241",
+ "94.183.84.144",
+ "94.183.84.236",
+ "94.183.85.31",
+ "94.183.85.115",
+ "94.183.85.139",
+ "94.183.85.190",
+ "94.183.85.232",
+ "94.183.88.131",
+ "94.183.88.134",
+ "94.183.90.106",
+ "94.183.90.166",
+ "94.183.90.221",
+ "94.183.90.227",
+ "94.183.91.32",
+ "94.183.91.82",
+ "94.183.91.241",
+ "94.183.92.64",
+ "94.183.92.70",
+ "94.183.92.77",
+ "94.183.92.84",
+ "94.183.92.92",
+ "94.183.92.95",
+ "94.183.92.112",
+ "94.183.92.121",
+ "94.183.92.227",
+ "94.183.92.232",
+ "94.183.93.28",
+ "94.183.93.48",
+ "94.183.93.51",
+ "94.183.93.52",
+ "94.183.93.74",
+ "94.183.93.103",
+ "94.183.93.106",
+ "94.183.93.109",
+ "94.183.93.117",
+ "94.183.93.123",
+ "94.183.93.200",
+ "94.183.93.210",
+ "94.183.93.228",
+ "94.183.93.239",
+ "94.183.94.29",
+ "94.183.94.38",
+ "94.183.94.39",
+ "94.183.94.40",
+ "94.183.94.54",
+ "94.183.94.55",
+ "94.183.95.114",
+ "94.183.95.122",
+ "94.183.95.146",
+ "94.183.95.171",
+ "94.183.95.206",
+ "94.183.95.208",
+ "94.183.97.22",
+ "94.183.99.63",
+ "94.183.99.81",
+ "94.183.99.111",
+ "94.183.99.176",
+ "94.183.99.210",
+ "94.183.99.218",
+ "94.183.99.222",
+ "94.183.99.226",
+ "94.183.99.237",
+ "94.183.99.238",
+ "94.183.100.59",
+ "94.183.100.202",
+ "94.183.100.251",
+ "94.183.102.151",
+ "94.183.102.226",
+ "94.183.103.139",
+ "94.183.104.107",
+ "94.183.106.110",
+ "94.183.107.102",
+ "94.183.108.65",
+ "94.183.109.224",
+ "94.183.110.113",
+ "94.183.110.223",
+ "94.183.111.6",
+ "94.183.113.41",
+ "94.183.113.86",
+ "94.183.114.81",
+ "94.183.114.92",
+ "94.183.115.73",
+ "94.183.115.167",
+ "94.183.115.187",
+ "94.183.115.188",
+ "94.183.116.18",
+ "94.183.116.56",
+ "94.183.116.126",
+ "94.183.116.220",
+ "94.183.117.124",
+ "94.183.117.200",
+ "94.183.118.6",
+ "94.183.118.14",
+ "94.183.118.42",
+ "94.183.118.107",
+ "94.183.118.123",
+ "94.183.118.127",
+ "94.183.119.28",
+ "94.183.119.88",
+ "94.183.119.104",
+ "94.183.119.202",
+ "94.183.119.246",
+ "94.183.120.17",
+ "94.183.120.34",
+ "94.183.120.86",
+ "94.183.120.104",
+ "94.183.120.224",
+ "94.183.122.16",
+ "94.183.122.17",
+ "94.183.122.64",
+ "94.183.122.126",
+ "94.183.122.174",
+ "94.183.123.128",
+ "94.183.123.129",
+ "94.183.123.132",
+ "94.183.124.16",
+ "94.183.124.21",
+ "94.183.124.30",
+ "94.183.124.45",
+ "94.183.124.77",
+ "94.183.124.130",
+ "94.183.124.140",
+ "94.183.124.187",
+ "94.183.124.194",
+ "94.183.125.56",
+ "94.183.125.172",
+ "94.183.125.187",
+ "94.183.126.39",
+ "94.183.126.41",
+ "94.183.126.42",
+ "94.183.126.111",
+ "94.183.126.211",
+ "94.183.127.13",
+ "94.183.127.27",
+ "94.183.127.40",
+ "94.183.127.76",
+ "94.183.127.100",
+ "94.183.127.114",
+ "94.183.127.123",
+ "94.183.127.163",
+ "94.183.129.209",
+ "94.183.132.5",
+ "94.183.132.100",
+ "94.183.132.119",
+ "94.183.132.126",
+ "94.183.132.128",
+ "94.183.132.143",
+ "94.183.132.144",
+ "94.183.132.174",
+ "94.183.132.214",
+ "94.183.133.82",
+ "94.183.133.113",
+ "94.183.133.132",
+ "94.183.133.146",
+ "94.183.133.159",
+ "94.183.133.175",
+ "94.183.133.223",
+ "94.183.133.235",
+ "94.183.133.247",
+ "94.183.134.150",
+ "94.183.134.153",
+ "94.183.134.202",
+ "94.183.134.255",
+ "94.183.135.140",
+ "94.183.138.109",
+ "94.183.139.136",
+ "94.183.140.110",
+ "94.183.140.138",
+ "94.183.141.68",
+ "94.183.144.185",
+ "94.183.145.89",
+ "94.183.145.147",
+ "94.183.145.155",
+ "94.183.145.214",
+ "94.183.146.186",
+ "94.183.146.203",
+ "94.183.146.221",
+ "94.183.147.241",
+ "94.183.148.65",
+ "94.183.148.98",
+ "94.183.148.129",
+ "94.183.148.184",
+ "94.183.148.238",
+ "94.183.149.65",
+ "94.183.149.85",
+ "94.183.149.140",
+ "94.183.149.146",
+ "94.183.149.171",
+ "94.183.149.204",
+ "94.183.149.249",
+ "94.183.149.252",
+ "94.183.154.207",
+ "94.183.156.128",
+ "94.183.156.137",
+ "94.183.163.52",
+ "94.183.163.60",
+ "94.183.163.75",
+ "94.183.176.45",
+ "94.183.180.21",
+ "94.184.3.203",
+ "94.184.3.226",
+ "94.184.3.227",
+ "94.184.3.230",
+ "94.184.10.98",
+ "94.184.16.7",
+ "94.184.16.178",
+ "94.184.17.213",
+ "94.184.18.24",
+ "94.184.18.44",
+ "94.184.18.189",
+ "94.184.21.66",
+ "94.184.22.6",
+ "94.184.22.158",
+ "94.184.23.65",
+ "94.184.23.243",
+ "94.184.29.33",
+ "94.184.29.218",
+ "94.184.90.225",
+ "94.184.177.129",
+ "94.184.208.77",
+ "94.184.208.102",
+ "94.199.0.1",
+ "94.199.0.41",
+ "94.199.0.60",
+ "94.199.0.78",
+ "94.199.0.212",
+ "94.232.168.162",
+ "94.232.171.82",
+ "94.232.171.83",
+ "94.232.171.84",
+ "94.232.171.85",
+ "94.232.171.91",
+ "94.232.172.109",
+ "94.232.173.8",
+ "94.232.173.136",
+ "94.232.173.192",
+ "94.232.175.210",
+ "94.232.175.211",
+ "95.38.10.9",
+ "95.38.10.65",
+ "95.38.10.153",
+ "95.38.10.195",
+ "95.38.10.197",
+ "95.38.10.219",
+ "95.38.10.230",
+ "95.38.10.253",
+ "95.38.11.1",
+ "95.38.11.26",
+ "95.38.11.42",
+ "95.38.11.46",
+ "95.38.11.84",
+ "95.38.11.89",
+ "95.38.11.94",
+ "95.38.11.95",
+ "95.38.11.201",
+ "95.38.11.223",
+ "95.38.15.205",
+ "95.38.15.247",
+ "95.38.20.66",
+ "95.38.20.67",
+ "95.38.24.146",
+ "95.38.25.0",
+ "95.38.27.16",
+ "95.38.27.32",
+ "95.38.27.36",
+ "95.38.34.30",
+ "95.38.34.58",
+ "95.38.34.59",
+ "95.38.34.60",
+ "95.38.34.242",
+ "95.38.35.44",
+ "95.38.38.75",
+ "95.38.38.83",
+ "95.38.39.173",
+ "95.38.46.84",
+ "95.38.46.130",
+ "95.38.47.173",
+ "95.38.48.253",
+ "95.38.49.157",
+ "95.38.50.102",
+ "95.38.52.218",
+ "95.38.53.118",
+ "95.38.60.5",
+ "95.38.60.11",
+ "95.38.60.42",
+ "95.38.60.252",
+ "95.38.63.47",
+ "95.38.63.59",
+ "95.38.63.200",
+ "95.38.63.234",
+ "95.38.65.2",
+ "95.38.65.3",
+ "95.38.65.5",
+ "95.38.65.234",
+ "95.38.66.23",
+ "95.38.72.23",
+ "95.38.75.75",
+ "95.38.75.79",
+ "95.38.76.42",
+ "95.38.76.160",
+ "95.38.77.190",
+ "95.38.78.69",
+ "95.38.78.239",
+ "95.38.86.50",
+ "95.38.86.51",
+ "95.38.86.52",
+ "95.38.86.53",
+ "95.38.86.54",
+ "95.38.86.55",
+ "95.38.86.56",
+ "95.38.86.59",
+ "95.38.86.60",
+ "95.38.86.61",
+ "95.38.86.62",
+ "95.38.89.16",
+ "95.38.89.17",
+ "95.38.89.18",
+ "95.38.89.19",
+ "95.38.89.21",
+ "95.38.89.77",
+ "95.38.89.78",
+ "95.38.89.80",
+ "95.38.89.90",
+ "95.38.89.95",
+ "95.38.89.107",
+ "95.38.89.112",
+ "95.38.89.192",
+ "95.38.89.199",
+ "95.38.94.14",
+ "95.38.94.21",
+ "95.38.94.218",
+ "95.38.96.230",
+ "95.38.99.146",
+ "95.38.102.89",
+ "95.38.103.70",
+ "95.38.103.218",
+ "95.38.103.254",
+ "95.38.105.66",
+ "95.38.105.71",
+ "95.38.105.122",
+ "95.38.106.146",
+ "95.38.123.254",
+ "95.38.130.108",
+ "95.38.131.28",
+ "95.38.131.44",
+ "95.38.131.59",
+ "95.38.131.81",
+ "95.38.131.93",
+ "95.38.131.95",
+ "95.38.131.110",
+ "95.38.131.143",
+ "95.38.131.144",
+ "95.38.131.159",
+ "95.38.131.163",
+ "95.38.131.194",
+ "95.38.131.199",
+ "95.38.131.216",
+ "95.38.131.243",
+ "95.38.131.247",
+ "95.38.131.248",
+ "95.38.134.24",
+ "95.38.134.26",
+ "95.38.134.50",
+ "95.38.134.85",
+ "95.38.134.190",
+ "95.38.134.202",
+ "95.38.135.12",
+ "95.38.135.140",
+ "95.38.138.38",
+ "95.38.138.154",
+ "95.38.138.174",
+ "95.38.138.202",
+ "95.38.142.34",
+ "95.38.142.62",
+ "95.38.144.16",
+ "95.38.144.17",
+ "95.38.144.26",
+ "95.38.144.41",
+ "95.38.144.127",
+ "95.38.144.158",
+ "95.38.144.178",
+ "95.38.144.203",
+ "95.38.145.12",
+ "95.38.145.68",
+ "95.38.145.73",
+ "95.38.145.74",
+ "95.38.145.78",
+ "95.38.145.95",
+ "95.38.146.86",
+ "95.38.146.202",
+ "95.38.146.217",
+ "95.38.147.86",
+ "95.38.147.133",
+ "95.38.147.134",
+ "95.38.147.190",
+ "95.38.148.15",
+ "95.38.148.59",
+ "95.38.148.163",
+ "95.38.148.171",
+ "95.38.148.198",
+ "95.38.149.2",
+ "95.38.149.176",
+ "95.38.153.226",
+ "95.38.155.50",
+ "95.38.155.74",
+ "95.38.156.45",
+ "95.38.156.53",
+ "95.38.156.56",
+ "95.38.156.60",
+ "95.38.157.90",
+ "95.38.157.120",
+ "95.38.159.194",
+ "95.38.159.254",
+ "95.38.169.118",
+ "95.38.169.154",
+ "95.38.169.202",
+ "95.38.169.222",
+ "95.38.170.16",
+ "95.38.170.17",
+ "95.38.174.38",
+ "95.38.174.65",
+ "95.38.174.81",
+ "95.38.174.83",
+ "95.38.174.85",
+ "95.38.174.87",
+ "95.38.174.106",
+ "95.38.174.226",
+ "95.38.192.99",
+ "95.38.192.140",
+ "95.38.192.167",
+ "95.38.192.183",
+ "95.38.196.129",
+ "95.38.196.134",
+ "95.38.196.190",
+ "95.38.196.216",
+ "95.38.197.134",
+ "95.38.197.254",
+ "95.38.199.0",
+ "95.38.199.10",
+ "95.38.199.18",
+ "95.38.201.30",
+ "95.38.201.114",
+ "95.38.201.201",
+ "95.38.201.211",
+ "95.38.203.178",
+ "95.38.209.226",
+ "95.38.209.227",
+ "95.38.209.229",
+ "95.38.209.230",
+ "95.38.209.231",
+ "95.38.209.232",
+ "95.38.209.233",
+ "95.38.209.234",
+ "95.38.209.235",
+ "95.38.211.243",
+ "95.38.211.250",
+ "95.38.224.86",
+ "95.38.224.151",
+ "95.38.224.202",
+ "95.38.224.218",
+ "95.38.241.65",
+ "95.38.243.46",
+ "95.38.243.250",
+ "95.38.244.50",
+ "95.38.244.114",
+ "95.38.244.115",
+ "95.38.244.120",
+ "95.38.244.121",
+ "95.38.244.122",
+ "95.38.244.124",
+ "95.38.244.126",
+ "95.38.245.14",
+ "95.38.245.33",
+ "95.38.245.58",
+ "95.38.245.62",
+ "95.38.245.146",
+ "95.38.245.147",
+ "95.38.245.148",
+ "95.38.245.149",
+ "95.38.245.150",
+ "95.38.246.19",
+ "95.38.248.184",
+ "95.38.248.194",
+ "95.38.248.246",
+ "95.38.248.250",
+ "95.38.250.184",
+ "95.38.250.195",
+ "95.38.250.230",
+ "95.80.140.2",
+ "95.80.140.26",
+ "95.80.140.32",
+ "95.80.140.53",
+ "95.80.140.64",
+ "95.80.140.80",
+ "95.80.140.91",
+ "95.80.140.92",
+ "95.80.140.110",
+ "95.80.140.126",
+ "95.80.140.159",
+ "95.80.140.162",
+ "95.80.140.205",
+ "95.80.140.210",
+ "95.80.140.229",
+ "95.80.140.233",
+ "95.80.140.238",
+ "95.80.141.2",
+ "95.80.141.12",
+ "95.80.141.15",
+ "95.80.141.18",
+ "95.80.141.37",
+ "95.80.141.48",
+ "95.80.141.71",
+ "95.80.141.74",
+ "95.80.141.81",
+ "95.80.141.84",
+ "95.80.141.103",
+ "95.80.141.110",
+ "95.80.141.112",
+ "95.80.141.117",
+ "95.80.141.124",
+ "95.80.141.142",
+ "95.80.141.150",
+ "95.80.141.151",
+ "95.80.141.162",
+ "95.80.141.167",
+ "95.80.141.176",
+ "95.80.141.190",
+ "95.80.141.214",
+ "95.80.141.220",
+ "95.80.141.238",
+ "95.80.141.253",
+ "95.80.142.4",
+ "95.80.142.9",
+ "95.80.142.29",
+ "95.80.142.33",
+ "95.80.142.42",
+ "95.80.142.54",
+ "95.80.142.57",
+ "95.80.142.81",
+ "95.80.142.96",
+ "95.80.142.102",
+ "95.80.142.106",
+ "95.80.142.117",
+ "95.80.142.124",
+ "95.80.142.140",
+ "95.80.142.150",
+ "95.80.142.167",
+ "95.80.142.177",
+ "95.80.142.199",
+ "95.80.142.217",
+ "95.80.142.224",
+ "95.80.142.228",
+ "95.80.142.244",
+ "95.80.142.248",
+ "95.80.143.1",
+ "95.80.143.11",
+ "95.80.143.28",
+ "95.80.143.31",
+ "95.80.143.45",
+ "95.80.143.82",
+ "95.80.143.83",
+ "95.80.143.119",
+ "95.80.143.134",
+ "95.80.143.137",
+ "95.80.143.138",
+ "95.80.143.151",
+ "95.80.143.160",
+ "95.80.143.163",
+ "95.80.143.169",
+ "95.80.143.183",
+ "95.80.143.198",
+ "95.80.143.224",
+ "95.80.157.65",
+ "95.80.159.242",
+ "95.80.160.58",
+ "95.80.160.66",
+ "95.80.160.180",
+ "95.80.161.130",
+ "95.80.168.12",
+ "95.80.168.22",
+ "95.80.168.56",
+ "95.80.168.63",
+ "95.80.168.69",
+ "95.80.168.90",
+ "95.80.168.115",
+ "95.80.168.151",
+ "95.80.168.161",
+ "95.80.168.194",
+ "95.80.168.203",
+ "95.80.168.221",
+ "95.80.168.233",
+ "95.80.169.1",
+ "95.80.169.8",
+ "95.80.169.14",
+ "95.80.169.20",
+ "95.80.169.48",
+ "95.80.169.61",
+ "95.80.169.62",
+ "95.80.169.78",
+ "95.80.169.101",
+ "95.80.169.131",
+ "95.80.169.138",
+ "95.80.169.152",
+ "95.80.169.177",
+ "95.80.169.185",
+ "95.80.169.190",
+ "95.80.169.191",
+ "95.80.169.198",
+ "95.80.169.215",
+ "95.80.170.4",
+ "95.80.170.24",
+ "95.80.170.25",
+ "95.80.170.36",
+ "95.80.170.42",
+ "95.80.170.53",
+ "95.80.170.81",
+ "95.80.170.95",
+ "95.80.170.104",
+ "95.80.170.125",
+ "95.80.170.133",
+ "95.80.170.134",
+ "95.80.170.142",
+ "95.80.170.167",
+ "95.80.170.176",
+ "95.80.170.180",
+ "95.80.170.225",
+ "95.80.170.251",
+ "95.80.171.12",
+ "95.80.171.23",
+ "95.80.171.32",
+ "95.80.171.93",
+ "95.80.171.94",
+ "95.80.171.113",
+ "95.80.171.122",
+ "95.80.171.141",
+ "95.80.171.168",
+ "95.80.171.197",
+ "95.80.171.216",
+ "95.80.171.249",
+ "95.80.172.18",
+ "95.80.172.36",
+ "95.80.172.55",
+ "95.80.172.88",
+ "95.80.172.123",
+ "95.80.172.128",
+ "95.80.172.138",
+ "95.80.172.140",
+ "95.80.172.157",
+ "95.80.172.165",
+ "95.80.172.191",
+ "95.80.172.222",
+ "95.80.172.242",
+ "95.80.172.248",
+ "95.80.172.250",
+ "95.80.173.89",
+ "95.80.173.99",
+ "95.80.173.137",
+ "95.80.173.141",
+ "95.80.173.146",
+ "95.80.173.156",
+ "95.80.173.158",
+ "95.80.173.168",
+ "95.80.173.228",
+ "95.80.173.236",
+ "95.80.173.244",
+ "95.80.173.253",
+ "95.80.174.2",
+ "95.80.174.3",
+ "95.80.174.12",
+ "95.80.174.19",
+ "95.80.174.83",
+ "95.80.174.100",
+ "95.80.174.109",
+ "95.80.174.152",
+ "95.80.174.160",
+ "95.80.174.180",
+ "95.80.174.181",
+ "95.80.174.187",
+ "95.80.174.191",
+ "95.80.174.196",
+ "95.80.174.200",
+ "95.80.174.214",
+ "95.80.174.222",
+ "95.80.174.229",
+ "95.80.174.237",
+ "95.80.175.21",
+ "95.80.175.25",
+ "95.80.175.33",
+ "95.80.175.34",
+ "95.80.175.57",
+ "95.80.175.64",
+ "95.80.175.93",
+ "95.80.175.99",
+ "95.80.175.127",
+ "95.80.175.167",
+ "95.80.175.184",
+ "95.80.175.205",
+ "95.80.175.228",
+ "95.80.175.235",
+ "95.80.190.10",
+ "95.80.190.11",
+ "95.130.56.214",
+ "95.130.58.25",
+ "95.130.58.40",
+ "95.130.60.34",
+ "95.130.62.46",
+ "95.130.225.12",
+ "95.130.225.65",
+ "95.142.226.13",
+ "95.142.237.244",
+ "95.156.236.25",
+ "95.156.236.27",
+ "95.156.236.58",
+ "95.156.236.59",
+ "95.156.236.60",
+ "95.156.253.34",
+ "95.156.253.51",
+ "95.215.59.140",
+ "95.215.160.1",
+ "95.215.160.22",
+ "95.215.160.62",
+ "95.215.160.108",
+ "95.215.160.126",
+ "95.215.160.157",
+ "95.215.160.195",
+ "95.215.160.217",
+ "95.215.160.223",
+ "95.215.161.106",
+ "95.215.161.125",
+ "95.215.161.137",
+ "95.215.161.187",
+ "95.215.161.231",
+ "95.215.161.233",
+ "95.215.161.246",
+ "103.215.220.216",
+ "103.215.223.64",
+ "103.215.223.91",
+ "103.216.61.171",
+ "103.216.63.202",
+ "103.216.63.203",
+ "103.216.63.204",
+ "103.231.136.0",
+ "103.231.136.255",
+ "103.231.137.0",
+ "103.231.137.255",
+ "103.231.138.0",
+ "103.231.138.1",
+ "103.231.139.0",
+ "103.231.139.255",
+ "109.70.237.25",
+ "109.70.237.44",
+ "109.70.237.50",
+ "109.70.237.67",
+ "109.70.237.94",
+ "109.70.237.118",
+ "109.70.237.123",
+ "109.70.237.137",
+ "109.70.237.177",
+ "109.70.237.207",
+ "109.70.237.233",
+ "109.70.237.235",
+ "109.70.237.245",
+ "109.72.195.128",
+ "109.72.195.139",
+ "109.72.195.159",
+ "109.72.195.161",
+ "109.72.195.178",
+ "109.72.195.184",
+ "109.72.195.188",
+ "109.72.195.192",
+ "109.72.195.203",
+ "109.72.195.211",
+ "109.72.195.221",
+ "109.72.195.223",
+ "109.72.195.225",
+ "109.72.195.226",
+ "109.72.195.230",
+ "109.72.195.234",
+ "109.72.195.237",
+ "109.72.195.239",
+ "109.72.195.243",
+ "109.72.195.251",
+ "109.72.195.255",
+ "109.72.201.9",
+ "109.72.201.14",
+ "109.72.201.17",
+ "109.72.201.29",
+ "109.72.201.36",
+ "109.72.201.44",
+ "109.72.201.47",
+ "109.72.201.51",
+ "109.72.201.54",
+ "109.72.201.61",
+ "109.72.201.65",
+ "109.72.201.66",
+ "109.72.201.73",
+ "109.72.201.80",
+ "109.72.201.81",
+ "109.72.201.84",
+ "109.72.201.87",
+ "109.72.201.115",
+ "109.72.201.125",
+ "109.72.201.127",
+ "109.72.201.128",
+ "109.72.201.154",
+ "109.72.201.155",
+ "109.72.201.163",
+ "109.72.201.167",
+ "109.72.201.183",
+ "109.72.201.187",
+ "109.72.201.193",
+ "109.72.201.216",
+ "109.72.201.223",
+ "109.72.201.231",
+ "109.72.201.239",
+ "109.72.201.242",
+ "109.74.226.188",
+ "109.74.228.195",
+ "109.74.230.245",
+ "109.74.238.178",
+ "109.94.164.100",
+ "109.94.164.170",
+ "109.95.60.4",
+ "109.95.60.33",
+ "109.95.60.38",
+ "109.95.60.56",
+ "109.95.60.57",
+ "109.95.60.59",
+ "109.95.60.61",
+ "109.95.60.77",
+ "109.95.60.97",
+ "109.95.60.139",
+ "109.95.60.149",
+ "109.95.60.242",
+ "109.95.60.255",
+ "109.95.61.201",
+ "109.95.61.204",
+ "109.95.61.245",
+ "109.95.61.254",
+ "109.95.62.134",
+ "109.95.63.192",
+ "109.95.67.100",
+ "109.95.71.25",
+ "109.109.42.61",
+ "109.109.43.186",
+ "109.109.43.199",
+ "109.109.46.76",
+ "109.109.52.167",
+ "109.109.54.104",
+ "109.109.54.150",
+ "109.109.55.91",
+ "109.109.63.58",
+ "109.122.227.126",
+ "109.122.228.6",
+ "109.122.228.152",
+ "109.122.230.26",
+ "109.122.231.102",
+ "109.122.232.193",
+ "109.122.233.36",
+ "109.122.236.62",
+ "109.122.238.53",
+ "109.122.238.121",
+ "109.122.240.4",
+ "109.122.240.6",
+ "109.122.240.16",
+ "109.122.240.17",
+ "109.122.240.19",
+ "109.122.240.20",
+ "109.122.240.22",
+ "109.122.245.53",
+ "109.122.245.58",
+ "109.125.128.28",
+ "109.125.128.59",
+ "109.125.128.166",
+ "109.125.128.236",
+ "109.125.129.72",
+ "109.125.129.84",
+ "109.125.129.170",
+ "109.125.129.226",
+ "109.125.130.3",
+ "109.125.130.50",
+ "109.125.130.111",
+ "109.125.130.176",
+ "109.125.131.80",
+ "109.125.131.90",
+ "109.125.131.101",
+ "109.125.131.136",
+ "109.125.131.162",
+ "109.125.132.73",
+ "109.125.132.147",
+ "109.125.132.154",
+ "109.125.133.22",
+ "109.125.133.102",
+ "109.125.133.206",
+ "109.125.134.30",
+ "109.125.134.83",
+ "109.125.134.87",
+ "109.125.134.254",
+ "109.125.135.50",
+ "109.125.135.62",
+ "109.125.135.160",
+ "109.125.135.213",
+ "109.125.136.12",
+ "109.125.136.149",
+ "109.125.136.234",
+ "109.125.136.239",
+ "109.125.137.32",
+ "109.125.137.170",
+ "109.125.137.212",
+ "109.125.138.89",
+ "109.125.140.57",
+ "109.125.140.127",
+ "109.125.140.150",
+ "109.125.140.211",
+ "109.125.141.45",
+ "109.125.141.57",
+ "109.125.141.67",
+ "109.125.141.78",
+ "109.125.141.148",
+ "109.125.141.166",
+ "109.125.141.235",
+ "109.125.141.246",
+ "109.125.142.212",
+ "109.125.143.33",
+ "109.125.144.51",
+ "109.125.144.96",
+ "109.125.144.143",
+ "109.125.145.79",
+ "109.125.145.97",
+ "109.125.146.166",
+ "109.125.146.173",
+ "109.125.148.226",
+ "109.125.160.3",
+ "109.125.160.7",
+ "109.125.160.9",
+ "109.125.160.10",
+ "109.125.160.65",
+ "109.125.160.144",
+ "109.125.160.147",
+ "109.125.160.160",
+ "109.125.160.176",
+ "109.125.160.191",
+ "109.125.160.205",
+ "109.125.160.209",
+ "109.125.160.226",
+ "109.125.160.252",
+ "109.125.168.1",
+ "109.125.168.35",
+ "109.125.168.41",
+ "109.125.168.53",
+ "109.125.168.83",
+ "109.125.168.119",
+ "109.125.168.126",
+ "109.125.168.141",
+ "109.125.168.218",
+ "109.125.168.226",
+ "109.125.168.234",
+ "109.125.178.101",
+ "109.125.191.2",
+ "109.125.191.54",
+ "109.162.128.193",
+ "109.162.158.62",
+ "109.162.158.111",
+ "109.162.196.66",
+ "109.162.196.138",
+ "109.162.197.28",
+ "109.162.197.65",
+ "109.162.198.243",
+ "109.162.230.136",
+ "109.162.251.14",
+ "109.162.251.43",
+ "109.162.251.46",
+ "109.162.251.110",
+ "109.162.251.158",
+ "109.201.0.17",
+ "109.201.0.58",
+ "109.201.2.81",
+ "109.201.8.84",
+ "109.201.8.85",
+ "109.201.8.86",
+ "109.201.13.186",
+ "109.201.13.187",
+ "109.201.13.189",
+ "109.201.13.190",
+ "109.201.15.10",
+ "109.201.15.38",
+ "109.201.15.86",
+ "109.201.15.161",
+ "109.201.17.57",
+ "109.201.19.177",
+ "109.201.19.213",
+ "109.201.19.241",
+ "109.201.19.244",
+ "109.201.19.246",
+ "109.201.23.6",
+ "109.201.23.25",
+ "109.201.23.41",
+ "109.201.23.43",
+ "109.201.23.48",
+ "109.201.23.63",
+ "109.201.23.77",
+ "109.201.23.96",
+ "109.201.23.138",
+ "109.201.23.147",
+ "109.201.23.195",
+ "109.201.24.138",
+ "109.201.24.194",
+ "109.201.24.196",
+ "109.201.27.79",
+ "109.201.27.146",
+ "109.206.254.122",
+ "109.206.254.123",
+ "109.206.254.124",
+ "109.206.254.125",
+ "109.206.254.126",
+ "109.206.254.130",
+ "109.230.72.32",
+ "109.230.72.53",
+ "109.230.72.63",
+ "109.230.72.97",
+ "109.230.72.98",
+ "109.230.72.99",
+ "109.230.72.110",
+ "109.230.72.137",
+ "109.230.72.145",
+ "109.230.72.162",
+ "109.230.72.172",
+ "109.230.72.222",
+ "109.230.72.224",
+ "109.230.72.226",
+ "109.230.72.227",
+ "109.230.72.228",
+ "109.230.72.231",
+ "109.230.72.236",
+ "109.230.72.242",
+ "109.230.72.243",
+ "109.230.72.245",
+ "109.230.73.109",
+ "109.230.73.151",
+ "109.230.74.86",
+ "109.230.74.105",
+ "109.230.75.51",
+ "109.230.77.76",
+ "109.230.77.77",
+ "109.230.77.78",
+ "109.230.77.79",
+ "109.230.78.3",
+ "109.230.78.13",
+ "109.230.78.86",
+ "109.230.78.113",
+ "109.230.78.114",
+ "109.230.78.115",
+ "109.230.78.116",
+ "109.230.78.117",
+ "109.230.78.118",
+ "109.230.78.119",
+ "109.230.78.120",
+ "109.230.78.121",
+ "109.230.78.122",
+ "109.230.78.123",
+ "109.230.78.124",
+ "109.230.78.125",
+ "109.230.78.126",
+ "109.230.78.245",
+ "109.230.79.1",
+ "109.230.79.2",
+ "109.230.79.4",
+ "109.230.79.10",
+ "109.230.79.198",
+ "109.230.79.208",
+ "109.230.79.248",
+ "109.230.79.250",
+ "109.230.79.251",
+ "109.230.80.126",
+ "109.230.80.186",
+ "109.230.80.218",
+ "109.230.80.219",
+ "109.230.80.220",
+ "109.230.80.221",
+ "109.230.80.222",
+ "109.230.80.242",
+ "109.230.81.50",
+ "109.230.81.54",
+ "109.230.81.98",
+ "109.230.81.102",
+ "109.230.81.201",
+ "109.230.82.70",
+ "109.230.83.155",
+ "109.230.83.210",
+ "109.230.83.212",
+ "109.230.83.214",
+ "109.230.83.245",
+ "109.230.88.22",
+ "109.230.88.42",
+ "109.230.88.226",
+ "109.230.88.234",
+ "109.230.88.235",
+ "109.230.88.236",
+ "109.230.88.237",
+ "109.230.89.114",
+ "109.230.89.115",
+ "109.230.89.116",
+ "109.230.89.118",
+ "109.230.89.126",
+ "109.230.89.139",
+ "109.230.89.140",
+ "109.230.89.154",
+ "109.230.89.155",
+ "109.230.89.156",
+ "109.230.89.158",
+ "109.230.89.210",
+ "109.230.90.146",
+ "109.230.90.238",
+ "109.230.91.226",
+ "109.230.91.227",
+ "109.230.91.228",
+ "109.230.92.98",
+ "109.230.92.158",
+ "109.230.92.166",
+ "109.230.92.174",
+ "109.230.92.178",
+ "109.230.92.182",
+ "109.230.92.242",
+ "109.230.93.51",
+ "109.230.93.82",
+ "109.230.93.138",
+ "109.230.93.206",
+ "109.230.94.50",
+ "109.230.94.130",
+ "109.230.94.182",
+ "109.230.95.62",
+ "109.230.95.82",
+ "109.230.95.194",
+ "109.230.95.196",
+ "109.230.95.208",
+ "109.230.95.226",
+ "109.230.95.234",
+ "109.230.200.83",
+ "109.230.200.84",
+ "109.230.200.85",
+ "109.230.204.64",
+ "109.230.205.174",
+ "109.230.221.18",
+ "109.230.221.19",
+ "109.230.221.20",
+ "109.230.221.66",
+ "109.230.221.67",
+ "109.230.221.221",
+ "109.230.221.225",
+ "109.230.242.53",
+ "109.230.242.90",
+ "109.230.242.227",
+ "109.232.0.34",
+ "109.232.0.36",
+ "109.232.0.76",
+ "109.232.0.85",
+ "109.232.0.248",
+ "109.232.0.250",
+ "109.232.0.251",
+ "109.232.1.46",
+ "109.232.1.84",
+ "109.232.1.105",
+ "109.232.1.145",
+ "109.232.1.158",
+ "109.232.1.255",
+ "109.232.2.7",
+ "109.232.2.13",
+ "109.232.2.31",
+ "109.232.2.44",
+ "109.232.2.73",
+ "109.232.2.74",
+ "109.232.2.107",
+ "109.232.2.227",
+ "109.232.2.253",
+ "109.232.2.255",
+ "109.232.3.3",
+ "109.232.3.10",
+ "109.232.3.11",
+ "109.232.3.87",
+ "109.232.3.108",
+ "109.232.3.128",
+ "109.232.3.205",
+ "109.232.4.34",
+ "109.232.4.53",
+ "109.232.4.54",
+ "109.232.4.83",
+ "109.238.181.9",
+ "109.238.187.93",
+ "109.238.187.241",
+ "109.238.187.246",
+ "109.238.188.49",
+ "109.238.188.148",
+ "109.238.188.149",
+ "109.238.189.70",
+ "109.238.190.41",
+ "109.238.190.49",
+ "109.238.190.93",
+ "109.238.191.34",
+ "109.238.191.225",
+ "128.65.176.41",
+ "128.65.176.57",
+ "128.65.176.64",
+ "128.65.176.82",
+ "128.65.176.139",
+ "128.65.176.154",
+ "128.65.177.117",
+ "128.65.177.254",
+ "128.65.178.130",
+ "128.65.178.172",
+ "128.65.178.213",
+ "128.65.179.52",
+ "128.65.179.62",
+ "128.65.179.126",
+ "128.65.179.151",
+ "128.65.179.177",
+ "128.65.179.229",
+ "128.65.179.252",
+ "128.65.181.35",
+ "128.65.181.50",
+ "128.65.181.122",
+ "128.65.181.167",
+ "128.65.181.224",
+ "128.65.181.247",
+ "128.65.182.14",
+ "128.65.182.27",
+ "128.65.182.34",
+ "128.65.182.87",
+ "128.65.183.18",
+ "128.65.183.128",
+ "128.65.183.141",
+ "128.65.183.144",
+ "128.65.183.194",
+ "128.65.184.36",
+ "128.65.184.66",
+ "128.65.184.84",
+ "128.65.184.195",
+ "128.65.184.207",
+ "128.65.185.45",
+ "128.65.185.82",
+ "128.65.185.167",
+ "128.65.185.227",
+ "128.65.185.247",
+ "128.65.186.99",
+ "128.65.187.46",
+ "128.65.188.23",
+ "128.65.188.67",
+ "128.65.188.113",
+ "128.65.188.209",
+ "128.65.189.162",
+ "128.65.190.48",
+ "128.65.190.182",
+ "128.65.191.19",
+ "130.185.72.101",
+ "130.185.72.147",
+ "130.185.72.188",
+ "130.185.72.220",
+ "130.185.72.222",
+ "130.185.72.239",
+ "130.185.73.133",
+ "130.185.73.173",
+ "130.185.73.202",
+ "130.185.73.213",
+ "130.185.74.10",
+ "130.185.74.55",
+ "130.185.74.182",
+ "130.185.74.196",
+ "130.185.74.200",
+ "130.185.75.48",
+ "130.185.75.161",
+ "130.185.75.199",
+ "130.185.76.29",
+ "130.185.76.93",
+ "130.185.76.98",
+ "130.185.76.159",
+ "130.185.76.167",
+ "130.185.76.186",
+ "130.185.76.222",
+ "130.185.76.242",
+ "130.185.77.163",
+ "130.185.77.211",
+ "130.185.77.223",
+ "130.185.77.235",
+ "130.185.78.32",
+ "130.185.78.97",
+ "130.193.77.3",
+ "130.193.77.65",
+ "130.193.77.72",
+ "130.193.77.135",
+ "130.193.77.200",
+ "134.255.200.202",
+ "134.255.201.90",
+ "134.255.201.198",
+ "134.255.206.5",
+ "146.19.212.24",
+ "146.19.212.29",
+ "146.19.212.90",
+ "146.19.212.125",
+ "146.19.212.169",
+ "146.19.212.189",
+ "151.232.1.192",
+ "151.232.1.193",
+ "151.232.1.194",
+ "151.232.1.197",
+ "151.232.1.198",
+ "151.232.1.199",
+ "151.232.1.201",
+ "151.232.2.118",
+ "151.232.3.162",
+ "151.232.8.14",
+ "151.232.8.80",
+ "151.232.8.82",
+ "151.232.8.84",
+ "151.232.8.85",
+ "151.232.8.87",
+ "151.232.8.88",
+ "151.232.8.89",
+ "151.232.8.94",
+ "151.232.9.3",
+ "151.232.9.48",
+ "151.232.9.64",
+ "151.232.9.222",
+ "151.232.17.161",
+ "151.232.18.66",
+ "151.232.18.69",
+ "151.232.23.53",
+ "151.232.36.11",
+ "151.232.36.129",
+ "151.232.37.137",
+ "151.232.76.21",
+ "151.232.76.142",
+ "151.232.80.214",
+ "151.232.81.227",
+ "151.232.83.174",
+ "151.232.83.205",
+ "151.232.84.74",
+ "151.232.87.195",
+ "151.232.124.57",
+ "151.232.130.87",
+ "151.232.143.14",
+ "151.232.143.214",
+ "151.232.193.44",
+ "151.232.195.120",
+ "151.232.201.125",
+ "151.232.202.148",
+ "151.232.203.139",
+ "151.232.207.162",
+ "151.233.48.38",
+ "151.233.48.61",
+ "151.233.48.113",
+ "151.233.49.80",
+ "151.233.49.238",
+ "151.233.50.9",
+ "151.233.50.51",
+ "151.233.50.57",
+ "151.233.50.58",
+ "151.233.50.82",
+ "151.233.50.91",
+ "151.233.50.158",
+ "151.233.50.203",
+ "151.233.50.251",
+ "151.233.51.43",
+ "151.233.51.64",
+ "151.233.51.90",
+ "151.233.51.169",
+ "151.233.51.187",
+ "151.233.51.192",
+ "151.233.51.208",
+ "151.233.51.223",
+ "151.233.51.239",
+ "151.233.52.97",
+ "151.233.52.245",
+ "151.233.52.255",
+ "151.233.53.29",
+ "151.233.53.53",
+ "151.233.53.100",
+ "151.233.53.106",
+ "151.233.53.170",
+ "151.233.53.226",
+ "151.233.54.20",
+ "151.233.54.44",
+ "151.233.54.60",
+ "151.233.54.65",
+ "151.233.54.80",
+ "151.233.54.182",
+ "151.233.54.240",
+ "151.233.55.15",
+ "151.233.55.108",
+ "151.233.55.125",
+ "151.233.55.133",
+ "151.233.55.149",
+ "151.233.56.140",
+ "151.233.56.149",
+ "151.233.56.164",
+ "151.233.57.7",
+ "151.233.57.13",
+ "151.233.57.89",
+ "151.233.57.129",
+ "151.233.57.151",
+ "151.233.57.182",
+ "151.233.57.255",
+ "151.233.58.3",
+ "151.233.58.16",
+ "151.233.58.74",
+ "151.233.58.92",
+ "151.233.58.93",
+ "151.233.58.227",
+ "151.233.59.39",
+ "151.233.59.136",
+ "151.233.75.0",
+ "151.233.76.239",
+ "151.233.81.99",
+ "151.233.89.126",
+ "151.233.103.231",
+ "151.233.144.2",
+ "151.233.170.0",
+ "151.233.172.5",
+ "151.234.24.238",
+ "151.234.25.204",
+ "151.234.26.244",
+ "151.234.27.0",
+ "151.234.27.197",
+ "151.234.29.147",
+ "151.234.30.219",
+ "151.234.30.223",
+ "151.234.31.188",
+ "151.234.31.191",
+ "151.234.31.221",
+ "151.234.72.89",
+ "151.234.73.63",
+ "151.234.73.92",
+ "151.234.73.155",
+ "151.234.75.100",
+ "151.234.75.105",
+ "151.234.77.38",
+ "151.234.77.219",
+ "151.234.87.1",
+ "151.234.87.40",
+ "151.234.87.114",
+ "151.234.87.165",
+ "151.234.87.194",
+ "151.234.87.210",
+ "151.234.87.211",
+ "151.234.87.242",
+ "151.234.92.135",
+ "151.234.113.106",
+ "151.234.115.64",
+ "151.234.150.188",
+ "151.234.151.114",
+ "151.234.156.241",
+ "151.234.157.118",
+ "151.234.158.28",
+ "151.234.158.113",
+ "151.234.158.197",
+ "151.234.161.54",
+ "151.234.161.74",
+ "151.234.161.176",
+ "151.234.161.204",
+ "151.234.161.224",
+ "151.234.161.241",
+ "151.234.161.242",
+ "151.234.161.244",
+ "151.234.186.191",
+ "151.234.189.135",
+ "151.234.191.195",
+ "151.234.191.217",
+ "151.234.213.48",
+ "151.234.219.129",
+ "151.234.225.130",
+ "151.234.226.164",
+ "151.234.242.190",
+ "151.234.245.221",
+ "151.234.249.4",
+ "151.234.249.182",
+ "151.234.249.224",
+ "151.234.250.47",
+ "151.234.251.59",
+ "151.234.251.135",
+ "151.235.0.146",
+ "151.235.0.237",
+ "151.235.5.101",
+ "151.235.10.118",
+ "151.235.10.218",
+ "151.235.11.43",
+ "151.235.11.227",
+ "151.235.13.114",
+ "151.235.13.222",
+ "151.235.13.252",
+ "151.235.17.25",
+ "151.235.18.33",
+ "151.235.18.73",
+ "151.235.28.168",
+ "151.235.29.252",
+ "151.235.34.200",
+ "151.235.34.224",
+ "151.235.36.180",
+ "151.235.37.161",
+ "151.235.128.57",
+ "151.235.128.147",
+ "151.235.128.153",
+ "151.235.129.153",
+ "151.235.130.71",
+ "151.235.133.10",
+ "151.235.134.174",
+ "151.235.135.50",
+ "151.235.135.181",
+ "151.235.135.186",
+ "151.235.136.191",
+ "151.235.136.230",
+ "151.235.137.37",
+ "151.235.138.46",
+ "151.235.138.247",
+ "151.235.140.42",
+ "151.235.140.80",
+ "151.235.140.246",
+ "151.235.141.196",
+ "151.235.142.241",
+ "151.235.164.118",
+ "151.235.165.6",
+ "151.235.167.214",
+ "151.235.169.72",
+ "151.235.175.211",
+ "151.235.180.120",
+ "151.235.183.250",
+ "151.235.186.159",
+ "151.235.187.218",
+ "151.235.188.185",
+ "151.235.190.187",
+ "151.235.190.205",
+ "151.235.192.69",
+ "151.235.193.122",
+ "151.235.196.22",
+ "151.235.197.125",
+ "151.235.198.102",
+ "151.235.201.56",
+ "151.235.201.162",
+ "151.235.204.31",
+ "151.235.206.184",
+ "151.235.208.44",
+ "151.235.210.61",
+ "151.235.210.73",
+ "151.235.212.131",
+ "151.235.213.71",
+ "151.235.214.4",
+ "151.235.215.175",
+ "151.235.215.224",
+ "151.235.216.23",
+ "151.235.216.27",
+ "151.235.217.215",
+ "151.235.218.134",
+ "151.235.220.179",
+ "151.235.220.218",
+ "151.235.221.71",
+ "151.235.223.17",
+ "151.235.224.240",
+ "151.235.225.172",
+ "151.235.227.237",
+ "151.235.229.66",
+ "151.235.229.140",
+ "151.235.229.210",
+ "151.235.232.49",
+ "151.235.233.108",
+ "151.235.233.146",
+ "151.235.234.18",
+ "151.235.234.38",
+ "151.235.236.56",
+ "151.235.236.152",
+ "151.235.237.71",
+ "151.235.237.171",
+ "151.235.239.155",
+ "151.235.239.169",
+ "151.235.239.212",
+ "151.235.240.147",
+ "151.235.242.23",
+ "151.235.243.133",
+ "151.235.249.16",
+ "151.235.250.210",
+ "151.235.253.108",
+ "151.235.253.221",
+ "151.235.254.196",
+ "151.235.255.118",
+ "151.235.255.131",
+ "151.238.184.86",
+ "151.238.184.246",
+ "151.238.185.102",
+ "151.238.186.13",
+ "151.238.186.173",
+ "151.238.187.46",
+ "151.238.187.116",
+ "151.238.190.155",
+ "151.238.190.165",
+ "151.238.193.134",
+ "151.238.193.178",
+ "151.238.193.182",
+ "151.238.194.110",
+ "151.238.195.0",
+ "151.238.195.35",
+ "151.238.196.29",
+ "151.238.196.207",
+ "151.238.196.251",
+ "151.238.197.123",
+ "151.238.198.106",
+ "151.238.198.134",
+ "151.238.204.159",
+ "151.238.205.88",
+ "151.238.205.150",
+ "151.238.207.135",
+ "151.238.207.197",
+ "151.238.208.237",
+ "151.238.208.239",
+ "151.238.209.137",
+ "151.238.210.27",
+ "151.238.210.154",
+ "151.238.211.61",
+ "151.238.212.194",
+ "151.238.212.219",
+ "151.238.213.21",
+ "151.238.213.62",
+ "151.238.213.99",
+ "151.238.216.107",
+ "151.238.218.31",
+ "151.238.218.114",
+ "151.238.220.172",
+ "151.238.220.253",
+ "151.238.222.203",
+ "151.238.222.237",
+ "151.238.223.235",
+ "151.238.224.2",
+ "151.238.225.244",
+ "151.238.226.19",
+ "151.238.232.186",
+ "151.238.233.90",
+ "151.238.234.231",
+ "151.238.240.186",
+ "151.238.242.23",
+ "151.238.243.33",
+ "151.238.244.103",
+ "151.238.248.152",
+ "151.238.248.203",
+ "151.238.250.71",
+ "151.238.251.250",
+ "151.238.252.32",
+ "151.238.252.162",
+ "151.238.253.25",
+ "151.238.253.54",
+ "151.238.254.63",
+ "151.238.254.142",
+ "151.238.254.254",
+ "151.238.255.176",
+ "151.239.1.37",
+ "151.239.1.66",
+ "151.239.11.99",
+ "151.239.11.159",
+ "151.239.14.27",
+ "151.239.14.73",
+ "151.239.15.154",
+ "151.239.15.226",
+ "151.239.16.160",
+ "151.239.17.80",
+ "151.239.18.84",
+ "151.239.18.137",
+ "151.239.18.224",
+ "151.239.19.56",
+ "151.239.19.131",
+ "151.239.19.178",
+ "151.239.22.1",
+ "151.239.22.42",
+ "151.239.22.65",
+ "151.239.24.135",
+ "151.239.25.75",
+ "151.239.25.111",
+ "151.239.38.241",
+ "151.239.39.41",
+ "151.239.40.194",
+ "151.239.40.206",
+ "151.239.40.239",
+ "151.239.42.33",
+ "151.239.42.90",
+ "151.239.43.114",
+ "151.239.44.93",
+ "151.239.44.204",
+ "151.239.45.80",
+ "151.239.45.162",
+ "151.239.49.100",
+ "151.239.51.84",
+ "151.239.52.50",
+ "151.239.52.84",
+ "151.239.55.108",
+ "151.239.57.23",
+ "151.239.57.138",
+ "151.239.57.141",
+ "151.239.57.144",
+ "151.239.59.104",
+ "151.239.60.8",
+ "151.239.60.48",
+ "151.239.62.85",
+ "151.239.63.111",
+ "151.239.64.86",
+ "151.239.64.154",
+ "151.239.64.179",
+ "151.239.66.174",
+ "151.239.69.194",
+ "151.239.72.162",
+ "151.239.76.67",
+ "151.239.76.69",
+ "151.239.76.126",
+ "151.239.77.139",
+ "151.239.79.39",
+ "151.239.79.85",
+ "151.239.79.146",
+ "151.239.87.78",
+ "151.239.88.240",
+ "151.239.89.88",
+ "151.239.89.147",
+ "151.239.89.152",
+ "151.239.89.215",
+ "151.239.91.162",
+ "151.239.92.206",
+ "151.239.94.229",
+ "151.239.95.199",
+ "151.239.96.66",
+ "151.239.97.53",
+ "151.239.98.194",
+ "151.239.100.227",
+ "151.239.103.11",
+ "151.239.103.119",
+ "151.239.104.254",
+ "151.239.105.172",
+ "151.239.105.228",
+ "151.239.111.149",
+ "151.239.112.50",
+ "151.239.113.8",
+ "151.239.113.218",
+ "151.239.113.242",
+ "151.239.114.86",
+ "151.239.115.141",
+ "151.239.116.70",
+ "151.239.116.152",
+ "151.239.117.135",
+ "157.119.188.208",
+ "157.119.188.209",
+ "157.119.188.218",
+ "157.119.191.243",
+ "157.119.191.244",
+ "157.119.191.249",
+ "158.58.184.98",
+ "158.58.185.43",
+ "158.58.185.106",
+ "158.58.185.170",
+ "158.58.187.5",
+ "158.58.187.21",
+ "158.58.187.43",
+ "158.58.187.140",
+ "158.58.187.188",
+ "158.58.188.22",
+ "158.58.190.44",
+ "158.255.74.7",
+ "158.255.74.18",
+ "158.255.74.28",
+ "158.255.74.37",
+ "158.255.74.92",
+ "158.255.74.139",
+ "158.255.74.161",
+ "158.255.74.222",
+ "158.255.74.227",
+ "159.20.96.100",
+ "159.20.102.234",
+ "159.20.109.48",
+ "164.138.16.46",
+ "164.138.16.181",
+ "164.138.16.191",
+ "164.138.17.234",
+ "164.138.18.73",
+ "164.138.19.203",
+ "164.138.19.217",
+ "164.138.19.218",
+ "164.138.19.219",
+ "164.138.19.220",
+ "164.138.19.221",
+ "164.138.20.154",
+ "164.138.21.3",
+ "164.138.22.115",
+ "164.138.22.116",
+ "164.138.128.0",
+ "164.138.128.1",
+ "164.138.128.2",
+ "164.138.128.3",
+ "164.138.128.7",
+ "164.138.128.8",
+ "164.138.203.1",
+ "164.215.59.116",
+ "171.22.24.19",
+ "171.22.24.71",
+ "171.22.24.99",
+ "171.22.24.173",
+ "171.22.24.213",
+ "171.22.25.17",
+ "171.22.25.38",
+ "171.22.25.67",
+ "171.22.25.74",
+ "171.22.25.85",
+ "171.22.25.184",
+ "171.22.26.61",
+ "171.22.26.65",
+ "171.22.26.71",
+ "171.22.26.213",
+ "171.22.27.22",
+ "171.22.27.105",
+ "171.22.27.186",
+ "176.10.95.144",
+ "176.10.95.176",
+ "176.10.95.225",
+ "176.10.95.253",
+ "176.65.176.61",
+ "176.65.177.21",
+ "176.65.177.237",
+ "176.65.178.227",
+ "176.65.180.244",
+ "176.65.183.179",
+ "176.65.184.237",
+ "176.65.187.129",
+ "176.65.191.87",
+ "176.65.191.237",
+ "176.65.232.19",
+ "176.65.233.3",
+ "176.65.238.47",
+ "176.65.240.82",
+ "176.65.240.83",
+ "176.65.240.84",
+ "176.65.240.85",
+ "176.65.240.86",
+ "176.65.240.88",
+ "176.65.240.90",
+ "176.65.240.91",
+ "176.65.240.92",
+ "176.65.240.93",
+ "176.65.240.94",
+ "176.65.240.130",
+ "176.65.241.110",
+ "176.65.241.163",
+ "176.65.241.166",
+ "176.65.241.194",
+ "176.65.241.236",
+ "176.65.242.68",
+ "176.65.242.100",
+ "176.65.242.130",
+ "176.65.242.132",
+ "176.65.243.55",
+ "176.65.243.237",
+ "176.65.243.245",
+ "176.65.252.2",
+ "176.65.252.15",
+ "176.65.252.26",
+ "176.65.252.29",
+ "176.65.252.53",
+ "176.65.252.60",
+ "176.65.252.71",
+ "176.65.252.72",
+ "176.65.252.96",
+ "176.65.252.116",
+ "176.65.252.150",
+ "176.65.252.198",
+ "176.65.252.214",
+ "176.65.252.243",
+ "176.65.253.21",
+ "176.65.253.32",
+ "176.65.253.44",
+ "176.65.253.49",
+ "176.65.253.69",
+ "176.65.253.87",
+ "176.65.253.132",
+ "176.65.253.135",
+ "176.65.253.149",
+ "176.65.253.205",
+ "176.65.253.240",
+ "176.65.253.241",
+ "176.65.253.242",
+ "176.65.253.243",
+ "176.65.253.244",
+ "176.65.253.245",
+ "176.65.253.246",
+ "176.65.253.255",
+ "176.65.254.50",
+ "176.65.254.80",
+ "176.65.254.85",
+ "176.65.254.86",
+ "176.65.254.120",
+ "176.65.254.121",
+ "176.65.254.130",
+ "176.65.254.162",
+ "176.65.254.202",
+ "176.65.254.212",
+ "176.65.254.239",
+ "176.65.254.241",
+ "176.97.218.20",
+ "176.97.218.22",
+ "176.97.218.39",
+ "176.97.218.55",
+ "176.97.218.184",
+ "176.97.220.65",
+ "176.97.220.149",
+ "176.101.32.2",
+ "176.101.32.62",
+ "176.101.32.90",
+ "176.101.32.98",
+ "176.101.32.146",
+ "176.101.32.200",
+ "176.101.33.190",
+ "176.101.33.214",
+ "176.101.48.250",
+ "176.102.224.50",
+ "176.102.233.11",
+ "176.102.233.253",
+ "176.102.240.123",
+ "176.102.240.200",
+ "176.102.251.1",
+ "176.102.253.1",
+ "176.120.16.220",
+ "176.120.16.242",
+ "176.122.210.1",
+ "176.122.210.5",
+ "176.122.210.9",
+ "176.122.210.13",
+ "176.122.210.17",
+ "176.122.210.21",
+ "176.122.210.25",
+ "176.122.210.29",
+ "176.122.210.34",
+ "176.122.210.37",
+ "176.122.210.40",
+ "176.122.210.41",
+ "176.122.210.42",
+ "176.122.210.43",
+ "176.122.210.44",
+ "176.122.210.45",
+ "176.122.210.46",
+ "176.122.210.57",
+ "176.122.210.89",
+ "176.122.210.97",
+ "176.122.210.101",
+ "176.122.210.190",
+ "176.122.211.0",
+ "176.122.211.48",
+ "176.122.211.255",
+ "176.221.66.2",
+ "176.221.66.9",
+ "178.21.161.14",
+ "178.21.161.139",
+ "178.21.163.54",
+ "178.21.163.66",
+ "178.21.163.83",
+ "178.21.163.84",
+ "178.21.163.85",
+ "178.21.164.176",
+ "178.21.164.177",
+ "178.22.121.211",
+ "178.22.121.213",
+ "178.22.121.254",
+ "178.22.122.102",
+ "178.22.122.246",
+ "178.22.122.250",
+ "178.22.122.253",
+ "178.22.123.6",
+ "178.22.126.90",
+ "178.131.9.23",
+ "178.131.16.8",
+ "178.131.17.162",
+ "178.131.17.214",
+ "178.131.18.13",
+ "178.131.18.63",
+ "178.131.19.140",
+ "178.131.19.192",
+ "178.131.20.57",
+ "178.131.20.111",
+ "178.131.20.156",
+ "178.131.20.180",
+ "178.131.23.33",
+ "178.131.28.7",
+ "178.131.30.3",
+ "178.131.30.244",
+ "178.131.40.9",
+ "178.131.40.56",
+ "178.131.40.83",
+ "178.131.41.99",
+ "178.131.41.212",
+ "178.131.42.225",
+ "178.131.42.254",
+ "178.131.43.32",
+ "178.131.43.78",
+ "178.131.44.3",
+ "178.131.44.142",
+ "178.131.46.16",
+ "178.131.47.218",
+ "178.131.47.220",
+ "178.131.48.19",
+ "178.131.49.249",
+ "178.131.50.56",
+ "178.131.50.203",
+ "178.131.51.39",
+ "178.131.54.56",
+ "178.131.55.72",
+ "178.131.57.93",
+ "178.131.59.45",
+ "178.131.59.80",
+ "178.131.61.47",
+ "178.131.62.127",
+ "178.131.63.36",
+ "178.131.63.166",
+ "178.131.63.182",
+ "178.131.63.206",
+ "178.131.64.50",
+ "178.131.64.66",
+ "178.131.65.18",
+ "178.131.65.111",
+ "178.131.65.232",
+ "178.131.66.192",
+ "178.131.67.252",
+ "178.131.68.20",
+ "178.131.68.123",
+ "178.131.69.104",
+ "178.131.69.213",
+ "178.131.70.80",
+ "178.131.71.200",
+ "178.131.73.105",
+ "178.131.73.211",
+ "178.131.74.27",
+ "178.131.74.97",
+ "178.131.76.7",
+ "178.131.77.156",
+ "178.131.77.251",
+ "178.131.78.185",
+ "178.131.78.222",
+ "178.131.78.227",
+ "178.131.79.133",
+ "178.131.79.169",
+ "178.131.80.5",
+ "178.131.80.23",
+ "178.131.80.41",
+ "178.131.82.47",
+ "178.131.83.57",
+ "178.131.84.118",
+ "178.131.85.103",
+ "178.131.86.77",
+ "178.131.86.133",
+ "178.131.86.141",
+ "178.131.87.166",
+ "178.131.87.170",
+ "178.131.88.87",
+ "178.131.88.156",
+ "178.131.89.205",
+ "178.131.89.249",
+ "178.131.90.103",
+ "178.131.93.109",
+ "178.131.93.112",
+ "178.131.93.188",
+ "178.131.93.195",
+ "178.131.93.205",
+ "178.131.102.148",
+ "178.131.105.110",
+ "178.131.107.34",
+ "178.131.108.6",
+ "178.131.109.241",
+ "178.131.110.99",
+ "178.131.111.49",
+ "178.131.114.21",
+ "178.131.115.48",
+ "178.131.116.190",
+ "178.131.125.33",
+ "178.131.126.12",
+ "178.131.133.113",
+ "178.131.140.116",
+ "178.131.142.33",
+ "178.131.142.190",
+ "178.131.145.1",
+ "178.131.157.34",
+ "178.131.165.18",
+ "178.131.172.252",
+ "178.131.177.36",
+ "178.131.180.73",
+ "178.131.181.136",
+ "178.131.181.227",
+ "178.131.182.149",
+ "178.131.182.155",
+ "178.131.183.122",
+ "178.131.183.130",
+ "178.131.190.216",
+ "178.131.190.237",
+ "178.157.0.86",
+ "178.157.0.113",
+ "178.157.0.140",
+ "178.157.0.144",
+ "178.157.0.166",
+ "178.173.128.88",
+ "178.173.130.10",
+ "178.173.130.36",
+ "178.173.131.93",
+ "178.173.131.128",
+ "178.173.132.25",
+ "178.173.132.37",
+ "178.173.132.86",
+ "178.173.132.104",
+ "178.173.132.114",
+ "178.173.132.117",
+ "178.173.134.42",
+ "178.173.134.57",
+ "178.173.134.72",
+ "178.173.134.183",
+ "178.173.134.236",
+ "178.173.134.239",
+ "178.173.137.96",
+ "178.173.137.140",
+ "178.173.137.176",
+ "178.173.137.192",
+ "178.173.137.215",
+ "178.173.137.231",
+ "178.173.138.53",
+ "178.173.138.169",
+ "178.173.138.235",
+ "178.173.138.252",
+ "178.173.139.11",
+ "178.173.139.49",
+ "178.173.139.120",
+ "178.173.139.149",
+ "178.173.139.171",
+ "178.173.139.173",
+ "178.173.139.237",
+ "178.173.140.148",
+ "178.173.140.161",
+ "178.173.140.250",
+ "178.173.141.63",
+ "178.173.141.83",
+ "178.173.141.147",
+ "178.173.141.158",
+ "178.173.141.194",
+ "178.173.141.244",
+ "178.173.142.5",
+ "178.173.142.37",
+ "178.173.142.68",
+ "178.173.142.134",
+ "178.173.142.159",
+ "178.173.142.173",
+ "178.173.142.206",
+ "178.173.142.210",
+ "178.173.142.219",
+ "178.173.143.29",
+ "178.173.143.50",
+ "178.173.143.112",
+ "178.173.143.150",
+ "178.173.143.209",
+ "178.173.144.45",
+ "178.173.144.59",
+ "178.173.144.71",
+ "178.173.144.149",
+ "178.173.144.175",
+ "178.173.144.240",
+ "178.173.145.17",
+ "178.173.145.83",
+ "178.173.145.149",
+ "178.173.145.217",
+ "178.173.147.25",
+ "178.173.147.43",
+ "178.173.147.58",
+ "178.173.147.132",
+ "178.173.147.133",
+ "178.173.147.149",
+ "178.173.147.169",
+ "178.173.147.238",
+ "178.173.147.240",
+ "178.173.147.242",
+ "178.173.148.20",
+ "178.173.148.128",
+ "178.173.148.129",
+ "178.173.148.130",
+ "178.173.148.140",
+ "178.173.148.142",
+ "178.173.148.143",
+ "178.173.148.145",
+ "178.173.148.240",
+ "178.173.149.21",
+ "178.173.149.36",
+ "178.173.149.210",
+ "178.173.149.213",
+ "178.173.149.247",
+ "178.173.149.249",
+ "178.173.151.94",
+ "178.173.151.166",
+ "178.173.151.211",
+ "178.173.151.226",
+ "178.173.160.70",
+ "178.173.163.66",
+ "178.173.163.67",
+ "178.173.163.77",
+ "178.173.163.85",
+ "178.173.163.117",
+ "178.173.163.166",
+ "178.173.163.196",
+ "178.173.163.216",
+ "178.173.163.217",
+ "178.173.163.233",
+ "178.173.169.12",
+ "178.173.169.100",
+ "178.173.169.125",
+ "178.173.169.150",
+ "178.173.169.179",
+ "178.173.169.203",
+ "178.173.170.42",
+ "178.173.170.68",
+ "178.173.170.124",
+ "178.173.170.222",
+ "178.173.170.250",
+ "178.173.171.58",
+ "178.173.171.242",
+ "178.173.171.243",
+ "178.173.171.244",
+ "178.173.171.245",
+ "178.173.171.246",
+ "178.173.171.247",
+ "178.173.171.248",
+ "178.173.171.250",
+ "178.173.171.251",
+ "178.173.172.10",
+ "178.173.172.71",
+ "178.173.172.74",
+ "178.173.172.241",
+ "178.173.172.243",
+ "178.173.172.245",
+ "178.173.172.247",
+ "178.173.172.252",
+ "178.173.174.145",
+ "178.173.174.182",
+ "178.173.174.240",
+ "178.173.175.47",
+ "178.173.175.84",
+ "178.173.175.90",
+ "178.173.175.91",
+ "178.173.175.156",
+ "178.173.175.199",
+ "178.173.175.227",
+ "178.173.182.27",
+ "178.173.182.40",
+ "178.173.182.48",
+ "178.173.182.128",
+ "178.173.182.186",
+ "178.173.182.213",
+ "178.173.182.249",
+ "178.173.183.19",
+ "178.173.183.81",
+ "178.173.183.168",
+ "178.173.183.233",
+ "178.173.184.106",
+ "178.173.184.232",
+ "178.173.186.80",
+ "178.173.186.121",
+ "178.173.186.157",
+ "178.173.186.186",
+ "178.173.186.229",
+ "178.173.186.253",
+ "178.173.187.45",
+ "178.173.187.47",
+ "178.173.187.62",
+ "178.173.187.92",
+ "178.173.187.115",
+ "178.173.187.122",
+ "178.173.187.164",
+ "178.173.187.179",
+ "178.173.187.182",
+ "178.173.187.223",
+ "178.173.188.9",
+ "178.173.188.128",
+ "178.173.188.133",
+ "178.173.188.191",
+ "178.173.188.207",
+ "178.173.188.240",
+ "178.173.189.15",
+ "178.173.189.35",
+ "178.173.189.43",
+ "178.173.189.78",
+ "178.173.189.133",
+ "178.173.189.141",
+ "178.173.189.189",
+ "178.173.189.207",
+ "178.173.189.213",
+ "178.173.189.247",
+ "178.173.190.62",
+ "178.173.190.222",
+ "178.173.190.244",
+ "178.173.191.3",
+ "178.173.191.149",
+ "178.173.192.32",
+ "178.173.192.122",
+ "178.173.192.139",
+ "178.173.192.146",
+ "178.173.192.169",
+ "178.173.193.10",
+ "178.173.193.45",
+ "178.173.193.78",
+ "178.173.193.84",
+ "178.173.193.139",
+ "178.173.193.144",
+ "178.173.195.24",
+ "178.173.195.52",
+ "178.173.195.60",
+ "178.173.195.70",
+ "178.173.195.86",
+ "178.173.195.123",
+ "178.173.195.138",
+ "178.173.195.163",
+ "178.173.195.170",
+ "178.173.195.188",
+ "178.173.195.195",
+ "178.173.195.243",
+ "178.173.196.45",
+ "178.173.196.164",
+ "178.173.196.212",
+ "178.173.197.82",
+ "178.173.197.132",
+ "178.173.198.3",
+ "178.173.198.16",
+ "178.173.198.25",
+ "178.173.198.39",
+ "178.173.198.237",
+ "178.173.198.246",
+ "178.173.199.48",
+ "178.173.199.76",
+ "178.173.199.162",
+ "178.173.200.44",
+ "178.173.200.72",
+ "178.173.200.107",
+ "178.173.200.212",
+ "178.173.210.128",
+ "178.173.210.212",
+ "178.173.210.249",
+ "178.173.211.22",
+ "178.173.211.33",
+ "178.173.211.80",
+ "178.173.211.164",
+ "178.173.211.177",
+ "178.173.211.240",
+ "178.173.212.39",
+ "178.173.212.168",
+ "178.173.212.169",
+ "178.173.212.171",
+ "178.173.212.203",
+ "178.173.213.48",
+ "178.173.213.51",
+ "178.173.213.112",
+ "178.173.213.217",
+ "178.173.214.85",
+ "178.173.214.152",
+ "178.173.214.172",
+ "178.173.214.250",
+ "178.173.215.25",
+ "178.173.215.57",
+ "178.173.215.89",
+ "178.173.215.92",
+ "178.173.215.166",
+ "178.173.215.168",
+ "178.173.215.212",
+ "178.173.215.236",
+ "178.173.216.34",
+ "178.173.216.40",
+ "178.173.216.131",
+ "178.173.216.159",
+ "178.173.216.190",
+ "178.173.217.29",
+ "178.173.217.145",
+ "178.173.217.253",
+ "178.173.218.29",
+ "178.173.218.35",
+ "178.173.218.64",
+ "178.173.218.107",
+ "178.173.218.214",
+ "178.173.218.220",
+ "178.173.219.10",
+ "178.173.219.128",
+ "178.173.219.229",
+ "178.173.219.242",
+ "178.173.219.251",
+ "178.173.220.55",
+ "178.173.220.103",
+ "178.173.220.146",
+ "178.173.220.160",
+ "178.173.220.161",
+ "178.173.220.215",
+ "178.173.221.2",
+ "178.173.221.9",
+ "178.173.221.46",
+ "178.173.221.125",
+ "178.173.221.195",
+ "178.173.222.2",
+ "178.173.222.3",
+ "178.173.222.177",
+ "178.173.222.200",
+ "178.173.222.206",
+ "178.216.248.235",
+ "178.216.248.236",
+ "178.216.248.237",
+ "178.216.249.213",
+ "178.216.250.190",
+ "178.216.251.236",
+ "178.216.251.237",
+ "178.216.251.238",
+ "178.236.33.129",
+ "178.236.33.161",
+ "178.236.100.59",
+ "178.236.104.48",
+ "178.236.104.118",
+ "178.236.104.192",
+ "178.236.104.240",
+ "178.236.105.223",
+ "178.236.106.91",
+ "178.236.106.227",
+ "178.236.107.71",
+ "178.236.108.175",
+ "178.236.109.34",
+ "178.236.109.97",
+ "178.238.192.60",
+ "178.238.192.112",
+ "178.238.192.166",
+ "178.238.193.205",
+ "178.238.194.22",
+ "178.238.194.118",
+ "178.238.194.139",
+ "178.238.195.99",
+ "178.238.195.240",
+ "178.238.197.73",
+ "178.238.199.3",
+ "178.239.144.129",
+ "178.239.147.133",
+ "178.239.151.4",
+ "178.239.151.49",
+ "178.239.151.80",
+ "178.239.151.94",
+ "178.239.151.158",
+ "178.239.151.229",
+ "178.239.152.57",
+ "178.239.152.145",
+ "178.239.152.150",
+ "178.239.152.160",
+ "178.239.152.179",
+ "178.239.152.184",
+ "178.239.156.1",
+ "178.239.156.5",
+ "178.239.156.56",
+ "178.239.156.61",
+ "178.239.156.67",
+ "178.239.156.126",
+ "178.239.158.66",
+ "178.239.158.129",
+ "178.239.159.73",
+ "178.239.159.160",
+ "178.239.159.255",
+ "178.252.129.30",
+ "178.252.132.125",
+ "178.252.132.217",
+ "178.252.132.218",
+ "178.252.132.222",
+ "178.252.132.228",
+ "178.252.133.85",
+ "178.252.133.222",
+ "178.252.134.178",
+ "178.252.134.213",
+ "178.252.134.229",
+ "178.252.134.238",
+ "178.252.135.2",
+ "178.252.135.26",
+ "178.252.135.53",
+ "178.252.135.54",
+ "178.252.135.117",
+ "178.252.135.196",
+ "178.252.135.202",
+ "178.252.135.206",
+ "178.252.136.2",
+ "178.252.136.18",
+ "178.252.136.130",
+ "178.252.136.132",
+ "178.252.136.133",
+ "178.252.136.250",
+ "178.252.140.98",
+ "178.252.140.99",
+ "178.252.140.104",
+ "178.252.140.107",
+ "178.252.141.50",
+ "178.252.141.134",
+ "178.252.141.226",
+ "178.252.142.78",
+ "178.252.143.22",
+ "178.252.143.99",
+ "178.252.143.102",
+ "178.252.143.234",
+ "178.252.144.18",
+ "178.252.144.58",
+ "178.252.144.102",
+ "178.252.144.240",
+ "178.252.147.35",
+ "178.252.147.54",
+ "178.252.147.65",
+ "178.252.147.82",
+ "178.252.147.83",
+ "178.252.147.84",
+ "178.252.147.85",
+ "178.252.147.86",
+ "178.252.147.122",
+ "178.252.147.123",
+ "178.252.147.124",
+ "178.252.147.146",
+ "178.252.147.148",
+ "178.252.147.150",
+ "178.252.147.154",
+ "178.252.147.186",
+ "178.252.147.187",
+ "178.252.147.188",
+ "178.252.147.189",
+ "178.252.148.204",
+ "178.252.149.202",
+ "178.252.151.18",
+ "178.252.151.22",
+ "178.252.151.42",
+ "178.252.151.43",
+ "178.252.151.44",
+ "178.252.151.46",
+ "178.252.151.154",
+ "178.252.151.162",
+ "178.252.151.238",
+ "178.252.151.250",
+ "178.252.151.251",
+ "178.252.152.56",
+ "178.252.152.57",
+ "178.252.152.58",
+ "178.252.152.61",
+ "178.252.152.62",
+ "178.252.153.106",
+ "178.252.153.122",
+ "178.252.165.24",
+ "178.252.165.82",
+ "178.252.165.83",
+ "178.252.165.84",
+ "178.252.165.85",
+ "178.252.165.102",
+ "178.252.165.118",
+ "178.252.165.193",
+ "178.252.165.230",
+ "178.252.166.10",
+ "178.252.166.98",
+ "178.252.166.153",
+ "178.252.166.182",
+ "178.252.167.51",
+ "178.252.167.90",
+ "178.252.170.106",
+ "178.252.170.166",
+ "178.252.170.222",
+ "178.252.171.70",
+ "178.252.171.74",
+ "178.252.171.226",
+ "178.252.171.228",
+ "178.252.171.229",
+ "178.252.171.234",
+ "178.252.176.10",
+ "178.252.176.68",
+ "178.252.176.115",
+ "178.252.176.130",
+ "178.252.176.131",
+ "178.252.176.146",
+ "178.252.177.6",
+ "178.252.177.8",
+ "178.252.177.10",
+ "178.252.177.12",
+ "178.252.177.170",
+ "178.252.178.205",
+ "178.252.178.209",
+ "178.252.178.210",
+ "178.252.178.222",
+ "178.252.183.28",
+ "178.252.183.99",
+ "178.252.183.250",
+ "178.252.183.251",
+ "178.252.183.252",
+ "178.252.183.253",
+ "178.252.183.254",
+ "178.252.184.70",
+ "178.252.184.138",
+ "178.252.184.139",
+ "178.252.184.141",
+ "178.252.184.154",
+ "178.252.189.82",
+ "178.252.189.83",
+ "178.252.189.84",
+ "178.252.189.213",
+ "178.252.189.214",
+ "178.252.191.19",
+ "178.252.191.163",
+ "178.252.191.164",
+ "178.252.191.169",
+ "185.2.14.94",
+ "185.2.14.253",
+ "185.3.124.62",
+ "185.3.124.83",
+ "185.3.124.85",
+ "185.3.124.86",
+ "185.3.125.2",
+ "185.3.125.3",
+ "185.3.125.4",
+ "185.3.125.87",
+ "185.3.125.144",
+ "185.3.201.197",
+ "185.3.202.42",
+ "185.3.202.57",
+ "185.3.203.19",
+ "185.3.203.77",
+ "185.3.203.84",
+ "185.3.203.85",
+ "185.3.203.91",
+ "185.3.212.76",
+ "185.3.212.141",
+ "185.3.213.61",
+ "185.3.215.200",
+ "185.3.215.226",
+ "185.4.1.24",
+ "185.4.1.25",
+ "185.4.1.45",
+ "185.4.1.96",
+ "185.4.3.2",
+ "185.4.3.73",
+ "185.4.30.6",
+ "185.4.30.46",
+ "185.4.30.58",
+ "185.4.30.72",
+ "185.4.30.100",
+ "185.7.172.1",
+ "185.7.172.2",
+ "185.7.172.7",
+ "185.7.172.17",
+ "185.7.172.33",
+ "185.7.172.49",
+ "185.7.172.65",
+ "185.7.172.81",
+ "185.7.172.97",
+ "185.7.172.113",
+ "185.7.172.129",
+ "185.7.172.145",
+ "185.7.212.35",
+ "185.7.212.89",
+ "185.7.212.133",
+ "185.7.212.150",
+ "185.8.172.49",
+ "185.8.172.207",
+ "185.8.173.27",
+ "185.8.173.91",
+ "185.8.174.13",
+ "185.8.174.184",
+ "185.8.174.207",
+ "185.8.175.44",
+ "185.8.175.153",
+ "185.8.175.187",
+ "185.8.175.229",
+ "185.8.175.241",
+ "185.8.175.249",
+ "185.10.71.235",
+ "185.10.72.124",
+ "185.10.74.112",
+ "185.10.74.234",
+ "185.10.75.77",
+ "185.10.75.108",
+ "185.10.75.113",
+ "185.10.75.119",
+ "185.10.75.121",
+ "185.10.75.196",
+ "185.11.69.55",
+ "185.11.69.56",
+ "185.11.69.148",
+ "185.11.69.150",
+ "185.11.69.174",
+ "185.11.70.18",
+ "185.11.70.55",
+ "185.11.70.211",
+ "185.11.70.217",
+ "185.11.70.230",
+ "185.11.70.233",
+ "185.11.71.169",
+ "185.13.229.253",
+ "185.13.229.254",
+ "185.13.230.46",
+ "185.13.230.116",
+ "185.13.230.155",
+ "185.13.230.158",
+ "185.13.231.49",
+ "185.14.81.252",
+ "185.14.161.36",
+ "185.14.161.67",
+ "185.14.161.82",
+ "185.14.161.84",
+ "185.14.161.85",
+ "185.14.162.5",
+ "185.14.162.18",
+ "185.14.163.162",
+ "185.14.163.163",
+ "185.14.163.164",
+ "185.14.163.165",
+ "185.14.163.166",
+ "185.14.163.167",
+ "185.14.163.168",
+ "185.14.163.169",
+ "185.14.163.170",
+ "185.14.163.171",
+ "185.14.163.172",
+ "185.14.163.174",
+ "185.14.163.210",
+ "185.14.163.234",
+ "185.14.163.235",
+ "185.18.212.67",
+ "185.18.213.26",
+ "185.18.213.47",
+ "185.18.213.67",
+ "185.18.213.76",
+ "185.18.213.98",
+ "185.18.213.180",
+ "185.18.214.4",
+ "185.18.214.120",
+ "185.18.214.138",
+ "185.18.214.244",
+ "185.18.215.26",
+ "185.18.215.36",
+ "185.18.215.38",
+ "185.18.215.90",
+ "185.18.215.208",
+ "185.18.215.240",
+ "185.19.201.102",
+ "185.19.201.188",
+ "185.19.201.193",
+ "185.19.201.199",
+ "185.21.68.53",
+ "185.21.70.41",
+ "185.21.70.233",
+ "185.21.71.46",
+ "185.21.71.199",
+ "185.21.71.216",
+ "185.21.71.246",
+ "185.22.30.174",
+ "185.22.31.226",
+ "185.22.31.227",
+ "185.23.128.147",
+ "185.23.128.148",
+ "185.24.252.43",
+ "185.24.252.65",
+ "185.24.252.76",
+ "185.24.252.111",
+ "185.24.252.115",
+ "185.24.252.129",
+ "185.24.252.242",
+ "185.24.252.250",
+ "185.24.253.1",
+ "185.24.253.8",
+ "185.24.253.48",
+ "185.24.253.65",
+ "185.24.253.96",
+ "185.24.253.120",
+ "185.24.253.129",
+ "185.24.255.109",
+ "185.24.255.115",
+ "185.24.255.161",
+ "185.24.255.169",
+ "185.24.255.187",
+ "185.26.33.213",
+ "185.26.34.227",
+ "185.26.35.47",
+ "185.26.35.242",
+ "185.26.235.53",
+ "185.29.223.233",
+ "185.33.25.86",
+ "185.36.228.170",
+ "185.36.231.37",
+ "185.36.231.53",
+ "185.36.231.140",
+ "185.37.53.144",
+ "185.37.53.146",
+ "185.37.53.147",
+ "185.37.53.148",
+ "185.37.53.149",
+ "185.37.53.150",
+ "185.37.54.10",
+ "185.37.54.186",
+ "185.39.181.6",
+ "185.39.181.17",
+ "185.39.181.21",
+ "185.39.181.23",
+ "185.39.181.92",
+ "185.39.181.110",
+ "185.39.181.142",
+ "185.39.181.179",
+ "185.39.181.229",
+ "185.39.181.243",
+ "185.39.182.34",
+ "185.39.183.157",
+ "185.41.3.5",
+ "185.42.224.170",
+ "185.42.225.68",
+ "185.42.225.74",
+ "185.42.225.90",
+ "185.42.225.196",
+ "185.42.225.199",
+ "185.42.226.26",
+ "185.42.226.27",
+ "185.42.226.28",
+ "185.42.226.30",
+ "185.42.227.93",
+ "185.42.227.94",
+ "185.42.227.238",
+ "185.44.36.3",
+ "185.44.36.30",
+ "185.44.36.50",
+ "185.44.36.193",
+ "185.44.112.13",
+ "185.44.112.170",
+ "185.44.112.206",
+ "185.44.114.153",
+ "185.46.109.0",
+ "185.46.109.2",
+ "185.46.109.10",
+ "185.46.109.123",
+ "185.46.109.126",
+ "185.46.109.127",
+ "185.46.109.130",
+ "185.46.109.131",
+ "185.46.109.146",
+ "185.46.109.149",
+ "185.46.109.151",
+ "185.46.109.161",
+ "185.46.109.167",
+ "185.46.109.172",
+ "185.46.109.175",
+ "185.46.109.179",
+ "185.46.110.92",
+ "185.46.110.122",
+ "185.46.111.43",
+ "185.46.111.45",
+ "185.46.111.74",
+ "185.46.111.106",
+ "185.46.111.219",
+ "185.46.111.228",
+ "185.46.111.231",
+ "185.46.217.105",
+ "185.46.218.77",
+ "185.46.218.127",
+ "185.46.218.198",
+ "185.46.219.18",
+ "185.46.219.87",
+ "185.46.219.126",
+ "185.46.219.220",
+ "185.47.48.6",
+ "185.47.48.10",
+ "185.47.48.13",
+ "185.47.48.14",
+ "185.47.48.131",
+ "185.47.48.178",
+ "185.47.48.201",
+ "185.47.48.225",
+ "185.47.48.253",
+ "185.47.48.254",
+ "185.47.49.46",
+ "185.47.49.53",
+ "185.47.49.89",
+ "185.47.49.127",
+ "185.47.49.138",
+ "185.47.49.168",
+ "185.47.49.172",
+ "185.47.49.226",
+ "185.47.49.229",
+ "185.47.49.245",
+ "185.47.49.252",
+ "185.47.50.62",
+ "185.47.50.95",
+ "185.47.50.238",
+ "185.47.51.2",
+ "185.47.51.201",
+ "185.49.84.122",
+ "185.49.84.123",
+ "185.49.84.124",
+ "185.49.84.125",
+ "185.49.84.126",
+ "185.49.85.202",
+ "185.49.86.35",
+ "185.49.86.228",
+ "185.49.86.229",
+ "185.49.86.230",
+ "185.49.86.241",
+ "185.49.87.156",
+ "185.49.96.168",
+ "185.49.96.207",
+ "185.49.96.209",
+ "185.49.97.49",
+ "185.49.97.69",
+ "185.49.97.83",
+ "185.49.97.108",
+ "185.49.97.170",
+ "185.49.97.186",
+ "185.49.97.187",
+ "185.49.97.228",
+ "185.50.38.1",
+ "185.50.38.2",
+ "185.50.38.3",
+ "185.51.40.10",
+ "185.51.42.255",
+ "185.51.43.96",
+ "185.51.43.130",
+ "185.51.201.68",
+ "185.51.201.69",
+ "185.51.201.70",
+ "185.53.140.9",
+ "185.53.140.14",
+ "185.53.140.18",
+ "185.53.140.20",
+ "185.53.140.25",
+ "185.53.140.37",
+ "185.53.140.38",
+ "185.53.140.69",
+ "185.53.140.75",
+ "185.53.140.85",
+ "185.53.140.106",
+ "185.53.140.107",
+ "185.53.140.119",
+ "185.53.140.122",
+ "185.53.140.147",
+ "185.53.140.150",
+ "185.53.140.151",
+ "185.53.140.155",
+ "185.53.140.157",
+ "185.53.140.181",
+ "185.53.140.184",
+ "185.53.140.186",
+ "185.53.140.187",
+ "185.53.140.189",
+ "185.53.140.194",
+ "185.53.140.195",
+ "185.53.140.196",
+ "185.53.140.198",
+ "185.53.140.206",
+ "185.53.140.238",
+ "185.53.140.239",
+ "185.53.140.240",
+ "185.53.140.242",
+ "185.53.140.243",
+ "185.53.140.245",
+ "185.53.140.246",
+ "185.53.140.248",
+ "185.53.140.249",
+ "185.53.140.250",
+ "185.53.140.251",
+ "185.53.140.252",
+ "185.53.141.101",
+ "185.53.142.12",
+ "185.53.142.44",
+ "185.53.142.101",
+ "185.53.142.248",
+ "185.53.143.13",
+ "185.53.143.50",
+ "185.53.143.51",
+ "185.53.143.52",
+ "185.53.143.53",
+ "185.53.143.55",
+ "185.53.143.56",
+ "185.53.143.57",
+ "185.53.143.58",
+ "185.53.143.59",
+ "185.53.143.60",
+ "185.53.143.78",
+ "185.55.224.58",
+ "185.55.224.79",
+ "185.55.224.89",
+ "185.55.224.92",
+ "185.55.224.95",
+ "185.55.224.103",
+ "185.55.224.115",
+ "185.55.224.131",
+ "185.55.224.193",
+ "185.55.225.101",
+ "185.55.225.158",
+ "185.55.225.176",
+ "185.55.225.189",
+ "185.55.226.19",
+ "185.55.226.25",
+ "185.55.226.40",
+ "185.55.227.25",
+ "185.55.227.38",
+ "185.55.227.43",
+ "185.55.227.52",
+ "185.55.227.90",
+ "185.55.227.101",
+ "185.55.227.121",
+ "185.55.227.143",
+ "185.55.227.147",
+ "185.55.227.188",
+ "185.55.227.200",
+ "185.56.93.29",
+ "185.56.93.30",
+ "185.56.93.70",
+ "185.56.93.122",
+ "185.56.94.1",
+ "185.56.94.16",
+ "185.56.94.17",
+ "185.56.95.186",
+ "185.57.132.27",
+ "185.57.133.62",
+ "185.57.133.109",
+ "185.57.133.140",
+ "185.57.133.235",
+ "185.57.133.245",
+ "185.57.135.9",
+ "185.57.167.225",
+ "185.58.240.145",
+ "185.58.240.165",
+ "185.58.241.128",
+ "185.58.242.64",
+ "185.58.242.113",
+ "185.58.242.220",
+ "185.58.243.169",
+ "185.60.59.2",
+ "185.60.59.3",
+ "185.60.59.4",
+ "185.60.59.73",
+ "185.60.136.28",
+ "185.60.136.65",
+ "185.60.136.74",
+ "185.60.136.193",
+ "185.63.113.12",
+ "185.63.113.164",
+ "185.63.113.165",
+ "185.63.113.206",
+ "185.63.113.216",
+ "185.63.237.10",
+ "185.64.176.19",
+ "185.64.176.103",
+ "185.66.224.14",
+ "185.66.224.110",
+ "185.66.224.148",
+ "185.66.226.43",
+ "185.66.226.130",
+ "185.66.226.235",
+ "185.66.227.59",
+ "185.66.227.102",
+ "185.66.227.113",
+ "185.66.227.115",
+ "185.66.227.118",
+ "185.66.227.123",
+ "185.66.227.124",
+ "185.66.227.224",
+ "185.66.227.227",
+ "185.66.228.1",
+ "185.66.228.2",
+ "185.66.230.18",
+ "185.66.230.155",
+ "185.66.230.255",
+ "185.71.194.140",
+ "185.71.194.141",
+ "185.71.194.153",
+ "185.71.194.163",
+ "185.72.25.85",
+ "185.72.25.86",
+ "185.72.25.94",
+ "185.72.25.95",
+ "185.72.25.121",
+ "185.72.25.122",
+ "185.72.25.124",
+ "185.72.25.130",
+ "185.72.25.146",
+ "185.72.26.62",
+ "185.72.26.114",
+ "185.72.26.146",
+ "185.72.26.147",
+ "185.72.26.148",
+ "185.72.26.149",
+ "185.72.26.150",
+ "185.72.26.218",
+ "185.72.27.50",
+ "185.72.27.97",
+ "185.72.27.162",
+ "185.72.27.232",
+ "185.73.112.114",
+ "185.73.112.123",
+ "185.73.112.253",
+ "185.73.114.228",
+ "185.73.226.235",
+ "185.74.221.11",
+ "185.74.221.12",
+ "185.74.221.14",
+ "185.75.207.100",
+ "185.75.207.210",
+ "185.75.207.223",
+ "185.78.21.48",
+ "185.79.96.35",
+ "185.79.96.36",
+ "185.79.96.37",
+ "185.79.96.92",
+ "185.79.96.93",
+ "185.79.96.94",
+ "185.79.96.123",
+ "185.79.96.124",
+ "185.79.97.2",
+ "185.79.97.5",
+ "185.79.97.19",
+ "185.79.97.131",
+ "185.79.97.132",
+ "185.79.97.133",
+ "185.79.97.195",
+ "185.79.97.196",
+ "185.79.97.197",
+ "185.79.98.131",
+ "185.79.98.132",
+ "185.79.98.133",
+ "185.79.156.39",
+ "185.79.156.55",
+ "185.79.156.77",
+ "185.79.156.82",
+ "185.79.156.109",
+ "185.79.156.170",
+ "185.79.156.191",
+ "185.79.156.208",
+ "185.79.156.209",
+ "185.79.156.210",
+ "185.79.156.211",
+ "185.79.156.212",
+ "185.79.156.213",
+ "185.79.156.230",
+ "185.79.156.238",
+ "185.79.156.239",
+ "185.79.156.251",
+ "185.79.156.253",
+ "185.79.157.130",
+ "185.79.157.131",
+ "185.79.157.133",
+ "185.79.157.162",
+ "185.79.157.190",
+ "185.79.158.12",
+ "185.79.158.14",
+ "185.79.158.19",
+ "185.79.158.133",
+ "185.79.159.130",
+ "185.81.99.52",
+ "185.82.65.172",
+ "185.82.65.205",
+ "185.82.67.2",
+ "185.82.67.35",
+ "185.82.67.36",
+ "185.82.67.37",
+ "185.82.67.144",
+ "185.82.67.146",
+ "185.82.67.147",
+ "185.82.67.169",
+ "185.82.67.175",
+ "185.82.67.178",
+ "185.82.136.149",
+ "185.82.136.163",
+ "185.82.136.188",
+ "185.82.136.207",
+ "185.82.136.215",
+ "185.82.136.250",
+ "185.82.136.254",
+ "185.82.137.14",
+ "185.82.137.18",
+ "185.82.137.24",
+ "185.82.137.33",
+ "185.82.137.47",
+ "185.82.137.55",
+ "185.82.137.84",
+ "185.82.137.97",
+ "185.82.137.100",
+ "185.82.139.9",
+ "185.82.139.114",
+ "185.82.139.124",
+ "185.82.139.140",
+ "185.82.139.168",
+ "185.82.139.206",
+ "185.82.139.227",
+ "185.82.139.237",
+ "185.82.139.238",
+ "185.82.165.10",
+ "185.82.165.66",
+ "185.82.165.110",
+ "185.83.88.9",
+ "185.83.88.11",
+ "185.83.88.13",
+ "185.83.88.15",
+ "185.83.88.18",
+ "185.83.88.22",
+ "185.83.88.44",
+ "185.83.88.66",
+ "185.83.88.89",
+ "185.83.88.112",
+ "185.83.88.113",
+ "185.83.88.118",
+ "185.83.88.156",
+ "185.83.88.162",
+ "185.83.88.190",
+ "185.83.88.193",
+ "185.83.88.241",
+ "185.83.89.114",
+ "185.83.89.194",
+ "185.83.91.236",
+ "185.83.112.19",
+ "185.83.113.29",
+ "185.83.114.220",
+ "185.83.115.121",
+ "185.83.115.122",
+ "185.83.115.193",
+ "185.83.115.204",
+ "185.83.180.41",
+ "185.83.180.145",
+ "185.83.180.151",
+ "185.83.182.20",
+ "185.83.182.90",
+ "185.83.182.197",
+ "185.83.182.218",
+ "185.83.183.96",
+ "185.83.183.126",
+ "185.83.183.137",
+ "185.83.183.162",
+ "185.83.183.251",
+ "185.83.196.13",
+ "185.83.196.14",
+ "185.83.196.17",
+ "185.83.196.30",
+ "185.83.196.90",
+ "185.83.196.102",
+ "185.83.196.134",
+ "185.83.196.150",
+ "185.83.196.249",
+ "185.83.197.42",
+ "185.83.197.43",
+ "185.83.197.45",
+ "185.83.198.154",
+ "185.83.198.156",
+ "185.83.198.162",
+ "185.83.199.83",
+ "185.83.199.96",
+ "185.83.199.99",
+ "185.83.199.100",
+ "185.83.199.101",
+ "185.83.199.102",
+ "185.83.199.123",
+ "185.83.199.178",
+ "185.83.199.234",
+ "185.83.208.134",
+ "185.83.208.166",
+ "185.83.208.181",
+ "185.83.208.185",
+ "185.84.158.17",
+ "185.84.158.36",
+ "185.84.158.55",
+ "185.85.136.1",
+ "185.85.136.3",
+ "185.85.136.5",
+ "185.85.136.12",
+ "185.85.136.18",
+ "185.85.136.21",
+ "185.85.136.22",
+ "185.85.136.24",
+ "185.85.136.26",
+ "185.85.136.39",
+ "185.85.136.253",
+ "185.85.138.130",
+ "185.85.138.200",
+ "185.85.138.201",
+ "185.85.138.202",
+ "185.85.138.203",
+ "185.85.139.201",
+ "185.85.139.203",
+ "185.85.139.205",
+ "185.85.139.206",
+ "185.85.139.207",
+ "185.85.139.208",
+ "185.85.139.209",
+ "185.85.139.210",
+ "185.85.139.211",
+ "185.85.139.212",
+ "185.85.139.213",
+ "185.85.139.214",
+ "185.85.139.215",
+ "185.85.139.217",
+ "185.85.139.218",
+ "185.85.139.219",
+ "185.85.139.222",
+ "185.85.139.223",
+ "185.85.139.240",
+ "185.85.139.242",
+ "185.85.139.243",
+ "185.85.139.245",
+ "185.85.139.246",
+ "185.85.139.247",
+ "185.85.139.248",
+ "185.85.139.249",
+ "185.85.139.250",
+ "185.85.139.251",
+ "185.85.139.252",
+ "185.85.139.253",
+ "185.85.139.254",
+ "185.86.36.113",
+ "185.86.181.52",
+ "185.86.181.55",
+ "185.86.181.84",
+ "185.86.181.167",
+ "185.86.183.160",
+ "185.88.50.38",
+ "185.88.50.53",
+ "185.88.50.88",
+ "185.88.50.177",
+ "185.88.50.186",
+ "185.88.51.17",
+ "185.88.51.41",
+ "185.88.51.96",
+ "185.88.51.97",
+ "185.88.51.98",
+ "185.88.51.99",
+ "185.88.51.100",
+ "185.88.51.101",
+ "185.88.51.102",
+ "185.88.51.103",
+ "185.88.152.54",
+ "185.88.152.90",
+ "185.88.152.198",
+ "185.88.152.251",
+ "185.88.153.3",
+ "185.88.153.12",
+ "185.88.153.48",
+ "185.88.153.136",
+ "185.88.153.160",
+ "185.88.153.202",
+ "185.88.153.248",
+ "185.88.154.8",
+ "185.88.154.68",
+ "185.88.154.244",
+ "185.88.176.10",
+ "185.88.176.44",
+ "185.88.177.23",
+ "185.88.177.39",
+ "185.88.177.65",
+ "185.88.177.93",
+ "185.88.177.108",
+ "185.88.177.137",
+ "185.88.177.189",
+ "185.88.177.208",
+ "185.88.177.213",
+ "185.88.178.8",
+ "185.88.178.10",
+ "185.88.178.12",
+ "185.88.178.14",
+ "185.88.178.19",
+ "185.88.178.25",
+ "185.88.178.34",
+ "185.88.178.37",
+ "185.88.178.54",
+ "185.88.178.70",
+ "185.88.178.74",
+ "185.88.178.78",
+ "185.88.178.120",
+ "185.88.178.121",
+ "185.88.178.184",
+ "185.88.179.232",
+ "185.88.252.71",
+ "185.88.252.79",
+ "185.88.252.87",
+ "185.88.252.107",
+ "185.88.252.117",
+ "185.88.252.146",
+ "185.88.253.11",
+ "185.89.112.58",
+ "185.89.112.68",
+ "185.89.112.162",
+ "185.89.112.212",
+ "185.89.113.106",
+ "185.89.113.126",
+ "185.89.113.200",
+ "185.89.115.185",
+ "185.92.40.1",
+ "185.92.40.40",
+ "185.92.42.89",
+ "185.94.96.1",
+ "185.94.96.5",
+ "185.94.96.9",
+ "185.94.96.17",
+ "185.94.96.21",
+ "185.94.96.25",
+ "185.94.96.37",
+ "185.94.96.41",
+ "185.94.96.45",
+ "185.94.96.49",
+ "185.94.96.65",
+ "185.94.96.97",
+ "185.94.96.105",
+ "185.94.96.117",
+ "185.94.96.121",
+ "185.94.96.129",
+ "185.94.96.133",
+ "185.94.96.137",
+ "185.94.96.141",
+ "185.94.96.145",
+ "185.94.96.157",
+ "185.94.96.161",
+ "185.94.96.165",
+ "185.94.96.169",
+ "185.94.96.173",
+ "185.94.96.177",
+ "185.94.96.181",
+ "185.94.96.185",
+ "185.94.96.189",
+ "185.94.96.193",
+ "185.94.96.225",
+ "185.94.96.241",
+ "185.94.96.245",
+ "185.94.96.249",
+ "185.94.97.1",
+ "185.94.97.17",
+ "185.94.97.21",
+ "185.94.97.22",
+ "185.94.97.25",
+ "185.94.97.29",
+ "185.94.97.33",
+ "185.94.97.38",
+ "185.94.97.41",
+ "185.94.97.45",
+ "185.94.97.49",
+ "185.94.97.53",
+ "185.94.97.57",
+ "185.94.97.61",
+ "185.94.97.65",
+ "185.94.97.69",
+ "185.94.97.73",
+ "185.94.97.77",
+ "185.94.97.81",
+ "185.94.97.97",
+ "185.94.97.105",
+ "185.94.97.109",
+ "185.94.97.117",
+ "185.94.97.145",
+ "185.94.97.149",
+ "185.94.97.157",
+ "185.94.97.197",
+ "185.94.97.201",
+ "185.94.97.205",
+ "185.94.97.209",
+ "185.94.97.213",
+ "185.94.97.217",
+ "185.94.97.225",
+ "185.94.97.232",
+ "185.94.97.241",
+ "185.94.97.245",
+ "185.94.97.249",
+ "185.94.97.253",
+ "185.94.98.1",
+ "185.94.98.37",
+ "185.94.98.41",
+ "185.94.98.49",
+ "185.94.98.53",
+ "185.94.98.57",
+ "185.94.98.61",
+ "185.94.98.73",
+ "185.94.98.81",
+ "185.94.98.89",
+ "185.94.98.97",
+ "185.94.98.101",
+ "185.94.98.105",
+ "185.94.98.109",
+ "185.94.98.113",
+ "185.94.98.129",
+ "185.94.98.145",
+ "185.94.98.165",
+ "185.94.98.193",
+ "185.94.98.225",
+ "185.94.98.233",
+ "185.94.98.241",
+ "185.94.98.249",
+ "185.94.99.1",
+ "185.94.99.5",
+ "185.94.99.33",
+ "185.94.99.65",
+ "185.94.99.129",
+ "185.94.99.137",
+ "185.94.99.141",
+ "185.94.99.145",
+ "185.94.99.153",
+ "185.94.99.157",
+ "185.94.99.161",
+ "185.94.99.165",
+ "185.94.99.169",
+ "185.94.99.177",
+ "185.94.99.185",
+ "185.94.99.193",
+ "185.94.99.208",
+ "185.94.99.212",
+ "185.94.99.225",
+ "185.95.152.33",
+ "185.95.152.105",
+ "185.95.152.130",
+ "185.95.152.132",
+ "185.95.152.148",
+ "185.95.182.1",
+ "185.97.117.1",
+ "185.97.117.112",
+ "185.97.118.189",
+ "185.97.118.202",
+ "185.97.119.194",
+ "185.97.119.241",
+ "185.99.212.43",
+ "185.99.212.92",
+ "185.99.213.56",
+ "185.100.44.28",
+ "185.100.44.106",
+ "185.100.44.183",
+ "185.100.44.222",
+ "185.100.45.22",
+ "185.100.45.102",
+ "185.100.46.56",
+ "185.100.46.167",
+ "185.100.46.168",
+ "185.100.47.161",
+ "185.100.47.166",
+ "185.100.47.249",
+ "185.101.231.186",
+ "185.101.231.188",
+ "185.101.231.190",
+ "185.101.231.242",
+ "185.103.84.1",
+ "185.103.84.16",
+ "185.103.87.30",
+ "185.103.129.69",
+ "185.103.129.70",
+ "185.103.129.110",
+ "185.103.130.34",
+ "185.103.130.146",
+ "185.103.130.162",
+ "185.103.130.170",
+ "185.103.130.238",
+ "185.103.131.10",
+ "185.103.131.131",
+ "185.103.248.13",
+ "185.103.248.150",
+ "185.103.250.253",
+ "185.104.229.202",
+ "185.104.229.203",
+ "185.104.229.204",
+ "185.104.229.205",
+ "185.104.229.206",
+ "185.104.243.80",
+ "185.105.101.1",
+ "185.105.184.125",
+ "185.105.187.133",
+ "185.105.187.148",
+ "185.105.187.172",
+ "185.105.237.98",
+ "185.105.238.157",
+ "185.106.136.153",
+ "185.106.136.154",
+ "185.106.137.93",
+ "185.106.138.209",
+ "185.106.144.29",
+ "185.106.145.98",
+ "185.106.146.221",
+ "185.106.201.7",
+ "185.107.31.90",
+ "185.107.31.91",
+ "185.107.32.62",
+ "185.107.244.195",
+ "185.107.245.100",
+ "185.107.245.177",
+ "185.107.245.240",
+ "185.107.246.26",
+ "185.107.246.129",
+ "185.107.246.131",
+ "185.107.246.140",
+ "185.107.246.141",
+ "185.107.246.142",
+ "185.107.246.146",
+ "185.107.246.154",
+ "185.107.247.215",
+ "185.109.60.43",
+ "185.109.60.45",
+ "185.109.61.7",
+ "185.109.61.41",
+ "185.109.61.228",
+ "185.109.62.69",
+ "185.109.62.105",
+ "185.109.62.108",
+ "185.109.63.106",
+ "185.109.63.107",
+ "185.109.63.108",
+ "185.109.63.109",
+ "185.109.63.158",
+ "185.109.63.192",
+ "185.109.74.1",
+ "185.109.74.87",
+ "185.109.74.119",
+ "185.109.74.124",
+ "185.109.74.175",
+ "185.109.74.195",
+ "185.109.74.199",
+ "185.109.74.241",
+ "185.109.75.41",
+ "185.109.81.91",
+ "185.109.82.73",
+ "185.109.82.77",
+ "185.109.83.55",
+ "185.109.244.188",
+ "185.109.245.114",
+ "185.109.246.82",
+ "185.109.246.114",
+ "185.109.247.18",
+ "185.109.247.19",
+ "185.109.247.20",
+ "185.109.247.21",
+ "185.109.247.85",
+ "185.109.247.99",
+ "185.109.247.226",
+ "185.109.248.126",
+ "185.110.28.1",
+ "185.110.28.8",
+ "185.110.28.9",
+ "185.110.28.20",
+ "185.110.28.30",
+ "185.110.28.54",
+ "185.110.28.79",
+ "185.110.28.97",
+ "185.110.28.98",
+ "185.110.28.99",
+ "185.110.28.100",
+ "185.110.28.101",
+ "185.110.28.102",
+ "185.110.28.103",
+ "185.110.28.105",
+ "185.110.28.193",
+ "185.110.28.194",
+ "185.110.28.245",
+ "185.110.28.249",
+ "185.110.28.253",
+ "185.110.29.38",
+ "185.110.29.113",
+ "185.110.29.153",
+ "185.110.29.193",
+ "185.110.29.249",
+ "185.110.30.14",
+ "185.110.30.62",
+ "185.110.30.70",
+ "185.110.30.79",
+ "185.110.30.145",
+ "185.110.30.177",
+ "185.110.30.241",
+ "185.110.31.10",
+ "185.110.31.17",
+ "185.110.31.140",
+ "185.110.31.170",
+ "185.110.219.25",
+ "185.110.219.57",
+ "185.110.219.131",
+ "185.110.236.0",
+ "185.110.236.33",
+ "185.110.236.36",
+ "185.110.236.66",
+ "185.110.237.0",
+ "185.110.237.58",
+ "185.110.237.197",
+ "185.110.238.0",
+ "185.110.239.1",
+ "185.110.244.55",
+ "185.110.247.23",
+ "185.110.252.41",
+ "185.110.252.49",
+ "185.110.252.97",
+ "185.110.252.145",
+ "185.110.252.159",
+ "185.110.252.167",
+ "185.110.252.229",
+ "185.110.253.208",
+ "185.111.65.28",
+ "185.111.81.117",
+ "185.111.81.118",
+ "185.111.82.139",
+ "185.111.83.6",
+ "185.111.83.73",
+ "185.111.83.144",
+ "185.111.83.163",
+ "185.111.83.221",
+ "185.112.32.26",
+ "185.112.32.42",
+ "185.112.32.186",
+ "185.112.33.80",
+ "185.112.33.88",
+ "185.112.33.89",
+ "185.112.33.108",
+ "185.112.33.109",
+ "185.112.33.178",
+ "185.112.33.179",
+ "185.112.33.253",
+ "185.112.34.115",
+ "185.112.35.84",
+ "185.112.35.202",
+ "185.112.35.205",
+ "185.112.35.206",
+ "185.112.36.8",
+ "185.112.36.17",
+ "185.112.36.51",
+ "185.112.36.70",
+ "185.112.36.94",
+ "185.112.36.106",
+ "185.112.36.134",
+ "185.112.36.188",
+ "185.112.36.197",
+ "185.112.36.200",
+ "185.112.36.201",
+ "185.112.36.205",
+ "185.112.36.215",
+ "185.112.36.223",
+ "185.112.36.253",
+ "185.112.37.5",
+ "185.112.37.43",
+ "185.112.37.56",
+ "185.112.37.57",
+ "185.112.37.65",
+ "185.112.37.83",
+ "185.112.37.94",
+ "185.112.37.110",
+ "185.112.37.112",
+ "185.112.37.119",
+ "185.112.37.128",
+ "185.112.37.155",
+ "185.112.37.181",
+ "185.112.37.186",
+ "185.112.37.214",
+ "185.112.37.218",
+ "185.112.37.238",
+ "185.112.38.16",
+ "185.112.38.18",
+ "185.112.38.44",
+ "185.112.38.46",
+ "185.112.38.55",
+ "185.112.38.64",
+ "185.112.38.71",
+ "185.112.38.91",
+ "185.112.38.96",
+ "185.112.38.104",
+ "185.112.38.112",
+ "185.112.38.118",
+ "185.112.38.121",
+ "185.112.38.131",
+ "185.112.38.137",
+ "185.112.38.225",
+ "185.112.38.227",
+ "185.112.38.230",
+ "185.112.39.7",
+ "185.112.39.21",
+ "185.112.39.36",
+ "185.112.39.45",
+ "185.112.39.60",
+ "185.112.39.88",
+ "185.112.39.123",
+ "185.112.39.129",
+ "185.112.39.151",
+ "185.112.39.160",
+ "185.112.150.24",
+ "185.112.150.26",
+ "185.112.151.4",
+ "185.112.151.178",
+ "185.112.151.207",
+ "185.112.151.223",
+ "185.112.151.246",
+ "185.113.9.56",
+ "185.113.9.124",
+ "185.113.9.211",
+ "185.113.9.246",
+ "185.113.56.1",
+ "185.113.56.11",
+ "185.113.56.19",
+ "185.113.56.30",
+ "185.113.56.35",
+ "185.113.56.125",
+ "185.113.56.130",
+ "185.113.57.17",
+ "185.113.57.208",
+ "185.113.58.71",
+ "185.113.58.73",
+ "185.113.58.92",
+ "185.113.58.221",
+ "185.113.58.229",
+ "185.113.58.231",
+ "185.113.58.235",
+ "185.113.59.161",
+ "185.115.149.29",
+ "185.115.149.228",
+ "185.115.168.1",
+ "185.115.168.3",
+ "185.115.168.4",
+ "185.115.168.11",
+ "185.115.168.24",
+ "185.115.168.55",
+ "185.115.168.109",
+ "185.115.168.157",
+ "185.115.168.181",
+ "185.115.168.195",
+ "185.115.169.29",
+ "185.115.169.46",
+ "185.115.169.90",
+ "185.115.169.162",
+ "185.115.169.179",
+ "185.115.169.186",
+ "185.115.169.223",
+ "185.115.171.5",
+ "185.115.171.29",
+ "185.115.171.31",
+ "185.115.171.42",
+ "185.115.171.45",
+ "185.115.171.46",
+ "185.115.171.48",
+ "185.115.171.81",
+ "185.115.171.91",
+ "185.115.171.110",
+ "185.115.171.171",
+ "185.115.171.174",
+ "185.115.171.184",
+ "185.115.171.187",
+ "185.115.171.194",
+ "185.115.171.219",
+ "185.115.171.252",
+ "185.116.20.97",
+ "185.116.20.169",
+ "185.116.20.173",
+ "185.116.20.190",
+ "185.116.21.75",
+ "185.116.21.76",
+ "185.116.21.77",
+ "185.116.22.5",
+ "185.116.22.8",
+ "185.116.22.49",
+ "185.116.22.50",
+ "185.116.22.66",
+ "185.116.22.81",
+ "185.116.22.177",
+ "185.116.23.2",
+ "185.116.23.13",
+ "185.116.23.17",
+ "185.116.23.57",
+ "185.116.23.129",
+ "185.116.23.193",
+ "185.116.160.30",
+ "185.116.160.73",
+ "185.116.160.125",
+ "185.116.160.131",
+ "185.116.161.31",
+ "185.116.161.108",
+ "185.116.161.114",
+ "185.116.162.37",
+ "185.116.162.88",
+ "185.116.163.32",
+ "185.116.163.71",
+ "185.116.163.76",
+ "185.116.163.95",
+ "185.116.163.99",
+ "185.116.163.105",
+ "185.116.163.142",
+ "185.116.163.214",
+ "185.117.48.248",
+ "185.117.139.83",
+ "185.117.139.84",
+ "185.117.139.89",
+ "185.117.139.91",
+ "185.117.139.132",
+ "185.117.139.162",
+ "185.117.139.163",
+ "185.117.139.164",
+ "185.117.139.166",
+ "185.117.139.167",
+ "185.117.139.170",
+ "185.117.139.171",
+ "185.117.139.172",
+ "185.117.139.174",
+ "185.118.13.101",
+ "185.118.13.140",
+ "185.118.13.185",
+ "185.118.13.229",
+ "185.118.14.22",
+ "185.118.14.83",
+ "185.118.14.99",
+ "185.118.14.113",
+ "185.118.14.122",
+ "185.118.14.130",
+ "185.118.14.142",
+ "185.118.14.149",
+ "185.118.14.165",
+ "185.118.14.176",
+ "185.118.14.191",
+ "185.118.14.199",
+ "185.118.14.201",
+ "185.118.14.203",
+ "185.118.152.13",
+ "185.118.152.17",
+ "185.118.152.21",
+ "185.118.152.22",
+ "185.118.152.30",
+ "185.118.152.93",
+ "185.118.152.101",
+ "185.118.152.169",
+ "185.118.152.182",
+ "185.118.152.185",
+ "185.118.152.193",
+ "185.118.152.214",
+ "185.118.152.248",
+ "185.118.152.249",
+ "185.118.153.19",
+ "185.118.153.98",
+ "185.118.155.25",
+ "185.118.155.33",
+ "185.118.155.84",
+ "185.118.155.95",
+ "185.118.155.114",
+ "185.118.155.122",
+ "185.118.155.212",
+ "185.118.155.233",
+ "185.118.155.237",
+ "185.119.164.61",
+ "185.119.164.65",
+ "185.119.164.66",
+ "185.119.164.67",
+ "185.119.164.69",
+ "185.119.164.70",
+ "185.119.164.77",
+ "185.119.164.166",
+ "185.119.166.8",
+ "185.119.166.165",
+ "185.120.162.49",
+ "185.120.162.60",
+ "185.120.162.61",
+ "185.120.162.62",
+ "185.120.162.97",
+ "185.120.169.150",
+ "185.120.201.34",
+ "185.120.201.35",
+ "185.120.201.42",
+ "185.120.201.56",
+ "185.120.220.27",
+ "185.120.220.28",
+ "185.120.220.155",
+ "185.120.220.193",
+ "185.120.220.194",
+ "185.120.221.84",
+ "185.120.221.180",
+ "185.120.221.249",
+ "185.120.222.138",
+ "185.120.222.166",
+ "185.120.222.184",
+ "185.120.222.198",
+ "185.120.222.211",
+ "185.120.222.217",
+ "185.120.222.218",
+ "185.120.222.232",
+ "185.120.222.242",
+ "185.120.249.175",
+ "185.120.250.225",
+ "185.121.128.102",
+ "185.121.128.115",
+ "185.121.128.119",
+ "185.121.128.130",
+ "185.121.128.162",
+ "185.121.128.163",
+ "185.121.128.164",
+ "185.121.129.66",
+ "185.121.129.67",
+ "185.121.129.69",
+ "185.121.129.75",
+ "185.121.129.85",
+ "185.121.129.86",
+ "185.121.129.89",
+ "185.121.129.134",
+ "185.121.129.158",
+ "185.121.129.170",
+ "185.121.130.106",
+ "185.121.130.154",
+ "185.121.130.210",
+ "185.121.130.230",
+ "185.121.131.6",
+ "185.121.131.105",
+ "185.121.131.107",
+ "185.121.131.109",
+ "185.121.131.110",
+ "185.121.131.186",
+ "185.124.112.51",
+ "185.124.112.59",
+ "185.124.112.153",
+ "185.124.113.224",
+ "185.124.114.37",
+ "185.124.114.40",
+ "185.124.114.96",
+ "185.124.114.131",
+ "185.124.114.214",
+ "185.124.114.220",
+ "185.124.115.104",
+ "185.124.115.137",
+ "185.124.173.90",
+ "185.124.173.100",
+ "185.125.20.4",
+ "185.125.20.5",
+ "185.125.20.32",
+ "185.125.20.102",
+ "185.125.20.119",
+ "185.125.20.204",
+ "185.125.20.205",
+ "185.125.20.229",
+ "185.125.20.254",
+ "185.125.23.106",
+ "185.125.23.107",
+ "185.125.23.108",
+ "185.125.23.109",
+ "185.125.23.113",
+ "185.125.23.203",
+ "185.125.23.218",
+ "185.125.23.228",
+ "185.125.23.229",
+ "185.125.248.129",
+ "185.125.248.154",
+ "185.125.248.217",
+ "185.125.248.229",
+ "185.125.249.42",
+ "185.125.251.90",
+ "185.125.252.77",
+ "185.125.252.102",
+ "185.125.252.190",
+ "185.125.252.226",
+ "185.125.255.82",
+ "185.125.255.83",
+ "185.125.255.84",
+ "185.125.255.85",
+ "185.125.255.86",
+ "185.125.255.88",
+ "185.125.255.89",
+ "185.125.255.90",
+ "185.125.255.91",
+ "185.125.255.92",
+ "185.125.255.93",
+ "185.125.255.113",
+ "185.125.255.114",
+ "185.125.255.119",
+ "185.125.255.120",
+ "185.125.255.241",
+ "185.126.0.84",
+ "185.126.1.4",
+ "185.126.1.166",
+ "185.126.2.44",
+ "185.126.3.91",
+ "185.126.3.92",
+ "185.126.3.132",
+ "185.126.3.133",
+ "185.126.3.134",
+ "185.126.3.135",
+ "185.126.3.136",
+ "185.126.3.137",
+ "185.126.3.138",
+ "185.126.3.140",
+ "185.126.3.141",
+ "185.126.3.142",
+ "185.126.3.143",
+ "185.126.3.145",
+ "185.126.3.146",
+ "185.126.3.147",
+ "185.126.3.149",
+ "185.126.3.151",
+ "185.126.3.152",
+ "185.126.3.153",
+ "185.126.3.154",
+ "185.126.3.155",
+ "185.126.3.158",
+ "185.126.4.62",
+ "185.126.4.170",
+ "185.126.5.14",
+ "185.126.5.40",
+ "185.126.5.41",
+ "185.126.5.49",
+ "185.126.5.221",
+ "185.126.6.174",
+ "185.126.6.241",
+ "185.126.8.18",
+ "185.126.8.19",
+ "185.126.8.21",
+ "185.126.8.22",
+ "185.126.9.147",
+ "185.126.9.148",
+ "185.126.9.150",
+ "185.126.9.186",
+ "185.126.10.180",
+ "185.126.10.205",
+ "185.126.11.97",
+ "185.126.14.109",
+ "185.126.14.110",
+ "185.126.14.114",
+ "185.126.14.115",
+ "185.126.14.116",
+ "185.126.14.117",
+ "185.126.14.118",
+ "185.126.14.119",
+ "185.126.14.120",
+ "185.126.14.121",
+ "185.126.14.122",
+ "185.126.14.123",
+ "185.126.14.124",
+ "185.126.14.126",
+ "185.126.14.196",
+ "185.126.14.202",
+ "185.126.14.204",
+ "185.126.14.205",
+ "185.126.14.212",
+ "185.126.14.244",
+ "185.126.14.245",
+ "185.126.15.13",
+ "185.126.15.202",
+ "185.126.16.9",
+ "185.126.18.9",
+ "185.126.40.95",
+ "185.126.40.106",
+ "185.126.40.109",
+ "185.126.40.125",
+ "185.126.40.175",
+ "185.126.40.178",
+ "185.126.40.226",
+ "185.126.201.3",
+ "185.126.201.4",
+ "185.126.201.5",
+ "185.126.201.6",
+ "185.126.201.7",
+ "185.126.201.8",
+ "185.126.201.9",
+ "185.126.201.19",
+ "185.126.201.22",
+ "185.126.201.25",
+ "185.126.201.26",
+ "185.126.201.27",
+ "185.126.201.235",
+ "185.126.202.12",
+ "185.126.202.13",
+ "185.126.202.202",
+ "185.126.203.26",
+ "185.126.203.44",
+ "185.128.40.16",
+ "185.128.80.32",
+ "185.128.80.68",
+ "185.128.81.50",
+ "185.128.81.225",
+ "185.128.136.12",
+ "185.128.137.200",
+ "185.128.137.202",
+ "185.128.138.2",
+ "185.128.138.100",
+ "185.128.138.102",
+ "185.128.138.103",
+ "185.128.138.175",
+ "185.128.139.73",
+ "185.128.139.133",
+ "185.128.152.13",
+ "185.128.152.59",
+ "185.128.152.137",
+ "185.128.152.201",
+ "185.128.152.246",
+ "185.129.116.74",
+ "185.129.116.75",
+ "185.129.116.76",
+ "185.129.116.77",
+ "185.129.117.67",
+ "185.129.117.68",
+ "185.129.117.69",
+ "185.129.117.105",
+ "185.129.117.195",
+ "185.129.117.196",
+ "185.129.117.197",
+ "185.129.118.2",
+ "185.129.118.3",
+ "185.129.118.5",
+ "185.129.118.6",
+ "185.129.118.53",
+ "185.129.118.131",
+ "185.129.118.132",
+ "185.129.118.237",
+ "185.129.119.3",
+ "185.129.119.4",
+ "185.129.119.5",
+ "185.129.119.131",
+ "185.129.119.132",
+ "185.129.119.133",
+ "185.129.168.41",
+ "185.129.168.166",
+ "185.129.168.193",
+ "185.129.169.131",
+ "185.129.169.132",
+ "185.129.169.137",
+ "185.129.170.87",
+ "185.129.197.155",
+ "185.129.197.173",
+ "185.129.197.215",
+ "185.129.197.226",
+ "185.129.197.227",
+ "185.129.197.233",
+ "185.129.197.235",
+ "185.129.199.74",
+ "185.129.199.186",
+ "185.129.200.201",
+ "185.129.202.131",
+ "185.129.212.178",
+ "185.129.213.145",
+ "185.129.213.149",
+ "185.129.213.170",
+ "185.129.213.189",
+ "185.129.213.203",
+ "185.129.213.210",
+ "185.129.213.221",
+ "185.129.214.25",
+ "185.129.214.47",
+ "185.129.214.200",
+ "185.129.215.29",
+ "185.129.215.45",
+ "185.129.215.165",
+ "185.129.216.19",
+ "185.129.216.30",
+ "185.129.216.152",
+ "185.129.217.10",
+ "185.129.217.38",
+ "185.129.217.59",
+ "185.129.217.116",
+ "185.129.217.129",
+ "185.129.217.203",
+ "185.129.218.0",
+ "185.129.230.18",
+ "185.129.230.213",
+ "185.129.236.49",
+ "185.129.236.194",
+ "185.129.236.195",
+ "185.129.237.45",
+ "185.129.238.52",
+ "185.129.238.178",
+ "185.129.238.255",
+ "185.129.239.37",
+ "185.129.239.43",
+ "185.129.239.48",
+ "185.129.239.93",
+ "185.129.239.123",
+ "185.129.239.171",
+ "185.129.239.232",
+ "185.129.239.235",
+ "185.130.50.92",
+ "185.130.50.113",
+ "185.130.50.130",
+ "185.130.50.141",
+ "185.130.50.142",
+ "185.130.50.154",
+ "185.130.50.248",
+ "185.130.79.230",
+ "185.131.30.14",
+ "185.131.30.18",
+ "185.131.30.21",
+ "185.131.30.49",
+ "185.131.30.50",
+ "185.131.30.58",
+ "185.131.30.83",
+ "185.131.30.104",
+ "185.131.30.122",
+ "185.131.30.135",
+ "185.131.30.168",
+ "185.131.30.205",
+ "185.131.30.237",
+ "185.131.30.250",
+ "185.131.117.125",
+ "185.131.117.145",
+ "185.131.119.78",
+ "185.131.155.109",
+ "185.132.80.3",
+ "185.132.80.18",
+ "185.132.80.20",
+ "185.132.80.30",
+ "185.132.80.65",
+ "185.132.80.131",
+ "185.132.80.228",
+ "185.132.80.232",
+ "185.132.80.244",
+ "185.132.81.17",
+ "185.132.81.19",
+ "185.132.81.25",
+ "185.132.81.53",
+ "185.132.81.74",
+ "185.132.81.109",
+ "185.132.81.148",
+ "185.132.81.172",
+ "185.132.81.197",
+ "185.132.81.200",
+ "185.132.81.249",
+ "185.132.82.7",
+ "185.132.82.19",
+ "185.132.82.20",
+ "185.132.82.58",
+ "185.132.82.84",
+ "185.132.82.94",
+ "185.132.82.128",
+ "185.132.82.160",
+ "185.132.82.168",
+ "185.132.82.177",
+ "185.132.82.178",
+ "185.132.82.191",
+ "185.134.96.114",
+ "185.134.96.150",
+ "185.134.96.161",
+ "185.134.96.162",
+ "185.134.96.230",
+ "185.134.97.98",
+ "185.134.97.230",
+ "185.134.97.250",
+ "185.134.98.10",
+ "185.134.98.130",
+ "185.134.98.142",
+ "185.134.98.144",
+ "185.134.98.166",
+ "185.134.98.196",
+ "185.134.98.213",
+ "185.134.98.220",
+ "185.134.98.250",
+ "185.134.99.250",
+ "185.135.47.70",
+ "185.135.228.209",
+ "185.135.229.72",
+ "185.135.229.227",
+ "185.135.230.4",
+ "185.135.230.84",
+ "185.135.230.246",
+ "185.135.230.251",
+ "185.135.231.122",
+ "185.136.100.43",
+ "185.136.100.78",
+ "185.136.101.31",
+ "185.136.101.142",
+ "185.136.102.96",
+ "185.136.102.124",
+ "185.136.102.229",
+ "185.136.103.90",
+ "185.136.103.125",
+ "185.136.133.36",
+ "185.136.133.37",
+ "185.136.133.38",
+ "185.136.133.106",
+ "185.136.133.107",
+ "185.136.180.9",
+ "185.136.180.75",
+ "185.136.180.91",
+ "185.136.180.102",
+ "185.136.180.176",
+ "185.136.180.184",
+ "185.136.180.218",
+ "185.136.180.221",
+ "185.136.180.234",
+ "185.136.180.255",
+ "185.136.182.160",
+ "185.136.182.185",
+ "185.136.183.168",
+ "185.136.183.180",
+ "185.136.183.210",
+ "185.136.183.220",
+ "185.136.183.252",
+ "185.136.192.18",
+ "185.136.192.114",
+ "185.136.193.22",
+ "185.136.193.41",
+ "185.136.193.207",
+ "185.136.193.233",
+ "185.136.194.33",
+ "185.136.194.34",
+ "185.136.194.36",
+ "185.136.194.38",
+ "185.136.194.39",
+ "185.136.194.42",
+ "185.136.194.43",
+ "185.136.194.44",
+ "185.136.194.45",
+ "185.136.194.46",
+ "185.136.195.206",
+ "185.137.25.70",
+ "185.137.25.98",
+ "185.137.25.210",
+ "185.137.26.54",
+ "185.137.26.138",
+ "185.137.26.155",
+ "185.137.26.182",
+ "185.137.60.112",
+ "185.137.60.150",
+ "185.137.60.202",
+ "185.137.108.1",
+ "185.137.108.106",
+ "185.137.108.128",
+ "185.137.108.137",
+ "185.137.108.163",
+ "185.137.108.192",
+ "185.137.108.193",
+ "185.137.108.197",
+ "185.137.108.198",
+ "185.137.108.211",
+ "185.137.108.215",
+ "185.137.108.230",
+ "185.137.108.238",
+ "185.137.109.0",
+ "185.137.109.1",
+ "185.137.109.2",
+ "185.137.109.13",
+ "185.137.109.36",
+ "185.137.109.49",
+ "185.137.109.131",
+ "185.137.109.254",
+ "185.137.109.255",
+ "185.137.110.0",
+ "185.137.110.18",
+ "185.137.110.25",
+ "185.137.110.31",
+ "185.137.110.57",
+ "185.137.110.64",
+ "185.137.110.74",
+ "185.137.110.76",
+ "185.137.110.106",
+ "185.137.110.109",
+ "185.137.111.0",
+ "185.140.4.8",
+ "185.140.4.14",
+ "185.140.4.24",
+ "185.140.4.26",
+ "185.140.4.27",
+ "185.140.4.28",
+ "185.140.4.29",
+ "185.140.4.65",
+ "185.140.4.66",
+ "185.140.4.67",
+ "185.140.4.72",
+ "185.140.4.73",
+ "185.140.4.76",
+ "185.140.4.77",
+ "185.140.4.78",
+ "185.140.4.79",
+ "185.140.5.6",
+ "185.140.7.130",
+ "185.140.7.131",
+ "185.140.7.142",
+ "185.140.56.21",
+ "185.140.58.179",
+ "185.140.59.3",
+ "185.140.59.162",
+ "185.140.59.186",
+ "185.140.232.9",
+ "185.140.232.28",
+ "185.140.232.47",
+ "185.140.232.57",
+ "185.140.232.66",
+ "185.140.232.242",
+ "185.140.232.249",
+ "185.140.232.251",
+ "185.140.232.252",
+ "185.140.234.1",
+ "185.140.234.47",
+ "185.140.234.251",
+ "185.140.235.2",
+ "185.140.240.1",
+ "185.140.240.16",
+ "185.140.240.49",
+ "185.140.240.50",
+ "185.140.240.54",
+ "185.140.240.89",
+ "185.140.240.94",
+ "185.140.240.159",
+ "185.140.240.161",
+ "185.140.240.162",
+ "185.140.240.239",
+ "185.140.240.250",
+ "185.140.240.252",
+ "185.140.241.148",
+ "185.140.242.33",
+ "185.140.242.35",
+ "185.140.242.41",
+ "185.140.242.42",
+ "185.140.242.44",
+ "185.140.242.49",
+ "185.140.242.50",
+ "185.140.242.129",
+ "185.140.242.133",
+ "185.140.242.134",
+ "185.140.242.146",
+ "185.140.242.155",
+ "185.140.243.13",
+ "185.140.243.104",
+ "185.140.243.121",
+ "185.140.243.128",
+ "185.140.243.133",
+ "185.140.243.169",
+ "185.140.243.175",
+ "185.140.243.176",
+ "185.140.243.179",
+ "185.140.243.182",
+ "185.140.243.254",
+ "185.140.243.255",
+ "185.141.36.58",
+ "185.141.36.67",
+ "185.141.39.3",
+ "185.141.39.21",
+ "185.141.39.30",
+ "185.141.39.39",
+ "185.141.39.114",
+ "185.141.39.225",
+ "185.141.49.129",
+ "185.141.104.120",
+ "185.141.104.209",
+ "185.141.105.209",
+ "185.141.105.210",
+ "185.141.105.211",
+ "185.141.105.212",
+ "185.141.105.213",
+ "185.141.105.235",
+ "185.141.105.236",
+ "185.141.106.51",
+ "185.141.106.217",
+ "185.141.106.219",
+ "185.141.106.220",
+ "185.141.106.221",
+ "185.141.106.222",
+ "185.141.106.223",
+ "185.141.107.137",
+ "185.141.107.220",
+ "185.141.132.64",
+ "185.141.132.65",
+ "185.141.132.66",
+ "185.141.133.164",
+ "185.141.134.48",
+ "185.141.134.149",
+ "185.141.134.150",
+ "185.141.134.219",
+ "185.141.134.253",
+ "185.141.168.12",
+ "185.141.168.98",
+ "185.141.168.118",
+ "185.141.169.233",
+ "185.141.171.114",
+ "185.141.171.115",
+ "185.141.171.116",
+ "185.141.171.117",
+ "185.141.213.130",
+ "185.141.213.169",
+ "185.141.213.246",
+ "185.141.213.252",
+ "185.141.214.19",
+ "185.141.214.92",
+ "185.141.215.61",
+ "185.142.92.104",
+ "185.142.92.107",
+ "185.142.92.111",
+ "185.142.92.117",
+ "185.142.92.156",
+ "185.142.92.166",
+ "185.142.92.177",
+ "185.142.92.184",
+ "185.142.92.198",
+ "185.142.92.199",
+ "185.142.92.214",
+ "185.142.92.220",
+ "185.142.92.222",
+ "185.142.93.27",
+ "185.142.93.48",
+ "185.142.93.64",
+ "185.142.93.81",
+ "185.142.93.100",
+ "185.142.93.137",
+ "185.142.93.138",
+ "185.142.93.144",
+ "185.142.93.146",
+ "185.142.93.173",
+ "185.142.93.200",
+ "185.142.93.203",
+ "185.142.93.208",
+ "185.142.93.214",
+ "185.142.93.230",
+ "185.142.93.234",
+ "185.142.93.235",
+ "185.142.93.236",
+ "185.142.93.243",
+ "185.142.94.6",
+ "185.142.94.16",
+ "185.142.94.31",
+ "185.142.94.38",
+ "185.142.94.42",
+ "185.142.94.48",
+ "185.142.94.53",
+ "185.142.94.66",
+ "185.142.94.68",
+ "185.142.94.77",
+ "185.142.94.79",
+ "185.142.94.82",
+ "185.142.94.121",
+ "185.142.94.143",
+ "185.142.94.152",
+ "185.142.94.158",
+ "185.142.94.159",
+ "185.142.94.160",
+ "185.142.95.52",
+ "185.142.95.53",
+ "185.142.95.55",
+ "185.142.95.98",
+ "185.142.95.178",
+ "185.142.124.18",
+ "185.142.124.19",
+ "185.142.124.21",
+ "185.142.124.65",
+ "185.142.124.66",
+ "185.142.124.67",
+ "185.142.124.68",
+ "185.142.124.69",
+ "185.142.124.70",
+ "185.142.124.103",
+ "185.142.124.241",
+ "185.142.125.6",
+ "185.142.125.8",
+ "185.142.125.13",
+ "185.142.125.14",
+ "185.142.125.46",
+ "185.142.125.60",
+ "185.142.125.63",
+ "185.142.125.64",
+ "185.142.125.84",
+ "185.142.125.110",
+ "185.142.125.119",
+ "185.142.125.123",
+ "185.142.125.132",
+ "185.142.125.133",
+ "185.142.125.143",
+ "185.142.125.151",
+ "185.142.125.155",
+ "185.142.125.160",
+ "185.142.125.170",
+ "185.142.125.181",
+ "185.142.125.212",
+ "185.142.125.216",
+ "185.142.125.220",
+ "185.142.126.2",
+ "185.142.126.25",
+ "185.142.126.27",
+ "185.142.126.28",
+ "185.142.126.30",
+ "185.142.126.31",
+ "185.142.126.50",
+ "185.142.126.59",
+ "185.142.126.65",
+ "185.142.126.66",
+ "185.142.126.76",
+ "185.142.126.82",
+ "185.142.126.96",
+ "185.142.126.130",
+ "185.142.126.134",
+ "185.142.126.177",
+ "185.142.126.184",
+ "185.142.126.188",
+ "185.142.126.198",
+ "185.142.126.224",
+ "185.142.126.226",
+ "185.142.126.236",
+ "185.142.126.243",
+ "185.142.127.58",
+ "185.142.127.76",
+ "185.142.127.101",
+ "185.142.127.109",
+ "185.142.127.126",
+ "185.142.127.131",
+ "185.142.127.161",
+ "185.142.127.166",
+ "185.142.127.212",
+ "185.142.127.214",
+ "185.142.156.216",
+ "185.142.156.226",
+ "185.142.157.54",
+ "185.142.157.94",
+ "185.142.157.250",
+ "185.142.159.66",
+ "185.142.159.85",
+ "185.142.159.100",
+ "185.142.159.110",
+ "185.142.159.170",
+ "185.142.159.187",
+ "185.142.159.250",
+ "185.142.159.252",
+ "185.143.205.13",
+ "185.143.205.62",
+ "185.143.205.96",
+ "185.143.205.141",
+ "185.143.205.146",
+ "185.143.205.150",
+ "185.143.205.160",
+ "185.143.205.226",
+ "185.143.207.3",
+ "185.143.207.13",
+ "185.143.207.92",
+ "185.143.207.111",
+ "185.143.207.114",
+ "185.143.207.117",
+ "185.143.207.130",
+ "185.143.207.142",
+ "185.143.207.148",
+ "185.143.207.150",
+ "185.143.207.151",
+ "185.143.207.182",
+ "185.143.207.253",
+ "185.145.8.254",
+ "185.145.9.76",
+ "185.145.9.80",
+ "185.145.9.161",
+ "185.145.184.91",
+ "185.145.184.94",
+ "185.145.184.145",
+ "185.145.184.147",
+ "185.145.184.148",
+ "185.145.184.151",
+ "185.145.184.175",
+ "185.145.184.183",
+ "185.145.184.192",
+ "185.145.184.193",
+ "185.145.184.195",
+ "185.145.184.235",
+ "185.145.185.13",
+ "185.145.185.14",
+ "185.145.185.15",
+ "185.145.185.87",
+ "185.145.185.96",
+ "185.145.185.98",
+ "185.145.185.99",
+ "185.145.185.111",
+ "185.145.185.127",
+ "185.145.185.132",
+ "185.145.185.170",
+ "185.145.185.176",
+ "185.145.186.45",
+ "185.145.186.80",
+ "185.145.186.134",
+ "185.145.186.141",
+ "185.145.186.161",
+ "185.145.186.170",
+ "185.145.186.240",
+ "185.145.186.241",
+ "185.145.186.242",
+ "185.145.186.243",
+ "185.145.186.244",
+ "185.145.186.245",
+ "185.145.186.246",
+ "185.145.186.247",
+ "185.145.187.13",
+ "185.145.187.161",
+ "185.145.187.169",
+ "185.145.187.190",
+ "185.145.187.196",
+ "185.145.187.221",
+ "185.145.187.229",
+ "185.145.187.235",
+ "185.145.187.241",
+ "185.145.187.243",
+ "185.147.40.10",
+ "185.147.40.39",
+ "185.147.40.88",
+ "185.147.40.210",
+ "185.147.41.28",
+ "185.147.41.42",
+ "185.147.41.176",
+ "185.147.160.66",
+ "185.147.160.101",
+ "185.147.161.195",
+ "185.147.161.200",
+ "185.147.161.205",
+ "185.147.162.11",
+ "185.147.163.206",
+ "185.149.192.20",
+ "185.149.192.27",
+ "185.149.192.37",
+ "185.149.192.41",
+ "185.149.192.137",
+ "185.149.192.138",
+ "185.153.185.11",
+ "185.153.185.254",
+ "185.153.208.6",
+ "185.155.9.102",
+ "185.155.10.3",
+ "185.155.10.6",
+ "185.155.10.7",
+ "185.155.10.60",
+ "185.155.10.66",
+ "185.155.10.163",
+ "185.155.10.169",
+ "185.155.10.212",
+ "185.155.14.83",
+ "185.155.14.95",
+ "185.155.14.126",
+ "185.155.14.174",
+ "185.155.14.199",
+ "185.155.14.226",
+ "185.155.15.27",
+ "185.155.15.56",
+ "185.155.15.92",
+ "185.155.15.189",
+ "185.155.15.244",
+ "185.158.172.26",
+ "185.158.172.30",
+ "185.158.172.116",
+ "185.158.172.129",
+ "185.158.172.245",
+ "185.158.173.53",
+ "185.158.173.119",
+ "185.158.173.181",
+ "185.158.174.73",
+ "185.158.174.237",
+ "185.159.153.14",
+ "185.159.153.28",
+ "185.159.153.41",
+ "185.159.153.117",
+ "185.159.153.144",
+ "185.159.153.188",
+ "185.159.153.195",
+ "185.159.153.206",
+ "185.159.153.217",
+ "185.159.153.229",
+ "185.159.154.12",
+ "185.159.154.121",
+ "185.159.154.122",
+ "185.159.154.148",
+ "185.159.154.156",
+ "185.159.154.203",
+ "185.160.205.6",
+ "185.161.38.18",
+ "185.161.38.117",
+ "185.161.38.121",
+ "185.161.38.145",
+ "185.161.38.253",
+ "185.161.39.72",
+ "185.161.39.73",
+ "185.161.39.77",
+ "185.161.39.116",
+ "185.161.39.170",
+ "185.161.39.194",
+ "185.161.39.195",
+ "185.161.39.196",
+ "185.161.39.197",
+ "185.161.39.222",
+ "185.161.112.231",
+ "185.161.112.249",
+ "185.161.113.130",
+ "185.161.113.134",
+ "185.161.113.226",
+ "185.161.113.228",
+ "185.161.113.242",
+ "185.161.114.10",
+ "185.161.114.22",
+ "185.161.114.74",
+ "185.161.114.138",
+ "185.161.114.189",
+ "185.161.115.178",
+ "185.161.115.243",
+ "185.162.40.27",
+ "185.162.41.69",
+ "185.162.41.122",
+ "185.164.72.41",
+ "185.164.72.54",
+ "185.164.72.90",
+ "185.164.72.123",
+ "185.164.72.158",
+ "185.164.72.234",
+ "185.164.73.172",
+ "185.164.73.253",
+ "185.164.74.240",
+ "185.164.252.27",
+ "185.164.252.28",
+ "185.164.252.130",
+ "185.164.253.24",
+ "185.165.30.80",
+ "185.165.40.11",
+ "185.165.41.221",
+ "185.165.41.222",
+ "185.165.43.11",
+ "185.165.116.18",
+ "185.165.116.33",
+ "185.165.116.35",
+ "185.165.116.138",
+ "185.165.116.147",
+ "185.165.116.240",
+ "185.165.118.55",
+ "185.165.118.65",
+ "185.165.119.49",
+ "185.166.104.55",
+ "185.169.6.62",
+ "185.169.6.120",
+ "185.169.6.197",
+ "185.169.6.204",
+ "185.169.20.34",
+ "185.169.20.74",
+ "185.169.20.234",
+ "185.169.21.50",
+ "185.169.21.118",
+ "185.169.22.102",
+ "185.170.236.18",
+ "185.170.236.125",
+ "185.170.236.130",
+ "185.170.236.145",
+ "185.170.236.171",
+ "185.170.236.205",
+ "185.170.237.141",
+ "185.170.237.161",
+ "185.170.237.204",
+ "185.170.237.209",
+ "185.170.238.64",
+ "185.170.238.70",
+ "185.170.238.159",
+ "185.170.238.194",
+ "185.170.238.200",
+ "185.170.239.5",
+ "185.170.239.59",
+ "185.170.239.72",
+ "185.170.239.130",
+ "185.170.239.150",
+ "185.170.239.210",
+ "185.171.53.150",
+ "185.171.54.18",
+ "185.171.54.20",
+ "185.171.54.21",
+ "185.171.54.26",
+ "185.171.54.29",
+ "185.171.54.30",
+ "185.171.54.34",
+ "185.171.54.35",
+ "185.171.54.36",
+ "185.171.54.42",
+ "185.171.54.67",
+ "185.171.54.68",
+ "185.171.54.69",
+ "185.171.54.84",
+ "185.171.54.86",
+ "185.171.54.90",
+ "185.171.54.138",
+ "185.171.54.139",
+ "185.171.54.140",
+ "185.171.54.141",
+ "185.171.54.156",
+ "185.171.54.170",
+ "185.171.54.234",
+ "185.171.54.237",
+ "185.171.54.238",
+ "185.171.55.138",
+ "185.171.55.139",
+ "185.171.55.140",
+ "185.171.55.141",
+ "185.171.55.162",
+ "185.171.55.163",
+ "185.171.55.164",
+ "185.171.55.219",
+ "185.171.55.220",
+ "185.171.55.221",
+ "185.171.55.222",
+ "185.171.55.233",
+ "185.172.0.42",
+ "185.172.0.206",
+ "185.172.0.218",
+ "185.172.0.238",
+ "185.172.1.70",
+ "185.172.1.126",
+ "185.172.1.202",
+ "185.172.1.214",
+ "185.172.2.194",
+ "185.172.2.195",
+ "185.172.2.196",
+ "185.172.2.198",
+ "185.172.3.162",
+ "185.172.3.242",
+ "185.172.68.1",
+ "185.172.68.3",
+ "185.172.68.4",
+ "185.172.68.13",
+ "185.172.68.16",
+ "185.172.68.31",
+ "185.172.68.32",
+ "185.172.68.37",
+ "185.172.68.41",
+ "185.172.68.64",
+ "185.172.68.71",
+ "185.172.68.75",
+ "185.172.68.76",
+ "185.172.69.9",
+ "185.172.69.37",
+ "185.172.70.70",
+ "185.173.104.53",
+ "185.173.104.194",
+ "185.173.104.200",
+ "185.173.104.208",
+ "185.173.105.78",
+ "185.173.105.141",
+ "185.173.105.142",
+ "185.173.106.117",
+ "185.173.107.26",
+ "185.173.129.35",
+ "185.173.129.91",
+ "185.173.129.185",
+ "185.173.129.203",
+ "185.173.129.240",
+ "185.173.129.243",
+ "185.174.132.21",
+ "185.174.132.25",
+ "185.174.132.130",
+ "185.174.132.217",
+ "185.174.132.254",
+ "185.174.134.66",
+ "185.175.76.162",
+ "185.175.76.164",
+ "185.175.76.165",
+ "185.175.76.166",
+ "185.175.77.67",
+ "185.175.79.89",
+ "185.175.79.177",
+ "185.175.79.193",
+ "185.176.32.38",
+ "185.176.33.38",
+ "185.176.34.16",
+ "185.176.34.25",
+ "185.176.34.94",
+ "185.176.35.130",
+ "185.176.56.253",
+ "185.176.57.98",
+ "185.176.57.138",
+ "185.176.59.48",
+ "185.176.59.49",
+ "185.176.59.201",
+ "185.176.59.209",
+ "185.176.59.246",
+ "185.176.59.254",
+ "185.177.158.50",
+ "185.177.158.53",
+ "185.177.158.54",
+ "185.177.158.60",
+ "185.177.159.84",
+ "185.177.159.227",
+ "185.177.159.247",
+ "185.179.90.107",
+ "185.179.168.3",
+ "185.179.168.4",
+ "185.179.168.13",
+ "185.179.168.14",
+ "185.179.168.16",
+ "185.179.168.17",
+ "185.179.168.18",
+ "185.179.168.19",
+ "185.179.168.31",
+ "185.179.168.36",
+ "185.179.168.47",
+ "185.179.168.114",
+ "185.179.168.115",
+ "185.179.168.116",
+ "185.179.168.117",
+ "185.179.168.118",
+ "185.179.168.119",
+ "185.179.168.120",
+ "185.179.168.121",
+ "185.179.168.122",
+ "185.179.168.123",
+ "185.179.168.124",
+ "185.179.168.125",
+ "185.179.168.126",
+ "185.179.168.169",
+ "185.179.169.28",
+ "185.179.169.82",
+ "185.179.169.141",
+ "185.179.169.166",
+ "185.179.169.169",
+ "185.179.169.180",
+ "185.179.169.203",
+ "185.179.169.208",
+ "185.179.169.212",
+ "185.179.169.221",
+ "185.179.169.244",
+ "185.179.170.2",
+ "185.179.170.124",
+ "185.179.170.127",
+ "185.179.170.217",
+ "185.179.170.230",
+ "185.179.170.239",
+ "185.179.171.0",
+ "185.179.171.25",
+ "185.179.171.55",
+ "185.179.171.72",
+ "185.179.171.110",
+ "185.179.171.121",
+ "185.179.171.130",
+ "185.179.171.200",
+ "185.179.221.3",
+ "185.179.221.168",
+ "185.180.128.22",
+ "185.180.128.54",
+ "185.180.128.64",
+ "185.180.128.69",
+ "185.180.128.70",
+ "185.180.128.100",
+ "185.180.129.2",
+ "185.180.129.4",
+ "185.180.129.5",
+ "185.180.129.6",
+ "185.180.129.7",
+ "185.180.129.40",
+ "185.180.129.41",
+ "185.180.129.100",
+ "185.180.129.138",
+ "185.180.129.142",
+ "185.180.129.216",
+ "185.180.129.222",
+ "185.180.129.228",
+ "185.180.129.229",
+ "185.180.129.230",
+ "185.180.129.231",
+ "185.180.129.234",
+ "185.180.130.1",
+ "185.180.130.8",
+ "185.180.130.47",
+ "185.180.130.133",
+ "185.180.130.136",
+ "185.180.130.182",
+ "185.180.130.184",
+ "185.180.130.231",
+ "185.180.130.240",
+ "185.180.130.246",
+ "185.180.130.254",
+ "185.181.180.138",
+ "185.181.181.64",
+ "185.181.181.65",
+ "185.181.181.67",
+ "185.181.181.68",
+ "185.181.181.69",
+ "185.181.181.70",
+ "185.181.181.71",
+ "185.181.181.72",
+ "185.181.181.73",
+ "185.181.181.75",
+ "185.181.181.77",
+ "185.181.181.79",
+ "185.181.181.167",
+ "185.181.182.39",
+ "185.181.182.61",
+ "185.181.182.141",
+ "185.181.182.169",
+ "185.181.182.235",
+ "185.181.183.4",
+ "185.181.183.12",
+ "185.181.183.17",
+ "185.181.183.51",
+ "185.181.183.100",
+ "185.181.183.105",
+ "185.181.183.117",
+ "185.186.50.221",
+ "185.186.51.49",
+ "185.186.240.9",
+ "185.186.240.64",
+ "185.186.240.65",
+ "185.186.240.66",
+ "185.186.240.67",
+ "185.186.240.177",
+ "185.186.240.179",
+ "185.186.240.180",
+ "185.186.240.182",
+ "185.186.240.232",
+ "185.186.242.66",
+ "185.186.242.146",
+ "185.186.243.23",
+ "185.186.243.30",
+ "185.186.243.31",
+ "185.186.243.39",
+ "185.186.243.48",
+ "185.186.243.57",
+ "185.186.243.98",
+ "185.186.243.99",
+ "185.186.243.112",
+ "185.186.243.124",
+ "185.186.243.148",
+ "185.186.243.176",
+ "185.186.243.240",
+ "185.186.243.241",
+ "185.186.243.243",
+ "185.186.243.245",
+ "185.186.243.246",
+ "185.187.48.30",
+ "185.187.48.74",
+ "185.187.48.122",
+ "185.187.49.12",
+ "185.187.49.15",
+ "185.187.49.56",
+ "185.187.49.60",
+ "185.187.49.70",
+ "185.187.50.39",
+ "185.187.50.43",
+ "185.187.51.0",
+ "185.187.51.32",
+ "185.187.51.42",
+ "185.187.51.48",
+ "185.187.51.49",
+ "185.187.51.94",
+ "185.187.51.245",
+ "185.187.51.255",
+ "185.187.87.253",
+ "185.188.112.149",
+ "185.188.112.154",
+ "185.188.112.172",
+ "185.188.112.193",
+ "185.188.112.207",
+ "185.188.113.21",
+ "185.188.113.104",
+ "185.188.113.113",
+ "185.188.115.5",
+ "185.188.115.10",
+ "185.190.39.59",
+ "185.190.39.242",
+ "185.191.76.26",
+ "185.191.77.170",
+ "185.191.77.174",
+ "185.191.77.253",
+ "185.191.78.86",
+ "185.191.78.233",
+ "185.191.78.245",
+ "185.191.79.6",
+ "185.191.79.154",
+ "185.191.79.210",
+ "185.192.112.69",
+ "185.192.112.73",
+ "185.192.112.143",
+ "185.192.112.252",
+ "185.192.113.83",
+ "185.192.113.87",
+ "185.192.113.108",
+ "185.192.113.121",
+ "185.192.113.148",
+ "185.196.148.111",
+ "185.196.151.7",
+ "185.201.48.17",
+ "185.201.48.141",
+ "185.201.48.172",
+ "185.201.48.184",
+ "185.201.48.231",
+ "185.201.49.146",
+ "185.201.50.90",
+ "185.201.51.41",
+ "185.201.51.67",
+ "185.201.51.69",
+ "185.201.51.75",
+ "185.201.51.76",
+ "185.201.51.116",
+ "185.201.51.161",
+ "185.201.51.217",
+ "185.201.51.221",
+ "185.201.51.229",
+ "185.202.56.22",
+ "185.202.56.74",
+ "185.202.56.86",
+ "185.202.56.98",
+ "185.202.56.102",
+ "185.202.56.210",
+ "185.202.56.214",
+ "185.202.58.150",
+ "185.202.58.183",
+ "185.202.58.236",
+ "185.202.59.114",
+ "185.204.182.10",
+ "185.204.197.53",
+ "185.204.197.149",
+ "185.204.197.226",
+ "185.205.203.242",
+ "185.206.92.63",
+ "185.206.93.203",
+ "185.206.94.42",
+ "185.206.95.9",
+ "185.206.229.21",
+ "185.206.229.22",
+ "185.206.229.23",
+ "185.206.229.24",
+ "185.206.229.25",
+ "185.206.229.30",
+ "185.206.229.31",
+ "185.206.229.32",
+ "185.206.229.35",
+ "185.206.229.36",
+ "185.206.229.50",
+ "185.206.229.72",
+ "185.206.229.103",
+ "185.206.229.104",
+ "185.206.231.31",
+ "185.206.231.68",
+ "185.206.231.79",
+ "185.206.231.216",
+ "185.206.238.178",
+ "185.208.76.101",
+ "185.208.76.102",
+ "185.208.76.103",
+ "185.208.76.104",
+ "185.208.76.105",
+ "185.208.76.106",
+ "185.208.77.85",
+ "185.208.77.178",
+ "185.208.77.179",
+ "185.208.78.100",
+ "185.208.78.101",
+ "185.208.79.95",
+ "185.208.148.3",
+ "185.208.148.48",
+ "185.208.148.216",
+ "185.208.148.241",
+ "185.208.149.138",
+ "185.208.174.44",
+ "185.208.174.68",
+ "185.208.174.153",
+ "185.208.175.11",
+ "185.208.175.167",
+ "185.208.175.209",
+ "185.208.175.235",
+ "185.208.180.9",
+ "185.208.180.170",
+ "185.208.181.66",
+ "185.208.181.67",
+ "185.208.181.68",
+ "185.208.181.86",
+ "185.208.182.3",
+ "185.208.182.77",
+ "185.208.182.117",
+ "185.208.183.14",
+ "185.208.183.164",
+ "185.208.183.188",
+ "185.209.42.6",
+ "185.209.42.50",
+ "185.209.42.95",
+ "185.211.56.126",
+ "185.211.57.166",
+ "185.211.58.79",
+ "185.211.58.146",
+ "185.211.59.115",
+ "185.211.59.134",
+ "185.211.59.160",
+ "185.212.50.5",
+ "185.212.50.10",
+ "185.212.51.73",
+ "185.212.51.119",
+ "185.212.51.144",
+ "185.212.51.160",
+ "185.212.51.201",
+ "185.212.51.202",
+ "185.212.51.203",
+ "185.212.51.204",
+ "185.212.51.205",
+ "185.212.51.206",
+ "185.212.51.241",
+ "185.212.193.4",
+ "185.212.193.21",
+ "185.212.193.22",
+ "185.212.193.23",
+ "185.212.193.97",
+ "185.212.193.160",
+ "185.212.193.162",
+ "185.212.193.163",
+ "185.212.193.165",
+ "185.212.193.170",
+ "185.212.195.34",
+ "185.212.195.35",
+ "185.212.195.36",
+ "185.212.195.37",
+ "185.212.195.38",
+ "185.212.195.41",
+ "185.212.195.58",
+ "185.212.195.113",
+ "185.212.195.114",
+ "185.212.195.116",
+ "185.212.195.154",
+ "185.212.195.161",
+ "185.212.195.167",
+ "185.212.195.174",
+ "185.212.195.177",
+ "185.212.195.178",
+ "185.212.195.254",
+ "185.213.10.99",
+ "185.213.10.101",
+ "185.213.11.23",
+ "185.213.11.59",
+ "185.213.11.75",
+ "185.213.11.77",
+ "185.213.11.93",
+ "185.213.164.4",
+ "185.213.164.5",
+ "185.213.164.25",
+ "185.213.164.105",
+ "185.213.164.151",
+ "185.213.164.191",
+ "185.213.164.242",
+ "185.213.165.30",
+ "185.213.165.31",
+ "185.213.165.32",
+ "185.213.165.62",
+ "185.213.165.70",
+ "185.213.165.82",
+ "185.213.165.97",
+ "185.213.165.104",
+ "185.213.165.224",
+ "185.214.39.156",
+ "185.215.154.23",
+ "185.217.6.30",
+ "185.217.6.130",
+ "185.218.139.80",
+ "185.218.139.100",
+ "185.218.139.133",
+ "185.221.192.6",
+ "185.221.192.27",
+ "185.221.192.28",
+ "185.221.192.101",
+ "185.221.192.215",
+ "185.221.194.133",
+ "185.221.194.195",
+ "185.221.194.228",
+ "185.221.194.238",
+ "185.221.194.250",
+ "185.221.194.252",
+ "185.221.195.94",
+ "185.221.195.95",
+ "185.221.195.227",
+ "185.221.195.235",
+ "185.221.239.51",
+ "185.221.239.59",
+ "185.221.239.73",
+ "185.221.239.89",
+ "185.221.239.92",
+ "185.221.239.164",
+ "185.221.239.220",
+ "185.222.163.1",
+ "185.222.163.2",
+ "185.222.163.65",
+ "185.222.163.81",
+ "185.222.163.89",
+ "185.222.163.93",
+ "185.222.163.97",
+ "185.222.163.165",
+ "185.222.163.169",
+ "185.222.163.177",
+ "185.222.163.185",
+ "185.222.163.193",
+ "185.222.163.201",
+ "185.222.163.209",
+ "185.224.176.14",
+ "185.224.176.24",
+ "185.224.176.41",
+ "185.224.176.82",
+ "185.224.176.112",
+ "185.224.176.125",
+ "185.224.176.127",
+ "185.224.176.159",
+ "185.224.176.163",
+ "185.224.176.177",
+ "185.224.176.190",
+ "185.224.176.215",
+ "185.224.176.220",
+ "185.224.177.33",
+ "185.224.177.91",
+ "185.224.177.112",
+ "185.224.177.163",
+ "185.224.177.187",
+ "185.224.177.244",
+ "185.224.179.16",
+ "185.224.179.17",
+ "185.224.179.27",
+ "185.224.179.38",
+ "185.224.179.45",
+ "185.224.179.47",
+ "185.224.179.61",
+ "185.224.179.75",
+ "185.224.179.81",
+ "185.224.179.90",
+ "185.224.179.118",
+ "185.224.179.176",
+ "185.224.179.186",
+ "185.224.179.204",
+ "185.224.179.213",
+ "185.224.179.227",
+ "185.225.80.25",
+ "185.225.80.73",
+ "185.225.80.102",
+ "185.225.80.130",
+ "185.225.80.233",
+ "185.225.80.234",
+ "185.225.82.154",
+ "185.225.82.162",
+ "185.225.82.195",
+ "185.225.83.64",
+ "185.225.183.2",
+ "185.225.240.138",
+ "185.225.240.150",
+ "185.225.241.230",
+ "185.225.241.242",
+ "185.225.241.250",
+ "185.225.242.162",
+ "185.225.242.178",
+ "185.225.242.243",
+ "185.225.243.83",
+ "185.225.243.84",
+ "185.225.243.86",
+ "185.225.243.87",
+ "185.225.243.88",
+ "185.225.243.89",
+ "185.225.243.91",
+ "185.225.243.94",
+ "185.226.116.89",
+ "185.226.116.243",
+ "185.226.117.8",
+ "185.226.117.111",
+ "185.226.117.156",
+ "185.226.117.161",
+ "185.226.117.193",
+ "185.226.117.231",
+ "185.226.118.2",
+ "185.226.119.93",
+ "185.226.119.113",
+ "185.226.119.143",
+ "185.226.119.220",
+ "185.228.59.189",
+ "185.229.28.46",
+ "185.229.31.47",
+ "185.229.31.73",
+ "185.229.31.171",
+ "185.229.31.193",
+ "185.229.133.40",
+ "185.229.204.98",
+ "185.229.204.99",
+ "185.229.204.100",
+ "185.229.204.101",
+ "185.229.204.145",
+ "185.231.65.2",
+ "185.231.65.213",
+ "185.231.112.64",
+ "185.231.112.114",
+ "185.231.112.169",
+ "185.231.115.28",
+ "185.231.115.126",
+ "185.231.115.201",
+ "185.231.115.248",
+ "185.231.180.157",
+ "185.231.181.20",
+ "185.231.181.30",
+ "185.231.182.164",
+ "185.231.182.250",
+ "185.231.183.143",
+ "185.232.154.125",
+ "185.233.131.19",
+ "185.233.131.30",
+ "185.233.131.152",
+ "185.233.131.154",
+ "185.233.131.156",
+ "185.233.131.170",
+ "185.233.131.171",
+ "185.233.131.183",
+ "185.233.131.186",
+ "185.235.136.161",
+ "185.235.136.184",
+ "185.235.139.9",
+ "185.235.139.41",
+ "185.235.139.57",
+ "185.235.139.70",
+ "185.235.139.151",
+ "185.235.196.3",
+ "185.235.196.6",
+ "185.235.196.21",
+ "185.235.196.41",
+ "185.235.196.42",
+ "185.235.196.44",
+ "185.235.196.51",
+ "185.235.196.54",
+ "185.235.196.58",
+ "185.235.196.75",
+ "185.235.196.91",
+ "185.235.196.105",
+ "185.235.196.109",
+ "185.235.196.118",
+ "185.235.196.144",
+ "185.235.197.39",
+ "185.235.245.149",
+ "185.235.245.186",
+ "185.236.36.154",
+ "185.236.37.101",
+ "185.236.37.199",
+ "185.236.38.41",
+ "185.236.38.42",
+ "185.236.38.43",
+ "185.236.38.47",
+ "185.236.38.84",
+ "185.237.84.36",
+ "185.237.84.49",
+ "185.237.84.188",
+ "185.237.84.195",
+ "185.237.84.241",
+ "185.237.84.243",
+ "185.237.84.245",
+ "185.237.85.220",
+ "185.237.86.140",
+ "185.237.87.6",
+ "185.237.87.65",
+ "185.237.87.99",
+ "185.237.87.128",
+ "185.237.87.141",
+ "185.237.87.158",
+ "185.237.87.165",
+ "185.237.87.195",
+ "185.237.87.214",
+ "185.238.44.24",
+ "185.238.44.61",
+ "185.238.44.72",
+ "185.238.44.121",
+ "185.238.44.134",
+ "185.238.44.205",
+ "185.238.44.212",
+ "185.238.44.215",
+ "185.238.44.232",
+ "185.238.44.234",
+ "185.238.45.15",
+ "185.238.45.17",
+ "185.238.45.25",
+ "185.238.45.47",
+ "185.238.45.71",
+ "185.238.45.76",
+ "185.238.45.119",
+ "185.238.45.121",
+ "185.238.45.129",
+ "185.238.45.156",
+ "185.238.45.173",
+ "185.238.45.176",
+ "185.238.45.181",
+ "185.238.45.211",
+ "185.238.45.214",
+ "185.238.45.246",
+ "185.238.45.250",
+ "185.238.46.8",
+ "185.238.46.18",
+ "185.238.46.54",
+ "185.238.46.59",
+ "185.238.46.62",
+ "185.238.46.118",
+ "185.238.46.138",
+ "185.238.46.140",
+ "185.238.46.146",
+ "185.238.46.158",
+ "185.238.46.164",
+ "185.238.46.172",
+ "185.238.46.181",
+ "185.238.46.200",
+ "185.238.46.214",
+ "185.238.46.215",
+ "185.238.46.232",
+ "185.238.46.237",
+ "185.238.46.244",
+ "185.238.47.6",
+ "185.238.47.11",
+ "185.238.47.13",
+ "185.238.47.21",
+ "185.238.47.36",
+ "185.238.47.62",
+ "185.238.47.109",
+ "185.238.47.111",
+ "185.238.47.115",
+ "185.238.47.124",
+ "185.238.47.147",
+ "185.238.47.152",
+ "185.238.47.185",
+ "185.238.47.199",
+ "185.238.47.216",
+ "185.238.47.252",
+ "185.238.140.75",
+ "185.239.0.72",
+ "185.239.1.30",
+ "185.239.1.62",
+ "185.239.2.3",
+ "185.239.3.51",
+ "185.239.3.69",
+ "185.239.3.166",
+ "185.239.3.189",
+ "185.239.106.121",
+ "185.243.48.103",
+ "185.243.48.133",
+ "185.243.48.190",
+ "185.243.49.158",
+ "185.243.50.1",
+ "185.243.50.2",
+ "185.246.6.94",
+ "185.246.6.102",
+ "185.251.76.53",
+ "185.251.76.193",
+ "185.251.76.194",
+ "185.251.77.130",
+ "185.252.29.116",
+ "185.252.29.233",
+ "185.252.30.130",
+ "185.252.31.36",
+ "185.252.31.58",
+ "185.252.31.68",
+ "185.252.31.113",
+ "185.252.31.130",
+ "185.252.31.156",
+ "185.252.31.200",
+ "185.252.31.210",
+ "185.252.86.16",
+ "185.252.86.40",
+ "185.252.86.154",
+ "185.252.86.182",
+ "185.255.88.108",
+ "185.255.88.114",
+ "185.255.88.138",
+ "185.255.88.155",
+ "185.255.88.166",
+ "185.255.88.204",
+ "185.255.88.237",
+ "185.255.89.69",
+ "185.255.89.80",
+ "185.255.89.100",
+ "185.255.89.101",
+ "185.255.89.108",
+ "185.255.89.130",
+ "185.255.89.146",
+ "185.255.89.156",
+ "185.255.89.158",
+ "185.255.89.164",
+ "185.255.89.246",
+ "185.255.90.24",
+ "185.255.90.114",
+ "185.255.90.130",
+ "185.255.90.140",
+ "185.255.90.147",
+ "185.255.91.1",
+ "185.255.91.2",
+ "185.255.91.10",
+ "185.255.91.42",
+ "185.255.91.84",
+ "185.255.91.207",
+ "185.255.208.35",
+ "185.255.208.179",
+ "185.255.208.194",
+ "185.255.209.132",
+ "185.255.209.134",
+ "185.255.209.137",
+ "185.255.209.224",
+ "185.255.209.227",
+ "185.255.209.253",
+ "185.255.210.32",
+ "185.255.210.151",
+ "185.255.210.152",
+ "185.255.210.167",
+ "185.255.210.175",
+ "185.255.210.195",
+ "185.255.210.198",
+ "185.255.210.199",
+ "185.255.210.209",
+ "185.255.211.6",
+ "185.255.211.30",
+ "185.255.211.48",
+ "185.255.211.67",
+ "185.255.211.121",
+ "185.255.211.150",
+ "185.255.211.158",
+ "185.255.211.195",
+ "188.0.240.2",
+ "188.0.240.3",
+ "188.0.240.5",
+ "188.0.240.6",
+ "188.0.241.253",
+ "188.0.244.246",
+ "188.0.244.254",
+ "188.0.245.1",
+ "188.0.246.55",
+ "188.0.246.94",
+ "188.0.247.47",
+ "188.0.247.245",
+ "188.0.249.124",
+ "188.0.249.204",
+ "188.0.249.219",
+ "188.0.251.180",
+ "188.0.252.126",
+ "188.0.254.153",
+ "188.0.255.161",
+ "188.75.65.201",
+ "188.75.78.42",
+ "188.75.78.131",
+ "188.75.78.173",
+ "188.75.78.181",
+ "188.75.80.42",
+ "188.75.80.73",
+ "188.75.80.192",
+ "188.75.80.226",
+ "188.75.80.227",
+ "188.75.80.228",
+ "188.75.80.234",
+ "188.75.81.162",
+ "188.75.81.163",
+ "188.75.81.165",
+ "188.75.81.166",
+ "188.75.87.195",
+ "188.75.88.147",
+ "188.75.88.148",
+ "188.75.88.149",
+ "188.75.88.150",
+ "188.75.93.203",
+ "188.75.93.227",
+ "188.75.104.114",
+ "188.75.104.115",
+ "188.75.104.116",
+ "188.75.104.117",
+ "188.75.104.118",
+ "188.75.126.18",
+ "188.75.126.74",
+ "188.94.188.1",
+ "188.121.96.87",
+ "188.121.100.30",
+ "188.121.100.110",
+ "188.121.100.111",
+ "188.121.100.169",
+ "188.121.100.176",
+ "188.121.100.203",
+ "188.121.101.25",
+ "188.121.101.133",
+ "188.121.101.140",
+ "188.121.102.5",
+ "188.121.102.200",
+ "188.121.103.53",
+ "188.121.103.86",
+ "188.121.103.248",
+ "188.121.104.17",
+ "188.121.104.40",
+ "188.121.105.16",
+ "188.121.105.93",
+ "188.121.105.118",
+ "188.121.105.171",
+ "188.121.106.202",
+ "188.121.107.141",
+ "188.121.107.164",
+ "188.121.108.55",
+ "188.121.108.56",
+ "188.121.109.133",
+ "188.121.110.36",
+ "188.121.110.61",
+ "188.121.110.172",
+ "188.121.110.202",
+ "188.121.111.40",
+ "188.121.111.127",
+ "188.121.112.15",
+ "188.121.113.136",
+ "188.121.116.47",
+ "188.121.116.238",
+ "188.121.117.164",
+ "188.121.117.166",
+ "188.121.118.101",
+ "188.121.118.105",
+ "188.121.118.128",
+ "188.121.118.162",
+ "188.121.118.197",
+ "188.121.118.206",
+ "188.121.118.216",
+ "188.121.119.99",
+ "188.121.119.145",
+ "188.121.119.191",
+ "188.121.119.217",
+ "188.121.120.91",
+ "188.121.120.194",
+ "188.121.122.208",
+ "188.121.123.70",
+ "188.121.123.188",
+ "188.121.124.67",
+ "188.121.128.40",
+ "188.121.129.122",
+ "188.121.129.226",
+ "188.121.129.227",
+ "188.121.129.228",
+ "188.121.129.238",
+ "188.121.144.30",
+ "188.121.144.162",
+ "188.121.144.194",
+ "188.121.144.238",
+ "188.121.145.6",
+ "188.121.145.22",
+ "188.121.145.78",
+ "188.121.145.122",
+ "188.121.145.154",
+ "188.121.145.182",
+ "188.121.146.50",
+ "188.121.146.142",
+ "188.121.146.198",
+ "188.121.146.226",
+ "188.121.147.34",
+ "188.121.147.38",
+ "188.121.147.42",
+ "188.121.147.46",
+ "188.121.147.50",
+ "188.121.147.58",
+ "188.121.147.62",
+ "188.121.147.66",
+ "188.121.147.70",
+ "188.121.147.74",
+ "188.121.147.78",
+ "188.121.147.90",
+ "188.121.147.118",
+ "188.121.147.150",
+ "188.121.147.166",
+ "188.121.148.46",
+ "188.121.148.66",
+ "188.121.148.94",
+ "188.121.148.162",
+ "188.121.148.174",
+ "188.121.148.186",
+ "188.121.148.190",
+ "188.121.149.50",
+ "188.121.149.62",
+ "188.121.149.114",
+ "188.121.149.138",
+ "188.121.149.186",
+ "188.121.149.242",
+ "188.121.156.211",
+ "188.121.157.133",
+ "188.121.157.170",
+ "188.121.157.181",
+ "188.121.157.186",
+ "188.121.157.250",
+ "188.121.159.2",
+ "188.121.159.34",
+ "188.121.159.36",
+ "188.121.159.37",
+ "188.136.130.1",
+ "188.136.130.160",
+ "188.136.133.33",
+ "188.136.133.111",
+ "188.136.133.114",
+ "188.136.133.123",
+ "188.136.133.218",
+ "188.136.133.224",
+ "188.136.133.225",
+ "188.136.133.243",
+ "188.136.142.81",
+ "188.136.142.133",
+ "188.136.142.134",
+ "188.136.142.166",
+ "188.136.143.13",
+ "188.136.143.20",
+ "188.136.144.38",
+ "188.136.144.131",
+ "188.136.144.143",
+ "188.136.154.38",
+ "188.136.154.51",
+ "188.136.154.137",
+ "188.136.154.186",
+ "188.136.154.187",
+ "188.136.154.188",
+ "188.136.154.189",
+ "188.136.155.41",
+ "188.136.162.21",
+ "188.136.162.30",
+ "188.136.162.104",
+ "188.136.162.213",
+ "188.136.162.216",
+ "188.136.162.217",
+ "188.136.162.218",
+ "188.136.162.220",
+ "188.136.162.221",
+ "188.136.165.1",
+ "188.136.172.33",
+ "188.136.172.34",
+ "188.136.172.35",
+ "188.136.172.37",
+ "188.136.172.38",
+ "188.136.172.44",
+ "188.136.172.45",
+ "188.136.172.47",
+ "188.136.172.53",
+ "188.136.172.76",
+ "188.136.172.83",
+ "188.136.172.86",
+ "188.136.172.97",
+ "188.136.172.101",
+ "188.136.172.103",
+ "188.136.172.120",
+ "188.136.172.121",
+ "188.136.172.126",
+ "188.136.172.127",
+ "188.136.172.129",
+ "188.136.172.132",
+ "188.136.172.136",
+ "188.136.172.142",
+ "188.136.172.148",
+ "188.136.172.152",
+ "188.136.172.157",
+ "188.136.172.158",
+ "188.136.172.160",
+ "188.136.172.161",
+ "188.136.172.165",
+ "188.136.172.172",
+ "188.136.172.176",
+ "188.136.172.183",
+ "188.136.172.184",
+ "188.136.172.185",
+ "188.136.172.186",
+ "188.136.172.187",
+ "188.136.172.188",
+ "188.136.172.189",
+ "188.136.172.190",
+ "188.136.172.193",
+ "188.136.172.224",
+ "188.136.172.226",
+ "188.136.172.227",
+ "188.136.172.229",
+ "188.136.172.230",
+ "188.136.172.231",
+ "188.136.172.232",
+ "188.136.172.234",
+ "188.136.172.235",
+ "188.136.172.237",
+ "188.136.172.240",
+ "188.136.172.241",
+ "188.136.172.242",
+ "188.136.172.245",
+ "188.136.172.247",
+ "188.136.172.250",
+ "188.136.172.251",
+ "188.136.172.253",
+ "188.136.174.34",
+ "188.136.174.35",
+ "188.136.174.42",
+ "188.136.174.86",
+ "188.136.174.118",
+ "188.136.174.130",
+ "188.136.174.131",
+ "188.136.174.133",
+ "188.136.174.134",
+ "188.136.174.214",
+ "188.136.174.234",
+ "188.136.174.242",
+ "188.136.194.54",
+ "188.136.194.238",
+ "188.136.196.1",
+ "188.136.196.29",
+ "188.136.196.36",
+ "188.136.196.125",
+ "188.136.196.164",
+ "188.136.196.167",
+ "188.136.196.178",
+ "188.136.196.180",
+ "188.136.196.216",
+ "188.136.196.217",
+ "188.136.196.220",
+ "188.136.196.221",
+ "188.136.196.222",
+ "188.136.196.224",
+ "188.136.196.226",
+ "188.136.196.228",
+ "188.136.196.229",
+ "188.136.208.6",
+ "188.136.208.82",
+ "188.136.208.83",
+ "188.136.208.114",
+ "188.136.208.210",
+ "188.136.208.211",
+ "188.136.208.212",
+ "188.136.208.242",
+ "188.136.208.244",
+ "188.136.208.250",
+ "188.136.208.251",
+ "188.136.208.253",
+ "188.136.208.254",
+ "188.208.56.88",
+ "188.208.56.94",
+ "188.208.56.134",
+ "188.208.56.230",
+ "188.208.63.30",
+ "188.208.63.66",
+ "188.208.144.7",
+ "188.208.144.84",
+ "188.208.144.141",
+ "188.208.144.191",
+ "188.208.144.218",
+ "188.208.145.14",
+ "188.208.145.39",
+ "188.208.145.67",
+ "188.208.145.83",
+ "188.208.145.97",
+ "188.208.145.124",
+ "188.208.145.184",
+ "188.208.145.187",
+ "188.208.146.177",
+ "188.208.146.210",
+ "188.208.147.201",
+ "188.208.149.13",
+ "188.208.149.118",
+ "188.208.149.200",
+ "188.208.149.213",
+ "188.208.149.246",
+ "188.208.150.5",
+ "188.208.150.68",
+ "188.208.150.73",
+ "188.208.150.91",
+ "188.208.150.117",
+ "188.208.150.161",
+ "188.208.150.165",
+ "188.208.150.171",
+ "188.208.150.174",
+ "188.208.150.179",
+ "188.208.150.229",
+ "188.208.151.8",
+ "188.208.151.20",
+ "188.208.151.188",
+ "188.208.151.194",
+ "188.208.151.216",
+ "188.208.151.231",
+ "188.208.151.235",
+ "188.208.151.239",
+ "188.208.152.48",
+ "188.209.5.105",
+ "188.209.7.237",
+ "188.209.64.130",
+ "188.209.67.86",
+ "188.209.68.119",
+ "188.209.68.154",
+ "188.209.70.75",
+ "188.209.71.99",
+ "188.209.73.96",
+ "188.209.73.213",
+ "188.209.75.111",
+ "188.209.152.41",
+ "188.209.152.44",
+ "188.209.152.45",
+ "188.210.87.44",
+ "188.210.101.67",
+ "188.210.102.82",
+ "188.210.106.213",
+ "188.210.108.144",
+ "188.210.111.45",
+ "188.210.119.248",
+ "188.210.122.152",
+ "188.210.124.2",
+ "188.211.0.21",
+ "188.211.36.106",
+ "188.211.37.41",
+ "188.211.37.66",
+ "188.211.37.241",
+ "188.211.38.53",
+ "188.211.38.123",
+ "188.211.39.239",
+ "188.211.64.58",
+ "188.211.67.61",
+ "188.211.68.251",
+ "188.211.71.224",
+ "188.211.72.217",
+ "188.211.73.160",
+ "188.211.74.213",
+ "188.211.75.219",
+ "188.211.77.39",
+ "188.211.81.212",
+ "188.211.83.2",
+ "188.211.83.111",
+ "188.211.85.38",
+ "188.211.86.144",
+ "188.211.87.74",
+ "188.211.87.109",
+ "188.211.88.213",
+ "188.211.94.162",
+ "188.211.97.75",
+ "188.211.97.191",
+ "188.211.101.64",
+ "188.211.102.1",
+ "188.211.102.63",
+ "188.211.103.103",
+ "188.211.104.86",
+ "188.211.106.247",
+ "188.211.108.91",
+ "188.211.108.225",
+ "188.211.108.233",
+ "188.211.109.198",
+ "188.211.109.231",
+ "188.211.111.1",
+ "188.211.111.88",
+ "188.211.112.52",
+ "188.211.116.32",
+ "188.211.116.106",
+ "188.211.117.99",
+ "188.211.119.76",
+ "188.211.119.151",
+ "188.211.120.127",
+ "188.211.122.83",
+ "188.211.122.114",
+ "188.211.122.196",
+ "188.211.200.215",
+ "188.211.201.191",
+ "188.211.202.114",
+ "188.211.203.139",
+ "188.211.204.58",
+ "188.211.205.92",
+ "188.211.205.231",
+ "188.211.206.93",
+ "188.211.206.213",
+ "188.212.22.1",
+ "188.212.22.9",
+ "188.212.22.33",
+ "188.212.22.65",
+ "188.212.22.129",
+ "188.212.22.137",
+ "188.212.22.141",
+ "188.212.22.145",
+ "188.212.22.162",
+ "188.212.22.177",
+ "188.212.22.181",
+ "188.212.22.193",
+ "188.212.22.225",
+ "188.212.22.233",
+ "188.212.22.241",
+ "188.212.22.245",
+ "188.212.64.211",
+ "188.212.65.46",
+ "188.212.66.9",
+ "188.212.66.23",
+ "188.212.66.156",
+ "188.212.68.65",
+ "188.212.68.198",
+ "188.212.71.143",
+ "188.212.71.247",
+ "188.212.73.158",
+ "188.212.74.73",
+ "188.212.79.110",
+ "188.212.82.196",
+ "188.212.85.146",
+ "188.212.85.156",
+ "188.212.88.208",
+ "188.212.88.236",
+ "188.212.89.105",
+ "188.212.89.188",
+ "188.212.90.171",
+ "188.212.92.230",
+ "188.212.92.247",
+ "188.212.93.138",
+ "188.212.93.197",
+ "188.212.95.78",
+ "188.212.148.162",
+ "188.212.160.208",
+ "188.212.161.115",
+ "188.212.169.84",
+ "188.212.171.199",
+ "188.212.172.58",
+ "188.212.173.54",
+ "188.212.177.247",
+ "188.212.178.9",
+ "188.212.178.118",
+ "188.212.178.182",
+ "188.212.183.13",
+ "188.212.183.19",
+ "188.212.186.53",
+ "188.212.187.42",
+ "188.212.242.211",
+ "188.212.244.182",
+ "188.213.66.15",
+ "188.213.66.20",
+ "188.213.66.25",
+ "188.213.66.90",
+ "188.213.66.131",
+ "188.213.66.132",
+ "188.213.66.133",
+ "188.213.67.70",
+ "188.213.67.98",
+ "188.213.67.108",
+ "188.213.67.131",
+ "188.213.68.146",
+ "188.213.71.62",
+ "188.213.71.207",
+ "188.213.76.19",
+ "188.213.76.94",
+ "188.213.76.183",
+ "188.213.76.240",
+ "188.213.77.26",
+ "188.213.78.22",
+ "188.213.79.21",
+ "188.213.79.116",
+ "188.213.79.221",
+ "188.213.79.240",
+ "188.213.176.97",
+ "188.213.178.0",
+ "188.213.178.61",
+ "188.213.178.62",
+ "188.213.179.251",
+ "188.213.180.79",
+ "188.213.181.176",
+ "188.213.189.255",
+ "188.213.191.85",
+ "188.213.195.243",
+ "188.213.196.20",
+ "188.213.196.137",
+ "188.213.196.138",
+ "188.213.196.185",
+ "188.213.198.13",
+ "188.213.198.219",
+ "188.213.209.124",
+ "188.213.209.146",
+ "188.213.209.149",
+ "188.213.209.156",
+ "188.213.209.168",
+ "188.213.209.178",
+ "188.213.209.218",
+ "188.213.211.25",
+ "188.213.211.170",
+ "188.214.96.65",
+ "188.214.96.106",
+ "188.214.96.146",
+ "188.214.96.150",
+ "188.214.97.41",
+ "188.214.98.114",
+ "188.214.98.215",
+ "188.214.98.253",
+ "188.214.99.182",
+ "188.214.173.57",
+ "188.214.216.26",
+ "188.214.216.59",
+ "188.214.216.154",
+ "188.214.216.255",
+ "188.214.217.240",
+ "188.214.218.34",
+ "188.214.219.48",
+ "188.214.219.103",
+ "188.214.219.142",
+ "188.214.219.206",
+ "188.214.219.248",
+ "188.214.220.225",
+ "188.214.221.32",
+ "188.214.221.78",
+ "188.214.222.47",
+ "188.214.223.109",
+ "188.214.223.160",
+ "188.214.223.232",
+ "188.215.140.46",
+ "188.215.140.220",
+ "188.215.160.200",
+ "188.215.162.36",
+ "188.215.163.71",
+ "188.215.164.144",
+ "188.215.166.176",
+ "188.215.167.35",
+ "188.215.168.146",
+ "188.215.168.152",
+ "188.215.174.188",
+ "188.215.213.76",
+ "188.215.214.66",
+ "188.240.212.9",
+ "193.3.255.1",
+ "193.3.255.2",
+ "193.3.255.3",
+ "193.3.255.4",
+ "193.3.255.5",
+ "193.3.255.6",
+ "193.3.255.7",
+ "193.3.255.8",
+ "193.3.255.9",
+ "193.3.255.12",
+ "193.3.255.15",
+ "193.3.255.16",
+ "193.3.255.18",
+ "193.3.255.19",
+ "193.3.255.21",
+ "193.3.255.22",
+ "193.3.255.24",
+ "193.3.255.25",
+ "193.3.255.28",
+ "193.3.255.29",
+ "193.3.255.30",
+ "193.3.255.31",
+ "193.3.255.32",
+ "193.3.255.33",
+ "193.3.255.34",
+ "193.3.255.35",
+ "193.3.255.36",
+ "193.3.255.37",
+ "193.3.255.38",
+ "193.3.255.39",
+ "193.3.255.40",
+ "193.3.255.41",
+ "193.3.255.42",
+ "193.3.255.43",
+ "193.3.255.44",
+ "193.3.255.45",
+ "193.3.255.46",
+ "193.3.255.47",
+ "193.3.255.48",
+ "193.3.255.49",
+ "193.3.255.50",
+ "193.3.255.51",
+ "193.3.255.52",
+ "193.3.255.53",
+ "193.3.255.54",
+ "193.3.255.55",
+ "193.3.255.56",
+ "193.3.255.57",
+ "193.3.255.59",
+ "193.3.255.60",
+ "193.3.255.61",
+ "193.3.255.62",
+ "193.3.255.63",
+ "193.3.255.65",
+ "193.3.255.66",
+ "193.3.255.67",
+ "193.3.255.68",
+ "193.3.255.69",
+ "193.3.255.70",
+ "193.3.255.71",
+ "193.3.255.72",
+ "193.3.255.73",
+ "193.3.255.74",
+ "193.3.255.75",
+ "193.3.255.76",
+ "193.3.255.77",
+ "193.3.255.79",
+ "193.3.255.80",
+ "193.3.255.81",
+ "193.3.255.82",
+ "193.3.255.83",
+ "193.3.255.84",
+ "193.3.255.85",
+ "193.3.255.86",
+ "193.3.255.87",
+ "193.3.255.88",
+ "193.3.255.89",
+ "193.3.255.90",
+ "193.3.255.91",
+ "193.3.255.92",
+ "193.3.255.93",
+ "193.3.255.95",
+ "193.3.255.96",
+ "193.3.255.98",
+ "193.3.255.99",
+ "193.3.255.100",
+ "193.3.255.102",
+ "193.3.255.103",
+ "193.3.255.104",
+ "193.3.255.105",
+ "193.3.255.106",
+ "193.3.255.107",
+ "193.3.255.108",
+ "193.3.255.109",
+ "193.3.255.110",
+ "193.3.255.111",
+ "193.3.255.112",
+ "193.3.255.113",
+ "193.3.255.114",
+ "193.3.255.115",
+ "193.3.255.116",
+ "193.3.255.117",
+ "193.3.255.118",
+ "193.3.255.119",
+ "193.3.255.120",
+ "193.3.255.121",
+ "193.3.255.122",
+ "193.3.255.123",
+ "193.3.255.124",
+ "193.3.255.125",
+ "193.3.255.126",
+ "193.3.255.128",
+ "193.3.255.129",
+ "193.3.255.130",
+ "193.3.255.131",
+ "193.3.255.133",
+ "193.3.255.134",
+ "193.3.255.135",
+ "193.3.255.137",
+ "193.3.255.139",
+ "193.3.255.140",
+ "193.3.255.141",
+ "193.3.255.142",
+ "193.3.255.143",
+ "193.3.255.144",
+ "193.3.255.145",
+ "193.3.255.146",
+ "193.3.255.147",
+ "193.3.255.148",
+ "193.3.255.149",
+ "193.3.255.150",
+ "193.3.255.151",
+ "193.3.255.152",
+ "193.3.255.153",
+ "193.3.255.154",
+ "193.3.255.155",
+ "193.3.255.156",
+ "193.3.255.157",
+ "193.3.255.158",
+ "193.3.255.160",
+ "193.3.255.161",
+ "193.3.255.164",
+ "193.3.255.165",
+ "193.3.255.166",
+ "193.3.255.167",
+ "193.3.255.168",
+ "193.3.255.169",
+ "193.3.255.170",
+ "193.3.255.171",
+ "193.3.255.172",
+ "193.3.255.174",
+ "193.3.255.175",
+ "193.3.255.176",
+ "193.3.255.177",
+ "193.3.255.178",
+ "193.3.255.179",
+ "193.3.255.180",
+ "193.3.255.182",
+ "193.3.255.184",
+ "193.3.255.185",
+ "193.3.255.186",
+ "193.3.255.187",
+ "193.3.255.188",
+ "193.3.255.191",
+ "193.3.255.192",
+ "193.3.255.193",
+ "193.3.255.197",
+ "193.3.255.198",
+ "193.3.255.199",
+ "193.3.255.200",
+ "193.3.255.201",
+ "193.3.255.202",
+ "193.3.255.203",
+ "193.3.255.204",
+ "193.3.255.205",
+ "193.3.255.206",
+ "193.3.255.207",
+ "193.3.255.208",
+ "193.3.255.209",
+ "193.3.255.210",
+ "193.3.255.211",
+ "193.3.255.212",
+ "193.3.255.213",
+ "193.3.255.214",
+ "193.3.255.216",
+ "193.3.255.217",
+ "193.3.255.218",
+ "193.3.255.219",
+ "193.3.255.220",
+ "193.3.255.221",
+ "193.3.255.222",
+ "193.3.255.223",
+ "193.3.255.224",
+ "193.3.255.225",
+ "193.3.255.226",
+ "193.3.255.227",
+ "193.3.255.228",
+ "193.3.255.229",
+ "193.3.255.230",
+ "193.3.255.231",
+ "193.3.255.232",
+ "193.3.255.233",
+ "193.3.255.234",
+ "193.3.255.235",
+ "193.3.255.236",
+ "193.3.255.237",
+ "193.3.255.238",
+ "193.3.255.239",
+ "193.3.255.240",
+ "193.3.255.241",
+ "193.3.255.242",
+ "193.3.255.243",
+ "193.3.255.244",
+ "193.3.255.245",
+ "193.3.255.246",
+ "193.3.255.248",
+ "193.3.255.249",
+ "193.3.255.250",
+ "193.3.255.251",
+ "193.3.255.252",
+ "193.3.255.253",
+ "193.5.44.24",
+ "193.5.44.96",
+ "193.5.44.201",
+ "193.19.144.9",
+ "193.19.144.10",
+ "193.22.20.2",
+ "193.24.103.1",
+ "193.24.103.2",
+ "193.35.230.2",
+ "193.35.230.9",
+ "193.35.230.34",
+ "193.37.37.2",
+ "193.37.37.3",
+ "193.37.37.248",
+ "193.39.9.66",
+ "193.39.9.101",
+ "193.39.9.115",
+ "193.56.59.10",
+ "193.56.61.140",
+ "193.56.61.164",
+ "193.56.107.107",
+ "193.56.107.180",
+ "193.56.107.196",
+ "193.56.107.236",
+ "193.56.107.238",
+ "193.56.118.24",
+ "193.56.118.26",
+ "193.56.118.33",
+ "193.56.118.126",
+ "193.56.118.199",
+ "193.58.119.39",
+ "193.84.255.67",
+ "193.104.29.50",
+ "193.105.6.203",
+ "193.105.234.5",
+ "193.105.234.74",
+ "193.105.234.122",
+ "193.105.234.141",
+ "193.105.234.153",
+ "193.111.234.83",
+ "193.111.234.117",
+ "193.111.234.145",
+ "193.111.234.205",
+ "193.111.234.217",
+ "193.111.235.31",
+ "193.111.235.42",
+ "193.111.235.91",
+ "193.111.235.95",
+ "193.111.235.231",
+ "193.111.235.232",
+ "193.111.235.235",
+ "193.111.235.236",
+ "193.111.236.136",
+ "193.111.236.139",
+ "193.111.236.180",
+ "193.134.100.74",
+ "193.134.100.108",
+ "193.134.100.243",
+ "193.134.101.67",
+ "193.134.101.132",
+ "193.141.64.6",
+ "193.141.64.75",
+ "193.141.64.79",
+ "193.141.64.101",
+ "193.141.64.106",
+ "193.141.64.113",
+ "193.141.64.135",
+ "193.141.64.156",
+ "193.141.64.163",
+ "193.141.64.188",
+ "193.141.64.236",
+ "193.141.65.130",
+ "193.148.65.41",
+ "193.148.65.69",
+ "193.148.65.240",
+ "193.148.65.244",
+ "193.148.66.21",
+ "193.148.66.165",
+ "193.148.67.117",
+ "193.150.66.62",
+ "193.150.66.134",
+ "193.151.132.30",
+ "193.151.137.70",
+ "193.151.145.132",
+ "193.151.153.134",
+ "193.151.154.156",
+ "193.151.157.155",
+ "193.151.157.157",
+ "193.151.157.158",
+ "193.151.157.175",
+ "193.151.157.190",
+ "193.151.157.191",
+ "193.151.157.192",
+ "193.151.157.193",
+ "193.151.159.229",
+ "193.151.159.248",
+ "193.176.97.103",
+ "193.176.97.128",
+ "193.176.97.141",
+ "193.177.242.20",
+ "193.178.200.20",
+ "193.186.32.83",
+ "193.186.32.102",
+ "193.186.32.158",
+ "193.186.32.226",
+ "193.186.215.9",
+ "193.200.148.10",
+ "193.200.148.17",
+ "193.200.148.48",
+ "193.200.148.55",
+ "193.200.148.58",
+ "193.200.148.68",
+ "193.200.148.149",
+ "193.200.148.151",
+ "193.200.148.162",
+ "193.200.148.186",
+ "193.200.148.197",
+ "193.200.148.205",
+ "193.201.192.250",
+ "193.228.90.29",
+ "193.228.90.30",
+ "193.228.90.96",
+ "193.228.90.118",
+ "193.228.90.138",
+ "193.228.90.153",
+ "193.228.91.26",
+ "193.228.91.27",
+ "193.228.91.153",
+ "193.228.136.128",
+ "193.228.136.133",
+ "193.228.136.138",
+ "193.228.136.139",
+ "193.228.136.140",
+ "193.228.136.144",
+ "193.228.136.145",
+ "193.228.136.151",
+ "193.228.136.155",
+ "193.228.136.158",
+ "193.228.136.192",
+ "193.228.136.193",
+ "193.228.136.204",
+ "193.228.136.209",
+ "193.228.136.210",
+ "193.228.136.215",
+ "193.228.136.218",
+ "193.228.136.219",
+ "193.228.136.220",
+ "193.228.136.221",
+ "193.228.136.223",
+ "193.228.168.52",
+ "193.228.168.162",
+ "193.228.168.234",
+ "193.228.169.10",
+ "193.228.169.21",
+ "193.228.169.25",
+ "193.242.125.66",
+ "193.246.200.1",
+ "193.246.200.33",
+ "193.246.200.34",
+ "193.246.200.65",
+ "193.246.200.81",
+ "193.246.200.82",
+ "193.246.200.114",
+ "193.246.200.117",
+ "193.246.200.119",
+ "193.246.200.120",
+ "193.246.200.124",
+ "193.246.200.125",
+ "193.246.200.126",
+ "193.246.201.46",
+ "194.1.155.9",
+ "194.1.155.54",
+ "194.5.175.112",
+ "194.5.175.159",
+ "194.5.175.225",
+ "194.5.176.42",
+ "194.5.177.1",
+ "194.5.179.1",
+ "194.5.188.44",
+ "194.5.188.81",
+ "194.5.188.109",
+ "194.5.188.160",
+ "194.5.195.19",
+ "194.5.195.97",
+ "194.5.195.166",
+ "194.5.195.189",
+ "194.5.205.51",
+ "194.5.205.159",
+ "194.5.205.227",
+ "194.5.205.241",
+ "194.9.57.32",
+ "194.9.57.119",
+ "194.9.57.148",
+ "194.9.57.160",
+ "194.9.57.167",
+ "194.9.57.186",
+ "194.9.57.199",
+ "194.9.57.217",
+ "194.9.80.21",
+ "194.9.80.35",
+ "194.9.80.38",
+ "194.9.80.56",
+ "194.9.80.84",
+ "194.9.80.125",
+ "194.9.80.127",
+ "194.26.117.37",
+ "194.26.117.40",
+ "194.26.117.57",
+ "194.26.117.68",
+ "194.31.108.22",
+ "194.31.108.45",
+ "194.31.108.250",
+ "194.31.108.251",
+ "194.31.194.184",
+ "194.31.194.203",
+ "194.33.105.11",
+ "194.33.105.12",
+ "194.33.105.53",
+ "194.33.105.96",
+ "194.33.105.185",
+ "194.33.107.242",
+ "194.34.163.55",
+ "194.36.174.30",
+ "194.36.174.157",
+ "194.36.174.251",
+ "194.39.254.54",
+ "194.41.48.21",
+ "194.48.198.50",
+ "194.48.198.204",
+ "194.53.118.3",
+ "194.53.119.3",
+ "194.53.122.41",
+ "194.53.122.61",
+ "194.53.122.70",
+ "194.53.122.75",
+ "194.53.122.76",
+ "194.53.122.83",
+ "194.53.122.101",
+ "194.53.122.119",
+ "194.53.122.123",
+ "194.53.122.126",
+ "194.53.122.141",
+ "194.53.122.150",
+ "194.53.122.178",
+ "194.53.122.248",
+ "194.56.148.5",
+ "194.56.148.129",
+ "194.56.148.170",
+ "194.56.148.177",
+ "194.56.148.225",
+ "194.56.148.235",
+ "194.56.148.243",
+ "194.59.170.3",
+ "194.59.170.235",
+ "194.59.171.12",
+ "194.59.171.32",
+ "194.59.171.71",
+ "194.59.214.78",
+ "194.59.214.89",
+ "194.59.214.254",
+ "194.59.215.114",
+ "194.60.209.10",
+ "194.60.209.11",
+ "194.60.209.12",
+ "194.60.209.14",
+ "194.60.209.26",
+ "194.60.209.98",
+ "194.60.211.105",
+ "194.60.211.125",
+ "194.60.230.60",
+ "194.60.230.118",
+ "194.60.231.14",
+ "194.60.231.55",
+ "194.60.231.73",
+ "194.60.231.153",
+ "194.60.231.173",
+ "194.60.231.226",
+ "194.60.231.229",
+ "194.62.17.34",
+ "194.62.17.171",
+ "194.62.17.246",
+ "194.62.43.52",
+ "194.62.43.119",
+ "194.62.43.147",
+ "194.62.43.173",
+ "194.107.116.115",
+ "194.107.116.116",
+ "194.107.116.117",
+ "194.107.116.118",
+ "194.107.116.254",
+ "194.146.151.21",
+ "194.147.142.11",
+ "194.147.142.226",
+ "194.147.167.48",
+ "194.147.167.85",
+ "194.147.167.221",
+ "194.147.222.122",
+ "194.150.68.0",
+ "194.150.68.98",
+ "194.150.68.101",
+ "194.150.68.128",
+ "194.150.68.144",
+ "194.150.68.145",
+ "194.150.68.147",
+ "194.150.68.148",
+ "194.150.68.149",
+ "194.150.68.150",
+ "194.150.68.151",
+ "194.150.68.152",
+ "194.150.68.153",
+ "194.150.68.156",
+ "194.150.68.158",
+ "194.150.68.199",
+ "194.150.68.207",
+ "194.150.68.248",
+ "194.150.68.249",
+ "194.150.68.250",
+ "194.150.68.251",
+ "194.150.69.148",
+ "194.150.69.159",
+ "194.150.69.181",
+ "194.150.69.197",
+ "194.150.69.198",
+ "194.150.69.199",
+ "194.150.70.38",
+ "194.150.70.44",
+ "194.150.70.45",
+ "194.150.70.46",
+ "194.150.70.47",
+ "194.150.70.55",
+ "194.150.70.91",
+ "194.150.70.180",
+ "194.150.71.17",
+ "194.150.71.37",
+ "194.150.71.45",
+ "194.150.71.57",
+ "194.150.71.58",
+ "194.150.71.174",
+ "194.150.71.234",
+ "194.150.71.251",
+ "194.156.140.111",
+ "194.156.140.167",
+ "194.180.11.149",
+ "194.180.11.197",
+ "194.180.11.203",
+ "194.180.11.252",
+ "194.180.224.21",
+ "194.225.24.15",
+ "194.225.24.113",
+ "194.225.26.41",
+ "194.225.50.88",
+ "194.225.70.5",
+ "194.225.70.83",
+ "194.225.101.1",
+ "194.225.101.2",
+ "194.225.101.3",
+ "194.225.101.5",
+ "194.225.101.7",
+ "194.225.101.9",
+ "194.225.101.11",
+ "194.225.101.12",
+ "194.225.101.13",
+ "194.225.101.14",
+ "194.225.101.15",
+ "194.225.101.16",
+ "194.225.101.17",
+ "194.225.101.18",
+ "194.225.101.19",
+ "194.225.101.20",
+ "194.225.101.21",
+ "194.225.101.22",
+ "194.225.101.24",
+ "194.225.101.26",
+ "194.225.101.27",
+ "194.225.101.32",
+ "194.225.116.10",
+ "194.225.136.254",
+ "194.225.230.72",
+ "195.2.234.254",
+ "195.8.102.50",
+ "195.18.10.15",
+ "195.26.27.158",
+ "195.28.11.12",
+ "195.28.11.56",
+ "195.28.11.100",
+ "195.28.11.107",
+ "195.28.11.126",
+ "195.28.11.227",
+ "195.62.4.28",
+ "195.62.4.29",
+ "195.88.189.5",
+ "195.88.189.18",
+ "195.88.189.33",
+ "195.88.189.38",
+ "195.88.189.56",
+ "195.88.189.67",
+ "195.88.189.85",
+ "195.88.189.89",
+ "195.88.189.103",
+ "195.88.189.105",
+ "195.88.189.119",
+ "195.88.189.144",
+ "195.88.189.153",
+ "195.88.189.189",
+ "195.88.189.195",
+ "195.110.38.130",
+ "195.110.38.233",
+ "195.114.8.145",
+ "195.114.8.146",
+ "195.114.8.147",
+ "195.114.8.148",
+ "195.114.8.149",
+ "195.114.8.150",
+ "195.114.8.151",
+ "195.177.255.7",
+ "195.177.255.92",
+ "195.177.255.133",
+ "195.177.255.138",
+ "195.177.255.149",
+ "195.177.255.198",
+ "195.177.255.211",
+ "195.181.36.29",
+ "195.181.36.41",
+ "195.181.36.63",
+ "195.181.36.80",
+ "195.181.37.11",
+ "195.181.37.49",
+ "195.181.37.75",
+ "195.181.37.79",
+ "195.181.37.190",
+ "195.181.38.44",
+ "195.181.38.48",
+ "195.181.38.56",
+ "195.181.38.128",
+ "195.181.38.211",
+ "195.181.38.234",
+ "195.181.39.40",
+ "195.181.40.13",
+ "195.181.40.70",
+ "195.181.41.140",
+ "195.181.42.99",
+ "195.181.42.100",
+ "195.181.42.101",
+ "195.181.42.102",
+ "195.181.42.103",
+ "195.181.42.105",
+ "195.181.42.106",
+ "195.181.42.107",
+ "195.181.42.109",
+ "195.181.42.110",
+ "195.181.57.219",
+ "195.181.58.29",
+ "195.181.58.63",
+ "195.181.59.49",
+ "195.181.67.97",
+ "195.181.67.208",
+ "195.181.68.14",
+ "195.181.68.235",
+ "195.181.69.11",
+ "195.181.69.69",
+ "195.181.69.251",
+ "195.181.70.117",
+ "195.181.71.73",
+ "195.181.74.147",
+ "195.181.75.174",
+ "195.181.76.140",
+ "195.181.77.166",
+ "195.181.78.111",
+ "195.181.78.163",
+ "195.181.79.112",
+ "195.181.79.121",
+ "195.181.79.153",
+ "195.181.80.176",
+ "195.181.81.96",
+ "195.181.82.25",
+ "195.181.82.183",
+ "195.181.83.149",
+ "195.181.85.207",
+ "195.181.88.31",
+ "195.181.88.147",
+ "195.181.88.219",
+ "195.181.88.223",
+ "195.181.89.140",
+ "195.181.94.39",
+ "195.181.110.185",
+ "195.181.112.94",
+ "195.181.112.252",
+ "195.181.113.38",
+ "195.181.113.53",
+ "195.181.113.189",
+ "195.181.113.219",
+ "195.181.113.255",
+ "195.181.114.59",
+ "195.181.114.81",
+ "195.181.114.107",
+ "195.181.114.196",
+ "195.181.114.224",
+ "195.181.117.163",
+ "195.181.118.41",
+ "195.181.118.57",
+ "195.181.119.171",
+ "195.181.119.186",
+ "195.191.44.6",
+ "195.191.44.7",
+ "195.191.44.20",
+ "195.191.44.70",
+ "195.191.44.98",
+ "195.191.44.115",
+ "195.191.44.142",
+ "195.191.44.154",
+ "195.191.44.161",
+ "195.191.44.170",
+ "195.191.44.176",
+ "195.191.44.191",
+ "195.191.44.207",
+ "195.191.44.213",
+ "195.191.44.214",
+ "195.191.44.254",
+ "195.191.44.255",
+ "195.191.45.12",
+ "195.191.45.14",
+ "195.191.45.26",
+ "195.191.45.44",
+ "195.191.45.45",
+ "195.191.45.47",
+ "195.191.45.61",
+ "195.191.45.75",
+ "195.191.45.88",
+ "195.191.45.130",
+ "195.191.45.149",
+ "195.191.45.151",
+ "195.191.45.155",
+ "195.191.45.179",
+ "195.191.45.189",
+ "195.191.45.241",
+ "195.191.45.250",
+ "195.211.44.20",
+ "195.211.44.25",
+ "195.211.44.164",
+ "195.211.44.165",
+ "195.211.44.166",
+ "195.211.44.175",
+ "195.211.45.150",
+ "195.211.45.222",
+ "195.211.45.228",
+ "195.211.46.63",
+ "195.211.46.208",
+ "195.211.46.243",
+ "195.211.46.244",
+ "195.211.47.66",
+ "195.211.47.135",
+ "195.211.47.195",
+ "195.214.235.6",
+ "195.214.235.27",
+ "195.214.235.115",
+ "195.214.235.120",
+ "195.214.235.140",
+ "195.214.235.173",
+ "195.214.235.174",
+ "195.214.235.208",
+ "195.226.223.12",
+ "195.226.223.27",
+ "195.226.223.28",
+ "195.226.223.29",
+ "195.226.223.30",
+ "195.226.223.214",
+ "195.230.107.93",
+ "195.238.231.97",
+ "195.238.240.83",
+ "195.238.240.84",
+ "195.238.240.89",
+ "195.245.70.1",
+ "195.245.70.65",
+ "212.16.68.41",
+ "212.16.68.124",
+ "212.16.75.253",
+ "212.16.77.19",
+ "212.16.77.20",
+ "212.16.77.21",
+ "212.16.77.22",
+ "212.16.84.128",
+ "212.16.86.17",
+ "212.16.86.86",
+ "212.16.86.112",
+ "212.16.86.137",
+ "212.16.86.139",
+ "212.23.201.166",
+ "212.23.201.238",
+ "212.23.216.12",
+ "212.23.216.99",
+ "212.23.216.116",
+ "212.23.216.123",
+ "212.23.216.149",
+ "212.33.195.77",
+ "212.33.195.84",
+ "212.33.195.201",
+ "212.33.197.9",
+ "212.33.198.66",
+ "212.33.198.98",
+ "212.33.198.245",
+ "212.33.199.2",
+ "212.33.201.73",
+ "212.33.201.227",
+ "212.33.202.146",
+ "212.33.202.180",
+ "212.33.204.94",
+ "212.33.205.10",
+ "212.33.205.59",
+ "212.33.205.72",
+ "212.33.205.148",
+ "212.33.206.9",
+ "212.33.206.21",
+ "212.33.206.22",
+ "212.33.206.23",
+ "212.33.206.24",
+ "212.33.206.25",
+ "212.33.206.27",
+ "212.33.206.181",
+ "212.33.206.185",
+ "212.33.206.186",
+ "212.33.206.188",
+ "212.33.206.189",
+ "212.33.206.190",
+ "212.33.206.191",
+ "212.33.212.180",
+ "212.33.213.154",
+ "212.33.215.66",
+ "212.33.216.151",
+ "212.33.216.213",
+ "212.33.218.29",
+ "212.33.218.62",
+ "212.33.218.134",
+ "212.33.219.209",
+ "212.33.222.251",
+ "212.33.223.56",
+ "212.33.223.66",
+ "212.80.8.8",
+ "212.80.8.58",
+ "212.80.8.152",
+ "212.80.10.78",
+ "212.80.10.91",
+ "212.80.20.98",
+ "212.80.20.103",
+ "212.80.24.14",
+ "212.86.64.2",
+ "212.86.64.68",
+ "212.86.64.79",
+ "212.86.64.83",
+ "212.86.64.101",
+ "212.86.64.102",
+ "212.86.64.103",
+ "212.86.64.105",
+ "212.86.65.25",
+ "212.86.65.40",
+ "212.86.65.60",
+ "212.86.65.126",
+ "212.86.72.0",
+ "212.86.72.11",
+ "212.86.72.46",
+ "212.86.72.56",
+ "212.86.72.72",
+ "212.86.72.91",
+ "212.86.72.123",
+ "212.86.72.217",
+ "212.86.73.4",
+ "212.86.73.41",
+ "212.86.73.56",
+ "212.86.73.97",
+ "212.86.73.173",
+ "212.86.73.175",
+ "212.86.73.200",
+ "212.86.73.217",
+ "212.86.73.220",
+ "212.86.74.0",
+ "212.86.74.6",
+ "212.86.74.10",
+ "212.86.74.49",
+ "212.86.74.60",
+ "212.86.74.67",
+ "212.86.74.76",
+ "212.86.74.79",
+ "212.86.74.158",
+ "212.86.74.160",
+ "212.86.74.188",
+ "212.86.74.194",
+ "212.86.74.216",
+ "212.86.74.218",
+ "212.86.74.225",
+ "212.86.75.0",
+ "212.86.75.36",
+ "212.86.75.42",
+ "212.86.75.52",
+ "212.86.75.71",
+ "212.86.75.94",
+ "212.86.75.96",
+ "212.86.75.160",
+ "212.86.75.205",
+ "212.86.75.240",
+ "212.86.75.243",
+ "212.86.76.41",
+ "212.86.79.177",
+ "212.86.79.179",
+ "212.86.79.183",
+ "212.86.79.186",
+ "212.86.79.187",
+ "212.86.82.225",
+ "212.86.87.251",
+ "212.86.93.93",
+ "212.86.94.20",
+ "212.86.94.74",
+ "212.86.94.113",
+ "212.86.94.144",
+ "212.86.94.207",
+ "212.108.125.92",
+ "212.120.192.236",
+ "212.120.192.254",
+ "212.120.193.20",
+ "212.120.193.241",
+ "212.120.194.72",
+ "212.120.196.90",
+ "212.120.197.31",
+ "212.120.198.232",
+ "212.120.201.203",
+ "212.120.203.88",
+ "212.120.204.95",
+ "212.120.210.84",
+ "212.120.218.141",
+ "212.120.219.9",
+ "212.120.219.153",
+ "212.120.221.10",
+ "212.120.221.141",
+ "212.120.222.106",
+ "212.120.223.163",
+ "212.120.223.165",
+ "213.108.240.139",
+ "213.108.240.153",
+ "213.108.240.206",
+ "213.108.241.134",
+ "213.108.242.161",
+ "213.108.242.193",
+ "213.108.242.225",
+ "213.108.242.227",
+ "213.108.242.245",
+ "213.109.199.3",
+ "213.109.248.105",
+ "213.109.250.84",
+ "213.109.252.154",
+ "213.109.253.62",
+ "213.109.253.187",
+ "213.109.254.199",
+ "213.176.4.6",
+ "213.176.6.230",
+ "213.176.7.117",
+ "213.176.28.53",
+ "213.176.28.147",
+ "213.176.29.10",
+ "213.176.69.211",
+ "213.176.120.16",
+ "213.176.120.74",
+ "213.176.122.5",
+ "213.176.122.28",
+ "213.176.122.56",
+ "213.176.124.10",
+ "213.176.124.55",
+ "213.176.127.130",
+ "213.177.176.3",
+ "213.177.176.103",
+ "213.177.176.107",
+ "213.177.176.112",
+ "213.177.178.212",
+ "213.195.22.51",
+ "213.195.22.67",
+ "213.195.22.109",
+ "213.195.22.122",
+ "213.195.56.45",
+ "213.195.58.44",
+ "213.195.58.177",
+ "213.195.59.0",
+ "213.195.59.10",
+ "213.195.59.11",
+ "213.195.59.179",
+ "213.195.60.19",
+ "213.195.61.119",
+ "213.195.61.124",
+ "213.195.61.254",
+ "213.195.62.126",
+ "213.207.195.118",
+ "213.207.195.194",
+ "213.207.196.30",
+ "213.207.196.114",
+ "213.207.196.138",
+ "213.207.196.214",
+ "213.207.198.22",
+ "213.207.198.91",
+ "213.207.198.180",
+ "213.207.198.226",
+ "213.207.200.114",
+ "213.207.200.115",
+ "213.207.200.162",
+ "213.207.200.186",
+ "213.207.200.226",
+ "213.207.202.44",
+ "213.207.202.94",
+ "213.207.202.235",
+ "213.207.202.242",
+ "213.207.203.2",
+ "213.207.203.30",
+ "213.207.203.106",
+ "213.207.203.122",
+ "213.207.203.123",
+ "213.207.203.124",
+ "213.207.204.70",
+ "213.207.204.104",
+ "213.207.204.107",
+ "213.207.204.154",
+ "213.207.204.186",
+ "213.207.204.226",
+ "213.207.204.242",
+ "213.207.250.159",
+ "213.207.250.218",
+ "213.232.124.210",
+ "213.232.124.250",
+ "213.232.127.18",
+ "213.232.127.28",
+ "213.232.127.30",
+ "213.233.177.103",
+ "213.233.178.35",
+ "213.233.181.18",
+ "213.233.181.26",
+ "213.233.181.27",
+ "213.233.181.106",
+ "213.233.182.146",
+ "213.233.182.229",
+ "213.233.184.40",
+ "217.11.18.50",
+ "217.11.18.51",
+ "217.11.18.52",
+ "217.11.18.53",
+ "217.11.18.54",
+ "217.11.18.58",
+ "217.11.18.59",
+ "217.11.18.61",
+ "217.11.18.62",
+ "217.11.18.114",
+ "217.11.18.178",
+ "217.11.18.179",
+ "217.11.18.180",
+ "217.11.18.183",
+ "217.11.18.189",
+ "217.11.22.34",
+ "217.11.24.162",
+ "217.11.24.249",
+ "217.11.26.6",
+ "217.11.27.138",
+ "217.11.27.139",
+ "217.11.27.140",
+ "217.11.27.211",
+ "217.11.27.213",
+ "217.11.28.74",
+ "217.11.28.138",
+ "217.11.28.237",
+ "217.11.29.185",
+ "217.11.29.189",
+ "217.11.30.34",
+ "217.11.30.182",
+ "217.24.144.122",
+ "217.24.145.5",
+ "217.24.146.16",
+ "217.24.147.76",
+ "217.24.148.1",
+ "217.24.151.89",
+ "217.24.151.109",
+ "217.24.151.141",
+ "217.24.153.18",
+ "217.24.155.149",
+ "217.24.155.244",
+ "217.24.157.131",
+ "217.25.48.63",
+ "217.25.56.90",
+ "217.26.222.235",
+ "217.60.238.99",
+ "217.60.243.183",
+ "217.66.195.26",
+ "217.66.200.206",
+ "217.66.200.219",
+ "217.66.201.115",
+ "217.66.201.116",
+ "217.66.201.118",
+ "217.66.203.166",
+ "217.66.207.1",
+ "217.66.212.246",
+ "217.66.213.5",
+ "217.66.213.105",
+ "217.66.213.133",
+ "217.66.213.134",
+ "217.66.213.145",
+ "217.66.215.86",
+ "217.66.215.138",
+ "217.66.221.21",
+ "217.114.40.23",
+ "217.114.40.244",
+ "217.114.46.130",
+ "217.144.104.1",
+ "217.144.104.45",
+ "217.144.104.104",
+ "217.144.104.115",
+ "217.144.104.124",
+ "217.144.104.252",
+ "217.144.105.1",
+ "217.144.105.92",
+ "217.144.106.1",
+ "217.144.106.42",
+ "217.144.106.65",
+ "217.144.106.97",
+ "217.144.106.98",
+ "217.144.106.161",
+ "217.144.106.213",
+ "217.144.107.1",
+ "217.144.107.122",
+ "217.144.107.165",
+ "217.144.107.206",
+ "217.146.208.2",
+ "217.146.209.178",
+ "217.146.209.179",
+ "217.146.215.100",
+ "217.146.217.247",
+ "217.146.218.141",
+ "217.146.218.142",
+ "217.171.145.233",
+ "217.171.148.147",
+ "217.171.148.190",
+ "217.171.148.236",
+ "217.171.149.81",
+ "217.171.149.188",
+ "217.171.149.201",
+ "217.171.150.82",
+ "217.171.150.242",
+ "217.171.151.3",
+ "217.171.151.16",
+ "217.172.98.11",
+ "217.172.98.73",
+ "217.172.98.107",
+ "217.172.98.130",
+ "217.172.98.134",
+ "217.172.104.161",
+ "217.172.108.198",
+ "217.172.112.36",
+ "217.172.113.123",
+ "217.172.113.235",
+ "217.172.114.74",
+ "217.172.114.92",
+ "217.172.116.133",
+ "217.172.117.38",
+ "217.172.121.49",
+ "217.172.121.115",
+ "217.172.121.116",
+ "217.172.121.210",
+ "217.172.122.154",
+ "217.172.122.155",
+ "217.172.122.156",
+ "217.172.122.157",
+ "217.172.122.158",
+ "217.172.126.1",
+ "217.172.126.20",
+ "217.172.126.209",
+ "217.172.126.215",
+ "217.172.126.234",
+ "217.172.126.237",
+ "217.172.126.253",
+ "217.172.127.43",
+ "217.172.127.77",
+ "217.172.127.78",
+ "217.172.127.81",
+ "217.172.127.93",
+ "217.172.127.101",
+ "217.172.127.118",
+ "217.172.127.136",
+ "217.172.127.186",
+ "217.172.127.189",
+ "217.198.190.41",
+ "217.198.190.96",
+ "217.218.3.51",
+ "217.218.3.163",
+ "217.218.3.233",
+ "217.218.42.1",
+ "217.218.42.21",
+ "217.218.42.22",
+ "217.218.42.246",
+ "217.218.44.189",
+ "217.218.46.34",
+ "217.218.46.35",
+ "217.218.46.36",
+ "217.218.51.78",
+ "217.218.54.250",
+ "217.218.56.227",
+ "217.218.56.228",
+ "217.218.56.235",
+ "217.218.62.62",
+ "217.218.74.14",
+ "217.218.77.131",
+ "217.218.81.137",
+ "217.218.82.32",
+ "217.218.82.33",
+ "217.218.82.34",
+ "217.218.82.102",
+ "217.218.83.138",
+ "217.218.85.245",
+ "217.218.87.29",
+ "217.218.87.51",
+ "217.218.91.8",
+ "217.218.100.216",
+ "217.218.100.239",
+ "217.218.103.120",
+ "217.218.108.177",
+ "217.218.113.130",
+ "217.218.114.240",
+ "217.218.114.241",
+ "217.218.114.242",
+ "217.218.114.244",
+ "217.218.114.245",
+ "217.218.114.247",
+ "217.218.114.250",
+ "217.218.114.253",
+ "217.218.115.42",
+ "217.218.115.43",
+ "217.218.115.44",
+ "217.218.115.46",
+ "217.218.115.178",
+ "217.218.115.179",
+ "217.218.120.2",
+ "217.218.120.216",
+ "217.218.121.54",
+ "217.218.125.21",
+ "217.218.126.164",
+ "217.218.134.57",
+ "217.218.134.58",
+ "217.218.134.59",
+ "217.218.134.60",
+ "217.218.134.61",
+ "217.218.134.62",
+ "217.218.135.87",
+ "217.218.136.230",
+ "217.218.139.255",
+ "217.218.159.68",
+ "217.218.162.62",
+ "217.218.164.77",
+ "217.218.180.42",
+ "217.218.180.225",
+ "217.218.192.210",
+ "217.218.192.211",
+ "217.218.195.26",
+ "217.218.196.183",
+ "217.218.201.16",
+ "217.218.201.24",
+ "217.218.201.49",
+ "217.218.201.101",
+ "217.218.201.113",
+ "217.218.201.140",
+ "217.218.201.175",
+ "217.218.201.184",
+ "217.218.201.198",
+ "217.218.201.213",
+ "217.218.204.114",
+ "217.218.204.115",
+ "217.218.204.117",
+ "217.218.204.130",
+ "217.218.204.138",
+ "217.218.204.170",
+ "217.218.206.34",
+ "217.218.206.189",
+ "217.218.212.136",
+ "217.218.212.137",
+ "217.218.213.13",
+ "217.218.219.105",
+ "217.218.219.201",
+ "217.218.222.187",
+ "217.218.223.154",
+ "217.218.224.2",
+ "217.218.224.156",
+ "217.218.224.157",
+ "217.218.224.158",
+ "217.218.224.210",
+ "217.218.224.211",
+ "217.218.224.213",
+ "217.218.224.230",
+ "217.218.225.190",
+ "217.218.226.98",
+ "217.218.226.131",
+ "217.218.227.2",
+ "217.218.227.3",
+ "217.218.227.4",
+ "217.218.227.5",
+ "217.218.227.6",
+ "217.218.227.10",
+ "217.218.227.50",
+ "217.218.227.245",
+ "217.218.227.246",
+ "217.218.235.138",
+ "217.218.236.2",
+ "217.218.236.68",
+ "217.218.236.70",
+ "217.218.236.76",
+ "217.218.236.85",
+ "217.218.236.86",
+ "217.218.236.88",
+ "217.218.236.89",
+ "217.218.236.162",
+ "217.218.236.171",
+ "217.218.237.26",
+ "217.218.237.27",
+ "217.218.237.28",
+ "217.218.238.76",
+ "217.218.242.24",
+ "217.218.242.75",
+ "217.218.243.191",
+ "217.218.243.204",
+ "217.218.243.207",
+ "217.218.243.249",
+ "217.218.245.13",
+ "217.218.248.170",
+ "217.218.249.17",
+ "217.218.249.63",
+ "217.218.249.240",
+ "217.218.250.16",
+ "217.218.250.145",
+ "217.218.250.172",
+ "217.218.252.33",
+ "217.218.252.64",
+ "217.218.252.66",
+ "217.218.253.93",
+ "217.218.253.110",
+ "217.219.1.1",
+ "217.219.14.162",
+ "217.219.14.164",
+ "217.219.16.1",
+ "217.219.21.26",
+ "217.219.26.145",
+ "217.219.27.58",
+ "217.219.27.65",
+ "217.219.29.186",
+ "217.219.29.202",
+ "217.219.29.203",
+ "217.219.29.250",
+ "217.219.30.153",
+ "217.219.30.156",
+ "217.219.31.90",
+ "217.219.33.127",
+ "217.219.34.6",
+ "217.219.34.15",
+ "217.219.34.57",
+ "217.219.34.66",
+ "217.219.34.95",
+ "217.219.35.3",
+ "217.219.35.7",
+ "217.219.35.10",
+ "217.219.35.14",
+ "217.219.35.32",
+ "217.219.35.49",
+ "217.219.35.55",
+ "217.219.35.63",
+ "217.219.35.69",
+ "217.219.35.73",
+ "217.219.35.90",
+ "217.219.35.129",
+ "217.219.35.134",
+ "217.219.35.171",
+ "217.219.35.183",
+ "217.219.35.196",
+ "217.219.35.201",
+ "217.219.35.254",
+ "217.219.37.3",
+ "217.219.39.74",
+ "217.219.39.75",
+ "217.219.39.76",
+ "217.219.39.77",
+ "217.219.39.122",
+ "217.219.39.234",
+ "217.219.42.135",
+ "217.219.45.2",
+ "217.219.45.3",
+ "217.219.45.5",
+ "217.219.45.138",
+ "217.219.45.178",
+ "217.219.45.210",
+ "217.219.45.222",
+ "217.219.47.66",
+ "217.219.47.122",
+ "217.219.47.138",
+ "217.219.47.139",
+ "217.219.47.146",
+ "217.219.47.170",
+ "217.219.47.186",
+ "217.219.47.194",
+ "217.219.47.195",
+ "217.219.64.66",
+ "217.219.64.117",
+ "217.219.64.196",
+ "217.219.67.166",
+ "217.219.67.179",
+ "217.219.67.221",
+ "217.219.68.169",
+ "217.219.68.190",
+ "217.219.68.250",
+ "217.219.70.61",
+ "217.219.70.122",
+ "217.219.71.242",
+ "217.219.72.10",
+ "217.219.72.18",
+ "217.219.72.19",
+ "217.219.72.98",
+ "217.219.72.102",
+ "217.219.72.111",
+ "217.219.72.115",
+ "217.219.72.116",
+ "217.219.72.119",
+ "217.219.72.121",
+ "217.219.72.123",
+ "217.219.72.194",
+ "217.219.72.199",
+ "217.219.72.200",
+ "217.219.72.203",
+ "217.219.72.206",
+ "217.219.73.193",
+ "217.219.77.69",
+ "217.219.77.114",
+ "217.219.77.194",
+ "217.219.77.250",
+ "217.219.78.151",
+ "217.219.80.154",
+ "217.219.80.241",
+ "217.219.81.2",
+ "217.219.81.3",
+ "217.219.81.18",
+ "217.219.81.74",
+ "217.219.81.249",
+ "217.219.82.110",
+ "217.219.82.218",
+ "217.219.82.226",
+ "217.219.83.146",
+ "217.219.84.83",
+ "217.219.85.6",
+ "217.219.86.98",
+ "217.219.86.99",
+ "217.219.86.100",
+ "217.219.87.2",
+ "217.219.87.26",
+ "217.219.87.42",
+ "217.219.87.122",
+ "217.219.87.154",
+ "217.219.87.170",
+ "217.219.90.87",
+ "217.219.106.144",
+ "217.219.106.146",
+ "217.219.113.164",
+ "217.219.113.180",
+ "217.219.121.156",
+ "217.219.124.78",
+ "217.219.124.96",
+ "217.219.124.97",
+ "217.219.124.98",
+ "217.219.124.99",
+ "217.219.124.100",
+ "217.219.124.101",
+ "217.219.124.102",
+ "217.219.124.103",
+ "217.219.124.104",
+ "217.219.124.105",
+ "217.219.124.106",
+ "217.219.124.107",
+ "217.219.124.108",
+ "217.219.124.109",
+ "217.219.124.110",
+ "217.219.124.111",
+ "217.219.129.19",
+ "217.219.129.213",
+ "217.219.129.215",
+ "217.219.129.247",
+ "217.219.131.14",
+ "217.219.131.116",
+ "217.219.131.130",
+ "217.219.132.14",
+ "217.219.132.22",
+ "217.219.132.65",
+ "217.219.132.75",
+ "217.219.132.88",
+ "217.219.132.104",
+ "217.219.133.86",
+ "217.219.135.137",
+ "217.219.136.77",
+ "217.219.136.156",
+ "217.219.138.206",
+ "217.219.141.170",
+ "217.219.143.83",
+ "217.219.143.87",
+ "217.219.146.81",
+ "217.219.146.201",
+ "217.219.147.89",
+ "217.219.147.90",
+ "217.219.148.34",
+ "217.219.148.209",
+ "217.219.148.217",
+ "217.219.149.137",
+ "217.219.149.201",
+ "217.219.150.49",
+ "217.219.155.36",
+ "217.219.157.65",
+ "217.219.157.88",
+ "217.219.157.121",
+ "217.219.158.50",
+ "217.219.158.113",
+ "217.219.161.172",
+ "217.219.161.190",
+ "217.219.162.178",
+ "217.219.163.1",
+ "217.219.163.3",
+ "217.219.163.10",
+ "217.219.163.11",
+ "217.219.163.13",
+ "217.219.163.14",
+ "217.219.163.15",
+ "217.219.163.16",
+ "217.219.163.17",
+ "217.219.163.18",
+ "217.219.163.19",
+ "217.219.163.21",
+ "217.219.163.23",
+ "217.219.163.24",
+ "217.219.163.25",
+ "217.219.163.26",
+ "217.219.163.28",
+ "217.219.163.30",
+ "217.219.163.31",
+ "217.219.163.32",
+ "217.219.163.33",
+ "217.219.163.34",
+ "217.219.163.35",
+ "217.219.163.36",
+ "217.219.163.37",
+ "217.219.163.38",
+ "217.219.163.39",
+ "217.219.163.40",
+ "217.219.163.41",
+ "217.219.163.42",
+ "217.219.163.43",
+ "217.219.163.44",
+ "217.219.163.47",
+ "217.219.163.48",
+ "217.219.163.49",
+ "217.219.163.50",
+ "217.219.163.51",
+ "217.219.163.52",
+ "217.219.163.54",
+ "217.219.163.55",
+ "217.219.163.56",
+ "217.219.163.57",
+ "217.219.163.59",
+ "217.219.163.60",
+ "217.219.163.62",
+ "217.219.163.63",
+ "217.219.163.64",
+ "217.219.163.65",
+ "217.219.163.66",
+ "217.219.163.67",
+ "217.219.163.68",
+ "217.219.163.69",
+ "217.219.163.71",
+ "217.219.163.73",
+ "217.219.163.74",
+ "217.219.163.75",
+ "217.219.163.76",
+ "217.219.163.77",
+ "217.219.163.80",
+ "217.219.163.81",
+ "217.219.163.82",
+ "217.219.163.85",
+ "217.219.163.88",
+ "217.219.163.90",
+ "217.219.163.95",
+ "217.219.163.96",
+ "217.219.163.99",
+ "217.219.163.100",
+ "217.219.163.101",
+ "217.219.163.102",
+ "217.219.163.103",
+ "217.219.163.104",
+ "217.219.163.105",
+ "217.219.163.110",
+ "217.219.163.111",
+ "217.219.163.121",
+ "217.219.163.122",
+ "217.219.163.123",
+ "217.219.163.125",
+ "217.219.163.126",
+ "217.219.163.133",
+ "217.219.163.134",
+ "217.219.163.143",
+ "217.219.163.150",
+ "217.219.163.152",
+ "217.219.163.153",
+ "217.219.163.154",
+ "217.219.163.155",
+ "217.219.163.156",
+ "217.219.163.157",
+ "217.219.163.159",
+ "217.219.163.160",
+ "217.219.163.161",
+ "217.219.163.164",
+ "217.219.163.165",
+ "217.219.163.166",
+ "217.219.163.170",
+ "217.219.163.171",
+ "217.219.163.174",
+ "217.219.163.180",
+ "217.219.163.190",
+ "217.219.163.200",
+ "217.219.163.201",
+ "217.219.163.210",
+ "217.219.163.211",
+ "217.219.163.222",
+ "217.219.163.223",
+ "217.219.163.252",
+ "217.219.164.105",
+ "217.219.164.106",
+ "217.219.164.129",
+ "217.219.164.194",
+ "217.219.165.201",
+ "217.219.166.3",
+ "217.219.166.228",
+ "217.219.166.229",
+ "217.219.166.231",
+ "217.219.166.235",
+ "217.219.168.23",
+ "217.219.169.161",
+ "217.219.169.180",
+ "217.219.172.106",
+ "217.219.172.185",
+ "217.219.172.238",
+ "217.219.175.61",
+ "217.219.175.66",
+ "217.219.178.154",
+ "217.219.179.5",
+ "217.219.179.6",
+ "217.219.179.18",
+ "217.219.179.33",
+ "217.219.179.61",
+ "217.219.179.62",
+ "217.219.181.228",
+ "217.219.191.169",
+ "217.219.192.117",
+ "217.219.196.67",
+ "217.219.196.114",
+ "217.219.196.115",
+ "217.219.196.116",
+ "217.219.196.117",
+ "217.219.196.170",
+ "217.219.196.218",
+ "217.219.196.226",
+ "217.219.199.50",
+ "217.219.202.234",
+ "217.219.203.210",
+ "217.219.206.144",
+ "217.219.207.226",
+ "217.219.209.125",
+ "217.219.209.130",
+ "217.219.216.123",
+ "217.219.217.128",
+ "217.219.217.141",
+ "217.219.217.217",
+ "217.219.217.249",
+ "217.219.219.10",
+ "217.219.219.137",
+ "217.219.219.138",
+ "217.219.219.145",
+ "217.219.219.150",
+ "217.219.222.76",
+ "217.219.223.1",
+ "217.219.223.2",
+ "217.219.223.14",
+ "217.219.223.106",
+ "217.219.224.2",
+ "217.219.224.162",
+ "217.219.224.194",
+ "217.219.225.2",
+ "217.219.226.70",
+ "217.219.227.34",
+ "217.219.227.40",
+ "217.219.228.36",
+ "217.219.228.88",
+ "217.219.228.130",
+ "217.219.229.154",
+ "217.219.229.155",
+ "217.219.229.156",
+ "217.219.229.157",
+ "217.219.230.22",
+ "217.219.230.221",
+ "217.219.243.10",
+ "217.219.244.6",
+ "217.219.245.3",
+ "217.219.245.14",
+ "217.219.245.70",
+ "217.219.245.95",
+ "217.219.245.106",
+ "217.219.245.136",
+ "217.219.245.175",
+ "217.219.245.191",
+ "217.219.246.98",
+ "217.219.247.99",
+ "217.219.247.122",
+ "2.144.2.111",
+ "2.144.4.21",
+ "2.144.5.134",
+ "2.144.5.203",
+ "2.144.6.52",
+ "2.144.6.158",
+ "2.144.20.43",
+ "2.144.21.174",
+ "2.144.22.179",
+ "2.144.23.66",
+ "2.144.247.175",
+ "2.176.61.28",
+ "2.176.193.50",
+ "2.176.197.47",
+ "2.176.199.118",
+ "2.176.202.164",
+ "2.176.205.179",
+ "2.176.231.4",
+ "2.176.232.223",
+ "2.176.237.47",
+ "2.176.239.230",
+ "2.176.240.92",
+ "2.176.243.141",
+ "2.176.244.41",
+ "2.176.245.72",
+ "2.176.245.231",
+ "2.176.246.166",
+ "2.176.250.217",
+ "2.176.255.77",
+ "2.177.13.185",
+ "2.177.14.0",
+ "2.177.14.32",
+ "2.177.14.43",
+ "2.177.31.166",
+ "2.177.36.242",
+ "2.177.37.184",
+ "2.177.41.202",
+ "2.177.48.152",
+ "2.177.51.194",
+ "2.177.64.43",
+ "2.177.68.25",
+ "2.177.73.48",
+ "2.177.73.79",
+ "2.177.79.37",
+ "2.177.83.219",
+ "2.177.99.220",
+ "2.177.100.226",
+ "2.177.107.104",
+ "2.177.113.124",
+ "2.177.117.169",
+ "2.177.118.6",
+ "2.177.129.148",
+ "2.177.130.105",
+ "2.177.137.86",
+ "2.177.142.148",
+ "2.177.151.132",
+ "2.177.151.156",
+ "2.177.165.9",
+ "2.177.166.150",
+ "2.177.168.234",
+ "2.177.171.89",
+ "2.177.182.115",
+ "2.177.185.122",
+ "2.177.187.200",
+ "2.177.197.115",
+ "2.177.198.53",
+ "2.177.199.51",
+ "2.177.199.107",
+ "2.177.199.245",
+ "2.177.204.214",
+ "2.177.211.79",
+ "2.177.216.209",
+ "2.177.223.128",
+ "2.177.225.220",
+ "2.177.226.55",
+ "2.177.227.249",
+ "2.177.228.177",
+ "2.177.230.204",
+ "2.177.231.85",
+ "2.177.233.155",
+ "2.177.240.13",
+ "2.177.241.251",
+ "2.177.242.157",
+ "2.177.248.198",
+ "2.177.249.33",
+ "2.178.10.49",
+ "2.178.26.120",
+ "2.178.29.129",
+ "2.178.33.172",
+ "2.178.39.222",
+ "2.178.47.252",
+ "2.178.50.226",
+ "2.178.68.197",
+ "2.178.75.96",
+ "2.178.82.205",
+ "2.178.96.216",
+ "2.178.97.192",
+ "2.178.106.14",
+ "2.178.165.235",
+ "2.178.166.233",
+ "2.178.178.132",
+ "2.178.190.214",
+ "2.178.196.1",
+ "2.178.212.26",
+ "2.178.213.139",
+ "2.178.222.197",
+ "2.178.224.182",
+ "2.178.248.58",
+ "2.178.248.241",
+ "2.179.110.69",
+ "2.179.111.38",
+ "2.179.127.252",
+ "2.179.165.153",
+ "2.179.175.184",
+ "2.179.232.32",
+ "2.180.40.2",
+ "2.180.160.254",
+ "2.180.198.17",
+ "2.180.203.21",
+ "2.180.228.113",
+ "2.181.165.5",
+ "2.181.167.6",
+ "2.181.194.140",
+ "2.181.198.224",
+ "2.181.241.244",
+ "2.182.46.37",
+ "2.182.56.10",
+ "2.182.184.108",
+ "2.182.185.9",
+ "2.182.188.221",
+ "2.182.197.16",
+ "2.182.215.254",
+ "2.182.245.1",
+ "2.183.173.236",
+ "2.183.203.2",
+ "2.185.17.37",
+ "2.185.18.125",
+ "2.185.108.67",
+ "2.185.109.142",
+ "2.185.122.248",
+ "2.185.126.202",
+ "2.185.142.5",
+ "2.185.228.204",
+ "2.185.230.220",
+ "2.185.247.106",
+ "2.185.248.133",
+ "2.185.249.127",
+ "2.185.249.210",
+ "2.185.251.86",
+ "2.187.18.3",
+ "2.187.140.164",
+ "2.188.3.60",
+ "2.188.168.129",
+ "2.188.175.242",
+ "2.189.1.0",
+ "2.189.9.97",
+ "2.189.11.159",
+ "2.189.86.97",
+ "2.189.145.17",
+ "2.189.145.173",
+ "2.189.157.249",
+ "2.189.217.144",
+ "2.189.219.152",
+ "2.189.242.12",
+ "2.190.3.235",
+ "2.190.26.244",
+ "2.190.28.221",
+ "2.190.28.244",
+ "2.190.29.197",
+ "2.190.40.249",
+ "2.190.49.235",
+ "2.190.59.172",
+ "2.190.60.13",
+ "2.190.60.27",
+ "2.190.61.4",
+ "2.190.61.175",
+ "2.190.62.132",
+ "2.190.71.116",
+ "2.190.72.84",
+ "2.190.87.152",
+ "2.190.95.36",
+ "2.190.97.50",
+ "2.190.103.243",
+ "2.190.110.83",
+ "2.190.117.30",
+ "2.190.131.33",
+ "2.190.140.44",
+ "2.190.142.104",
+ "2.190.157.58",
+ "2.190.159.232",
+ "2.190.168.235",
+ "2.190.173.111",
+ "2.190.174.81",
+ "2.190.180.13",
+ "2.190.180.245",
+ "2.190.182.58",
+ "2.190.189.139",
+ "2.190.193.93",
+ "2.190.205.31",
+ "2.190.210.124",
+ "2.190.212.127",
+ "2.190.216.0",
+ "2.190.222.0",
+ "2.190.226.150",
+ "2.190.234.39",
+ "2.190.240.24",
+ "2.191.5.220",
+ "2.191.6.55",
+ "2.191.11.21",
+ "2.191.19.182",
+ "2.191.21.202",
+ "2.191.26.194",
+ "2.191.34.72",
+ "2.191.40.236",
+ "2.191.42.139",
+ "2.191.46.127",
+ "2.191.49.238",
+ "2.191.52.197",
+ "2.191.54.134",
+ "2.191.57.99",
+ "2.191.59.64",
+ "2.191.61.46",
+ "2.191.69.203",
+ "2.191.73.215",
+ "2.191.79.184",
+ "2.191.88.247",
+ "2.191.99.161",
+ "2.191.100.238",
+ "2.191.103.229",
+ "2.191.111.210",
+ "2.191.115.176",
+ "2.191.116.220",
+ "5.10.248.174",
+ "5.10.249.91",
+ "5.42.223.178",
+ "5.57.32.117",
+ "5.57.32.181",
+ "5.57.32.184",
+ "5.57.39.168",
+ "5.63.8.22",
+ "5.74.7.121",
+ "5.74.21.26",
+ "5.74.26.180",
+ "5.74.26.234",
+ "5.74.38.29",
+ "5.74.47.64",
+ "5.74.52.237",
+ "5.74.53.212",
+ "5.74.56.152",
+ "5.74.68.57",
+ "5.74.69.171",
+ "5.74.72.160",
+ "5.74.76.182",
+ "5.74.86.57",
+ "5.74.90.172",
+ "5.74.99.0",
+ "5.74.101.93",
+ "5.74.105.40",
+ "5.74.109.253",
+ "5.74.111.45",
+ "5.74.113.74",
+ "5.74.115.250",
+ "5.74.133.146",
+ "5.74.137.184",
+ "5.74.139.166",
+ "5.74.142.206",
+ "5.74.160.227",
+ "5.74.173.21",
+ "5.74.175.47",
+ "5.74.184.125",
+ "5.74.188.152",
+ "5.74.201.91",
+ "5.74.219.145",
+ "5.74.239.134",
+ "5.74.239.234",
+ "5.74.246.169",
+ "5.144.129.5",
+ "5.144.129.11",
+ "5.144.129.32",
+ "5.144.129.40",
+ "5.144.129.63",
+ "5.144.129.64",
+ "5.144.129.66",
+ "5.144.129.69",
+ "5.144.129.110",
+ "5.144.129.148",
+ "5.144.129.151",
+ "5.144.129.166",
+ "5.144.129.216",
+ "5.144.130.19",
+ "5.144.130.26",
+ "5.144.130.82",
+ "5.144.130.96",
+ "5.144.130.117",
+ "5.144.130.159",
+ "5.144.130.196",
+ "5.144.130.214",
+ "5.144.130.219",
+ "5.144.130.245",
+ "5.144.130.249",
+ "5.144.131.245",
+ "5.159.48.21",
+ "5.159.48.40",
+ "5.159.51.194",
+ "5.159.51.207",
+ "5.159.53.8",
+ "5.160.40.6",
+ "5.160.46.203",
+ "5.160.55.3",
+ "5.160.55.13",
+ "5.160.79.248",
+ "5.160.95.165",
+ "5.160.96.210",
+ "5.160.118.66",
+ "5.160.186.19",
+ "5.160.225.168",
+ "5.160.242.53",
+ "5.182.44.177",
+ "5.190.86.86",
+ "5.190.87.87",
+ "5.198.161.51",
+ "5.198.161.55",
+ "5.200.134.206",
+ "5.200.144.52",
+ "5.200.150.169",
+ "5.200.183.90",
+ "5.200.186.226",
+ "5.200.238.224",
+ "5.201.165.192",
+ "5.202.5.131",
+ "5.202.50.82",
+ "5.202.52.36",
+ "5.202.67.5",
+ "5.202.97.22",
+ "5.232.125.241",
+ "5.232.135.255",
+ "5.233.57.47",
+ "5.233.68.161",
+ "5.233.183.139",
+ "5.233.193.222",
+ "5.234.3.0",
+ "5.234.8.25",
+ "5.234.9.41",
+ "5.234.15.25",
+ "5.234.17.120",
+ "5.234.18.35",
+ "5.234.18.94",
+ "5.234.22.170",
+ "5.234.28.171",
+ "5.234.160.153",
+ "5.234.198.228",
+ "5.234.207.158",
+ "5.234.208.42",
+ "5.234.211.176",
+ "5.235.163.209",
+ "5.235.164.4",
+ "5.235.166.97",
+ "5.235.166.254",
+ "5.235.168.38",
+ "5.235.174.230",
+ "5.235.176.185",
+ "5.235.183.53",
+ "5.235.198.109",
+ "5.236.64.61",
+ "5.236.75.164",
+ "5.236.80.59",
+ "5.236.117.196",
+ "5.236.125.34",
+ "5.236.193.186",
+ "5.236.218.37",
+ "5.236.224.25",
+ "5.236.231.47",
+ "5.236.248.172",
+ "5.236.251.85",
+ "5.237.171.184",
+ "5.237.182.67",
+ "5.237.184.184",
+ "5.237.190.101",
+ "5.237.200.102",
+ "5.237.249.162",
+ "5.238.77.204",
+ "5.238.84.14",
+ "5.238.128.102",
+ "5.238.145.107",
+ "5.238.162.247",
+ "5.238.169.180",
+ "5.238.171.106",
+ "5.238.179.1",
+ "5.238.187.194",
+ "5.238.189.61",
+ "5.238.192.15",
+ "5.238.205.201",
+ "5.238.213.205",
+ "5.238.219.22",
+ "5.238.225.98",
+ "5.238.225.134",
+ "5.238.226.108",
+ "5.238.226.157",
+ "5.238.229.48",
+ "5.238.229.227",
+ "5.238.236.60",
+ "5.238.243.239",
+ "5.239.10.166",
+ "5.239.18.23",
+ "5.239.32.209",
+ "5.239.34.3",
+ "5.239.43.82",
+ "5.239.46.65",
+ "5.239.53.249",
+ "5.239.62.129",
+ "5.239.77.105",
+ "5.239.79.88",
+ "5.239.81.68",
+ "5.239.82.223",
+ "5.239.84.107",
+ "5.239.89.157",
+ "5.239.92.43",
+ "5.239.105.226",
+ "5.239.106.140",
+ "5.239.120.67",
+ "31.7.72.178",
+ "31.7.111.214",
+ "31.47.40.31",
+ "31.170.50.93",
+ "31.171.222.195",
+ "31.171.222.199",
+ "31.184.140.207",
+ "31.216.62.142",
+ "37.32.10.23",
+ "37.148.24.109",
+ "37.148.46.201",
+ "37.148.50.109",
+ "37.148.51.63",
+ "37.148.82.202",
+ "37.148.82.225",
+ "37.152.176.135",
+ "37.152.191.247",
+ "37.156.31.22",
+ "37.202.155.93",
+ "37.202.225.135",
+ "37.202.225.137",
+ "37.202.225.156",
+ "37.202.225.160",
+ "37.228.137.89",
+ "37.255.173.82",
+ "37.255.243.165",
+ "45.82.138.154",
+ "45.89.236.235",
+ "45.92.92.10",
+ "45.92.92.18",
+ "45.92.92.25",
+ "45.92.92.41",
+ "45.92.92.53",
+ "45.92.92.69",
+ "45.92.92.73",
+ "45.92.92.76",
+ "45.92.92.151",
+ "45.92.92.175",
+ "45.92.92.196",
+ "45.92.94.92",
+ "45.92.94.96",
+ "45.135.243.138",
+ "45.138.132.238",
+ "45.138.133.43",
+ "45.138.133.55",
+ "45.138.133.59",
+ "45.138.133.63",
+ "45.138.133.146",
+ "45.138.133.161",
+ "45.138.134.19",
+ "45.138.134.44",
+ "45.138.134.81",
+ "45.138.134.134",
+ "45.138.134.142",
+ "45.138.134.169",
+ "45.138.134.176",
+ "45.138.134.251",
+ "45.138.135.179",
+ "45.147.77.157",
+ "45.149.79.40",
+ "45.156.185.85",
+ "45.159.113.35",
+ "45.159.149.196",
+ "45.159.151.14",
+ "45.159.151.83",
+ "45.159.151.137",
+ "46.18.248.134",
+ "46.100.5.51",
+ "46.100.47.7",
+ "46.100.59.39",
+ "46.100.145.243",
+ "46.100.177.40",
+ "46.167.141.24",
+ "46.209.67.146",
+ "46.209.212.75",
+ "46.245.1.100",
+ "46.245.8.151",
+ "46.245.10.1",
+ "46.245.16.4",
+ "46.245.19.220",
+ "46.245.27.65",
+ "46.245.34.19",
+ "46.245.39.187",
+ "46.245.40.151",
+ "46.245.43.89",
+ "46.245.45.43",
+ "46.245.77.2",
+ "46.245.86.27",
+ "46.245.91.230",
+ "46.245.115.37",
+ "62.3.41.64",
+ "62.3.41.95",
+ "62.3.42.23",
+ "62.60.133.3",
+ "62.60.133.8",
+ "62.60.133.28",
+ "62.60.133.35",
+ "62.60.133.46",
+ "62.60.133.57",
+ "62.60.133.60",
+ "62.60.133.81",
+ "62.60.133.82",
+ "62.60.133.101",
+ "62.60.133.129",
+ "62.60.133.193",
+ "62.60.133.199",
+ "62.60.133.204",
+ "62.60.163.226",
+ "62.60.195.95",
+ "62.60.201.19",
+ "62.60.201.23",
+ "62.60.201.91",
+ "62.60.201.114",
+ "62.60.201.129",
+ "62.60.201.150",
+ "62.60.201.181",
+ "62.60.201.188",
+ "62.60.201.237",
+ "62.60.204.166",
+ "62.60.205.96",
+ "62.60.205.165",
+ "62.60.205.190",
+ "62.60.205.205",
+ "62.60.205.206",
+ "62.60.205.252",
+ "62.60.206.155",
+ "62.60.207.78",
+ "62.60.211.198",
+ "62.60.211.201",
+ "62.60.214.83",
+ "62.204.61.159",
+ "62.220.117.130",
+ "66.79.110.174",
+ "77.81.144.148",
+ "77.81.146.166",
+ "77.81.152.206",
+ "77.104.118.2",
+ "77.237.67.13",
+ "77.237.75.148",
+ "77.237.83.30",
+ "78.38.29.129",
+ "78.38.182.201",
+ "78.38.189.230",
+ "78.39.62.36",
+ "78.39.81.46",
+ "78.39.122.99",
+ "78.39.146.149",
+ "78.39.147.33",
+ "78.39.194.10",
+ "78.39.224.155",
+ "78.39.245.8",
+ "78.39.248.252",
+ "78.39.255.27",
+ "78.109.202.101",
+ "78.157.33.201",
+ "78.157.35.39",
+ "78.157.35.47",
+ "78.157.35.96",
+ "78.157.38.200",
+ "78.157.40.143",
+ "78.157.40.184",
+ "78.157.40.224",
+ "78.157.41.79",
+ "78.157.43.64",
+ "78.157.43.127",
+ "78.157.45.32",
+ "78.157.45.63",
+ "78.157.45.143",
+ "78.157.46.111",
+ "78.157.50.16",
+ "78.157.50.248",
+ "78.157.52.8",
+ "78.157.52.10",
+ "78.157.57.159",
+ "78.157.57.233",
+ "78.157.58.47",
+ "78.158.179.134",
+ "79.127.125.126",
+ "79.127.126.68",
+ "79.127.127.55",
+ "79.175.134.65",
+ "79.175.167.4",
+ "79.175.171.67",
+ "79.175.187.131",
+ "80.191.62.6",
+ "80.191.65.174",
+ "80.191.103.98",
+ "80.191.110.242",
+ "80.191.170.173",
+ "80.210.27.243",
+ "80.210.34.217",
+ "80.210.136.8",
+ "80.210.140.143",
+ "80.210.142.120",
+ "80.210.160.220",
+ "80.210.168.80",
+ "80.210.170.69",
+ "80.210.171.8",
+ "80.210.171.49",
+ "80.210.177.84",
+ "81.12.20.85",
+ "81.12.54.213",
+ "81.12.54.248",
+ "81.12.104.84",
+ "81.12.106.190",
+ "81.12.108.142",
+ "81.16.121.120",
+ "81.16.124.109",
+ "81.91.156.130",
+ "82.99.206.97",
+ "84.47.239.13",
+ "84.241.0.112",
+ "84.241.2.163",
+ "84.241.7.245",
+ "84.241.19.157",
+ "84.241.28.59",
+ "84.241.34.116",
+ "84.241.36.70",
+ "85.9.98.70",
+ "85.9.122.167",
+ "85.9.125.118",
+ "85.133.182.163",
+ "85.133.184.122",
+ "85.133.187.22",
+ "85.185.17.75",
+ "85.185.17.115",
+ "85.185.52.32",
+ "85.185.54.129",
+ "85.185.55.190",
+ "85.185.75.108",
+ "85.185.86.212",
+ "85.185.205.28",
+ "85.185.216.27",
+ "85.208.253.58",
+ "85.208.254.65",
+ "86.104.32.35",
+ "86.104.104.68",
+ "86.105.41.35",
+ "86.105.42.20",
+ "86.105.47.95",
+ "86.106.142.123",
+ "86.107.148.140",
+ "86.107.158.131",
+ "87.107.102.4",
+ "87.107.104.60",
+ "87.236.211.12",
+ "87.236.211.83",
+ "87.248.130.22",
+ "88.135.75.144",
+ "89.32.196.33",
+ "89.32.248.22",
+ "89.32.251.75",
+ "89.37.103.20",
+ "89.38.24.35",
+ "89.42.199.197",
+ "89.42.209.50",
+ "89.42.210.237",
+ "89.42.211.230",
+ "89.43.216.130",
+ "89.43.219.10",
+ "89.43.227.128",
+ "89.46.94.42",
+ "89.46.94.164",
+ "89.46.218.69",
+ "89.46.218.109",
+ "89.46.218.127",
+ "89.46.219.82",
+ "89.46.219.199",
+ "89.144.131.138",
+ "89.144.137.223",
+ "89.144.137.233",
+ "89.144.137.244",
+ "89.144.137.247",
+ "89.144.137.255",
+ "89.144.138.156",
+ "89.144.139.1",
+ "89.144.139.7",
+ "89.144.139.11",
+ "89.144.139.25",
+ "89.144.139.36",
+ "89.144.139.60",
+ "89.144.139.61",
+ "89.144.139.69",
+ "89.144.139.80",
+ "89.144.139.81",
+ "89.144.139.83",
+ "89.144.139.99",
+ "89.144.139.100",
+ "89.144.139.107",
+ "89.144.139.109",
+ "89.144.139.111",
+ "89.144.139.113",
+ "89.144.139.120",
+ "89.144.149.191",
+ "89.144.154.235",
+ "89.144.166.172",
+ "89.144.166.191",
+ "89.144.166.193",
+ "89.144.166.217",
+ "89.144.166.242",
+ "89.144.175.238",
+ "89.144.189.137",
+ "89.144.189.177",
+ "89.144.189.191",
+ "89.144.189.232",
+ "89.144.189.234",
+ "89.219.64.174",
+ "89.219.66.175",
+ "89.219.73.15",
+ "89.219.74.106",
+ "89.219.77.0",
+ "89.219.78.56",
+ "89.219.93.252",
+ "89.219.97.108",
+ "89.219.99.81",
+ "89.219.107.135",
+ "89.219.107.220",
+ "89.219.110.207",
+ "89.219.115.60",
+ "89.219.116.22",
+ "89.219.118.105",
+ "89.219.120.2",
+ "89.219.123.224",
+ "89.219.197.210",
+ "89.219.202.225",
+ "89.219.233.5",
+ "89.219.252.178",
+ "89.219.255.108",
+ "89.235.103.95",
+ "91.92.126.7",
+ "91.92.150.122",
+ "91.92.164.144",
+ "91.92.205.110",
+ "91.92.208.114",
+ "91.92.231.138",
+ "91.199.27.108",
+ "91.220.113.242",
+ "91.223.116.140",
+ "91.228.132.22",
+ "91.247.171.251",
+ "92.42.53.30",
+ "92.114.48.234",
+ "93.114.105.206",
+ "93.115.149.15",
+ "93.115.149.237",
+ "93.117.33.12",
+ "93.117.34.217",
+ "93.117.35.8",
+ "93.117.38.185",
+ "93.117.43.30",
+ "93.118.114.23",
+ "93.118.116.117",
+ "93.118.123.32",
+ "93.118.125.189",
+ "93.118.145.201",
+ "93.126.61.205",
+ "94.74.128.171",
+ "94.101.176.247",
+ "94.182.39.201",
+ "94.182.39.230",
+ "94.182.91.237",
+ "94.182.92.68",
+ "94.182.106.3",
+ "94.182.178.90",
+ "94.182.181.250",
+ "94.182.186.6",
+ "94.182.192.220",
+ "94.182.195.189",
+ "94.182.209.62",
+ "94.182.210.200",
+ "94.182.216.105",
+ "94.182.227.239",
+ "94.182.251.1",
+ "94.183.180.71",
+ "95.38.24.226",
+ "95.38.34.104",
+ "95.38.103.219",
+ "95.38.209.209",
+ "109.109.32.12",
+ "109.109.32.89",
+ "109.109.32.97",
+ "109.109.32.98",
+ "109.109.32.103",
+ "109.109.32.217",
+ "109.109.34.76",
+ "109.109.34.85",
+ "109.109.34.123",
+ "109.109.34.139",
+ "109.109.34.183",
+ "109.109.34.185",
+ "109.109.34.188",
+ "109.109.34.199",
+ "109.109.34.213",
+ "109.109.34.218",
+ "109.109.34.231",
+ "109.109.34.234",
+ "109.109.34.237",
+ "109.109.34.249",
+ "109.109.35.12",
+ "109.109.35.75",
+ "109.109.35.125",
+ "109.109.37.159",
+ "109.109.40.58",
+ "109.109.41.24",
+ "109.109.43.141",
+ "109.109.43.142",
+ "109.109.43.145",
+ "109.109.43.148",
+ "109.109.43.194",
+ "109.109.43.207",
+ "109.109.43.208",
+ "109.109.43.219",
+ "109.109.43.228",
+ "109.109.43.231",
+ "109.109.43.244",
+ "109.109.43.251",
+ "109.109.45.21",
+ "109.109.45.69",
+ "109.109.45.82",
+ "109.109.45.86",
+ "109.109.45.97",
+ "109.109.47.39",
+ "109.109.47.58",
+ "109.109.47.61",
+ "109.109.47.68",
+ "109.109.47.71",
+ "109.109.47.88",
+ "109.109.47.89",
+ "109.109.47.110",
+ "109.109.47.111",
+ "109.109.47.118",
+ "109.109.53.30",
+ "109.109.54.39",
+ "109.109.54.50",
+ "109.109.54.51",
+ "109.109.54.77",
+ "109.109.54.89",
+ "109.109.54.109",
+ "109.109.54.141",
+ "109.109.54.146",
+ "109.109.54.166",
+ "109.109.54.168",
+ "109.109.54.207",
+ "109.109.54.209",
+ "109.109.54.212",
+ "109.109.58.8",
+ "109.109.58.36",
+ "109.109.58.43",
+ "109.109.58.76",
+ "109.109.58.166",
+ "109.109.59.6",
+ "109.109.59.24",
+ "109.109.59.25",
+ "109.109.59.26",
+ "109.109.59.35",
+ "109.109.59.52",
+ "109.109.59.53",
+ "109.109.59.55",
+ "109.109.59.84",
+ "109.109.59.88",
+ "109.109.59.99",
+ "109.109.59.231",
+ "109.109.60.7",
+ "109.109.60.40",
+ "109.109.60.43",
+ "109.109.60.69",
+ "109.109.60.73",
+ "109.109.60.93",
+ "109.109.60.98",
+ "109.109.60.102",
+ "109.109.60.116",
+ "109.109.60.176",
+ "109.109.60.204",
+ "109.109.61.208",
+ "109.109.61.209",
+ "109.109.61.216",
+ "109.109.61.218",
+ "109.109.61.232",
+ "109.109.62.0",
+ "109.109.62.2",
+ "109.109.63.130",
+ "109.109.63.136",
+ "109.109.63.152",
+ "109.109.63.193",
+ "109.109.63.196",
+ "109.109.63.208",
+ "109.109.63.241",
+ "109.109.63.253",
+ "109.122.251.188",
+ "109.206.252.43",
+ "128.65.181.82",
+ "130.185.77.137",
+ "130.193.77.37",
+ "130.193.77.124",
+ "151.232.80.169",
+ "151.234.25.189",
+ "151.234.29.56",
+ "151.234.75.123",
+ "151.234.186.93",
+ "151.234.245.87",
+ "151.235.13.16",
+ "151.235.18.98",
+ "151.235.123.250",
+ "151.235.125.168",
+ "151.235.126.91",
+ "159.20.99.117",
+ "171.22.24.162",
+ "176.62.144.37",
+ "176.62.144.44",
+ "176.65.224.95",
+ "178.173.140.41",
+ "178.173.140.129",
+ "178.173.148.167",
+ "178.173.211.35",
+ "178.173.216.97",
+ "178.173.218.96",
+ "178.173.221.167",
+ "178.216.248.85",
+ "178.216.251.244",
+ "178.236.105.153",
+ "178.236.106.202",
+ "178.238.196.223",
+ "178.239.147.81",
+ "178.252.134.188",
+ "178.252.166.146",
+ "178.252.181.101",
+ "185.3.202.129",
+ "185.4.30.50",
+ "185.8.175.98",
+ "185.10.75.8",
+ "185.10.75.75",
+ "185.10.75.199",
+ "185.18.213.84",
+ "185.41.3.106",
+ "185.42.225.197",
+ "185.44.36.51",
+ "185.53.142.229",
+ "185.55.224.119",
+ "185.55.225.182",
+ "185.58.241.89",
+ "185.59.112.25",
+ "185.73.112.229",
+ "185.73.226.28",
+ "185.79.156.242",
+ "185.79.157.196",
+ "185.83.113.170",
+ "185.83.183.95",
+ "185.83.183.125",
+ "185.84.158.30",
+ "185.88.153.190",
+ "185.88.154.59",
+ "185.88.154.223",
+ "185.88.178.43",
+ "185.88.178.53",
+ "185.94.97.11",
+ "185.94.99.26",
+ "185.94.99.37",
+ "185.94.99.245",
+ "185.97.116.171",
+ "185.100.46.141",
+ "185.103.84.39",
+ "185.109.74.238",
+ "185.110.219.40",
+ "185.111.83.10",
+ "185.112.149.97",
+ "185.112.149.115",
+ "185.112.149.118",
+ "185.113.9.175",
+ "185.113.58.197",
+ "185.113.59.202",
+ "185.117.50.230",
+ "185.118.155.62",
+ "185.119.167.5",
+ "185.120.219.76",
+ "185.120.221.228",
+ "185.124.115.15",
+ "185.129.169.78",
+ "185.129.200.200",
+ "185.131.88.224",
+ "185.131.152.196",
+ "185.137.27.47",
+ "185.140.240.8",
+ "185.141.104.86",
+ "185.141.105.237",
+ "185.141.105.238",
+ "185.141.132.69",
+ "185.141.134.205",
+ "185.147.41.71",
+ "185.149.192.24",
+ "185.149.192.165",
+ "185.164.72.9",
+ "185.164.73.213",
+ "185.165.116.184",
+ "185.165.118.34",
+ "185.165.118.245",
+ "185.169.6.195",
+ "185.190.39.68",
+ "185.191.76.146",
+ "185.192.10.2",
+ "185.192.112.4",
+ "185.192.112.37",
+ "185.192.114.72",
+ "185.192.114.109",
+ "185.192.114.136",
+ "185.192.114.152",
+ "185.192.114.251",
+ "185.208.174.78",
+ "185.208.174.125",
+ "185.208.175.79",
+ "185.211.59.123",
+ "185.231.112.172",
+ "185.231.115.129",
+ "185.231.115.167",
+ "185.231.181.225",
+ "185.232.154.79",
+ "185.235.196.141",
+ "185.235.197.79",
+ "185.243.50.0",
+ "185.243.50.3",
+ "185.243.50.4",
+ "185.243.50.5",
+ "185.243.50.6",
+ "185.243.50.8",
+ "185.243.50.9",
+ "185.243.50.10",
+ "185.243.50.11",
+ "185.243.50.12",
+ "185.243.50.13",
+ "185.243.50.14",
+ "185.243.50.15",
+ "185.243.50.17",
+ "185.243.50.18",
+ "185.243.50.19",
+ "185.243.50.20",
+ "185.243.50.21",
+ "185.243.50.22",
+ "185.243.50.23",
+ "185.243.50.24",
+ "185.243.50.25",
+ "185.243.50.26",
+ "185.243.50.27",
+ "185.243.50.28",
+ "185.243.50.29",
+ "185.243.50.30",
+ "185.243.50.31",
+ "185.243.50.32",
+ "185.243.50.34",
+ "185.243.50.35",
+ "185.243.50.36",
+ "185.243.50.37",
+ "185.243.50.38",
+ "185.243.50.39",
+ "185.243.50.40",
+ "185.243.50.41",
+ "185.243.50.42",
+ "185.243.50.43",
+ "185.243.50.44",
+ "185.243.50.45",
+ "185.243.50.46",
+ "185.243.50.47",
+ "185.243.50.48",
+ "185.243.50.49",
+ "185.243.50.50",
+ "185.243.50.51",
+ "185.243.50.52",
+ "185.243.50.53",
+ "185.243.50.54",
+ "185.243.50.55",
+ "185.243.50.56",
+ "185.243.50.57",
+ "185.243.50.59",
+ "185.243.50.60",
+ "185.243.50.61",
+ "185.243.50.62",
+ "185.243.50.63",
+ "185.243.50.64",
+ "185.243.50.65",
+ "185.243.50.67",
+ "185.243.50.68",
+ "185.243.50.70",
+ "185.243.50.71",
+ "185.243.50.72",
+ "185.243.50.73",
+ "185.243.50.74",
+ "185.243.50.75",
+ "185.243.50.76",
+ "185.243.50.77",
+ "185.243.50.78",
+ "185.243.50.79",
+ "185.243.50.80",
+ "185.243.50.81",
+ "185.243.50.82",
+ "185.243.50.84",
+ "185.243.50.85",
+ "185.243.50.86",
+ "185.243.50.87",
+ "185.243.50.88",
+ "185.243.50.89",
+ "185.243.50.90",
+ "185.243.50.91",
+ "185.243.50.92",
+ "185.243.50.93",
+ "185.243.50.95",
+ "185.243.50.96",
+ "185.243.50.97",
+ "185.243.50.98",
+ "185.243.50.99",
+ "185.243.50.100",
+ "185.243.50.101",
+ "185.243.50.103",
+ "185.243.50.104",
+ "185.243.50.105",
+ "185.243.50.106",
+ "185.243.50.107",
+ "185.243.50.108",
+ "185.243.50.109",
+ "185.243.50.110",
+ "185.243.50.111",
+ "185.243.50.112",
+ "185.243.50.113",
+ "185.243.50.115",
+ "185.243.50.116",
+ "185.243.50.117",
+ "185.243.50.118",
+ "185.243.50.119",
+ "185.243.50.121",
+ "185.243.50.122",
+ "185.243.50.123",
+ "185.243.50.124",
+ "185.243.50.126",
+ "185.243.50.127",
+ "185.243.50.129",
+ "185.243.50.130",
+ "185.243.50.131",
+ "185.243.50.132",
+ "185.243.50.133",
+ "185.243.50.134",
+ "185.243.50.135",
+ "185.243.50.136",
+ "185.243.50.137",
+ "185.243.50.138",
+ "185.243.50.139",
+ "185.243.50.140",
+ "185.243.50.141",
+ "185.243.50.142",
+ "185.243.50.143",
+ "185.243.50.144",
+ "185.243.50.145",
+ "185.243.50.146",
+ "185.243.50.147",
+ "185.243.50.148",
+ "185.243.50.149",
+ "185.243.50.150",
+ "185.243.50.151",
+ "185.243.50.152",
+ "185.243.50.153",
+ "185.243.50.154",
+ "185.243.50.157",
+ "185.243.50.158",
+ "185.243.50.159",
+ "185.243.50.161",
+ "185.243.50.162",
+ "185.243.50.164",
+ "185.243.50.166",
+ "185.243.50.168",
+ "185.243.50.169",
+ "185.243.50.170",
+ "185.243.50.171",
+ "185.243.50.172",
+ "185.243.50.173",
+ "185.243.50.174",
+ "185.243.50.175",
+ "185.243.50.176",
+ "185.243.50.177",
+ "185.243.50.178",
+ "185.243.50.179",
+ "185.243.50.180",
+ "185.243.50.181",
+ "185.243.50.182",
+ "185.243.50.184",
+ "185.243.50.185",
+ "185.243.50.186",
+ "185.243.50.187",
+ "185.243.50.188",
+ "185.243.50.189",
+ "185.243.50.190",
+ "185.243.50.191",
+ "185.243.50.193",
+ "185.243.50.194",
+ "185.243.50.196",
+ "185.243.50.197",
+ "185.243.50.200",
+ "185.243.50.201",
+ "185.243.50.202",
+ "185.243.50.205",
+ "185.243.50.206",
+ "185.243.50.207",
+ "185.243.50.208",
+ "185.243.50.209",
+ "185.243.50.210",
+ "185.243.50.211",
+ "185.243.50.212",
+ "185.243.50.213",
+ "185.243.50.214",
+ "185.243.50.217",
+ "185.243.50.218",
+ "185.243.50.219",
+ "185.243.50.220",
+ "185.243.50.221",
+ "185.243.50.222",
+ "185.243.50.223",
+ "185.243.50.224",
+ "185.243.50.225",
+ "185.243.50.226",
+ "185.243.50.227",
+ "185.243.50.228",
+ "185.243.50.231",
+ "185.243.50.232",
+ "185.243.50.234",
+ "185.243.50.236",
+ "185.243.50.237",
+ "185.243.50.238",
+ "185.243.50.239",
+ "185.243.50.241",
+ "185.243.50.242",
+ "185.243.50.243",
+ "185.243.50.244",
+ "185.243.50.245",
+ "185.243.50.246",
+ "185.243.50.247",
+ "185.243.50.249",
+ "185.243.50.250",
+ "185.243.50.251",
+ "185.243.50.252",
+ "185.243.50.253",
+ "185.243.50.254",
+ "185.255.88.55",
+ "185.255.88.128",
+ "188.0.240.133",
+ "188.0.249.52",
+ "188.121.100.132",
+ "188.121.104.21",
+ "188.121.117.78",
+ "188.121.119.175",
+ "188.121.123.128",
+ "188.208.59.159",
+ "188.208.151.64",
+ "188.209.6.170",
+ "188.209.68.61",
+ "188.209.71.69",
+ "188.209.76.133",
+ "188.209.78.143",
+ "188.210.97.80",
+ "188.210.116.62",
+ "188.211.68.160",
+ "188.211.70.150",
+ "188.211.87.38",
+ "188.211.99.14",
+ "188.211.99.23",
+ "188.211.103.126",
+ "188.211.108.135",
+ "188.211.108.255",
+ "188.211.113.11",
+ "188.211.114.213",
+ "188.211.121.143",
+ "188.211.123.106",
+ "188.211.126.196",
+ "188.212.22.21",
+ "188.212.76.158",
+ "188.212.80.155",
+ "188.213.66.140",
+ "188.213.79.54",
+ "188.213.181.202",
+ "188.213.190.157",
+ "188.215.165.169",
+ "193.39.9.161",
+ "193.58.119.108",
+ "193.58.119.223",
+ "193.105.234.127",
+ "193.141.64.116",
+ "193.141.65.182",
+ "193.162.129.210",
+ "193.228.90.213",
+ "193.228.136.200",
+ "193.242.125.194",
+ "194.5.179.18",
+ "194.5.195.74",
+ "194.5.195.170",
+ "194.41.51.39",
+ "194.62.43.124",
+ "194.150.70.88",
+ "194.225.40.115",
+ "195.26.27.173",
+ "195.245.70.230",
+ "212.23.201.215",
+ "212.33.202.232",
+ "212.80.24.24",
+ "212.120.193.152",
+ "212.120.194.55",
+ "212.120.205.188",
+ "212.120.212.25",
+ "212.120.216.60",
+ "212.120.221.106",
+ "212.120.223.208",
+ "213.176.0.14",
+ "213.176.29.251",
+ "213.195.60.63",
+ "213.232.124.11",
+ "217.11.24.233",
+ "217.77.117.252",
+ "217.144.106.34",
+ "217.144.107.175",
+ "217.170.251.3",
+ "217.170.252.66",
+ "217.170.252.156",
+ "217.170.252.165",
+ "217.171.149.19",
+ "217.171.150.0",
+ "217.172.98.173",
+ "217.218.59.18",
+ "217.218.66.24",
+ "217.218.66.54",
+ "217.218.72.215",
+ "217.218.91.126",
+ "217.218.102.173",
+ "217.218.121.219",
+ "217.218.126.180",
+ "217.218.126.192",
+ "217.218.147.109",
+ "217.218.162.250",
+ "217.218.171.21",
+ "217.218.231.165",
+ "217.219.78.210",
+ "217.219.113.176",
+ "217.219.146.132",
+ "217.219.162.171",
+ "217.219.162.179",
+ "217.219.162.190",
+ "217.219.219.68",
+ "217.219.247.178",
+ "217.219.247.179",
+ "217.219.247.180",
+ "217.219.247.182",
+ "217.219.247.186",
+ "217.219.247.208",
+ "217.219.247.226",
+ "217.219.250.67",
+ "217.219.251.250",
+ "2.184.237.250",
+ "2.184.239.96",
+ "2.185.60.53",
+ "2.185.100.114",
+ "2.185.111.42",
+ "2.185.115.187",
+ "2.185.118.190",
+ "2.185.119.25",
+ "2.185.121.161",
+ "2.185.123.125",
+ "2.185.144.18",
+ "2.185.144.71",
+ "2.185.146.147",
+ "2.185.152.23",
+ "2.185.228.3",
+ "2.185.228.166",
+ "2.185.229.141",
+ "2.185.229.223",
+ "2.185.232.202",
+ "2.185.233.97",
+ "2.185.234.29",
+ "2.185.251.169",
+ "2.185.254.215",
+ "2.186.12.33",
+ "2.186.12.72",
+ "2.186.12.169",
+ "2.186.14.53",
+ "2.186.114.102",
+ "2.186.118.65",
+ "2.186.121.65",
+ "2.186.122.56",
+ "2.186.123.180",
+ "2.186.123.193",
+ "2.187.25.177",
+ "2.187.32.105",
+ "2.187.59.28",
+ "2.187.97.193",
+ "2.187.150.211",
+ "2.187.188.97",
+ "2.187.189.192",
+ "2.188.2.253",
+ "2.188.15.200",
+ "2.188.15.201",
+ "2.188.15.202",
+ "2.188.21.20",
+ "2.188.21.90",
+ "2.188.21.100",
+ "2.188.21.120",
+ "2.188.21.130",
+ "2.188.21.190",
+ "2.188.21.200",
+ "2.188.21.230",
+ "2.188.21.240",
+ "2.188.26.10",
+ "2.188.43.88",
+ "2.188.54.1",
+ "2.188.54.2",
+ "2.188.54.54",
+ "2.188.54.55",
+ "2.188.58.12",
+ "2.188.73.81",
+ "2.188.163.135",
+ "2.188.163.136",
+ "2.188.164.29",
+ "2.188.164.30",
+ "2.188.165.106",
+ "2.188.168.184",
+ "2.188.184.19",
+ "2.188.212.158",
+ "2.188.218.179",
+ "2.188.218.180",
+ "2.188.218.181",
+ "2.188.228.114",
+ "2.188.230.127",
+ "2.188.235.83",
+ "2.188.236.82",
+ "2.189.1.10",
+ "2.189.1.13",
+ "2.189.1.15",
+ "2.189.1.19",
+ "2.189.1.253",
+ "2.189.4.29",
+ "2.189.4.30",
+ "2.189.5.183",
+ "2.189.9.56",
+ "2.189.9.87",
+ "2.189.44.44",
+ "2.189.58.3",
+ "2.189.87.170",
+ "2.189.90.130",
+ "2.189.92.1",
+ "2.189.120.111",
+ "2.189.142.70",
+ "2.189.147.101",
+ "2.189.147.211",
+ "2.189.160.131",
+ "2.189.161.45",
+ "2.189.162.131",
+ "2.189.162.136",
+ "2.189.172.227",
+ "2.189.172.229",
+ "2.189.172.233",
+ "2.189.173.198",
+ "2.189.188.54",
+ "2.189.188.56",
+ "2.189.188.62",
+ "2.189.188.190",
+ "2.189.217.95",
+ "2.189.217.251",
+ "2.189.222.223",
+ "2.189.242.36",
+ "2.189.242.86",
+ "2.189.242.100",
+ "2.189.242.107",
+ "2.189.242.109",
+ "2.189.243.18",
+ "2.189.243.19",
+ "2.189.243.21",
+ "2.189.243.25",
+ "2.189.243.101",
+ "2.189.243.103",
+ "2.189.243.226",
+ "2.189.243.228",
+ "2.189.254.58",
+ "2.189.254.67",
+ "2.189.255.21",
+ "2.189.255.130",
+ "2.189.255.227",
+ "2.190.3.49",
+ "2.190.9.251",
+ "2.190.12.228",
+ "2.190.13.15",
+ "2.190.14.71",
+ "2.190.17.170",
+ "2.190.18.195",
+ "2.190.31.215",
+ "2.190.35.50",
+ "2.190.36.61",
+ "2.190.37.214",
+ "2.190.37.229",
+ "2.190.41.98",
+ "2.190.43.76",
+ "2.190.44.114",
+ "2.190.44.119",
+ "2.190.48.163",
+ "2.190.49.111",
+ "2.190.53.64",
+ "2.190.53.68",
+ "2.190.53.92",
+ "2.190.53.100",
+ "2.190.55.74",
+ "2.190.55.120",
+ "2.190.59.91",
+ "2.190.59.155",
+ "2.190.73.43",
+ "2.190.73.67",
+ "2.190.78.115",
+ "2.190.79.245",
+ "2.190.86.118",
+ "2.190.92.26",
+ "2.190.94.100",
+ "2.190.100.174",
+ "2.190.108.91",
+ "2.190.111.134",
+ "2.190.113.182",
+ "2.190.133.106",
+ "2.190.137.215",
+ "2.190.139.102",
+ "2.190.144.183",
+ "2.190.147.151",
+ "2.190.152.187",
+ "2.190.153.67",
+ "2.190.159.244",
+ "2.190.163.207",
+ "2.190.169.87",
+ "2.190.179.133",
+ "2.190.182.32",
+ "2.190.183.92",
+ "2.190.185.210",
+ "2.190.189.114",
+ "2.190.196.38",
+ "2.190.197.33",
+ "2.190.197.175",
+ "2.190.208.237",
+ "2.190.211.50",
+ "2.190.218.16",
+ "2.190.218.137",
+ "2.190.222.23",
+ "2.190.225.89",
+ "2.190.226.224",
+ "2.190.230.164",
+ "2.190.239.52",
+ "2.190.254.192",
+ "2.191.1.142",
+ "2.191.3.59",
+ "2.191.7.101",
+ "2.191.11.236",
+ "2.191.13.68",
+ "2.191.14.96",
+ "2.191.17.34",
+ "2.191.19.25",
+ "2.191.20.200",
+ "2.191.30.238",
+ "2.191.34.90",
+ "2.191.37.81",
+ "2.191.37.155",
+ "2.191.38.203",
+ "2.191.42.29",
+ "2.191.44.179",
+ "2.191.46.6",
+ "2.191.50.40",
+ "2.191.53.152",
+ "2.191.59.4",
+ "2.191.59.95",
+ "2.191.65.208",
+ "2.191.66.14",
+ "2.191.66.48",
+ "2.191.70.85",
+ "2.191.78.251",
+ "2.191.79.86",
+ "2.191.83.25",
+ "2.191.92.195",
+ "2.191.95.198",
+ "2.191.112.91",
+ "2.191.114.44",
+ "2.191.119.38",
+ "2.191.120.15",
+ "5.10.248.4",
+ "5.10.248.7",
+ "5.10.248.13",
+ "5.10.248.23",
+ "5.10.248.26",
+ "5.10.248.31",
+ "5.10.248.33",
+ "5.10.248.41",
+ "5.10.248.57",
+ "5.10.248.65",
+ "5.10.248.67",
+ "5.10.248.88",
+ "5.10.248.92",
+ "5.10.248.95",
+ "5.10.248.99",
+ "5.10.248.107",
+ "5.10.248.110",
+ "5.10.248.117",
+ "5.10.248.119",
+ "5.10.248.128",
+ "5.10.248.138",
+ "5.10.248.155",
+ "5.10.248.158",
+ "5.10.248.160",
+ "5.10.248.164",
+ "5.10.248.169",
+ "5.10.248.170",
+ "5.10.248.171",
+ "5.10.248.183",
+ "5.10.248.215",
+ "5.10.248.225",
+ "5.10.248.237",
+ "5.10.248.240",
+ "5.10.248.241",
+ "5.10.249.2",
+ "5.10.249.24",
+ "5.10.249.44",
+ "5.10.249.79",
+ "5.10.249.105",
+ "5.10.249.138",
+ "5.10.249.140",
+ "5.10.249.175",
+ "5.10.249.184",
+ "5.10.249.208",
+ "5.10.249.233",
+ "5.10.249.242",
+ "5.22.193.2",
+ "5.22.193.3",
+ "5.22.200.250",
+ "5.22.203.46",
+ "5.22.203.47",
+ "5.42.217.8",
+ "5.42.217.25",
+ "5.42.217.76",
+ "5.42.217.181",
+ "5.42.217.186",
+ "5.42.217.207",
+ "5.42.217.208",
+ "5.42.223.9",
+ "5.42.223.119",
+ "5.42.223.160",
+ "5.42.223.179",
+ "5.42.223.189",
+ "5.42.223.247",
+ "5.42.223.254",
+ "5.56.128.128",
+ "5.56.132.47",
+ "5.56.132.69",
+ "5.56.132.70",
+ "5.56.132.76",
+ "5.56.132.79",
+ "5.56.132.89",
+ "5.56.132.93",
+ "5.56.132.97",
+ "5.56.132.99",
+ "5.56.132.100",
+ "5.56.132.109",
+ "5.56.132.120",
+ "5.56.132.121",
+ "5.56.132.126",
+ "5.56.132.132",
+ "5.56.132.145",
+ "5.56.132.148",
+ "5.56.132.150",
+ "5.56.132.157",
+ "5.56.132.169",
+ "5.56.132.170",
+ "5.56.132.174",
+ "5.56.132.176",
+ "5.56.132.177",
+ "5.56.132.180",
+ "5.56.132.182",
+ "5.56.132.183",
+ "5.56.132.185",
+ "5.56.132.186",
+ "5.56.132.188",
+ "5.56.132.189",
+ "5.56.132.203",
+ "5.56.132.218",
+ "5.56.132.219",
+ "5.56.132.220",
+ "5.56.132.235",
+ "5.56.132.251",
+ "5.56.132.253",
+ "5.56.134.9",
+ "5.56.134.51",
+ "5.56.134.95",
+ "5.56.134.153",
+ "5.56.134.237",
+ "5.56.135.5",
+ "5.56.135.15",
+ "5.56.135.16",
+ "5.56.135.25",
+ "5.56.135.131",
+ "5.56.135.132",
+ "5.56.135.196",
+ "5.56.135.218",
+ "5.56.135.244",
+ "5.57.32.2",
+ "5.57.32.29",
+ "5.57.32.32",
+ "5.57.32.103",
+ "5.57.32.106",
+ "5.57.32.125",
+ "5.57.32.140",
+ "5.57.32.163",
+ "5.57.32.164",
+ "5.57.32.165",
+ "5.57.32.167",
+ "5.57.32.168",
+ "5.57.32.169",
+ "5.57.32.170",
+ "5.57.32.171",
+ "5.57.32.172",
+ "5.57.32.174",
+ "5.57.32.205",
+ "5.57.32.226",
+ "5.57.32.228",
+ "5.57.32.229",
+ "5.57.32.231",
+ "5.57.32.232",
+ "5.57.32.236",
+ "5.57.32.237",
+ "5.57.32.239",
+ "5.57.32.240",
+ "5.57.32.242",
+ "5.57.32.243",
+ "5.57.32.244",
+ "5.57.32.245",
+ "5.57.32.246",
+ "5.57.32.248",
+ "5.57.32.249",
+ "5.57.32.252",
+ "5.57.32.253",
+ "5.57.34.4",
+ "5.57.34.48",
+ "5.57.34.53",
+ "5.57.34.121",
+ "5.57.34.140",
+ "5.57.34.142",
+ "5.57.34.194",
+ "5.57.34.195",
+ "5.57.34.197",
+ "5.57.34.229",
+ "5.57.34.230",
+ "5.57.34.231",
+ "5.57.34.232",
+ "5.57.34.233",
+ "5.57.34.234",
+ "5.57.34.235",
+ "5.57.34.236",
+ "5.57.34.237",
+ "5.57.34.238",
+ "5.57.34.242",
+ "5.57.34.243",
+ "5.57.34.244",
+ "5.57.34.246",
+ "5.57.34.249",
+ "5.57.34.250",
+ "5.57.34.251",
+ "5.57.34.252",
+ "5.57.35.57",
+ "5.57.35.112",
+ "5.57.35.181",
+ "5.57.35.229",
+ "5.57.37.20",
+ "5.57.37.40",
+ "5.57.37.84",
+ "5.57.37.89",
+ "5.57.37.144",
+ "5.57.37.224",
+ "5.57.39.16",
+ "5.57.39.80",
+ "5.57.39.101",
+ "5.57.39.114",
+ "5.57.39.178",
+ "5.57.39.189",
+ "5.57.39.197",
+ "5.57.39.230",
+ "5.61.24.2",
+ "5.61.24.5",
+ "5.61.24.15",
+ "5.61.24.24",
+ "5.61.24.30",
+ "5.61.24.64",
+ "5.61.24.78",
+ "5.61.24.126",
+ "5.61.24.202",
+ "5.61.24.236",
+ "5.61.25.2",
+ "5.61.25.34",
+ "5.61.25.55",
+ "5.61.25.132",
+ "5.61.25.226",
+ "5.61.26.4",
+ "5.61.26.5",
+ "5.61.28.2",
+ "5.61.28.12",
+ "5.61.28.34",
+ "5.61.28.38",
+ "5.61.28.44",
+ "5.61.28.48",
+ "5.61.28.102",
+ "5.61.28.103",
+ "5.61.28.109",
+ "5.61.28.113",
+ "5.61.28.236",
+ "5.61.28.239",
+ "5.61.28.245",
+ "5.61.29.43",
+ "5.61.29.113",
+ "5.61.29.135",
+ "5.61.29.140",
+ "5.61.29.165",
+ "5.61.29.168",
+ "5.61.29.170",
+ "5.61.29.181",
+ "5.61.29.183",
+ "5.61.29.210",
+ "5.61.29.212",
+ "5.61.29.230",
+ "5.61.30.20",
+ "5.61.30.42",
+ "5.61.30.84",
+ "5.61.30.99",
+ "5.61.30.100",
+ "5.61.30.101",
+ "5.61.30.102",
+ "5.61.30.116",
+ "5.61.30.132",
+ "5.61.30.135",
+ "5.61.30.145",
+ "5.61.30.164",
+ "5.61.30.195",
+ "5.61.30.230",
+ "5.61.30.233",
+ "5.61.30.238",
+ "5.61.31.35",
+ "5.61.31.72",
+ "5.61.31.84",
+ "5.61.31.88",
+ "5.61.31.101",
+ "5.61.31.103",
+ "5.61.31.106",
+ "5.61.31.148",
+ "5.61.31.170",
+ "5.61.31.184",
+ "5.61.31.190",
+ "5.61.31.214",
+ "5.61.31.236",
+ "5.61.31.241",
+ "5.62.190.164",
+ "5.63.8.38",
+ "5.63.8.43",
+ "5.63.8.44",
+ "5.63.8.46",
+ "5.63.8.62",
+ "5.63.8.70",
+ "5.63.8.83",
+ "5.63.8.130",
+ "5.63.8.134",
+ "5.63.8.138",
+ "5.63.8.142",
+ "5.63.8.146",
+ "5.63.8.155",
+ "5.63.8.186",
+ "5.63.8.190",
+ "5.63.8.243",
+ "5.63.8.247",
+ "5.63.8.248",
+ "5.63.8.252",
+ "5.63.8.253",
+ "5.63.8.254",
+ "5.63.9.35",
+ "5.63.9.36",
+ "5.63.9.38",
+ "5.63.9.39",
+ "5.63.9.40",
+ "5.63.9.41",
+ "5.63.9.42",
+ "5.63.9.43",
+ "5.63.9.44",
+ "5.63.9.45",
+ "5.63.9.142",
+ "5.63.9.179",
+ "5.63.9.180",
+ "5.63.9.181",
+ "5.63.9.202",
+ "5.63.9.205",
+ "5.63.9.206",
+ "5.63.9.219",
+ "5.63.9.222",
+ "5.63.9.242",
+ "5.63.9.251",
+ "5.63.10.115",
+ "5.63.10.122",
+ "5.63.10.202",
+ "5.63.10.227",
+ "5.63.10.228",
+ "5.63.13.6",
+ "5.63.13.10",
+ "5.63.13.14",
+ "5.63.13.61",
+ "5.63.13.62",
+ "5.63.13.91",
+ "5.63.13.92",
+ "5.63.13.93",
+ "5.63.13.94",
+ "5.63.13.98",
+ "5.63.13.125",
+ "5.63.13.147",
+ "5.63.13.158",
+ "5.63.13.172",
+ "5.63.13.174",
+ "5.63.13.179",
+ "5.63.13.183",
+ "5.63.13.187",
+ "5.63.13.188",
+ "5.63.13.212",
+ "5.63.13.246",
+ "5.63.13.250",
+ "5.63.15.2",
+ "5.63.15.95",
+ "5.74.13.212",
+ "5.74.20.118",
+ "5.74.25.40",
+ "5.74.27.137",
+ "5.74.30.157",
+ "5.74.35.175",
+ "5.74.40.57",
+ "5.74.64.61",
+ "5.74.70.72",
+ "5.74.80.124",
+ "5.74.82.62",
+ "5.74.85.54",
+ "5.74.87.230",
+ "5.74.89.141",
+ "5.74.91.84",
+ "5.74.93.18",
+ "5.74.94.246",
+ "5.74.103.0",
+ "5.74.108.253",
+ "5.74.116.99",
+ "5.74.157.17",
+ "5.74.159.248",
+ "5.74.168.73",
+ "5.74.169.165",
+ "5.74.173.111",
+ "5.74.177.58",
+ "5.74.179.196",
+ "5.74.193.165",
+ "5.74.201.57",
+ "5.74.204.86",
+ "5.74.220.174",
+ "5.74.226.60",
+ "5.74.229.186",
+ "5.74.230.137",
+ "5.74.233.4",
+ "5.74.247.49",
+ "5.74.249.133",
+ "5.74.249.152",
+ "5.74.250.193",
+ "5.74.254.130",
+ "5.74.255.47",
+ "5.106.6.30",
+ "5.106.18.134",
+ "5.106.19.21",
+ "5.106.28.197",
+ "5.106.50.108",
+ "5.106.52.108",
+ "5.134.192.129",
+ "5.134.194.83",
+ "5.144.128.17",
+ "5.144.128.20",
+ "5.144.128.21",
+ "5.144.129.2",
+ "5.144.129.4",
+ "5.144.129.6",
+ "5.144.129.7",
+ "5.144.129.8",
+ "5.144.129.9",
+ "5.144.129.10",
+ "5.144.129.12",
+ "5.144.129.14",
+ "5.144.129.15",
+ "5.144.129.16",
+ "5.144.129.18",
+ "5.144.129.19",
+ "5.144.129.20",
+ "5.144.129.21",
+ "5.144.129.22",
+ "5.144.129.23",
+ "5.144.129.24",
+ "5.144.129.26",
+ "5.144.129.27",
+ "5.144.129.28",
+ "5.144.129.29",
+ "5.144.129.30",
+ "5.144.129.31",
+ "5.144.129.33",
+ "5.144.129.34",
+ "5.144.129.35",
+ "5.144.129.36",
+ "5.144.129.37",
+ "5.144.129.38",
+ "5.144.129.39",
+ "5.144.129.41",
+ "5.144.129.42",
+ "5.144.129.43",
+ "5.144.129.44",
+ "5.144.129.45",
+ "5.144.129.46",
+ "5.144.129.47",
+ "5.144.129.48",
+ "5.144.129.50",
+ "5.144.129.51",
+ "5.144.129.53",
+ "5.144.129.54",
+ "5.144.129.55",
+ "5.144.129.56",
+ "5.144.129.58",
+ "5.144.129.59",
+ "5.144.129.60",
+ "5.144.129.61",
+ "5.144.129.62",
+ "5.144.129.65",
+ "5.144.129.67",
+ "5.144.129.68",
+ "5.144.129.70",
+ "5.144.129.71",
+ "5.144.129.72",
+ "5.144.129.73",
+ "5.144.129.74",
+ "5.144.129.75",
+ "5.144.129.76",
+ "5.144.129.77",
+ "5.144.129.78",
+ "5.144.129.79",
+ "5.144.129.80",
+ "5.144.129.81",
+ "5.144.129.82",
+ "5.144.129.84",
+ "5.144.129.85",
+ "5.144.129.86",
+ "5.144.129.87",
+ "5.144.129.88",
+ "5.144.129.89",
+ "5.144.129.90",
+ "5.144.129.91",
+ "5.144.129.92",
+ "5.144.129.93",
+ "5.144.129.94",
+ "5.144.129.95",
+ "5.144.129.96",
+ "5.144.129.97",
+ "5.144.129.98",
+ "5.144.129.99",
+ "5.144.129.102",
+ "5.144.129.103",
+ "5.144.129.104",
+ "5.144.129.105",
+ "5.144.129.106",
+ "5.144.129.107",
+ "5.144.129.108",
+ "5.144.129.109",
+ "5.144.129.112",
+ "5.144.129.113",
+ "5.144.129.114",
+ "5.144.129.115",
+ "5.144.129.116",
+ "5.144.129.117",
+ "5.144.129.118",
+ "5.144.129.119",
+ "5.144.129.120",
+ "5.144.129.121",
+ "5.144.129.122",
+ "5.144.129.123",
+ "5.144.129.124",
+ "5.144.129.125",
+ "5.144.129.126",
+ "5.144.129.127",
+ "5.144.129.128",
+ "5.144.129.129",
+ "5.144.129.130",
+ "5.144.129.131",
+ "5.144.129.132",
+ "5.144.129.133",
+ "5.144.129.134",
+ "5.144.129.135",
+ "5.144.129.136",
+ "5.144.129.137",
+ "5.144.129.139",
+ "5.144.129.140",
+ "5.144.129.141",
+ "5.144.129.142",
+ "5.144.129.143",
+ "5.144.129.144",
+ "5.144.129.145",
+ "5.144.129.146",
+ "5.144.129.147",
+ "5.144.129.149",
+ "5.144.129.150",
+ "5.144.129.152",
+ "5.144.129.153",
+ "5.144.129.154",
+ "5.144.129.155",
+ "5.144.129.156",
+ "5.144.129.157",
+ "5.144.129.158",
+ "5.144.129.159",
+ "5.144.129.160",
+ "5.144.129.161",
+ "5.144.129.162",
+ "5.144.129.163",
+ "5.144.129.164",
+ "5.144.129.165",
+ "5.144.129.167",
+ "5.144.129.168",
+ "5.144.129.169",
+ "5.144.129.170",
+ "5.144.129.171",
+ "5.144.129.172",
+ "5.144.129.173",
+ "5.144.129.174",
+ "5.144.129.175",
+ "5.144.129.176",
+ "5.144.129.178",
+ "5.144.129.179",
+ "5.144.129.180",
+ "5.144.129.181",
+ "5.144.129.182",
+ "5.144.129.183",
+ "5.144.129.184",
+ "5.144.129.185",
+ "5.144.129.186",
+ "5.144.129.187",
+ "5.144.129.188",
+ "5.144.129.190",
+ "5.144.129.191",
+ "5.144.129.192",
+ "5.144.129.193",
+ "5.144.129.194",
+ "5.144.129.195",
+ "5.144.129.196",
+ "5.144.129.197",
+ "5.144.129.198",
+ "5.144.129.199",
+ "5.144.129.200",
+ "5.144.129.201",
+ "5.144.129.202",
+ "5.144.129.203",
+ "5.144.129.204",
+ "5.144.129.205",
+ "5.144.129.206",
+ "5.144.129.207",
+ "5.144.129.208",
+ "5.144.129.209",
+ "5.144.129.210",
+ "5.144.129.211",
+ "5.144.129.212",
+ "5.144.129.213",
+ "5.144.129.214",
+ "5.144.129.215",
+ "5.144.129.217",
+ "5.144.129.218",
+ "5.144.129.219",
+ "5.144.129.220",
+ "5.144.129.221",
+ "5.144.129.222",
+ "5.144.129.223",
+ "5.144.129.224",
+ "5.144.129.225",
+ "5.144.129.226",
+ "5.144.129.227",
+ "5.144.129.228",
+ "5.144.129.229",
+ "5.144.129.230",
+ "5.144.129.231",
+ "5.144.129.232",
+ "5.144.129.233",
+ "5.144.129.234",
+ "5.144.129.235",
+ "5.144.129.237",
+ "5.144.129.238",
+ "5.144.129.239",
+ "5.144.129.240",
+ "5.144.129.241",
+ "5.144.129.242",
+ "5.144.129.243",
+ "5.144.129.244",
+ "5.144.129.245",
+ "5.144.129.246",
+ "5.144.129.247",
+ "5.144.129.248",
+ "5.144.129.249",
+ "5.144.129.250",
+ "5.144.129.251",
+ "5.144.129.252",
+ "5.144.129.253",
+ "5.144.129.254",
+ "5.144.130.3",
+ "5.144.130.5",
+ "5.144.130.7",
+ "5.144.130.9",
+ "5.144.130.10",
+ "5.144.130.11",
+ "5.144.130.12",
+ "5.144.130.13",
+ "5.144.130.14",
+ "5.144.130.15",
+ "5.144.130.16",
+ "5.144.130.17",
+ "5.144.130.20",
+ "5.144.130.21",
+ "5.144.130.23",
+ "5.144.130.24",
+ "5.144.130.25",
+ "5.144.130.27",
+ "5.144.130.28",
+ "5.144.130.29",
+ "5.144.130.30",
+ "5.144.130.31",
+ "5.144.130.32",
+ "5.144.130.34",
+ "5.144.130.35",
+ "5.144.130.36",
+ "5.144.130.37",
+ "5.144.130.40",
+ "5.144.130.42",
+ "5.144.130.43",
+ "5.144.130.44",
+ "5.144.130.45",
+ "5.144.130.46",
+ "5.144.130.47",
+ "5.144.130.48",
+ "5.144.130.50",
+ "5.144.130.51",
+ "5.144.130.53",
+ "5.144.130.57",
+ "5.144.130.59",
+ "5.144.130.60",
+ "5.144.130.61",
+ "5.144.130.62",
+ "5.144.130.63",
+ "5.144.130.64",
+ "5.144.130.65",
+ "5.144.130.66",
+ "5.144.130.67",
+ "5.144.130.68",
+ "5.144.130.69",
+ "5.144.130.70",
+ "5.144.130.71",
+ "5.144.130.72",
+ "5.144.130.73",
+ "5.144.130.74",
+ "5.144.130.76",
+ "5.144.130.77",
+ "5.144.130.78",
+ "5.144.130.79",
+ "5.144.130.80",
+ "5.144.130.81",
+ "5.144.130.83",
+ "5.144.130.85",
+ "5.144.130.86",
+ "5.144.130.87",
+ "5.144.130.88",
+ "5.144.130.89",
+ "5.144.130.91",
+ "5.144.130.92",
+ "5.144.130.93",
+ "5.144.130.95",
+ "5.144.130.97",
+ "5.144.130.98",
+ "5.144.130.99",
+ "5.144.130.100",
+ "5.144.130.101",
+ "5.144.130.102",
+ "5.144.130.103",
+ "5.144.130.104",
+ "5.144.130.105",
+ "5.144.130.106",
+ "5.144.130.107",
+ "5.144.130.108",
+ "5.144.130.109",
+ "5.144.130.110",
+ "5.144.130.111",
+ "5.144.130.112",
+ "5.144.130.114",
+ "5.144.130.115",
+ "5.144.130.116",
+ "5.144.130.118",
+ "5.144.130.120",
+ "5.144.130.121",
+ "5.144.130.123",
+ "5.144.130.125",
+ "5.144.130.126",
+ "5.144.130.127",
+ "5.144.130.128",
+ "5.144.130.129",
+ "5.144.130.130",
+ "5.144.130.131",
+ "5.144.130.132",
+ "5.144.130.133",
+ "5.144.130.134",
+ "5.144.130.135",
+ "5.144.130.136",
+ "5.144.130.137",
+ "5.144.130.139",
+ "5.144.130.140",
+ "5.144.130.141",
+ "5.144.130.142",
+ "5.144.130.144",
+ "5.144.130.146",
+ "5.144.130.148",
+ "5.144.130.149",
+ "5.144.130.151",
+ "5.144.130.152",
+ "5.144.130.153",
+ "5.144.130.154",
+ "5.144.130.155",
+ "5.144.130.156",
+ "5.144.130.157",
+ "5.144.130.158",
+ "5.144.130.160",
+ "5.144.130.161",
+ "5.144.130.162",
+ "5.144.130.163",
+ "5.144.130.164",
+ "5.144.130.165",
+ "5.144.130.166",
+ "5.144.130.167",
+ "5.144.130.168",
+ "5.144.130.169",
+ "5.144.130.170",
+ "5.144.130.172",
+ "5.144.130.173",
+ "5.144.130.174",
+ "5.144.130.175",
+ "5.144.130.176",
+ "5.144.130.178",
+ "5.144.130.179",
+ "5.144.130.180",
+ "5.144.130.181",
+ "5.144.130.182",
+ "5.144.130.183",
+ "5.144.130.184",
+ "5.144.130.185",
+ "5.144.130.187",
+ "5.144.130.188",
+ "5.144.130.189",
+ "5.144.130.191",
+ "5.144.130.192",
+ "5.144.130.193",
+ "5.144.130.194",
+ "5.144.130.195",
+ "5.144.130.197",
+ "5.144.130.198",
+ "5.144.130.199",
+ "5.144.130.201",
+ "5.144.130.202",
+ "5.144.130.203",
+ "5.144.130.204",
+ "5.144.130.205",
+ "5.144.130.206",
+ "5.144.130.207",
+ "5.144.130.208",
+ "5.144.130.209",
+ "5.144.130.210",
+ "5.144.130.211",
+ "5.144.130.212",
+ "5.144.130.213",
+ "5.144.130.215",
+ "5.144.130.216",
+ "5.144.130.217",
+ "5.144.130.218",
+ "5.144.130.220",
+ "5.144.130.221",
+ "5.144.130.222",
+ "5.144.130.223",
+ "5.144.130.224",
+ "5.144.130.225",
+ "5.144.130.226",
+ "5.144.130.227",
+ "5.144.130.228",
+ "5.144.130.229",
+ "5.144.130.230",
+ "5.144.130.231",
+ "5.144.130.232",
+ "5.144.130.233",
+ "5.144.130.234",
+ "5.144.130.235",
+ "5.144.130.236",
+ "5.144.130.238",
+ "5.144.130.239",
+ "5.144.130.241",
+ "5.144.130.242",
+ "5.144.130.243",
+ "5.144.130.244",
+ "5.144.130.246",
+ "5.144.130.247",
+ "5.144.130.248",
+ "5.144.130.250",
+ "5.144.130.251",
+ "5.144.130.253",
+ "5.144.130.254",
+ "5.144.131.168",
+ "5.144.131.226",
+ "5.144.131.227",
+ "5.144.131.228",
+ "5.144.131.229",
+ "5.144.131.230",
+ "5.144.131.231",
+ "5.144.131.234",
+ "5.144.131.236",
+ "5.144.131.237",
+ "5.144.131.238",
+ "5.144.131.239",
+ "5.144.131.244",
+ "5.144.131.249",
+ "5.144.131.250",
+ "5.144.131.251",
+ "5.144.131.252",
+ "5.144.131.254",
+ "5.144.132.4",
+ "5.144.132.6",
+ "5.144.132.23",
+ "5.144.132.24",
+ "5.144.132.25",
+ "5.144.132.29",
+ "5.144.132.33",
+ "5.144.132.38",
+ "5.144.132.53",
+ "5.144.132.111",
+ "5.144.132.123",
+ "5.144.132.137",
+ "5.144.132.151",
+ "5.144.132.155",
+ "5.144.132.158",
+ "5.144.132.167",
+ "5.144.132.175",
+ "5.144.132.178",
+ "5.144.132.199",
+ "5.144.132.237",
+ "5.144.132.238",
+ "5.144.132.241",
+ "5.144.133.55",
+ "5.144.133.156",
+ "5.144.133.163",
+ "5.144.133.164",
+ "5.144.133.171",
+ "5.144.133.182",
+ "5.144.133.183",
+ "5.144.133.195",
+ "5.144.133.198",
+ "5.144.133.244",
+ "5.144.134.74",
+ "5.144.134.85",
+ "5.144.134.126",
+ "5.144.134.210",
+ "5.144.134.211",
+ "5.144.134.212",
+ "5.144.134.213",
+ "5.144.134.214",
+ "5.144.135.35",
+ "5.144.135.36",
+ "5.144.135.37",
+ "5.144.135.186",
+ "5.145.112.38",
+ "5.145.112.39",
+ "5.145.112.50",
+ "5.145.112.51",
+ "5.145.112.52",
+ "5.145.112.54",
+ "5.145.112.55",
+ "5.145.112.56",
+ "5.145.112.58",
+ "5.145.112.59",
+ "5.145.112.70",
+ "5.145.112.112",
+ "5.145.113.112",
+ "5.145.115.90",
+ "5.145.115.115",
+ "5.145.115.125",
+ "5.145.119.118",
+ "5.145.119.119",
+ "5.159.48.16",
+ "5.159.48.25",
+ "5.159.48.41",
+ "5.159.48.42",
+ "5.159.48.43",
+ "5.159.48.49",
+ "5.159.49.10",
+ "5.159.49.28",
+ "5.159.49.40",
+ "5.159.49.59",
+ "5.159.49.78",
+ "5.159.49.95",
+ "5.159.49.100",
+ "5.159.49.118",
+ "5.159.49.141",
+ "5.159.49.154",
+ "5.159.49.162",
+ "5.159.49.177",
+ "5.159.49.212",
+ "5.159.49.233",
+ "5.159.50.144",
+ "5.159.50.146",
+ "5.159.50.147",
+ "5.159.50.148",
+ "5.159.50.149",
+ "5.159.50.150",
+ "5.159.51.1",
+ "5.159.51.2",
+ "5.159.51.16",
+ "5.159.51.17",
+ "5.159.51.18",
+ "5.159.51.19",
+ "5.159.51.20",
+ "5.159.51.21",
+ "5.159.51.22",
+ "5.159.51.23",
+ "5.159.51.192",
+ "5.159.51.193",
+ "5.159.51.195",
+ "5.159.51.196",
+ "5.159.51.197",
+ "5.159.51.198",
+ "5.159.51.199",
+ "5.159.51.200",
+ "5.159.51.201",
+ "5.159.51.202",
+ "5.159.51.203",
+ "5.159.51.204",
+ "5.159.51.205",
+ "5.159.51.206",
+ "5.159.52.46",
+ "5.159.52.47",
+ "5.159.52.48",
+ "5.159.52.49",
+ "5.159.52.50",
+ "5.159.52.51",
+ "5.159.52.52",
+ "5.159.52.54",
+ "5.159.52.55",
+ "5.159.52.56",
+ "5.159.52.57",
+ "5.159.52.58",
+ "5.159.52.59",
+ "5.159.52.60",
+ "5.159.52.61",
+ "5.159.52.62",
+ "5.159.52.74",
+ "5.159.52.75",
+ "5.159.53.9",
+ "5.159.53.10",
+ "5.159.53.11",
+ "5.159.55.51",
+ "5.159.55.55",
+ "5.159.55.106",
+ "5.159.55.116",
+ "5.159.55.123",
+ "5.159.55.154",
+ "5.159.55.226",
+ "5.159.55.227",
+ "5.160.0.37",
+ "5.160.2.51",
+ "5.160.2.157",
+ "5.160.2.158",
+ "5.160.5.66",
+ "5.160.5.67",
+ "5.160.5.68",
+ "5.160.5.207",
+ "5.160.6.67",
+ "5.160.8.243",
+ "5.160.10.151",
+ "5.160.10.152",
+ "5.160.10.204",
+ "5.160.11.95",
+ "5.160.12.98",
+ "5.160.13.235",
+ "5.160.14.4",
+ "5.160.27.80",
+ "5.160.28.35",
+ "5.160.28.180",
+ "5.160.29.154",
+ "5.160.30.27",
+ "5.160.42.43",
+ "5.160.42.44",
+ "5.160.42.120",
+ "5.160.42.138",
+ "5.160.42.180",
+ "5.160.43.117",
+ "5.160.43.195",
+ "5.160.46.2",
+ "5.160.46.234",
+ "5.160.47.154",
+ "5.160.47.196",
+ "5.160.47.199",
+ "5.160.48.202",
+ "5.160.48.210",
+ "5.160.48.212",
+ "5.160.48.214",
+ "5.160.48.215",
+ "5.160.48.216",
+ "5.160.48.217",
+ "5.160.48.218",
+ "5.160.48.219",
+ "5.160.48.220",
+ "5.160.50.34",
+ "5.160.50.174",
+ "5.160.53.92",
+ "5.160.56.242",
+ "5.160.56.244",
+ "5.160.56.254",
+ "5.160.61.43",
+ "5.160.61.167",
+ "5.160.63.135",
+ "5.160.64.69",
+ "5.160.65.23",
+ "5.160.66.82",
+ "5.160.66.91",
+ "5.160.66.171",
+ "5.160.66.172",
+ "5.160.66.173",
+ "5.160.68.228",
+ "5.160.69.36",
+ "5.160.71.168",
+ "5.160.72.210",
+ "5.160.72.211",
+ "5.160.72.212",
+ "5.160.75.2",
+ "5.160.79.56",
+ "5.160.79.219",
+ "5.160.80.180",
+ "5.160.80.183",
+ "5.160.80.230",
+ "5.160.83.253",
+ "5.160.85.243",
+ "5.160.85.244",
+ "5.160.86.141",
+ "5.160.90.91",
+ "5.160.91.141",
+ "5.160.91.243",
+ "5.160.92.164",
+ "5.160.93.189",
+ "5.160.95.50",
+ "5.160.96.34",
+ "5.160.98.197",
+ "5.160.99.121",
+ "5.160.99.226",
+ "5.160.99.238",
+ "5.160.103.178",
+ "5.160.103.179",
+ "5.160.104.2",
+ "5.160.104.3",
+ "5.160.108.179",
+ "5.160.108.181",
+ "5.160.109.165",
+ "5.160.109.229",
+ "5.160.115.35",
+ "5.160.116.174",
+ "5.160.116.180",
+ "5.160.118.138",
+ "5.160.119.53",
+ "5.160.120.52",
+ "5.160.121.70",
+ "5.160.121.186",
+ "5.160.122.41",
+ "5.160.123.165",
+ "5.160.128.142",
+ "5.160.134.2",
+ "5.160.135.51",
+ "5.160.138.21",
+ "5.160.138.43",
+ "5.160.138.66",
+ "5.160.138.70",
+ "5.160.138.157",
+ "5.160.138.220",
+ "5.160.139.18",
+ "5.160.139.19",
+ "5.160.139.74",
+ "5.160.139.86",
+ "5.160.139.91",
+ "5.160.140.4",
+ "5.160.142.7",
+ "5.160.144.16",
+ "5.160.146.1",
+ "5.160.146.74",
+ "5.160.146.194",
+ "5.160.146.196",
+ "5.160.146.197",
+ "5.160.146.232",
+ "5.160.146.234",
+ "5.160.150.30",
+ "5.160.151.59",
+ "5.160.151.60",
+ "5.160.152.135",
+ "5.160.152.163",
+ "5.160.152.164",
+ "5.160.152.165",
+ "5.160.152.171",
+ "5.160.153.4",
+ "5.160.154.34",
+ "5.160.154.53",
+ "5.160.154.61",
+ "5.160.159.98",
+ "5.160.166.36",
+ "5.160.167.249",
+ "5.160.178.229",
+ "5.160.179.179",
+ "5.160.179.227",
+ "5.160.179.237",
+ "5.160.186.163",
+ "5.160.187.35",
+ "5.160.187.51",
+ "5.160.189.11",
+ "5.160.189.12",
+ "5.160.192.5",
+ "5.160.192.9",
+ "5.160.195.11",
+ "5.160.196.134",
+ "5.160.196.141",
+ "5.160.196.142",
+ "5.160.196.181",
+ "5.160.197.195",
+ "5.160.197.196",
+ "5.160.197.197",
+ "5.160.197.199",
+ "5.160.197.200",
+ "5.160.197.210",
+ "5.160.197.221",
+ "5.160.198.78",
+ "5.160.200.18",
+ "5.160.200.163",
+ "5.160.200.168",
+ "5.160.200.172",
+ "5.160.200.174",
+ "5.160.200.178",
+ "5.160.200.197",
+ "5.160.200.204",
+ "5.160.203.70",
+ "5.160.208.6",
+ "5.160.211.32",
+ "5.160.211.131",
+ "5.160.211.132",
+ "5.160.215.166",
+ "5.160.217.10",
+ "5.160.217.11",
+ "5.160.218.102",
+ "5.160.218.121",
+ "5.160.218.125",
+ "5.160.218.236",
+ "5.160.218.245",
+ "5.160.219.133",
+ "5.160.219.139",
+ "5.160.219.188",
+ "5.160.223.51",
+ "5.160.223.52",
+ "5.160.225.4",
+ "5.160.225.20",
+ "5.160.227.245",
+ "5.160.228.181",
+ "5.160.230.66",
+ "5.160.231.210",
+ "5.160.232.104",
+ "5.160.242.54",
+ "5.160.242.184",
+ "5.160.243.30",
+ "5.160.243.66",
+ "5.160.243.137",
+ "5.160.243.151",
+ "5.160.243.157",
+ "5.160.243.227",
+ "5.160.243.231",
+ "5.160.246.47",
+ "5.160.246.178",
+ "5.160.246.252",
+ "5.160.247.71",
+ "5.160.247.147",
+ "5.160.247.148",
+ "5.160.247.158",
+ "5.160.247.196",
+ "5.160.247.198",
+ "5.160.247.199",
+ "5.160.247.200",
+ "5.160.247.201",
+ "5.160.247.202",
+ "5.182.44.16",
+ "5.182.44.19",
+ "5.182.44.20",
+ "5.182.44.26",
+ "5.182.44.28",
+ "5.182.44.33",
+ "5.182.44.34",
+ "5.182.44.39",
+ "5.182.44.41",
+ "5.182.44.43",
+ "5.182.44.48",
+ "5.182.44.55",
+ "5.182.44.58",
+ "5.182.44.61",
+ "5.182.44.63",
+ "5.182.44.65",
+ "5.182.44.67",
+ "5.182.44.71",
+ "5.182.44.72",
+ "5.182.44.74",
+ "5.182.44.77",
+ "5.182.44.92",
+ "5.182.44.98",
+ "5.182.44.99",
+ "5.182.44.100",
+ "5.182.44.101",
+ "5.182.44.102",
+ "5.182.44.103",
+ "5.182.44.104",
+ "5.182.44.105",
+ "5.182.44.106",
+ "5.182.44.107",
+ "5.182.44.110",
+ "5.182.44.112",
+ "5.182.44.113",
+ "5.182.44.114",
+ "5.182.44.115",
+ "5.182.44.116",
+ "5.182.44.117",
+ "5.182.44.119",
+ "5.182.44.121",
+ "5.182.44.127",
+ "5.182.44.129",
+ "5.182.44.130",
+ "5.182.44.131",
+ "5.182.44.138",
+ "5.182.44.139",
+ "5.182.44.141",
+ "5.182.44.142",
+ "5.182.44.144",
+ "5.182.44.146",
+ "5.182.44.148",
+ "5.182.44.149",
+ "5.182.44.152",
+ "5.182.44.154",
+ "5.182.44.155",
+ "5.182.44.158",
+ "5.182.44.160",
+ "5.182.44.162",
+ "5.182.44.163",
+ "5.182.44.164",
+ "5.182.44.165",
+ "5.182.44.167",
+ "5.182.44.171",
+ "5.182.44.172",
+ "5.182.44.173",
+ "5.182.44.178",
+ "5.182.44.180",
+ "5.182.44.181",
+ "5.182.44.182",
+ "5.182.44.185",
+ "5.182.44.187",
+ "5.182.44.188",
+ "5.182.44.189",
+ "5.182.44.192",
+ "5.182.44.194",
+ "5.182.44.196",
+ "5.182.44.198",
+ "5.182.44.202",
+ "5.182.44.204",
+ "5.182.44.206",
+ "5.182.44.207",
+ "5.182.44.210",
+ "5.182.44.217",
+ "5.182.44.219",
+ "5.182.44.223",
+ "5.182.44.224",
+ "5.182.44.226",
+ "5.182.44.228",
+ "5.182.44.229",
+ "5.182.44.241",
+ "5.182.44.244",
+ "5.182.44.250",
+ "5.182.45.24",
+ "5.182.46.1",
+ "5.182.46.2",
+ "5.182.46.7",
+ "5.182.46.23",
+ "5.182.46.31",
+ "5.182.46.34",
+ "5.182.46.36",
+ "5.182.46.41",
+ "5.182.46.48",
+ "5.182.46.57",
+ "5.182.46.192",
+ "5.182.46.195",
+ "5.190.1.5",
+ "5.190.1.25",
+ "5.190.1.27",
+ "5.190.2.65",
+ "5.190.8.113",
+ "5.190.15.130",
+ "5.190.29.201",
+ "5.190.48.6",
+ "5.190.52.102",
+ "5.190.52.245",
+ "5.190.69.66",
+ "5.190.77.209",
+ "5.190.100.67",
+ "5.190.101.130",
+ "5.190.116.154",
+ "5.190.154.36",
+ "5.190.154.37",
+ "5.190.166.2",
+ "5.190.190.3",
+ "5.190.209.10",
+ "5.190.211.50",
+ "5.190.211.52",
+ "5.200.65.61",
+ "5.200.69.88",
+ "5.200.72.229",
+ "5.200.128.135",
+ "5.200.149.177",
+ "5.200.150.244",
+ "5.200.168.221",
+ "5.200.169.199",
+ "5.200.176.227",
+ "5.200.189.251",
+ "5.200.206.162",
+ "5.200.228.95",
+ "5.200.229.26",
+ "5.200.229.99",
+ "5.201.161.214",
+ "5.201.164.149",
+ "5.201.165.218",
+ "5.201.175.194",
+ "5.201.177.244",
+ "5.202.5.222",
+ "5.202.6.42",
+ "5.202.6.46",
+ "5.202.6.67",
+ "5.202.6.68",
+ "5.202.6.195",
+ "5.202.6.198",
+ "5.202.6.199",
+ "5.202.6.200",
+ "5.202.6.201",
+ "5.202.6.202",
+ "5.202.6.203",
+ "5.202.6.207",
+ "5.202.6.230",
+ "5.202.7.28",
+ "5.202.7.70",
+ "5.202.7.85",
+ "5.202.7.168",
+ "5.202.7.170",
+ "5.202.8.253",
+ "5.202.9.71",
+ "5.202.9.77",
+ "5.202.9.78",
+ "5.202.9.99",
+ "5.202.10.2",
+ "5.202.10.36",
+ "5.202.10.39",
+ "5.202.10.42",
+ "5.202.10.44",
+ "5.202.10.45",
+ "5.202.10.48",
+ "5.202.10.49",
+ "5.202.10.50",
+ "5.202.10.52",
+ "5.202.10.54",
+ "5.202.10.55",
+ "5.202.10.58",
+ "5.202.10.61",
+ "5.202.12.20",
+ "5.202.13.85",
+ "5.202.13.86",
+ "5.202.13.234",
+ "5.202.13.235",
+ "5.202.13.236",
+ "5.202.14.2",
+ "5.202.14.7",
+ "5.202.15.246",
+ "5.202.28.142",
+ "5.202.45.250",
+ "5.202.50.41",
+ "5.202.50.42",
+ "5.202.56.58",
+ "5.202.60.146",
+ "5.202.74.30",
+ "5.202.75.244",
+ "5.202.82.59",
+ "5.202.84.226",
+ "5.202.84.234",
+ "5.202.85.159",
+ "5.202.90.128",
+ "5.202.90.131",
+ "5.202.90.187",
+ "5.202.93.180",
+ "5.202.100.100",
+ "5.202.100.101",
+ "5.202.104.85",
+ "5.202.104.163",
+ "5.202.129.29",
+ "5.202.129.30",
+ "5.202.129.31",
+ "5.202.129.32",
+ "5.202.163.204",
+ "5.202.171.138",
+ "5.202.174.168",
+ "5.202.174.211",
+ "5.202.175.80",
+ "5.202.179.237",
+ "5.202.181.233",
+ "5.202.181.246",
+ "5.202.183.10",
+ "5.202.183.165",
+ "5.202.192.34",
+ "5.202.195.114",
+ "5.202.196.63",
+ "5.202.196.245",
+ "5.202.197.202",
+ "5.202.240.33",
+ "5.202.240.36",
+ "5.202.240.37",
+ "5.202.240.43",
+ "5.202.243.94",
+ "5.202.252.30",
+ "5.202.254.25",
+ "5.232.142.26",
+ "5.232.200.53",
+ "5.232.202.36",
+ "5.232.207.123",
+ "5.233.44.58",
+ "5.233.44.60",
+ "5.233.44.130",
+ "5.233.46.104",
+ "5.233.49.38",
+ "5.233.64.155",
+ "5.233.68.117",
+ "5.233.69.52",
+ "5.233.74.61",
+ "5.233.79.124",
+ "5.233.87.166",
+ "5.233.184.241",
+ "5.234.1.249",
+ "5.234.2.97",
+ "5.234.3.203",
+ "5.234.6.249",
+ "5.234.7.101",
+ "5.234.14.184",
+ "5.234.17.49",
+ "5.234.18.240",
+ "5.234.21.81",
+ "5.234.23.206",
+ "5.234.28.29",
+ "5.234.28.201",
+ "5.234.45.50",
+ "5.234.45.240",
+ "5.234.165.195",
+ "5.234.194.136",
+ "5.234.196.39",
+ "5.234.201.187",
+ "5.234.202.60",
+ "5.234.213.173",
+ "5.234.215.171",
+ "5.235.161.28",
+ "5.235.172.1",
+ "5.235.175.177",
+ "5.235.177.154",
+ "5.235.178.108",
+ "5.235.180.3",
+ "5.235.186.172",
+ "5.235.232.65",
+ "5.235.254.187",
+ "5.236.24.76",
+ "5.236.25.20",
+ "5.236.37.8",
+ "5.236.96.242",
+ "5.236.104.163",
+ "5.236.105.251",
+ "5.236.193.47",
+ "5.236.193.128",
+ "5.236.194.247",
+ "5.236.195.113",
+ "5.236.195.211",
+ "5.237.179.70",
+ "5.237.193.239",
+ "5.237.201.65",
+ "5.237.243.46",
+ "5.237.243.168",
+ "5.238.52.10",
+ "5.238.52.133",
+ "5.238.65.238",
+ "5.238.88.214",
+ "5.238.91.216",
+ "5.238.110.141",
+ "5.238.110.178",
+ "5.238.129.145",
+ "5.238.136.226",
+ "5.238.139.75",
+ "5.238.142.6",
+ "5.238.146.31",
+ "5.238.146.126",
+ "5.238.152.244",
+ "5.238.157.188",
+ "5.238.158.161",
+ "5.238.161.202",
+ "5.238.163.58",
+ "5.238.165.255",
+ "5.238.167.20",
+ "5.238.168.18",
+ "5.238.169.163",
+ "5.238.169.251",
+ "5.238.171.210",
+ "5.238.176.158",
+ "5.238.184.49",
+ "5.238.192.34",
+ "5.238.192.161",
+ "5.238.200.214",
+ "5.238.205.46",
+ "5.238.206.81",
+ "5.238.211.141",
+ "5.238.220.93",
+ "5.238.221.36",
+ "5.238.227.230",
+ "5.238.228.234",
+ "5.238.229.0",
+ "5.238.230.8",
+ "5.238.236.19",
+ "5.238.239.99",
+ "5.238.241.190",
+ "5.238.242.251",
+ "5.238.243.187",
+ "5.238.245.7",
+ "5.238.255.152",
+ "5.239.10.28",
+ "5.239.19.142",
+ "5.239.39.175",
+ "5.239.62.113",
+ "5.239.62.215",
+ "5.239.76.206",
+ "5.239.78.243",
+ "5.239.80.95",
+ "5.239.80.138",
+ "5.239.85.223",
+ "5.239.100.27",
+ "5.239.110.134",
+ "5.239.122.122",
+ "5.239.147.118",
+ "5.239.160.77",
+ "5.239.177.85",
+ "5.239.241.236",
+ "5.239.244.75",
+ "31.7.65.29",
+ "31.7.65.45",
+ "31.7.65.61",
+ "31.7.65.92",
+ "31.7.65.102",
+ "31.7.65.132",
+ "31.7.65.133",
+ "31.7.65.134",
+ "31.7.65.135",
+ "31.7.66.78",
+ "31.7.66.235",
+ "31.7.68.93",
+ "31.7.68.201",
+ "31.7.68.202",
+ "31.7.68.206",
+ "31.7.68.215",
+ "31.7.68.220",
+ "31.7.68.246",
+ "31.7.68.248",
+ "31.7.68.250",
+ "31.7.68.251",
+ "31.7.69.57",
+ "31.7.69.218",
+ "31.7.70.12",
+ "31.7.70.104",
+ "31.7.71.8",
+ "31.7.71.11",
+ "31.7.71.122",
+ "31.7.71.197",
+ "31.7.72.37",
+ "31.7.72.114",
+ "31.7.72.147",
+ "31.7.72.148",
+ "31.7.72.179",
+ "31.7.72.180",
+ "31.7.72.181",
+ "31.7.72.182",
+ "31.7.73.5",
+ "31.7.73.6",
+ "31.7.73.21",
+ "31.7.73.91",
+ "31.7.73.95",
+ "31.7.73.117",
+ "31.7.73.120",
+ "31.7.73.131",
+ "31.7.74.4",
+ "31.7.74.164",
+ "31.7.76.254",
+ "31.7.77.226",
+ "31.7.78.15",
+ "31.7.78.39",
+ "31.7.78.83",
+ "31.7.78.124",
+ "31.7.78.133",
+ "31.7.78.140",
+ "31.7.78.157",
+ "31.7.78.180",
+ "31.7.78.191",
+ "31.7.79.69",
+ "31.7.79.114",
+ "31.7.79.130",
+ "31.7.79.137",
+ "31.7.79.140",
+ "31.7.79.150",
+ "31.7.79.155",
+ "31.7.79.156",
+ "31.7.79.200",
+ "31.7.89.103",
+ "31.7.89.104",
+ "31.14.113.35",
+ "31.14.113.146",
+ "31.14.113.147",
+ "31.14.113.148",
+ "31.14.113.149",
+ "31.14.113.150",
+ "31.14.114.62",
+ "31.14.115.2",
+ "31.14.115.12",
+ "31.14.115.70",
+ "31.14.115.83",
+ "31.14.115.196",
+ "31.14.115.198",
+ "31.14.116.2",
+ "31.14.117.10",
+ "31.14.117.194",
+ "31.14.117.202",
+ "31.14.117.207",
+ "31.14.117.212",
+ "31.14.118.146",
+ "31.14.118.147",
+ "31.14.118.228",
+ "31.14.118.229",
+ "31.14.119.165",
+ "31.14.120.2",
+ "31.14.121.116",
+ "31.14.121.131",
+ "31.14.123.2",
+ "31.14.123.24",
+ "31.14.123.127",
+ "31.14.123.145",
+ "31.14.124.74",
+ "31.24.234.34",
+ "31.24.234.35",
+ "31.24.234.37",
+ "31.25.90.7",
+ "31.25.90.10",
+ "31.25.90.11",
+ "31.25.90.13",
+ "31.25.90.22",
+ "31.25.90.29",
+ "31.25.90.76",
+ "31.25.90.93",
+ "31.25.90.94",
+ "31.25.90.100",
+ "31.25.90.110",
+ "31.25.90.114",
+ "31.25.90.116",
+ "31.25.90.130",
+ "31.25.90.131",
+ "31.25.90.132",
+ "31.25.90.142",
+ "31.25.90.143",
+ "31.25.90.145",
+ "31.25.90.146",
+ "31.25.90.147",
+ "31.25.90.148",
+ "31.25.90.149",
+ "31.25.90.150",
+ "31.25.90.151",
+ "31.25.90.152",
+ "31.25.90.158",
+ "31.25.90.163",
+ "31.25.90.164",
+ "31.25.90.165",
+ "31.25.90.166",
+ "31.25.90.167",
+ "31.25.90.168",
+ "31.25.90.169",
+ "31.25.90.170",
+ "31.25.90.171",
+ "31.25.90.172",
+ "31.25.90.176",
+ "31.25.90.177",
+ "31.25.90.178",
+ "31.25.90.179",
+ "31.25.90.180",
+ "31.25.90.182",
+ "31.25.90.189",
+ "31.25.90.194",
+ "31.25.90.229",
+ "31.25.90.242",
+ "31.25.91.4",
+ "31.25.91.5",
+ "31.25.91.6",
+ "31.25.91.9",
+ "31.25.91.10",
+ "31.25.91.11",
+ "31.25.91.12",
+ "31.25.91.13",
+ "31.25.91.15",
+ "31.25.91.22",
+ "31.25.91.40",
+ "31.25.91.41",
+ "31.25.91.84",
+ "31.25.91.85",
+ "31.25.91.87",
+ "31.25.91.97",
+ "31.25.91.112",
+ "31.25.91.113",
+ "31.25.91.115",
+ "31.25.91.124",
+ "31.25.91.204",
+ "31.25.95.227",
+ "31.47.38.137",
+ "31.47.42.2",
+ "31.47.43.228",
+ "31.47.43.241",
+ "31.47.43.246",
+ "31.47.45.2",
+ "31.47.46.34",
+ "31.47.46.35",
+ "31.47.46.36",
+ "31.47.46.37",
+ "31.47.46.38",
+ "31.47.46.41",
+ "31.47.46.42",
+ "31.47.46.44",
+ "31.47.46.46",
+ "31.47.46.51",
+ "31.47.46.53",
+ "31.47.46.54",
+ "31.47.46.56",
+ "31.47.46.59",
+ "31.47.46.60",
+ "31.47.46.61",
+ "31.47.46.62",
+ "31.47.46.67",
+ "31.47.46.69",
+ "31.47.46.70",
+ "31.47.46.72",
+ "31.47.46.73",
+ "31.47.46.75",
+ "31.47.46.76",
+ "31.47.46.81",
+ "31.47.46.83",
+ "31.47.46.84",
+ "31.47.46.86",
+ "31.47.46.87",
+ "31.47.51.2",
+ "31.47.51.32",
+ "31.47.51.102",
+ "31.47.53.2",
+ "31.47.55.162",
+ "31.47.56.131",
+ "31.47.61.33",
+ "31.47.61.66",
+ "31.47.61.99",
+ "31.47.62.193",
+ "31.58.237.101",
+ "31.58.237.107",
+ "31.130.182.10",
+ "31.170.49.43",
+ "31.171.222.180",
+ "31.171.223.114",
+ "31.184.129.66",
+ "31.184.130.2",
+ "31.184.130.252",
+ "31.184.131.3",
+ "31.184.134.159",
+ "31.184.134.161",
+ "31.184.134.178",
+ "31.184.136.173",
+ "31.184.160.109",
+ "31.184.170.203",
+ "31.184.171.128",
+ "31.184.191.246",
+ "31.193.186.2",
+ "31.193.186.3",
+ "31.193.186.4",
+ "31.193.186.5",
+ "31.193.186.6",
+ "31.193.186.7",
+ "31.193.186.8",
+ "31.193.186.9",
+ "31.193.186.10",
+ "31.193.186.11",
+ "31.193.186.12",
+ "31.193.186.13",
+ "31.193.186.14",
+ "31.214.168.26",
+ "31.214.168.35",
+ "31.214.168.42",
+ "31.214.168.68",
+ "31.214.168.100",
+ "31.214.168.132",
+ "31.214.168.162",
+ "31.214.168.164",
+ "31.214.168.166",
+ "31.214.168.179",
+ "31.214.168.180",
+ "31.214.168.229",
+ "31.214.168.246",
+ "31.214.169.21",
+ "31.214.169.22",
+ "31.214.169.206",
+ "31.214.169.244",
+ "31.214.170.74",
+ "31.214.170.163",
+ "31.214.170.194",
+ "31.214.170.213",
+ "31.214.171.86",
+ "31.214.171.130",
+ "31.214.171.132",
+ "31.214.171.133",
+ "31.214.171.134",
+ "31.214.171.135",
+ "31.214.171.170",
+ "31.214.171.171",
+ "31.214.171.174",
+ "31.214.172.6",
+ "31.214.172.11",
+ "31.214.172.78",
+ "31.214.172.183",
+ "31.214.172.184",
+ "31.214.173.30",
+ "31.214.173.76",
+ "31.214.173.170",
+ "31.214.173.178",
+ "31.214.173.210",
+ "31.214.173.244",
+ "31.214.173.254",
+ "31.214.174.4",
+ "31.214.174.6",
+ "31.214.174.27",
+ "31.214.174.90",
+ "31.214.174.91",
+ "31.214.174.92",
+ "31.214.174.93",
+ "31.214.174.99",
+ "31.214.174.114",
+ "31.214.174.125",
+ "31.214.174.163",
+ "31.214.174.166",
+ "31.214.174.194",
+ "31.214.174.195",
+ "31.214.174.196",
+ "31.214.174.197",
+ "31.214.174.205",
+ "31.214.175.10",
+ "31.214.175.11",
+ "31.214.175.13",
+ "31.214.175.14",
+ "31.214.175.146",
+ "31.214.175.185",
+ "31.214.175.214",
+ "31.214.175.220",
+ "31.214.175.246",
+ "31.214.228.242",
+ "31.214.228.243",
+ "31.214.229.212",
+ "31.214.231.121",
+ "31.214.248.27",
+ "31.214.248.60",
+ "31.214.248.74",
+ "31.214.248.75",
+ "31.214.248.76",
+ "31.214.248.77",
+ "31.214.248.78",
+ "31.214.248.102",
+ "31.214.248.146",
+ "31.214.248.147",
+ "31.214.248.174",
+ "31.214.250.14",
+ "31.214.250.28",
+ "31.214.250.42",
+ "31.214.250.69",
+ "31.214.250.70",
+ "31.214.250.72",
+ "31.214.250.75",
+ "31.214.250.76",
+ "31.214.250.77",
+ "31.214.250.83",
+ "31.214.250.84",
+ "31.214.250.88",
+ "31.214.250.90",
+ "31.214.250.91",
+ "31.214.250.92",
+ "31.214.250.94",
+ "31.214.250.96",
+ "31.214.250.98",
+ "31.214.250.99",
+ "31.214.250.100",
+ "31.214.250.101",
+ "31.214.250.102",
+ "31.214.250.106",
+ "31.214.250.108",
+ "31.214.250.109",
+ "31.214.250.112",
+ "31.214.250.113",
+ "31.214.250.114",
+ "31.214.250.116",
+ "31.214.250.118",
+ "31.214.250.121",
+ "31.214.250.122",
+ "31.214.250.123",
+ "31.214.250.125",
+ "31.214.250.198",
+ "31.214.250.199",
+ "31.214.250.201",
+ "31.214.250.203",
+ "31.214.250.209",
+ "31.214.250.210",
+ "31.214.250.211",
+ "31.214.250.213",
+ "31.214.250.214",
+ "31.214.250.215",
+ "31.214.250.216",
+ "31.214.250.217",
+ "31.214.250.218",
+ "31.214.250.219",
+ "31.214.250.220",
+ "31.214.250.221",
+ "31.214.251.6",
+ "31.214.251.147",
+ "31.214.251.148",
+ "31.214.251.149",
+ "31.214.251.194",
+ "31.214.251.196",
+ "31.214.251.199",
+ "31.214.251.200",
+ "31.214.251.201",
+ "31.214.251.202",
+ "31.214.251.203",
+ "31.214.251.204",
+ "31.214.251.206",
+ "31.214.251.207",
+ "31.214.251.208",
+ "31.214.251.209",
+ "31.214.251.215",
+ "31.214.251.217",
+ "31.214.251.219",
+ "31.214.251.220",
+ "31.214.251.228",
+ "31.214.251.230",
+ "31.214.251.231",
+ "31.214.251.232",
+ "31.214.251.233",
+ "31.214.251.234",
+ "31.214.251.238",
+ "31.214.251.239",
+ "31.214.251.241",
+ "31.214.251.247",
+ "31.214.251.253",
+ "31.214.255.50",
+ "31.214.255.53",
+ "31.214.255.54",
+ "31.214.255.139",
+ "31.214.255.140",
+ "31.214.255.152",
+ "31.214.255.154",
+ "31.214.255.155",
+ "31.214.255.156",
+ "31.214.255.160",
+ "31.214.255.161",
+ "31.214.255.163",
+ "31.214.255.165",
+ "31.214.255.166",
+ "31.214.255.167",
+ "31.214.255.168",
+ "31.214.255.169",
+ "31.214.255.170",
+ "31.214.255.171",
+ "31.214.255.176",
+ "31.214.255.177",
+ "31.214.255.178",
+ "31.214.255.179",
+ "31.214.255.180",
+ "31.214.255.181",
+ "31.214.255.182",
+ "31.214.255.183",
+ "31.214.255.184",
+ "31.214.255.185",
+ "31.214.255.186",
+ "31.214.255.187",
+ "31.214.255.188",
+ "31.214.255.189",
+ "31.216.62.30",
+ "31.216.62.39",
+ "31.216.62.58",
+ "31.216.62.60",
+ "31.216.62.82",
+ "31.216.62.86",
+ "31.216.62.93",
+ "31.216.62.102",
+ "31.216.62.107",
+ "31.216.62.118",
+ "31.216.62.131",
+ "31.216.62.136",
+ "31.216.62.137",
+ "31.216.62.144",
+ "31.216.62.146",
+ "31.216.62.147",
+ "31.216.62.158",
+ "31.216.62.170",
+ "31.216.62.203",
+ "31.216.62.212",
+ "31.216.62.227",
+ "31.216.62.248",
+ "37.9.253.32",
+ "37.9.253.33",
+ "37.10.67.10",
+ "37.10.67.18",
+ "37.10.109.29",
+ "37.32.2.2",
+ "37.32.4.41",
+ "37.32.4.124",
+ "37.32.8.52",
+ "37.32.8.55",
+ "37.32.8.100",
+ "37.32.8.180",
+ "37.32.8.208",
+ "37.32.8.253",
+ "37.32.9.100",
+ "37.32.9.117",
+ "37.32.9.118",
+ "37.32.9.248",
+ "37.32.10.21",
+ "37.32.10.53",
+ "37.32.10.120",
+ "37.32.10.151",
+ "37.32.10.227",
+ "37.32.10.254",
+ "37.32.11.26",
+ "37.32.12.41",
+ "37.32.12.48",
+ "37.32.12.50",
+ "37.32.12.52",
+ "37.32.12.146",
+ "37.32.13.105",
+ "37.32.13.171",
+ "37.32.14.47",
+ "37.32.14.114",
+ "37.32.14.184",
+ "37.32.14.226",
+ "37.32.14.234",
+ "37.32.15.0",
+ "37.32.15.18",
+ "37.32.15.85",
+ "37.32.15.155",
+ "37.32.15.205",
+ "37.32.15.208",
+ "37.32.15.248",
+ "37.32.22.248",
+ "37.32.24.35",
+ "37.32.24.126",
+ "37.32.24.156",
+ "37.32.24.192",
+ "37.32.25.162",
+ "37.32.25.174",
+ "37.32.25.185",
+ "37.32.26.165",
+ "37.32.27.138",
+ "37.32.27.222",
+ "37.32.28.174",
+ "37.32.29.195",
+ "37.32.29.247",
+ "37.32.43.208",
+ "37.32.43.224",
+ "37.32.44.58",
+ "37.32.45.18",
+ "37.32.45.20",
+ "37.32.46.131",
+ "37.32.46.132",
+ "37.32.46.133",
+ "37.32.46.134",
+ "37.32.46.135",
+ "37.32.46.136",
+ "37.32.46.137",
+ "37.32.46.138",
+ "37.32.46.139",
+ "37.32.46.141",
+ "37.32.46.142",
+ "37.32.46.143",
+ "37.32.46.144",
+ "37.32.46.145",
+ "37.32.46.146",
+ "37.32.46.147",
+ "37.32.46.148",
+ "37.32.46.149",
+ "37.32.46.162",
+ "37.32.46.163",
+ "37.32.46.165",
+ "37.32.46.166",
+ "37.32.46.168",
+ "37.32.46.169",
+ "37.32.46.171",
+ "37.32.46.172",
+ "37.32.46.174",
+ "37.32.46.175",
+ "37.32.47.196",
+ "37.32.120.138",
+ "37.32.120.139",
+ "37.32.120.148",
+ "37.32.121.133",
+ "37.32.125.138",
+ "37.32.126.130",
+ "37.32.127.99",
+ "37.32.127.100",
+ "37.32.127.106",
+ "37.75.240.5",
+ "37.75.240.14",
+ "37.75.240.15",
+ "37.75.240.16",
+ "37.75.241.200",
+ "37.130.202.14",
+ "37.130.202.66",
+ "37.130.206.6",
+ "37.130.206.7",
+ "37.143.148.145",
+ "37.148.0.167",
+ "37.148.0.222",
+ "37.148.3.35",
+ "37.148.3.51",
+ "37.148.4.83",
+ "37.148.13.79",
+ "37.148.13.187",
+ "37.148.15.80",
+ "37.148.15.221",
+ "37.148.18.165",
+ "37.148.20.117",
+ "37.148.21.64",
+ "37.148.23.120",
+ "37.148.23.172",
+ "37.148.31.13",
+ "37.148.31.44",
+ "37.148.40.88",
+ "37.148.42.47",
+ "37.148.45.196",
+ "37.148.48.54",
+ "37.148.49.252",
+ "37.148.50.125",
+ "37.148.50.202",
+ "37.148.57.6",
+ "37.148.58.5",
+ "37.148.59.134",
+ "37.148.61.147",
+ "37.148.81.227",
+ "37.148.82.138",
+ "37.148.83.154",
+ "37.148.83.210",
+ "37.148.84.245",
+ "37.148.85.86",
+ "37.148.85.180",
+ "37.148.87.111",
+ "37.148.91.8",
+ "37.148.248.50",
+ "37.148.248.77",
+ "37.152.160.27",
+ "37.152.173.170",
+ "37.152.173.215",
+ "37.152.175.67",
+ "37.152.176.118",
+ "37.152.176.179",
+ "37.152.176.237",
+ "37.152.177.84",
+ "37.152.177.138",
+ "37.152.179.31",
+ "37.152.179.69",
+ "37.152.180.124",
+ "37.152.180.157",
+ "37.152.180.240",
+ "37.152.181.60",
+ "37.152.181.115",
+ "37.152.181.142",
+ "37.152.182.41",
+ "37.152.182.119",
+ "37.152.182.187",
+ "37.152.183.92",
+ "37.152.186.170",
+ "37.152.186.203",
+ "37.152.186.224",
+ "37.152.188.11",
+ "37.152.188.16",
+ "37.152.188.131",
+ "37.152.188.132",
+ "37.152.188.220",
+ "37.152.188.254",
+ "37.152.189.114",
+ "37.152.189.128",
+ "37.152.189.156",
+ "37.152.190.8",
+ "37.152.190.9",
+ "37.152.190.80",
+ "37.152.190.239",
+ "37.152.190.252",
+ "37.152.191.223",
+ "37.156.8.90",
+ "37.156.9.203",
+ "37.156.9.255",
+ "37.156.11.220",
+ "37.156.14.221",
+ "37.156.20.91",
+ "37.156.144.82",
+ "37.156.144.83",
+ "37.156.144.85",
+ "37.156.144.91",
+ "37.156.144.125",
+ "37.156.144.202",
+ "37.156.144.203",
+ "37.156.144.204",
+ "37.156.145.84",
+ "37.156.145.86",
+ "37.156.145.136",
+ "37.156.145.137",
+ "37.156.145.138",
+ "37.156.145.139",
+ "37.156.145.141",
+ "37.156.145.144",
+ "37.156.145.146",
+ "37.156.145.147",
+ "37.156.145.152",
+ "37.156.145.153",
+ "37.156.145.155",
+ "37.156.145.158",
+ "37.156.145.197",
+ "37.156.145.251",
+ "37.156.145.252",
+ "37.156.146.39",
+ "37.156.146.40",
+ "37.156.146.45",
+ "37.156.146.61",
+ "37.156.146.105",
+ "37.156.146.109",
+ "37.156.146.125",
+ "37.156.146.166",
+ "37.156.146.245",
+ "37.156.147.43",
+ "37.156.147.110",
+ "37.156.147.116",
+ "37.156.147.125",
+ "37.156.147.220",
+ "37.156.147.221",
+ "37.156.147.242",
+ "37.156.147.243",
+ "37.156.147.244",
+ "37.156.147.245",
+ "37.156.147.246",
+ "37.191.76.202",
+ "37.191.77.81",
+ "37.191.79.136",
+ "37.191.92.114",
+ "37.191.92.115",
+ "37.191.92.116",
+ "37.191.92.117",
+ "37.191.92.118",
+ "37.191.92.119",
+ "37.191.93.195",
+ "37.191.93.196",
+ "37.191.93.202",
+ "37.191.93.203",
+ "37.191.94.35",
+ "37.191.94.44",
+ "37.191.95.6",
+ "37.191.95.7",
+ "37.191.95.13",
+ "37.191.95.14",
+ "37.191.95.70",
+ "37.191.95.82",
+ "37.191.95.86",
+ "37.191.95.99",
+ "37.191.95.100",
+ "37.202.148.139",
+ "37.202.154.171",
+ "37.202.158.11",
+ "37.202.159.84",
+ "37.202.159.125",
+ "37.202.159.230",
+ "37.202.169.144",
+ "37.202.169.202",
+ "37.202.169.251",
+ "37.202.170.32",
+ "37.202.171.239",
+ "37.202.172.64",
+ "37.202.172.82",
+ "37.202.182.143",
+ "37.202.185.61",
+ "37.202.185.66",
+ "37.202.185.132",
+ "37.202.188.85",
+ "37.202.189.203",
+ "37.202.191.176",
+ "37.202.225.95",
+ "37.202.225.173",
+ "37.202.225.206",
+ "37.202.225.224",
+ "37.202.229.195",
+ "37.202.229.200",
+ "37.202.229.205",
+ "37.202.229.209",
+ "37.202.229.215",
+ "37.202.229.220",
+ "37.202.232.222",
+ "37.202.236.4",
+ "37.202.236.12",
+ "37.202.236.100",
+ "37.202.236.126",
+ "37.202.237.2",
+ "37.202.237.195",
+ "37.202.237.242",
+ "37.202.237.246",
+ "37.202.238.11",
+ "37.202.246.70",
+ "37.228.136.98",
+ "37.228.136.157",
+ "37.228.136.181",
+ "37.228.137.35",
+ "37.228.137.66",
+ "37.228.137.76",
+ "37.228.138.34",
+ "37.228.138.123",
+ "37.228.138.134",
+ "37.228.138.138",
+ "37.228.138.154",
+ "37.228.138.155",
+ "37.228.138.201",
+ "37.228.138.203",
+ "37.228.139.3",
+ "37.228.139.5",
+ "37.228.139.26",
+ "37.228.139.40",
+ "37.228.139.41",
+ "37.228.139.107",
+ "37.228.139.229",
+ "37.255.128.78",
+ "37.255.128.250",
+ "37.255.132.14",
+ "37.255.132.54",
+ "37.255.135.36",
+ "37.255.148.218",
+ "37.255.148.221",
+ "37.255.173.171",
+ "37.255.173.172",
+ "37.255.177.60",
+ "37.255.177.138",
+ "37.255.177.153",
+ "37.255.186.102",
+ "37.255.187.164",
+ "37.255.193.188",
+ "37.255.194.13",
+ "37.255.194.69",
+ "37.255.198.80",
+ "37.255.201.39",
+ "37.255.202.25",
+ "37.255.202.70",
+ "37.255.208.38",
+ "37.255.212.55",
+ "37.255.213.220",
+ "37.255.216.121",
+ "37.255.223.36",
+ "37.255.223.218",
+ "37.255.223.240",
+ "37.255.223.243",
+ "37.255.223.244",
+ "37.255.230.35",
+ "37.255.234.14",
+ "37.255.234.34",
+ "37.255.236.67",
+ "37.255.239.57",
+ "37.255.239.175",
+ "37.255.242.68",
+ "37.255.245.39",
+ "37.255.249.150",
+ "37.255.249.166",
+ "37.255.249.172",
+ "37.255.249.205",
+ "37.255.249.220",
+ "45.9.252.79",
+ "45.11.184.151",
+ "45.11.185.10",
+ "45.11.185.148",
+ "45.11.187.103",
+ "45.15.200.31",
+ "45.81.19.49",
+ "45.81.19.60",
+ "45.81.19.133",
+ "45.82.136.141",
+ "45.82.136.148",
+ "45.82.138.40",
+ "45.82.138.113",
+ "45.82.138.224",
+ "45.82.139.150",
+ "45.86.87.84",
+ "45.86.87.85",
+ "45.89.139.5",
+ "45.89.236.7",
+ "45.89.236.11",
+ "45.89.236.13",
+ "45.89.236.15",
+ "45.89.236.16",
+ "45.89.236.17",
+ "45.89.236.28",
+ "45.89.236.29",
+ "45.89.236.30",
+ "45.89.236.40",
+ "45.89.236.41",
+ "45.89.236.47",
+ "45.89.236.48",
+ "45.89.236.51",
+ "45.89.236.52",
+ "45.89.236.53",
+ "45.89.236.55",
+ "45.89.236.59",
+ "45.89.236.67",
+ "45.89.236.68",
+ "45.89.236.73",
+ "45.89.236.74",
+ "45.89.236.87",
+ "45.89.236.89",
+ "45.89.236.133",
+ "45.89.236.153",
+ "45.89.236.154",
+ "45.89.236.158",
+ "45.89.236.163",
+ "45.89.236.173",
+ "45.89.236.179",
+ "45.89.236.180",
+ "45.89.236.183",
+ "45.89.236.185",
+ "45.89.236.187",
+ "45.89.236.190",
+ "45.89.236.227",
+ "45.89.236.228",
+ "45.89.236.247",
+ "45.89.236.249",
+ "45.89.236.252",
+ "45.89.237.18",
+ "45.89.237.24",
+ "45.89.237.67",
+ "45.89.237.68",
+ "45.89.237.70",
+ "45.89.237.72",
+ "45.89.237.80",
+ "45.89.237.81",
+ "45.89.237.82",
+ "45.89.237.85",
+ "45.89.237.86",
+ "45.89.237.101",
+ "45.89.237.109",
+ "45.89.237.158",
+ "45.89.238.179",
+ "45.89.238.183",
+ "45.89.238.185",
+ "45.89.238.187",
+ "45.89.238.189",
+ "45.89.238.190",
+ "45.89.239.33",
+ "45.89.239.35",
+ "45.89.239.39",
+ "45.89.239.40",
+ "45.89.239.41",
+ "45.89.239.42",
+ "45.89.239.43",
+ "45.89.239.44",
+ "45.89.239.45",
+ "45.89.239.109",
+ "45.89.239.110",
+ "45.89.239.121",
+ "45.89.239.130",
+ "45.89.239.190",
+ "45.89.239.210",
+ "45.89.239.228",
+ "45.89.239.234",
+ "45.89.239.238",
+ "45.89.239.252",
+ "45.89.239.253",
+ "45.90.72.14",
+ "45.90.72.85",
+ "45.90.72.153",
+ "45.90.72.161",
+ "45.90.72.172",
+ "45.90.72.227",
+ "45.90.72.228",
+ "45.90.73.12",
+ "45.90.73.14",
+ "45.90.73.15",
+ "45.90.73.16",
+ "45.90.73.30",
+ "45.90.73.31",
+ "45.90.73.56",
+ "45.90.73.61",
+ "45.90.73.66",
+ "45.90.73.68",
+ "45.90.73.153",
+ "45.90.73.154",
+ "45.90.73.187",
+ "45.90.73.205",
+ "45.90.73.206",
+ "45.90.73.208",
+ "45.90.73.209",
+ "45.90.74.14",
+ "45.90.74.24",
+ "45.90.74.29",
+ "45.90.74.61",
+ "45.90.74.104",
+ "45.90.74.114",
+ "45.90.74.159",
+ "45.90.74.174",
+ "45.90.74.175",
+ "45.90.74.176",
+ "45.90.74.185",
+ "45.90.74.192",
+ "45.90.74.202",
+ "45.90.74.204",
+ "45.90.74.217",
+ "45.90.74.241",
+ "45.90.74.253",
+ "45.90.75.75",
+ "45.91.152.3",
+ "45.91.152.10",
+ "45.91.152.11",
+ "45.91.153.10",
+ "45.92.92.2",
+ "45.92.92.3",
+ "45.92.92.4",
+ "45.92.92.5",
+ "45.92.92.6",
+ "45.92.92.7",
+ "45.92.92.8",
+ "45.92.92.9",
+ "45.92.92.11",
+ "45.92.92.12",
+ "45.92.92.13",
+ "45.92.92.14",
+ "45.92.92.15",
+ "45.92.92.16",
+ "45.92.92.17",
+ "45.92.92.19",
+ "45.92.92.20",
+ "45.92.92.22",
+ "45.92.92.23",
+ "45.92.92.24",
+ "45.92.92.26",
+ "45.92.92.27",
+ "45.92.92.28",
+ "45.92.92.29",
+ "45.92.92.30",
+ "45.92.92.31",
+ "45.92.92.32",
+ "45.92.92.34",
+ "45.92.92.35",
+ "45.92.92.36",
+ "45.92.92.38",
+ "45.92.92.39",
+ "45.92.92.40",
+ "45.92.92.42",
+ "45.92.92.43",
+ "45.92.92.44",
+ "45.92.92.47",
+ "45.92.92.50",
+ "45.92.92.51",
+ "45.92.92.52",
+ "45.92.92.54",
+ "45.92.92.55",
+ "45.92.92.56",
+ "45.92.92.57",
+ "45.92.92.58",
+ "45.92.92.59",
+ "45.92.92.60",
+ "45.92.92.61",
+ "45.92.92.62",
+ "45.92.92.63",
+ "45.92.92.64",
+ "45.92.92.65",
+ "45.92.92.66",
+ "45.92.92.67",
+ "45.92.92.68",
+ "45.92.92.70",
+ "45.92.92.71",
+ "45.92.92.72",
+ "45.92.92.74",
+ "45.92.92.75",
+ "45.92.92.77",
+ "45.92.92.78",
+ "45.92.92.79",
+ "45.92.92.80",
+ "45.92.92.81",
+ "45.92.92.82",
+ "45.92.92.83",
+ "45.92.92.84",
+ "45.92.92.85",
+ "45.92.92.86",
+ "45.92.92.87",
+ "45.92.92.88",
+ "45.92.92.89",
+ "45.92.92.90",
+ "45.92.92.91",
+ "45.92.92.93",
+ "45.92.92.94",
+ "45.92.92.95",
+ "45.92.92.96",
+ "45.92.92.97",
+ "45.92.92.98",
+ "45.92.92.99",
+ "45.92.92.100",
+ "45.92.92.101",
+ "45.92.92.102",
+ "45.92.92.103",
+ "45.92.92.104",
+ "45.92.92.105",
+ "45.92.92.106",
+ "45.92.92.107",
+ "45.92.92.108",
+ "45.92.92.109",
+ "45.92.92.110",
+ "45.92.92.111",
+ "45.92.92.112",
+ "45.92.92.113",
+ "45.92.92.115",
+ "45.92.92.116",
+ "45.92.92.117",
+ "45.92.92.118",
+ "45.92.92.119",
+ "45.92.92.120",
+ "45.92.92.121",
+ "45.92.92.122",
+ "45.92.92.123",
+ "45.92.92.124",
+ "45.92.92.125",
+ "45.92.92.127",
+ "45.92.92.128",
+ "45.92.92.129",
+ "45.92.92.130",
+ "45.92.92.131",
+ "45.92.92.132",
+ "45.92.92.133",
+ "45.92.92.134",
+ "45.92.92.135",
+ "45.92.92.136",
+ "45.92.92.137",
+ "45.92.92.139",
+ "45.92.92.140",
+ "45.92.92.141",
+ "45.92.92.142",
+ "45.92.92.143",
+ "45.92.92.144",
+ "45.92.92.145",
+ "45.92.92.146",
+ "45.92.92.147",
+ "45.92.92.148",
+ "45.92.92.149",
+ "45.92.92.150",
+ "45.92.92.152",
+ "45.92.92.153",
+ "45.92.92.154",
+ "45.92.92.156",
+ "45.92.92.157",
+ "45.92.92.158",
+ "45.92.92.159",
+ "45.92.92.161",
+ "45.92.92.163",
+ "45.92.92.164",
+ "45.92.92.165",
+ "45.92.92.166",
+ "45.92.92.168",
+ "45.92.92.169",
+ "45.92.92.170",
+ "45.92.92.172",
+ "45.92.92.174",
+ "45.92.92.176",
+ "45.92.92.177",
+ "45.92.92.178",
+ "45.92.92.179",
+ "45.92.92.181",
+ "45.92.92.182",
+ "45.92.92.183",
+ "45.92.92.185",
+ "45.92.92.186",
+ "45.92.92.187",
+ "45.92.92.188",
+ "45.92.92.190",
+ "45.92.92.191",
+ "45.92.92.192",
+ "45.92.92.193",
+ "45.92.92.194",
+ "45.92.92.195",
+ "45.92.92.197",
+ "45.92.92.199",
+ "45.92.92.201",
+ "45.92.92.202",
+ "45.92.92.203",
+ "45.92.92.204",
+ "45.92.92.205",
+ "45.92.92.206",
+ "45.92.92.207",
+ "45.92.92.208",
+ "45.92.92.209",
+ "45.92.92.210",
+ "45.92.92.211",
+ "45.92.92.212",
+ "45.92.92.213",
+ "45.92.92.214",
+ "45.92.92.215",
+ "45.92.92.216",
+ "45.92.92.217",
+ "45.92.92.218",
+ "45.92.92.219",
+ "45.92.92.220",
+ "45.92.92.221",
+ "45.92.92.222",
+ "45.92.92.223",
+ "45.92.92.224",
+ "45.92.92.225",
+ "45.92.92.226",
+ "45.92.92.227",
+ "45.92.92.228",
+ "45.92.92.229",
+ "45.92.92.231",
+ "45.92.92.232",
+ "45.92.92.233",
+ "45.92.92.234",
+ "45.92.92.235",
+ "45.92.92.236",
+ "45.92.92.237",
+ "45.92.92.238",
+ "45.92.92.239",
+ "45.92.92.240",
+ "45.92.92.241",
+ "45.92.92.242",
+ "45.92.92.243",
+ "45.92.92.244",
+ "45.92.92.245",
+ "45.92.92.246",
+ "45.92.92.248",
+ "45.92.92.249",
+ "45.92.92.250",
+ "45.92.92.251",
+ "45.92.92.252",
+ "45.92.92.253",
+ "45.92.93.18",
+ "45.92.93.48",
+ "45.92.93.70",
+ "45.92.93.94",
+ "45.92.93.97",
+ "45.92.93.98",
+ "45.92.93.104",
+ "45.92.93.118",
+ "45.92.93.137",
+ "45.92.93.138",
+ "45.92.93.139",
+ "45.92.93.151",
+ "45.92.93.162",
+ "45.92.93.164",
+ "45.92.93.172",
+ "45.92.93.180",
+ "45.92.93.249",
+ "45.92.93.250",
+ "45.92.93.251",
+ "45.92.94.2",
+ "45.92.94.3",
+ "45.92.94.5",
+ "45.92.94.6",
+ "45.92.94.8",
+ "45.92.94.9",
+ "45.92.94.10",
+ "45.92.94.16",
+ "45.92.94.19",
+ "45.92.94.21",
+ "45.92.94.22",
+ "45.92.94.34",
+ "45.92.94.46",
+ "45.92.94.47",
+ "45.92.94.48",
+ "45.92.94.49",
+ "45.92.94.50",
+ "45.92.94.51",
+ "45.92.94.52",
+ "45.92.94.53",
+ "45.92.94.54",
+ "45.92.94.55",
+ "45.92.94.56",
+ "45.92.94.57",
+ "45.92.94.58",
+ "45.92.94.59",
+ "45.92.94.60",
+ "45.92.94.89",
+ "45.92.94.97",
+ "45.92.94.109",
+ "45.92.94.151",
+ "45.92.94.170",
+ "45.92.94.171",
+ "45.92.94.226",
+ "45.92.94.244",
+ "45.92.95.67",
+ "45.92.95.68",
+ "45.92.95.70",
+ "45.92.95.254",
+ "45.94.212.13",
+ "45.94.214.22",
+ "45.94.214.230",
+ "45.94.254.34",
+ "45.94.254.69",
+ "45.94.254.70",
+ "45.94.255.189",
+ "45.94.255.222",
+ "45.129.36.6",
+ "45.129.36.10",
+ "45.129.36.19",
+ "45.129.36.28",
+ "45.129.36.30",
+ "45.129.36.42",
+ "45.129.36.58",
+ "45.129.36.59",
+ "45.129.36.60",
+ "45.129.36.61",
+ "45.129.36.62",
+ "45.129.36.114",
+ "45.129.36.162",
+ "45.129.36.166",
+ "45.129.36.182",
+ "45.129.37.10",
+ "45.129.37.70",
+ "45.129.37.71",
+ "45.129.37.72",
+ "45.129.37.76",
+ "45.129.37.98",
+ "45.129.37.115",
+ "45.129.37.116",
+ "45.129.37.117",
+ "45.129.37.118",
+ "45.129.37.150",
+ "45.129.37.151",
+ "45.129.37.178",
+ "45.129.37.183",
+ "45.129.37.184",
+ "45.129.38.34",
+ "45.129.38.37",
+ "45.129.38.52",
+ "45.129.38.54",
+ "45.129.38.61",
+ "45.129.38.66",
+ "45.129.38.130",
+ "45.129.38.140",
+ "45.129.38.170",
+ "45.129.38.173",
+ "45.129.39.90",
+ "45.129.39.117",
+ "45.129.39.146",
+ "45.129.39.195",
+ "45.129.39.206",
+ "45.132.32.4",
+ "45.132.32.5",
+ "45.132.32.222",
+ "45.132.172.90",
+ "45.132.172.95",
+ "45.132.172.241",
+ "45.135.241.12",
+ "45.135.241.22",
+ "45.135.241.33",
+ "45.135.241.70",
+ "45.135.241.74",
+ "45.135.241.83",
+ "45.135.241.95",
+ "45.135.241.129",
+ "45.135.241.144",
+ "45.135.241.228",
+ "45.135.241.237",
+ "45.135.241.245",
+ "45.135.241.253",
+ "45.135.243.22",
+ "45.135.243.30",
+ "45.135.243.34",
+ "45.135.243.56",
+ "45.135.243.58",
+ "45.135.243.73",
+ "45.135.243.76",
+ "45.135.243.78",
+ "45.135.243.79",
+ "45.135.243.85",
+ "45.135.243.87",
+ "45.135.243.88",
+ "45.135.243.92",
+ "45.135.243.94",
+ "45.135.243.105",
+ "45.135.243.206",
+ "45.135.243.216",
+ "45.135.243.217",
+ "45.135.243.222",
+ "45.135.243.226",
+ "45.135.243.227",
+ "45.135.243.235",
+ "45.137.16.10",
+ "45.137.17.120",
+ "45.137.17.133",
+ "45.137.17.242",
+ "45.137.17.243",
+ "45.137.17.244",
+ "45.137.17.245",
+ "45.138.132.25",
+ "45.138.132.26",
+ "45.138.132.28",
+ "45.138.132.29",
+ "45.138.132.30",
+ "45.138.132.31",
+ "45.138.132.38",
+ "45.138.132.43",
+ "45.138.132.46",
+ "45.138.132.47",
+ "45.138.132.48",
+ "45.138.132.57",
+ "45.138.132.71",
+ "45.138.132.80",
+ "45.138.132.117",
+ "45.138.132.118",
+ "45.138.132.136",
+ "45.138.132.174",
+ "45.138.132.193",
+ "45.138.132.204",
+ "45.138.132.247",
+ "45.138.132.249",
+ "45.138.133.3",
+ "45.138.133.4",
+ "45.138.133.5",
+ "45.138.133.6",
+ "45.138.133.7",
+ "45.138.133.8",
+ "45.138.133.9",
+ "45.138.133.10",
+ "45.138.133.11",
+ "45.138.133.12",
+ "45.138.133.13",
+ "45.138.133.14",
+ "45.138.133.15",
+ "45.138.133.16",
+ "45.138.133.17",
+ "45.138.133.18",
+ "45.138.133.20",
+ "45.138.133.21",
+ "45.138.133.22",
+ "45.138.133.23",
+ "45.138.133.24",
+ "45.138.133.25",
+ "45.138.133.26",
+ "45.138.133.28",
+ "45.138.133.29",
+ "45.138.133.30",
+ "45.138.133.32",
+ "45.138.133.33",
+ "45.138.133.34",
+ "45.138.133.35",
+ "45.138.133.36",
+ "45.138.133.37",
+ "45.138.133.38",
+ "45.138.133.39",
+ "45.138.133.41",
+ "45.138.133.42",
+ "45.138.133.44",
+ "45.138.133.45",
+ "45.138.133.46",
+ "45.138.133.47",
+ "45.138.133.49",
+ "45.138.133.51",
+ "45.138.133.52",
+ "45.138.133.53",
+ "45.138.133.56",
+ "45.138.133.57",
+ "45.138.133.60",
+ "45.138.133.61",
+ "45.138.133.62",
+ "45.138.133.64",
+ "45.138.133.65",
+ "45.138.133.66",
+ "45.138.133.67",
+ "45.138.133.69",
+ "45.138.133.70",
+ "45.138.133.71",
+ "45.138.133.72",
+ "45.138.133.73",
+ "45.138.133.75",
+ "45.138.133.76",
+ "45.138.133.77",
+ "45.138.133.78",
+ "45.138.133.79",
+ "45.138.133.81",
+ "45.138.133.85",
+ "45.138.133.89",
+ "45.138.133.90",
+ "45.138.133.91",
+ "45.138.133.92",
+ "45.138.133.93",
+ "45.138.133.94",
+ "45.138.133.95",
+ "45.138.133.96",
+ "45.138.133.98",
+ "45.138.133.99",
+ "45.138.133.100",
+ "45.138.133.101",
+ "45.138.133.102",
+ "45.138.133.103",
+ "45.138.133.104",
+ "45.138.133.105",
+ "45.138.133.107",
+ "45.138.133.108",
+ "45.138.133.110",
+ "45.138.133.111",
+ "45.138.133.112",
+ "45.138.133.114",
+ "45.138.133.115",
+ "45.138.133.117",
+ "45.138.133.118",
+ "45.138.133.122",
+ "45.138.133.123",
+ "45.138.133.124",
+ "45.138.133.125",
+ "45.138.133.128",
+ "45.138.133.129",
+ "45.138.133.130",
+ "45.138.133.131",
+ "45.138.133.132",
+ "45.138.133.133",
+ "45.138.133.134",
+ "45.138.133.136",
+ "45.138.133.137",
+ "45.138.133.138",
+ "45.138.133.140",
+ "45.138.133.141",
+ "45.138.133.142",
+ "45.138.133.143",
+ "45.138.133.144",
+ "45.138.133.147",
+ "45.138.133.148",
+ "45.138.133.149",
+ "45.138.133.150",
+ "45.138.133.151",
+ "45.138.133.152",
+ "45.138.133.154",
+ "45.138.133.155",
+ "45.138.133.156",
+ "45.138.133.157",
+ "45.138.133.158",
+ "45.138.133.159",
+ "45.138.133.160",
+ "45.138.133.162",
+ "45.138.133.163",
+ "45.138.133.164",
+ "45.138.133.165",
+ "45.138.133.167",
+ "45.138.133.168",
+ "45.138.133.169",
+ "45.138.133.170",
+ "45.138.133.171",
+ "45.138.133.172",
+ "45.138.133.173",
+ "45.138.133.174",
+ "45.138.133.175",
+ "45.138.133.176",
+ "45.138.133.177",
+ "45.138.133.178",
+ "45.138.133.179",
+ "45.138.133.180",
+ "45.138.133.181",
+ "45.138.133.182",
+ "45.138.133.183",
+ "45.138.133.184",
+ "45.138.133.185",
+ "45.138.133.186",
+ "45.138.133.187",
+ "45.138.133.188",
+ "45.138.133.189",
+ "45.138.133.190",
+ "45.138.133.191",
+ "45.138.133.192",
+ "45.138.133.193",
+ "45.138.133.194",
+ "45.138.133.195",
+ "45.138.133.196",
+ "45.138.133.197",
+ "45.138.133.199",
+ "45.138.133.200",
+ "45.138.133.201",
+ "45.138.133.202",
+ "45.138.133.203",
+ "45.138.133.204",
+ "45.138.133.206",
+ "45.138.133.207",
+ "45.138.133.208",
+ "45.138.133.209",
+ "45.138.133.211",
+ "45.138.133.212",
+ "45.138.133.213",
+ "45.138.133.214",
+ "45.138.133.215",
+ "45.138.133.217",
+ "45.138.133.218",
+ "45.138.133.219",
+ "45.138.133.220",
+ "45.138.133.221",
+ "45.138.133.223",
+ "45.138.133.224",
+ "45.138.133.225",
+ "45.138.133.226",
+ "45.138.133.227",
+ "45.138.133.228",
+ "45.138.133.229",
+ "45.138.133.230",
+ "45.138.133.231",
+ "45.138.133.232",
+ "45.138.133.233",
+ "45.138.133.234",
+ "45.138.133.235",
+ "45.138.133.236",
+ "45.138.133.237",
+ "45.138.133.238",
+ "45.138.133.239",
+ "45.138.133.240",
+ "45.138.133.241",
+ "45.138.133.242",
+ "45.138.133.243",
+ "45.138.133.244",
+ "45.138.133.245",
+ "45.138.133.247",
+ "45.138.133.248",
+ "45.138.133.249",
+ "45.138.133.250",
+ "45.138.133.251",
+ "45.138.133.252",
+ "45.138.133.253",
+ "45.138.133.254",
+ "45.138.134.2",
+ "45.138.134.3",
+ "45.138.134.4",
+ "45.138.134.5",
+ "45.138.134.6",
+ "45.138.134.7",
+ "45.138.134.8",
+ "45.138.134.9",
+ "45.138.134.10",
+ "45.138.134.11",
+ "45.138.134.12",
+ "45.138.134.13",
+ "45.138.134.14",
+ "45.138.134.16",
+ "45.138.134.17",
+ "45.138.134.18",
+ "45.138.134.20",
+ "45.138.134.21",
+ "45.138.134.22",
+ "45.138.134.23",
+ "45.138.134.24",
+ "45.138.134.25",
+ "45.138.134.27",
+ "45.138.134.28",
+ "45.138.134.29",
+ "45.138.134.30",
+ "45.138.134.33",
+ "45.138.134.34",
+ "45.138.134.35",
+ "45.138.134.36",
+ "45.138.134.37",
+ "45.138.134.38",
+ "45.138.134.39",
+ "45.138.134.40",
+ "45.138.134.41",
+ "45.138.134.42",
+ "45.138.134.43",
+ "45.138.134.45",
+ "45.138.134.46",
+ "45.138.134.47",
+ "45.138.134.48",
+ "45.138.134.49",
+ "45.138.134.50",
+ "45.138.134.51",
+ "45.138.134.52",
+ "45.138.134.53",
+ "45.138.134.54",
+ "45.138.134.55",
+ "45.138.134.56",
+ "45.138.134.57",
+ "45.138.134.58",
+ "45.138.134.59",
+ "45.138.134.60",
+ "45.138.134.61",
+ "45.138.134.62",
+ "45.138.134.63",
+ "45.138.134.64",
+ "45.138.134.65",
+ "45.138.134.67",
+ "45.138.134.68",
+ "45.138.134.69",
+ "45.138.134.70",
+ "45.138.134.71",
+ "45.138.134.72",
+ "45.138.134.73",
+ "45.138.134.74",
+ "45.138.134.75",
+ "45.138.134.76",
+ "45.138.134.77",
+ "45.138.134.78",
+ "45.138.134.79",
+ "45.138.134.80",
+ "45.138.134.82",
+ "45.138.134.83",
+ "45.138.134.84",
+ "45.138.134.85",
+ "45.138.134.86",
+ "45.138.134.87",
+ "45.138.134.88",
+ "45.138.134.89",
+ "45.138.134.90",
+ "45.138.134.91",
+ "45.138.134.92",
+ "45.138.134.93",
+ "45.138.134.94",
+ "45.138.134.97",
+ "45.138.134.98",
+ "45.138.134.100",
+ "45.138.134.101",
+ "45.138.134.102",
+ "45.138.134.103",
+ "45.138.134.104",
+ "45.138.134.106",
+ "45.138.134.107",
+ "45.138.134.108",
+ "45.138.134.109",
+ "45.138.134.110",
+ "45.138.134.111",
+ "45.138.134.112",
+ "45.138.134.113",
+ "45.138.134.114",
+ "45.138.134.115",
+ "45.138.134.116",
+ "45.138.134.118",
+ "45.138.134.119",
+ "45.138.134.120",
+ "45.138.134.121",
+ "45.138.134.122",
+ "45.138.134.123",
+ "45.138.134.124",
+ "45.138.134.125",
+ "45.138.134.126",
+ "45.138.134.127",
+ "45.138.134.130",
+ "45.138.134.131",
+ "45.138.134.132",
+ "45.138.134.133",
+ "45.138.134.135",
+ "45.138.134.136",
+ "45.138.134.137",
+ "45.138.134.138",
+ "45.138.134.139",
+ "45.138.134.140",
+ "45.138.134.141",
+ "45.138.134.143",
+ "45.138.134.145",
+ "45.138.134.146",
+ "45.138.134.147",
+ "45.138.134.149",
+ "45.138.134.150",
+ "45.138.134.151",
+ "45.138.134.152",
+ "45.138.134.153",
+ "45.138.134.155",
+ "45.138.134.157",
+ "45.138.134.158",
+ "45.138.134.159",
+ "45.138.134.161",
+ "45.138.134.162",
+ "45.138.134.163",
+ "45.138.134.164",
+ "45.138.134.165",
+ "45.138.134.166",
+ "45.138.134.167",
+ "45.138.134.168",
+ "45.138.134.171",
+ "45.138.134.172",
+ "45.138.134.173",
+ "45.138.134.175",
+ "45.138.134.177",
+ "45.138.134.178",
+ "45.138.134.179",
+ "45.138.134.180",
+ "45.138.134.181",
+ "45.138.134.184",
+ "45.138.134.185",
+ "45.138.134.187",
+ "45.138.134.188",
+ "45.138.134.189",
+ "45.138.134.190",
+ "45.138.134.191",
+ "45.138.134.192",
+ "45.138.134.193",
+ "45.138.134.195",
+ "45.138.134.196",
+ "45.138.134.197",
+ "45.138.134.198",
+ "45.138.134.200",
+ "45.138.134.203",
+ "45.138.134.205",
+ "45.138.134.206",
+ "45.138.134.207",
+ "45.138.134.209",
+ "45.138.134.210",
+ "45.138.134.211",
+ "45.138.134.212",
+ "45.138.134.213",
+ "45.138.134.214",
+ "45.138.134.215",
+ "45.138.134.216",
+ "45.138.134.217",
+ "45.138.134.218",
+ "45.138.134.219",
+ "45.138.134.220",
+ "45.138.134.221",
+ "45.138.134.223",
+ "45.138.134.224",
+ "45.138.134.225",
+ "45.138.134.226",
+ "45.138.134.227",
+ "45.138.134.230",
+ "45.138.134.233",
+ "45.138.134.234",
+ "45.138.134.236",
+ "45.138.134.237",
+ "45.138.134.238",
+ "45.138.134.239",
+ "45.138.134.240",
+ "45.138.134.241",
+ "45.138.134.242",
+ "45.138.134.243",
+ "45.138.134.244",
+ "45.138.134.245",
+ "45.138.134.246",
+ "45.138.134.247",
+ "45.138.134.250",
+ "45.138.134.252",
+ "45.138.134.253",
+ "45.138.135.4",
+ "45.138.135.6",
+ "45.138.135.7",
+ "45.138.135.8",
+ "45.138.135.9",
+ "45.138.135.10",
+ "45.138.135.11",
+ "45.138.135.12",
+ "45.138.135.13",
+ "45.138.135.14",
+ "45.138.135.15",
+ "45.138.135.16",
+ "45.138.135.17",
+ "45.138.135.18",
+ "45.138.135.19",
+ "45.138.135.21",
+ "45.138.135.22",
+ "45.138.135.23",
+ "45.138.135.24",
+ "45.138.135.25",
+ "45.138.135.26",
+ "45.138.135.27",
+ "45.138.135.28",
+ "45.138.135.29",
+ "45.138.135.30",
+ "45.138.135.31",
+ "45.138.135.35",
+ "45.138.135.38",
+ "45.138.135.42",
+ "45.138.135.43",
+ "45.138.135.45",
+ "45.138.135.48",
+ "45.138.135.51",
+ "45.138.135.52",
+ "45.138.135.59",
+ "45.138.135.83",
+ "45.138.135.97",
+ "45.138.135.114",
+ "45.138.135.115",
+ "45.138.135.116",
+ "45.138.135.120",
+ "45.138.135.131",
+ "45.138.135.140",
+ "45.138.135.145",
+ "45.138.135.153",
+ "45.138.135.158",
+ "45.138.135.163",
+ "45.138.135.171",
+ "45.138.135.176",
+ "45.138.135.182",
+ "45.138.135.185",
+ "45.138.135.186",
+ "45.138.135.190",
+ "45.138.135.202",
+ "45.138.135.203",
+ "45.138.135.205",
+ "45.138.135.209",
+ "45.138.135.222",
+ "45.138.135.223",
+ "45.138.135.231",
+ "45.138.135.233",
+ "45.138.135.238",
+ "45.138.135.241",
+ "45.138.135.250",
+ "45.138.135.251",
+ "45.139.10.8",
+ "45.139.10.23",
+ "45.139.10.37",
+ "45.139.10.42",
+ "45.139.10.45",
+ "45.139.10.51",
+ "45.139.10.52",
+ "45.139.10.53",
+ "45.139.10.58",
+ "45.139.10.65",
+ "45.139.10.68",
+ "45.139.10.70",
+ "45.139.10.82",
+ "45.139.10.86",
+ "45.139.10.87",
+ "45.139.10.92",
+ "45.139.10.100",
+ "45.139.10.108",
+ "45.139.10.110",
+ "45.139.10.113",
+ "45.139.10.119",
+ "45.139.10.120",
+ "45.139.10.124",
+ "45.139.10.126",
+ "45.139.10.130",
+ "45.139.10.133",
+ "45.139.10.136",
+ "45.139.10.139",
+ "45.139.10.143",
+ "45.139.10.157",
+ "45.139.10.167",
+ "45.139.10.181",
+ "45.139.10.190",
+ "45.139.10.194",
+ "45.139.10.195",
+ "45.139.10.198",
+ "45.139.10.203",
+ "45.139.10.210",
+ "45.139.10.213",
+ "45.139.10.215",
+ "45.139.10.224",
+ "45.139.10.233",
+ "45.139.10.242",
+ "45.139.10.243",
+ "45.139.10.246",
+ "45.139.10.247",
+ "45.139.10.251",
+ "45.139.10.252",
+ "45.139.10.253",
+ "45.139.11.5",
+ "45.139.11.7",
+ "45.139.11.29",
+ "45.139.11.43",
+ "45.139.11.45",
+ "45.139.11.46",
+ "45.139.11.47",
+ "45.139.11.48",
+ "45.139.11.50",
+ "45.139.11.51",
+ "45.139.11.60",
+ "45.139.11.72",
+ "45.139.11.78",
+ "45.139.11.83",
+ "45.139.11.89",
+ "45.139.11.98",
+ "45.139.11.100",
+ "45.139.11.102",
+ "45.139.11.107",
+ "45.139.11.108",
+ "45.139.11.115",
+ "45.139.11.124",
+ "45.139.11.125",
+ "45.139.11.128",
+ "45.139.11.133",
+ "45.139.11.135",
+ "45.139.11.137",
+ "45.139.11.139",
+ "45.139.11.140",
+ "45.139.11.142",
+ "45.139.11.145",
+ "45.139.11.146",
+ "45.139.11.149",
+ "45.139.11.155",
+ "45.139.11.157",
+ "45.139.11.164",
+ "45.139.11.169",
+ "45.139.11.170",
+ "45.139.11.174",
+ "45.139.11.177",
+ "45.139.11.179",
+ "45.139.11.187",
+ "45.139.11.194",
+ "45.139.11.212",
+ "45.139.11.216",
+ "45.139.11.219",
+ "45.139.11.222",
+ "45.139.11.226",
+ "45.139.11.229",
+ "45.139.11.244",
+ "45.142.189.25",
+ "45.142.189.68",
+ "45.142.189.114",
+ "45.142.189.200",
+ "45.142.191.152",
+ "45.144.18.2",
+ "45.144.18.6",
+ "45.144.18.10",
+ "45.144.18.12",
+ "45.144.18.17",
+ "45.144.18.20",
+ "45.144.18.50",
+ "45.144.18.51",
+ "45.144.18.58",
+ "45.144.18.59",
+ "45.144.18.60",
+ "45.144.18.66",
+ "45.144.18.72",
+ "45.144.18.73",
+ "45.144.18.100",
+ "45.144.18.102",
+ "45.144.18.104",
+ "45.144.18.110",
+ "45.144.18.115",
+ "45.144.18.118",
+ "45.144.18.119",
+ "45.144.18.124",
+ "45.144.18.129",
+ "45.144.18.130",
+ "45.147.76.66",
+ "45.147.76.115",
+ "45.147.76.118",
+ "45.147.76.119",
+ "45.147.76.120",
+ "45.147.76.121",
+ "45.147.76.138",
+ "45.147.76.171",
+ "45.147.76.173",
+ "45.147.76.211",
+ "45.147.76.249",
+ "45.147.76.250",
+ "45.147.76.251",
+ "45.147.76.253",
+ "45.147.76.254",
+ "45.147.77.50",
+ "45.147.77.53",
+ "45.147.77.82",
+ "45.147.77.83",
+ "45.147.77.91",
+ "45.147.77.221",
+ "45.147.78.21",
+ "45.147.78.40",
+ "45.147.78.99",
+ "45.147.78.198",
+ "45.147.78.200",
+ "45.147.78.201",
+ "45.147.78.204",
+ "45.147.78.243",
+ "45.148.250.246",
+ "45.149.76.11",
+ "45.149.76.13",
+ "45.149.76.14",
+ "45.149.76.15",
+ "45.149.76.16",
+ "45.149.76.17",
+ "45.149.76.22",
+ "45.149.76.26",
+ "45.149.76.27",
+ "45.149.76.28",
+ "45.149.76.29",
+ "45.149.76.31",
+ "45.149.76.34",
+ "45.149.76.36",
+ "45.149.76.37",
+ "45.149.76.39",
+ "45.149.76.47",
+ "45.149.76.49",
+ "45.149.76.50",
+ "45.149.76.59",
+ "45.149.76.64",
+ "45.149.76.69",
+ "45.149.76.87",
+ "45.149.76.90",
+ "45.149.76.93",
+ "45.149.76.94",
+ "45.149.76.96",
+ "45.149.76.117",
+ "45.149.76.130",
+ "45.149.76.131",
+ "45.149.76.141",
+ "45.149.76.144",
+ "45.149.76.145",
+ "45.149.76.148",
+ "45.149.76.151",
+ "45.149.76.154",
+ "45.149.76.156",
+ "45.149.76.157",
+ "45.149.76.164",
+ "45.149.76.170",
+ "45.149.76.172",
+ "45.149.76.173",
+ "45.149.76.174",
+ "45.149.76.187",
+ "45.149.76.192",
+ "45.149.76.204",
+ "45.149.76.210",
+ "45.149.76.213",
+ "45.149.76.218",
+ "45.149.76.226",
+ "45.149.76.229",
+ "45.149.76.230",
+ "45.149.76.231",
+ "45.149.76.234",
+ "45.149.76.244",
+ "45.149.76.249",
+ "45.149.76.250",
+ "45.149.77.5",
+ "45.149.77.7",
+ "45.149.77.12",
+ "45.149.77.25",
+ "45.149.77.30",
+ "45.149.77.31",
+ "45.149.77.35",
+ "45.149.77.45",
+ "45.149.77.51",
+ "45.149.77.61",
+ "45.149.77.73",
+ "45.149.77.77",
+ "45.149.77.80",
+ "45.149.77.84",
+ "45.149.77.85",
+ "45.149.77.87",
+ "45.149.77.92",
+ "45.149.77.94",
+ "45.149.77.95",
+ "45.149.77.97",
+ "45.149.77.100",
+ "45.149.77.101",
+ "45.149.77.108",
+ "45.149.77.126",
+ "45.149.77.131",
+ "45.149.77.139",
+ "45.149.77.143",
+ "45.149.77.147",
+ "45.149.77.154",
+ "45.149.77.162",
+ "45.149.77.166",
+ "45.149.77.167",
+ "45.149.77.175",
+ "45.149.77.181",
+ "45.149.77.182",
+ "45.149.77.191",
+ "45.149.77.196",
+ "45.149.77.204",
+ "45.149.77.222",
+ "45.149.77.224",
+ "45.149.77.232",
+ "45.149.77.233",
+ "45.149.77.236",
+ "45.149.77.247",
+ "45.149.77.248",
+ "45.149.78.5",
+ "45.149.78.16",
+ "45.149.78.17",
+ "45.149.78.20",
+ "45.149.78.21",
+ "45.149.78.30",
+ "45.149.78.33",
+ "45.149.78.44",
+ "45.149.78.45",
+ "45.149.78.53",
+ "45.149.78.56",
+ "45.149.78.59",
+ "45.149.78.61",
+ "45.149.78.64",
+ "45.149.78.69",
+ "45.149.78.75",
+ "45.149.78.82",
+ "45.149.78.83",
+ "45.149.78.87",
+ "45.149.78.89",
+ "45.149.78.92",
+ "45.149.78.95",
+ "45.149.78.96",
+ "45.149.78.101",
+ "45.149.78.106",
+ "45.149.78.114",
+ "45.149.78.120",
+ "45.149.78.121",
+ "45.149.78.131",
+ "45.149.78.132",
+ "45.149.78.135",
+ "45.149.78.142",
+ "45.149.78.143",
+ "45.149.78.146",
+ "45.149.78.159",
+ "45.149.78.169",
+ "45.149.78.172",
+ "45.149.78.176",
+ "45.149.78.180",
+ "45.149.78.197",
+ "45.149.78.207",
+ "45.149.78.211",
+ "45.149.78.220",
+ "45.149.78.224",
+ "45.149.78.233",
+ "45.149.78.234",
+ "45.149.78.246",
+ "45.149.78.248",
+ "45.149.78.253",
+ "45.149.79.5",
+ "45.149.79.8",
+ "45.149.79.9",
+ "45.149.79.13",
+ "45.149.79.15",
+ "45.149.79.18",
+ "45.149.79.25",
+ "45.149.79.26",
+ "45.149.79.29",
+ "45.149.79.36",
+ "45.149.79.50",
+ "45.149.79.54",
+ "45.149.79.62",
+ "45.149.79.64",
+ "45.149.79.67",
+ "45.149.79.71",
+ "45.149.79.80",
+ "45.149.79.84",
+ "45.149.79.88",
+ "45.149.79.98",
+ "45.149.79.104",
+ "45.149.79.105",
+ "45.149.79.111",
+ "45.149.79.114",
+ "45.149.79.125",
+ "45.149.79.127",
+ "45.149.79.132",
+ "45.149.79.133",
+ "45.149.79.134",
+ "45.149.79.139",
+ "45.149.79.142",
+ "45.149.79.152",
+ "45.149.79.160",
+ "45.149.79.162",
+ "45.149.79.164",
+ "45.149.79.165",
+ "45.149.79.167",
+ "45.149.79.169",
+ "45.149.79.171",
+ "45.149.79.174",
+ "45.149.79.185",
+ "45.149.79.186",
+ "45.149.79.189",
+ "45.149.79.190",
+ "45.149.79.194",
+ "45.149.79.199",
+ "45.149.79.204",
+ "45.149.79.210",
+ "45.149.79.212",
+ "45.149.79.223",
+ "45.149.79.243",
+ "45.149.79.250",
+ "45.156.184.24",
+ "45.156.184.25",
+ "45.156.184.27",
+ "45.156.184.28",
+ "45.156.184.29",
+ "45.156.184.30",
+ "45.156.184.31",
+ "45.156.184.33",
+ "45.156.184.34",
+ "45.156.184.35",
+ "45.156.184.37",
+ "45.156.184.38",
+ "45.156.184.39",
+ "45.156.184.41",
+ "45.156.184.42",
+ "45.156.184.47",
+ "45.156.184.51",
+ "45.156.184.104",
+ "45.156.184.243",
+ "45.156.185.5",
+ "45.156.185.8",
+ "45.156.185.43",
+ "45.156.185.45",
+ "45.156.185.48",
+ "45.156.185.53",
+ "45.156.185.69",
+ "45.156.185.77",
+ "45.156.185.78",
+ "45.156.185.83",
+ "45.156.185.88",
+ "45.156.185.91",
+ "45.156.185.92",
+ "45.156.185.98",
+ "45.156.185.131",
+ "45.156.185.151",
+ "45.156.185.157",
+ "45.156.185.166",
+ "45.156.185.170",
+ "45.156.185.171",
+ "45.156.185.188",
+ "45.156.185.195",
+ "45.156.185.199",
+ "45.156.185.222",
+ "45.156.185.230",
+ "45.156.185.233",
+ "45.156.185.249",
+ "45.156.186.17",
+ "45.156.186.19",
+ "45.156.186.25",
+ "45.156.186.41",
+ "45.156.186.42",
+ "45.156.186.92",
+ "45.156.186.128",
+ "45.156.186.183",
+ "45.156.186.200",
+ "45.156.186.246",
+ "45.156.187.38",
+ "45.156.187.48",
+ "45.156.187.62",
+ "45.156.187.99",
+ "45.156.187.102",
+ "45.156.187.108",
+ "45.156.187.110",
+ "45.156.187.134",
+ "45.157.244.200",
+ "45.157.244.201",
+ "45.159.112.5",
+ "45.159.112.11",
+ "45.159.112.12",
+ "45.159.112.14",
+ "45.159.112.16",
+ "45.159.112.17",
+ "45.159.112.19",
+ "45.159.112.21",
+ "45.159.112.25",
+ "45.159.112.30",
+ "45.159.112.33",
+ "45.159.112.34",
+ "45.159.112.35",
+ "45.159.112.36",
+ "45.159.112.37",
+ "45.159.112.60",
+ "45.159.112.63",
+ "45.159.112.65",
+ "45.159.112.66",
+ "45.159.112.68",
+ "45.159.112.70",
+ "45.159.112.72",
+ "45.159.112.73",
+ "45.159.112.81",
+ "45.159.112.82",
+ "45.159.112.85",
+ "45.159.112.92",
+ "45.159.112.96",
+ "45.159.112.115",
+ "45.159.112.116",
+ "45.159.112.117",
+ "45.159.112.118",
+ "45.159.112.124",
+ "45.159.112.130",
+ "45.159.112.131",
+ "45.159.112.132",
+ "45.159.112.135",
+ "45.159.112.136",
+ "45.159.112.141",
+ "45.159.112.147",
+ "45.159.112.149",
+ "45.159.112.152",
+ "45.159.112.168",
+ "45.159.112.171",
+ "45.159.112.186",
+ "45.159.112.203",
+ "45.159.112.205",
+ "45.159.112.216",
+ "45.159.113.16",
+ "45.159.113.18",
+ "45.159.113.22",
+ "45.159.113.39",
+ "45.159.113.41",
+ "45.159.113.51",
+ "45.159.113.64",
+ "45.159.113.66",
+ "45.159.113.67",
+ "45.159.113.72",
+ "45.159.113.88",
+ "45.159.113.91",
+ "45.159.113.98",
+ "45.159.113.101",
+ "45.159.113.102",
+ "45.159.113.103",
+ "45.159.113.106",
+ "45.159.113.108",
+ "45.159.113.110",
+ "45.159.113.111",
+ "45.159.113.116",
+ "45.159.113.117",
+ "45.159.113.118",
+ "45.159.113.119",
+ "45.159.113.121",
+ "45.159.113.123",
+ "45.159.113.124",
+ "45.159.113.126",
+ "45.159.113.128",
+ "45.159.113.129",
+ "45.159.113.133",
+ "45.159.113.134",
+ "45.159.113.135",
+ "45.159.113.137",
+ "45.159.113.146",
+ "45.159.113.149",
+ "45.159.113.154",
+ "45.159.113.157",
+ "45.159.113.160",
+ "45.159.113.163",
+ "45.159.113.171",
+ "45.159.113.194",
+ "45.159.113.200",
+ "45.159.113.202",
+ "45.159.113.203",
+ "45.159.113.204",
+ "45.159.113.206",
+ "45.159.113.208",
+ "45.159.113.211",
+ "45.159.113.216",
+ "45.159.113.224",
+ "45.159.113.225",
+ "45.159.113.228",
+ "45.159.113.236",
+ "45.159.113.249",
+ "45.159.114.211",
+ "45.159.114.213",
+ "45.159.114.215",
+ "45.159.114.219",
+ "45.159.114.220",
+ "45.159.114.227",
+ "45.159.114.229",
+ "45.159.114.230",
+ "45.159.114.231",
+ "45.159.114.232",
+ "45.159.114.239",
+ "45.159.114.241",
+ "45.159.114.251",
+ "45.159.115.7",
+ "45.159.115.10",
+ "45.159.115.11",
+ "45.159.115.12",
+ "45.159.115.14",
+ "45.159.115.15",
+ "45.159.115.21",
+ "45.159.115.32",
+ "45.159.115.38",
+ "45.159.115.39",
+ "45.159.115.40",
+ "45.159.115.44",
+ "45.159.115.51",
+ "45.159.115.52",
+ "45.159.115.68",
+ "45.159.115.79",
+ "45.159.115.81",
+ "45.159.115.86",
+ "45.159.115.88",
+ "45.159.115.90",
+ "45.159.115.91",
+ "45.159.115.92",
+ "45.159.115.93",
+ "45.159.115.98",
+ "45.159.115.100",
+ "45.159.115.101",
+ "45.159.115.103",
+ "45.159.115.105",
+ "45.159.115.107",
+ "45.159.115.108",
+ "45.159.115.109",
+ "45.159.115.110",
+ "45.159.115.112",
+ "45.159.115.114",
+ "45.159.115.115",
+ "45.159.115.116",
+ "45.159.115.118",
+ "45.159.115.120",
+ "45.159.115.123",
+ "45.159.115.124",
+ "45.159.115.126",
+ "45.159.115.128",
+ "45.159.115.130",
+ "45.159.115.136",
+ "45.159.115.137",
+ "45.159.115.138",
+ "45.159.115.139",
+ "45.159.115.141",
+ "45.159.115.142",
+ "45.159.115.146",
+ "45.159.115.147",
+ "45.159.115.149",
+ "45.159.115.154",
+ "45.159.115.156",
+ "45.159.115.157",
+ "45.159.115.158",
+ "45.159.115.159",
+ "45.159.115.162",
+ "45.159.115.163",
+ "45.159.115.165",
+ "45.159.115.170",
+ "45.159.115.173",
+ "45.159.115.174",
+ "45.159.115.175",
+ "45.159.115.179",
+ "45.159.115.180",
+ "45.159.115.181",
+ "45.159.115.183",
+ "45.159.115.185",
+ "45.159.115.186",
+ "45.159.115.188",
+ "45.159.115.190",
+ "45.159.115.197",
+ "45.159.115.200",
+ "45.159.115.205",
+ "45.159.115.215",
+ "45.159.115.218",
+ "45.159.115.230",
+ "45.159.115.231",
+ "45.159.115.232",
+ "45.159.115.234",
+ "45.159.115.238",
+ "45.159.149.5",
+ "45.159.149.6",
+ "45.159.149.7",
+ "45.159.149.8",
+ "45.159.149.13",
+ "45.159.149.15",
+ "45.159.149.17",
+ "45.159.149.19",
+ "45.159.149.25",
+ "45.159.149.29",
+ "45.159.149.31",
+ "45.159.149.42",
+ "45.159.149.52",
+ "45.159.149.55",
+ "45.159.149.63",
+ "45.159.149.64",
+ "45.159.149.70",
+ "45.159.149.79",
+ "45.159.149.83",
+ "45.159.149.89",
+ "45.159.149.91",
+ "45.159.149.92",
+ "45.159.149.95",
+ "45.159.149.101",
+ "45.159.149.105",
+ "45.159.149.109",
+ "45.159.149.125",
+ "45.159.149.127",
+ "45.159.149.135",
+ "45.159.149.146",
+ "45.159.149.147",
+ "45.159.149.154",
+ "45.159.149.160",
+ "45.159.149.165",
+ "45.159.149.172",
+ "45.159.149.180",
+ "45.159.149.186",
+ "45.159.149.209",
+ "45.159.149.211",
+ "45.159.149.215",
+ "45.159.149.217",
+ "45.159.149.232",
+ "45.159.149.252",
+ "45.159.149.253",
+ "45.159.150.5",
+ "45.159.150.12",
+ "45.159.150.14",
+ "45.159.150.20",
+ "45.159.150.26",
+ "45.159.150.27",
+ "45.159.150.41",
+ "45.159.150.53",
+ "45.159.150.69",
+ "45.159.150.75",
+ "45.159.150.78",
+ "45.159.150.88",
+ "45.159.150.89",
+ "45.159.150.100",
+ "45.159.150.107",
+ "45.159.150.115",
+ "45.159.150.129",
+ "45.159.150.133",
+ "45.159.150.136",
+ "45.159.150.142",
+ "45.159.150.146",
+ "45.159.150.152",
+ "45.159.150.166",
+ "45.159.150.173",
+ "45.159.150.179",
+ "45.159.150.181",
+ "45.159.150.184",
+ "45.159.150.194",
+ "45.159.150.204",
+ "45.159.150.221",
+ "45.159.150.222",
+ "45.159.150.223",
+ "45.159.150.224",
+ "45.159.150.231",
+ "45.159.150.242",
+ "45.159.150.244",
+ "45.159.150.245",
+ "45.159.151.8",
+ "45.159.151.25",
+ "45.159.151.33",
+ "45.159.151.34",
+ "45.159.151.35",
+ "45.159.151.42",
+ "45.159.151.44",
+ "45.159.151.48",
+ "45.159.151.53",
+ "45.159.151.55",
+ "45.159.151.56",
+ "45.159.151.58",
+ "45.159.151.59",
+ "45.159.151.61",
+ "45.159.151.63",
+ "45.159.151.64",
+ "45.159.151.65",
+ "45.159.151.66",
+ "45.159.151.67",
+ "45.159.151.70",
+ "45.159.151.71",
+ "45.159.151.73",
+ "45.159.151.74",
+ "45.159.151.75",
+ "45.159.151.76",
+ "45.159.151.77",
+ "45.159.151.78",
+ "45.159.151.79",
+ "45.159.151.80",
+ "45.159.151.81",
+ "45.159.151.82",
+ "45.159.151.84",
+ "45.159.151.85",
+ "45.159.151.86",
+ "45.159.151.87",
+ "45.159.151.88",
+ "45.159.151.89",
+ "45.159.151.90",
+ "45.159.151.91",
+ "45.159.151.92",
+ "45.159.151.93",
+ "45.159.151.94",
+ "45.159.151.95",
+ "45.159.151.99",
+ "45.159.151.100",
+ "45.159.151.101",
+ "45.159.151.102",
+ "45.159.151.109",
+ "45.159.151.110",
+ "45.159.151.111",
+ "45.159.151.112",
+ "45.159.151.113",
+ "45.159.151.114",
+ "45.159.151.115",
+ "45.159.151.116",
+ "45.159.151.117",
+ "45.159.151.118",
+ "45.159.151.119",
+ "45.159.151.120",
+ "45.159.151.121",
+ "45.159.151.122",
+ "45.159.151.123",
+ "45.159.151.124",
+ "45.159.151.125",
+ "45.159.151.126",
+ "45.159.151.129",
+ "45.159.151.133",
+ "45.159.151.134",
+ "45.159.151.135",
+ "45.159.151.136",
+ "45.159.151.138",
+ "45.159.151.145",
+ "45.159.151.146",
+ "45.159.151.147",
+ "45.159.151.149",
+ "45.159.151.150",
+ "45.159.151.151",
+ "45.159.151.152",
+ "45.159.151.154",
+ "45.159.151.155",
+ "45.159.151.156",
+ "45.159.151.158",
+ "45.159.151.159",
+ "45.159.151.160",
+ "45.159.151.161",
+ "45.159.151.162",
+ "45.159.151.163",
+ "45.159.151.164",
+ "45.159.151.165",
+ "45.159.151.166",
+ "45.159.151.167",
+ "45.159.151.168",
+ "45.159.151.170",
+ "45.159.151.171",
+ "45.159.196.5",
+ "45.159.197.66",
+ "45.159.197.99",
+ "45.159.197.139",
+ "45.159.197.141",
+ "45.159.198.4",
+ "45.159.198.5",
+ "45.159.198.9",
+ "45.159.198.10",
+ "45.159.198.182",
+ "45.159.198.251",
+ "45.159.199.130",
+ "46.18.248.136",
+ "46.28.74.35",
+ "46.28.78.11",
+ "46.28.78.12",
+ "46.32.4.137",
+ "46.32.4.165",
+ "46.32.4.244",
+ "46.32.10.50",
+ "46.32.11.130",
+ "46.32.11.131",
+ "46.32.12.72",
+ "46.32.15.196",
+ "46.32.16.68",
+ "46.32.17.68",
+ "46.32.17.70",
+ "46.32.26.18",
+ "46.32.30.74",
+ "46.32.30.81",
+ "46.32.31.29",
+ "46.32.31.30",
+ "46.34.160.41",
+ "46.34.160.56",
+ "46.34.162.76",
+ "46.34.163.85",
+ "46.34.165.1",
+ "46.34.166.60",
+ "46.34.166.210",
+ "46.34.167.120",
+ "46.36.96.1",
+ "46.36.96.65",
+ "46.36.96.66",
+ "46.36.107.98",
+ "46.36.107.99",
+ "46.36.111.2",
+ "46.36.111.3",
+ "46.38.138.47",
+ "46.38.138.84",
+ "46.38.138.89",
+ "46.38.138.92",
+ "46.38.138.156",
+ "46.38.138.168",
+ "46.38.142.66",
+ "46.38.146.131",
+ "46.38.146.163",
+ "46.38.147.10",
+ "46.38.150.195",
+ "46.38.150.243",
+ "46.38.159.21",
+ "46.38.159.23",
+ "46.100.5.49",
+ "46.100.8.21",
+ "46.100.10.64",
+ "46.100.12.158",
+ "46.100.12.255",
+ "46.100.13.60",
+ "46.100.41.110",
+ "46.100.41.240",
+ "46.100.45.147",
+ "46.100.47.154",
+ "46.100.48.239",
+ "46.100.58.214",
+ "46.100.63.131",
+ "46.100.74.83",
+ "46.100.84.60",
+ "46.100.85.5",
+ "46.100.90.13",
+ "46.100.90.93",
+ "46.100.90.166",
+ "46.100.95.206",
+ "46.100.166.125",
+ "46.100.167.215",
+ "46.100.167.222",
+ "46.100.177.148",
+ "46.100.218.22",
+ "46.100.249.63",
+ "46.100.249.195",
+ "46.102.129.202",
+ "46.102.129.203",
+ "46.102.130.2",
+ "46.102.130.31",
+ "46.102.130.116",
+ "46.102.130.165",
+ "46.102.130.166",
+ "46.102.130.215",
+ "46.102.130.229",
+ "46.102.132.112",
+ "46.102.136.2",
+ "46.102.136.33",
+ "46.102.136.34",
+ "46.102.136.35",
+ "46.102.136.36",
+ "46.102.136.75",
+ "46.102.136.77",
+ "46.102.136.89",
+ "46.102.136.93",
+ "46.102.137.18",
+ "46.102.138.219",
+ "46.102.138.222",
+ "46.102.139.45",
+ "46.102.139.66",
+ "46.102.139.67",
+ "46.102.139.68",
+ "46.102.139.69",
+ "46.102.139.70",
+ "46.102.139.98",
+ "46.102.139.118",
+ "46.102.140.16",
+ "46.102.140.45",
+ "46.102.141.156",
+ "46.148.34.202",
+ "46.148.35.162",
+ "46.148.35.163",
+ "46.148.36.9",
+ "46.148.41.47",
+ "46.148.47.1",
+ "46.148.47.27",
+ "46.167.135.183",
+ "46.167.139.74",
+ "46.167.139.125",
+ "46.167.141.33",
+ "46.167.141.196",
+ "46.167.144.175",
+ "46.167.146.37",
+ "46.167.146.174",
+ "46.167.146.202",
+ "46.167.146.231",
+ "46.167.158.79",
+ "46.167.159.116",
+ "46.209.7.114",
+ "46.209.7.115",
+ "46.209.7.116",
+ "46.209.7.136",
+ "46.209.9.178",
+ "46.209.11.8",
+ "46.209.11.30",
+ "46.209.16.181",
+ "46.209.20.86",
+ "46.209.20.154",
+ "46.209.20.181",
+ "46.209.22.219",
+ "46.209.25.195",
+ "46.209.30.13",
+ "46.209.31.248",
+ "46.209.44.74",
+ "46.209.50.15",
+ "46.209.50.133",
+ "46.209.59.66",
+ "46.209.59.67",
+ "46.209.62.250",
+ "46.209.67.150",
+ "46.209.69.121",
+ "46.209.69.123",
+ "46.209.73.211",
+ "46.209.89.19",
+ "46.209.92.54",
+ "46.209.92.147",
+ "46.209.115.6",
+ "46.209.128.217",
+ "46.209.150.220",
+ "46.209.157.179",
+ "46.209.191.3",
+ "46.209.191.4",
+ "46.209.206.205",
+ "46.209.207.153",
+ "46.209.207.154",
+ "46.209.207.202",
+ "46.209.207.203",
+ "46.209.209.209",
+ "46.209.211.13",
+ "46.209.213.114",
+ "46.209.216.247",
+ "46.209.221.92",
+ "46.209.239.189",
+ "46.209.239.190",
+ "46.209.240.130",
+ "46.209.241.66",
+ "46.209.244.246",
+ "46.209.251.12",
+ "46.235.77.195",
+ "46.245.0.105",
+ "46.245.4.205",
+ "46.245.5.30",
+ "46.245.6.140",
+ "46.245.8.140",
+ "46.245.13.16",
+ "46.245.16.181",
+ "46.245.17.163",
+ "46.245.24.138",
+ "46.245.28.206",
+ "46.245.34.157",
+ "46.245.38.100",
+ "46.245.38.101",
+ "46.245.39.140",
+ "46.245.39.163",
+ "46.245.43.60",
+ "46.245.43.87",
+ "46.245.45.87",
+ "46.245.45.174",
+ "46.245.64.24",
+ "46.245.64.36",
+ "46.245.64.37",
+ "46.245.64.38",
+ "46.245.64.55",
+ "46.245.64.132",
+ "46.245.66.13",
+ "46.245.66.26",
+ "46.245.66.61",
+ "46.245.66.72",
+ "46.245.66.91",
+ "46.245.66.120",
+ "46.245.66.137",
+ "46.245.67.36",
+ "46.245.67.101",
+ "46.245.67.141",
+ "46.245.67.162",
+ "46.245.68.169",
+ "46.245.69.35",
+ "46.245.69.94",
+ "46.245.69.109",
+ "46.245.69.110",
+ "46.245.69.133",
+ "46.245.69.134",
+ "46.245.69.135",
+ "46.245.69.215",
+ "46.245.69.222",
+ "46.245.69.229",
+ "46.245.69.234",
+ "46.245.72.183",
+ "46.245.73.17",
+ "46.245.73.26",
+ "46.245.76.4",
+ "46.245.76.5",
+ "46.245.76.6",
+ "46.245.76.7",
+ "46.245.76.8",
+ "46.245.76.9",
+ "46.245.76.10",
+ "46.245.76.11",
+ "46.245.76.12",
+ "46.245.76.13",
+ "46.245.76.14",
+ "46.245.76.28",
+ "46.245.76.29",
+ "46.245.76.50",
+ "46.245.76.51",
+ "46.245.76.52",
+ "46.245.76.53",
+ "46.245.76.54",
+ "46.245.76.116",
+ "46.245.76.162",
+ "46.245.76.171",
+ "46.245.76.172",
+ "46.245.76.173",
+ "46.245.76.174",
+ "46.245.77.7",
+ "46.245.77.8",
+ "46.245.77.70",
+ "46.245.77.75",
+ "46.245.77.76",
+ "46.245.77.77",
+ "46.245.77.78",
+ "46.245.78.18",
+ "46.245.78.19",
+ "46.245.78.227",
+ "46.245.79.11",
+ "46.245.79.134",
+ "46.245.79.135",
+ "46.245.79.136",
+ "46.245.79.137",
+ "46.245.79.235",
+ "46.245.80.35",
+ "46.245.80.75",
+ "46.245.80.77",
+ "46.245.80.82",
+ "46.245.80.206",
+ "46.245.81.54",
+ "46.245.81.61",
+ "46.245.81.68",
+ "46.245.81.90",
+ "46.245.83.130",
+ "46.245.84.44",
+ "46.245.85.3",
+ "46.245.85.22",
+ "46.245.85.27",
+ "46.245.85.28",
+ "46.245.85.29",
+ "46.245.85.36",
+ "46.245.85.37",
+ "46.245.85.44",
+ "46.245.85.179",
+ "46.245.86.26",
+ "46.245.86.28",
+ "46.245.86.29",
+ "46.245.86.30",
+ "46.245.86.177",
+ "46.245.86.186",
+ "46.245.86.190",
+ "46.245.86.242",
+ "46.245.86.245",
+ "46.245.87.68",
+ "46.245.87.69",
+ "46.245.87.72",
+ "46.245.87.74",
+ "46.245.87.75",
+ "46.245.87.105",
+ "46.245.87.110",
+ "46.245.87.132",
+ "46.245.87.222",
+ "46.245.88.170",
+ "46.245.88.171",
+ "46.245.88.172",
+ "46.245.88.173",
+ "46.245.88.174",
+ "46.245.89.100",
+ "46.245.89.130",
+ "46.245.89.131",
+ "46.245.89.133",
+ "46.245.89.136",
+ "46.245.89.138",
+ "46.245.89.141",
+ "46.245.89.203",
+ "46.245.91.214",
+ "46.245.91.227",
+ "46.245.91.228",
+ "46.245.91.229",
+ "46.245.91.231",
+ "46.245.91.233",
+ "46.245.91.237",
+ "46.245.91.238",
+ "46.245.91.245",
+ "46.245.92.2",
+ "46.245.92.58",
+ "46.245.92.85",
+ "46.245.92.86",
+ "46.245.92.107",
+ "46.245.92.108",
+ "46.245.92.109",
+ "46.245.92.116",
+ "46.245.92.185",
+ "46.245.93.42",
+ "46.245.93.115",
+ "46.245.93.201",
+ "46.245.93.202",
+ "46.245.93.209",
+ "46.245.94.109",
+ "46.245.94.163",
+ "46.245.94.170",
+ "46.245.94.171",
+ "46.245.94.172",
+ "46.245.95.99",
+ "46.245.95.133",
+ "46.245.95.136",
+ "46.245.95.152",
+ "46.245.95.160",
+ "46.245.95.162",
+ "46.245.95.165",
+ "46.245.95.237",
+ "46.245.96.216",
+ "46.245.98.13",
+ "46.245.99.40",
+ "46.245.99.142",
+ "46.245.100.90",
+ "46.245.107.28",
+ "46.245.107.29",
+ "46.245.107.164",
+ "46.245.107.195",
+ "46.245.107.198",
+ "46.245.107.199",
+ "46.245.107.201",
+ "46.245.107.202",
+ "46.245.107.205",
+ "46.245.112.61",
+ "46.245.114.228",
+ "46.245.115.51",
+ "46.245.115.56",
+ "46.245.115.201",
+ "46.245.115.213",
+ "46.245.120.150",
+ "46.245.122.8",
+ "46.245.122.24",
+ "46.245.122.25",
+ "46.245.123.19",
+ "46.245.123.20",
+ "46.245.123.21",
+ "46.245.123.23",
+ "46.245.123.25",
+ "46.245.124.20",
+ "46.245.124.48",
+ "46.249.122.162",
+ "46.249.125.22",
+ "62.3.14.59",
+ "62.3.14.68",
+ "62.3.14.132",
+ "62.3.14.133",
+ "62.3.14.134",
+ "62.3.14.135",
+ "62.3.14.140",
+ "62.3.14.153",
+ "62.3.14.154",
+ "62.3.14.162",
+ "62.3.14.163",
+ "62.3.14.164",
+ "62.3.14.167",
+ "62.3.14.168",
+ "62.3.14.169",
+ "62.3.14.203",
+ "62.3.14.204",
+ "62.3.14.205",
+ "62.3.41.8",
+ "62.3.41.9",
+ "62.3.41.28",
+ "62.3.41.32",
+ "62.3.41.36",
+ "62.3.41.45",
+ "62.3.41.47",
+ "62.3.41.50",
+ "62.3.41.53",
+ "62.3.41.66",
+ "62.3.41.73",
+ "62.3.41.77",
+ "62.3.41.82",
+ "62.3.41.87",
+ "62.3.41.89",
+ "62.3.41.92",
+ "62.3.41.111",
+ "62.3.41.114",
+ "62.3.41.117",
+ "62.3.41.122",
+ "62.3.41.129",
+ "62.3.41.132",
+ "62.3.41.135",
+ "62.3.41.149",
+ "62.3.41.159",
+ "62.3.41.160",
+ "62.3.41.178",
+ "62.3.41.179",
+ "62.3.41.191",
+ "62.3.41.194",
+ "62.3.41.198",
+ "62.3.41.199",
+ "62.3.41.200",
+ "62.3.41.210",
+ "62.3.41.215",
+ "62.3.41.226",
+ "62.3.41.227",
+ "62.3.41.228",
+ "62.3.41.229",
+ "62.3.41.233",
+ "62.3.41.237",
+ "62.3.41.242",
+ "62.3.41.253",
+ "62.3.42.17",
+ "62.3.42.32",
+ "62.3.42.34",
+ "62.3.42.47",
+ "62.3.42.59",
+ "62.3.42.85",
+ "62.3.42.90",
+ "62.3.42.99",
+ "62.3.42.105",
+ "62.3.42.106",
+ "62.3.42.111",
+ "62.3.42.119",
+ "62.3.42.126",
+ "62.3.42.131",
+ "62.3.42.134",
+ "62.3.42.137",
+ "62.3.42.139",
+ "62.3.42.145",
+ "62.3.42.171",
+ "62.3.42.176",
+ "62.3.42.187",
+ "62.3.42.198",
+ "62.3.42.206",
+ "62.3.42.215",
+ "62.3.42.237",
+ "62.3.42.238",
+ "62.60.128.8",
+ "62.60.128.11",
+ "62.60.128.42",
+ "62.60.128.49",
+ "62.60.128.54",
+ "62.60.128.56",
+ "62.60.128.58",
+ "62.60.128.59",
+ "62.60.128.89",
+ "62.60.128.105",
+ "62.60.128.119",
+ "62.60.128.120",
+ "62.60.128.122",
+ "62.60.128.124",
+ "62.60.128.125",
+ "62.60.128.126",
+ "62.60.128.127",
+ "62.60.128.209",
+ "62.60.129.186",
+ "62.60.129.189",
+ "62.60.132.61",
+ "62.60.132.133",
+ "62.60.132.174",
+ "62.60.132.248",
+ "62.60.133.4",
+ "62.60.133.5",
+ "62.60.133.6",
+ "62.60.133.7",
+ "62.60.133.9",
+ "62.60.133.10",
+ "62.60.133.11",
+ "62.60.133.12",
+ "62.60.133.13",
+ "62.60.133.14",
+ "62.60.133.15",
+ "62.60.133.16",
+ "62.60.133.17",
+ "62.60.133.18",
+ "62.60.133.19",
+ "62.60.133.20",
+ "62.60.133.22",
+ "62.60.133.23",
+ "62.60.133.24",
+ "62.60.133.25",
+ "62.60.133.26",
+ "62.60.133.27",
+ "62.60.133.29",
+ "62.60.133.30",
+ "62.60.133.31",
+ "62.60.133.32",
+ "62.60.133.33",
+ "62.60.133.34",
+ "62.60.133.36",
+ "62.60.133.37",
+ "62.60.133.38",
+ "62.60.133.39",
+ "62.60.133.40",
+ "62.60.133.41",
+ "62.60.133.42",
+ "62.60.133.43",
+ "62.60.133.44",
+ "62.60.133.45",
+ "62.60.133.47",
+ "62.60.133.48",
+ "62.60.133.49",
+ "62.60.133.50",
+ "62.60.133.51",
+ "62.60.133.52",
+ "62.60.133.53",
+ "62.60.133.54",
+ "62.60.133.55",
+ "62.60.133.56",
+ "62.60.133.58",
+ "62.60.133.59",
+ "62.60.133.61",
+ "62.60.133.62",
+ "62.60.133.63",
+ "62.60.133.64",
+ "62.60.133.65",
+ "62.60.133.66",
+ "62.60.133.67",
+ "62.60.133.68",
+ "62.60.133.69",
+ "62.60.133.70",
+ "62.60.133.71",
+ "62.60.133.72",
+ "62.60.133.73",
+ "62.60.133.74",
+ "62.60.133.75",
+ "62.60.133.76",
+ "62.60.133.77",
+ "62.60.133.78",
+ "62.60.133.79",
+ "62.60.133.80",
+ "62.60.133.83",
+ "62.60.133.84",
+ "62.60.133.85",
+ "62.60.133.86",
+ "62.60.133.87",
+ "62.60.133.88",
+ "62.60.133.89",
+ "62.60.133.90",
+ "62.60.133.91",
+ "62.60.133.92",
+ "62.60.133.93",
+ "62.60.133.94",
+ "62.60.133.95",
+ "62.60.133.96",
+ "62.60.133.97",
+ "62.60.133.98",
+ "62.60.133.99",
+ "62.60.133.100",
+ "62.60.133.102",
+ "62.60.133.103",
+ "62.60.133.104",
+ "62.60.133.105",
+ "62.60.133.106",
+ "62.60.133.107",
+ "62.60.133.109",
+ "62.60.133.110",
+ "62.60.133.111",
+ "62.60.133.112",
+ "62.60.133.113",
+ "62.60.133.114",
+ "62.60.133.115",
+ "62.60.133.116",
+ "62.60.133.117",
+ "62.60.133.118",
+ "62.60.133.119",
+ "62.60.133.120",
+ "62.60.133.121",
+ "62.60.133.122",
+ "62.60.133.123",
+ "62.60.133.124",
+ "62.60.133.125",
+ "62.60.133.126",
+ "62.60.133.127",
+ "62.60.133.128",
+ "62.60.133.130",
+ "62.60.133.131",
+ "62.60.133.132",
+ "62.60.133.133",
+ "62.60.133.134",
+ "62.60.133.135",
+ "62.60.133.136",
+ "62.60.133.137",
+ "62.60.133.138",
+ "62.60.133.139",
+ "62.60.133.140",
+ "62.60.133.141",
+ "62.60.133.142",
+ "62.60.133.143",
+ "62.60.133.144",
+ "62.60.133.145",
+ "62.60.133.146",
+ "62.60.133.147",
+ "62.60.133.148",
+ "62.60.133.149",
+ "62.60.133.150",
+ "62.60.133.152",
+ "62.60.133.153",
+ "62.60.133.154",
+ "62.60.133.155",
+ "62.60.133.156",
+ "62.60.133.157",
+ "62.60.133.158",
+ "62.60.133.159",
+ "62.60.133.160",
+ "62.60.133.161",
+ "62.60.133.162",
+ "62.60.133.163",
+ "62.60.133.164",
+ "62.60.133.165",
+ "62.60.133.166",
+ "62.60.133.167",
+ "62.60.133.168",
+ "62.60.133.169",
+ "62.60.133.170",
+ "62.60.133.171",
+ "62.60.133.172",
+ "62.60.133.173",
+ "62.60.133.174",
+ "62.60.133.175",
+ "62.60.133.176",
+ "62.60.133.177",
+ "62.60.133.178",
+ "62.60.133.179",
+ "62.60.133.180",
+ "62.60.133.181",
+ "62.60.133.182",
+ "62.60.133.183",
+ "62.60.133.184",
+ "62.60.133.185",
+ "62.60.133.186",
+ "62.60.133.187",
+ "62.60.133.188",
+ "62.60.133.189",
+ "62.60.133.190",
+ "62.60.133.191",
+ "62.60.133.192",
+ "62.60.133.194",
+ "62.60.133.195",
+ "62.60.133.196",
+ "62.60.133.197",
+ "62.60.133.198",
+ "62.60.133.201",
+ "62.60.133.202",
+ "62.60.133.203",
+ "62.60.133.205",
+ "62.60.133.207",
+ "62.60.133.208",
+ "62.60.133.209",
+ "62.60.133.210",
+ "62.60.133.228",
+ "62.60.133.238",
+ "62.60.133.243",
+ "62.60.133.245",
+ "62.60.133.246",
+ "62.60.133.247",
+ "62.60.133.249",
+ "62.60.133.250",
+ "62.60.133.251",
+ "62.60.133.252",
+ "62.60.133.253",
+ "62.60.133.254",
+ "62.60.136.105",
+ "62.60.136.158",
+ "62.60.136.190",
+ "62.60.136.215",
+ "62.60.136.225",
+ "62.60.137.2",
+ "62.60.140.47",
+ "62.60.140.251",
+ "62.60.141.4",
+ "62.60.144.44",
+ "62.60.144.45",
+ "62.60.144.68",
+ "62.60.144.85",
+ "62.60.144.87",
+ "62.60.160.28",
+ "62.60.160.33",
+ "62.60.160.34",
+ "62.60.160.38",
+ "62.60.160.40",
+ "62.60.160.75",
+ "62.60.160.79",
+ "62.60.160.80",
+ "62.60.160.100",
+ "62.60.161.109",
+ "62.60.161.115",
+ "62.60.162.96",
+ "62.60.162.100",
+ "62.60.162.102",
+ "62.60.162.104",
+ "62.60.162.109",
+ "62.60.162.110",
+ "62.60.162.206",
+ "62.60.162.247",
+ "62.60.163.203",
+ "62.60.164.19",
+ "62.60.164.32",
+ "62.60.164.43",
+ "62.60.164.49",
+ "62.60.164.133",
+ "62.60.164.137",
+ "62.60.164.158",
+ "62.60.164.191",
+ "62.60.164.197",
+ "62.60.164.198",
+ "62.60.164.206",
+ "62.60.164.207",
+ "62.60.164.214",
+ "62.60.164.216",
+ "62.60.164.217",
+ "62.60.164.219",
+ "62.60.164.242",
+ "62.60.165.23",
+ "62.60.165.151",
+ "62.60.165.203",
+ "62.60.165.216",
+ "62.60.165.219",
+ "62.60.165.230",
+ "62.60.165.233",
+ "62.60.165.236",
+ "62.60.165.239",
+ "62.60.165.241",
+ "62.60.165.246",
+ "62.60.165.248",
+ "62.60.166.50",
+ "62.60.167.38",
+ "62.60.167.66",
+ "62.60.167.67",
+ "62.60.167.68",
+ "62.60.167.69",
+ "62.60.167.74",
+ "62.60.167.194",
+ "62.60.167.202",
+ "62.60.167.203",
+ "62.60.167.204",
+ "62.60.167.205",
+ "62.60.167.206",
+ "62.60.167.210",
+ "62.60.167.234",
+ "62.60.167.242",
+ "62.60.167.250",
+ "62.60.190.61",
+ "62.60.196.13",
+ "62.60.196.26",
+ "62.60.196.44",
+ "62.60.196.235",
+ "62.60.196.238",
+ "62.60.197.3",
+ "62.60.197.4",
+ "62.60.197.5",
+ "62.60.197.6",
+ "62.60.197.7",
+ "62.60.197.8",
+ "62.60.197.9",
+ "62.60.197.10",
+ "62.60.197.12",
+ "62.60.197.14",
+ "62.60.197.83",
+ "62.60.197.85",
+ "62.60.197.222",
+ "62.60.198.38",
+ "62.60.198.239",
+ "62.60.200.93",
+ "62.60.200.94",
+ "62.60.200.118",
+ "62.60.200.131",
+ "62.60.200.144",
+ "62.60.200.196",
+ "62.60.200.197",
+ "62.60.200.203",
+ "62.60.200.214",
+ "62.60.200.252",
+ "62.60.201.3",
+ "62.60.201.4",
+ "62.60.201.5",
+ "62.60.201.6",
+ "62.60.201.7",
+ "62.60.201.8",
+ "62.60.201.9",
+ "62.60.201.10",
+ "62.60.201.12",
+ "62.60.201.13",
+ "62.60.201.14",
+ "62.60.201.15",
+ "62.60.201.16",
+ "62.60.201.17",
+ "62.60.201.18",
+ "62.60.201.20",
+ "62.60.201.21",
+ "62.60.201.22",
+ "62.60.201.24",
+ "62.60.201.25",
+ "62.60.201.26",
+ "62.60.201.27",
+ "62.60.201.28",
+ "62.60.201.29",
+ "62.60.201.30",
+ "62.60.201.31",
+ "62.60.201.32",
+ "62.60.201.33",
+ "62.60.201.34",
+ "62.60.201.62",
+ "62.60.201.63",
+ "62.60.201.64",
+ "62.60.201.65",
+ "62.60.201.66",
+ "62.60.201.67",
+ "62.60.201.68",
+ "62.60.201.69",
+ "62.60.201.70",
+ "62.60.201.71",
+ "62.60.201.72",
+ "62.60.201.73",
+ "62.60.201.74",
+ "62.60.201.75",
+ "62.60.201.76",
+ "62.60.201.77",
+ "62.60.201.78",
+ "62.60.201.79",
+ "62.60.201.80",
+ "62.60.201.81",
+ "62.60.201.82",
+ "62.60.201.83",
+ "62.60.201.84",
+ "62.60.201.85",
+ "62.60.201.86",
+ "62.60.201.87",
+ "62.60.201.88",
+ "62.60.201.89",
+ "62.60.201.90",
+ "62.60.201.92",
+ "62.60.201.93",
+ "62.60.201.94",
+ "62.60.201.95",
+ "62.60.201.97",
+ "62.60.201.99",
+ "62.60.201.100",
+ "62.60.201.102",
+ "62.60.201.103",
+ "62.60.201.104",
+ "62.60.201.105",
+ "62.60.201.106",
+ "62.60.201.107",
+ "62.60.201.108",
+ "62.60.201.109",
+ "62.60.201.110",
+ "62.60.201.111",
+ "62.60.201.112",
+ "62.60.201.113",
+ "62.60.201.115",
+ "62.60.201.116",
+ "62.60.201.117",
+ "62.60.201.118",
+ "62.60.201.119",
+ "62.60.201.120",
+ "62.60.201.121",
+ "62.60.201.122",
+ "62.60.201.123",
+ "62.60.201.124",
+ "62.60.201.125",
+ "62.60.201.126",
+ "62.60.201.127",
+ "62.60.201.128",
+ "62.60.201.130",
+ "62.60.201.131",
+ "62.60.201.132",
+ "62.60.201.133",
+ "62.60.201.134",
+ "62.60.201.135",
+ "62.60.201.136",
+ "62.60.201.137",
+ "62.60.201.138",
+ "62.60.201.139",
+ "62.60.201.140",
+ "62.60.201.141",
+ "62.60.201.142",
+ "62.60.201.143",
+ "62.60.201.144",
+ "62.60.201.145",
+ "62.60.201.146",
+ "62.60.201.147",
+ "62.60.201.148",
+ "62.60.201.149",
+ "62.60.201.151",
+ "62.60.201.152",
+ "62.60.201.153",
+ "62.60.201.154",
+ "62.60.201.155",
+ "62.60.201.156",
+ "62.60.201.157",
+ "62.60.201.158",
+ "62.60.201.159",
+ "62.60.201.160",
+ "62.60.201.162",
+ "62.60.201.163",
+ "62.60.201.164",
+ "62.60.201.165",
+ "62.60.201.166",
+ "62.60.201.167",
+ "62.60.201.168",
+ "62.60.201.169",
+ "62.60.201.170",
+ "62.60.201.171",
+ "62.60.201.173",
+ "62.60.201.174",
+ "62.60.201.175",
+ "62.60.201.176",
+ "62.60.201.177",
+ "62.60.201.180",
+ "62.60.201.182",
+ "62.60.201.183",
+ "62.60.201.184",
+ "62.60.201.185",
+ "62.60.201.186",
+ "62.60.201.187",
+ "62.60.201.189",
+ "62.60.201.190",
+ "62.60.201.191",
+ "62.60.201.192",
+ "62.60.201.193",
+ "62.60.201.194",
+ "62.60.201.196",
+ "62.60.201.197",
+ "62.60.201.198",
+ "62.60.201.199",
+ "62.60.201.200",
+ "62.60.201.201",
+ "62.60.201.203",
+ "62.60.201.204",
+ "62.60.201.205",
+ "62.60.201.206",
+ "62.60.201.207",
+ "62.60.201.208",
+ "62.60.201.209",
+ "62.60.201.210",
+ "62.60.201.211",
+ "62.60.201.212",
+ "62.60.201.213",
+ "62.60.201.214",
+ "62.60.201.215",
+ "62.60.201.218",
+ "62.60.201.219",
+ "62.60.201.220",
+ "62.60.201.221",
+ "62.60.201.222",
+ "62.60.201.223",
+ "62.60.201.224",
+ "62.60.201.225",
+ "62.60.201.226",
+ "62.60.201.227",
+ "62.60.201.228",
+ "62.60.201.229",
+ "62.60.201.230",
+ "62.60.201.231",
+ "62.60.201.232",
+ "62.60.201.233",
+ "62.60.201.234",
+ "62.60.201.235",
+ "62.60.201.236",
+ "62.60.201.238",
+ "62.60.201.239",
+ "62.60.201.240",
+ "62.60.201.241",
+ "62.60.201.243",
+ "62.60.201.244",
+ "62.60.201.245",
+ "62.60.201.246",
+ "62.60.201.247",
+ "62.60.201.248",
+ "62.60.201.249",
+ "62.60.201.250",
+ "62.60.201.251",
+ "62.60.201.252",
+ "62.60.201.253",
+ "62.60.202.5",
+ "62.60.202.33",
+ "62.60.202.50",
+ "62.60.202.61",
+ "62.60.202.158",
+ "62.60.202.243",
+ "62.60.203.14",
+ "62.60.203.16",
+ "62.60.203.23",
+ "62.60.203.46",
+ "62.60.203.47",
+ "62.60.204.5",
+ "62.60.204.17",
+ "62.60.204.123",
+ "62.60.204.162",
+ "62.60.204.187",
+ "62.60.204.207",
+ "62.60.204.233",
+ "62.60.204.234",
+ "62.60.205.3",
+ "62.60.205.4",
+ "62.60.205.5",
+ "62.60.205.6",
+ "62.60.205.7",
+ "62.60.205.8",
+ "62.60.205.9",
+ "62.60.205.10",
+ "62.60.205.11",
+ "62.60.205.12",
+ "62.60.205.13",
+ "62.60.205.14",
+ "62.60.205.15",
+ "62.60.205.16",
+ "62.60.205.17",
+ "62.60.205.18",
+ "62.60.205.19",
+ "62.60.205.20",
+ "62.60.205.21",
+ "62.60.205.22",
+ "62.60.205.23",
+ "62.60.205.25",
+ "62.60.205.26",
+ "62.60.205.27",
+ "62.60.205.28",
+ "62.60.205.29",
+ "62.60.205.30",
+ "62.60.205.31",
+ "62.60.205.32",
+ "62.60.205.33",
+ "62.60.205.34",
+ "62.60.205.35",
+ "62.60.205.36",
+ "62.60.205.37",
+ "62.60.205.38",
+ "62.60.205.39",
+ "62.60.205.40",
+ "62.60.205.41",
+ "62.60.205.42",
+ "62.60.205.43",
+ "62.60.205.44",
+ "62.60.205.45",
+ "62.60.205.46",
+ "62.60.205.47",
+ "62.60.205.48",
+ "62.60.205.49",
+ "62.60.205.50",
+ "62.60.205.51",
+ "62.60.205.52",
+ "62.60.205.53",
+ "62.60.205.54",
+ "62.60.205.55",
+ "62.60.205.56",
+ "62.60.205.57",
+ "62.60.205.58",
+ "62.60.205.59",
+ "62.60.205.60",
+ "62.60.205.61",
+ "62.60.205.62",
+ "62.60.205.63",
+ "62.60.205.64",
+ "62.60.205.65",
+ "62.60.205.68",
+ "62.60.205.69",
+ "62.60.205.70",
+ "62.60.205.71",
+ "62.60.205.72",
+ "62.60.205.73",
+ "62.60.205.74",
+ "62.60.205.76",
+ "62.60.205.77",
+ "62.60.205.78",
+ "62.60.205.79",
+ "62.60.205.80",
+ "62.60.205.81",
+ "62.60.205.83",
+ "62.60.205.84",
+ "62.60.205.85",
+ "62.60.205.86",
+ "62.60.205.88",
+ "62.60.205.89",
+ "62.60.205.90",
+ "62.60.205.91",
+ "62.60.205.92",
+ "62.60.205.93",
+ "62.60.205.94",
+ "62.60.205.95",
+ "62.60.205.97",
+ "62.60.205.98",
+ "62.60.205.99",
+ "62.60.205.101",
+ "62.60.205.102",
+ "62.60.205.103",
+ "62.60.205.104",
+ "62.60.205.105",
+ "62.60.205.106",
+ "62.60.205.107",
+ "62.60.205.108",
+ "62.60.205.109",
+ "62.60.205.110",
+ "62.60.205.111",
+ "62.60.205.112",
+ "62.60.205.113",
+ "62.60.205.115",
+ "62.60.205.116",
+ "62.60.205.117",
+ "62.60.205.118",
+ "62.60.205.119",
+ "62.60.205.120",
+ "62.60.205.121",
+ "62.60.205.122",
+ "62.60.205.123",
+ "62.60.205.124",
+ "62.60.205.125",
+ "62.60.205.126",
+ "62.60.205.128",
+ "62.60.205.129",
+ "62.60.205.131",
+ "62.60.205.132",
+ "62.60.205.133",
+ "62.60.205.134",
+ "62.60.205.135",
+ "62.60.205.136",
+ "62.60.205.137",
+ "62.60.205.138",
+ "62.60.205.139",
+ "62.60.205.140",
+ "62.60.205.141",
+ "62.60.205.142",
+ "62.60.205.143",
+ "62.60.205.144",
+ "62.60.205.145",
+ "62.60.205.146",
+ "62.60.205.147",
+ "62.60.205.148",
+ "62.60.205.150",
+ "62.60.205.151",
+ "62.60.205.152",
+ "62.60.205.153",
+ "62.60.205.154",
+ "62.60.205.155",
+ "62.60.205.156",
+ "62.60.205.157",
+ "62.60.205.158",
+ "62.60.205.159",
+ "62.60.205.160",
+ "62.60.205.161",
+ "62.60.205.162",
+ "62.60.205.163",
+ "62.60.205.164",
+ "62.60.205.166",
+ "62.60.205.167",
+ "62.60.205.168",
+ "62.60.205.169",
+ "62.60.205.170",
+ "62.60.205.171",
+ "62.60.205.172",
+ "62.60.205.173",
+ "62.60.205.174",
+ "62.60.205.175",
+ "62.60.205.176",
+ "62.60.205.177",
+ "62.60.205.178",
+ "62.60.205.179",
+ "62.60.205.180",
+ "62.60.205.181",
+ "62.60.205.182",
+ "62.60.205.183",
+ "62.60.205.184",
+ "62.60.205.185",
+ "62.60.205.186",
+ "62.60.205.187",
+ "62.60.205.188",
+ "62.60.205.189",
+ "62.60.205.191",
+ "62.60.205.192",
+ "62.60.205.193",
+ "62.60.205.194",
+ "62.60.205.195",
+ "62.60.205.196",
+ "62.60.205.197",
+ "62.60.205.198",
+ "62.60.205.199",
+ "62.60.205.200",
+ "62.60.205.201",
+ "62.60.205.202",
+ "62.60.205.203",
+ "62.60.205.204",
+ "62.60.205.207",
+ "62.60.205.208",
+ "62.60.205.209",
+ "62.60.205.210",
+ "62.60.205.211",
+ "62.60.205.212",
+ "62.60.205.213",
+ "62.60.205.214",
+ "62.60.205.215",
+ "62.60.205.216",
+ "62.60.205.217",
+ "62.60.205.218",
+ "62.60.205.219",
+ "62.60.205.220",
+ "62.60.205.221",
+ "62.60.205.222",
+ "62.60.205.223",
+ "62.60.205.224",
+ "62.60.205.225",
+ "62.60.205.226",
+ "62.60.205.227",
+ "62.60.205.228",
+ "62.60.205.229",
+ "62.60.205.231",
+ "62.60.205.232",
+ "62.60.205.233",
+ "62.60.205.234",
+ "62.60.205.235",
+ "62.60.205.236",
+ "62.60.205.237",
+ "62.60.205.238",
+ "62.60.205.239",
+ "62.60.205.240",
+ "62.60.205.241",
+ "62.60.205.242",
+ "62.60.205.243",
+ "62.60.205.244",
+ "62.60.205.245",
+ "62.60.205.246",
+ "62.60.205.248",
+ "62.60.205.249",
+ "62.60.205.250",
+ "62.60.205.251",
+ "62.60.205.253",
+ "62.60.206.35",
+ "62.60.206.50",
+ "62.60.206.65",
+ "62.60.206.71",
+ "62.60.206.83",
+ "62.60.206.111",
+ "62.60.206.132",
+ "62.60.206.133",
+ "62.60.206.182",
+ "62.60.206.205",
+ "62.60.207.14",
+ "62.60.207.22",
+ "62.60.207.47",
+ "62.60.207.70",
+ "62.60.207.75",
+ "62.60.207.77",
+ "62.60.207.97",
+ "62.60.207.104",
+ "62.60.207.132",
+ "62.60.207.138",
+ "62.60.207.223",
+ "62.60.207.241",
+ "62.60.210.3",
+ "62.60.210.4",
+ "62.60.210.5",
+ "62.60.210.10",
+ "62.60.210.17",
+ "62.60.210.24",
+ "62.60.210.68",
+ "62.60.210.69",
+ "62.60.210.70",
+ "62.60.210.74",
+ "62.60.210.77",
+ "62.60.210.85",
+ "62.60.210.91",
+ "62.60.210.94",
+ "62.60.210.95",
+ "62.60.210.96",
+ "62.60.210.102",
+ "62.60.210.110",
+ "62.60.210.130",
+ "62.60.210.131",
+ "62.60.210.141",
+ "62.60.210.143",
+ "62.60.210.176",
+ "62.60.210.181",
+ "62.60.210.186",
+ "62.60.210.199",
+ "62.60.210.234",
+ "62.60.210.235",
+ "62.60.210.248",
+ "62.60.210.250",
+ "62.60.211.56",
+ "62.60.211.85",
+ "62.60.211.90",
+ "62.60.211.104",
+ "62.60.211.114",
+ "62.60.211.118",
+ "62.60.211.119",
+ "62.60.211.123",
+ "62.60.211.145",
+ "62.60.211.153",
+ "62.60.211.155",
+ "62.60.211.156",
+ "62.60.211.163",
+ "62.60.211.164",
+ "62.60.211.174",
+ "62.60.211.175",
+ "62.60.211.183",
+ "62.60.211.184",
+ "62.60.211.185",
+ "62.60.211.189",
+ "62.60.211.190",
+ "62.60.211.191",
+ "62.60.211.192",
+ "62.60.211.195",
+ "62.60.211.196",
+ "62.60.211.197",
+ "62.60.211.199",
+ "62.60.211.203",
+ "62.60.211.211",
+ "62.60.211.212",
+ "62.60.211.213",
+ "62.60.211.215",
+ "62.60.211.218",
+ "62.60.211.222",
+ "62.60.211.226",
+ "62.60.211.229",
+ "62.60.211.230",
+ "62.60.211.234",
+ "62.60.211.235",
+ "62.60.211.237",
+ "62.60.211.239",
+ "62.60.211.241",
+ "62.60.211.248",
+ "62.60.211.251",
+ "62.60.211.253",
+ "62.60.212.26",
+ "62.60.212.27",
+ "62.60.212.32",
+ "62.60.212.91",
+ "62.60.212.158",
+ "62.60.212.159",
+ "62.60.212.193",
+ "62.60.212.222",
+ "62.60.212.232",
+ "62.60.212.243",
+ "62.60.212.247",
+ "62.60.213.10",
+ "62.60.213.11",
+ "62.60.213.14",
+ "62.60.213.26",
+ "62.60.213.58",
+ "62.60.213.66",
+ "62.60.213.122",
+ "62.60.213.126",
+ "62.60.213.206",
+ "62.60.213.220",
+ "62.60.214.60",
+ "62.60.214.64",
+ "62.60.214.80",
+ "62.60.214.91",
+ "62.60.214.151",
+ "62.60.214.228",
+ "62.60.219.3",
+ "62.106.95.14",
+ "62.106.95.25",
+ "62.106.95.28",
+ "62.106.95.34",
+ "62.106.95.37",
+ "62.106.95.43",
+ "62.106.95.74",
+ "62.106.95.76",
+ "62.106.95.81",
+ "62.106.95.87",
+ "62.106.95.99",
+ "62.106.95.106",
+ "62.106.95.129",
+ "62.106.95.134",
+ "62.106.95.141",
+ "62.106.95.147",
+ "62.106.95.149",
+ "62.106.95.152",
+ "62.106.95.153",
+ "62.106.95.156",
+ "62.106.95.165",
+ "62.106.95.169",
+ "62.106.95.182",
+ "62.106.95.192",
+ "62.106.95.193",
+ "62.106.95.198",
+ "62.106.95.199",
+ "62.106.95.217",
+ "62.106.95.239",
+ "62.106.95.242",
+ "62.106.95.247",
+ "62.106.95.251",
+ "62.106.95.252",
+ "62.193.13.5",
+ "62.193.13.9",
+ "62.204.61.2",
+ "62.204.61.5",
+ "62.204.61.6",
+ "62.204.61.7",
+ "62.204.61.8",
+ "62.204.61.9",
+ "62.204.61.12",
+ "62.204.61.13",
+ "62.204.61.14",
+ "62.204.61.15",
+ "62.204.61.17",
+ "62.204.61.18",
+ "62.204.61.19",
+ "62.204.61.22",
+ "62.204.61.23",
+ "62.204.61.25",
+ "62.204.61.30",
+ "62.204.61.33",
+ "62.204.61.35",
+ "62.204.61.36",
+ "62.204.61.37",
+ "62.204.61.44",
+ "62.204.61.46",
+ "62.204.61.47",
+ "62.204.61.60",
+ "62.204.61.63",
+ "62.204.61.72",
+ "62.204.61.93",
+ "62.204.61.112",
+ "62.204.61.114",
+ "62.204.61.115",
+ "62.204.61.116",
+ "62.204.61.117",
+ "62.204.61.118",
+ "62.204.61.119",
+ "62.204.61.122",
+ "62.204.61.130",
+ "62.204.61.141",
+ "62.204.61.143",
+ "62.204.61.145",
+ "62.204.61.148",
+ "62.204.61.155",
+ "62.204.61.156",
+ "62.204.61.160",
+ "62.204.61.164",
+ "62.204.61.177",
+ "62.204.61.185",
+ "62.204.61.202",
+ "62.204.61.222",
+ "62.204.61.224",
+ "62.204.61.233",
+ "62.204.61.254",
+ "62.220.98.5",
+ "62.220.100.168",
+ "62.220.100.182",
+ "62.220.100.187",
+ "62.220.112.46",
+ "62.220.112.71",
+ "62.220.114.204",
+ "62.220.114.253",
+ "62.220.115.101",
+ "62.220.126.218",
+ "62.220.127.13",
+ "62.220.127.165",
+ "77.36.160.4",
+ "77.36.160.7",
+ "77.36.164.20",
+ "77.36.164.21",
+ "77.36.164.34",
+ "77.36.164.36",
+ "77.36.227.3",
+ "77.74.202.74",
+ "77.74.202.202",
+ "77.81.40.244",
+ "77.81.76.2",
+ "77.81.76.4",
+ "77.81.76.7",
+ "77.81.76.8",
+ "77.81.76.10",
+ "77.81.76.12",
+ "77.81.76.13",
+ "77.81.76.14",
+ "77.81.76.15",
+ "77.81.76.17",
+ "77.81.76.18",
+ "77.81.76.19",
+ "77.81.76.20",
+ "77.81.76.21",
+ "77.81.76.22",
+ "77.81.76.23",
+ "77.81.76.24",
+ "77.81.76.25",
+ "77.81.76.26",
+ "77.81.76.27",
+ "77.81.76.28",
+ "77.81.76.30",
+ "77.81.76.32",
+ "77.81.76.33",
+ "77.81.76.34",
+ "77.81.76.35",
+ "77.81.76.37",
+ "77.81.76.39",
+ "77.81.76.40",
+ "77.81.76.41",
+ "77.81.76.42",
+ "77.81.76.43",
+ "77.81.76.44",
+ "77.81.76.45",
+ "77.81.76.46",
+ "77.81.76.47",
+ "77.81.76.48",
+ "77.81.76.51",
+ "77.81.76.52",
+ "77.81.76.55",
+ "77.81.76.59",
+ "77.81.76.62",
+ "77.81.76.64",
+ "77.81.76.66",
+ "77.81.76.68",
+ "77.81.76.72",
+ "77.81.76.77",
+ "77.81.76.82",
+ "77.81.76.83",
+ "77.81.76.84",
+ "77.81.76.85",
+ "77.81.76.87",
+ "77.81.76.99",
+ "77.81.76.100",
+ "77.81.76.101",
+ "77.81.76.102",
+ "77.81.76.103",
+ "77.81.76.104",
+ "77.81.76.105",
+ "77.81.76.118",
+ "77.81.76.120",
+ "77.81.147.31",
+ "77.81.149.211",
+ "77.81.157.153",
+ "77.81.157.202",
+ "77.81.158.4",
+ "77.81.159.61",
+ "77.104.65.73",
+ "77.104.66.41",
+ "77.104.66.165",
+ "77.104.67.55",
+ "77.104.67.56",
+ "77.104.69.40",
+ "77.104.73.147",
+ "77.104.73.229",
+ "77.104.74.71",
+ "77.104.76.45",
+ "77.104.79.30",
+ "77.104.80.3",
+ "77.104.81.127",
+ "77.104.81.242",
+ "77.104.82.2",
+ "77.104.83.201",
+ "77.104.83.206",
+ "77.104.85.163",
+ "77.104.88.139",
+ "77.104.90.18",
+ "77.104.98.115",
+ "77.104.98.205",
+ "77.104.98.231",
+ "77.104.103.147",
+ "77.104.104.104",
+ "77.104.106.55",
+ "77.104.116.15",
+ "77.104.117.2",
+ "77.104.119.6",
+ "77.237.64.209",
+ "77.237.66.66",
+ "77.237.66.67",
+ "77.237.66.71",
+ "77.237.66.76",
+ "77.237.66.77",
+ "77.237.66.78",
+ "77.237.66.80",
+ "77.237.66.81",
+ "77.237.66.84",
+ "77.237.66.89",
+ "77.237.66.98",
+ "77.237.66.126",
+ "77.237.66.195",
+ "77.237.66.238",
+ "77.237.67.10",
+ "77.237.67.11",
+ "77.237.67.12",
+ "77.237.67.14",
+ "77.237.67.15",
+ "77.237.67.16",
+ "77.237.67.17",
+ "77.237.67.18",
+ "77.237.67.20",
+ "77.237.67.21",
+ "77.237.67.22",
+ "77.237.67.23",
+ "77.237.67.24",
+ "77.237.67.25",
+ "77.237.70.140",
+ "77.237.70.170",
+ "77.237.71.19",
+ "77.237.71.20",
+ "77.237.79.5",
+ "77.237.79.6",
+ "77.237.81.6",
+ "77.237.82.123",
+ "77.237.85.210",
+ "77.237.87.187",
+ "77.237.87.188",
+ "77.237.87.189",
+ "77.237.91.141",
+ "77.238.104.132",
+ "77.238.106.15",
+ "77.238.108.91",
+ "77.238.108.100",
+ "77.238.108.124",
+ "77.238.108.125",
+ "77.238.109.67",
+ "77.238.109.76",
+ "77.238.109.77",
+ "77.238.110.42",
+ "77.238.110.45",
+ "77.238.110.80",
+ "77.238.110.83",
+ "77.238.110.84",
+ "77.238.110.85",
+ "77.238.110.86",
+ "77.238.110.106",
+ "77.238.110.140",
+ "77.238.110.157",
+ "77.238.110.158",
+ "77.238.110.162",
+ "77.238.110.181",
+ "77.238.110.187",
+ "77.238.110.191",
+ "77.238.110.226",
+ "77.238.110.250",
+ "77.238.110.251",
+ "77.238.110.252",
+ "77.238.111.234",
+ "77.238.111.236",
+ "77.238.111.237",
+ "77.238.111.238",
+ "77.238.113.8",
+ "77.238.117.53",
+ "77.238.117.158",
+ "77.238.120.17",
+ "77.238.120.21",
+ "77.238.120.52",
+ "77.238.120.98",
+ "77.238.120.99",
+ "77.238.120.100",
+ "77.238.120.101",
+ "77.238.120.102",
+ "77.238.120.121",
+ "77.238.121.54",
+ "77.238.121.55",
+ "77.238.121.107",
+ "77.238.121.155",
+ "77.238.121.242",
+ "77.238.121.243",
+ "77.238.121.245",
+ "77.238.121.247",
+ "77.238.121.249",
+ "77.238.122.130",
+ "77.238.122.132",
+ "77.238.122.133",
+ "77.238.122.134",
+ "77.238.122.135",
+ "77.238.122.136",
+ "77.238.122.139",
+ "77.238.122.140",
+ "77.238.122.141",
+ "77.238.122.142",
+ "77.238.122.143",
+ "77.238.122.145",
+ "77.238.122.147",
+ "77.238.122.148",
+ "77.238.122.149",
+ "77.238.122.152",
+ "77.238.122.153",
+ "77.238.122.156",
+ "77.238.122.157",
+ "77.238.122.158",
+ "77.238.122.159",
+ "77.238.122.160",
+ "77.238.122.161",
+ "77.238.122.162",
+ "77.238.122.164",
+ "77.238.122.165",
+ "77.238.122.166",
+ "77.238.122.167",
+ "77.238.122.169",
+ "77.238.122.172",
+ "77.238.122.174",
+ "77.238.122.175",
+ "77.238.122.178",
+ "77.238.122.179",
+ "77.238.122.180",
+ "77.238.122.181",
+ "77.238.122.182",
+ "77.238.122.185",
+ "77.238.122.187",
+ "77.238.122.189",
+ "77.238.122.196",
+ "77.238.122.206",
+ "77.238.123.84",
+ "77.238.123.179",
+ "77.238.123.237",
+ "78.31.232.3",
+ "78.31.235.119",
+ "78.38.0.131",
+ "78.38.0.132",
+ "78.38.17.28",
+ "78.38.25.2",
+ "78.38.25.3",
+ "78.38.34.125",
+ "78.38.35.11",
+ "78.38.41.96",
+ "78.38.45.2",
+ "78.38.45.3",
+ "78.38.49.84",
+ "78.38.50.218",
+ "78.38.64.156",
+ "78.38.69.2",
+ "78.38.76.251",
+ "78.38.77.2",
+ "78.38.77.3",
+ "78.38.80.251",
+ "78.38.84.11",
+ "78.38.90.70",
+ "78.38.100.34",
+ "78.38.101.37",
+ "78.38.108.48",
+ "78.38.109.130",
+ "78.38.113.2",
+ "78.38.114.69",
+ "78.38.114.85",
+ "78.38.114.99",
+ "78.38.114.102",
+ "78.38.120.95",
+ "78.38.120.131",
+ "78.38.121.66",
+ "78.38.123.247",
+ "78.38.131.114",
+ "78.38.138.158",
+ "78.38.138.159",
+ "78.38.152.74",
+ "78.38.153.74",
+ "78.38.153.86",
+ "78.38.153.132",
+ "78.38.156.68",
+ "78.38.156.72",
+ "78.38.157.241",
+ "78.38.158.1",
+ "78.38.166.162",
+ "78.38.174.30",
+ "78.38.175.2",
+ "78.38.175.3",
+ "78.38.176.10",
+ "78.38.201.120",
+ "78.38.208.156",
+ "78.38.221.187",
+ "78.38.227.2",
+ "78.38.227.3",
+ "78.38.237.49",
+ "78.38.239.67",
+ "78.38.239.134",
+ "78.38.239.202",
+ "78.38.248.66",
+ "78.38.248.94",
+ "78.38.248.107",
+ "78.39.9.27",
+ "78.39.9.224",
+ "78.39.9.251",
+ "78.39.10.44",
+ "78.39.11.42",
+ "78.39.35.65",
+ "78.39.35.66",
+ "78.39.39.139",
+ "78.39.40.11",
+ "78.39.43.137",
+ "78.39.51.25",
+ "78.39.51.26",
+ "78.39.53.204",
+ "78.39.56.43",
+ "78.39.56.114",
+ "78.39.57.172",
+ "78.39.57.254",
+ "78.39.59.246",
+ "78.39.62.35",
+ "78.39.80.9",
+ "78.39.80.190",
+ "78.39.80.199",
+ "78.39.81.33",
+ "78.39.81.220",
+ "78.39.85.8",
+ "78.39.85.9",
+ "78.39.98.10",
+ "78.39.98.27",
+ "78.39.98.28",
+ "78.39.101.2",
+ "78.39.103.28",
+ "78.39.103.54",
+ "78.39.103.252",
+ "78.39.107.114",
+ "78.39.107.115",
+ "78.39.108.132",
+ "78.39.112.126",
+ "78.39.114.34",
+ "78.39.121.110",
+ "78.39.121.117",
+ "78.39.122.251",
+ "78.39.129.20",
+ "78.39.129.148",
+ "78.39.129.149",
+ "78.39.136.13",
+ "78.39.136.49",
+ "78.39.136.67",
+ "78.39.136.97",
+ "78.39.136.98",
+ "78.39.136.101",
+ "78.39.136.106",
+ "78.39.136.114",
+ "78.39.136.247",
+ "78.39.136.251",
+ "78.39.136.254",
+ "78.39.140.113",
+ "78.39.141.71",
+ "78.39.152.60",
+ "78.39.152.135",
+ "78.39.152.249",
+ "78.39.159.3",
+ "78.39.159.12",
+ "78.39.159.48",
+ "78.39.159.49",
+ "78.39.159.61",
+ "78.39.159.111",
+ "78.39.164.212",
+ "78.39.180.34",
+ "78.39.188.253",
+ "78.39.188.254",
+ "78.39.205.34",
+ "78.39.205.35",
+ "78.39.208.212",
+ "78.39.212.8",
+ "78.39.212.9",
+ "78.39.217.156",
+ "78.39.217.170",
+ "78.39.226.36",
+ "78.39.226.209",
+ "78.39.227.3",
+ "78.39.234.140",
+ "78.39.234.230",
+ "78.39.234.237",
+ "78.39.250.101",
+ "78.39.250.128",
+ "78.39.251.25",
+ "78.39.252.167",
+ "78.41.62.20",
+ "78.41.62.196",
+ "78.109.193.2",
+ "78.109.194.2",
+ "78.109.195.42",
+ "78.109.195.50",
+ "78.109.195.148",
+ "78.109.195.149",
+ "78.109.196.135",
+ "78.109.196.153",
+ "78.109.196.159",
+ "78.109.196.173",
+ "78.109.196.177",
+ "78.109.198.60",
+ "78.109.198.61",
+ "78.109.199.2",
+ "78.109.199.5",
+ "78.109.199.13",
+ "78.109.199.36",
+ "78.109.199.65",
+ "78.109.199.203",
+ "78.109.199.218",
+ "78.109.200.2",
+ "78.109.200.29",
+ "78.109.200.64",
+ "78.109.200.199",
+ "78.109.200.207",
+ "78.109.201.2",
+ "78.109.201.71",
+ "78.109.201.78",
+ "78.109.201.119",
+ "78.109.201.201",
+ "78.109.202.100",
+ "78.109.206.2",
+ "78.109.206.91",
+ "78.109.206.102",
+ "78.109.206.124",
+ "78.109.206.186",
+ "78.109.206.206",
+ "78.110.120.64",
+ "78.110.120.67",
+ "78.110.120.87",
+ "78.110.120.96",
+ "78.110.120.97",
+ "78.110.120.98",
+ "78.110.120.99",
+ "78.110.120.120",
+ "78.110.120.124",
+ "78.110.120.145",
+ "78.110.120.150",
+ "78.110.120.220",
+ "78.110.120.231",
+ "78.110.120.234",
+ "78.110.120.243",
+ "78.110.121.92",
+ "78.110.121.93",
+ "78.110.121.94",
+ "78.110.121.95",
+ "78.110.121.96",
+ "78.110.121.127",
+ "78.110.121.130",
+ "78.110.121.155",
+ "78.110.121.156",
+ "78.110.121.157",
+ "78.110.121.158",
+ "78.110.121.166",
+ "78.110.121.169",
+ "78.110.121.170",
+ "78.110.121.184",
+ "78.110.121.185",
+ "78.110.122.56",
+ "78.110.122.57",
+ "78.110.122.61",
+ "78.110.122.62",
+ "78.110.122.112",
+ "78.110.122.148",
+ "78.110.122.150",
+ "78.110.122.181",
+ "78.110.122.182",
+ "78.110.122.191",
+ "78.110.122.236",
+ "78.110.123.71",
+ "78.110.125.131",
+ "78.111.0.67",
+ "78.111.2.84",
+ "78.111.5.186",
+ "78.111.5.190",
+ "78.111.5.194",
+ "78.111.5.198",
+ "78.111.13.100",
+ "78.157.33.200",
+ "78.157.34.68",
+ "78.157.34.69",
+ "78.157.34.85",
+ "78.157.34.125",
+ "78.157.34.210",
+ "78.157.35.8",
+ "78.157.35.15",
+ "78.157.35.32",
+ "78.157.35.59",
+ "78.157.35.70",
+ "78.157.35.75",
+ "78.157.35.76",
+ "78.157.35.77",
+ "78.157.35.78",
+ "78.157.35.127",
+ "78.157.36.186",
+ "78.157.37.90",
+ "78.157.37.141",
+ "78.157.37.142",
+ "78.157.37.152",
+ "78.157.37.157",
+ "78.157.37.158",
+ "78.157.37.255",
+ "78.157.38.66",
+ "78.157.38.67",
+ "78.157.38.68",
+ "78.157.38.69",
+ "78.157.38.70",
+ "78.157.38.72",
+ "78.157.38.73",
+ "78.157.38.74",
+ "78.157.38.75",
+ "78.157.38.76",
+ "78.157.38.78",
+ "78.157.38.79",
+ "78.157.38.80",
+ "78.157.38.81",
+ "78.157.38.82",
+ "78.157.38.83",
+ "78.157.38.84",
+ "78.157.38.86",
+ "78.157.38.87",
+ "78.157.38.88",
+ "78.157.38.90",
+ "78.157.38.91",
+ "78.157.38.92",
+ "78.157.38.93",
+ "78.157.38.97",
+ "78.157.38.98",
+ "78.157.38.99",
+ "78.157.38.101",
+ "78.157.38.104",
+ "78.157.38.106",
+ "78.157.38.107",
+ "78.157.38.108",
+ "78.157.38.111",
+ "78.157.38.112",
+ "78.157.38.113",
+ "78.157.38.116",
+ "78.157.38.117",
+ "78.157.38.120",
+ "78.157.38.121",
+ "78.157.38.122",
+ "78.157.38.123",
+ "78.157.38.168",
+ "78.157.38.192",
+ "78.157.38.199",
+ "78.157.38.203",
+ "78.157.38.208",
+ "78.157.38.215",
+ "78.157.39.21",
+ "78.157.39.22",
+ "78.157.39.60",
+ "78.157.39.106",
+ "78.157.40.34",
+ "78.157.40.35",
+ "78.157.40.38",
+ "78.157.40.39",
+ "78.157.40.40",
+ "78.157.40.41",
+ "78.157.40.42",
+ "78.157.40.43",
+ "78.157.40.44",
+ "78.157.40.46",
+ "78.157.40.70",
+ "78.157.40.158",
+ "78.157.40.168",
+ "78.157.40.175",
+ "78.157.40.191",
+ "78.157.40.192",
+ "78.157.40.200",
+ "78.157.40.201",
+ "78.157.40.207",
+ "78.157.41.60",
+ "78.157.41.63",
+ "78.157.41.119",
+ "78.157.41.127",
+ "78.157.41.149",
+ "78.157.41.175",
+ "78.157.41.224",
+ "78.157.41.231",
+ "78.157.42.23",
+ "78.157.42.62",
+ "78.157.42.201",
+ "78.157.42.202",
+ "78.157.42.203",
+ "78.157.42.204",
+ "78.157.42.205",
+ "78.157.42.209",
+ "78.157.42.210",
+ "78.157.42.214",
+ "78.157.42.215",
+ "78.157.42.216",
+ "78.157.42.217",
+ "78.157.42.218",
+ "78.157.42.219",
+ "78.157.42.235",
+ "78.157.43.229",
+ "78.157.43.230",
+ "78.157.43.241",
+ "78.157.44.74",
+ "78.157.44.212",
+ "78.157.44.215",
+ "78.157.45.47",
+ "78.157.45.210",
+ "78.157.45.212",
+ "78.157.45.214",
+ "78.157.45.215",
+ "78.157.46.95",
+ "78.157.46.104",
+ "78.157.46.120",
+ "78.157.46.128",
+ "78.157.46.143",
+ "78.157.46.213",
+ "78.157.47.201",
+ "78.157.47.202",
+ "78.157.47.203",
+ "78.157.47.204",
+ "78.157.47.205",
+ "78.157.47.206",
+ "78.157.47.207",
+ "78.157.47.209",
+ "78.157.47.210",
+ "78.157.48.16",
+ "78.157.48.44",
+ "78.157.48.51",
+ "78.157.48.52",
+ "78.157.48.112",
+ "78.157.48.135",
+ "78.157.48.150",
+ "78.157.48.162",
+ "78.157.48.175",
+ "78.157.48.176",
+ "78.157.49.22",
+ "78.157.49.100",
+ "78.157.49.105",
+ "78.157.49.110",
+ "78.157.49.111",
+ "78.157.49.120",
+ "78.157.50.22",
+ "78.157.50.24",
+ "78.157.50.31",
+ "78.157.50.255",
+ "78.157.51.3",
+ "78.157.51.5",
+ "78.157.51.28",
+ "78.157.51.49",
+ "78.157.51.64",
+ "78.157.51.93",
+ "78.157.51.136",
+ "78.157.51.159",
+ "78.157.51.163",
+ "78.157.51.185",
+ "78.157.51.192",
+ "78.157.51.203",
+ "78.157.51.232",
+ "78.157.51.240",
+ "78.157.51.248",
+ "78.157.53.67",
+ "78.157.53.187",
+ "78.157.56.19",
+ "78.157.56.24",
+ "78.157.56.25",
+ "78.157.56.53",
+ "78.157.56.133",
+ "78.157.56.181",
+ "78.157.56.215",
+ "78.157.57.39",
+ "78.157.57.120",
+ "78.157.57.152",
+ "78.157.57.154",
+ "78.157.57.162",
+ "78.157.57.199",
+ "78.157.57.224",
+ "78.157.57.230",
+ "78.157.57.231",
+ "78.157.57.234",
+ "78.157.57.241",
+ "78.157.57.245",
+ "78.157.57.247",
+ "78.157.57.252",
+ "78.157.57.255",
+ "78.157.58.38",
+ "78.157.58.39",
+ "78.157.58.42",
+ "78.157.58.170",
+ "78.157.59.20",
+ "78.157.59.22",
+ "78.157.59.23",
+ "78.157.59.24",
+ "78.157.59.25",
+ "78.157.59.28",
+ "78.157.59.29",
+ "78.157.59.34",
+ "78.157.59.195",
+ "78.157.59.196",
+ "78.157.59.197",
+ "78.157.59.198",
+ "78.157.59.201",
+ "78.157.60.77",
+ "78.157.61.79",
+ "78.157.62.99",
+ "78.157.63.105",
+ "78.157.63.121",
+ "78.158.161.146",
+ "78.158.166.38",
+ "78.158.166.66",
+ "78.158.166.71",
+ "79.127.2.30",
+ "79.127.2.168",
+ "79.127.4.203",
+ "79.127.4.207",
+ "79.127.5.97",
+ "79.127.5.98",
+ "79.127.6.1",
+ "79.127.7.239",
+ "79.127.12.89",
+ "79.127.12.156",
+ "79.127.41.218",
+ "79.127.45.26",
+ "79.127.47.173",
+ "79.127.48.173",
+ "79.127.52.5",
+ "79.127.52.76",
+ "79.127.61.70",
+ "79.127.67.36",
+ "79.127.69.230",
+ "79.127.69.233",
+ "79.127.73.202",
+ "79.127.87.170",
+ "79.127.87.174",
+ "79.127.92.60",
+ "79.127.94.222",
+ "79.127.96.153",
+ "79.127.106.228",
+ "79.127.114.46",
+ "79.127.125.7",
+ "79.127.125.13",
+ "79.127.125.36",
+ "79.127.125.37",
+ "79.127.125.38",
+ "79.127.125.80",
+ "79.127.125.156",
+ "79.127.125.178",
+ "79.127.125.179",
+ "79.127.125.180",
+ "79.127.125.181",
+ "79.127.125.182",
+ "79.127.125.250",
+ "79.127.125.252",
+ "79.127.126.26",
+ "79.127.126.27",
+ "79.127.126.28",
+ "79.127.126.29",
+ "79.127.126.30",
+ "79.127.126.66",
+ "79.127.126.69",
+ "79.127.126.70",
+ "79.127.126.71",
+ "79.127.126.72",
+ "79.127.126.73",
+ "79.127.126.74",
+ "79.127.126.76",
+ "79.127.126.77",
+ "79.127.126.78",
+ "79.127.126.85",
+ "79.127.126.92",
+ "79.127.126.104",
+ "79.127.126.111",
+ "79.127.126.112",
+ "79.127.126.113",
+ "79.127.126.116",
+ "79.127.126.123",
+ "79.127.126.124",
+ "79.127.126.126",
+ "79.127.126.133",
+ "79.127.126.226",
+ "79.127.126.228",
+ "79.127.126.242",
+ "79.127.126.245",
+ "79.127.126.246",
+ "79.127.126.247",
+ "79.127.126.249",
+ "79.127.126.251",
+ "79.127.127.6",
+ "79.127.127.11",
+ "79.127.127.17",
+ "79.127.127.18",
+ "79.127.127.20",
+ "79.127.127.23",
+ "79.127.127.24",
+ "79.127.127.25",
+ "79.127.127.27",
+ "79.127.127.28",
+ "79.127.127.29",
+ "79.127.127.31",
+ "79.127.127.32",
+ "79.127.127.33",
+ "79.127.127.34",
+ "79.127.127.35",
+ "79.127.127.36",
+ "79.127.127.37",
+ "79.127.127.38",
+ "79.127.127.39",
+ "79.127.127.43",
+ "79.127.127.44",
+ "79.127.127.45",
+ "79.127.127.46",
+ "79.127.127.47",
+ "79.127.127.49",
+ "79.127.127.51",
+ "79.127.127.62",
+ "79.127.127.64",
+ "79.127.127.65",
+ "79.127.127.66",
+ "79.127.127.67",
+ "79.127.127.68",
+ "79.127.127.69",
+ "79.127.127.70",
+ "79.127.127.72",
+ "79.127.127.74",
+ "79.127.127.75",
+ "79.127.127.76",
+ "79.127.127.77",
+ "79.127.127.78",
+ "79.127.127.79",
+ "79.127.127.80",
+ "79.127.127.82",
+ "79.127.127.84",
+ "79.127.127.85",
+ "79.127.127.86",
+ "79.127.127.87",
+ "79.127.127.88",
+ "79.127.127.90",
+ "79.127.127.91",
+ "79.127.127.93",
+ "79.127.127.94",
+ "79.127.127.95",
+ "79.127.127.96",
+ "79.127.127.97",
+ "79.127.127.98",
+ "79.127.127.99",
+ "79.127.127.100",
+ "79.127.127.101",
+ "79.127.127.103",
+ "79.127.127.105",
+ "79.127.127.106",
+ "79.127.127.111",
+ "79.127.127.113",
+ "79.127.127.114",
+ "79.127.127.115",
+ "79.127.127.116",
+ "79.127.127.118",
+ "79.127.127.119",
+ "79.127.127.120",
+ "79.127.127.123",
+ "79.127.127.125",
+ "79.127.127.134",
+ "79.127.127.138",
+ "79.127.127.151",
+ "79.127.127.154",
+ "79.127.127.190",
+ "79.127.127.210",
+ "79.127.127.213",
+ "79.127.127.215",
+ "79.132.192.15",
+ "79.132.192.82",
+ "79.132.192.196",
+ "79.132.192.233",
+ "79.132.192.238",
+ "79.132.193.26",
+ "79.132.193.36",
+ "79.132.193.38",
+ "79.132.193.39",
+ "79.132.193.43",
+ "79.132.193.44",
+ "79.132.193.46",
+ "79.132.193.70",
+ "79.132.193.72",
+ "79.132.193.74",
+ "79.132.193.78",
+ "79.132.193.83",
+ "79.132.193.94",
+ "79.132.193.96",
+ "79.132.193.101",
+ "79.132.193.105",
+ "79.132.193.107",
+ "79.132.193.116",
+ "79.132.193.125",
+ "79.132.193.133",
+ "79.132.193.134",
+ "79.132.193.135",
+ "79.132.193.143",
+ "79.132.193.144",
+ "79.132.193.147",
+ "79.132.193.148",
+ "79.132.193.150",
+ "79.132.193.153",
+ "79.132.193.155",
+ "79.132.193.162",
+ "79.132.193.168",
+ "79.132.193.180",
+ "79.132.193.186",
+ "79.132.193.194",
+ "79.132.193.200",
+ "79.132.193.201",
+ "79.132.193.206",
+ "79.132.193.210",
+ "79.132.193.216",
+ "79.132.193.225",
+ "79.132.193.226",
+ "79.132.193.228",
+ "79.132.193.229",
+ "79.132.193.236",
+ "79.132.193.238",
+ "79.132.193.239",
+ "79.132.193.240",
+ "79.132.193.243",
+ "79.132.193.245",
+ "79.132.193.248",
+ "79.132.193.249",
+ "79.132.193.251",
+ "79.132.193.253",
+ "79.132.206.249",
+ "79.132.206.250",
+ "79.132.210.66",
+ "79.143.84.18",
+ "79.143.84.77",
+ "79.143.84.114",
+ "79.143.84.118",
+ "79.143.84.126",
+ "79.143.84.162",
+ "79.143.84.166",
+ "79.143.86.4",
+ "79.143.86.6",
+ "79.143.86.7",
+ "79.143.86.154",
+ "79.143.86.156",
+ "79.143.86.165",
+ "79.143.86.166",
+ "79.143.86.172",
+ "79.174.161.219",
+ "79.174.161.222",
+ "79.174.165.135",
+ "79.174.165.136",
+ "79.175.129.2",
+ "79.175.130.58",
+ "79.175.130.59",
+ "79.175.130.60",
+ "79.175.130.61",
+ "79.175.130.62",
+ "79.175.131.17",
+ "79.175.131.19",
+ "79.175.131.38",
+ "79.175.131.85",
+ "79.175.131.145",
+ "79.175.133.5",
+ "79.175.133.6",
+ "79.175.133.14",
+ "79.175.133.31",
+ "79.175.133.93",
+ "79.175.133.102",
+ "79.175.133.108",
+ "79.175.133.127",
+ "79.175.133.138",
+ "79.175.133.149",
+ "79.175.133.154",
+ "79.175.133.196",
+ "79.175.133.220",
+ "79.175.133.233",
+ "79.175.133.239",
+ "79.175.133.241",
+ "79.175.134.2",
+ "79.175.134.20",
+ "79.175.134.68",
+ "79.175.134.85",
+ "79.175.134.141",
+ "79.175.134.172",
+ "79.175.134.176",
+ "79.175.134.220",
+ "79.175.136.2",
+ "79.175.136.3",
+ "79.175.136.4",
+ "79.175.136.13",
+ "79.175.136.72",
+ "79.175.136.86",
+ "79.175.136.194",
+ "79.175.137.2",
+ "79.175.137.3",
+ "79.175.137.4",
+ "79.175.138.2",
+ "79.175.138.4",
+ "79.175.138.5",
+ "79.175.139.179",
+ "79.175.139.180",
+ "79.175.139.181",
+ "79.175.139.182",
+ "79.175.139.183",
+ "79.175.139.184",
+ "79.175.139.187",
+ "79.175.139.188",
+ "79.175.139.189",
+ "79.175.139.190",
+ "79.175.142.147",
+ "79.175.142.150",
+ "79.175.145.90",
+ "79.175.145.147",
+ "79.175.145.149",
+ "79.175.146.74",
+ "79.175.148.66",
+ "79.175.148.67",
+ "79.175.148.200",
+ "79.175.148.242",
+ "79.175.149.194",
+ "79.175.151.2",
+ "79.175.151.27",
+ "79.175.151.31",
+ "79.175.151.40",
+ "79.175.151.57",
+ "79.175.151.63",
+ "79.175.151.74",
+ "79.175.151.80",
+ "79.175.151.84",
+ "79.175.151.90",
+ "79.175.151.102",
+ "79.175.151.122",
+ "79.175.151.130",
+ "79.175.151.173",
+ "79.175.151.174",
+ "79.175.151.213",
+ "79.175.151.226",
+ "79.175.151.233",
+ "79.175.151.250",
+ "79.175.154.20",
+ "79.175.155.2",
+ "79.175.155.3",
+ "79.175.155.66",
+ "79.175.155.68",
+ "79.175.155.69",
+ "79.175.155.82",
+ "79.175.155.83",
+ "79.175.155.84",
+ "79.175.155.88",
+ "79.175.155.91",
+ "79.175.157.2",
+ "79.175.157.3",
+ "79.175.157.4",
+ "79.175.157.5",
+ "79.175.157.6",
+ "79.175.157.66",
+ "79.175.157.67",
+ "79.175.157.68",
+ "79.175.157.69",
+ "79.175.157.70",
+ "79.175.157.102",
+ "79.175.157.103",
+ "79.175.157.163",
+ "79.175.160.90",
+ "79.175.162.2",
+ "79.175.164.171",
+ "79.175.164.172",
+ "79.175.165.3",
+ "79.175.165.170",
+ "79.175.166.90",
+ "79.175.166.98",
+ "79.175.166.100",
+ "79.175.166.102",
+ "79.175.166.146",
+ "79.175.166.147",
+ "79.175.167.2",
+ "79.175.167.238",
+ "79.175.168.67",
+ "79.175.168.94",
+ "79.175.168.142",
+ "79.175.168.219",
+ "79.175.169.51",
+ "79.175.169.53",
+ "79.175.169.54",
+ "79.175.169.55",
+ "79.175.169.56",
+ "79.175.169.57",
+ "79.175.169.58",
+ "79.175.169.59",
+ "79.175.169.62",
+ "79.175.169.120",
+ "79.175.169.125",
+ "79.175.169.138",
+ "79.175.169.139",
+ "79.175.169.141",
+ "79.175.169.217",
+ "79.175.169.218",
+ "79.175.169.219",
+ "79.175.169.222",
+ "79.175.169.226",
+ "79.175.169.229",
+ "79.175.171.179",
+ "79.175.172.98",
+ "79.175.172.101",
+ "79.175.172.147",
+ "79.175.172.150",
+ "79.175.172.155",
+ "79.175.172.156",
+ "79.175.173.179",
+ "79.175.173.198",
+ "79.175.173.217",
+ "79.175.173.234",
+ "79.175.174.124",
+ "79.175.174.125",
+ "79.175.176.3",
+ "79.175.176.22",
+ "79.175.176.36",
+ "79.175.176.37",
+ "79.175.176.46",
+ "79.175.176.49",
+ "79.175.176.60",
+ "79.175.176.69",
+ "79.175.176.70",
+ "79.175.176.74",
+ "79.175.176.76",
+ "79.175.176.99",
+ "79.175.176.118",
+ "79.175.176.123",
+ "79.175.176.136",
+ "79.175.176.177",
+ "79.175.176.184",
+ "79.175.176.188",
+ "79.175.176.191",
+ "79.175.176.209",
+ "79.175.177.2",
+ "79.175.177.17",
+ "79.175.177.30",
+ "79.175.177.67",
+ "79.175.177.103",
+ "79.175.177.112",
+ "79.175.177.113",
+ "79.175.177.136",
+ "79.175.177.138",
+ "79.175.181.148",
+ "79.175.181.150",
+ "79.175.181.153",
+ "79.175.181.156",
+ "79.175.181.158",
+ "79.175.181.171",
+ "79.175.181.203",
+ "79.175.181.206",
+ "79.175.181.213",
+ "79.175.186.162",
+ "79.175.188.2",
+ "79.175.188.41",
+ "79.175.188.135",
+ "79.175.188.186",
+ "79.175.189.104",
+ "79.175.190.162",
+ "79.175.190.166",
+ "79.175.190.180",
+ "79.175.190.181",
+ "79.175.190.182",
+ "79.175.190.237",
+ "80.66.177.4",
+ "80.66.177.5",
+ "80.66.177.22",
+ "80.66.177.49",
+ "80.71.119.2",
+ "80.71.149.3",
+ "80.71.149.4",
+ "80.71.149.40",
+ "80.71.149.42",
+ "80.71.149.127",
+ "80.71.149.152",
+ "80.71.149.158",
+ "80.71.149.175",
+ "80.71.149.241",
+ "80.71.149.249",
+ "80.75.0.2",
+ "80.75.1.42",
+ "80.75.2.15",
+ "80.75.2.135",
+ "80.75.3.7",
+ "80.75.3.17",
+ "80.75.3.86",
+ "80.75.3.93",
+ "80.75.3.227",
+ "80.75.4.101",
+ "80.75.4.167",
+ "80.75.4.168",
+ "80.75.7.10",
+ "80.75.7.26",
+ "80.75.7.188",
+ "80.75.9.7",
+ "80.75.10.134",
+ "80.75.13.179",
+ "80.75.14.70",
+ "80.75.14.71",
+ "80.75.14.96",
+ "80.75.14.99",
+ "80.75.14.102",
+ "80.75.14.103",
+ "80.75.14.108",
+ "80.75.14.115",
+ "80.75.14.116",
+ "80.75.14.118",
+ "80.75.14.124",
+ "80.75.213.70",
+ "80.75.213.90",
+ "80.75.213.131",
+ "80.75.213.146",
+ "80.75.213.147",
+ "80.75.213.148",
+ "80.75.213.149",
+ "80.75.213.155",
+ "80.75.213.253",
+ "80.91.208.18",
+ "80.91.208.206",
+ "80.191.0.17",
+ "80.191.0.18",
+ "80.191.2.218",
+ "80.191.8.40",
+ "80.191.11.134",
+ "80.191.24.2",
+ "80.191.24.9",
+ "80.191.27.199",
+ "80.191.27.203",
+ "80.191.27.204",
+ "80.191.27.205",
+ "80.191.27.206",
+ "80.191.32.3",
+ "80.191.32.56",
+ "80.191.36.20",
+ "80.191.41.83",
+ "80.191.41.84",
+ "80.191.47.2",
+ "80.191.49.130",
+ "80.191.49.131",
+ "80.191.49.133",
+ "80.191.56.7",
+ "80.191.56.100",
+ "80.191.56.110",
+ "80.191.62.5",
+ "80.191.65.241",
+ "80.191.68.247",
+ "80.191.70.34",
+ "80.191.75.110",
+ "80.191.80.9",
+ "80.191.89.50",
+ "80.191.89.98",
+ "80.191.90.54",
+ "80.191.90.62",
+ "80.191.92.15",
+ "80.191.92.179",
+ "80.191.92.188",
+ "80.191.92.199",
+ "80.191.92.233",
+ "80.191.100.246",
+ "80.191.103.92",
+ "80.191.105.200",
+ "80.191.105.245",
+ "80.191.105.249",
+ "80.191.105.252",
+ "80.191.110.138",
+ "80.191.111.4",
+ "80.191.111.5",
+ "80.191.111.170",
+ "80.191.131.131",
+ "80.191.153.109",
+ "80.191.156.134",
+ "80.191.156.234",
+ "80.191.163.249",
+ "80.191.163.251",
+ "80.191.170.194",
+ "80.191.172.4",
+ "80.191.172.69",
+ "80.191.174.111",
+ "80.191.174.112",
+ "80.191.192.6",
+ "80.191.192.115",
+ "80.191.193.40",
+ "80.191.202.15",
+ "80.191.203.10",
+ "80.191.214.20",
+ "80.191.216.2",
+ "80.191.221.12",
+ "80.191.221.14",
+ "80.191.221.19",
+ "80.191.221.20",
+ "80.191.221.21",
+ "80.191.221.22",
+ "80.191.221.25",
+ "80.191.221.28",
+ "80.191.221.29",
+ "80.191.221.30",
+ "80.191.221.32",
+ "80.191.221.40",
+ "80.191.221.41",
+ "80.191.221.61",
+ "80.191.221.72",
+ "80.191.228.3",
+ "80.191.236.54",
+ "80.191.242.1",
+ "80.191.242.90",
+ "80.191.242.228",
+ "80.191.248.61",
+ "80.191.248.62",
+ "80.210.17.2",
+ "80.210.20.226",
+ "80.210.22.97",
+ "80.210.24.8",
+ "80.210.26.114",
+ "80.210.26.166",
+ "80.210.30.38",
+ "80.210.30.78",
+ "80.210.30.156",
+ "80.210.32.30",
+ "80.210.32.38",
+ "80.210.32.132",
+ "80.210.32.162",
+ "80.210.38.9",
+ "80.210.38.11",
+ "80.210.40.54",
+ "80.210.40.208",
+ "80.210.41.96",
+ "80.210.48.145",
+ "80.210.51.88",
+ "80.210.53.80",
+ "80.210.57.212",
+ "80.210.59.19",
+ "80.210.59.98",
+ "80.210.61.28",
+ "80.210.62.28",
+ "80.210.62.245",
+ "80.210.63.54",
+ "80.210.141.120",
+ "80.210.166.118",
+ "80.210.167.23",
+ "80.210.168.153",
+ "80.210.173.249",
+ "80.253.136.12",
+ "80.253.145.150",
+ "80.253.147.222",
+ "81.12.0.3",
+ "81.12.4.10",
+ "81.12.5.164",
+ "81.12.5.221",
+ "81.12.7.54",
+ "81.12.12.201",
+ "81.12.12.202",
+ "81.12.13.11",
+ "81.12.13.74",
+ "81.12.25.53",
+ "81.12.27.38",
+ "81.12.27.122",
+ "81.12.27.171",
+ "81.12.27.210",
+ "81.12.27.218",
+ "81.12.27.222",
+ "81.12.28.206",
+ "81.12.30.13",
+ "81.12.30.82",
+ "81.12.30.139",
+ "81.12.30.140",
+ "81.12.30.141",
+ "81.12.30.195",
+ "81.12.31.48",
+ "81.12.34.177",
+ "81.12.35.100",
+ "81.12.39.2",
+ "81.12.39.3",
+ "81.12.39.4",
+ "81.12.39.8",
+ "81.12.39.9",
+ "81.12.39.10",
+ "81.12.39.11",
+ "81.12.39.12",
+ "81.12.39.13",
+ "81.12.39.14",
+ "81.12.39.15",
+ "81.12.39.16",
+ "81.12.39.17",
+ "81.12.39.18",
+ "81.12.39.19",
+ "81.12.39.20",
+ "81.12.39.21",
+ "81.12.39.22",
+ "81.12.39.23",
+ "81.12.39.24",
+ "81.12.39.25",
+ "81.12.39.26",
+ "81.12.39.27",
+ "81.12.39.28",
+ "81.12.39.29",
+ "81.12.39.31",
+ "81.12.39.54",
+ "81.12.39.81",
+ "81.12.39.116",
+ "81.12.39.134",
+ "81.12.39.135",
+ "81.12.39.137",
+ "81.12.39.138",
+ "81.12.39.159",
+ "81.12.39.193",
+ "81.12.39.194",
+ "81.12.39.195",
+ "81.12.39.197",
+ "81.12.39.198",
+ "81.12.39.199",
+ "81.12.39.202",
+ "81.12.39.210",
+ "81.12.39.233",
+ "81.12.52.4",
+ "81.12.52.58",
+ "81.12.52.90",
+ "81.12.52.122",
+ "81.12.52.126",
+ "81.12.52.146",
+ "81.12.52.155",
+ "81.12.52.158",
+ "81.12.52.162",
+ "81.12.52.172",
+ "81.12.52.178",
+ "81.12.52.190",
+ "81.12.52.235",
+ "81.12.53.76",
+ "81.12.53.90",
+ "81.12.53.115",
+ "81.12.53.116",
+ "81.12.53.124",
+ "81.12.53.126",
+ "81.12.53.131",
+ "81.12.53.150",
+ "81.12.53.162",
+ "81.12.53.182",
+ "81.12.53.206",
+ "81.12.53.217",
+ "81.12.54.123",
+ "81.12.55.235",
+ "81.12.59.137",
+ "81.12.59.138",
+ "81.12.62.101",
+ "81.12.63.109",
+ "81.12.65.141",
+ "81.12.65.144",
+ "81.12.70.4",
+ "81.12.72.123",
+ "81.12.72.218",
+ "81.12.75.140",
+ "81.12.87.104",
+ "81.12.88.52",
+ "81.12.91.51",
+ "81.12.91.52",
+ "81.12.91.53",
+ "81.12.93.250",
+ "81.12.93.251",
+ "81.12.93.252",
+ "81.12.93.253",
+ "81.12.97.60",
+ "81.12.97.124",
+ "81.12.98.18",
+ "81.12.98.19",
+ "81.12.98.21",
+ "81.12.98.22",
+ "81.12.101.62",
+ "81.12.105.194",
+ "81.12.108.99",
+ "81.12.108.100",
+ "81.12.108.101",
+ "81.12.108.102",
+ "81.12.112.180",
+ "81.12.113.26",
+ "81.12.116.130",
+ "81.12.116.131",
+ "81.12.116.133",
+ "81.12.116.134",
+ "81.12.116.135",
+ "81.12.116.136",
+ "81.12.116.137",
+ "81.12.116.138",
+ "81.12.116.139",
+ "81.12.116.140",
+ "81.12.120.27",
+ "81.12.120.131",
+ "81.12.122.130",
+ "81.12.123.151",
+ "81.16.114.126",
+ "81.16.115.130",
+ "81.16.116.178",
+ "81.16.121.124",
+ "81.16.121.161",
+ "81.16.123.125",
+ "81.16.124.169",
+ "81.16.126.103",
+ "81.16.126.237",
+ "81.16.127.253",
+ "81.28.52.30",
+ "81.28.61.72",
+ "81.29.245.169",
+ "81.29.255.35",
+ "81.31.160.34",
+ "81.31.160.35",
+ "81.31.169.19",
+ "81.31.250.184",
+ "81.31.250.186",
+ "81.31.250.188",
+ "81.31.250.189",
+ "81.90.144.210",
+ "81.90.147.2",
+ "81.90.147.189",
+ "81.90.152.150",
+ "81.90.158.26",
+ "81.90.159.170",
+ "81.91.129.226",
+ "81.91.129.227",
+ "81.91.129.229",
+ "81.91.129.230",
+ "81.91.139.109",
+ "81.91.139.118",
+ "81.91.140.90",
+ "81.91.145.181",
+ "81.91.146.254",
+ "81.91.147.3",
+ "81.91.147.250",
+ "81.91.151.172",
+ "81.91.155.46",
+ "81.91.155.94",
+ "81.91.157.181",
+ "82.99.202.102",
+ "82.99.202.212",
+ "82.99.204.74",
+ "82.99.204.93",
+ "82.99.227.214",
+ "82.99.240.57",
+ "82.99.250.149",
+ "82.99.252.117",
+ "82.99.253.93",
+ "83.147.193.2",
+ "83.147.193.3",
+ "83.147.193.4",
+ "83.147.193.240",
+ "83.150.192.12",
+ "83.150.193.12",
+ "84.47.239.2",
+ "84.47.239.3",
+ "84.47.239.4",
+ "84.47.239.6",
+ "84.47.239.7",
+ "84.47.239.8",
+ "84.47.239.9",
+ "84.47.239.10",
+ "84.47.239.11",
+ "84.47.239.12",
+ "84.47.239.14",
+ "84.47.239.15",
+ "84.47.239.16",
+ "84.47.239.17",
+ "84.47.239.18",
+ "84.47.239.19",
+ "84.47.239.20",
+ "84.47.239.22",
+ "84.47.239.23",
+ "84.47.239.25",
+ "84.241.0.237",
+ "84.241.1.202",
+ "84.241.2.22",
+ "84.241.2.42",
+ "84.241.2.100",
+ "84.241.2.253",
+ "84.241.4.59",
+ "84.241.7.39",
+ "84.241.7.200",
+ "84.241.10.229",
+ "84.241.11.102",
+ "84.241.11.222",
+ "84.241.13.118",
+ "84.241.14.122",
+ "84.241.16.25",
+ "84.241.16.49",
+ "84.241.19.230",
+ "84.241.22.21",
+ "84.241.22.121",
+ "84.241.22.236",
+ "84.241.26.155",
+ "84.241.27.20",
+ "84.241.27.165",
+ "84.241.28.236",
+ "84.241.30.11",
+ "84.241.30.192",
+ "84.241.32.141",
+ "84.241.35.82",
+ "84.241.38.8",
+ "84.241.39.230",
+ "84.241.39.250",
+ "84.241.41.23",
+ "84.241.41.93",
+ "84.241.41.195",
+ "84.241.43.83",
+ "84.241.45.39",
+ "84.241.47.146",
+ "84.241.56.89",
+ "84.241.63.178",
+ "85.9.66.19",
+ "85.9.71.176",
+ "85.9.91.133",
+ "85.9.104.2",
+ "85.9.105.37",
+ "85.9.105.46",
+ "85.9.107.3",
+ "85.9.107.123",
+ "85.9.107.154",
+ "85.9.107.163",
+ "85.9.107.165",
+ "85.9.107.169",
+ "85.9.107.217",
+ "85.9.107.228",
+ "85.9.107.229",
+ "85.9.108.3",
+ "85.9.108.4",
+ "85.9.108.98",
+ "85.9.108.100",
+ "85.9.108.101",
+ "85.9.108.102",
+ "85.9.108.103",
+ "85.9.108.104",
+ "85.9.108.108",
+ "85.9.109.5",
+ "85.9.111.122",
+ "85.9.111.123",
+ "85.9.111.125",
+ "85.9.111.126",
+ "85.9.111.154",
+ "85.9.111.172",
+ "85.9.111.186",
+ "85.9.112.212",
+ "85.9.112.227",
+ "85.9.112.228",
+ "85.9.112.230",
+ "85.9.112.232",
+ "85.9.120.53",
+ "85.9.123.33",
+ "85.9.125.22",
+ "85.15.6.12",
+ "85.15.6.13",
+ "85.15.24.14",
+ "85.133.128.248",
+ "85.133.128.249",
+ "85.133.148.126",
+ "85.133.149.54",
+ "85.133.153.149",
+ "85.133.153.170",
+ "85.133.153.172",
+ "85.133.153.173",
+ "85.133.153.174",
+ "85.133.155.216",
+ "85.133.155.217",
+ "85.133.155.218",
+ "85.133.155.219",
+ "85.133.155.220",
+ "85.133.155.221",
+ "85.133.155.222",
+ "85.133.155.223",
+ "85.133.159.76",
+ "85.133.159.94",
+ "85.133.167.166",
+ "85.133.167.187",
+ "85.133.168.52",
+ "85.133.168.115",
+ "85.133.169.53",
+ "85.133.169.61",
+ "85.133.171.186",
+ "85.133.171.187",
+ "85.133.173.53",
+ "85.133.176.113",
+ "85.133.179.34",
+ "85.133.180.90",
+ "85.133.187.102",
+ "85.133.188.38",
+ "85.133.193.31",
+ "85.133.193.38",
+ "85.133.193.43",
+ "85.133.193.53",
+ "85.133.193.55",
+ "85.133.193.58",
+ "85.133.193.59",
+ "85.133.193.71",
+ "85.133.193.79",
+ "85.133.193.80",
+ "85.133.193.82",
+ "85.133.193.83",
+ "85.133.193.128",
+ "85.133.193.139",
+ "85.133.193.143",
+ "85.133.193.148",
+ "85.133.193.152",
+ "85.133.193.153",
+ "85.133.193.199",
+ "85.133.195.212",
+ "85.133.195.216",
+ "85.133.197.63",
+ "85.133.197.198",
+ "85.133.198.72",
+ "85.133.198.73",
+ "85.133.200.9",
+ "85.133.200.250",
+ "85.133.200.254",
+ "85.133.205.40",
+ "85.133.205.76",
+ "85.133.205.113",
+ "85.133.205.133",
+ "85.133.206.130",
+ "85.133.206.137",
+ "85.133.206.138",
+ "85.133.206.139",
+ "85.133.206.142",
+ "85.133.207.169",
+ "85.133.212.54",
+ "85.133.212.218",
+ "85.133.212.243",
+ "85.133.212.244",
+ "85.133.212.246",
+ "85.133.212.247",
+ "85.133.212.249",
+ "85.133.217.9",
+ "85.133.217.13",
+ "85.133.217.14",
+ "85.133.217.26",
+ "85.133.217.66",
+ "85.133.217.67",
+ "85.133.217.69",
+ "85.133.217.70",
+ "85.133.217.110",
+ "85.133.217.242",
+ "85.133.217.253",
+ "85.133.217.254",
+ "85.133.220.130",
+ "85.133.227.61",
+ "85.133.235.180",
+ "85.133.237.237",
+ "85.133.240.32",
+ "85.133.243.5",
+ "85.133.243.6",
+ "85.133.243.8",
+ "85.133.243.9",
+ "85.133.243.10",
+ "85.133.243.12",
+ "85.133.243.13",
+ "85.133.243.14",
+ "85.133.243.15",
+ "85.133.243.16",
+ "85.133.243.18",
+ "85.133.243.19",
+ "85.133.243.20",
+ "85.133.243.21",
+ "85.133.243.22",
+ "85.133.243.23",
+ "85.133.243.24",
+ "85.133.243.25",
+ "85.133.243.26",
+ "85.133.243.27",
+ "85.133.243.28",
+ "85.133.243.29",
+ "85.133.243.30",
+ "85.133.243.31",
+ "85.133.243.32",
+ "85.133.243.33",
+ "85.133.243.35",
+ "85.133.243.36",
+ "85.133.243.37",
+ "85.133.243.38",
+ "85.133.243.39",
+ "85.133.243.40",
+ "85.133.243.41",
+ "85.133.243.42",
+ "85.133.243.43",
+ "85.133.243.44",
+ "85.133.243.45",
+ "85.133.243.46",
+ "85.133.243.47",
+ "85.133.243.48",
+ "85.133.243.49",
+ "85.133.243.50",
+ "85.133.243.51",
+ "85.133.243.52",
+ "85.133.243.53",
+ "85.133.243.54",
+ "85.133.243.55",
+ "85.133.243.56",
+ "85.133.243.57",
+ "85.133.243.58",
+ "85.133.243.60",
+ "85.133.243.61",
+ "85.133.243.62",
+ "85.133.243.63",
+ "85.133.243.64",
+ "85.133.243.65",
+ "85.133.243.66",
+ "85.133.243.67",
+ "85.133.243.68",
+ "85.133.243.69",
+ "85.133.243.70",
+ "85.133.243.71",
+ "85.133.243.72",
+ "85.133.243.73",
+ "85.133.243.74",
+ "85.133.243.75",
+ "85.133.243.76",
+ "85.133.243.77",
+ "85.133.243.78",
+ "85.133.243.79",
+ "85.133.243.80",
+ "85.133.243.81",
+ "85.133.243.82",
+ "85.133.243.83",
+ "85.133.243.84",
+ "85.133.243.85",
+ "85.133.243.86",
+ "85.133.243.87",
+ "85.133.243.88",
+ "85.133.243.89",
+ "85.133.243.90",
+ "85.133.243.91",
+ "85.133.243.92",
+ "85.133.243.150",
+ "85.133.250.125",
+ "85.133.250.126",
+ "85.133.250.184",
+ "85.133.253.100",
+ "85.133.253.103",
+ "85.185.1.10",
+ "85.185.1.125",
+ "85.185.8.204",
+ "85.185.27.131",
+ "85.185.36.132",
+ "85.185.41.131",
+ "85.185.45.50",
+ "85.185.53.30",
+ "85.185.54.61",
+ "85.185.67.253",
+ "85.185.67.254",
+ "85.185.69.83",
+ "85.185.75.110",
+ "85.185.75.202",
+ "85.185.81.116",
+ "85.185.81.130",
+ "85.185.81.132",
+ "85.185.82.100",
+ "85.185.82.130",
+ "85.185.82.152",
+ "85.185.83.67",
+ "85.185.83.172",
+ "85.185.85.195",
+ "85.185.88.138",
+ "85.185.91.3",
+ "85.185.93.64",
+ "85.185.93.69",
+ "85.185.93.90",
+ "85.185.93.115",
+ "85.185.93.117",
+ "85.185.93.118",
+ "85.185.95.134",
+ "85.185.95.141",
+ "85.185.99.235",
+ "85.185.101.66",
+ "85.185.101.67",
+ "85.185.101.69",
+ "85.185.104.21",
+ "85.185.105.99",
+ "85.185.123.3",
+ "85.185.123.4",
+ "85.185.123.5",
+ "85.185.123.121",
+ "85.185.123.122",
+ "85.185.152.66",
+ "85.185.153.10",
+ "85.185.157.2",
+ "85.185.158.236",
+ "85.185.159.197",
+ "85.185.161.4",
+ "85.185.161.5",
+ "85.185.161.25",
+ "85.185.161.30",
+ "85.185.161.49",
+ "85.185.161.73",
+ "85.185.161.77",
+ "85.185.161.83",
+ "85.185.161.140",
+ "85.185.163.4",
+ "85.185.163.101",
+ "85.185.163.106",
+ "85.185.163.123",
+ "85.185.165.12",
+ "85.185.165.13",
+ "85.185.170.245",
+ "85.185.201.6",
+ "85.185.201.7",
+ "85.185.201.11",
+ "85.185.201.13",
+ "85.185.201.18",
+ "85.185.201.20",
+ "85.185.201.21",
+ "85.185.201.22",
+ "85.185.201.26",
+ "85.185.201.35",
+ "85.185.206.226",
+ "85.185.211.17",
+ "85.185.211.19",
+ "85.185.215.43",
+ "85.185.231.22",
+ "85.185.231.42",
+ "85.185.232.135",
+ "85.185.236.66",
+ "85.185.237.114",
+ "85.185.250.67",
+ "85.185.250.250",
+ "85.185.251.253",
+ "85.185.254.95",
+ "85.198.1.10",
+ "85.198.1.26",
+ "85.198.9.221",
+ "85.198.12.178",
+ "85.198.14.3",
+ "85.198.16.43",
+ "85.198.17.29",
+ "85.198.17.91",
+ "85.198.26.46",
+ "85.198.29.12",
+ "85.204.77.179",
+ "85.204.104.34",
+ "85.204.104.47",
+ "85.208.253.13",
+ "85.208.253.15",
+ "85.208.253.16",
+ "85.208.253.19",
+ "85.208.253.22",
+ "85.208.253.26",
+ "85.208.253.37",
+ "85.208.253.39",
+ "85.208.253.40",
+ "85.208.253.44",
+ "85.208.253.48",
+ "85.208.253.50",
+ "85.208.253.52",
+ "85.208.253.53",
+ "85.208.253.60",
+ "85.208.253.75",
+ "85.208.253.77",
+ "85.208.253.78",
+ "85.208.253.91",
+ "85.208.253.92",
+ "85.208.253.102",
+ "85.208.253.103",
+ "85.208.253.106",
+ "85.208.253.107",
+ "85.208.253.112",
+ "85.208.253.127",
+ "85.208.253.129",
+ "85.208.253.133",
+ "85.208.253.142",
+ "85.208.253.149",
+ "85.208.253.150",
+ "85.208.253.151",
+ "85.208.253.153",
+ "85.208.253.155",
+ "85.208.253.159",
+ "85.208.253.169",
+ "85.208.253.173",
+ "85.208.253.180",
+ "85.208.253.181",
+ "85.208.253.182",
+ "85.208.253.183",
+ "85.208.253.186",
+ "85.208.253.191",
+ "85.208.253.194",
+ "85.208.253.196",
+ "85.208.253.199",
+ "85.208.253.202",
+ "85.208.253.205",
+ "85.208.253.208",
+ "85.208.253.211",
+ "85.208.253.218",
+ "85.208.253.219",
+ "85.208.253.224",
+ "85.208.253.226",
+ "85.208.253.235",
+ "85.208.253.237",
+ "85.208.253.239",
+ "85.208.253.242",
+ "85.208.253.249",
+ "85.208.253.253",
+ "85.208.254.38",
+ "85.208.254.51",
+ "85.208.254.55",
+ "85.208.254.58",
+ "85.208.254.59",
+ "85.208.254.64",
+ "85.208.254.143",
+ "85.208.254.145",
+ "85.208.254.147",
+ "85.208.254.155",
+ "85.208.254.156",
+ "85.208.254.168",
+ "85.208.254.173",
+ "85.208.254.175",
+ "85.208.254.177",
+ "85.208.254.183",
+ "85.208.254.192",
+ "85.208.254.194",
+ "85.208.254.195",
+ "85.208.254.198",
+ "85.208.254.199",
+ "85.208.254.202",
+ "85.208.254.208",
+ "85.208.254.214",
+ "85.208.254.216",
+ "85.208.254.225",
+ "85.208.254.228",
+ "85.208.254.231",
+ "85.208.254.234",
+ "85.208.254.237",
+ "85.208.254.248",
+ "85.208.254.250",
+ "86.104.32.2",
+ "86.104.32.36",
+ "86.104.32.60",
+ "86.104.32.73",
+ "86.104.32.84",
+ "86.104.32.119",
+ "86.104.32.131",
+ "86.104.32.163",
+ "86.104.32.188",
+ "86.104.32.192",
+ "86.104.32.245",
+ "86.104.32.248",
+ "86.104.32.252",
+ "86.104.33.230",
+ "86.104.33.235",
+ "86.104.35.182",
+ "86.104.35.183",
+ "86.104.35.184",
+ "86.104.35.186",
+ "86.104.35.187",
+ "86.104.35.188",
+ "86.104.35.189",
+ "86.104.37.4",
+ "86.104.37.8",
+ "86.104.37.12",
+ "86.104.37.37",
+ "86.104.37.63",
+ "86.104.37.66",
+ "86.104.37.106",
+ "86.104.39.4",
+ "86.104.39.5",
+ "86.104.39.101",
+ "86.104.44.51",
+ "86.104.44.52",
+ "86.104.44.53",
+ "86.104.44.54",
+ "86.104.44.55",
+ "86.104.44.56",
+ "86.104.44.57",
+ "86.104.44.58",
+ "86.104.44.59",
+ "86.104.244.145",
+ "86.106.142.7",
+ "86.106.142.10",
+ "86.106.142.12",
+ "86.106.142.13",
+ "86.106.142.14",
+ "86.106.142.17",
+ "86.106.142.18",
+ "86.106.142.19",
+ "86.106.142.20",
+ "86.106.142.27",
+ "86.106.142.31",
+ "86.106.142.32",
+ "86.106.142.33",
+ "86.106.142.42",
+ "86.106.142.45",
+ "86.106.142.47",
+ "86.106.142.53",
+ "86.106.142.54",
+ "86.106.142.66",
+ "86.106.142.101",
+ "86.106.142.109",
+ "86.106.142.111",
+ "86.106.142.115",
+ "86.106.142.118",
+ "86.106.142.120",
+ "86.106.142.121",
+ "86.106.142.122",
+ "86.106.142.124",
+ "86.107.14.240",
+ "86.107.144.157",
+ "86.107.146.145",
+ "86.107.155.83",
+ "86.107.158.199",
+ "87.107.6.2",
+ "87.107.6.3",
+ "87.107.6.4",
+ "87.107.6.5",
+ "87.107.6.6",
+ "87.107.6.7",
+ "87.107.6.8",
+ "87.107.6.9",
+ "87.107.6.10",
+ "87.107.6.11",
+ "87.107.6.12",
+ "87.107.6.13",
+ "87.107.6.14",
+ "87.107.6.15",
+ "87.107.6.16",
+ "87.107.6.18",
+ "87.107.6.19",
+ "87.107.6.20",
+ "87.107.6.21",
+ "87.107.6.22",
+ "87.107.6.24",
+ "87.107.6.25",
+ "87.107.6.26",
+ "87.107.6.27",
+ "87.107.6.28",
+ "87.107.6.29",
+ "87.107.6.30",
+ "87.107.6.31",
+ "87.107.6.32",
+ "87.107.6.33",
+ "87.107.6.34",
+ "87.107.6.35",
+ "87.107.6.37",
+ "87.107.6.38",
+ "87.107.6.39",
+ "87.107.6.40",
+ "87.107.6.41",
+ "87.107.6.42",
+ "87.107.6.43",
+ "87.107.6.44",
+ "87.107.6.45",
+ "87.107.6.46",
+ "87.107.6.47",
+ "87.107.6.48",
+ "87.107.6.49",
+ "87.107.6.50",
+ "87.107.6.51",
+ "87.107.6.52",
+ "87.107.6.53",
+ "87.107.6.54",
+ "87.107.6.55",
+ "87.107.6.56",
+ "87.107.6.57",
+ "87.107.6.58",
+ "87.107.6.61",
+ "87.107.6.62",
+ "87.107.6.63",
+ "87.107.6.64",
+ "87.107.6.65",
+ "87.107.6.66",
+ "87.107.6.67",
+ "87.107.6.68",
+ "87.107.6.69",
+ "87.107.6.70",
+ "87.107.6.71",
+ "87.107.6.72",
+ "87.107.6.73",
+ "87.107.6.74",
+ "87.107.6.75",
+ "87.107.6.76",
+ "87.107.6.77",
+ "87.107.6.78",
+ "87.107.6.79",
+ "87.107.6.80",
+ "87.107.6.81",
+ "87.107.6.82",
+ "87.107.6.83",
+ "87.107.6.85",
+ "87.107.6.86",
+ "87.107.6.87",
+ "87.107.6.88",
+ "87.107.6.89",
+ "87.107.6.90",
+ "87.107.6.91",
+ "87.107.6.92",
+ "87.107.6.93",
+ "87.107.6.94",
+ "87.107.6.95",
+ "87.107.6.96",
+ "87.107.6.98",
+ "87.107.6.99",
+ "87.107.6.100",
+ "87.107.6.101",
+ "87.107.6.102",
+ "87.107.6.103",
+ "87.107.6.104",
+ "87.107.6.105",
+ "87.107.6.106",
+ "87.107.6.107",
+ "87.107.6.108",
+ "87.107.6.109",
+ "87.107.6.110",
+ "87.107.6.111",
+ "87.107.6.112",
+ "87.107.6.113",
+ "87.107.6.114",
+ "87.107.6.115",
+ "87.107.6.116",
+ "87.107.6.117",
+ "87.107.6.118",
+ "87.107.6.119",
+ "87.107.6.120",
+ "87.107.6.121",
+ "87.107.6.122",
+ "87.107.6.123",
+ "87.107.6.124",
+ "87.107.6.125",
+ "87.107.6.126",
+ "87.107.6.171",
+ "87.107.6.178",
+ "87.107.6.198",
+ "87.107.7.19",
+ "87.107.7.30",
+ "87.107.7.54",
+ "87.107.7.67",
+ "87.107.7.69",
+ "87.107.7.70",
+ "87.107.7.71",
+ "87.107.7.74",
+ "87.107.7.75",
+ "87.107.7.78",
+ "87.107.7.81",
+ "87.107.7.88",
+ "87.107.7.92",
+ "87.107.7.110",
+ "87.107.7.168",
+ "87.107.7.173",
+ "87.107.7.210",
+ "87.107.8.21",
+ "87.107.8.86",
+ "87.107.8.92",
+ "87.107.8.98",
+ "87.107.8.138",
+ "87.107.8.170",
+ "87.107.8.174",
+ "87.107.8.227",
+ "87.107.9.37",
+ "87.107.9.67",
+ "87.107.9.68",
+ "87.107.9.69",
+ "87.107.9.71",
+ "87.107.9.75",
+ "87.107.9.76",
+ "87.107.9.78",
+ "87.107.9.91",
+ "87.107.9.206",
+ "87.107.9.232",
+ "87.107.9.233",
+ "87.107.9.236",
+ "87.107.9.237",
+ "87.107.9.238",
+ "87.107.9.241",
+ "87.107.9.248",
+ "87.107.10.46",
+ "87.107.10.99",
+ "87.107.10.100",
+ "87.107.10.147",
+ "87.107.10.210",
+ "87.107.10.234",
+ "87.107.11.82",
+ "87.107.12.4",
+ "87.107.12.70",
+ "87.107.12.71",
+ "87.107.12.124",
+ "87.107.12.136",
+ "87.107.12.188",
+ "87.107.12.211",
+ "87.107.12.217",
+ "87.107.13.138",
+ "87.107.13.139",
+ "87.107.13.140",
+ "87.107.13.141",
+ "87.107.13.142",
+ "87.107.13.190",
+ "87.107.19.195",
+ "87.107.19.197",
+ "87.107.27.3",
+ "87.107.28.26",
+ "87.107.28.27",
+ "87.107.28.222",
+ "87.107.29.82",
+ "87.107.29.83",
+ "87.107.29.84",
+ "87.107.29.230",
+ "87.107.30.149",
+ "87.107.45.9",
+ "87.107.49.14",
+ "87.107.50.36",
+ "87.107.52.98",
+ "87.107.52.198",
+ "87.107.52.202",
+ "87.107.52.206",
+ "87.107.52.212",
+ "87.107.54.18",
+ "87.107.54.47",
+ "87.107.54.49",
+ "87.107.54.76",
+ "87.107.54.144",
+ "87.107.54.153",
+ "87.107.54.156",
+ "87.107.54.212",
+ "87.107.54.224",
+ "87.107.54.243",
+ "87.107.55.10",
+ "87.107.55.11",
+ "87.107.55.55",
+ "87.107.55.70",
+ "87.107.55.85",
+ "87.107.55.101",
+ "87.107.55.106",
+ "87.107.55.117",
+ "87.107.55.178",
+ "87.107.55.179",
+ "87.107.55.180",
+ "87.107.55.182",
+ "87.107.55.186",
+ "87.107.55.194",
+ "87.107.68.36",
+ "87.107.68.52",
+ "87.107.68.59",
+ "87.107.68.62",
+ "87.107.68.69",
+ "87.107.68.79",
+ "87.107.68.92",
+ "87.107.68.156",
+ "87.107.68.171",
+ "87.107.69.3",
+ "87.107.69.4",
+ "87.107.69.163",
+ "87.107.69.169",
+ "87.107.69.171",
+ "87.107.69.172",
+ "87.107.69.179",
+ "87.107.69.180",
+ "87.107.73.55",
+ "87.107.73.61",
+ "87.107.73.212",
+ "87.107.73.214",
+ "87.107.76.91",
+ "87.107.76.92",
+ "87.107.82.245",
+ "87.107.86.240",
+ "87.107.86.241",
+ "87.107.87.67",
+ "87.107.87.68",
+ "87.107.87.69",
+ "87.107.91.66",
+ "87.107.100.215",
+ "87.107.102.5",
+ "87.107.102.6",
+ "87.107.102.7",
+ "87.107.102.15",
+ "87.107.102.16",
+ "87.107.102.18",
+ "87.107.102.19",
+ "87.107.102.21",
+ "87.107.102.23",
+ "87.107.102.24",
+ "87.107.102.25",
+ "87.107.102.27",
+ "87.107.102.28",
+ "87.107.102.29",
+ "87.107.102.30",
+ "87.107.102.61",
+ "87.107.102.68",
+ "87.107.102.90",
+ "87.107.102.122",
+ "87.107.102.126",
+ "87.107.104.14",
+ "87.107.104.21",
+ "87.107.104.26",
+ "87.107.104.33",
+ "87.107.104.74",
+ "87.107.104.81",
+ "87.107.104.86",
+ "87.107.104.91",
+ "87.107.104.107",
+ "87.107.104.117",
+ "87.107.104.120",
+ "87.107.104.122",
+ "87.107.104.124",
+ "87.107.104.144",
+ "87.107.104.147",
+ "87.107.104.211",
+ "87.107.104.247",
+ "87.107.104.250",
+ "87.107.104.252",
+ "87.107.105.20",
+ "87.107.105.37",
+ "87.107.105.51",
+ "87.107.105.65",
+ "87.107.105.67",
+ "87.107.105.72",
+ "87.107.105.84",
+ "87.107.105.86",
+ "87.107.105.97",
+ "87.107.105.102",
+ "87.107.105.137",
+ "87.107.105.139",
+ "87.107.105.163",
+ "87.107.105.179",
+ "87.107.105.181",
+ "87.107.105.190",
+ "87.107.105.230",
+ "87.107.105.234",
+ "87.107.108.13",
+ "87.107.108.15",
+ "87.107.108.28",
+ "87.107.108.43",
+ "87.107.108.44",
+ "87.107.108.61",
+ "87.107.108.86",
+ "87.107.108.87",
+ "87.107.108.90",
+ "87.107.108.111",
+ "87.107.108.152",
+ "87.107.108.158",
+ "87.107.108.162",
+ "87.107.108.172",
+ "87.107.108.212",
+ "87.107.108.216",
+ "87.107.109.11",
+ "87.107.109.12",
+ "87.107.109.13",
+ "87.107.109.22",
+ "87.107.109.34",
+ "87.107.109.77",
+ "87.107.109.84",
+ "87.107.109.105",
+ "87.107.109.106",
+ "87.107.109.109",
+ "87.107.109.110",
+ "87.107.109.143",
+ "87.107.109.174",
+ "87.107.109.254",
+ "87.107.110.6",
+ "87.107.110.7",
+ "87.107.110.8",
+ "87.107.110.11",
+ "87.107.110.12",
+ "87.107.110.13",
+ "87.107.110.14",
+ "87.107.110.15",
+ "87.107.110.20",
+ "87.107.110.21",
+ "87.107.110.24",
+ "87.107.110.27",
+ "87.107.110.29",
+ "87.107.110.30",
+ "87.107.110.109",
+ "87.107.110.110",
+ "87.107.110.165",
+ "87.107.110.196",
+ "87.107.111.21",
+ "87.107.111.32",
+ "87.107.111.37",
+ "87.107.111.38",
+ "87.107.111.58",
+ "87.107.111.104",
+ "87.107.111.113",
+ "87.107.111.123",
+ "87.107.116.4",
+ "87.107.116.218",
+ "87.107.121.16",
+ "87.107.121.24",
+ "87.107.121.59",
+ "87.107.121.60",
+ "87.107.121.61",
+ "87.107.121.66",
+ "87.107.121.70",
+ "87.107.121.84",
+ "87.107.121.110",
+ "87.107.121.197",
+ "87.107.121.227",
+ "87.107.121.234",
+ "87.107.124.19",
+ "87.107.124.100",
+ "87.107.124.109",
+ "87.107.124.116",
+ "87.107.124.118",
+ "87.107.132.36",
+ "87.107.132.38",
+ "87.107.132.50",
+ "87.107.132.77",
+ "87.107.133.73",
+ "87.107.133.81",
+ "87.107.134.94",
+ "87.107.139.60",
+ "87.107.143.24",
+ "87.107.144.26",
+ "87.107.144.51",
+ "87.107.144.53",
+ "87.107.144.55",
+ "87.107.144.56",
+ "87.107.144.57",
+ "87.107.144.58",
+ "87.107.144.60",
+ "87.107.144.61",
+ "87.107.144.212",
+ "87.107.144.234",
+ "87.107.144.246",
+ "87.107.146.13",
+ "87.107.146.21",
+ "87.107.146.41",
+ "87.107.146.43",
+ "87.107.146.54",
+ "87.107.146.70",
+ "87.107.146.72",
+ "87.107.146.79",
+ "87.107.146.83",
+ "87.107.146.95",
+ "87.107.146.133",
+ "87.107.146.157",
+ "87.107.146.160",
+ "87.107.146.170",
+ "87.107.146.171",
+ "87.107.146.178",
+ "87.107.146.199",
+ "87.107.146.205",
+ "87.107.146.214",
+ "87.107.146.221",
+ "87.107.147.34",
+ "87.107.147.46",
+ "87.107.147.86",
+ "87.107.147.106",
+ "87.107.147.122",
+ "87.107.147.158",
+ "87.107.150.10",
+ "87.107.152.10",
+ "87.107.152.22",
+ "87.107.152.23",
+ "87.107.152.84",
+ "87.107.152.118",
+ "87.107.152.133",
+ "87.107.152.134",
+ "87.107.152.139",
+ "87.107.152.150",
+ "87.107.152.186",
+ "87.107.153.5",
+ "87.107.153.10",
+ "87.107.153.11",
+ "87.107.153.60",
+ "87.107.153.84",
+ "87.107.153.102",
+ "87.107.153.131",
+ "87.107.153.254",
+ "87.107.154.18",
+ "87.107.154.20",
+ "87.107.154.21",
+ "87.107.154.22",
+ "87.107.154.42",
+ "87.107.154.43",
+ "87.107.154.44",
+ "87.107.154.94",
+ "87.107.154.107",
+ "87.107.154.109",
+ "87.107.154.123",
+ "87.107.154.140",
+ "87.107.155.59",
+ "87.107.155.63",
+ "87.107.155.70",
+ "87.107.155.78",
+ "87.107.155.94",
+ "87.107.155.95",
+ "87.107.155.98",
+ "87.107.155.110",
+ "87.107.155.119",
+ "87.107.155.143",
+ "87.107.155.147",
+ "87.107.155.157",
+ "87.107.155.181",
+ "87.107.155.221",
+ "87.107.155.230",
+ "87.107.155.243",
+ "87.107.159.57",
+ "87.107.164.10",
+ "87.107.164.68",
+ "87.107.164.81",
+ "87.107.164.85",
+ "87.107.164.99",
+ "87.107.164.119",
+ "87.107.164.120",
+ "87.107.164.134",
+ "87.107.164.138",
+ "87.107.164.142",
+ "87.107.164.167",
+ "87.107.164.191",
+ "87.107.164.223",
+ "87.107.164.230",
+ "87.107.164.233",
+ "87.107.164.234",
+ "87.107.164.238",
+ "87.107.164.241",
+ "87.107.165.4",
+ "87.107.165.10",
+ "87.107.165.24",
+ "87.107.165.66",
+ "87.107.165.86",
+ "87.107.165.87",
+ "87.107.165.95",
+ "87.107.165.113",
+ "87.107.165.114",
+ "87.107.165.119",
+ "87.107.165.149",
+ "87.107.165.168",
+ "87.107.165.175",
+ "87.107.165.184",
+ "87.107.165.207",
+ "87.107.165.217",
+ "87.107.165.222",
+ "87.107.165.249",
+ "87.107.166.10",
+ "87.107.166.35",
+ "87.107.166.203",
+ "87.107.166.213",
+ "87.107.172.8",
+ "87.107.172.84",
+ "87.107.174.19",
+ "87.107.174.52",
+ "87.107.174.100",
+ "87.107.174.182",
+ "87.107.174.189",
+ "87.107.175.5",
+ "87.107.175.7",
+ "87.107.175.104",
+ "87.107.175.107",
+ "87.107.175.162",
+ "87.107.175.166",
+ "87.107.175.182",
+ "87.107.175.218",
+ "87.107.184.40",
+ "87.107.184.123",
+ "87.107.185.33",
+ "87.107.185.34",
+ "87.107.185.234",
+ "87.107.186.4",
+ "87.107.190.4",
+ "87.107.190.117",
+ "87.107.191.49",
+ "87.236.38.106",
+ "87.236.38.107",
+ "87.236.39.40",
+ "87.236.39.43",
+ "87.236.39.120",
+ "87.236.39.133",
+ "87.236.209.20",
+ "87.236.209.38",
+ "87.236.209.77",
+ "87.236.209.154",
+ "87.236.209.196",
+ "87.236.209.199",
+ "87.236.209.201",
+ "87.236.209.203",
+ "87.236.209.207",
+ "87.236.209.209",
+ "87.236.209.210",
+ "87.236.209.211",
+ "87.236.209.219",
+ "87.236.209.220",
+ "87.236.209.222",
+ "87.236.209.227",
+ "87.236.209.228",
+ "87.236.209.235",
+ "87.236.209.236",
+ "87.236.210.4",
+ "87.236.210.5",
+ "87.236.210.6",
+ "87.236.210.9",
+ "87.236.210.11",
+ "87.236.210.12",
+ "87.236.210.15",
+ "87.236.210.18",
+ "87.236.210.20",
+ "87.236.210.21",
+ "87.236.210.22",
+ "87.236.210.25",
+ "87.236.210.26",
+ "87.236.210.27",
+ "87.236.210.28",
+ "87.236.210.30",
+ "87.236.210.32",
+ "87.236.210.36",
+ "87.236.210.37",
+ "87.236.210.38",
+ "87.236.210.39",
+ "87.236.210.44",
+ "87.236.210.45",
+ "87.236.210.47",
+ "87.236.210.51",
+ "87.236.210.52",
+ "87.236.210.55",
+ "87.236.210.56",
+ "87.236.210.58",
+ "87.236.210.59",
+ "87.236.210.61",
+ "87.236.210.66",
+ "87.236.210.67",
+ "87.236.210.68",
+ "87.236.210.71",
+ "87.236.210.72",
+ "87.236.210.73",
+ "87.236.210.74",
+ "87.236.210.77",
+ "87.236.210.79",
+ "87.236.210.81",
+ "87.236.210.82",
+ "87.236.210.85",
+ "87.236.210.86",
+ "87.236.210.87",
+ "87.236.210.88",
+ "87.236.210.89",
+ "87.236.210.92",
+ "87.236.210.93",
+ "87.236.210.99",
+ "87.236.210.101",
+ "87.236.210.102",
+ "87.236.210.106",
+ "87.236.210.107",
+ "87.236.210.108",
+ "87.236.210.109",
+ "87.236.210.110",
+ "87.236.210.112",
+ "87.236.210.114",
+ "87.236.210.115",
+ "87.236.210.116",
+ "87.236.210.117",
+ "87.236.210.118",
+ "87.236.210.120",
+ "87.236.210.122",
+ "87.236.210.123",
+ "87.236.210.124",
+ "87.236.210.127",
+ "87.236.210.130",
+ "87.236.210.131",
+ "87.236.210.132",
+ "87.236.210.133",
+ "87.236.210.134",
+ "87.236.210.136",
+ "87.236.210.138",
+ "87.236.210.139",
+ "87.236.210.140",
+ "87.236.210.142",
+ "87.236.210.143",
+ "87.236.210.144",
+ "87.236.210.145",
+ "87.236.210.148",
+ "87.236.210.149",
+ "87.236.210.150",
+ "87.236.210.153",
+ "87.236.210.154",
+ "87.236.210.155",
+ "87.236.210.156",
+ "87.236.210.158",
+ "87.236.210.159",
+ "87.236.210.160",
+ "87.236.210.161",
+ "87.236.210.162",
+ "87.236.210.163",
+ "87.236.210.164",
+ "87.236.210.170",
+ "87.236.210.171",
+ "87.236.210.173",
+ "87.236.210.175",
+ "87.236.210.182",
+ "87.236.210.183",
+ "87.236.210.185",
+ "87.236.210.188",
+ "87.236.210.189",
+ "87.236.210.190",
+ "87.236.210.193",
+ "87.236.210.195",
+ "87.236.210.196",
+ "87.236.210.199",
+ "87.236.210.202",
+ "87.236.210.203",
+ "87.236.210.205",
+ "87.236.210.207",
+ "87.236.210.208",
+ "87.236.210.209",
+ "87.236.210.212",
+ "87.236.210.214",
+ "87.236.210.215",
+ "87.236.210.216",
+ "87.236.210.217",
+ "87.236.210.218",
+ "87.236.210.221",
+ "87.236.210.224",
+ "87.236.210.225",
+ "87.236.210.228",
+ "87.236.211.3",
+ "87.236.211.8",
+ "87.236.211.10",
+ "87.236.211.13",
+ "87.236.211.14",
+ "87.236.211.16",
+ "87.236.211.21",
+ "87.236.211.22",
+ "87.236.211.23",
+ "87.236.211.24",
+ "87.236.211.28",
+ "87.236.211.29",
+ "87.236.211.67",
+ "87.236.211.69",
+ "87.236.211.72",
+ "87.236.211.74",
+ "87.236.211.81",
+ "87.236.211.82",
+ "87.236.211.85",
+ "87.236.211.87",
+ "87.236.211.88",
+ "87.236.211.89",
+ "87.236.211.90",
+ "87.236.211.91",
+ "87.236.211.93",
+ "87.236.211.96",
+ "87.236.211.98",
+ "87.236.211.99",
+ "87.236.211.100",
+ "87.236.211.101",
+ "87.236.211.104",
+ "87.236.211.106",
+ "87.236.211.107",
+ "87.236.211.108",
+ "87.236.211.109",
+ "87.236.211.110",
+ "87.236.211.111",
+ "87.236.211.113",
+ "87.236.211.114",
+ "87.236.211.115",
+ "87.236.211.116",
+ "87.236.211.117",
+ "87.236.211.118",
+ "87.236.211.123",
+ "87.236.211.126",
+ "87.236.211.210",
+ "87.236.211.211",
+ "87.236.211.212",
+ "87.236.211.213",
+ "87.236.211.214",
+ "87.236.211.215",
+ "87.236.211.218",
+ "87.236.211.219",
+ "87.236.211.221",
+ "87.236.211.226",
+ "87.236.211.227",
+ "87.236.211.228",
+ "87.236.211.229",
+ "87.236.211.231",
+ "87.236.211.232",
+ "87.236.211.234",
+ "87.236.211.237",
+ "87.236.212.68",
+ "87.236.212.126",
+ "87.236.212.162",
+ "87.236.212.195",
+ "87.236.213.139",
+ "87.236.215.42",
+ "87.236.215.46",
+ "87.236.215.106",
+ "87.236.215.166",
+ "87.236.215.246",
+ "87.247.171.247",
+ "87.247.174.180",
+ "87.247.175.72",
+ "87.247.175.212",
+ "87.247.176.22",
+ "87.247.176.46",
+ "87.247.176.49",
+ "87.247.176.50",
+ "87.247.176.54",
+ "87.247.176.55",
+ "87.247.176.56",
+ "87.247.176.64",
+ "87.247.176.67",
+ "87.247.176.241",
+ "87.247.177.4",
+ "87.247.177.6",
+ "87.247.177.22",
+ "87.247.177.23",
+ "87.247.177.26",
+ "87.247.177.28",
+ "87.247.177.31",
+ "87.247.177.62",
+ "87.247.177.68",
+ "87.247.177.69",
+ "87.247.177.70",
+ "87.247.177.71",
+ "87.247.177.72",
+ "87.247.177.73",
+ "87.247.177.74",
+ "87.247.177.80",
+ "87.247.177.109",
+ "87.247.177.131",
+ "87.247.177.241",
+ "87.247.177.242",
+ "87.247.185.75",
+ "87.247.185.123",
+ "87.247.186.129",
+ "87.247.186.200",
+ "87.247.188.212",
+ "87.248.128.10",
+ "87.248.128.11",
+ "87.248.128.20",
+ "87.248.128.23",
+ "87.248.128.26",
+ "87.248.128.128",
+ "87.248.128.207",
+ "87.248.130.71",
+ "87.248.130.80",
+ "87.248.130.97",
+ "87.248.130.122",
+ "87.248.130.146",
+ "87.248.130.151",
+ "87.248.130.166",
+ "87.248.130.192",
+ "87.248.130.206",
+ "87.248.130.212",
+ "87.248.130.244",
+ "87.248.133.90",
+ "87.248.133.115",
+ "87.248.133.139",
+ "87.248.137.2",
+ "87.248.137.11",
+ "87.248.137.75",
+ "87.248.137.170",
+ "87.248.138.93",
+ "87.248.138.114",
+ "87.248.138.170",
+ "87.248.138.210",
+ "87.248.138.218",
+ "87.248.138.246",
+ "87.248.139.45",
+ "87.248.139.70",
+ "87.248.139.74",
+ "87.248.139.92",
+ "87.248.139.98",
+ "87.248.139.179",
+ "87.248.139.197",
+ "87.248.139.200",
+ "87.248.139.201",
+ "87.248.139.216",
+ "87.248.139.252",
+ "87.248.145.5",
+ "87.248.145.81",
+ "87.248.145.90",
+ "87.248.145.121",
+ "87.248.145.164",
+ "87.248.145.179",
+ "87.248.145.201",
+ "87.248.145.207",
+ "87.248.145.208",
+ "87.248.145.246",
+ "87.248.147.224",
+ "87.248.147.227",
+ "87.248.147.228",
+ "87.248.147.233",
+ "87.248.147.239",
+ "87.248.147.248",
+ "87.248.147.251",
+ "87.248.147.252",
+ "87.248.150.4",
+ "87.248.150.9",
+ "87.248.150.40",
+ "87.248.150.41",
+ "87.248.150.52",
+ "87.248.150.138",
+ "87.248.150.142",
+ "87.248.150.170",
+ "87.248.150.171",
+ "87.248.150.172",
+ "87.248.150.175",
+ "87.248.150.176",
+ "87.248.150.204",
+ "87.248.150.208",
+ "87.248.150.222",
+ "87.248.150.250",
+ "87.248.151.100",
+ "87.248.151.102",
+ "87.248.151.114",
+ "87.248.151.115",
+ "87.248.151.116",
+ "87.248.151.118",
+ "87.248.151.122",
+ "87.248.151.123",
+ "87.248.151.125",
+ "87.248.151.126",
+ "87.248.151.183",
+ "87.248.151.194",
+ "87.248.152.10",
+ "87.248.152.16",
+ "87.248.152.29",
+ "87.248.152.40",
+ "87.248.152.53",
+ "87.248.152.79",
+ "87.248.152.88",
+ "87.248.152.102",
+ "87.248.152.124",
+ "87.248.152.125",
+ "87.248.152.138",
+ "87.248.152.140",
+ "87.248.152.149",
+ "87.248.152.161",
+ "87.248.152.210",
+ "87.248.152.223",
+ "87.248.152.240",
+ "87.248.152.247",
+ "87.248.153.24",
+ "87.248.153.38",
+ "87.248.153.43",
+ "87.248.153.52",
+ "87.248.153.62",
+ "87.248.153.64",
+ "87.248.153.83",
+ "87.248.153.86",
+ "87.248.153.87",
+ "87.248.153.88",
+ "87.248.153.90",
+ "87.248.153.93",
+ "87.248.153.95",
+ "87.248.153.96",
+ "87.248.153.101",
+ "87.248.153.109",
+ "87.248.153.133",
+ "87.248.153.141",
+ "87.248.153.142",
+ "87.248.153.147",
+ "87.248.153.167",
+ "87.248.153.192",
+ "87.248.153.217",
+ "87.248.153.220",
+ "87.248.153.244",
+ "87.248.153.252",
+ "87.248.153.253",
+ "87.248.155.12",
+ "87.248.155.27",
+ "87.248.155.38",
+ "87.248.155.44",
+ "87.248.155.56",
+ "87.248.155.113",
+ "87.248.155.122",
+ "87.248.155.129",
+ "87.248.155.167",
+ "87.248.155.175",
+ "87.248.155.179",
+ "87.248.155.203",
+ "87.248.155.206",
+ "87.248.155.216",
+ "87.248.155.222",
+ "87.248.155.227",
+ "87.248.155.237",
+ "87.248.156.14",
+ "87.248.156.15",
+ "87.248.156.17",
+ "87.248.156.31",
+ "87.248.156.41",
+ "87.248.156.75",
+ "87.248.156.91",
+ "87.248.156.98",
+ "87.248.156.108",
+ "87.248.156.113",
+ "87.248.156.127",
+ "87.248.156.128",
+ "87.248.156.129",
+ "87.248.156.140",
+ "87.248.156.150",
+ "87.248.156.162",
+ "87.248.156.183",
+ "87.248.156.191",
+ "87.248.156.204",
+ "87.248.156.239",
+ "87.248.156.242",
+ "88.135.36.35",
+ "88.135.36.39",
+ "88.135.36.65",
+ "88.135.37.47",
+ "88.135.37.70",
+ "88.135.37.85",
+ "88.135.38.19",
+ "88.135.38.54",
+ "88.135.39.28",
+ "88.135.68.1",
+ "88.135.68.3",
+ "88.135.68.5",
+ "88.135.68.6",
+ "88.135.68.7",
+ "88.135.68.9",
+ "88.135.68.10",
+ "88.135.68.11",
+ "88.135.68.12",
+ "88.135.68.13",
+ "88.135.68.16",
+ "88.135.68.17",
+ "88.135.68.25",
+ "88.135.68.26",
+ "88.135.68.27",
+ "88.135.68.28",
+ "88.135.68.29",
+ "88.135.68.30",
+ "88.135.68.98",
+ "88.135.68.99",
+ "88.135.68.100",
+ "88.135.68.247",
+ "88.135.68.248",
+ "88.135.68.249",
+ "88.135.75.22",
+ "88.135.75.23",
+ "88.135.75.31",
+ "88.135.75.132",
+ "88.135.75.133",
+ "88.135.75.134",
+ "88.135.75.135",
+ "88.135.75.138",
+ "88.135.75.141",
+ "88.135.75.142",
+ "88.135.75.146",
+ "88.135.75.150",
+ "88.135.75.151",
+ "88.135.75.152",
+ "88.135.75.153",
+ "88.135.75.155",
+ "88.135.75.156",
+ "88.135.75.157",
+ "88.135.75.178",
+ "88.135.75.179",
+ "88.135.75.181",
+ "88.135.75.194",
+ "88.135.75.202",
+ "88.135.75.206",
+ "88.218.16.122",
+ "89.32.197.22",
+ "89.32.197.226",
+ "89.32.248.3",
+ "89.32.248.5",
+ "89.32.248.6",
+ "89.32.248.7",
+ "89.32.248.8",
+ "89.32.248.10",
+ "89.32.248.11",
+ "89.32.248.12",
+ "89.32.248.13",
+ "89.32.248.14",
+ "89.32.248.16",
+ "89.32.248.18",
+ "89.32.248.19",
+ "89.32.248.20",
+ "89.32.248.23",
+ "89.32.248.24",
+ "89.32.248.25",
+ "89.32.248.26",
+ "89.32.248.27",
+ "89.32.248.28",
+ "89.32.248.35",
+ "89.32.248.37",
+ "89.32.248.38",
+ "89.32.248.41",
+ "89.32.248.49",
+ "89.32.248.50",
+ "89.32.248.51",
+ "89.32.248.54",
+ "89.32.248.60",
+ "89.32.248.66",
+ "89.32.248.67",
+ "89.32.248.68",
+ "89.32.248.69",
+ "89.32.248.70",
+ "89.32.248.74",
+ "89.32.248.75",
+ "89.32.248.76",
+ "89.32.248.77",
+ "89.32.248.83",
+ "89.32.248.84",
+ "89.32.248.86",
+ "89.32.248.88",
+ "89.32.248.89",
+ "89.32.248.90",
+ "89.32.248.91",
+ "89.32.248.93",
+ "89.32.248.94",
+ "89.32.248.131",
+ "89.32.248.138",
+ "89.32.248.139",
+ "89.32.248.140",
+ "89.32.248.142",
+ "89.32.248.158",
+ "89.32.248.164",
+ "89.32.248.170",
+ "89.32.248.190",
+ "89.32.248.193",
+ "89.32.248.195",
+ "89.32.248.196",
+ "89.32.248.197",
+ "89.32.248.198",
+ "89.32.248.205",
+ "89.32.248.211",
+ "89.32.248.212",
+ "89.32.248.213",
+ "89.32.248.216",
+ "89.32.248.219",
+ "89.32.248.231",
+ "89.32.248.233",
+ "89.32.248.235",
+ "89.32.248.236",
+ "89.32.248.238",
+ "89.32.248.245",
+ "89.32.248.246",
+ "89.32.248.247",
+ "89.32.248.251",
+ "89.32.248.252",
+ "89.32.249.3",
+ "89.32.249.10",
+ "89.32.249.14",
+ "89.32.249.15",
+ "89.32.249.27",
+ "89.32.249.29",
+ "89.32.249.30",
+ "89.32.249.66",
+ "89.32.249.67",
+ "89.32.249.69",
+ "89.32.249.72",
+ "89.32.249.73",
+ "89.32.249.75",
+ "89.32.249.76",
+ "89.32.249.77",
+ "89.32.249.78",
+ "89.32.249.84",
+ "89.32.249.87",
+ "89.32.249.88",
+ "89.32.249.101",
+ "89.32.249.103",
+ "89.32.249.106",
+ "89.32.249.117",
+ "89.32.249.118",
+ "89.32.249.119",
+ "89.32.249.120",
+ "89.32.249.121",
+ "89.32.249.124",
+ "89.32.249.125",
+ "89.32.249.130",
+ "89.32.249.146",
+ "89.32.249.147",
+ "89.32.249.148",
+ "89.32.249.150",
+ "89.32.249.154",
+ "89.32.249.155",
+ "89.32.249.156",
+ "89.32.249.158",
+ "89.32.249.166",
+ "89.32.249.167",
+ "89.32.249.168",
+ "89.32.249.169",
+ "89.32.249.171",
+ "89.32.249.172",
+ "89.32.249.178",
+ "89.32.249.187",
+ "89.32.249.194",
+ "89.32.249.202",
+ "89.32.249.215",
+ "89.32.249.232",
+ "89.32.249.238",
+ "89.32.249.241",
+ "89.32.249.242",
+ "89.32.249.245",
+ "89.32.249.246",
+ "89.32.249.247",
+ "89.32.249.253",
+ "89.32.251.2",
+ "89.32.251.3",
+ "89.32.251.4",
+ "89.32.251.5",
+ "89.32.251.6",
+ "89.32.251.7",
+ "89.32.251.9",
+ "89.32.251.10",
+ "89.32.251.11",
+ "89.32.251.14",
+ "89.32.251.70",
+ "89.32.251.71",
+ "89.32.251.73",
+ "89.32.251.79",
+ "89.32.251.80",
+ "89.32.251.84",
+ "89.32.251.85",
+ "89.32.251.90",
+ "89.32.251.94",
+ "89.32.251.96",
+ "89.32.251.102",
+ "89.32.251.103",
+ "89.32.251.104",
+ "89.32.251.105",
+ "89.32.251.110",
+ "89.32.251.112",
+ "89.32.251.115",
+ "89.32.251.122",
+ "89.32.251.124",
+ "89.32.251.125",
+ "89.32.251.132",
+ "89.32.251.167",
+ "89.33.129.171",
+ "89.33.241.44",
+ "89.34.176.99",
+ "89.35.133.178",
+ "89.35.176.20",
+ "89.35.176.24",
+ "89.37.0.211",
+ "89.37.5.189",
+ "89.37.6.162",
+ "89.37.12.76",
+ "89.37.13.115",
+ "89.37.15.116",
+ "89.37.219.155",
+ "89.37.219.186",
+ "89.37.219.187",
+ "89.37.250.122",
+ "89.39.208.11",
+ "89.39.208.13",
+ "89.39.208.14",
+ "89.39.208.18",
+ "89.39.208.19",
+ "89.39.208.20",
+ "89.39.208.22",
+ "89.39.208.28",
+ "89.39.208.30",
+ "89.39.208.34",
+ "89.39.208.35",
+ "89.39.208.36",
+ "89.39.208.38",
+ "89.39.208.41",
+ "89.39.208.42",
+ "89.39.208.44",
+ "89.39.208.45",
+ "89.39.208.48",
+ "89.39.208.49",
+ "89.39.208.50",
+ "89.39.208.55",
+ "89.39.208.57",
+ "89.39.208.62",
+ "89.39.208.66",
+ "89.39.208.67",
+ "89.39.208.68",
+ "89.39.208.70",
+ "89.39.208.84",
+ "89.39.208.86",
+ "89.39.208.87",
+ "89.39.208.88",
+ "89.39.208.89",
+ "89.39.208.90",
+ "89.39.208.91",
+ "89.39.208.93",
+ "89.39.208.94",
+ "89.39.208.98",
+ "89.39.208.99",
+ "89.39.208.100",
+ "89.39.208.101",
+ "89.39.208.102",
+ "89.39.208.110",
+ "89.39.208.119",
+ "89.39.208.130",
+ "89.39.208.131",
+ "89.39.208.132",
+ "89.39.208.134",
+ "89.39.208.135",
+ "89.39.208.136",
+ "89.39.208.137",
+ "89.39.208.146",
+ "89.39.208.147",
+ "89.39.208.148",
+ "89.39.208.152",
+ "89.39.208.153",
+ "89.39.208.154",
+ "89.39.208.155",
+ "89.39.208.162",
+ "89.39.208.163",
+ "89.39.208.164",
+ "89.39.208.165",
+ "89.39.208.170",
+ "89.39.208.173",
+ "89.39.208.178",
+ "89.39.208.179",
+ "89.39.208.180",
+ "89.39.208.181",
+ "89.39.208.184",
+ "89.39.208.185",
+ "89.39.208.186",
+ "89.39.208.187",
+ "89.39.208.188",
+ "89.39.208.190",
+ "89.39.208.195",
+ "89.39.208.196",
+ "89.39.208.197",
+ "89.39.208.198",
+ "89.39.208.199",
+ "89.39.208.200",
+ "89.39.208.202",
+ "89.39.208.203",
+ "89.39.208.204",
+ "89.39.208.205",
+ "89.39.208.206",
+ "89.39.208.209",
+ "89.39.208.210",
+ "89.39.208.212",
+ "89.39.208.213",
+ "89.39.208.216",
+ "89.39.208.218",
+ "89.39.208.219",
+ "89.39.208.240",
+ "89.39.208.241",
+ "89.39.208.242",
+ "89.39.208.246",
+ "89.39.208.247",
+ "89.39.208.250",
+ "89.39.208.251",
+ "89.40.78.156",
+ "89.40.246.40",
+ "89.40.247.81",
+ "89.42.136.6",
+ "89.42.136.67",
+ "89.42.136.94",
+ "89.42.137.119",
+ "89.42.137.122",
+ "89.42.137.195",
+ "89.42.138.21",
+ "89.42.138.66",
+ "89.42.138.71",
+ "89.42.138.74",
+ "89.42.138.98",
+ "89.42.138.124",
+ "89.42.138.212",
+ "89.42.138.243",
+ "89.42.138.244",
+ "89.42.138.245",
+ "89.42.138.246",
+ "89.42.138.247",
+ "89.42.138.248",
+ "89.42.138.249",
+ "89.42.138.250",
+ "89.42.138.251",
+ "89.42.138.252",
+ "89.42.138.253",
+ "89.42.138.254",
+ "89.42.139.142",
+ "89.42.139.180",
+ "89.42.139.181",
+ "89.42.139.182",
+ "89.42.139.187",
+ "89.42.197.254",
+ "89.42.199.49",
+ "89.42.199.137",
+ "89.42.208.14",
+ "89.42.208.15",
+ "89.42.208.16",
+ "89.42.208.17",
+ "89.42.208.21",
+ "89.42.208.25",
+ "89.42.208.26",
+ "89.42.208.27",
+ "89.42.208.28",
+ "89.42.208.29",
+ "89.42.208.33",
+ "89.42.208.34",
+ "89.42.208.40",
+ "89.42.208.46",
+ "89.42.208.51",
+ "89.42.208.53",
+ "89.42.208.66",
+ "89.42.208.99",
+ "89.42.208.101",
+ "89.42.208.105",
+ "89.42.208.109",
+ "89.42.208.111",
+ "89.42.208.119",
+ "89.42.208.121",
+ "89.42.208.124",
+ "89.42.208.139",
+ "89.42.208.146",
+ "89.42.208.147",
+ "89.42.208.150",
+ "89.42.208.155",
+ "89.42.208.156",
+ "89.42.208.157",
+ "89.42.208.179",
+ "89.42.208.180",
+ "89.42.208.181",
+ "89.42.208.182",
+ "89.42.208.195",
+ "89.42.208.196",
+ "89.42.208.202",
+ "89.42.208.203",
+ "89.42.208.210",
+ "89.42.208.213",
+ "89.42.208.214",
+ "89.42.208.219",
+ "89.42.208.246",
+ "89.42.208.249",
+ "89.42.209.4",
+ "89.42.209.13",
+ "89.42.209.16",
+ "89.42.209.17",
+ "89.42.209.19",
+ "89.42.209.23",
+ "89.42.209.26",
+ "89.42.209.35",
+ "89.42.209.40",
+ "89.42.209.43",
+ "89.42.209.45",
+ "89.42.209.48",
+ "89.42.209.49",
+ "89.42.209.58",
+ "89.42.209.68",
+ "89.42.209.69",
+ "89.42.209.70",
+ "89.42.209.71",
+ "89.42.209.72",
+ "89.42.209.73",
+ "89.42.209.74",
+ "89.42.209.76",
+ "89.42.209.77",
+ "89.42.209.79",
+ "89.42.209.80",
+ "89.42.209.81",
+ "89.42.209.82",
+ "89.42.209.87",
+ "89.42.209.108",
+ "89.42.209.110",
+ "89.42.209.167",
+ "89.42.209.190",
+ "89.42.209.194",
+ "89.42.209.196",
+ "89.42.209.197",
+ "89.42.209.198",
+ "89.42.209.203",
+ "89.42.209.204",
+ "89.42.209.205",
+ "89.42.209.206",
+ "89.42.209.226",
+ "89.42.209.227",
+ "89.42.209.229",
+ "89.42.209.230",
+ "89.42.209.234",
+ "89.42.209.235",
+ "89.42.209.236",
+ "89.42.209.237",
+ "89.42.209.238",
+ "89.42.209.242",
+ "89.42.209.244",
+ "89.42.209.246",
+ "89.42.210.8",
+ "89.42.210.16",
+ "89.42.210.30",
+ "89.42.210.36",
+ "89.42.210.39",
+ "89.42.210.45",
+ "89.42.210.47",
+ "89.42.210.48",
+ "89.42.210.49",
+ "89.42.210.51",
+ "89.42.210.52",
+ "89.42.210.54",
+ "89.42.210.57",
+ "89.42.210.64",
+ "89.42.210.74",
+ "89.42.210.83",
+ "89.42.210.113",
+ "89.42.210.115",
+ "89.42.210.116",
+ "89.42.210.118",
+ "89.42.210.119",
+ "89.42.210.122",
+ "89.42.210.123",
+ "89.42.210.146",
+ "89.42.210.162",
+ "89.42.210.165",
+ "89.42.210.166",
+ "89.42.210.168",
+ "89.42.210.169",
+ "89.42.210.171",
+ "89.42.210.176",
+ "89.42.210.177",
+ "89.42.210.179",
+ "89.42.210.180",
+ "89.42.210.181",
+ "89.42.210.182",
+ "89.42.210.183",
+ "89.42.210.186",
+ "89.42.210.187",
+ "89.42.210.188",
+ "89.42.210.189",
+ "89.42.210.200",
+ "89.42.210.201",
+ "89.42.210.222",
+ "89.42.210.227",
+ "89.42.210.228",
+ "89.42.210.229",
+ "89.42.210.230",
+ "89.42.210.234",
+ "89.42.210.236",
+ "89.42.210.243",
+ "89.42.210.244",
+ "89.42.210.245",
+ "89.42.210.246",
+ "89.42.210.250",
+ "89.42.210.251",
+ "89.42.210.254",
+ "89.42.211.2",
+ "89.42.211.3",
+ "89.42.211.10",
+ "89.42.211.13",
+ "89.42.211.14",
+ "89.42.211.18",
+ "89.42.211.22",
+ "89.42.211.23",
+ "89.42.211.44",
+ "89.42.211.47",
+ "89.42.211.48",
+ "89.42.211.50",
+ "89.42.211.52",
+ "89.42.211.55",
+ "89.42.211.67",
+ "89.42.211.70",
+ "89.42.211.71",
+ "89.42.211.72",
+ "89.42.211.74",
+ "89.42.211.77",
+ "89.42.211.78",
+ "89.42.211.80",
+ "89.42.211.81",
+ "89.42.211.82",
+ "89.42.211.85",
+ "89.42.211.87",
+ "89.42.211.93",
+ "89.42.211.98",
+ "89.42.211.99",
+ "89.42.211.101",
+ "89.42.211.102",
+ "89.42.211.108",
+ "89.42.211.109",
+ "89.42.211.110",
+ "89.42.211.114",
+ "89.42.211.162",
+ "89.42.211.163",
+ "89.42.211.164",
+ "89.42.211.165",
+ "89.42.211.166",
+ "89.42.211.170",
+ "89.42.211.171",
+ "89.42.211.172",
+ "89.42.211.173",
+ "89.42.211.174",
+ "89.42.211.220",
+ "89.42.211.222",
+ "89.42.211.226",
+ "89.42.211.227",
+ "89.42.211.228",
+ "89.42.211.236",
+ "89.43.0.33",
+ "89.43.0.232",
+ "89.43.4.178",
+ "89.43.5.218",
+ "89.43.5.219",
+ "89.43.7.222",
+ "89.43.10.43",
+ "89.43.10.44",
+ "89.43.224.135",
+ "89.43.226.192",
+ "89.43.231.91",
+ "89.43.231.203",
+ "89.44.112.5",
+ "89.44.118.10",
+ "89.44.134.50",
+ "89.44.182.229",
+ "89.45.89.3",
+ "89.45.89.8",
+ "89.45.89.9",
+ "89.46.60.176",
+ "89.46.61.56",
+ "89.46.216.6",
+ "89.46.216.7",
+ "89.46.216.20",
+ "89.46.216.21",
+ "89.46.216.22",
+ "89.46.216.23",
+ "89.46.216.25",
+ "89.46.216.26",
+ "89.46.216.28",
+ "89.46.216.29",
+ "89.46.216.30",
+ "89.46.216.31",
+ "89.46.216.112",
+ "89.46.216.113",
+ "89.46.216.114",
+ "89.46.216.115",
+ "89.46.216.116",
+ "89.46.216.117",
+ "89.46.216.118",
+ "89.46.216.119",
+ "89.46.216.200",
+ "89.46.216.201",
+ "89.46.216.202",
+ "89.46.216.203",
+ "89.46.216.204",
+ "89.46.216.205",
+ "89.46.216.206",
+ "89.46.216.207",
+ "89.46.218.12",
+ "89.46.218.13",
+ "89.46.218.14",
+ "89.46.218.15",
+ "89.46.218.24",
+ "89.46.218.50",
+ "89.46.218.56",
+ "89.46.218.57",
+ "89.46.218.58",
+ "89.46.218.59",
+ "89.46.218.60",
+ "89.46.218.61",
+ "89.46.218.62",
+ "89.46.218.63",
+ "89.46.218.64",
+ "89.46.218.65",
+ "89.46.218.66",
+ "89.46.218.67",
+ "89.46.218.68",
+ "89.46.218.70",
+ "89.46.218.71",
+ "89.46.218.72",
+ "89.46.218.73",
+ "89.46.218.74",
+ "89.46.218.75",
+ "89.46.218.76",
+ "89.46.218.77",
+ "89.46.218.78",
+ "89.46.218.79",
+ "89.46.218.80",
+ "89.46.218.81",
+ "89.46.218.82",
+ "89.46.218.83",
+ "89.46.218.84",
+ "89.46.218.85",
+ "89.46.218.86",
+ "89.46.218.87",
+ "89.46.218.88",
+ "89.46.218.89",
+ "89.46.218.90",
+ "89.46.218.91",
+ "89.46.218.92",
+ "89.46.218.93",
+ "89.46.218.94",
+ "89.46.218.95",
+ "89.46.218.96",
+ "89.46.218.97",
+ "89.46.218.98",
+ "89.46.218.99",
+ "89.46.218.100",
+ "89.46.218.101",
+ "89.46.218.102",
+ "89.46.218.103",
+ "89.46.218.104",
+ "89.46.218.105",
+ "89.46.218.106",
+ "89.46.218.107",
+ "89.46.218.108",
+ "89.46.218.110",
+ "89.46.218.111",
+ "89.46.218.112",
+ "89.46.218.113",
+ "89.46.218.114",
+ "89.46.218.115",
+ "89.46.218.116",
+ "89.46.218.117",
+ "89.46.218.118",
+ "89.46.218.119",
+ "89.46.218.120",
+ "89.46.218.121",
+ "89.46.218.122",
+ "89.46.218.123",
+ "89.46.218.124",
+ "89.46.218.125",
+ "89.46.218.126",
+ "89.46.218.128",
+ "89.46.218.129",
+ "89.46.218.130",
+ "89.46.218.131",
+ "89.46.218.132",
+ "89.46.219.16",
+ "89.46.219.18",
+ "89.46.219.64",
+ "89.46.219.65",
+ "89.46.219.66",
+ "89.46.219.67",
+ "89.46.219.68",
+ "89.46.219.69",
+ "89.46.219.70",
+ "89.46.219.71",
+ "89.46.219.80",
+ "89.46.219.81",
+ "89.46.219.83",
+ "89.46.219.84",
+ "89.46.219.85",
+ "89.46.219.86",
+ "89.46.219.87",
+ "89.46.219.88",
+ "89.46.219.89",
+ "89.46.219.90",
+ "89.46.219.91",
+ "89.46.219.92",
+ "89.46.219.93",
+ "89.46.219.94",
+ "89.46.219.95",
+ "89.46.219.104",
+ "89.46.219.105",
+ "89.46.219.106",
+ "89.46.219.107",
+ "89.46.219.108",
+ "89.46.219.109",
+ "89.46.219.110",
+ "89.46.219.111",
+ "89.46.219.112",
+ "89.46.219.113",
+ "89.46.219.114",
+ "89.46.219.115",
+ "89.46.219.116",
+ "89.46.219.117",
+ "89.46.219.118",
+ "89.46.219.119",
+ "89.46.219.176",
+ "89.46.219.177",
+ "89.46.219.178",
+ "89.46.219.179",
+ "89.46.219.180",
+ "89.46.219.181",
+ "89.46.219.182",
+ "89.46.219.183",
+ "89.46.219.192",
+ "89.46.219.193",
+ "89.46.219.194",
+ "89.46.219.195",
+ "89.46.219.196",
+ "89.46.219.197",
+ "89.46.219.198",
+ "89.46.219.220",
+ "89.46.219.221",
+ "89.46.219.222",
+ "89.46.219.223",
+ "89.144.128.21",
+ "89.144.129.18",
+ "89.144.129.234",
+ "89.144.131.136",
+ "89.144.131.137",
+ "89.144.131.139",
+ "89.144.131.140",
+ "89.144.131.141",
+ "89.144.131.142",
+ "89.144.131.143",
+ "89.144.132.168",
+ "89.144.132.169",
+ "89.144.132.170",
+ "89.144.132.171",
+ "89.144.132.172",
+ "89.144.132.174",
+ "89.144.132.175",
+ "89.144.132.184",
+ "89.144.132.185",
+ "89.144.132.186",
+ "89.144.132.187",
+ "89.144.132.188",
+ "89.144.132.190",
+ "89.144.132.191",
+ "89.144.132.193",
+ "89.144.132.194",
+ "89.144.137.192",
+ "89.144.137.193",
+ "89.144.137.194",
+ "89.144.137.195",
+ "89.144.137.196",
+ "89.144.137.198",
+ "89.144.137.201",
+ "89.144.137.202",
+ "89.144.137.203",
+ "89.144.137.205",
+ "89.144.137.206",
+ "89.144.137.209",
+ "89.144.137.211",
+ "89.144.137.213",
+ "89.144.137.214",
+ "89.144.137.216",
+ "89.144.137.218",
+ "89.144.137.219",
+ "89.144.137.221",
+ "89.144.137.222",
+ "89.144.137.224",
+ "89.144.137.225",
+ "89.144.137.226",
+ "89.144.137.227",
+ "89.144.137.228",
+ "89.144.137.230",
+ "89.144.137.231",
+ "89.144.137.232",
+ "89.144.137.235",
+ "89.144.137.239",
+ "89.144.137.241",
+ "89.144.137.242",
+ "89.144.137.243",
+ "89.144.137.245",
+ "89.144.137.246",
+ "89.144.137.248",
+ "89.144.137.249",
+ "89.144.137.250",
+ "89.144.137.252",
+ "89.144.138.138",
+ "89.144.138.153",
+ "89.144.138.154",
+ "89.144.138.157",
+ "89.144.138.158",
+ "89.144.138.159",
+ "89.144.139.0",
+ "89.144.139.2",
+ "89.144.139.3",
+ "89.144.139.5",
+ "89.144.139.6",
+ "89.144.139.8",
+ "89.144.139.9",
+ "89.144.139.10",
+ "89.144.139.12",
+ "89.144.139.13",
+ "89.144.139.15",
+ "89.144.139.17",
+ "89.144.139.18",
+ "89.144.139.20",
+ "89.144.139.21",
+ "89.144.139.22",
+ "89.144.139.23",
+ "89.144.139.24",
+ "89.144.139.26",
+ "89.144.139.27",
+ "89.144.139.28",
+ "89.144.139.29",
+ "89.144.139.30",
+ "89.144.139.31",
+ "89.144.139.32",
+ "89.144.139.33",
+ "89.144.139.34",
+ "89.144.139.35",
+ "89.144.139.37",
+ "89.144.139.38",
+ "89.144.139.39",
+ "89.144.139.40",
+ "89.144.139.41",
+ "89.144.139.42",
+ "89.144.139.43",
+ "89.144.139.44",
+ "89.144.139.45",
+ "89.144.139.46",
+ "89.144.139.47",
+ "89.144.139.48",
+ "89.144.139.49",
+ "89.144.139.50",
+ "89.144.139.51",
+ "89.144.139.52",
+ "89.144.139.53",
+ "89.144.139.54",
+ "89.144.139.55",
+ "89.144.139.56",
+ "89.144.139.57",
+ "89.144.139.59",
+ "89.144.139.62",
+ "89.144.139.63",
+ "89.144.139.64",
+ "89.144.139.65",
+ "89.144.139.66",
+ "89.144.139.67",
+ "89.144.139.68",
+ "89.144.139.70",
+ "89.144.139.71",
+ "89.144.139.72",
+ "89.144.139.73",
+ "89.144.139.74",
+ "89.144.139.75",
+ "89.144.139.76",
+ "89.144.139.77",
+ "89.144.139.78",
+ "89.144.139.79",
+ "89.144.139.82",
+ "89.144.139.84",
+ "89.144.139.85",
+ "89.144.139.87",
+ "89.144.139.88",
+ "89.144.139.89",
+ "89.144.139.90",
+ "89.144.139.91",
+ "89.144.139.92",
+ "89.144.139.93",
+ "89.144.139.95",
+ "89.144.139.96",
+ "89.144.139.97",
+ "89.144.139.102",
+ "89.144.139.103",
+ "89.144.139.104",
+ "89.144.139.105",
+ "89.144.139.106",
+ "89.144.139.108",
+ "89.144.139.110",
+ "89.144.139.112",
+ "89.144.139.114",
+ "89.144.139.115",
+ "89.144.139.116",
+ "89.144.139.117",
+ "89.144.139.118",
+ "89.144.139.121",
+ "89.144.139.122",
+ "89.144.139.123",
+ "89.144.139.124",
+ "89.144.139.125",
+ "89.144.139.126",
+ "89.144.139.127",
+ "89.144.140.34",
+ "89.144.141.159",
+ "89.144.141.220",
+ "89.144.143.130",
+ "89.144.144.118",
+ "89.144.144.144",
+ "89.144.145.210",
+ "89.144.145.212",
+ "89.144.145.213",
+ "89.144.145.214",
+ "89.144.145.215",
+ "89.144.151.22",
+ "89.144.151.251",
+ "89.144.151.252",
+ "89.144.154.98",
+ "89.144.156.249",
+ "89.144.166.144",
+ "89.144.166.145",
+ "89.144.166.146",
+ "89.144.166.147",
+ "89.144.166.148",
+ "89.144.166.149",
+ "89.144.166.150",
+ "89.144.166.151",
+ "89.144.166.152",
+ "89.144.166.153",
+ "89.144.166.154",
+ "89.144.166.155",
+ "89.144.166.156",
+ "89.144.166.157",
+ "89.144.166.158",
+ "89.144.166.159",
+ "89.144.166.160",
+ "89.144.166.166",
+ "89.144.166.167",
+ "89.144.166.168",
+ "89.144.166.169",
+ "89.144.166.170",
+ "89.144.166.171",
+ "89.144.166.173",
+ "89.144.166.174",
+ "89.144.166.175",
+ "89.144.166.176",
+ "89.144.166.177",
+ "89.144.166.178",
+ "89.144.166.179",
+ "89.144.166.180",
+ "89.144.166.181",
+ "89.144.166.182",
+ "89.144.166.183",
+ "89.144.166.184",
+ "89.144.166.185",
+ "89.144.166.186",
+ "89.144.166.187",
+ "89.144.166.189",
+ "89.144.166.190",
+ "89.144.166.192",
+ "89.144.166.194",
+ "89.144.166.195",
+ "89.144.166.196",
+ "89.144.166.197",
+ "89.144.166.198",
+ "89.144.166.199",
+ "89.144.166.200",
+ "89.144.166.201",
+ "89.144.166.202",
+ "89.144.166.203",
+ "89.144.166.204",
+ "89.144.166.205",
+ "89.144.166.206",
+ "89.144.166.207",
+ "89.144.166.208",
+ "89.144.166.209",
+ "89.144.166.210",
+ "89.144.166.211",
+ "89.144.166.212",
+ "89.144.166.213",
+ "89.144.166.214",
+ "89.144.166.215",
+ "89.144.166.216",
+ "89.144.166.218",
+ "89.144.166.219",
+ "89.144.166.220",
+ "89.144.166.221",
+ "89.144.166.222",
+ "89.144.166.223",
+ "89.144.166.224",
+ "89.144.166.225",
+ "89.144.166.226",
+ "89.144.166.227",
+ "89.144.166.228",
+ "89.144.166.229",
+ "89.144.166.230",
+ "89.144.166.231",
+ "89.144.166.240",
+ "89.144.166.241",
+ "89.144.166.243",
+ "89.144.166.244",
+ "89.144.166.245",
+ "89.144.166.246",
+ "89.144.166.247",
+ "89.144.166.248",
+ "89.144.166.249",
+ "89.144.166.250",
+ "89.144.166.251",
+ "89.144.166.252",
+ "89.144.166.253",
+ "89.144.166.254",
+ "89.144.166.255",
+ "89.144.176.190",
+ "89.144.182.3",
+ "89.144.183.0",
+ "89.144.183.1",
+ "89.144.183.2",
+ "89.144.183.3",
+ "89.144.183.4",
+ "89.144.183.5",
+ "89.144.183.6",
+ "89.144.183.7",
+ "89.144.183.16",
+ "89.144.183.17",
+ "89.144.183.18",
+ "89.144.183.19",
+ "89.144.183.22",
+ "89.144.183.23",
+ "89.144.183.42",
+ "89.144.187.66",
+ "89.144.187.67",
+ "89.144.187.68",
+ "89.144.188.87",
+ "89.144.189.112",
+ "89.144.189.115",
+ "89.144.189.118",
+ "89.144.189.119",
+ "89.144.189.121",
+ "89.144.189.122",
+ "89.144.189.123",
+ "89.144.189.125",
+ "89.144.189.126",
+ "89.144.189.127",
+ "89.144.189.128",
+ "89.144.189.130",
+ "89.144.189.131",
+ "89.144.189.134",
+ "89.144.189.135",
+ "89.144.189.139",
+ "89.144.189.141",
+ "89.144.189.143",
+ "89.144.189.144",
+ "89.144.189.145",
+ "89.144.189.146",
+ "89.144.189.148",
+ "89.144.189.149",
+ "89.144.189.150",
+ "89.144.189.158",
+ "89.144.189.163",
+ "89.144.189.167",
+ "89.144.189.169",
+ "89.144.189.171",
+ "89.144.189.173",
+ "89.144.189.175",
+ "89.144.189.178",
+ "89.144.189.179",
+ "89.144.189.180",
+ "89.144.189.182",
+ "89.144.189.183",
+ "89.144.189.184",
+ "89.144.189.187",
+ "89.144.189.188",
+ "89.144.189.190",
+ "89.144.189.193",
+ "89.144.189.195",
+ "89.144.189.199",
+ "89.144.189.200",
+ "89.144.189.201",
+ "89.144.189.203",
+ "89.144.189.205",
+ "89.144.189.206",
+ "89.144.189.210",
+ "89.144.189.212",
+ "89.144.189.215",
+ "89.144.189.216",
+ "89.144.189.217",
+ "89.144.189.218",
+ "89.144.189.220",
+ "89.144.189.221",
+ "89.144.189.222",
+ "89.144.189.224",
+ "89.144.189.225",
+ "89.144.189.226",
+ "89.144.189.229",
+ "89.144.189.231",
+ "89.144.189.233",
+ "89.144.189.235",
+ "89.144.189.238",
+ "89.144.189.242",
+ "89.144.189.243",
+ "89.144.189.244",
+ "89.144.189.245",
+ "89.144.189.246",
+ "89.144.189.247",
+ "89.144.189.249",
+ "89.144.189.250",
+ "89.144.189.251",
+ "89.144.189.253",
+ "89.144.189.254",
+ "89.144.189.255",
+ "89.165.0.13",
+ "89.165.0.14",
+ "89.165.1.212",
+ "89.165.1.232",
+ "89.165.56.19",
+ "89.219.64.58",
+ "89.219.64.157",
+ "89.219.65.151",
+ "89.219.66.83",
+ "89.219.66.163",
+ "89.219.79.161",
+ "89.219.81.18",
+ "89.219.83.86",
+ "89.219.83.227",
+ "89.219.84.161",
+ "89.219.84.162",
+ "89.219.89.61",
+ "89.219.92.21",
+ "89.219.94.12",
+ "89.219.96.28",
+ "89.219.112.149",
+ "89.219.192.22",
+ "89.219.200.102",
+ "89.219.216.206",
+ "89.219.219.255",
+ "89.219.220.231",
+ "89.219.233.8",
+ "89.219.237.50",
+ "89.219.237.81",
+ "89.219.237.239",
+ "89.219.239.108",
+ "89.219.252.233",
+ "89.221.80.9",
+ "89.221.80.10",
+ "89.221.81.31",
+ "89.221.81.140",
+ "89.221.83.12",
+ "89.221.83.20",
+ "89.235.64.65",
+ "89.235.64.66",
+ "89.235.66.5",
+ "89.235.66.6",
+ "89.235.67.4",
+ "89.235.67.5",
+ "89.235.68.2",
+ "89.235.68.5",
+ "89.235.69.2",
+ "89.235.79.4",
+ "89.235.79.5",
+ "89.235.79.6",
+ "89.235.79.8",
+ "89.235.79.9",
+ "89.235.79.13",
+ "89.235.79.15",
+ "89.235.79.16",
+ "89.235.79.19",
+ "89.235.79.20",
+ "89.235.79.21",
+ "89.235.79.22",
+ "89.235.79.23",
+ "89.235.79.24",
+ "89.235.79.26",
+ "89.235.79.27",
+ "89.235.79.29",
+ "89.235.79.32",
+ "89.235.79.35",
+ "89.235.79.39",
+ "89.235.79.41",
+ "89.235.79.43",
+ "89.235.79.44",
+ "89.235.79.45",
+ "89.235.79.46",
+ "89.235.79.47",
+ "89.235.79.48",
+ "89.235.79.51",
+ "89.235.79.52",
+ "89.235.79.54",
+ "89.235.79.55",
+ "89.235.79.56",
+ "89.235.79.57",
+ "89.235.79.58",
+ "89.235.79.59",
+ "89.235.79.60",
+ "89.235.79.67",
+ "89.235.79.68",
+ "89.235.79.110",
+ "89.235.116.201",
+ "89.235.116.202",
+ "89.235.116.203",
+ "89.235.116.211",
+ "89.235.116.216",
+ "91.92.114.189",
+ "91.92.121.183",
+ "91.92.121.200",
+ "91.92.125.90",
+ "91.92.126.55",
+ "91.92.127.236",
+ "91.92.130.216",
+ "91.92.132.42",
+ "91.92.158.85",
+ "91.92.158.146",
+ "91.92.158.186",
+ "91.92.159.116",
+ "91.92.180.77",
+ "91.92.180.198",
+ "91.92.182.182",
+ "91.92.186.205",
+ "91.92.187.146",
+ "91.92.188.192",
+ "91.92.190.5",
+ "91.92.190.17",
+ "91.92.191.165",
+ "91.92.204.208",
+ "91.92.204.220",
+ "91.92.209.6",
+ "91.92.209.151",
+ "91.92.213.228",
+ "91.92.214.28",
+ "91.92.214.110",
+ "91.92.214.241",
+ "91.92.215.66",
+ "91.92.215.250",
+ "91.106.65.46",
+ "91.106.65.47",
+ "91.106.78.194",
+ "91.106.85.10",
+ "91.106.86.218",
+ "91.106.87.54",
+ "91.106.91.5",
+ "91.106.91.6",
+ "91.108.128.18",
+ "91.108.129.121",
+ "91.108.130.18",
+ "91.108.130.203",
+ "91.108.130.204",
+ "91.108.130.206",
+ "91.108.152.115",
+ "91.108.152.116",
+ "91.185.133.81",
+ "91.186.193.4",
+ "91.186.193.20",
+ "91.186.193.21",
+ "91.186.193.29",
+ "91.186.193.32",
+ "91.186.193.35",
+ "91.186.193.41",
+ "91.186.193.89",
+ "91.186.193.108",
+ "91.186.193.125",
+ "91.186.193.130",
+ "91.186.193.131",
+ "91.186.193.132",
+ "91.186.193.133",
+ "91.186.193.134",
+ "91.186.193.162",
+ "91.186.193.192",
+ "91.186.193.193",
+ "91.186.193.194",
+ "91.186.193.196",
+ "91.186.193.229",
+ "91.186.193.230",
+ "91.186.193.232",
+ "91.197.242.5",
+ "91.197.242.6",
+ "91.199.9.87",
+ "91.199.9.199",
+ "91.199.27.62",
+ "91.199.27.83",
+ "91.199.27.185",
+ "91.199.27.237",
+ "91.199.30.171",
+ "91.199.30.196",
+ "91.199.215.3",
+ "91.199.215.26",
+ "91.199.215.30",
+ "91.199.215.69",
+ "91.199.215.70",
+ "91.199.215.72",
+ "91.199.215.73",
+ "91.199.215.77",
+ "91.199.215.78",
+ "91.199.215.115",
+ "91.199.215.248",
+ "91.207.138.55",
+ "91.207.205.4",
+ "91.207.205.5",
+ "91.207.205.6",
+ "91.207.205.8",
+ "91.207.205.9",
+ "91.207.205.10",
+ "91.207.205.11",
+ "91.207.205.12",
+ "91.207.205.13",
+ "91.207.205.14",
+ "91.207.205.15",
+ "91.207.205.16",
+ "91.207.205.17",
+ "91.207.205.18",
+ "91.207.205.19",
+ "91.207.205.20",
+ "91.207.205.21",
+ "91.207.205.22",
+ "91.207.205.24",
+ "91.207.205.26",
+ "91.207.205.29",
+ "91.207.205.30",
+ "91.207.205.34",
+ "91.207.205.35",
+ "91.207.205.36",
+ "91.207.205.37",
+ "91.207.205.38",
+ "91.207.205.41",
+ "91.207.205.44",
+ "91.207.205.46",
+ "91.207.205.47",
+ "91.207.205.48",
+ "91.207.205.50",
+ "91.208.163.196",
+ "91.212.174.5",
+ "91.212.174.10",
+ "91.212.174.21",
+ "91.212.174.28",
+ "91.212.174.39",
+ "91.212.174.43",
+ "91.212.174.48",
+ "91.212.174.50",
+ "91.212.174.56",
+ "91.212.174.80",
+ "91.212.174.86",
+ "91.212.174.95",
+ "91.212.174.98",
+ "91.212.174.100",
+ "91.212.174.105",
+ "91.212.174.114",
+ "91.212.174.119",
+ "91.212.174.131",
+ "91.212.174.133",
+ "91.212.174.136",
+ "91.212.174.138",
+ "91.212.174.141",
+ "91.212.174.148",
+ "91.212.174.149",
+ "91.212.174.163",
+ "91.212.174.178",
+ "91.212.174.183",
+ "91.212.174.184",
+ "91.212.174.185",
+ "91.212.174.191",
+ "91.212.174.196",
+ "91.212.174.205",
+ "91.212.174.226",
+ "91.212.174.233",
+ "91.212.174.250",
+ "91.212.252.53",
+ "91.212.252.54",
+ "91.212.252.184",
+ "91.212.252.200",
+ "91.212.252.201",
+ "91.216.171.3",
+ "91.216.171.4",
+ "91.216.171.8",
+ "91.220.113.2",
+ "91.220.113.7",
+ "91.220.113.18",
+ "91.220.113.22",
+ "91.220.113.40",
+ "91.220.113.47",
+ "91.220.113.119",
+ "91.220.113.125",
+ "91.220.113.151",
+ "91.220.113.157",
+ "91.220.113.167",
+ "91.220.113.172",
+ "91.220.113.185",
+ "91.220.113.199",
+ "91.220.113.200",
+ "91.220.113.207",
+ "91.220.113.221",
+ "91.220.113.231",
+ "91.220.113.239",
+ "91.220.113.241",
+ "91.220.113.245",
+ "91.220.113.246",
+ "91.220.113.251",
+ "91.220.113.252",
+ "91.221.241.200",
+ "91.222.199.9",
+ "91.222.199.95",
+ "91.222.199.98",
+ "91.222.199.250",
+ "91.222.199.251",
+ "91.222.199.252",
+ "91.223.116.1",
+ "91.223.116.15",
+ "91.223.116.50",
+ "91.223.116.52",
+ "91.223.116.61",
+ "91.223.116.116",
+ "91.223.116.128",
+ "91.223.116.130",
+ "91.223.116.134",
+ "91.223.116.135",
+ "91.223.116.136",
+ "91.223.116.137",
+ "91.223.116.138",
+ "91.223.116.143",
+ "91.223.116.144",
+ "91.223.116.146",
+ "91.223.116.147",
+ "91.223.116.152",
+ "91.223.116.153",
+ "91.223.116.156",
+ "91.223.116.158",
+ "91.223.116.161",
+ "91.223.116.163",
+ "91.223.116.167",
+ "91.223.116.168",
+ "91.223.116.170",
+ "91.223.116.171",
+ "91.223.116.172",
+ "91.223.116.175",
+ "91.223.116.187",
+ "91.223.116.194",
+ "91.223.116.196",
+ "91.223.116.200",
+ "91.223.116.206",
+ "91.223.116.220",
+ "91.223.116.221",
+ "91.223.116.234",
+ "91.223.116.249",
+ "91.223.146.10",
+ "91.223.146.20",
+ "91.224.110.2",
+ "91.224.110.56",
+ "91.224.110.58",
+ "91.224.111.101",
+ "91.225.54.67",
+ "91.225.54.70",
+ "91.228.132.6",
+ "91.228.132.21",
+ "91.228.132.23",
+ "91.228.132.91",
+ "91.228.133.91",
+ "91.232.73.11",
+ "91.232.73.12",
+ "91.232.73.55",
+ "91.232.73.56",
+ "91.232.73.66",
+ "91.232.73.67",
+ "91.234.39.11",
+ "91.234.39.15",
+ "91.234.39.16",
+ "91.234.39.32",
+ "91.234.39.33",
+ "91.234.39.44",
+ "91.234.39.58",
+ "91.234.39.61",
+ "91.234.39.68",
+ "91.234.39.112",
+ "91.234.39.115",
+ "91.234.39.179",
+ "91.234.39.181",
+ "91.234.39.203",
+ "91.234.39.208",
+ "91.234.39.214",
+ "91.234.39.228",
+ "91.234.39.234",
+ "91.236.168.56",
+ "91.236.168.68",
+ "91.236.168.84",
+ "91.236.168.121",
+ "91.236.168.145",
+ "91.236.168.164",
+ "91.236.168.167",
+ "91.236.168.178",
+ "91.236.168.179",
+ "91.236.168.208",
+ "91.236.168.210",
+ "91.236.168.220",
+ "91.236.168.249",
+ "91.236.168.250",
+ "91.236.168.251",
+ "91.236.168.252",
+ "91.236.168.253",
+ "91.236.169.187",
+ "91.239.14.3",
+ "91.239.14.4",
+ "91.239.214.2",
+ "91.239.214.130",
+ "91.240.60.5",
+ "91.240.60.10",
+ "91.240.60.15",
+ "91.240.60.60",
+ "91.240.60.61",
+ "91.240.61.110",
+ "91.240.62.2",
+ "91.240.62.10",
+ "91.240.62.11",
+ "91.240.63.37",
+ "91.240.63.114",
+ "91.240.63.115",
+ "91.240.180.10",
+ "91.240.180.11",
+ "91.240.180.215",
+ "91.240.180.216",
+ "91.240.182.210",
+ "91.240.182.211",
+ "91.242.44.228",
+ "91.243.127.102",
+ "91.243.171.83",
+ "91.243.171.172",
+ "91.245.228.96",
+ "91.245.228.101",
+ "91.245.228.102",
+ "91.245.228.250",
+ "91.245.228.251",
+ "91.245.229.1",
+ "91.245.229.66",
+ "91.246.31.25",
+ "91.246.44.9",
+ "91.246.44.112",
+ "91.247.171.14",
+ "91.247.171.36",
+ "91.247.171.61",
+ "91.247.171.65",
+ "91.247.171.75",
+ "91.247.171.80",
+ "91.247.171.135",
+ "91.247.171.146",
+ "91.247.171.154",
+ "91.247.171.203",
+ "91.247.171.231",
+ "92.42.50.58",
+ "92.42.50.209",
+ "92.42.50.210",
+ "92.42.51.109",
+ "92.42.51.209",
+ "92.42.53.28",
+ "92.42.53.29",
+ "92.42.207.35",
+ "92.43.163.198",
+ "92.61.181.55",
+ "92.61.181.181",
+ "92.61.181.253",
+ "92.61.181.254",
+ "92.61.183.8",
+ "92.61.183.136",
+ "92.61.183.141",
+ "92.61.183.146",
+ "92.114.17.228",
+ "92.114.17.229",
+ "92.114.17.230",
+ "92.114.18.46",
+ "92.114.18.100",
+ "92.114.18.102",
+ "92.114.18.104",
+ "92.114.18.111",
+ "92.114.18.116",
+ "92.114.18.117",
+ "92.114.19.9",
+ "92.114.19.28",
+ "92.114.19.29",
+ "92.114.19.41",
+ "92.114.19.226",
+ "92.114.19.251",
+ "92.114.19.252",
+ "92.114.24.110",
+ "92.114.28.66",
+ "92.114.31.112",
+ "92.114.50.2",
+ "92.114.51.151",
+ "92.119.57.68",
+ "92.119.57.75",
+ "92.119.57.82",
+ "92.119.57.108",
+ "92.119.57.109",
+ "92.119.57.110",
+ "92.119.57.134",
+ "92.119.57.147",
+ "92.119.57.164",
+ "92.119.57.176",
+ "92.119.57.210",
+ "92.119.58.22",
+ "92.119.58.32",
+ "92.119.58.59",
+ "92.119.58.60",
+ "92.119.58.62",
+ "92.119.58.114",
+ "92.119.58.158",
+ "92.242.195.53",
+ "92.242.195.54",
+ "92.242.198.7",
+ "92.242.198.21",
+ "92.242.198.22",
+ "92.242.198.42",
+ "92.242.198.50",
+ "92.242.198.51",
+ "92.242.198.52",
+ "92.242.198.123",
+ "92.242.198.166",
+ "92.242.198.181",
+ "92.242.198.230",
+ "92.242.198.233",
+ "92.242.198.253",
+ "92.242.201.2",
+ "92.242.201.10",
+ "92.242.201.11",
+ "92.242.203.85",
+ "92.242.204.73",
+ "92.242.204.74",
+ "92.242.205.40",
+ "92.242.207.200",
+ "92.242.210.6",
+ "92.242.212.103",
+ "92.242.216.50",
+ "92.242.216.150",
+ "92.242.216.248",
+ "92.242.220.116",
+ "92.242.220.122",
+ "92.242.220.162",
+ "92.242.220.200",
+ "92.242.220.228",
+ "92.242.220.238",
+ "92.242.223.115",
+ "92.242.223.116",
+ "92.246.144.179",
+ "92.246.144.205",
+ "92.246.145.99",
+ "92.246.146.139",
+ "93.113.224.58",
+ "93.113.224.60",
+ "93.113.224.62",
+ "93.113.225.7",
+ "93.113.225.8",
+ "93.113.226.82",
+ "93.113.234.62",
+ "93.113.234.67",
+ "93.113.235.105",
+ "93.113.235.106",
+ "93.113.235.107",
+ "93.113.235.108",
+ "93.113.236.50",
+ "93.113.236.52",
+ "93.113.236.53",
+ "93.113.237.170",
+ "93.113.238.2",
+ "93.113.239.55",
+ "93.113.239.56",
+ "93.113.239.57",
+ "93.113.239.58",
+ "93.114.110.20",
+ "93.115.126.14",
+ "93.115.127.9",
+ "93.115.144.212",
+ "93.115.148.150",
+ "93.115.149.88",
+ "93.115.150.27",
+ "93.115.150.28",
+ "93.115.150.29",
+ "93.115.150.66",
+ "93.115.150.68",
+ "93.115.150.229",
+ "93.115.150.230",
+ "93.115.150.231",
+ "93.115.150.235",
+ "93.115.150.236",
+ "93.115.150.237",
+ "93.115.150.238",
+ "93.115.151.75",
+ "93.115.151.76",
+ "93.115.151.77",
+ "93.115.151.78",
+ "93.115.151.100",
+ "93.115.151.138",
+ "93.115.219.48",
+ "93.117.27.61",
+ "93.117.30.40",
+ "93.117.30.53",
+ "93.117.36.33",
+ "93.117.37.237",
+ "93.117.39.171",
+ "93.117.43.82",
+ "93.117.46.181",
+ "93.117.46.187",
+ "93.117.47.43",
+ "93.117.127.141",
+ "93.118.99.182",
+ "93.118.104.137",
+ "93.118.108.162",
+ "93.118.109.213",
+ "93.118.110.144",
+ "93.118.112.28",
+ "93.118.112.76",
+ "93.118.112.118",
+ "93.118.115.173",
+ "93.118.116.13",
+ "93.118.117.12",
+ "93.118.121.130",
+ "93.118.122.27",
+ "93.118.123.140",
+ "93.118.125.167",
+ "93.118.126.176",
+ "93.118.126.196",
+ "93.118.127.96",
+ "93.118.132.34",
+ "93.118.134.242",
+ "93.118.135.237",
+ "93.118.137.33",
+ "93.118.137.209",
+ "93.118.138.109",
+ "93.118.140.95",
+ "93.118.140.160",
+ "93.118.144.69",
+ "93.118.145.139",
+ "93.118.146.112",
+ "93.118.148.134",
+ "93.118.153.59",
+ "93.118.153.218",
+ "93.118.156.84",
+ "93.118.160.148",
+ "93.118.160.151",
+ "93.118.163.159",
+ "93.118.163.238",
+ "93.118.164.87",
+ "93.118.164.193",
+ "93.118.165.89",
+ "93.118.166.2",
+ "93.118.167.175",
+ "93.118.182.221",
+ "93.118.183.120",
+ "93.119.57.119",
+ "93.126.2.3",
+ "93.126.2.4",
+ "93.126.2.77",
+ "93.126.2.212",
+ "93.126.3.99",
+ "93.126.3.169",
+ "93.126.6.131",
+ "93.126.6.132",
+ "93.126.6.133",
+ "93.126.6.134",
+ "93.126.6.145",
+ "93.126.6.146",
+ "93.126.6.147",
+ "93.126.6.150",
+ "93.126.6.151",
+ "93.126.6.176",
+ "93.126.6.178",
+ "93.126.6.182",
+ "93.126.6.186",
+ "93.126.23.245",
+ "93.126.23.251",
+ "93.126.25.8",
+ "93.126.25.10",
+ "93.126.25.15",
+ "93.126.31.166",
+ "94.74.128.2",
+ "94.74.128.3",
+ "94.74.128.4",
+ "94.74.128.12",
+ "94.74.128.13",
+ "94.74.128.18",
+ "94.74.128.110",
+ "94.74.128.129",
+ "94.74.128.234",
+ "94.74.128.252",
+ "94.74.145.11",
+ "94.74.145.14",
+ "94.74.145.16",
+ "94.74.145.23",
+ "94.74.145.24",
+ "94.74.145.27",
+ "94.74.145.122",
+ "94.74.145.130",
+ "94.74.145.155",
+ "94.74.145.173",
+ "94.74.145.178",
+ "94.74.145.191",
+ "94.74.145.202",
+ "94.74.163.130",
+ "94.74.168.36",
+ "94.74.168.179",
+ "94.74.170.119",
+ "94.74.170.162",
+ "94.74.170.167",
+ "94.101.136.138",
+ "94.101.140.196",
+ "94.101.176.219",
+ "94.101.177.8",
+ "94.101.177.34",
+ "94.101.177.39",
+ "94.101.178.79",
+ "94.101.179.19",
+ "94.101.179.98",
+ "94.101.179.105",
+ "94.101.180.19",
+ "94.101.180.39",
+ "94.101.180.41",
+ "94.101.184.158",
+ "94.101.184.190",
+ "94.101.184.222",
+ "94.101.184.254",
+ "94.101.185.65",
+ "94.101.185.73",
+ "94.101.185.75",
+ "94.101.185.151",
+ "94.101.186.22",
+ "94.101.186.40",
+ "94.101.186.107",
+ "94.101.186.138",
+ "94.101.186.151",
+ "94.101.187.89",
+ "94.101.187.195",
+ "94.101.190.208",
+ "94.101.190.209",
+ "94.182.17.202",
+ "94.182.17.205",
+ "94.182.17.206",
+ "94.182.17.214",
+ "94.182.18.246",
+ "94.182.20.10",
+ "94.182.28.3",
+ "94.182.28.56",
+ "94.182.37.50",
+ "94.182.40.34",
+ "94.182.40.35",
+ "94.182.40.70",
+ "94.182.40.78",
+ "94.182.42.194",
+ "94.182.44.54",
+ "94.182.50.77",
+ "94.182.83.197",
+ "94.182.83.200",
+ "94.182.83.201",
+ "94.182.83.202",
+ "94.182.83.205",
+ "94.182.83.206",
+ "94.182.83.209",
+ "94.182.83.210",
+ "94.182.83.211",
+ "94.182.83.212",
+ "94.182.83.214",
+ "94.182.83.216",
+ "94.182.83.219",
+ "94.182.83.233",
+ "94.182.83.234",
+ "94.182.83.235",
+ "94.182.83.236",
+ "94.182.83.237",
+ "94.182.83.238",
+ "94.182.83.246",
+ "94.182.83.247",
+ "94.182.83.248",
+ "94.182.83.252",
+ "94.182.84.172",
+ "94.182.85.227",
+ "94.182.85.231",
+ "94.182.85.232",
+ "94.182.85.237",
+ "94.182.85.244",
+ "94.182.85.250",
+ "94.182.85.252",
+ "94.182.86.187",
+ "94.182.86.190",
+ "94.182.87.209",
+ "94.182.87.210",
+ "94.182.87.211",
+ "94.182.87.212",
+ "94.182.87.214",
+ "94.182.87.215",
+ "94.182.87.216",
+ "94.182.87.217",
+ "94.182.87.218",
+ "94.182.87.219",
+ "94.182.87.220",
+ "94.182.87.222",
+ "94.182.88.18",
+ "94.182.88.20",
+ "94.182.88.21",
+ "94.182.88.22",
+ "94.182.88.116",
+ "94.182.88.120",
+ "94.182.89.41",
+ "94.182.89.107",
+ "94.182.89.131",
+ "94.182.89.132",
+ "94.182.89.133",
+ "94.182.89.135",
+ "94.182.89.136",
+ "94.182.89.137",
+ "94.182.89.138",
+ "94.182.89.139",
+ "94.182.89.142",
+ "94.182.89.143",
+ "94.182.89.145",
+ "94.182.89.146",
+ "94.182.89.147",
+ "94.182.89.148",
+ "94.182.89.150",
+ "94.182.89.152",
+ "94.182.89.154",
+ "94.182.89.155",
+ "94.182.89.156",
+ "94.182.89.157",
+ "94.182.89.159",
+ "94.182.89.161",
+ "94.182.89.163",
+ "94.182.89.167",
+ "94.182.89.169",
+ "94.182.89.170",
+ "94.182.89.174",
+ "94.182.89.175",
+ "94.182.89.179",
+ "94.182.89.182",
+ "94.182.89.224",
+ "94.182.89.227",
+ "94.182.89.235",
+ "94.182.89.236",
+ "94.182.89.237",
+ "94.182.89.247",
+ "94.182.90.18",
+ "94.182.90.19",
+ "94.182.90.20",
+ "94.182.90.21",
+ "94.182.90.66",
+ "94.182.90.149",
+ "94.182.90.170",
+ "94.182.90.200",
+ "94.182.90.210",
+ "94.182.90.213",
+ "94.182.90.216",
+ "94.182.90.217",
+ "94.182.91.114",
+ "94.182.91.126",
+ "94.182.91.130",
+ "94.182.91.133",
+ "94.182.91.134",
+ "94.182.92.19",
+ "94.182.92.57",
+ "94.182.92.80",
+ "94.182.92.165",
+ "94.182.93.45",
+ "94.182.93.133",
+ "94.182.94.5",
+ "94.182.94.67",
+ "94.182.94.75",
+ "94.182.94.121",
+ "94.182.94.170",
+ "94.182.94.217",
+ "94.182.95.2",
+ "94.182.95.3",
+ "94.182.95.4",
+ "94.182.95.6",
+ "94.182.95.8",
+ "94.182.95.246",
+ "94.182.97.45",
+ "94.182.102.102",
+ "94.182.102.200",
+ "94.182.104.11",
+ "94.182.104.12",
+ "94.182.104.13",
+ "94.182.104.14",
+ "94.182.105.213",
+ "94.182.105.215",
+ "94.182.107.227",
+ "94.182.108.98",
+ "94.182.108.150",
+ "94.182.110.234",
+ "94.182.110.235",
+ "94.182.110.236",
+ "94.182.110.237",
+ "94.182.110.238",
+ "94.182.113.117",
+ "94.182.115.130",
+ "94.182.115.173",
+ "94.182.128.123",
+ "94.182.128.124",
+ "94.182.129.5",
+ "94.182.129.114",
+ "94.182.129.121",
+ "94.182.130.2",
+ "94.182.130.91",
+ "94.182.130.93",
+ "94.182.133.6",
+ "94.182.133.36",
+ "94.182.133.70",
+ "94.182.133.73",
+ "94.182.133.130",
+ "94.182.133.254",
+ "94.182.135.77",
+ "94.182.135.254",
+ "94.182.136.19",
+ "94.182.136.39",
+ "94.182.136.45",
+ "94.182.136.50",
+ "94.182.136.51",
+ "94.182.136.106",
+ "94.182.138.37",
+ "94.182.140.18",
+ "94.182.140.19",
+ "94.182.140.20",
+ "94.182.140.21",
+ "94.182.140.22",
+ "94.182.142.40",
+ "94.182.142.41",
+ "94.182.142.42",
+ "94.182.142.43",
+ "94.182.142.45",
+ "94.182.142.48",
+ "94.182.142.49",
+ "94.182.142.50",
+ "94.182.142.54",
+ "94.182.142.152",
+ "94.182.142.176",
+ "94.182.142.177",
+ "94.182.142.201",
+ "94.182.142.205",
+ "94.182.142.216",
+ "94.182.142.248",
+ "94.182.146.2",
+ "94.182.146.116",
+ "94.182.146.191",
+ "94.182.146.252",
+ "94.182.147.138",
+ "94.182.150.180",
+ "94.182.150.181",
+ "94.182.151.14",
+ "94.182.153.4",
+ "94.182.153.26",
+ "94.182.153.30",
+ "94.182.153.34",
+ "94.182.153.38",
+ "94.182.153.78",
+ "94.182.153.99",
+ "94.182.153.100",
+ "94.182.153.164",
+ "94.182.153.169",
+ "94.182.153.170",
+ "94.182.153.173",
+ "94.182.153.174",
+ "94.182.153.175",
+ "94.182.153.197",
+ "94.182.154.12",
+ "94.182.154.20",
+ "94.182.154.22",
+ "94.182.154.67",
+ "94.182.154.68",
+ "94.182.154.69",
+ "94.182.154.71",
+ "94.182.154.105",
+ "94.182.154.111",
+ "94.182.154.201",
+ "94.182.154.220",
+ "94.182.154.246",
+ "94.182.154.247",
+ "94.182.154.251",
+ "94.182.155.10",
+ "94.182.155.111",
+ "94.182.155.121",
+ "94.182.156.91",
+ "94.182.156.118",
+ "94.182.156.122",
+ "94.182.156.187",
+ "94.182.156.220",
+ "94.182.157.181",
+ "94.182.157.185",
+ "94.182.157.187",
+ "94.182.159.34",
+ "94.182.159.35",
+ "94.182.159.36",
+ "94.182.159.37",
+ "94.182.159.38",
+ "94.182.159.41",
+ "94.182.159.51",
+ "94.182.159.55",
+ "94.182.159.56",
+ "94.182.169.52",
+ "94.182.169.120",
+ "94.182.169.124",
+ "94.182.170.219",
+ "94.182.171.83",
+ "94.182.171.85",
+ "94.182.171.94",
+ "94.182.172.17",
+ "94.182.172.18",
+ "94.182.172.21",
+ "94.182.172.36",
+ "94.182.172.46",
+ "94.182.172.47",
+ "94.182.172.48",
+ "94.182.172.49",
+ "94.182.172.51",
+ "94.182.172.52",
+ "94.182.172.53",
+ "94.182.172.194",
+ "94.182.172.196",
+ "94.182.172.197",
+ "94.182.172.198",
+ "94.182.172.200",
+ "94.182.172.203",
+ "94.182.172.204",
+ "94.182.172.206",
+ "94.182.172.209",
+ "94.182.172.210",
+ "94.182.172.211",
+ "94.182.172.212",
+ "94.182.172.213",
+ "94.182.172.216",
+ "94.182.172.218",
+ "94.182.172.219",
+ "94.182.172.251",
+ "94.182.172.254",
+ "94.182.173.82",
+ "94.182.173.189",
+ "94.182.174.43",
+ "94.182.174.165",
+ "94.182.174.172",
+ "94.182.174.173",
+ "94.182.175.2",
+ "94.182.175.4",
+ "94.182.175.5",
+ "94.182.175.6",
+ "94.182.175.10",
+ "94.182.175.11",
+ "94.182.175.12",
+ "94.182.175.14",
+ "94.182.175.15",
+ "94.182.175.17",
+ "94.182.175.20",
+ "94.182.175.35",
+ "94.182.175.38",
+ "94.182.175.44",
+ "94.182.175.50",
+ "94.182.175.53",
+ "94.182.175.55",
+ "94.182.175.56",
+ "94.182.176.184",
+ "94.182.176.188",
+ "94.182.177.43",
+ "94.182.177.67",
+ "94.182.177.68",
+ "94.182.177.70",
+ "94.182.177.72",
+ "94.182.177.73",
+ "94.182.177.80",
+ "94.182.177.81",
+ "94.182.177.82",
+ "94.182.178.50",
+ "94.182.178.52",
+ "94.182.178.53",
+ "94.182.178.54",
+ "94.182.178.55",
+ "94.182.178.71",
+ "94.182.178.73",
+ "94.182.178.75",
+ "94.182.178.80",
+ "94.182.178.81",
+ "94.182.178.83",
+ "94.182.178.85",
+ "94.182.178.88",
+ "94.182.178.91",
+ "94.182.178.92",
+ "94.182.178.93",
+ "94.182.178.94",
+ "94.182.178.95",
+ "94.182.178.97",
+ "94.182.178.98",
+ "94.182.178.100",
+ "94.182.178.107",
+ "94.182.178.109",
+ "94.182.178.110",
+ "94.182.178.111",
+ "94.182.178.112",
+ "94.182.178.113",
+ "94.182.178.114",
+ "94.182.178.115",
+ "94.182.178.116",
+ "94.182.178.117",
+ "94.182.178.118",
+ "94.182.178.119",
+ "94.182.178.120",
+ "94.182.178.121",
+ "94.182.178.122",
+ "94.182.178.132",
+ "94.182.178.233",
+ "94.182.179.232",
+ "94.182.180.140",
+ "94.182.181.50",
+ "94.182.181.222",
+ "94.182.182.98",
+ "94.182.183.211",
+ "94.182.184.190",
+ "94.182.185.95",
+ "94.182.185.97",
+ "94.182.185.126",
+ "94.182.185.226",
+ "94.182.185.227",
+ "94.182.186.79",
+ "94.182.186.231",
+ "94.182.186.232",
+ "94.182.186.250",
+ "94.182.187.148",
+ "94.182.187.149",
+ "94.182.190.229",
+ "94.182.190.245",
+ "94.182.192.178",
+ "94.182.195.42",
+ "94.182.195.54",
+ "94.182.195.107",
+ "94.182.195.158",
+ "94.182.195.164",
+ "94.182.195.182",
+ "94.182.195.183",
+ "94.182.195.188",
+ "94.182.195.194",
+ "94.182.195.218",
+ "94.182.195.223",
+ "94.182.195.225",
+ "94.182.195.231",
+ "94.182.195.243",
+ "94.182.195.247",
+ "94.182.196.187",
+ "94.182.198.62",
+ "94.182.198.146",
+ "94.182.199.222",
+ "94.182.202.78",
+ "94.182.208.45",
+ "94.182.208.46",
+ "94.182.209.58",
+ "94.182.209.66",
+ "94.182.209.70",
+ "94.182.209.71",
+ "94.182.214.34",
+ "94.182.214.182",
+ "94.182.215.6",
+ "94.182.215.72",
+ "94.182.215.75",
+ "94.182.215.90",
+ "94.182.227.5",
+ "94.182.227.8",
+ "94.182.227.10",
+ "94.182.227.19",
+ "94.182.227.34",
+ "94.182.227.37",
+ "94.182.227.38",
+ "94.182.227.40",
+ "94.182.227.42",
+ "94.182.227.56",
+ "94.182.227.61",
+ "94.182.227.80",
+ "94.182.227.83",
+ "94.182.227.85",
+ "94.182.227.96",
+ "94.182.227.99",
+ "94.182.227.103",
+ "94.182.227.120",
+ "94.182.227.121",
+ "94.182.227.131",
+ "94.182.227.134",
+ "94.182.227.164",
+ "94.182.227.165",
+ "94.182.227.166",
+ "94.182.227.167",
+ "94.182.227.170",
+ "94.182.227.181",
+ "94.182.227.194",
+ "94.182.227.195",
+ "94.182.227.200",
+ "94.182.227.209",
+ "94.182.227.219",
+ "94.182.227.225",
+ "94.182.227.229",
+ "94.182.227.237",
+ "94.182.227.238",
+ "94.182.227.241",
+ "94.182.227.242",
+ "94.182.227.246",
+ "94.182.227.247",
+ "94.182.242.13",
+ "94.182.249.11",
+ "94.182.250.30",
+ "94.182.251.16",
+ "94.182.255.154",
+ "94.183.0.19",
+ "94.183.2.164",
+ "94.183.3.131",
+ "94.183.3.199",
+ "94.183.3.233",
+ "94.183.8.70",
+ "94.183.10.192",
+ "94.183.10.193",
+ "94.183.12.86",
+ "94.183.14.129",
+ "94.183.14.154",
+ "94.183.17.153",
+ "94.183.25.223",
+ "94.183.26.90",
+ "94.183.27.1",
+ "94.183.29.64",
+ "94.183.30.17",
+ "94.183.31.47",
+ "94.183.32.45",
+ "94.183.33.193",
+ "94.183.36.82",
+ "94.183.42.239",
+ "94.183.47.239",
+ "94.183.51.96",
+ "94.183.51.149",
+ "94.183.53.16",
+ "94.183.53.17",
+ "94.183.53.18",
+ "94.183.53.19",
+ "94.183.57.172",
+ "94.183.58.73",
+ "94.183.59.36",
+ "94.183.62.83",
+ "94.183.62.232",
+ "94.183.84.184",
+ "94.183.84.227",
+ "94.183.85.177",
+ "94.183.88.99",
+ "94.183.90.243",
+ "94.183.100.148",
+ "94.183.108.245",
+ "94.183.110.118",
+ "94.183.117.238",
+ "94.183.118.64",
+ "94.183.119.8",
+ "94.183.122.41",
+ "94.183.123.216",
+ "94.183.124.28",
+ "94.183.124.97",
+ "94.183.124.129",
+ "94.183.125.86",
+ "94.183.125.191",
+ "94.183.126.155",
+ "94.183.127.185",
+ "94.183.128.221",
+ "94.183.130.253",
+ "94.183.132.106",
+ "94.183.132.251",
+ "94.183.137.113",
+ "94.183.141.177",
+ "94.183.146.170",
+ "94.183.146.198",
+ "94.183.146.205",
+ "94.183.156.141",
+ "94.183.157.7",
+ "94.183.157.188",
+ "94.183.160.175",
+ "94.183.160.239",
+ "94.183.163.63",
+ "94.183.163.90",
+ "94.183.163.132",
+ "94.183.163.180",
+ "94.183.163.181",
+ "94.183.176.60",
+ "94.183.176.65",
+ "94.183.177.100",
+ "94.184.9.31",
+ "94.184.10.82",
+ "94.184.16.6",
+ "94.184.17.197",
+ "94.184.22.5",
+ "94.184.22.62",
+ "94.184.29.217",
+ "94.184.29.219",
+ "94.184.29.220",
+ "94.184.89.2",
+ "94.184.120.67",
+ "94.184.141.137",
+ "94.184.141.141",
+ "94.184.176.5",
+ "94.184.176.6",
+ "94.184.176.201",
+ "94.184.224.196",
+ "94.184.225.25",
+ "94.184.236.20",
+ "94.184.236.32",
+ "94.184.236.50",
+ "94.184.239.20",
+ "94.199.0.166",
+ "94.232.168.26",
+ "94.232.168.103",
+ "94.232.168.105",
+ "94.232.168.151",
+ "94.232.168.211",
+ "94.232.170.65",
+ "94.232.170.66",
+ "94.232.170.67",
+ "94.232.170.68",
+ "94.232.171.86",
+ "94.232.171.140",
+ "94.232.171.141",
+ "94.232.171.150",
+ "94.232.171.151",
+ "94.232.172.2",
+ "94.232.172.96",
+ "94.232.172.104",
+ "94.232.172.135",
+ "94.232.173.4",
+ "94.232.173.28",
+ "94.232.173.52",
+ "94.232.173.69",
+ "94.232.173.70",
+ "94.232.173.71",
+ "94.232.173.100",
+ "94.232.173.114",
+ "94.232.173.128",
+ "94.232.173.137",
+ "94.232.173.148",
+ "94.232.173.150",
+ "94.232.173.153",
+ "94.232.173.154",
+ "94.232.173.155",
+ "94.232.173.199",
+ "94.232.173.229",
+ "94.232.174.1",
+ "94.232.174.28",
+ "94.232.174.35",
+ "94.232.174.84",
+ "94.232.174.176",
+ "94.232.174.181",
+ "94.232.174.222",
+ "94.232.174.247",
+ "94.232.174.249",
+ "94.232.174.250",
+ "94.232.175.29",
+ "94.232.175.32",
+ "94.232.175.85",
+ "94.232.175.194",
+ "95.38.13.239",
+ "95.38.24.138",
+ "95.38.34.53",
+ "95.38.40.169",
+ "95.38.47.170",
+ "95.38.47.171",
+ "95.38.47.172",
+ "95.38.47.174",
+ "95.38.48.56",
+ "95.38.60.141",
+ "95.38.60.173",
+ "95.38.60.185",
+ "95.38.60.251",
+ "95.38.65.161",
+ "95.38.65.237",
+ "95.38.72.30",
+ "95.38.77.158",
+ "95.38.86.17",
+ "95.38.102.86",
+ "95.38.102.117",
+ "95.38.102.190",
+ "95.38.103.189",
+ "95.38.103.220",
+ "95.38.103.221",
+ "95.38.103.222",
+ "95.38.125.44",
+ "95.38.130.112",
+ "95.38.130.131",
+ "95.38.134.99",
+ "95.38.135.150",
+ "95.38.137.129",
+ "95.38.138.3",
+ "95.38.153.168",
+ "95.38.155.35",
+ "95.38.155.58",
+ "95.38.201.199",
+ "95.38.209.3",
+ "95.38.245.135",
+ "95.38.250.86",
+ "95.80.141.218",
+ "95.80.155.159",
+ "95.80.164.5",
+ "95.80.164.6",
+ "95.80.164.10",
+ "95.80.168.55",
+ "95.80.173.169",
+ "95.80.182.185",
+ "95.80.184.15",
+ "95.80.184.19",
+ "95.80.184.180",
+ "95.80.184.184",
+ "95.80.185.180",
+ "95.80.185.185",
+ "95.130.56.37",
+ "95.130.56.40",
+ "95.130.245.66",
+ "95.142.224.142",
+ "95.142.226.4",
+ "95.142.226.26",
+ "95.142.227.6",
+ "95.142.227.7",
+ "95.142.227.50",
+ "95.142.227.178",
+ "95.142.227.195",
+ "95.142.227.206",
+ "95.142.227.227",
+ "95.142.227.230",
+ "95.142.227.231",
+ "95.142.231.137",
+ "95.142.235.40",
+ "95.142.237.3",
+ "95.142.237.4",
+ "95.142.237.20",
+ "95.142.237.52",
+ "95.142.237.82",
+ "95.142.237.190",
+ "95.142.237.254",
+ "95.156.252.219",
+ "95.156.253.8",
+ "95.156.253.9",
+ "95.156.253.10",
+ "95.156.253.11",
+ "95.156.253.12",
+ "95.156.253.13",
+ "95.156.253.14",
+ "95.156.253.17",
+ "95.156.253.18",
+ "95.156.253.20",
+ "95.156.253.21",
+ "95.156.253.24",
+ "95.156.253.27",
+ "95.156.253.30",
+ "95.156.253.31",
+ "95.156.253.33",
+ "95.156.253.36",
+ "95.156.253.38",
+ "95.156.253.39",
+ "95.156.253.43",
+ "95.156.253.44",
+ "95.156.253.45",
+ "95.156.253.49",
+ "95.156.253.52",
+ "95.156.253.53",
+ "95.156.253.54",
+ "95.156.253.55",
+ "95.156.253.59",
+ "95.156.253.61",
+ "95.156.253.99",
+ "95.156.253.100",
+ "95.156.253.174",
+ "95.156.253.177",
+ "95.156.254.227",
+ "95.156.254.228",
+ "95.156.254.229",
+ "95.156.254.234",
+ "95.156.254.235",
+ "95.156.254.236",
+ "95.215.59.90",
+ "95.215.59.121",
+ "95.215.59.147",
+ "95.215.59.173",
+ "95.215.59.189",
+ "95.215.59.195",
+ "95.215.173.178",
+ "95.215.173.180",
+ "103.130.144.1",
+ "103.130.144.2",
+ "103.130.144.3",
+ "103.215.222.11",
+ "103.215.222.12",
+ "103.215.222.33",
+ "103.215.222.44",
+ "103.215.222.55",
+ "103.215.222.66",
+ "103.215.222.102",
+ "103.215.222.103",
+ "103.215.222.104",
+ "103.215.222.105",
+ "103.215.222.106",
+ "103.215.222.107",
+ "103.215.222.108",
+ "103.215.222.109",
+ "103.215.222.112",
+ "103.215.222.113",
+ "103.215.222.114",
+ "103.215.222.115",
+ "103.215.222.116",
+ "103.215.222.118",
+ "103.215.222.119",
+ "103.215.222.122",
+ "103.215.222.124",
+ "103.215.222.126",
+ "103.215.222.127",
+ "103.215.222.128",
+ "103.215.222.129",
+ "103.215.222.130",
+ "103.215.222.131",
+ "103.215.222.132",
+ "103.215.222.133",
+ "103.215.222.135",
+ "103.215.222.136",
+ "103.215.222.140",
+ "103.215.222.141",
+ "103.215.222.142",
+ "103.215.222.143",
+ "103.215.222.144",
+ "103.215.222.145",
+ "103.215.222.146",
+ "103.215.222.147",
+ "103.215.222.149",
+ "103.215.222.150",
+ "103.215.222.151",
+ "103.215.222.153",
+ "103.215.222.154",
+ "103.215.222.157",
+ "103.215.223.4",
+ "103.215.223.9",
+ "103.215.223.10",
+ "103.215.223.11",
+ "103.215.223.14",
+ "103.215.223.19",
+ "103.215.223.26",
+ "103.215.223.40",
+ "103.215.223.42",
+ "103.215.223.58",
+ "103.215.223.166",
+ "103.215.223.214",
+ "103.215.223.240",
+ "103.215.223.241",
+ "103.216.60.29",
+ "103.216.60.37",
+ "103.216.60.40",
+ "103.216.60.46",
+ "103.216.61.154",
+ "103.216.62.68",
+ "103.216.62.102",
+ "109.72.192.37",
+ "109.72.192.40",
+ "109.72.197.38",
+ "109.95.61.174",
+ "109.95.61.207",
+ "109.95.61.239",
+ "109.95.61.249",
+ "109.95.61.251",
+ "109.95.67.210",
+ "109.95.68.12",
+ "109.95.68.14",
+ "109.95.68.16",
+ "109.95.68.21",
+ "109.95.68.29",
+ "109.95.68.32",
+ "109.95.70.246",
+ "109.95.71.29",
+ "109.109.32.0",
+ "109.109.32.1",
+ "109.109.32.4",
+ "109.109.32.5",
+ "109.109.32.6",
+ "109.109.32.7",
+ "109.109.32.8",
+ "109.109.32.10",
+ "109.109.32.11",
+ "109.109.32.13",
+ "109.109.32.14",
+ "109.109.32.15",
+ "109.109.32.16",
+ "109.109.32.17",
+ "109.109.32.18",
+ "109.109.32.19",
+ "109.109.32.20",
+ "109.109.32.21",
+ "109.109.32.22",
+ "109.109.32.23",
+ "109.109.32.24",
+ "109.109.32.25",
+ "109.109.32.26",
+ "109.109.32.27",
+ "109.109.32.28",
+ "109.109.32.29",
+ "109.109.32.30",
+ "109.109.32.31",
+ "109.109.32.44",
+ "109.109.32.45",
+ "109.109.32.47",
+ "109.109.32.56",
+ "109.109.32.58",
+ "109.109.32.59",
+ "109.109.32.60",
+ "109.109.32.61",
+ "109.109.32.62",
+ "109.109.32.63",
+ "109.109.32.64",
+ "109.109.32.65",
+ "109.109.32.66",
+ "109.109.32.67",
+ "109.109.32.68",
+ "109.109.32.69",
+ "109.109.32.70",
+ "109.109.32.71",
+ "109.109.32.72",
+ "109.109.32.73",
+ "109.109.32.74",
+ "109.109.32.75",
+ "109.109.32.76",
+ "109.109.32.77",
+ "109.109.32.78",
+ "109.109.32.79",
+ "109.109.32.88",
+ "109.109.32.90",
+ "109.109.32.91",
+ "109.109.32.92",
+ "109.109.32.93",
+ "109.109.32.94",
+ "109.109.32.95",
+ "109.109.32.96",
+ "109.109.32.99",
+ "109.109.32.100",
+ "109.109.32.101",
+ "109.109.32.102",
+ "109.109.32.104",
+ "109.109.32.105",
+ "109.109.32.106",
+ "109.109.32.107",
+ "109.109.32.108",
+ "109.109.32.109",
+ "109.109.32.110",
+ "109.109.32.111",
+ "109.109.32.112",
+ "109.109.32.113",
+ "109.109.32.114",
+ "109.109.32.115",
+ "109.109.32.116",
+ "109.109.32.117",
+ "109.109.32.118",
+ "109.109.32.119",
+ "109.109.32.120",
+ "109.109.32.121",
+ "109.109.32.122",
+ "109.109.32.123",
+ "109.109.32.124",
+ "109.109.32.125",
+ "109.109.32.126",
+ "109.109.32.152",
+ "109.109.32.153",
+ "109.109.32.154",
+ "109.109.32.155",
+ "109.109.32.156",
+ "109.109.32.158",
+ "109.109.32.159",
+ "109.109.32.216",
+ "109.109.32.218",
+ "109.109.32.219",
+ "109.109.32.220",
+ "109.109.32.221",
+ "109.109.32.222",
+ "109.109.32.223",
+ "109.109.34.72",
+ "109.109.34.73",
+ "109.109.34.74",
+ "109.109.34.75",
+ "109.109.34.77",
+ "109.109.34.78",
+ "109.109.34.79",
+ "109.109.34.80",
+ "109.109.34.81",
+ "109.109.34.82",
+ "109.109.34.83",
+ "109.109.34.84",
+ "109.109.34.86",
+ "109.109.34.87",
+ "109.109.34.88",
+ "109.109.34.89",
+ "109.109.34.90",
+ "109.109.34.91",
+ "109.109.34.92",
+ "109.109.34.93",
+ "109.109.34.94",
+ "109.109.34.95",
+ "109.109.34.96",
+ "109.109.34.98",
+ "109.109.34.99",
+ "109.109.34.100",
+ "109.109.34.101",
+ "109.109.34.102",
+ "109.109.34.103",
+ "109.109.34.104",
+ "109.109.34.105",
+ "109.109.34.106",
+ "109.109.34.107",
+ "109.109.34.108",
+ "109.109.34.109",
+ "109.109.34.110",
+ "109.109.34.111",
+ "109.109.34.112",
+ "109.109.34.113",
+ "109.109.34.114",
+ "109.109.34.115",
+ "109.109.34.116",
+ "109.109.34.117",
+ "109.109.34.118",
+ "109.109.34.119",
+ "109.109.34.120",
+ "109.109.34.121",
+ "109.109.34.122",
+ "109.109.34.124",
+ "109.109.34.125",
+ "109.109.34.127",
+ "109.109.34.128",
+ "109.109.34.129",
+ "109.109.34.130",
+ "109.109.34.131",
+ "109.109.34.132",
+ "109.109.34.133",
+ "109.109.34.134",
+ "109.109.34.135",
+ "109.109.34.136",
+ "109.109.34.137",
+ "109.109.34.138",
+ "109.109.34.140",
+ "109.109.34.141",
+ "109.109.34.142",
+ "109.109.34.143",
+ "109.109.34.144",
+ "109.109.34.145",
+ "109.109.34.146",
+ "109.109.34.147",
+ "109.109.34.148",
+ "109.109.34.149",
+ "109.109.34.150",
+ "109.109.34.151",
+ "109.109.34.152",
+ "109.109.34.153",
+ "109.109.34.154",
+ "109.109.34.155",
+ "109.109.34.156",
+ "109.109.34.157",
+ "109.109.34.158",
+ "109.109.34.159",
+ "109.109.34.160",
+ "109.109.34.161",
+ "109.109.34.162",
+ "109.109.34.163",
+ "109.109.34.164",
+ "109.109.34.165",
+ "109.109.34.167",
+ "109.109.34.168",
+ "109.109.34.169",
+ "109.109.34.170",
+ "109.109.34.171",
+ "109.109.34.172",
+ "109.109.34.173",
+ "109.109.34.174",
+ "109.109.34.175",
+ "109.109.34.176",
+ "109.109.34.177",
+ "109.109.34.178",
+ "109.109.34.179",
+ "109.109.34.180",
+ "109.109.34.181",
+ "109.109.34.182",
+ "109.109.34.184",
+ "109.109.34.186",
+ "109.109.34.187",
+ "109.109.34.189",
+ "109.109.34.191",
+ "109.109.34.192",
+ "109.109.34.193",
+ "109.109.34.194",
+ "109.109.34.195",
+ "109.109.34.196",
+ "109.109.34.197",
+ "109.109.34.198",
+ "109.109.34.200",
+ "109.109.34.201",
+ "109.109.34.202",
+ "109.109.34.203",
+ "109.109.34.204",
+ "109.109.34.205",
+ "109.109.34.206",
+ "109.109.34.207",
+ "109.109.34.208",
+ "109.109.34.209",
+ "109.109.34.210",
+ "109.109.34.211",
+ "109.109.34.212",
+ "109.109.34.214",
+ "109.109.34.215",
+ "109.109.34.216",
+ "109.109.34.217",
+ "109.109.34.219",
+ "109.109.34.220",
+ "109.109.34.221",
+ "109.109.34.222",
+ "109.109.34.223",
+ "109.109.34.224",
+ "109.109.34.225",
+ "109.109.34.226",
+ "109.109.34.227",
+ "109.109.34.228",
+ "109.109.34.229",
+ "109.109.34.230",
+ "109.109.34.232",
+ "109.109.34.233",
+ "109.109.34.235",
+ "109.109.34.236",
+ "109.109.34.238",
+ "109.109.34.239",
+ "109.109.34.240",
+ "109.109.34.241",
+ "109.109.34.242",
+ "109.109.34.243",
+ "109.109.34.244",
+ "109.109.34.245",
+ "109.109.34.246",
+ "109.109.34.247",
+ "109.109.34.248",
+ "109.109.34.250",
+ "109.109.34.251",
+ "109.109.34.252",
+ "109.109.34.253",
+ "109.109.34.254",
+ "109.109.35.0",
+ "109.109.35.1",
+ "109.109.35.2",
+ "109.109.35.3",
+ "109.109.35.4",
+ "109.109.35.5",
+ "109.109.35.6",
+ "109.109.35.7",
+ "109.109.35.8",
+ "109.109.35.9",
+ "109.109.35.10",
+ "109.109.35.11",
+ "109.109.35.13",
+ "109.109.35.14",
+ "109.109.35.15",
+ "109.109.35.16",
+ "109.109.35.17",
+ "109.109.35.18",
+ "109.109.35.19",
+ "109.109.35.20",
+ "109.109.35.21",
+ "109.109.35.22",
+ "109.109.35.23",
+ "109.109.35.24",
+ "109.109.35.25",
+ "109.109.35.26",
+ "109.109.35.27",
+ "109.109.35.28",
+ "109.109.35.29",
+ "109.109.35.30",
+ "109.109.35.31",
+ "109.109.35.32",
+ "109.109.35.33",
+ "109.109.35.34",
+ "109.109.35.35",
+ "109.109.35.36",
+ "109.109.35.37",
+ "109.109.35.38",
+ "109.109.35.39",
+ "109.109.35.40",
+ "109.109.35.41",
+ "109.109.35.42",
+ "109.109.35.43",
+ "109.109.35.44",
+ "109.109.35.45",
+ "109.109.35.46",
+ "109.109.35.47",
+ "109.109.35.48",
+ "109.109.35.49",
+ "109.109.35.50",
+ "109.109.35.51",
+ "109.109.35.52",
+ "109.109.35.53",
+ "109.109.35.54",
+ "109.109.35.55",
+ "109.109.35.56",
+ "109.109.35.57",
+ "109.109.35.59",
+ "109.109.35.60",
+ "109.109.35.61",
+ "109.109.35.62",
+ "109.109.35.63",
+ "109.109.35.64",
+ "109.109.35.65",
+ "109.109.35.66",
+ "109.109.35.67",
+ "109.109.35.69",
+ "109.109.35.70",
+ "109.109.35.71",
+ "109.109.35.72",
+ "109.109.35.73",
+ "109.109.35.76",
+ "109.109.35.77",
+ "109.109.35.78",
+ "109.109.35.79",
+ "109.109.35.80",
+ "109.109.35.81",
+ "109.109.35.82",
+ "109.109.35.83",
+ "109.109.35.84",
+ "109.109.35.85",
+ "109.109.35.86",
+ "109.109.35.88",
+ "109.109.35.89",
+ "109.109.35.90",
+ "109.109.35.91",
+ "109.109.35.92",
+ "109.109.35.93",
+ "109.109.35.94",
+ "109.109.35.95",
+ "109.109.35.96",
+ "109.109.35.97",
+ "109.109.35.98",
+ "109.109.35.99",
+ "109.109.35.100",
+ "109.109.35.101",
+ "109.109.35.102",
+ "109.109.35.103",
+ "109.109.35.104",
+ "109.109.35.105",
+ "109.109.35.106",
+ "109.109.35.108",
+ "109.109.35.109",
+ "109.109.35.110",
+ "109.109.35.111",
+ "109.109.35.112",
+ "109.109.35.113",
+ "109.109.35.114",
+ "109.109.35.115",
+ "109.109.35.116",
+ "109.109.35.117",
+ "109.109.35.118",
+ "109.109.35.119",
+ "109.109.35.120",
+ "109.109.35.121",
+ "109.109.35.122",
+ "109.109.35.123",
+ "109.109.35.124",
+ "109.109.35.126",
+ "109.109.35.127",
+ "109.109.42.73",
+ "109.109.43.128",
+ "109.109.43.130",
+ "109.109.43.131",
+ "109.109.43.133",
+ "109.109.43.134",
+ "109.109.43.135",
+ "109.109.43.138",
+ "109.109.43.139",
+ "109.109.43.140",
+ "109.109.43.143",
+ "109.109.43.144",
+ "109.109.43.151",
+ "109.109.43.155",
+ "109.109.43.162",
+ "109.109.43.164",
+ "109.109.43.168",
+ "109.109.43.172",
+ "109.109.43.173",
+ "109.109.43.174",
+ "109.109.43.175",
+ "109.109.43.177",
+ "109.109.43.180",
+ "109.109.43.183",
+ "109.109.43.185",
+ "109.109.43.188",
+ "109.109.43.191",
+ "109.109.43.193",
+ "109.109.43.195",
+ "109.109.43.196",
+ "109.109.43.200",
+ "109.109.43.201",
+ "109.109.43.206",
+ "109.109.43.209",
+ "109.109.43.212",
+ "109.109.43.213",
+ "109.109.43.215",
+ "109.109.43.220",
+ "109.109.43.221",
+ "109.109.43.223",
+ "109.109.43.229",
+ "109.109.43.230",
+ "109.109.43.232",
+ "109.109.43.233",
+ "109.109.43.235",
+ "109.109.43.236",
+ "109.109.43.241",
+ "109.109.43.242",
+ "109.109.43.243",
+ "109.109.43.247",
+ "109.109.43.250",
+ "109.109.43.255",
+ "109.109.45.0",
+ "109.109.45.1",
+ "109.109.45.2",
+ "109.109.45.3",
+ "109.109.45.4",
+ "109.109.45.5",
+ "109.109.45.6",
+ "109.109.45.7",
+ "109.109.45.8",
+ "109.109.45.9",
+ "109.109.45.10",
+ "109.109.45.11",
+ "109.109.45.12",
+ "109.109.45.13",
+ "109.109.45.14",
+ "109.109.45.15",
+ "109.109.45.16",
+ "109.109.45.17",
+ "109.109.45.18",
+ "109.109.45.19",
+ "109.109.45.20",
+ "109.109.45.22",
+ "109.109.45.23",
+ "109.109.45.24",
+ "109.109.45.25",
+ "109.109.45.26",
+ "109.109.45.27",
+ "109.109.45.28",
+ "109.109.45.29",
+ "109.109.45.30",
+ "109.109.45.31",
+ "109.109.45.40",
+ "109.109.45.41",
+ "109.109.45.42",
+ "109.109.45.43",
+ "109.109.45.44",
+ "109.109.45.45",
+ "109.109.45.46",
+ "109.109.45.47",
+ "109.109.45.48",
+ "109.109.45.49",
+ "109.109.45.50",
+ "109.109.45.51",
+ "109.109.45.52",
+ "109.109.45.54",
+ "109.109.45.55",
+ "109.109.45.56",
+ "109.109.45.57",
+ "109.109.45.58",
+ "109.109.45.59",
+ "109.109.45.60",
+ "109.109.45.61",
+ "109.109.45.62",
+ "109.109.45.63",
+ "109.109.45.64",
+ "109.109.45.65",
+ "109.109.45.66",
+ "109.109.45.67",
+ "109.109.45.68",
+ "109.109.45.70",
+ "109.109.45.71",
+ "109.109.45.72",
+ "109.109.45.73",
+ "109.109.45.74",
+ "109.109.45.75",
+ "109.109.45.76",
+ "109.109.45.77",
+ "109.109.45.78",
+ "109.109.45.79",
+ "109.109.45.80",
+ "109.109.45.81",
+ "109.109.45.84",
+ "109.109.45.87",
+ "109.109.45.88",
+ "109.109.45.89",
+ "109.109.45.90",
+ "109.109.45.91",
+ "109.109.45.92",
+ "109.109.45.93",
+ "109.109.45.94",
+ "109.109.45.95",
+ "109.109.45.96",
+ "109.109.45.98",
+ "109.109.45.99",
+ "109.109.45.100",
+ "109.109.45.101",
+ "109.109.45.102",
+ "109.109.45.103",
+ "109.109.45.104",
+ "109.109.45.105",
+ "109.109.45.106",
+ "109.109.45.107",
+ "109.109.45.108",
+ "109.109.45.109",
+ "109.109.45.110",
+ "109.109.45.111",
+ "109.109.45.112",
+ "109.109.45.113",
+ "109.109.45.115",
+ "109.109.45.116",
+ "109.109.45.117",
+ "109.109.45.119",
+ "109.109.45.120",
+ "109.109.45.121",
+ "109.109.45.123",
+ "109.109.45.124",
+ "109.109.45.125",
+ "109.109.45.126",
+ "109.109.45.127",
+ "109.109.47.0",
+ "109.109.47.2",
+ "109.109.47.3",
+ "109.109.47.4",
+ "109.109.47.5",
+ "109.109.47.8",
+ "109.109.47.10",
+ "109.109.47.13",
+ "109.109.47.16",
+ "109.109.47.17",
+ "109.109.47.18",
+ "109.109.47.19",
+ "109.109.47.23",
+ "109.109.47.25",
+ "109.109.47.27",
+ "109.109.47.29",
+ "109.109.47.32",
+ "109.109.47.34",
+ "109.109.47.35",
+ "109.109.47.43",
+ "109.109.47.50",
+ "109.109.47.51",
+ "109.109.47.52",
+ "109.109.47.54",
+ "109.109.47.57",
+ "109.109.47.59",
+ "109.109.47.62",
+ "109.109.47.63",
+ "109.109.47.64",
+ "109.109.47.65",
+ "109.109.47.67",
+ "109.109.47.70",
+ "109.109.47.72",
+ "109.109.47.73",
+ "109.109.47.74",
+ "109.109.47.76",
+ "109.109.47.78",
+ "109.109.47.80",
+ "109.109.47.81",
+ "109.109.47.82",
+ "109.109.47.83",
+ "109.109.47.84",
+ "109.109.47.85",
+ "109.109.47.86",
+ "109.109.47.87",
+ "109.109.47.90",
+ "109.109.47.91",
+ "109.109.47.92",
+ "109.109.47.94",
+ "109.109.47.95",
+ "109.109.47.97",
+ "109.109.47.101",
+ "109.109.47.102",
+ "109.109.47.103",
+ "109.109.47.104",
+ "109.109.47.106",
+ "109.109.47.107",
+ "109.109.47.108",
+ "109.109.47.109",
+ "109.109.47.113",
+ "109.109.47.115",
+ "109.109.47.116",
+ "109.109.47.117",
+ "109.109.47.119",
+ "109.109.47.120",
+ "109.109.47.121",
+ "109.109.47.122",
+ "109.109.47.123",
+ "109.109.47.124",
+ "109.109.47.125",
+ "109.109.47.126",
+ "109.109.51.111",
+ "109.109.51.178",
+ "109.109.52.111",
+ "109.109.54.0",
+ "109.109.54.4",
+ "109.109.54.7",
+ "109.109.54.11",
+ "109.109.54.12",
+ "109.109.54.13",
+ "109.109.54.14",
+ "109.109.54.20",
+ "109.109.54.22",
+ "109.109.54.23",
+ "109.109.54.34",
+ "109.109.54.35",
+ "109.109.54.36",
+ "109.109.54.37",
+ "109.109.54.40",
+ "109.109.54.41",
+ "109.109.54.42",
+ "109.109.54.45",
+ "109.109.54.49",
+ "109.109.54.52",
+ "109.109.54.56",
+ "109.109.54.57",
+ "109.109.54.59",
+ "109.109.54.61",
+ "109.109.54.63",
+ "109.109.54.64",
+ "109.109.54.65",
+ "109.109.54.66",
+ "109.109.54.67",
+ "109.109.54.70",
+ "109.109.54.71",
+ "109.109.54.72",
+ "109.109.54.73",
+ "109.109.54.74",
+ "109.109.54.75",
+ "109.109.54.76",
+ "109.109.54.78",
+ "109.109.54.79",
+ "109.109.54.80",
+ "109.109.54.81",
+ "109.109.54.82",
+ "109.109.54.85",
+ "109.109.54.88",
+ "109.109.54.90",
+ "109.109.54.95",
+ "109.109.54.96",
+ "109.109.54.99",
+ "109.109.54.100",
+ "109.109.54.102",
+ "109.109.54.103",
+ "109.109.54.105",
+ "109.109.54.106",
+ "109.109.54.107",
+ "109.109.54.110",
+ "109.109.54.111",
+ "109.109.54.112",
+ "109.109.54.121",
+ "109.109.54.123",
+ "109.109.54.124",
+ "109.109.54.125",
+ "109.109.54.127",
+ "109.109.54.136",
+ "109.109.54.137",
+ "109.109.54.138",
+ "109.109.54.139",
+ "109.109.54.140",
+ "109.109.54.143",
+ "109.109.54.144",
+ "109.109.54.145",
+ "109.109.54.147",
+ "109.109.54.149",
+ "109.109.54.151",
+ "109.109.54.154",
+ "109.109.54.157",
+ "109.109.54.158",
+ "109.109.54.160",
+ "109.109.54.161",
+ "109.109.54.162",
+ "109.109.54.163",
+ "109.109.54.165",
+ "109.109.54.167",
+ "109.109.54.170",
+ "109.109.54.172",
+ "109.109.54.175",
+ "109.109.54.176",
+ "109.109.54.179",
+ "109.109.54.180",
+ "109.109.54.181",
+ "109.109.54.182",
+ "109.109.54.184",
+ "109.109.54.185",
+ "109.109.54.186",
+ "109.109.54.188",
+ "109.109.54.190",
+ "109.109.54.191",
+ "109.109.54.192",
+ "109.109.54.193",
+ "109.109.54.194",
+ "109.109.54.195",
+ "109.109.54.196",
+ "109.109.54.197",
+ "109.109.54.201",
+ "109.109.54.202",
+ "109.109.54.203",
+ "109.109.54.204",
+ "109.109.54.205",
+ "109.109.54.206",
+ "109.109.54.208",
+ "109.109.54.210",
+ "109.109.54.211",
+ "109.109.54.213",
+ "109.109.54.214",
+ "109.109.54.215",
+ "109.109.54.216",
+ "109.109.54.217",
+ "109.109.54.218",
+ "109.109.54.220",
+ "109.109.54.221",
+ "109.109.54.222",
+ "109.109.54.223",
+ "109.109.54.224",
+ "109.109.54.225",
+ "109.109.54.226",
+ "109.109.54.227",
+ "109.109.54.228",
+ "109.109.54.229",
+ "109.109.54.230",
+ "109.109.54.231",
+ "109.109.54.237",
+ "109.109.54.238",
+ "109.109.54.240",
+ "109.109.54.241",
+ "109.109.54.242",
+ "109.109.54.243",
+ "109.109.54.244",
+ "109.109.54.245",
+ "109.109.54.246",
+ "109.109.54.247",
+ "109.109.54.248",
+ "109.109.54.249",
+ "109.109.54.250",
+ "109.109.54.251",
+ "109.109.54.252",
+ "109.109.54.254",
+ "109.109.54.255",
+ "109.109.56.137",
+ "109.109.58.0",
+ "109.109.58.1",
+ "109.109.58.2",
+ "109.109.58.3",
+ "109.109.58.4",
+ "109.109.58.5",
+ "109.109.58.6",
+ "109.109.58.7",
+ "109.109.58.9",
+ "109.109.58.10",
+ "109.109.58.11",
+ "109.109.58.12",
+ "109.109.58.13",
+ "109.109.58.14",
+ "109.109.58.15",
+ "109.109.58.16",
+ "109.109.58.17",
+ "109.109.58.18",
+ "109.109.58.19",
+ "109.109.58.20",
+ "109.109.58.21",
+ "109.109.58.22",
+ "109.109.58.23",
+ "109.109.58.24",
+ "109.109.58.25",
+ "109.109.58.26",
+ "109.109.58.27",
+ "109.109.58.28",
+ "109.109.58.29",
+ "109.109.58.30",
+ "109.109.58.31",
+ "109.109.58.32",
+ "109.109.58.33",
+ "109.109.58.34",
+ "109.109.58.35",
+ "109.109.58.37",
+ "109.109.58.38",
+ "109.109.58.39",
+ "109.109.58.40",
+ "109.109.58.41",
+ "109.109.58.42",
+ "109.109.58.44",
+ "109.109.58.45",
+ "109.109.58.46",
+ "109.109.58.47",
+ "109.109.58.48",
+ "109.109.58.49",
+ "109.109.58.50",
+ "109.109.58.51",
+ "109.109.58.52",
+ "109.109.58.53",
+ "109.109.58.54",
+ "109.109.58.55",
+ "109.109.58.56",
+ "109.109.58.57",
+ "109.109.58.58",
+ "109.109.58.59",
+ "109.109.58.60",
+ "109.109.58.61",
+ "109.109.58.62",
+ "109.109.58.63",
+ "109.109.58.128",
+ "109.109.58.129",
+ "109.109.58.131",
+ "109.109.58.132",
+ "109.109.58.133",
+ "109.109.58.134",
+ "109.109.58.135",
+ "109.109.58.136",
+ "109.109.58.137",
+ "109.109.58.138",
+ "109.109.58.139",
+ "109.109.58.140",
+ "109.109.58.141",
+ "109.109.58.142",
+ "109.109.58.143",
+ "109.109.58.160",
+ "109.109.58.161",
+ "109.109.58.162",
+ "109.109.58.163",
+ "109.109.58.164",
+ "109.109.58.165",
+ "109.109.58.168",
+ "109.109.58.169",
+ "109.109.58.170",
+ "109.109.58.171",
+ "109.109.58.172",
+ "109.109.58.173",
+ "109.109.58.174",
+ "109.109.58.175",
+ "109.109.59.0",
+ "109.109.59.2",
+ "109.109.59.3",
+ "109.109.59.4",
+ "109.109.59.5",
+ "109.109.59.7",
+ "109.109.59.32",
+ "109.109.59.33",
+ "109.109.59.37",
+ "109.109.59.38",
+ "109.109.59.39",
+ "109.109.59.40",
+ "109.109.59.41",
+ "109.109.59.42",
+ "109.109.59.43",
+ "109.109.59.44",
+ "109.109.59.45",
+ "109.109.59.46",
+ "109.109.59.47",
+ "109.109.59.48",
+ "109.109.59.49",
+ "109.109.59.50",
+ "109.109.59.51",
+ "109.109.59.60",
+ "109.109.59.61",
+ "109.109.59.62",
+ "109.109.59.63",
+ "109.109.59.64",
+ "109.109.59.65",
+ "109.109.59.66",
+ "109.109.59.67",
+ "109.109.59.68",
+ "109.109.59.69",
+ "109.109.59.70",
+ "109.109.59.71",
+ "109.109.59.72",
+ "109.109.59.73",
+ "109.109.59.74",
+ "109.109.59.75",
+ "109.109.59.76",
+ "109.109.59.78",
+ "109.109.59.80",
+ "109.109.59.81",
+ "109.109.59.82",
+ "109.109.59.83",
+ "109.109.59.85",
+ "109.109.59.87",
+ "109.109.59.89",
+ "109.109.59.90",
+ "109.109.59.91",
+ "109.109.59.92",
+ "109.109.59.93",
+ "109.109.59.94",
+ "109.109.59.95",
+ "109.109.59.96",
+ "109.109.59.97",
+ "109.109.59.98",
+ "109.109.59.100",
+ "109.109.59.101",
+ "109.109.59.102",
+ "109.109.59.103",
+ "109.109.59.104",
+ "109.109.59.105",
+ "109.109.59.106",
+ "109.109.59.107",
+ "109.109.59.109",
+ "109.109.59.110",
+ "109.109.59.111",
+ "109.109.59.112",
+ "109.109.59.113",
+ "109.109.59.114",
+ "109.109.59.115",
+ "109.109.59.116",
+ "109.109.59.117",
+ "109.109.59.118",
+ "109.109.59.119",
+ "109.109.59.120",
+ "109.109.59.121",
+ "109.109.59.122",
+ "109.109.59.123",
+ "109.109.59.124",
+ "109.109.59.125",
+ "109.109.59.126",
+ "109.109.59.127",
+ "109.109.60.0",
+ "109.109.60.1",
+ "109.109.60.2",
+ "109.109.60.3",
+ "109.109.60.4",
+ "109.109.60.5",
+ "109.109.60.6",
+ "109.109.60.8",
+ "109.109.60.10",
+ "109.109.60.11",
+ "109.109.60.12",
+ "109.109.60.13",
+ "109.109.60.14",
+ "109.109.60.15",
+ "109.109.60.17",
+ "109.109.60.18",
+ "109.109.60.19",
+ "109.109.60.20",
+ "109.109.60.21",
+ "109.109.60.22",
+ "109.109.60.27",
+ "109.109.60.28",
+ "109.109.60.29",
+ "109.109.60.30",
+ "109.109.60.33",
+ "109.109.60.35",
+ "109.109.60.37",
+ "109.109.60.38",
+ "109.109.60.41",
+ "109.109.60.45",
+ "109.109.60.47",
+ "109.109.60.50",
+ "109.109.60.52",
+ "109.109.60.53",
+ "109.109.60.55",
+ "109.109.60.57",
+ "109.109.60.58",
+ "109.109.60.59",
+ "109.109.60.60",
+ "109.109.60.61",
+ "109.109.60.62",
+ "109.109.60.63",
+ "109.109.60.64",
+ "109.109.60.65",
+ "109.109.60.66",
+ "109.109.60.67",
+ "109.109.60.68",
+ "109.109.60.72",
+ "109.109.60.76",
+ "109.109.60.77",
+ "109.109.60.79",
+ "109.109.60.84",
+ "109.109.60.85",
+ "109.109.60.87",
+ "109.109.60.88",
+ "109.109.60.89",
+ "109.109.60.92",
+ "109.109.60.94",
+ "109.109.60.96",
+ "109.109.60.97",
+ "109.109.60.103",
+ "109.109.60.104",
+ "109.109.60.106",
+ "109.109.60.109",
+ "109.109.60.110",
+ "109.109.60.111",
+ "109.109.60.112",
+ "109.109.60.114",
+ "109.109.60.117",
+ "109.109.60.118",
+ "109.109.60.120",
+ "109.109.60.122",
+ "109.109.60.123",
+ "109.109.60.125",
+ "109.109.60.126",
+ "109.109.60.127",
+ "109.109.60.128",
+ "109.109.60.129",
+ "109.109.60.130",
+ "109.109.60.131",
+ "109.109.60.132",
+ "109.109.60.133",
+ "109.109.60.134",
+ "109.109.60.135",
+ "109.109.60.136",
+ "109.109.60.137",
+ "109.109.60.138",
+ "109.109.60.139",
+ "109.109.60.140",
+ "109.109.60.141",
+ "109.109.60.142",
+ "109.109.60.143",
+ "109.109.60.144",
+ "109.109.60.145",
+ "109.109.60.146",
+ "109.109.60.147",
+ "109.109.60.148",
+ "109.109.60.149",
+ "109.109.60.152",
+ "109.109.60.153",
+ "109.109.60.154",
+ "109.109.60.155",
+ "109.109.60.156",
+ "109.109.60.157",
+ "109.109.60.158",
+ "109.109.60.159",
+ "109.109.60.160",
+ "109.109.60.161",
+ "109.109.60.162",
+ "109.109.60.163",
+ "109.109.60.164",
+ "109.109.60.165",
+ "109.109.60.166",
+ "109.109.60.167",
+ "109.109.60.168",
+ "109.109.60.169",
+ "109.109.60.170",
+ "109.109.60.171",
+ "109.109.60.172",
+ "109.109.60.173",
+ "109.109.60.174",
+ "109.109.60.175",
+ "109.109.60.177",
+ "109.109.60.178",
+ "109.109.60.179",
+ "109.109.60.180",
+ "109.109.60.181",
+ "109.109.60.182",
+ "109.109.60.183",
+ "109.109.60.184",
+ "109.109.60.185",
+ "109.109.60.186",
+ "109.109.60.187",
+ "109.109.60.188",
+ "109.109.60.189",
+ "109.109.60.190",
+ "109.109.60.191",
+ "109.109.60.192",
+ "109.109.60.193",
+ "109.109.60.194",
+ "109.109.60.195",
+ "109.109.60.196",
+ "109.109.60.197",
+ "109.109.60.198",
+ "109.109.60.199",
+ "109.109.60.200",
+ "109.109.60.201",
+ "109.109.60.202",
+ "109.109.60.203",
+ "109.109.60.205",
+ "109.109.60.207",
+ "109.109.60.208",
+ "109.109.60.209",
+ "109.109.60.210",
+ "109.109.60.211",
+ "109.109.60.212",
+ "109.109.60.213",
+ "109.109.60.214",
+ "109.109.60.215",
+ "109.109.60.216",
+ "109.109.60.217",
+ "109.109.60.218",
+ "109.109.60.219",
+ "109.109.60.220",
+ "109.109.60.221",
+ "109.109.60.222",
+ "109.109.60.223",
+ "109.109.60.224",
+ "109.109.60.225",
+ "109.109.60.226",
+ "109.109.60.227",
+ "109.109.60.228",
+ "109.109.60.229",
+ "109.109.60.230",
+ "109.109.60.231",
+ "109.109.60.232",
+ "109.109.60.233",
+ "109.109.60.234",
+ "109.109.60.235",
+ "109.109.60.236",
+ "109.109.60.237",
+ "109.109.60.238",
+ "109.109.60.239",
+ "109.109.61.99",
+ "109.109.61.192",
+ "109.109.61.193",
+ "109.109.61.194",
+ "109.109.61.196",
+ "109.109.61.197",
+ "109.109.61.198",
+ "109.109.61.199",
+ "109.109.61.200",
+ "109.109.61.201",
+ "109.109.61.202",
+ "109.109.61.203",
+ "109.109.61.204",
+ "109.109.61.205",
+ "109.109.61.206",
+ "109.109.61.207",
+ "109.109.61.210",
+ "109.109.61.211",
+ "109.109.61.212",
+ "109.109.61.213",
+ "109.109.61.214",
+ "109.109.61.215",
+ "109.109.61.217",
+ "109.109.61.219",
+ "109.109.61.220",
+ "109.109.61.221",
+ "109.109.61.222",
+ "109.109.61.223",
+ "109.109.61.224",
+ "109.109.61.225",
+ "109.109.61.226",
+ "109.109.61.227",
+ "109.109.61.228",
+ "109.109.61.229",
+ "109.109.61.230",
+ "109.109.61.231",
+ "109.109.61.233",
+ "109.109.61.234",
+ "109.109.61.235",
+ "109.109.61.236",
+ "109.109.61.237",
+ "109.109.61.238",
+ "109.109.61.240",
+ "109.109.61.241",
+ "109.109.61.242",
+ "109.109.61.243",
+ "109.109.61.244",
+ "109.109.61.245",
+ "109.109.61.246",
+ "109.109.61.247",
+ "109.109.61.248",
+ "109.109.61.249",
+ "109.109.61.250",
+ "109.109.61.251",
+ "109.109.61.252",
+ "109.109.61.253",
+ "109.109.61.254",
+ "109.109.61.255",
+ "109.109.62.1",
+ "109.109.62.3",
+ "109.109.62.4",
+ "109.109.62.5",
+ "109.109.62.6",
+ "109.109.62.40",
+ "109.109.62.41",
+ "109.109.62.42",
+ "109.109.62.43",
+ "109.109.62.44",
+ "109.109.62.45",
+ "109.109.62.46",
+ "109.109.62.47",
+ "109.109.62.48",
+ "109.109.62.49",
+ "109.109.62.50",
+ "109.109.62.51",
+ "109.109.62.52",
+ "109.109.62.54",
+ "109.109.62.55",
+ "109.109.63.128",
+ "109.109.63.129",
+ "109.109.63.131",
+ "109.109.63.132",
+ "109.109.63.133",
+ "109.109.63.134",
+ "109.109.63.135",
+ "109.109.63.137",
+ "109.109.63.138",
+ "109.109.63.139",
+ "109.109.63.140",
+ "109.109.63.141",
+ "109.109.63.142",
+ "109.109.63.143",
+ "109.109.63.144",
+ "109.109.63.145",
+ "109.109.63.146",
+ "109.109.63.147",
+ "109.109.63.148",
+ "109.109.63.149",
+ "109.109.63.150",
+ "109.109.63.151",
+ "109.109.63.153",
+ "109.109.63.154",
+ "109.109.63.155",
+ "109.109.63.156",
+ "109.109.63.157",
+ "109.109.63.158",
+ "109.109.63.159",
+ "109.109.63.160",
+ "109.109.63.161",
+ "109.109.63.162",
+ "109.109.63.163",
+ "109.109.63.164",
+ "109.109.63.165",
+ "109.109.63.166",
+ "109.109.63.167",
+ "109.109.63.168",
+ "109.109.63.169",
+ "109.109.63.170",
+ "109.109.63.171",
+ "109.109.63.172",
+ "109.109.63.173",
+ "109.109.63.174",
+ "109.109.63.175",
+ "109.109.63.184",
+ "109.109.63.185",
+ "109.109.63.186",
+ "109.109.63.187",
+ "109.109.63.188",
+ "109.109.63.189",
+ "109.109.63.190",
+ "109.109.63.191",
+ "109.109.63.192",
+ "109.109.63.194",
+ "109.109.63.195",
+ "109.109.63.197",
+ "109.109.63.198",
+ "109.109.63.199",
+ "109.109.63.200",
+ "109.109.63.201",
+ "109.109.63.202",
+ "109.109.63.203",
+ "109.109.63.204",
+ "109.109.63.205",
+ "109.109.63.206",
+ "109.109.63.207",
+ "109.109.63.209",
+ "109.109.63.210",
+ "109.109.63.211",
+ "109.109.63.212",
+ "109.109.63.213",
+ "109.109.63.214",
+ "109.109.63.215",
+ "109.109.63.224",
+ "109.109.63.226",
+ "109.109.63.227",
+ "109.109.63.228",
+ "109.109.63.229",
+ "109.109.63.230",
+ "109.109.63.231",
+ "109.109.63.232",
+ "109.109.63.233",
+ "109.109.63.234",
+ "109.109.63.235",
+ "109.109.63.236",
+ "109.109.63.237",
+ "109.109.63.238",
+ "109.109.63.239",
+ "109.109.63.240",
+ "109.109.63.242",
+ "109.109.63.243",
+ "109.109.63.244",
+ "109.109.63.245",
+ "109.109.63.246",
+ "109.109.63.247",
+ "109.109.63.248",
+ "109.109.63.249",
+ "109.109.63.250",
+ "109.109.63.251",
+ "109.109.63.252",
+ "109.109.63.254",
+ "109.109.63.255",
+ "109.122.235.163",
+ "109.122.240.164",
+ "109.122.245.12",
+ "109.122.245.14",
+ "109.122.245.20",
+ "109.122.245.28",
+ "109.122.245.32",
+ "109.122.245.34",
+ "109.122.245.37",
+ "109.122.245.47",
+ "109.122.245.48",
+ "109.122.245.49",
+ "109.122.245.50",
+ "109.122.245.52",
+ "109.122.245.55",
+ "109.122.245.57",
+ "109.122.245.83",
+ "109.122.245.90",
+ "109.122.245.94",
+ "109.122.245.114",
+ "109.122.245.115",
+ "109.122.245.116",
+ "109.122.245.117",
+ "109.122.245.118",
+ "109.122.245.122",
+ "109.122.245.138",
+ "109.122.245.163",
+ "109.122.245.196",
+ "109.122.246.22",
+ "109.122.246.32",
+ "109.122.246.41",
+ "109.122.246.51",
+ "109.122.246.122",
+ "109.122.246.172",
+ "109.122.246.210",
+ "109.122.246.226",
+ "109.122.246.250",
+ "109.122.246.252",
+ "109.122.251.4",
+ "109.122.251.5",
+ "109.122.251.10",
+ "109.122.251.12",
+ "109.122.251.13",
+ "109.122.251.118",
+ "109.122.253.18",
+ "109.125.129.255",
+ "109.125.130.0",
+ "109.125.131.87",
+ "109.125.135.109",
+ "109.125.150.34",
+ "109.125.151.67",
+ "109.125.160.14",
+ "109.125.160.170",
+ "109.201.24.195",
+ "109.201.24.197",
+ "109.201.24.198",
+ "109.201.24.199",
+ "109.201.24.200",
+ "109.201.24.201",
+ "109.201.24.202",
+ "109.201.24.203",
+ "109.201.24.204",
+ "109.201.24.205",
+ "109.201.24.206",
+ "109.206.252.44",
+ "109.206.252.198",
+ "109.206.254.13",
+ "109.206.254.140",
+ "109.206.255.13",
+ "109.206.255.146",
+ "109.206.255.148",
+ "109.206.255.149",
+ "109.206.255.178",
+ "109.206.255.188",
+ "109.230.81.238",
+ "109.230.82.34",
+ "109.230.83.227",
+ "109.230.83.234",
+ "109.230.88.171",
+ "109.230.89.74",
+ "109.230.89.75",
+ "109.230.89.76",
+ "109.230.89.77",
+ "109.230.89.78",
+ "109.230.89.90",
+ "109.230.89.91",
+ "109.230.89.94",
+ "109.230.92.50",
+ "109.230.94.82",
+ "109.230.95.153",
+ "109.230.95.164",
+ "109.230.200.117",
+ "109.230.200.118",
+ "109.230.200.119",
+ "109.230.200.120",
+ "109.230.200.188",
+ "109.230.204.17",
+ "109.230.204.95",
+ "109.230.204.180",
+ "109.230.205.16",
+ "109.230.205.20",
+ "109.230.205.21",
+ "109.230.205.139",
+ "109.230.205.154",
+ "109.230.205.164",
+ "109.230.206.171",
+ "109.230.206.174",
+ "109.230.206.175",
+ "109.230.206.180",
+ "109.230.221.102",
+ "109.230.221.103",
+ "109.230.221.106",
+ "109.230.223.74",
+ "109.230.223.75",
+ "109.230.223.170",
+ "109.230.223.182",
+ "109.230.242.117",
+ "109.232.1.6",
+ "109.232.1.59",
+ "109.232.1.60",
+ "109.232.1.62",
+ "109.232.1.138",
+ "109.232.1.217",
+ "109.232.1.219",
+ "109.232.2.123",
+ "109.238.191.251",
+ "128.65.181.137",
+ "128.65.183.223",
+ "128.65.184.126",
+ "128.65.187.239",
+ "128.65.188.31",
+ "130.185.72.53",
+ "130.185.72.61",
+ "130.185.72.64",
+ "130.185.72.84",
+ "130.185.72.85",
+ "130.185.72.94",
+ "130.185.72.98",
+ "130.185.72.105",
+ "130.185.72.107",
+ "130.185.72.108",
+ "130.185.72.115",
+ "130.185.72.119",
+ "130.185.72.120",
+ "130.185.72.125",
+ "130.185.72.131",
+ "130.185.72.138",
+ "130.185.72.142",
+ "130.185.72.149",
+ "130.185.72.170",
+ "130.185.72.172",
+ "130.185.72.181",
+ "130.185.72.213",
+ "130.185.72.216",
+ "130.185.72.223",
+ "130.185.72.248",
+ "130.185.72.249",
+ "130.185.73.3",
+ "130.185.73.4",
+ "130.185.73.5",
+ "130.185.73.6",
+ "130.185.73.8",
+ "130.185.73.12",
+ "130.185.73.13",
+ "130.185.73.18",
+ "130.185.73.19",
+ "130.185.73.22",
+ "130.185.73.30",
+ "130.185.73.32",
+ "130.185.73.34",
+ "130.185.73.58",
+ "130.185.73.64",
+ "130.185.73.65",
+ "130.185.73.70",
+ "130.185.73.88",
+ "130.185.73.90",
+ "130.185.73.96",
+ "130.185.73.100",
+ "130.185.73.102",
+ "130.185.73.104",
+ "130.185.73.105",
+ "130.185.73.106",
+ "130.185.73.108",
+ "130.185.73.111",
+ "130.185.73.126",
+ "130.185.73.131",
+ "130.185.73.134",
+ "130.185.73.137",
+ "130.185.73.140",
+ "130.185.73.141",
+ "130.185.73.144",
+ "130.185.73.146",
+ "130.185.73.149",
+ "130.185.73.153",
+ "130.185.73.156",
+ "130.185.73.160",
+ "130.185.73.165",
+ "130.185.73.176",
+ "130.185.73.189",
+ "130.185.73.190",
+ "130.185.73.194",
+ "130.185.73.197",
+ "130.185.73.200",
+ "130.185.73.209",
+ "130.185.73.214",
+ "130.185.73.217",
+ "130.185.73.220",
+ "130.185.73.230",
+ "130.185.73.239",
+ "130.185.73.242",
+ "130.185.73.245",
+ "130.185.73.246",
+ "130.185.74.11",
+ "130.185.74.18",
+ "130.185.74.26",
+ "130.185.74.28",
+ "130.185.74.33",
+ "130.185.74.43",
+ "130.185.74.47",
+ "130.185.74.51",
+ "130.185.74.65",
+ "130.185.74.76",
+ "130.185.74.79",
+ "130.185.74.84",
+ "130.185.74.85",
+ "130.185.74.86",
+ "130.185.74.90",
+ "130.185.74.91",
+ "130.185.74.94",
+ "130.185.74.96",
+ "130.185.74.97",
+ "130.185.74.105",
+ "130.185.74.106",
+ "130.185.74.116",
+ "130.185.74.120",
+ "130.185.74.122",
+ "130.185.74.123",
+ "130.185.74.125",
+ "130.185.74.126",
+ "130.185.74.133",
+ "130.185.74.134",
+ "130.185.74.136",
+ "130.185.74.140",
+ "130.185.74.145",
+ "130.185.74.147",
+ "130.185.74.150",
+ "130.185.74.152",
+ "130.185.74.155",
+ "130.185.74.160",
+ "130.185.74.161",
+ "130.185.74.163",
+ "130.185.74.168",
+ "130.185.74.170",
+ "130.185.74.183",
+ "130.185.74.185",
+ "130.185.74.193",
+ "130.185.74.197",
+ "130.185.74.198",
+ "130.185.74.204",
+ "130.185.74.208",
+ "130.185.74.218",
+ "130.185.74.227",
+ "130.185.74.234",
+ "130.185.74.239",
+ "130.185.74.245",
+ "130.185.74.246",
+ "130.185.74.249",
+ "130.185.74.250",
+ "130.185.75.5",
+ "130.185.75.7",
+ "130.185.75.8",
+ "130.185.75.11",
+ "130.185.75.15",
+ "130.185.75.27",
+ "130.185.75.29",
+ "130.185.75.33",
+ "130.185.75.40",
+ "130.185.75.43",
+ "130.185.75.46",
+ "130.185.75.54",
+ "130.185.75.57",
+ "130.185.75.75",
+ "130.185.75.76",
+ "130.185.75.78",
+ "130.185.75.80",
+ "130.185.75.85",
+ "130.185.75.92",
+ "130.185.75.93",
+ "130.185.75.100",
+ "130.185.75.116",
+ "130.185.75.121",
+ "130.185.75.123",
+ "130.185.75.135",
+ "130.185.75.138",
+ "130.185.75.144",
+ "130.185.75.149",
+ "130.185.75.152",
+ "130.185.75.159",
+ "130.185.75.163",
+ "130.185.75.165",
+ "130.185.75.168",
+ "130.185.75.170",
+ "130.185.75.179",
+ "130.185.75.180",
+ "130.185.75.182",
+ "130.185.75.184",
+ "130.185.75.185",
+ "130.185.75.186",
+ "130.185.75.189",
+ "130.185.75.190",
+ "130.185.75.197",
+ "130.185.75.206",
+ "130.185.75.207",
+ "130.185.75.216",
+ "130.185.75.217",
+ "130.185.75.219",
+ "130.185.75.224",
+ "130.185.75.229",
+ "130.185.75.232",
+ "130.185.75.233",
+ "130.185.75.234",
+ "130.185.75.241",
+ "130.185.75.243",
+ "130.185.75.244",
+ "130.185.75.252",
+ "130.185.76.7",
+ "130.185.76.9",
+ "130.185.76.12",
+ "130.185.76.20",
+ "130.185.76.21",
+ "130.185.76.26",
+ "130.185.76.28",
+ "130.185.76.31",
+ "130.185.76.48",
+ "130.185.76.52",
+ "130.185.76.53",
+ "130.185.76.64",
+ "130.185.76.66",
+ "130.185.76.69",
+ "130.185.76.70",
+ "130.185.76.74",
+ "130.185.76.78",
+ "130.185.76.84",
+ "130.185.76.86",
+ "130.185.76.91",
+ "130.185.76.94",
+ "130.185.76.103",
+ "130.185.76.104",
+ "130.185.76.106",
+ "130.185.76.114",
+ "130.185.76.123",
+ "130.185.76.127",
+ "130.185.76.132",
+ "130.185.76.140",
+ "130.185.76.149",
+ "130.185.76.150",
+ "130.185.76.152",
+ "130.185.76.156",
+ "130.185.76.162",
+ "130.185.76.165",
+ "130.185.76.170",
+ "130.185.76.172",
+ "130.185.76.176",
+ "130.185.76.185",
+ "130.185.76.188",
+ "130.185.76.191",
+ "130.185.76.197",
+ "130.185.76.200",
+ "130.185.76.205",
+ "130.185.76.225",
+ "130.185.76.231",
+ "130.185.76.238",
+ "130.185.76.240",
+ "130.185.76.243",
+ "130.185.76.248",
+ "130.185.76.251",
+ "130.185.77.10",
+ "130.185.77.12",
+ "130.185.77.16",
+ "130.185.77.17",
+ "130.185.77.22",
+ "130.185.77.29",
+ "130.185.77.34",
+ "130.185.77.40",
+ "130.185.77.43",
+ "130.185.77.44",
+ "130.185.77.46",
+ "130.185.77.48",
+ "130.185.77.54",
+ "130.185.77.61",
+ "130.185.77.62",
+ "130.185.77.63",
+ "130.185.77.64",
+ "130.185.77.67",
+ "130.185.77.69",
+ "130.185.77.71",
+ "130.185.77.72",
+ "130.185.77.77",
+ "130.185.77.78",
+ "130.185.77.79",
+ "130.185.77.86",
+ "130.185.77.88",
+ "130.185.77.89",
+ "130.185.77.91",
+ "130.185.77.97",
+ "130.185.77.101",
+ "130.185.77.114",
+ "130.185.77.118",
+ "130.185.77.124",
+ "130.185.77.129",
+ "130.185.77.131",
+ "130.185.77.132",
+ "130.185.77.133",
+ "130.185.77.145",
+ "130.185.77.146",
+ "130.185.77.158",
+ "130.185.77.160",
+ "130.185.77.162",
+ "130.185.77.165",
+ "130.185.77.173",
+ "130.185.77.181",
+ "130.185.77.195",
+ "130.185.77.199",
+ "130.185.77.206",
+ "130.185.77.214",
+ "130.185.77.218",
+ "130.185.77.221",
+ "130.185.77.222",
+ "130.185.77.225",
+ "130.185.77.227",
+ "130.185.77.230",
+ "130.185.77.237",
+ "130.185.77.242",
+ "130.185.77.246",
+ "130.185.77.247",
+ "130.185.77.249",
+ "130.185.78.5",
+ "130.185.78.18",
+ "130.185.78.40",
+ "130.185.78.44",
+ "130.185.78.51",
+ "130.185.78.64",
+ "130.185.78.67",
+ "130.185.78.72",
+ "130.185.78.74",
+ "130.185.78.76",
+ "130.185.78.81",
+ "130.185.78.84",
+ "130.185.78.85",
+ "130.185.78.87",
+ "130.185.78.95",
+ "130.185.78.100",
+ "130.185.78.101",
+ "130.185.78.113",
+ "130.185.78.117",
+ "130.185.78.124",
+ "130.185.78.127",
+ "130.185.78.140",
+ "130.185.78.148",
+ "130.185.78.151",
+ "130.185.78.152",
+ "130.185.78.155",
+ "130.185.78.167",
+ "130.185.78.170",
+ "130.185.78.171",
+ "130.185.78.177",
+ "130.185.78.179",
+ "130.185.78.182",
+ "130.185.78.184",
+ "130.185.78.185",
+ "130.185.78.186",
+ "130.185.78.189",
+ "130.185.78.201",
+ "130.185.78.212",
+ "130.185.78.217",
+ "130.185.78.218",
+ "130.185.78.220",
+ "130.185.78.223",
+ "130.185.78.225",
+ "130.185.78.228",
+ "130.185.78.229",
+ "130.185.78.230",
+ "130.185.78.233",
+ "130.185.78.234",
+ "130.185.78.247",
+ "130.185.78.248",
+ "130.185.78.249",
+ "130.185.79.138",
+ "130.185.79.170",
+ "130.185.79.180",
+ "130.185.79.181",
+ "130.185.79.184",
+ "130.185.79.187",
+ "130.185.79.197",
+ "130.193.77.5",
+ "130.193.77.35",
+ "130.193.77.61",
+ "130.193.77.62",
+ "130.193.77.82",
+ "130.193.77.91",
+ "130.193.77.98",
+ "130.193.77.99",
+ "130.193.77.100",
+ "130.193.77.101",
+ "130.193.77.102",
+ "130.193.77.103",
+ "130.193.77.104",
+ "130.193.77.105",
+ "130.193.77.106",
+ "130.193.77.107",
+ "130.193.77.108",
+ "130.193.77.109",
+ "130.193.77.110",
+ "130.193.77.111",
+ "130.193.77.112",
+ "130.193.77.113",
+ "130.193.77.114",
+ "130.193.77.115",
+ "130.193.77.116",
+ "130.193.77.117",
+ "130.193.77.118",
+ "130.193.77.119",
+ "130.193.77.120",
+ "130.193.77.121",
+ "130.193.77.122",
+ "130.193.77.123",
+ "130.193.77.126",
+ "130.193.77.198",
+ "130.193.77.199",
+ "130.193.77.201",
+ "130.193.77.202",
+ "130.193.77.204",
+ "130.193.77.205",
+ "130.193.77.207",
+ "130.193.77.211",
+ "130.193.77.212",
+ "130.193.77.214",
+ "130.193.77.215",
+ "130.193.77.216",
+ "130.193.77.217",
+ "130.193.77.222",
+ "130.193.77.236",
+ "130.193.77.247",
+ "130.193.77.248",
+ "130.193.77.249",
+ "134.255.200.50",
+ "134.255.200.52",
+ "134.255.200.54",
+ "134.255.200.130",
+ "134.255.200.133",
+ "134.255.200.147",
+ "134.255.200.151",
+ "134.255.200.154",
+ "134.255.200.218",
+ "134.255.200.250",
+ "134.255.201.29",
+ "134.255.201.91",
+ "134.255.201.92",
+ "134.255.201.94",
+ "134.255.201.162",
+ "134.255.202.7",
+ "134.255.202.82",
+ "134.255.202.164",
+ "134.255.202.188",
+ "134.255.203.50",
+ "134.255.203.67",
+ "134.255.203.68",
+ "134.255.203.142",
+ "134.255.203.171",
+ "134.255.203.172",
+ "134.255.203.174",
+ "134.255.204.3",
+ "146.19.212.5",
+ "146.19.212.10",
+ "146.19.212.12",
+ "146.19.212.14",
+ "146.19.212.22",
+ "146.19.212.34",
+ "146.19.212.51",
+ "146.19.212.69",
+ "146.19.212.70",
+ "146.19.212.71",
+ "146.19.212.74",
+ "146.19.212.79",
+ "146.19.212.80",
+ "146.19.212.87",
+ "146.19.212.88",
+ "146.19.212.94",
+ "146.19.212.99",
+ "146.19.212.103",
+ "146.19.212.104",
+ "146.19.212.107",
+ "146.19.212.108",
+ "146.19.212.120",
+ "146.19.212.121",
+ "146.19.212.122",
+ "146.19.212.136",
+ "146.19.212.144",
+ "146.19.212.145",
+ "146.19.212.154",
+ "146.19.212.156",
+ "146.19.212.161",
+ "146.19.212.163",
+ "146.19.212.172",
+ "146.19.212.173",
+ "146.19.212.178",
+ "146.19.212.183",
+ "146.19.212.185",
+ "146.19.212.186",
+ "146.19.212.187",
+ "146.19.212.192",
+ "146.19.212.206",
+ "146.19.212.212",
+ "146.19.212.215",
+ "146.19.212.217",
+ "146.19.212.220",
+ "146.19.212.224",
+ "146.19.212.225",
+ "146.19.212.227",
+ "146.19.212.245",
+ "146.19.212.249",
+ "146.66.134.55",
+ "146.66.135.55",
+ "151.232.0.133",
+ "151.232.8.90",
+ "151.232.10.25",
+ "151.232.20.66",
+ "151.232.36.4",
+ "151.232.36.5",
+ "151.232.36.131",
+ "151.232.36.132",
+ "151.232.39.202",
+ "151.232.103.94",
+ "151.232.103.130",
+ "151.232.133.244",
+ "151.233.50.143",
+ "151.233.50.216",
+ "151.233.52.156",
+ "151.233.53.44",
+ "151.233.54.25",
+ "151.233.54.200",
+ "151.233.55.181",
+ "151.233.56.110",
+ "151.233.59.182",
+ "151.233.74.80",
+ "151.234.29.148",
+ "151.234.121.165",
+ "151.234.123.36",
+ "151.234.127.139",
+ "151.234.161.32",
+ "151.234.161.33",
+ "151.234.161.34",
+ "151.235.91.187",
+ "151.235.98.108",
+ "151.235.99.85",
+ "151.235.102.146",
+ "151.235.113.194",
+ "151.235.113.225",
+ "151.235.117.185",
+ "151.235.122.252",
+ "151.235.127.103",
+ "151.235.136.138",
+ "151.235.181.165",
+ "151.235.218.81",
+ "151.235.237.253",
+ "157.119.188.90",
+ "157.119.188.122",
+ "157.119.188.140",
+ "157.119.190.146",
+ "157.119.190.148",
+ "157.119.190.150",
+ "157.119.190.151",
+ "157.119.190.153",
+ "157.119.190.154",
+ "157.119.190.155",
+ "157.119.190.156",
+ "157.119.190.157",
+ "157.119.190.229",
+ "157.119.191.50",
+ "157.119.191.132",
+ "157.119.191.134",
+ "157.119.191.181",
+ "158.58.184.68",
+ "158.58.184.73",
+ "158.58.184.74",
+ "158.58.184.75",
+ "158.58.184.76",
+ "158.58.184.118",
+ "158.58.184.138",
+ "158.58.184.147",
+ "158.58.184.148",
+ "158.58.184.166",
+ "158.58.184.170",
+ "158.58.184.180",
+ "158.58.184.243",
+ "158.58.184.250",
+ "158.58.184.251",
+ "158.58.184.252",
+ "158.58.184.253",
+ "158.58.184.254",
+ "158.58.185.5",
+ "158.58.185.6",
+ "158.58.185.7",
+ "158.58.185.8",
+ "158.58.185.12",
+ "158.58.185.13",
+ "158.58.185.38",
+ "158.58.185.39",
+ "158.58.185.56",
+ "158.58.185.58",
+ "158.58.185.59",
+ "158.58.185.60",
+ "158.58.185.61",
+ "158.58.185.62",
+ "158.58.185.72",
+ "158.58.185.78",
+ "158.58.185.79",
+ "158.58.185.83",
+ "158.58.185.85",
+ "158.58.185.88",
+ "158.58.185.89",
+ "158.58.185.94",
+ "158.58.185.95",
+ "158.58.185.100",
+ "158.58.185.103",
+ "158.58.185.108",
+ "158.58.185.111",
+ "158.58.185.114",
+ "158.58.185.115",
+ "158.58.185.117",
+ "158.58.185.120",
+ "158.58.185.121",
+ "158.58.185.122",
+ "158.58.185.164",
+ "158.58.185.174",
+ "158.58.185.209",
+ "158.58.185.210",
+ "158.58.185.244",
+ "158.58.185.246",
+ "158.58.185.248",
+ "158.58.185.250",
+ "158.58.185.252",
+ "158.58.186.34",
+ "158.58.187.4",
+ "158.58.187.6",
+ "158.58.187.12",
+ "158.58.187.13",
+ "158.58.187.14",
+ "158.58.187.20",
+ "158.58.187.22",
+ "158.58.187.38",
+ "158.58.187.44",
+ "158.58.187.50",
+ "158.58.187.68",
+ "158.58.187.70",
+ "158.58.187.75",
+ "158.58.187.76",
+ "158.58.187.78",
+ "158.58.187.91",
+ "158.58.187.108",
+ "158.58.187.109",
+ "158.58.187.116",
+ "158.58.187.118",
+ "158.58.187.124",
+ "158.58.187.131",
+ "158.58.187.132",
+ "158.58.187.134",
+ "158.58.187.139",
+ "158.58.187.141",
+ "158.58.187.142",
+ "158.58.187.148",
+ "158.58.187.149",
+ "158.58.187.155",
+ "158.58.187.157",
+ "158.58.187.163",
+ "158.58.187.164",
+ "158.58.187.165",
+ "158.58.187.166",
+ "158.58.187.171",
+ "158.58.187.172",
+ "158.58.187.173",
+ "158.58.187.179",
+ "158.58.187.180",
+ "158.58.187.187",
+ "158.58.187.194",
+ "158.58.187.203",
+ "158.58.187.204",
+ "158.58.187.205",
+ "158.58.187.211",
+ "158.58.187.214",
+ "158.58.187.220",
+ "158.58.187.221",
+ "158.58.187.226",
+ "158.58.187.234",
+ "158.58.187.243",
+ "158.58.187.244",
+ "158.58.187.246",
+ "158.58.188.147",
+ "158.58.188.148",
+ "158.58.188.152",
+ "158.58.188.155",
+ "158.58.190.43",
+ "158.58.191.20",
+ "158.58.191.21",
+ "158.58.191.36",
+ "158.58.191.37",
+ "158.58.191.39",
+ "158.58.191.40",
+ "158.58.191.41",
+ "158.58.191.42",
+ "158.58.191.43",
+ "158.58.191.44",
+ "158.58.191.45",
+ "158.58.191.107",
+ "158.58.191.108",
+ "158.58.191.109",
+ "158.58.191.130",
+ "158.58.191.186",
+ "158.58.191.190",
+ "158.255.74.8",
+ "158.255.74.27",
+ "158.255.74.33",
+ "158.255.74.38",
+ "158.255.74.49",
+ "158.255.74.52",
+ "158.255.74.54",
+ "158.255.74.60",
+ "158.255.74.69",
+ "158.255.74.71",
+ "158.255.74.75",
+ "158.255.74.79",
+ "158.255.74.89",
+ "158.255.74.100",
+ "158.255.74.117",
+ "158.255.74.124",
+ "158.255.74.130",
+ "158.255.74.133",
+ "158.255.74.144",
+ "158.255.74.150",
+ "158.255.74.159",
+ "158.255.74.164",
+ "158.255.74.166",
+ "158.255.74.167",
+ "158.255.74.172",
+ "158.255.74.174",
+ "158.255.74.177",
+ "158.255.74.184",
+ "158.255.74.185",
+ "158.255.74.190",
+ "158.255.74.194",
+ "158.255.74.196",
+ "158.255.74.198",
+ "158.255.74.200",
+ "158.255.74.208",
+ "158.255.74.212",
+ "158.255.74.216",
+ "158.255.74.218",
+ "158.255.74.221",
+ "158.255.74.223",
+ "158.255.74.229",
+ "158.255.74.246",
+ "158.255.74.251",
+ "158.255.78.168",
+ "159.20.96.122",
+ "159.20.102.136",
+ "159.20.102.137",
+ "159.20.102.138",
+ "159.20.102.139",
+ "159.20.102.140",
+ "159.20.102.141",
+ "159.20.102.142",
+ "159.20.102.143",
+ "164.138.16.1",
+ "164.138.16.2",
+ "164.138.16.4",
+ "164.138.16.6",
+ "164.138.16.7",
+ "164.138.16.9",
+ "164.138.16.40",
+ "164.138.16.41",
+ "164.138.16.42",
+ "164.138.16.43",
+ "164.138.16.44",
+ "164.138.16.45",
+ "164.138.16.47",
+ "164.138.16.48",
+ "164.138.16.49",
+ "164.138.16.50",
+ "164.138.16.51",
+ "164.138.16.52",
+ "164.138.16.53",
+ "164.138.16.54",
+ "164.138.16.55",
+ "164.138.16.56",
+ "164.138.16.57",
+ "164.138.16.58",
+ "164.138.16.59",
+ "164.138.16.89",
+ "164.138.16.100",
+ "164.138.16.110",
+ "164.138.16.111",
+ "164.138.16.112",
+ "164.138.16.130",
+ "164.138.16.131",
+ "164.138.16.132",
+ "164.138.16.133",
+ "164.138.16.134",
+ "164.138.16.135",
+ "164.138.16.136",
+ "164.138.16.137",
+ "164.138.16.138",
+ "164.138.16.139",
+ "164.138.16.140",
+ "164.138.16.141",
+ "164.138.16.142",
+ "164.138.16.143",
+ "164.138.16.144",
+ "164.138.16.145",
+ "164.138.16.150",
+ "164.138.16.151",
+ "164.138.16.164",
+ "164.138.16.180",
+ "164.138.16.183",
+ "164.138.16.187",
+ "164.138.17.1",
+ "164.138.17.9",
+ "164.138.17.10",
+ "164.138.17.11",
+ "164.138.17.12",
+ "164.138.17.13",
+ "164.138.17.66",
+ "164.138.17.99",
+ "164.138.17.100",
+ "164.138.17.114",
+ "164.138.17.122",
+ "164.138.17.137",
+ "164.138.17.161",
+ "164.138.17.162",
+ "164.138.17.163",
+ "164.138.17.164",
+ "164.138.17.165",
+ "164.138.17.170",
+ "164.138.17.201",
+ "164.138.17.233",
+ "164.138.17.235",
+ "164.138.17.236",
+ "164.138.17.250",
+ "164.138.17.251",
+ "164.138.17.252",
+ "164.138.17.253",
+ "164.138.18.65",
+ "164.138.18.66",
+ "164.138.18.67",
+ "164.138.18.68",
+ "164.138.18.69",
+ "164.138.18.71",
+ "164.138.18.72",
+ "164.138.18.74",
+ "164.138.18.75",
+ "164.138.18.76",
+ "164.138.18.105",
+ "164.138.18.106",
+ "164.138.18.153",
+ "164.138.18.154",
+ "164.138.18.155",
+ "164.138.18.156",
+ "164.138.18.157",
+ "164.138.18.169",
+ "164.138.18.170",
+ "164.138.18.171",
+ "164.138.18.172",
+ "164.138.18.173",
+ "164.138.19.1",
+ "164.138.19.2",
+ "164.138.19.4",
+ "164.138.19.5",
+ "164.138.19.6",
+ "164.138.19.7",
+ "164.138.19.8",
+ "164.138.19.11",
+ "164.138.19.13",
+ "164.138.19.17",
+ "164.138.19.18",
+ "164.138.19.19",
+ "164.138.19.34",
+ "164.138.19.35",
+ "164.138.19.49",
+ "164.138.19.50",
+ "164.138.19.97",
+ "164.138.19.98",
+ "164.138.19.99",
+ "164.138.19.100",
+ "164.138.19.101",
+ "164.138.19.139",
+ "164.138.19.185",
+ "164.138.19.193",
+ "164.138.19.194",
+ "164.138.19.195",
+ "164.138.19.196",
+ "164.138.19.197",
+ "164.138.19.198",
+ "164.138.19.199",
+ "164.138.19.200",
+ "164.138.19.201",
+ "164.138.19.202",
+ "164.138.19.204",
+ "164.138.19.225",
+ "164.138.19.226",
+ "164.138.19.227",
+ "164.138.19.234",
+ "164.138.19.250",
+ "164.138.19.251",
+ "164.138.19.252",
+ "164.138.19.253",
+ "164.138.20.81",
+ "164.138.20.82",
+ "164.138.20.83",
+ "164.138.20.84",
+ "164.138.20.85",
+ "164.138.20.89",
+ "164.138.20.90",
+ "164.138.20.91",
+ "164.138.20.92",
+ "164.138.20.93",
+ "164.138.20.98",
+ "164.138.20.99",
+ "164.138.20.100",
+ "164.138.20.101",
+ "164.138.20.121",
+ "164.138.20.122",
+ "164.138.20.123",
+ "164.138.20.124",
+ "164.138.20.125",
+ "164.138.20.129",
+ "164.138.20.130",
+ "164.138.20.131",
+ "164.138.20.132",
+ "164.138.20.155",
+ "164.138.20.156",
+ "164.138.20.217",
+ "164.138.20.218",
+ "164.138.20.221",
+ "164.138.21.1",
+ "164.138.21.2",
+ "164.138.21.4",
+ "164.138.21.17",
+ "164.138.21.18",
+ "164.138.21.49",
+ "164.138.21.57",
+ "164.138.21.58",
+ "164.138.21.59",
+ "164.138.21.60",
+ "164.138.21.73",
+ "164.138.21.81",
+ "164.138.21.82",
+ "164.138.21.83",
+ "164.138.21.84",
+ "164.138.21.85",
+ "164.138.21.105",
+ "164.138.21.106",
+ "164.138.21.107",
+ "164.138.21.108",
+ "164.138.21.109",
+ "164.138.21.121",
+ "164.138.21.122",
+ "164.138.21.123",
+ "164.138.21.124",
+ "164.138.21.169",
+ "164.138.21.170",
+ "164.138.21.171",
+ "164.138.21.172",
+ "164.138.21.173",
+ "164.138.21.201",
+ "164.138.21.202",
+ "164.138.21.204",
+ "164.138.21.209",
+ "164.138.21.210",
+ "164.138.21.211",
+ "164.138.22.9",
+ "164.138.22.10",
+ "164.138.22.11",
+ "164.138.22.13",
+ "164.138.22.65",
+ "164.138.22.66",
+ "164.138.22.114",
+ "164.138.22.117",
+ "164.138.22.118",
+ "164.138.22.119",
+ "164.138.22.120",
+ "164.138.22.121",
+ "164.138.22.122",
+ "164.138.22.123",
+ "164.138.22.124",
+ "164.138.22.129",
+ "164.138.22.130",
+ "164.138.22.131",
+ "164.138.22.132",
+ "164.138.22.133",
+ "164.138.22.134",
+ "164.138.22.137",
+ "164.138.22.138",
+ "164.138.22.139",
+ "164.138.22.140",
+ "164.138.22.141",
+ "164.138.22.169",
+ "164.138.22.177",
+ "164.138.22.179",
+ "164.138.22.180",
+ "164.138.22.181",
+ "164.138.22.186",
+ "164.138.22.187",
+ "164.138.23.50",
+ "164.138.23.51",
+ "164.138.23.52",
+ "164.138.23.173",
+ "164.138.23.233",
+ "164.138.23.237",
+ "164.138.206.100",
+ "164.215.57.55",
+ "164.215.57.56",
+ "164.215.59.37",
+ "164.215.59.117",
+ "171.22.24.5",
+ "171.22.24.13",
+ "171.22.24.15",
+ "171.22.24.16",
+ "171.22.24.24",
+ "171.22.24.34",
+ "171.22.24.38",
+ "171.22.24.42",
+ "171.22.24.50",
+ "171.22.24.54",
+ "171.22.24.80",
+ "171.22.24.88",
+ "171.22.24.91",
+ "171.22.24.103",
+ "171.22.24.105",
+ "171.22.24.112",
+ "171.22.24.115",
+ "171.22.24.130",
+ "171.22.24.134",
+ "171.22.24.137",
+ "171.22.24.146",
+ "171.22.24.150",
+ "171.22.24.155",
+ "171.22.24.157",
+ "171.22.24.159",
+ "171.22.24.161",
+ "171.22.24.164",
+ "171.22.24.165",
+ "171.22.24.169",
+ "171.22.24.176",
+ "171.22.24.182",
+ "171.22.24.187",
+ "171.22.24.188",
+ "171.22.24.211",
+ "171.22.24.221",
+ "171.22.24.231",
+ "171.22.24.236",
+ "171.22.24.246",
+ "171.22.25.10",
+ "171.22.25.18",
+ "171.22.25.19",
+ "171.22.25.20",
+ "171.22.25.24",
+ "171.22.25.25",
+ "171.22.25.26",
+ "171.22.25.31",
+ "171.22.25.32",
+ "171.22.25.41",
+ "171.22.25.44",
+ "171.22.25.49",
+ "171.22.25.50",
+ "171.22.25.54",
+ "171.22.25.63",
+ "171.22.25.64",
+ "171.22.25.65",
+ "171.22.25.69",
+ "171.22.25.71",
+ "171.22.25.73",
+ "171.22.25.75",
+ "171.22.25.79",
+ "171.22.25.80",
+ "171.22.25.83",
+ "171.22.25.84",
+ "171.22.25.86",
+ "171.22.25.90",
+ "171.22.25.91",
+ "171.22.25.96",
+ "171.22.25.99",
+ "171.22.25.100",
+ "171.22.25.102",
+ "171.22.25.104",
+ "171.22.25.105",
+ "171.22.25.107",
+ "171.22.25.110",
+ "171.22.25.113",
+ "171.22.25.128",
+ "171.22.25.133",
+ "171.22.25.140",
+ "171.22.25.148",
+ "171.22.25.149",
+ "171.22.25.150",
+ "171.22.25.155",
+ "171.22.25.156",
+ "171.22.25.161",
+ "171.22.25.174",
+ "171.22.25.185",
+ "171.22.25.190",
+ "171.22.25.191",
+ "171.22.25.198",
+ "171.22.25.222",
+ "171.22.25.234",
+ "171.22.25.253",
+ "171.22.26.13",
+ "171.22.26.31",
+ "171.22.26.35",
+ "171.22.26.41",
+ "171.22.26.44",
+ "171.22.26.46",
+ "171.22.26.50",
+ "171.22.26.69",
+ "171.22.26.73",
+ "171.22.26.75",
+ "171.22.26.76",
+ "171.22.26.82",
+ "171.22.26.88",
+ "171.22.26.90",
+ "171.22.26.92",
+ "171.22.26.95",
+ "171.22.26.99",
+ "171.22.26.104",
+ "171.22.26.106",
+ "171.22.26.108",
+ "171.22.26.116",
+ "171.22.26.120",
+ "171.22.26.121",
+ "171.22.26.127",
+ "171.22.26.129",
+ "171.22.26.131",
+ "171.22.26.135",
+ "171.22.26.140",
+ "171.22.26.143",
+ "171.22.26.145",
+ "171.22.26.146",
+ "171.22.26.151",
+ "171.22.26.157",
+ "171.22.26.165",
+ "171.22.26.172",
+ "171.22.26.176",
+ "171.22.26.180",
+ "171.22.26.193",
+ "171.22.26.194",
+ "171.22.26.196",
+ "171.22.26.199",
+ "171.22.26.202",
+ "171.22.26.204",
+ "171.22.26.205",
+ "171.22.26.206",
+ "171.22.26.207",
+ "171.22.26.210",
+ "171.22.26.212",
+ "171.22.26.225",
+ "171.22.26.233",
+ "171.22.26.234",
+ "171.22.26.238",
+ "171.22.26.250",
+ "171.22.27.13",
+ "171.22.27.16",
+ "171.22.27.29",
+ "171.22.27.45",
+ "171.22.27.49",
+ "171.22.27.57",
+ "171.22.27.75",
+ "171.22.27.76",
+ "171.22.27.83",
+ "171.22.27.93",
+ "171.22.27.98",
+ "171.22.27.106",
+ "171.22.27.108",
+ "171.22.27.109",
+ "171.22.27.110",
+ "171.22.27.115",
+ "171.22.27.119",
+ "171.22.27.122",
+ "171.22.27.123",
+ "171.22.27.125",
+ "171.22.27.130",
+ "171.22.27.132",
+ "171.22.27.133",
+ "171.22.27.137",
+ "171.22.27.143",
+ "171.22.27.145",
+ "171.22.27.146",
+ "171.22.27.151",
+ "171.22.27.152",
+ "171.22.27.155",
+ "171.22.27.158",
+ "171.22.27.159",
+ "171.22.27.160",
+ "171.22.27.162",
+ "171.22.27.164",
+ "171.22.27.170",
+ "171.22.27.172",
+ "171.22.27.173",
+ "171.22.27.175",
+ "171.22.27.184",
+ "171.22.27.189",
+ "171.22.27.194",
+ "171.22.27.197",
+ "171.22.27.200",
+ "171.22.27.201",
+ "171.22.27.207",
+ "171.22.27.225",
+ "171.22.27.240",
+ "171.22.27.244",
+ "171.22.27.247",
+ "171.22.27.251",
+ "176.10.95.10",
+ "176.56.156.4",
+ "176.56.157.4",
+ "176.62.144.36",
+ "176.62.144.43",
+ "176.62.144.45",
+ "176.62.144.46",
+ "176.65.191.39",
+ "176.65.224.205",
+ "176.65.225.161",
+ "176.65.240.45",
+ "176.65.240.46",
+ "176.65.240.50",
+ "176.65.240.51",
+ "176.65.240.87",
+ "176.65.240.89",
+ "176.65.240.162",
+ "176.65.240.163",
+ "176.65.241.162",
+ "176.65.241.164",
+ "176.65.241.165",
+ "176.65.242.131",
+ "176.65.242.204",
+ "176.65.242.205",
+ "176.65.243.44",
+ "176.65.243.51",
+ "176.65.243.52",
+ "176.65.243.53",
+ "176.65.243.57",
+ "176.65.243.61",
+ "176.65.243.196",
+ "176.65.243.230",
+ "176.65.252.158",
+ "176.97.218.7",
+ "176.97.218.9",
+ "176.97.218.30",
+ "176.97.218.31",
+ "176.97.218.35",
+ "176.97.218.36",
+ "176.97.218.37",
+ "176.97.218.42",
+ "176.97.218.46",
+ "176.97.218.49",
+ "176.97.218.50",
+ "176.97.218.65",
+ "176.97.218.66",
+ "176.97.218.70",
+ "176.97.218.73",
+ "176.97.218.74",
+ "176.97.218.75",
+ "176.97.218.86",
+ "176.97.218.98",
+ "176.97.218.99",
+ "176.97.218.105",
+ "176.97.218.142",
+ "176.97.218.144",
+ "176.97.218.150",
+ "176.97.218.152",
+ "176.97.218.156",
+ "176.97.218.159",
+ "176.97.218.161",
+ "176.97.218.166",
+ "176.97.218.189",
+ "176.97.218.215",
+ "176.97.218.217",
+ "176.97.218.226",
+ "176.97.218.237",
+ "176.97.218.246",
+ "176.97.218.248",
+ "176.97.218.252",
+ "176.97.220.34",
+ "176.97.220.69",
+ "176.97.220.70",
+ "176.97.220.162",
+ "176.97.220.235",
+ "176.97.220.236",
+ "176.97.220.237",
+ "176.97.220.238",
+ "176.101.33.161",
+ "176.101.48.167",
+ "176.101.48.192",
+ "176.101.48.195",
+ "176.102.224.6",
+ "176.102.224.7",
+ "176.120.16.4",
+ "176.120.16.21",
+ "176.120.16.25",
+ "176.120.16.55",
+ "176.120.16.56",
+ "176.120.16.60",
+ "176.120.16.85",
+ "176.120.16.88",
+ "176.120.16.96",
+ "176.120.16.104",
+ "176.120.16.122",
+ "176.120.16.136",
+ "176.120.16.163",
+ "176.120.16.181",
+ "176.120.16.186",
+ "176.120.16.205",
+ "176.120.16.212",
+ "176.120.16.217",
+ "176.120.16.224",
+ "176.120.16.228",
+ "176.120.16.229",
+ "176.120.16.232",
+ "176.120.16.252",
+ "176.120.16.254",
+ "176.122.210.2",
+ "176.122.210.6",
+ "176.122.210.10",
+ "176.122.210.78",
+ "176.122.210.98",
+ "176.126.120.3",
+ "176.126.120.5",
+ "176.126.120.8",
+ "176.126.120.19",
+ "176.126.120.33",
+ "176.126.120.101",
+ "176.126.120.108",
+ "176.126.120.199",
+ "176.126.120.207",
+ "176.126.120.208",
+ "176.126.120.209",
+ "176.126.120.217",
+ "176.126.120.218",
+ "176.126.120.234",
+ "176.126.120.235",
+ "176.126.120.236",
+ "176.126.120.237",
+ "176.126.120.238",
+ "176.126.120.243",
+ "178.21.40.17",
+ "178.21.40.20",
+ "178.21.40.21",
+ "178.21.41.20",
+ "178.21.45.10",
+ "178.21.45.11",
+ "178.21.46.10",
+ "178.21.46.11",
+ "178.21.161.12",
+ "178.21.161.13",
+ "178.21.161.53",
+ "178.21.161.137",
+ "178.21.162.38",
+ "178.21.162.44",
+ "178.21.162.47",
+ "178.21.162.49",
+ "178.21.162.56",
+ "178.21.163.51",
+ "178.21.163.60",
+ "178.21.163.81",
+ "178.21.163.97",
+ "178.21.164.113",
+ "178.21.164.247",
+ "178.22.120.85",
+ "178.22.120.100",
+ "178.22.120.103",
+ "178.22.120.110",
+ "178.22.120.113",
+ "178.22.120.140",
+ "178.22.120.238",
+ "178.22.121.70",
+ "178.22.121.72",
+ "178.22.121.139",
+ "178.22.121.148",
+ "178.22.121.149",
+ "178.22.121.212",
+ "178.22.121.214",
+ "178.22.122.72",
+ "178.22.122.75",
+ "178.22.122.101",
+ "178.22.122.103",
+ "178.22.122.122",
+ "178.22.122.232",
+ "178.22.123.10",
+ "178.22.123.42",
+ "178.22.123.43",
+ "178.22.123.44",
+ "178.22.123.45",
+ "178.22.123.114",
+ "178.22.123.198",
+ "178.22.124.7",
+ "178.22.124.17",
+ "178.22.124.20",
+ "178.22.124.21",
+ "178.22.124.25",
+ "178.22.124.29",
+ "178.22.124.230",
+ "178.22.124.231",
+ "178.22.124.237",
+ "178.22.126.2",
+ "178.22.126.18",
+ "178.22.126.26",
+ "178.22.126.30",
+ "178.22.126.42",
+ "178.22.127.57",
+ "178.22.127.58",
+ "178.22.127.179",
+ "178.22.127.180",
+ "178.131.8.229",
+ "178.131.78.211",
+ "178.131.88.93",
+ "178.131.89.118",
+ "178.131.109.152",
+ "178.131.110.148",
+ "178.131.119.93",
+ "178.131.120.31",
+ "178.131.120.32",
+ "178.131.120.33",
+ "178.131.120.34",
+ "178.131.123.31",
+ "178.131.123.32",
+ "178.131.124.31",
+ "178.131.124.32",
+ "178.131.125.31",
+ "178.131.125.32",
+ "178.131.127.31",
+ "178.173.128.7",
+ "178.173.128.16",
+ "178.173.128.28",
+ "178.173.128.29",
+ "178.173.140.108",
+ "178.173.141.28",
+ "178.173.141.47",
+ "178.173.143.43",
+ "178.173.144.93",
+ "178.173.145.26",
+ "178.173.145.137",
+ "178.173.149.25",
+ "178.173.151.16",
+ "178.173.151.23",
+ "178.173.161.190",
+ "178.173.170.83",
+ "178.173.171.82",
+ "178.173.190.9",
+ "178.173.190.58",
+ "178.173.212.160",
+ "178.173.214.4",
+ "178.173.219.7",
+ "178.215.8.18",
+ "178.215.8.54",
+ "178.216.248.4",
+ "178.216.248.30",
+ "178.216.248.100",
+ "178.216.248.106",
+ "178.216.248.108",
+ "178.216.248.110",
+ "178.216.248.251",
+ "178.216.249.55",
+ "178.216.249.194",
+ "178.216.249.202",
+ "178.216.249.206",
+ "178.216.250.162",
+ "178.216.250.163",
+ "178.216.250.167",
+ "178.216.250.173",
+ "178.216.250.181",
+ "178.216.250.182",
+ "178.216.250.183",
+ "178.216.250.184",
+ "178.216.250.186",
+ "178.216.250.188",
+ "178.216.250.189",
+ "178.216.251.14",
+ "178.216.251.34",
+ "178.216.251.106",
+ "178.216.251.219",
+ "178.216.251.220",
+ "178.216.251.226",
+ "178.216.251.229",
+ "178.216.251.231",
+ "178.216.251.232",
+ "178.216.251.233",
+ "178.216.251.234",
+ "178.216.251.235",
+ "178.216.251.240",
+ "178.216.251.241",
+ "178.216.251.242",
+ "178.216.251.243",
+ "178.216.251.245",
+ "178.216.251.246",
+ "178.216.251.248",
+ "178.216.251.249",
+ "178.216.251.252",
+ "178.216.251.253",
+ "178.216.251.254",
+ "178.219.238.55",
+ "178.236.105.45",
+ "178.236.108.24",
+ "178.236.108.72",
+ "178.238.193.14",
+ "178.238.195.158",
+ "178.238.197.244",
+ "178.239.145.30",
+ "178.239.147.62",
+ "178.239.147.71",
+ "178.239.147.86",
+ "178.239.147.91",
+ "178.239.147.98",
+ "178.239.147.99",
+ "178.239.147.100",
+ "178.239.147.101",
+ "178.239.147.102",
+ "178.239.147.106",
+ "178.239.147.107",
+ "178.239.147.108",
+ "178.239.147.109",
+ "178.239.147.114",
+ "178.239.147.115",
+ "178.239.147.116",
+ "178.239.147.117",
+ "178.239.147.118",
+ "178.239.147.119",
+ "178.239.147.120",
+ "178.239.147.121",
+ "178.239.147.122",
+ "178.239.147.123",
+ "178.239.147.137",
+ "178.239.147.139",
+ "178.239.147.146",
+ "178.239.148.110",
+ "178.239.148.129",
+ "178.239.148.133",
+ "178.239.151.13",
+ "178.239.151.16",
+ "178.239.151.20",
+ "178.239.151.26",
+ "178.239.151.28",
+ "178.239.151.42",
+ "178.239.151.60",
+ "178.239.151.64",
+ "178.239.151.84",
+ "178.239.151.86",
+ "178.239.151.87",
+ "178.239.151.89",
+ "178.239.151.97",
+ "178.239.151.100",
+ "178.239.151.112",
+ "178.239.151.123",
+ "178.239.151.130",
+ "178.239.151.136",
+ "178.239.151.137",
+ "178.239.151.139",
+ "178.239.151.160",
+ "178.239.151.179",
+ "178.239.151.185",
+ "178.239.151.186",
+ "178.239.151.193",
+ "178.239.151.196",
+ "178.239.151.200",
+ "178.239.151.207",
+ "178.239.151.225",
+ "178.239.151.226",
+ "178.239.151.228",
+ "178.239.151.239",
+ "178.239.151.240",
+ "178.239.158.14",
+ "178.239.158.56",
+ "178.239.158.60",
+ "178.239.158.61",
+ "178.239.158.64",
+ "178.239.158.65",
+ "178.239.158.67",
+ "178.239.158.76",
+ "178.239.158.80",
+ "178.239.158.90",
+ "178.239.158.91",
+ "178.239.158.95",
+ "178.239.158.96",
+ "178.239.158.103",
+ "178.239.158.117",
+ "178.239.158.118",
+ "178.239.158.128",
+ "178.239.158.140",
+ "178.239.158.141",
+ "178.239.158.145",
+ "178.252.128.66",
+ "178.252.128.67",
+ "178.252.130.200",
+ "178.252.132.131",
+ "178.252.132.202",
+ "178.252.134.6",
+ "178.252.134.106",
+ "178.252.137.98",
+ "178.252.137.99",
+ "178.252.137.100",
+ "178.252.138.62",
+ "178.252.140.186",
+ "178.252.140.198",
+ "178.252.140.210",
+ "178.252.140.211",
+ "178.252.140.212",
+ "178.252.141.66",
+ "178.252.141.72",
+ "178.252.141.73",
+ "178.252.141.74",
+ "178.252.141.75",
+ "178.252.141.76",
+ "178.252.141.77",
+ "178.252.141.78",
+ "178.252.141.228",
+ "178.252.143.122",
+ "178.252.143.123",
+ "178.252.143.124",
+ "178.252.143.125",
+ "178.252.143.126",
+ "178.252.143.132",
+ "178.252.143.133",
+ "178.252.144.227",
+ "178.252.144.228",
+ "178.252.146.186",
+ "178.252.147.66",
+ "178.252.147.69",
+ "178.252.147.219",
+ "178.252.148.244",
+ "178.252.149.134",
+ "178.252.149.237",
+ "178.252.153.60",
+ "178.252.153.197",
+ "178.252.166.35",
+ "178.252.166.147",
+ "178.252.166.148",
+ "178.252.166.150",
+ "178.252.166.151",
+ "178.252.166.152",
+ "178.252.167.151",
+ "178.252.178.34",
+ "178.252.178.35",
+ "178.252.178.40",
+ "178.252.178.44",
+ "178.252.180.195",
+ "178.252.181.45",
+ "178.252.181.52",
+ "178.252.181.73",
+ "178.252.181.246",
+ "178.252.181.247",
+ "178.252.182.180",
+ "178.252.183.11",
+ "178.252.190.15",
+ "185.2.13.98",
+ "185.2.13.193",
+ "185.2.13.207",
+ "185.2.13.208",
+ "185.2.13.211",
+ "185.2.13.212",
+ "185.2.13.213",
+ "185.2.13.214",
+ "185.2.13.217",
+ "185.2.13.218",
+ "185.2.13.219",
+ "185.2.13.220",
+ "185.2.13.221",
+ "185.2.13.222",
+ "185.2.14.3",
+ "185.2.14.4",
+ "185.2.14.5",
+ "185.2.14.7",
+ "185.2.14.12",
+ "185.2.14.37",
+ "185.2.14.39",
+ "185.2.14.42",
+ "185.2.14.59",
+ "185.2.14.61",
+ "185.2.14.62",
+ "185.2.14.67",
+ "185.2.14.70",
+ "185.2.14.75",
+ "185.2.14.76",
+ "185.2.14.77",
+ "185.2.14.86",
+ "185.2.14.91",
+ "185.2.14.93",
+ "185.2.14.126",
+ "185.2.14.131",
+ "185.2.14.132",
+ "185.2.14.156",
+ "185.2.14.157",
+ "185.2.14.164",
+ "185.2.14.179",
+ "185.2.14.180",
+ "185.2.14.181",
+ "185.2.14.197",
+ "185.2.14.198",
+ "185.2.14.201",
+ "185.2.14.214",
+ "185.2.14.219",
+ "185.2.14.220",
+ "185.2.14.227",
+ "185.2.14.236",
+ "185.2.14.237",
+ "185.2.14.238",
+ "185.2.14.243",
+ "185.2.14.252",
+ "185.2.14.254",
+ "185.3.124.35",
+ "185.3.124.36",
+ "185.3.124.42",
+ "185.3.124.51",
+ "185.3.124.52",
+ "185.3.124.53",
+ "185.3.124.54",
+ "185.3.124.58",
+ "185.3.124.68",
+ "185.3.124.94",
+ "185.3.124.98",
+ "185.3.124.99",
+ "185.3.124.106",
+ "185.3.124.131",
+ "185.3.124.150",
+ "185.3.124.206",
+ "185.3.124.226",
+ "185.3.124.247",
+ "185.3.124.253",
+ "185.3.126.3",
+ "185.3.126.4",
+ "185.3.201.195",
+ "185.3.201.240",
+ "185.3.201.241",
+ "185.3.201.242",
+ "185.3.201.243",
+ "185.3.201.244",
+ "185.3.201.245",
+ "185.3.201.246",
+ "185.3.201.247",
+ "185.3.201.248",
+ "185.3.201.249",
+ "185.3.201.250",
+ "185.3.201.251",
+ "185.3.201.252",
+ "185.3.201.253",
+ "185.3.201.254",
+ "185.3.201.255",
+ "185.3.202.148",
+ "185.3.203.32",
+ "185.3.203.33",
+ "185.3.203.35",
+ "185.3.203.203",
+ "185.4.1.14",
+ "185.4.1.15",
+ "185.4.1.20",
+ "185.4.1.21",
+ "185.4.1.23",
+ "185.4.1.26",
+ "185.4.1.30",
+ "185.4.1.37",
+ "185.4.1.38",
+ "185.4.1.39",
+ "185.4.1.41",
+ "185.4.1.44",
+ "185.4.1.47",
+ "185.4.1.62",
+ "185.4.1.64",
+ "185.4.1.67",
+ "185.4.1.70",
+ "185.4.1.72",
+ "185.4.1.76",
+ "185.4.1.87",
+ "185.4.1.90",
+ "185.4.1.98",
+ "185.4.1.100",
+ "185.4.1.154",
+ "185.4.1.170",
+ "185.4.2.50",
+ "185.4.3.12",
+ "185.4.3.14",
+ "185.4.3.15",
+ "185.4.3.16",
+ "185.4.3.17",
+ "185.4.3.26",
+ "185.4.3.27",
+ "185.4.3.28",
+ "185.4.3.29",
+ "185.4.3.30",
+ "185.4.3.31",
+ "185.4.3.32",
+ "185.4.3.33",
+ "185.4.3.34",
+ "185.4.3.37",
+ "185.4.3.42",
+ "185.4.3.43",
+ "185.4.3.44",
+ "185.4.3.45",
+ "185.4.3.54",
+ "185.4.3.64",
+ "185.4.3.65",
+ "185.4.3.66",
+ "185.4.3.74",
+ "185.4.3.75",
+ "185.4.3.78",
+ "185.4.28.184",
+ "185.4.29.181",
+ "185.4.29.196",
+ "185.4.30.4",
+ "185.4.30.13",
+ "185.4.30.24",
+ "185.4.30.31",
+ "185.4.30.32",
+ "185.4.30.33",
+ "185.4.30.41",
+ "185.4.30.42",
+ "185.4.30.44",
+ "185.4.30.54",
+ "185.4.30.62",
+ "185.4.30.64",
+ "185.4.30.66",
+ "185.4.30.69",
+ "185.4.30.73",
+ "185.4.30.74",
+ "185.4.30.82",
+ "185.4.30.87",
+ "185.4.30.88",
+ "185.4.30.89",
+ "185.4.30.90",
+ "185.4.30.91",
+ "185.4.30.111",
+ "185.4.30.120",
+ "185.4.30.130",
+ "185.4.30.173",
+ "185.4.30.174",
+ "185.4.30.175",
+ "185.4.30.176",
+ "185.4.30.177",
+ "185.4.30.178",
+ "185.4.30.179",
+ "185.4.30.180",
+ "185.4.30.181",
+ "185.4.30.182",
+ "185.4.30.234",
+ "185.4.31.6",
+ "185.7.172.4",
+ "185.7.172.5",
+ "185.7.172.11",
+ "185.7.172.12",
+ "185.7.172.34",
+ "185.7.172.53",
+ "185.7.172.56",
+ "185.7.172.58",
+ "185.7.172.59",
+ "185.7.172.66",
+ "185.7.172.67",
+ "185.7.172.68",
+ "185.7.172.74",
+ "185.7.172.82",
+ "185.7.172.122",
+ "185.7.172.130",
+ "185.7.172.133",
+ "185.7.172.134",
+ "185.7.172.136",
+ "185.7.172.137",
+ "185.7.172.150",
+ "185.7.212.4",
+ "185.7.212.5",
+ "185.7.212.16",
+ "185.7.212.29",
+ "185.7.212.32",
+ "185.7.212.37",
+ "185.7.212.53",
+ "185.7.212.60",
+ "185.7.212.63",
+ "185.7.212.72",
+ "185.7.212.83",
+ "185.7.212.87",
+ "185.7.212.95",
+ "185.7.212.101",
+ "185.7.212.109",
+ "185.7.212.111",
+ "185.7.212.112",
+ "185.7.212.120",
+ "185.7.212.135",
+ "185.7.212.139",
+ "185.7.212.145",
+ "185.7.212.154",
+ "185.7.212.155",
+ "185.7.212.166",
+ "185.7.212.168",
+ "185.7.212.169",
+ "185.7.212.170",
+ "185.7.212.171",
+ "185.7.212.172",
+ "185.7.212.181",
+ "185.7.212.183",
+ "185.7.212.192",
+ "185.7.212.195",
+ "185.7.212.201",
+ "185.7.212.204",
+ "185.7.212.217",
+ "185.7.212.218",
+ "185.7.212.219",
+ "185.7.212.221",
+ "185.7.212.232",
+ "185.7.212.236",
+ "185.7.212.245",
+ "185.7.212.246",
+ "185.7.212.252",
+ "185.8.172.6",
+ "185.8.172.12",
+ "185.8.172.14",
+ "185.8.172.15",
+ "185.8.172.19",
+ "185.8.172.22",
+ "185.8.172.25",
+ "185.8.172.35",
+ "185.8.172.56",
+ "185.8.172.58",
+ "185.8.172.67",
+ "185.8.172.68",
+ "185.8.172.69",
+ "185.8.172.81",
+ "185.8.172.83",
+ "185.8.172.101",
+ "185.8.172.104",
+ "185.8.172.105",
+ "185.8.172.107",
+ "185.8.172.117",
+ "185.8.172.118",
+ "185.8.172.119",
+ "185.8.172.120",
+ "185.8.172.125",
+ "185.8.172.137",
+ "185.8.172.139",
+ "185.8.172.145",
+ "185.8.172.146",
+ "185.8.172.147",
+ "185.8.172.151",
+ "185.8.172.155",
+ "185.8.172.156",
+ "185.8.172.159",
+ "185.8.172.161",
+ "185.8.172.165",
+ "185.8.172.168",
+ "185.8.172.170",
+ "185.8.172.172",
+ "185.8.172.180",
+ "185.8.172.196",
+ "185.8.172.197",
+ "185.8.172.198",
+ "185.8.172.205",
+ "185.8.172.208",
+ "185.8.172.211",
+ "185.8.172.216",
+ "185.8.172.217",
+ "185.8.172.218",
+ "185.8.172.227",
+ "185.8.172.233",
+ "185.8.172.243",
+ "185.8.172.249",
+ "185.8.173.13",
+ "185.8.173.16",
+ "185.8.173.36",
+ "185.8.173.39",
+ "185.8.173.42",
+ "185.8.173.44",
+ "185.8.173.45",
+ "185.8.173.53",
+ "185.8.173.59",
+ "185.8.173.71",
+ "185.8.173.72",
+ "185.8.173.79",
+ "185.8.173.83",
+ "185.8.173.102",
+ "185.8.173.104",
+ "185.8.173.107",
+ "185.8.173.110",
+ "185.8.173.122",
+ "185.8.173.126",
+ "185.8.173.127",
+ "185.8.173.128",
+ "185.8.173.129",
+ "185.8.173.131",
+ "185.8.173.136",
+ "185.8.173.137",
+ "185.8.173.140",
+ "185.8.173.142",
+ "185.8.173.146",
+ "185.8.173.151",
+ "185.8.173.153",
+ "185.8.173.154",
+ "185.8.173.159",
+ "185.8.173.163",
+ "185.8.173.168",
+ "185.8.173.170",
+ "185.8.173.172",
+ "185.8.173.181",
+ "185.8.173.182",
+ "185.8.173.193",
+ "185.8.173.196",
+ "185.8.173.198",
+ "185.8.173.201",
+ "185.8.173.206",
+ "185.8.173.212",
+ "185.8.173.213",
+ "185.8.173.217",
+ "185.8.173.218",
+ "185.8.173.226",
+ "185.8.173.229",
+ "185.8.173.248",
+ "185.8.173.249",
+ "185.8.174.6",
+ "185.8.174.7",
+ "185.8.174.16",
+ "185.8.174.18",
+ "185.8.174.37",
+ "185.8.174.39",
+ "185.8.174.40",
+ "185.8.174.43",
+ "185.8.174.49",
+ "185.8.174.55",
+ "185.8.174.62",
+ "185.8.174.65",
+ "185.8.174.70",
+ "185.8.174.82",
+ "185.8.174.86",
+ "185.8.174.87",
+ "185.8.174.88",
+ "185.8.174.92",
+ "185.8.174.98",
+ "185.8.174.100",
+ "185.8.174.105",
+ "185.8.174.110",
+ "185.8.174.111",
+ "185.8.174.112",
+ "185.8.174.116",
+ "185.8.174.117",
+ "185.8.174.121",
+ "185.8.174.123",
+ "185.8.174.133",
+ "185.8.174.139",
+ "185.8.174.140",
+ "185.8.174.143",
+ "185.8.174.144",
+ "185.8.174.145",
+ "185.8.174.148",
+ "185.8.174.149",
+ "185.8.174.150",
+ "185.8.174.151",
+ "185.8.174.155",
+ "185.8.174.159",
+ "185.8.174.160",
+ "185.8.174.162",
+ "185.8.174.167",
+ "185.8.174.168",
+ "185.8.174.171",
+ "185.8.174.178",
+ "185.8.174.179",
+ "185.8.174.181",
+ "185.8.174.182",
+ "185.8.174.189",
+ "185.8.174.190",
+ "185.8.174.193",
+ "185.8.174.196",
+ "185.8.174.198",
+ "185.8.174.199",
+ "185.8.174.200",
+ "185.8.174.211",
+ "185.8.174.218",
+ "185.8.174.219",
+ "185.8.174.222",
+ "185.8.174.224",
+ "185.8.174.231",
+ "185.8.174.232",
+ "185.8.174.234",
+ "185.8.174.244",
+ "185.8.174.245",
+ "185.8.174.247",
+ "185.8.174.251",
+ "185.8.175.13",
+ "185.8.175.27",
+ "185.8.175.29",
+ "185.8.175.31",
+ "185.8.175.37",
+ "185.8.175.40",
+ "185.8.175.45",
+ "185.8.175.46",
+ "185.8.175.49",
+ "185.8.175.51",
+ "185.8.175.52",
+ "185.8.175.58",
+ "185.8.175.61",
+ "185.8.175.64",
+ "185.8.175.92",
+ "185.8.175.96",
+ "185.8.175.101",
+ "185.8.175.102",
+ "185.8.175.104",
+ "185.8.175.107",
+ "185.8.175.109",
+ "185.8.175.117",
+ "185.8.175.118",
+ "185.8.175.126",
+ "185.8.175.132",
+ "185.8.175.134",
+ "185.8.175.137",
+ "185.8.175.144",
+ "185.8.175.145",
+ "185.8.175.146",
+ "185.8.175.159",
+ "185.8.175.162",
+ "185.8.175.163",
+ "185.8.175.169",
+ "185.8.175.170",
+ "185.8.175.171",
+ "185.8.175.173",
+ "185.8.175.198",
+ "185.8.175.199",
+ "185.8.175.203",
+ "185.8.175.206",
+ "185.8.175.208",
+ "185.8.175.213",
+ "185.8.175.223",
+ "185.8.175.224",
+ "185.8.175.228",
+ "185.8.175.230",
+ "185.8.175.234",
+ "185.8.175.238",
+ "185.10.71.138",
+ "185.10.72.35",
+ "185.10.72.41",
+ "185.10.72.49",
+ "185.10.72.64",
+ "185.10.72.65",
+ "185.10.72.66",
+ "185.10.72.67",
+ "185.10.72.70",
+ "185.10.72.76",
+ "185.10.72.83",
+ "185.10.72.90",
+ "185.10.72.121",
+ "185.10.72.123",
+ "185.10.72.136",
+ "185.10.72.141",
+ "185.10.72.150",
+ "185.10.72.156",
+ "185.10.72.165",
+ "185.10.72.168",
+ "185.10.72.182",
+ "185.10.72.184",
+ "185.10.72.216",
+ "185.10.73.10",
+ "185.10.73.11",
+ "185.10.73.12",
+ "185.10.73.15",
+ "185.10.73.17",
+ "185.10.73.19",
+ "185.10.73.53",
+ "185.10.73.72",
+ "185.10.73.83",
+ "185.10.73.84",
+ "185.10.73.88",
+ "185.10.73.96",
+ "185.10.73.114",
+ "185.10.73.116",
+ "185.10.73.145",
+ "185.10.73.152",
+ "185.10.73.190",
+ "185.10.73.192",
+ "185.10.73.200",
+ "185.10.73.227",
+ "185.10.73.230",
+ "185.10.74.2",
+ "185.10.74.33",
+ "185.10.74.37",
+ "185.10.74.44",
+ "185.10.74.47",
+ "185.10.74.55",
+ "185.10.74.56",
+ "185.10.74.64",
+ "185.10.74.72",
+ "185.10.74.91",
+ "185.10.74.105",
+ "185.10.74.110",
+ "185.10.74.123",
+ "185.10.74.137",
+ "185.10.74.149",
+ "185.10.74.154",
+ "185.10.74.156",
+ "185.10.74.159",
+ "185.10.74.184",
+ "185.10.74.207",
+ "185.10.74.240",
+ "185.10.74.244",
+ "185.10.74.245",
+ "185.10.74.251",
+ "185.10.74.253",
+ "185.10.75.10",
+ "185.10.75.51",
+ "185.10.75.67",
+ "185.10.75.69",
+ "185.10.75.71",
+ "185.10.75.73",
+ "185.10.75.79",
+ "185.10.75.85",
+ "185.10.75.88",
+ "185.10.75.89",
+ "185.10.75.93",
+ "185.10.75.94",
+ "185.10.75.100",
+ "185.10.75.102",
+ "185.10.75.103",
+ "185.10.75.104",
+ "185.10.75.106",
+ "185.10.75.109",
+ "185.10.75.110",
+ "185.10.75.112",
+ "185.10.75.114",
+ "185.10.75.116",
+ "185.10.75.117",
+ "185.10.75.122",
+ "185.10.75.125",
+ "185.10.75.126",
+ "185.10.75.132",
+ "185.10.75.136",
+ "185.10.75.139",
+ "185.10.75.142",
+ "185.10.75.147",
+ "185.10.75.154",
+ "185.10.75.155",
+ "185.10.75.160",
+ "185.10.75.163",
+ "185.10.75.165",
+ "185.10.75.172",
+ "185.10.75.174",
+ "185.10.75.178",
+ "185.10.75.179",
+ "185.10.75.180",
+ "185.10.75.181",
+ "185.10.75.182",
+ "185.10.75.183",
+ "185.10.75.185",
+ "185.10.75.186",
+ "185.10.75.188",
+ "185.10.75.189",
+ "185.10.75.195",
+ "185.10.75.216",
+ "185.11.68.7",
+ "185.11.68.8",
+ "185.11.68.14",
+ "185.11.68.29",
+ "185.11.68.30",
+ "185.11.69.99",
+ "185.11.89.100",
+ "185.12.101.11",
+ "185.12.101.18",
+ "185.13.228.45",
+ "185.13.228.50",
+ "185.13.228.59",
+ "185.13.228.130",
+ "185.13.228.135",
+ "185.13.228.136",
+ "185.13.228.137",
+ "185.13.228.139",
+ "185.13.228.150",
+ "185.13.228.153",
+ "185.13.228.154",
+ "185.13.228.155",
+ "185.13.228.157",
+ "185.13.228.158",
+ "185.13.228.162",
+ "185.13.228.218",
+ "185.13.228.244",
+ "185.13.229.3",
+ "185.13.229.4",
+ "185.13.229.53",
+ "185.13.229.228",
+ "185.13.230.75",
+ "185.13.230.115",
+ "185.13.230.117",
+ "185.13.230.118",
+ "185.13.230.156",
+ "185.13.231.11",
+ "185.14.162.68",
+ "185.14.162.80",
+ "185.14.163.6",
+ "185.14.163.7",
+ "185.14.163.75",
+ "185.18.212.19",
+ "185.18.212.65",
+ "185.18.212.71",
+ "185.18.212.83",
+ "185.18.212.85",
+ "185.18.212.96",
+ "185.18.212.100",
+ "185.18.212.102",
+ "185.18.212.113",
+ "185.18.212.132",
+ "185.18.212.136",
+ "185.18.212.137",
+ "185.18.212.176",
+ "185.18.212.177",
+ "185.18.212.185",
+ "185.18.212.188",
+ "185.18.212.200",
+ "185.18.212.216",
+ "185.18.213.17",
+ "185.18.213.18",
+ "185.18.213.20",
+ "185.18.213.22",
+ "185.18.213.43",
+ "185.18.213.52",
+ "185.18.213.56",
+ "185.18.213.59",
+ "185.18.213.78",
+ "185.18.213.82",
+ "185.18.213.86",
+ "185.18.213.164",
+ "185.18.213.191",
+ "185.18.213.211",
+ "185.18.213.218",
+ "185.18.213.224",
+ "185.18.213.225",
+ "185.18.213.226",
+ "185.18.213.227",
+ "185.18.214.23",
+ "185.18.214.26",
+ "185.18.214.28",
+ "185.18.214.76",
+ "185.18.214.82",
+ "185.18.214.92",
+ "185.18.214.130",
+ "185.18.214.154",
+ "185.18.214.243",
+ "185.18.214.249",
+ "185.18.214.250",
+ "185.18.215.6",
+ "185.18.215.18",
+ "185.18.215.35",
+ "185.18.215.42",
+ "185.18.215.43",
+ "185.18.215.109",
+ "185.18.215.110",
+ "185.18.215.120",
+ "185.18.215.134",
+ "185.18.215.136",
+ "185.18.215.138",
+ "185.18.215.209",
+ "185.18.215.213",
+ "185.18.215.214",
+ "185.18.215.241",
+ "185.19.201.19",
+ "185.19.201.21",
+ "185.19.201.25",
+ "185.19.201.39",
+ "185.19.201.41",
+ "185.19.201.43",
+ "185.19.201.49",
+ "185.19.201.59",
+ "185.19.201.60",
+ "185.19.201.65",
+ "185.19.201.78",
+ "185.19.201.89",
+ "185.19.201.106",
+ "185.19.201.110",
+ "185.19.201.116",
+ "185.19.201.125",
+ "185.19.201.142",
+ "185.19.201.144",
+ "185.19.201.148",
+ "185.19.201.162",
+ "185.19.201.167",
+ "185.19.201.183",
+ "185.19.201.190",
+ "185.19.201.200",
+ "185.20.162.8",
+ "185.20.162.9",
+ "185.21.70.234",
+ "185.24.136.90",
+ "185.24.139.71",
+ "185.24.139.91",
+ "185.24.252.133",
+ "185.24.252.166",
+ "185.24.252.195",
+ "185.24.252.199",
+ "185.24.255.71",
+ "185.24.255.75",
+ "185.24.255.195",
+ "185.24.255.200",
+ "185.26.32.33",
+ "185.26.32.137",
+ "185.31.124.3",
+ "185.31.124.7",
+ "185.31.125.3",
+ "185.31.125.7",
+ "185.31.126.3",
+ "185.31.127.3",
+ "185.36.228.117",
+ "185.36.228.160",
+ "185.36.228.161",
+ "185.36.228.174",
+ "185.36.231.11",
+ "185.36.231.47",
+ "185.36.231.88",
+ "185.36.231.91",
+ "185.36.231.93",
+ "185.36.231.157",
+ "185.36.231.231",
+ "185.37.52.36",
+ "185.37.52.37",
+ "185.37.52.126",
+ "185.37.53.209",
+ "185.37.54.19",
+ "185.37.54.20",
+ "185.37.54.30",
+ "185.37.54.112",
+ "185.37.54.113",
+ "185.37.54.133",
+ "185.37.54.152",
+ "185.37.54.191",
+ "185.37.54.253",
+ "185.37.54.254",
+ "185.37.55.30",
+ "185.37.55.127",
+ "185.37.55.169",
+ "185.37.55.203",
+ "185.37.55.243",
+ "185.37.55.247",
+ "185.39.180.119",
+ "185.39.180.120",
+ "185.39.180.181",
+ "185.39.182.228",
+ "185.39.182.230",
+ "185.39.182.232",
+ "185.39.182.233",
+ "185.39.182.234",
+ "185.40.16.42",
+ "185.40.16.194",
+ "185.40.16.198",
+ "185.41.1.130",
+ "185.41.1.134",
+ "185.41.1.141",
+ "185.41.3.2",
+ "185.41.3.3",
+ "185.41.3.4",
+ "185.41.3.6",
+ "185.41.3.7",
+ "185.41.3.8",
+ "185.41.3.9",
+ "185.41.3.10",
+ "185.41.3.11",
+ "185.41.3.12",
+ "185.41.3.13",
+ "185.41.3.14",
+ "185.41.3.15",
+ "185.41.3.16",
+ "185.41.3.17",
+ "185.41.3.18",
+ "185.41.3.19",
+ "185.41.3.20",
+ "185.41.3.21",
+ "185.41.3.22",
+ "185.41.3.23",
+ "185.41.3.24",
+ "185.41.3.25",
+ "185.41.3.26",
+ "185.41.3.27",
+ "185.41.3.28",
+ "185.41.3.29",
+ "185.41.3.30",
+ "185.41.3.34",
+ "185.41.3.98",
+ "185.41.3.99",
+ "185.41.3.100",
+ "185.41.3.101",
+ "185.41.3.102",
+ "185.41.3.103",
+ "185.41.3.104",
+ "185.41.3.105",
+ "185.41.3.107",
+ "185.41.3.108",
+ "185.41.3.109",
+ "185.41.3.110",
+ "185.41.3.111",
+ "185.41.3.112",
+ "185.41.3.113",
+ "185.41.3.114",
+ "185.41.3.115",
+ "185.41.3.116",
+ "185.41.3.117",
+ "185.41.3.118",
+ "185.41.3.119",
+ "185.41.3.120",
+ "185.41.3.121",
+ "185.41.3.122",
+ "185.41.3.123",
+ "185.41.3.124",
+ "185.41.3.125",
+ "185.41.3.126",
+ "185.42.224.5",
+ "185.42.224.7",
+ "185.42.225.31",
+ "185.42.226.18",
+ "185.44.36.36",
+ "185.44.36.216",
+ "185.44.36.248",
+ "185.46.217.234",
+ "185.47.48.26",
+ "185.47.50.162",
+ "185.47.50.166",
+ "185.49.84.18",
+ "185.49.84.34",
+ "185.49.84.51",
+ "185.49.84.68",
+ "185.49.84.83",
+ "185.49.84.84",
+ "185.49.84.90",
+ "185.49.84.91",
+ "185.49.84.92",
+ "185.49.84.93",
+ "185.49.84.134",
+ "185.49.84.143",
+ "185.49.84.157",
+ "185.49.84.166",
+ "185.49.84.209",
+ "185.49.84.226",
+ "185.49.84.228",
+ "185.49.84.229",
+ "185.49.84.230",
+ "185.49.84.231",
+ "185.49.84.232",
+ "185.49.84.233",
+ "185.49.84.234",
+ "185.49.84.235",
+ "185.49.84.236",
+ "185.49.84.237",
+ "185.49.84.238",
+ "185.49.84.239",
+ "185.49.84.240",
+ "185.49.84.241",
+ "185.49.84.242",
+ "185.49.84.243",
+ "185.49.84.244",
+ "185.49.84.245",
+ "185.49.84.246",
+ "185.49.84.248",
+ "185.49.84.252",
+ "185.49.85.2",
+ "185.49.85.5",
+ "185.49.85.19",
+ "185.49.85.27",
+ "185.49.85.28",
+ "185.49.85.34",
+ "185.49.85.35",
+ "185.49.85.36",
+ "185.49.85.37",
+ "185.49.85.38",
+ "185.49.85.39",
+ "185.49.85.40",
+ "185.49.85.41",
+ "185.49.85.42",
+ "185.49.85.43",
+ "185.49.85.44",
+ "185.49.85.45",
+ "185.49.85.46",
+ "185.49.85.130",
+ "185.49.85.131",
+ "185.49.85.133",
+ "185.49.85.135",
+ "185.49.85.138",
+ "185.49.85.142",
+ "185.49.85.143",
+ "185.49.85.146",
+ "185.49.85.149",
+ "185.49.85.152",
+ "185.49.85.154",
+ "185.49.85.157",
+ "185.49.85.163",
+ "185.49.85.168",
+ "185.49.85.172",
+ "185.49.85.173",
+ "185.49.85.204",
+ "185.49.85.206",
+ "185.49.85.212",
+ "185.49.85.244",
+ "185.49.86.13",
+ "185.49.86.42",
+ "185.49.86.56",
+ "185.49.86.57",
+ "185.49.86.111",
+ "185.49.86.194",
+ "185.49.86.202",
+ "185.49.86.213",
+ "185.49.87.94",
+ "185.49.87.180",
+ "185.49.87.181",
+ "185.49.87.182",
+ "185.49.87.218",
+ "185.49.87.219",
+ "185.49.87.240",
+ "185.49.96.252",
+ "185.49.96.253",
+ "185.50.37.15",
+ "185.50.37.46",
+ "185.50.37.48",
+ "185.50.37.52",
+ "185.50.37.56",
+ "185.50.37.66",
+ "185.50.37.91",
+ "185.50.37.166",
+ "185.50.37.168",
+ "185.50.37.171",
+ "185.50.37.174",
+ "185.50.37.175",
+ "185.50.38.29",
+ "185.50.38.33",
+ "185.50.38.38",
+ "185.50.38.72",
+ "185.50.38.128",
+ "185.50.38.135",
+ "185.50.38.145",
+ "185.50.38.148",
+ "185.50.38.168",
+ "185.50.38.171",
+ "185.50.38.191",
+ "185.50.38.201",
+ "185.50.38.216",
+ "185.50.38.220",
+ "185.50.38.225",
+ "185.50.38.236",
+ "185.50.39.3",
+ "185.50.39.32",
+ "185.50.39.49",
+ "185.50.39.50",
+ "185.50.39.53",
+ "185.50.39.94",
+ "185.50.39.96",
+ "185.50.39.97",
+ "185.50.39.159",
+ "185.51.43.2",
+ "185.51.200.1",
+ "185.51.200.5",
+ "185.51.200.58",
+ "185.51.200.182",
+ "185.51.201.58",
+ "185.51.201.77",
+ "185.51.201.195",
+ "185.51.201.255",
+ "185.51.202.251",
+ "185.53.140.6",
+ "185.53.140.43",
+ "185.53.141.45",
+ "185.53.141.54",
+ "185.53.141.120",
+ "185.53.141.182",
+ "185.53.141.187",
+ "185.53.141.194",
+ "185.53.141.195",
+ "185.53.141.218",
+ "185.53.141.229",
+ "185.53.142.2",
+ "185.53.142.3",
+ "185.53.142.4",
+ "185.53.142.5",
+ "185.53.142.6",
+ "185.53.142.35",
+ "185.53.142.37",
+ "185.53.142.123",
+ "185.53.142.174",
+ "185.53.142.180",
+ "185.53.142.211",
+ "185.53.142.212",
+ "185.53.142.213",
+ "185.53.142.214",
+ "185.53.143.3",
+ "185.53.143.74",
+ "185.53.143.133",
+ "185.53.143.134",
+ "185.53.143.135",
+ "185.53.143.136",
+ "185.53.143.137",
+ "185.53.143.139",
+ "185.53.143.141",
+ "185.53.143.142",
+ "185.53.143.143",
+ "185.53.143.146",
+ "185.53.143.156",
+ "185.53.143.157",
+ "185.53.143.186",
+ "185.53.143.244",
+ "185.55.224.3",
+ "185.55.224.4",
+ "185.55.224.8",
+ "185.55.224.10",
+ "185.55.224.11",
+ "185.55.224.12",
+ "185.55.224.13",
+ "185.55.224.14",
+ "185.55.224.15",
+ "185.55.224.16",
+ "185.55.224.17",
+ "185.55.224.18",
+ "185.55.224.20",
+ "185.55.224.21",
+ "185.55.224.22",
+ "185.55.224.23",
+ "185.55.224.27",
+ "185.55.224.28",
+ "185.55.224.29",
+ "185.55.224.30",
+ "185.55.224.31",
+ "185.55.224.32",
+ "185.55.224.33",
+ "185.55.224.34",
+ "185.55.224.35",
+ "185.55.224.36",
+ "185.55.224.38",
+ "185.55.224.39",
+ "185.55.224.45",
+ "185.55.224.46",
+ "185.55.224.48",
+ "185.55.224.49",
+ "185.55.224.50",
+ "185.55.224.51",
+ "185.55.224.52",
+ "185.55.224.53",
+ "185.55.224.54",
+ "185.55.224.55",
+ "185.55.224.56",
+ "185.55.224.57",
+ "185.55.224.59",
+ "185.55.224.60",
+ "185.55.224.61",
+ "185.55.224.62",
+ "185.55.224.63",
+ "185.55.224.64",
+ "185.55.224.65",
+ "185.55.224.66",
+ "185.55.224.67",
+ "185.55.224.68",
+ "185.55.224.69",
+ "185.55.224.70",
+ "185.55.224.71",
+ "185.55.224.72",
+ "185.55.224.73",
+ "185.55.224.74",
+ "185.55.224.75",
+ "185.55.224.76",
+ "185.55.224.77",
+ "185.55.224.78",
+ "185.55.224.80",
+ "185.55.224.81",
+ "185.55.224.82",
+ "185.55.224.83",
+ "185.55.224.84",
+ "185.55.224.85",
+ "185.55.224.86",
+ "185.55.224.87",
+ "185.55.224.88",
+ "185.55.224.93",
+ "185.55.224.94",
+ "185.55.224.96",
+ "185.55.224.97",
+ "185.55.224.98",
+ "185.55.224.99",
+ "185.55.224.101",
+ "185.55.224.102",
+ "185.55.224.104",
+ "185.55.224.105",
+ "185.55.224.106",
+ "185.55.224.108",
+ "185.55.224.110",
+ "185.55.224.111",
+ "185.55.224.112",
+ "185.55.224.113",
+ "185.55.224.114",
+ "185.55.224.117",
+ "185.55.224.118",
+ "185.55.224.120",
+ "185.55.224.122",
+ "185.55.224.123",
+ "185.55.224.124",
+ "185.55.224.125",
+ "185.55.224.126",
+ "185.55.224.127",
+ "185.55.224.128",
+ "185.55.224.129",
+ "185.55.224.132",
+ "185.55.224.134",
+ "185.55.224.135",
+ "185.55.224.136",
+ "185.55.224.137",
+ "185.55.224.138",
+ "185.55.224.139",
+ "185.55.224.140",
+ "185.55.224.141",
+ "185.55.224.142",
+ "185.55.224.143",
+ "185.55.224.144",
+ "185.55.224.145",
+ "185.55.224.146",
+ "185.55.224.148",
+ "185.55.224.149",
+ "185.55.224.150",
+ "185.55.224.152",
+ "185.55.224.153",
+ "185.55.224.154",
+ "185.55.224.155",
+ "185.55.224.156",
+ "185.55.224.157",
+ "185.55.224.158",
+ "185.55.224.159",
+ "185.55.224.160",
+ "185.55.224.161",
+ "185.55.224.162",
+ "185.55.224.165",
+ "185.55.224.166",
+ "185.55.224.172",
+ "185.55.224.179",
+ "185.55.224.180",
+ "185.55.224.181",
+ "185.55.224.182",
+ "185.55.224.183",
+ "185.55.224.184",
+ "185.55.224.185",
+ "185.55.224.188",
+ "185.55.224.191",
+ "185.55.224.192",
+ "185.55.224.194",
+ "185.55.224.195",
+ "185.55.224.196",
+ "185.55.224.197",
+ "185.55.224.198",
+ "185.55.224.199",
+ "185.55.224.201",
+ "185.55.224.203",
+ "185.55.224.204",
+ "185.55.224.206",
+ "185.55.224.207",
+ "185.55.224.208",
+ "185.55.224.209",
+ "185.55.224.211",
+ "185.55.224.212",
+ "185.55.224.213",
+ "185.55.224.215",
+ "185.55.224.216",
+ "185.55.224.217",
+ "185.55.224.218",
+ "185.55.224.219",
+ "185.55.224.220",
+ "185.55.224.221",
+ "185.55.224.227",
+ "185.55.224.229",
+ "185.55.224.230",
+ "185.55.224.231",
+ "185.55.224.232",
+ "185.55.224.233",
+ "185.55.224.234",
+ "185.55.224.235",
+ "185.55.224.236",
+ "185.55.224.237",
+ "185.55.224.245",
+ "185.55.224.246",
+ "185.55.224.247",
+ "185.55.224.251",
+ "185.55.225.2",
+ "185.55.225.3",
+ "185.55.225.4",
+ "185.55.225.5",
+ "185.55.225.6",
+ "185.55.225.7",
+ "185.55.225.8",
+ "185.55.225.9",
+ "185.55.225.10",
+ "185.55.225.11",
+ "185.55.225.15",
+ "185.55.225.16",
+ "185.55.225.17",
+ "185.55.225.18",
+ "185.55.225.19",
+ "185.55.225.20",
+ "185.55.225.21",
+ "185.55.225.22",
+ "185.55.225.23",
+ "185.55.225.24",
+ "185.55.225.26",
+ "185.55.225.27",
+ "185.55.225.28",
+ "185.55.225.29",
+ "185.55.225.34",
+ "185.55.225.35",
+ "185.55.225.36",
+ "185.55.225.37",
+ "185.55.225.38",
+ "185.55.225.39",
+ "185.55.225.41",
+ "185.55.225.42",
+ "185.55.225.43",
+ "185.55.225.44",
+ "185.55.225.45",
+ "185.55.225.46",
+ "185.55.225.47",
+ "185.55.225.48",
+ "185.55.225.49",
+ "185.55.225.50",
+ "185.55.225.51",
+ "185.55.225.52",
+ "185.55.225.53",
+ "185.55.225.54",
+ "185.55.225.55",
+ "185.55.225.56",
+ "185.55.225.57",
+ "185.55.225.59",
+ "185.55.225.60",
+ "185.55.225.61",
+ "185.55.225.62",
+ "185.55.225.63",
+ "185.55.225.65",
+ "185.55.225.66",
+ "185.55.225.67",
+ "185.55.225.69",
+ "185.55.225.72",
+ "185.55.225.73",
+ "185.55.225.77",
+ "185.55.225.78",
+ "185.55.225.79",
+ "185.55.225.80",
+ "185.55.225.81",
+ "185.55.225.82",
+ "185.55.225.83",
+ "185.55.225.84",
+ "185.55.225.85",
+ "185.55.225.86",
+ "185.55.225.87",
+ "185.55.225.88",
+ "185.55.225.89",
+ "185.55.225.90",
+ "185.55.225.91",
+ "185.55.225.92",
+ "185.55.225.93",
+ "185.55.225.94",
+ "185.55.225.95",
+ "185.55.225.96",
+ "185.55.225.98",
+ "185.55.225.99",
+ "185.55.225.100",
+ "185.55.225.102",
+ "185.55.225.103",
+ "185.55.225.104",
+ "185.55.225.105",
+ "185.55.225.106",
+ "185.55.225.107",
+ "185.55.225.108",
+ "185.55.225.110",
+ "185.55.225.111",
+ "185.55.225.112",
+ "185.55.225.113",
+ "185.55.225.114",
+ "185.55.225.115",
+ "185.55.225.116",
+ "185.55.225.117",
+ "185.55.225.118",
+ "185.55.225.119",
+ "185.55.225.120",
+ "185.55.225.121",
+ "185.55.225.122",
+ "185.55.225.123",
+ "185.55.225.124",
+ "185.55.225.125",
+ "185.55.225.126",
+ "185.55.225.127",
+ "185.55.225.128",
+ "185.55.225.129",
+ "185.55.225.130",
+ "185.55.225.131",
+ "185.55.225.132",
+ "185.55.225.133",
+ "185.55.225.134",
+ "185.55.225.135",
+ "185.55.225.136",
+ "185.55.225.137",
+ "185.55.225.138",
+ "185.55.225.139",
+ "185.55.225.140",
+ "185.55.225.141",
+ "185.55.225.142",
+ "185.55.225.143",
+ "185.55.225.144",
+ "185.55.225.145",
+ "185.55.225.146",
+ "185.55.225.147",
+ "185.55.225.148",
+ "185.55.225.149",
+ "185.55.225.152",
+ "185.55.225.153",
+ "185.55.225.154",
+ "185.55.225.155",
+ "185.55.225.156",
+ "185.55.225.157",
+ "185.55.225.159",
+ "185.55.225.160",
+ "185.55.225.161",
+ "185.55.225.162",
+ "185.55.225.164",
+ "185.55.225.165",
+ "185.55.225.166",
+ "185.55.225.167",
+ "185.55.225.168",
+ "185.55.225.169",
+ "185.55.225.170",
+ "185.55.225.172",
+ "185.55.225.173",
+ "185.55.225.174",
+ "185.55.225.175",
+ "185.55.225.177",
+ "185.55.225.178",
+ "185.55.225.179",
+ "185.55.225.180",
+ "185.55.225.181",
+ "185.55.225.183",
+ "185.55.225.184",
+ "185.55.225.185",
+ "185.55.225.186",
+ "185.55.225.187",
+ "185.55.225.188",
+ "185.55.225.191",
+ "185.55.225.192",
+ "185.55.225.193",
+ "185.55.225.194",
+ "185.55.225.195",
+ "185.55.225.196",
+ "185.55.225.197",
+ "185.55.225.198",
+ "185.55.225.199",
+ "185.55.225.200",
+ "185.55.225.201",
+ "185.55.225.202",
+ "185.55.225.203",
+ "185.55.225.204",
+ "185.55.225.205",
+ "185.55.225.206",
+ "185.55.225.207",
+ "185.55.225.208",
+ "185.55.225.209",
+ "185.55.225.211",
+ "185.55.225.212",
+ "185.55.225.213",
+ "185.55.225.214",
+ "185.55.225.215",
+ "185.55.225.216",
+ "185.55.225.217",
+ "185.55.225.218",
+ "185.55.225.219",
+ "185.55.225.220",
+ "185.55.225.221",
+ "185.55.225.222",
+ "185.55.225.223",
+ "185.55.225.224",
+ "185.55.225.225",
+ "185.55.225.227",
+ "185.55.225.228",
+ "185.55.225.229",
+ "185.55.225.230",
+ "185.55.225.231",
+ "185.55.225.232",
+ "185.55.225.233",
+ "185.55.225.234",
+ "185.55.225.235",
+ "185.55.225.236",
+ "185.55.225.237",
+ "185.55.225.240",
+ "185.55.225.241",
+ "185.55.225.242",
+ "185.55.225.243",
+ "185.55.225.244",
+ "185.55.225.245",
+ "185.55.225.246",
+ "185.55.225.247",
+ "185.55.225.248",
+ "185.55.225.251",
+ "185.55.226.20",
+ "185.55.226.39",
+ "185.55.226.100",
+ "185.55.226.116",
+ "185.55.226.121",
+ "185.55.226.124",
+ "185.55.226.145",
+ "185.55.226.171",
+ "185.55.226.173",
+ "185.55.226.181",
+ "185.55.226.194",
+ "185.55.226.211",
+ "185.55.226.226",
+ "185.55.226.231",
+ "185.55.226.239",
+ "185.55.227.2",
+ "185.55.227.7",
+ "185.55.227.9",
+ "185.55.227.12",
+ "185.55.227.15",
+ "185.55.227.20",
+ "185.55.227.21",
+ "185.55.227.22",
+ "185.55.227.23",
+ "185.55.227.24",
+ "185.55.227.26",
+ "185.55.227.29",
+ "185.55.227.31",
+ "185.55.227.32",
+ "185.55.227.33",
+ "185.55.227.35",
+ "185.55.227.44",
+ "185.55.227.49",
+ "185.55.227.50",
+ "185.55.227.51",
+ "185.55.227.53",
+ "185.55.227.54",
+ "185.55.227.55",
+ "185.55.227.56",
+ "185.55.227.57",
+ "185.55.227.58",
+ "185.55.227.59",
+ "185.55.227.60",
+ "185.55.227.61",
+ "185.55.227.62",
+ "185.55.227.63",
+ "185.55.227.64",
+ "185.55.227.65",
+ "185.55.227.66",
+ "185.55.227.67",
+ "185.55.227.68",
+ "185.55.227.69",
+ "185.55.227.70",
+ "185.55.227.71",
+ "185.55.227.72",
+ "185.55.227.73",
+ "185.55.227.76",
+ "185.55.227.77",
+ "185.55.227.78",
+ "185.55.227.79",
+ "185.55.227.80",
+ "185.55.227.81",
+ "185.55.227.82",
+ "185.55.227.83",
+ "185.55.227.84",
+ "185.55.227.85",
+ "185.55.227.86",
+ "185.55.227.87",
+ "185.55.227.88",
+ "185.55.227.89",
+ "185.55.227.91",
+ "185.55.227.92",
+ "185.55.227.93",
+ "185.55.227.94",
+ "185.55.227.95",
+ "185.55.227.96",
+ "185.55.227.97",
+ "185.55.227.98",
+ "185.55.227.99",
+ "185.55.227.100",
+ "185.55.227.102",
+ "185.55.227.103",
+ "185.55.227.104",
+ "185.55.227.106",
+ "185.55.227.107",
+ "185.55.227.108",
+ "185.55.227.109",
+ "185.55.227.110",
+ "185.55.227.111",
+ "185.55.227.112",
+ "185.55.227.113",
+ "185.55.227.114",
+ "185.55.227.115",
+ "185.55.227.116",
+ "185.55.227.117",
+ "185.55.227.118",
+ "185.55.227.119",
+ "185.55.227.120",
+ "185.55.227.122",
+ "185.55.227.123",
+ "185.55.227.124",
+ "185.55.227.125",
+ "185.55.227.126",
+ "185.55.227.127",
+ "185.55.227.128",
+ "185.55.227.129",
+ "185.55.227.130",
+ "185.55.227.131",
+ "185.55.227.132",
+ "185.55.227.133",
+ "185.55.227.134",
+ "185.55.227.139",
+ "185.55.227.140",
+ "185.55.227.144",
+ "185.55.227.145",
+ "185.55.227.146",
+ "185.55.227.148",
+ "185.55.227.149",
+ "185.55.227.150",
+ "185.55.227.151",
+ "185.55.227.152",
+ "185.55.227.153",
+ "185.55.227.154",
+ "185.55.227.155",
+ "185.55.227.156",
+ "185.55.227.157",
+ "185.55.227.158",
+ "185.55.227.159",
+ "185.55.227.160",
+ "185.55.227.161",
+ "185.55.227.162",
+ "185.55.227.163",
+ "185.55.227.164",
+ "185.55.227.165",
+ "185.55.227.166",
+ "185.55.227.168",
+ "185.55.227.169",
+ "185.55.227.171",
+ "185.55.227.172",
+ "185.55.227.174",
+ "185.55.227.176",
+ "185.55.227.177",
+ "185.55.227.178",
+ "185.55.227.179",
+ "185.55.227.180",
+ "185.55.227.181",
+ "185.55.227.182",
+ "185.55.227.183",
+ "185.55.227.184",
+ "185.55.227.185",
+ "185.55.227.189",
+ "185.55.227.190",
+ "185.55.227.191",
+ "185.55.227.194",
+ "185.55.227.196",
+ "185.55.227.197",
+ "185.55.227.198",
+ "185.55.227.199",
+ "185.55.227.201",
+ "185.55.227.202",
+ "185.55.227.203",
+ "185.55.227.204",
+ "185.55.227.206",
+ "185.55.227.207",
+ "185.55.227.208",
+ "185.55.227.210",
+ "185.55.227.211",
+ "185.55.227.213",
+ "185.55.227.215",
+ "185.55.227.216",
+ "185.55.227.218",
+ "185.55.227.220",
+ "185.55.227.222",
+ "185.55.227.223",
+ "185.55.227.224",
+ "185.55.227.225",
+ "185.55.227.226",
+ "185.55.227.228",
+ "185.55.227.229",
+ "185.55.227.231",
+ "185.55.227.233",
+ "185.55.227.235",
+ "185.55.227.236",
+ "185.55.227.239",
+ "185.55.227.240",
+ "185.55.227.241",
+ "185.55.227.243",
+ "185.55.227.245",
+ "185.56.93.100",
+ "185.56.93.101",
+ "185.57.164.4",
+ "185.57.164.5",
+ "185.57.164.177",
+ "185.57.165.93",
+ "185.58.240.15",
+ "185.58.240.80",
+ "185.58.240.81",
+ "185.58.240.105",
+ "185.58.240.114",
+ "185.58.240.115",
+ "185.58.240.120",
+ "185.58.240.167",
+ "185.58.240.216",
+ "185.58.240.251",
+ "185.58.241.5",
+ "185.58.241.12",
+ "185.58.241.27",
+ "185.58.241.44",
+ "185.58.241.54",
+ "185.58.241.62",
+ "185.58.241.139",
+ "185.58.241.148",
+ "185.58.241.169",
+ "185.58.241.225",
+ "185.58.241.226",
+ "185.58.241.227",
+ "185.58.241.235",
+ "185.58.242.19",
+ "185.58.242.37",
+ "185.58.242.129",
+ "185.58.242.215",
+ "185.58.242.230",
+ "185.58.242.236",
+ "185.58.242.253",
+ "185.58.243.65",
+ "185.59.112.218",
+ "185.60.136.90",
+ "185.60.136.128",
+ "185.60.136.140",
+ "185.60.137.149",
+ "185.63.113.16",
+ "185.63.113.17",
+ "185.63.113.18",
+ "185.63.113.20",
+ "185.63.113.25",
+ "185.63.113.30",
+ "185.63.113.35",
+ "185.63.113.37",
+ "185.63.113.131",
+ "185.63.113.134",
+ "185.63.113.137",
+ "185.63.113.141",
+ "185.63.113.145",
+ "185.63.113.148",
+ "185.63.113.156",
+ "185.63.113.158",
+ "185.63.113.173",
+ "185.63.113.194",
+ "185.63.113.196",
+ "185.63.113.211",
+ "185.63.113.212",
+ "185.63.113.219",
+ "185.63.113.236",
+ "185.63.113.242",
+ "185.63.113.245",
+ "185.63.114.119",
+ "185.63.237.12",
+ "185.66.224.4",
+ "185.66.224.24",
+ "185.66.226.83",
+ "185.66.230.194",
+ "185.66.230.195",
+ "185.66.230.253",
+ "185.67.12.11",
+ "185.67.12.12",
+ "185.67.14.11",
+ "185.67.156.5",
+ "185.67.156.7",
+ "185.67.213.50",
+ "185.67.214.50",
+ "185.71.193.84",
+ "185.71.194.171",
+ "185.72.25.204",
+ "185.72.25.205",
+ "185.72.25.226",
+ "185.73.78.10",
+ "185.73.112.39",
+ "185.73.112.41",
+ "185.73.112.62",
+ "185.73.112.163",
+ "185.73.112.180",
+ "185.73.112.227",
+ "185.73.112.228",
+ "185.73.114.28",
+ "185.73.114.67",
+ "185.73.114.82",
+ "185.73.114.86",
+ "185.73.114.123",
+ "185.73.114.207",
+ "185.73.114.232",
+ "185.73.114.247",
+ "185.73.114.254",
+ "185.73.226.237",
+ "185.73.226.241",
+ "185.73.226.242",
+ "185.73.226.243",
+ "185.74.221.2",
+ "185.74.221.51",
+ "185.74.221.155",
+ "185.74.221.180",
+ "185.74.221.197",
+ "185.74.221.238",
+ "185.78.21.33",
+ "185.78.21.35",
+ "185.78.21.40",
+ "185.78.21.42",
+ "185.78.21.43",
+ "185.78.21.49",
+ "185.78.21.50",
+ "185.78.21.51",
+ "185.78.22.2",
+ "185.78.22.174",
+ "185.78.22.175",
+ "185.78.23.202",
+ "185.79.62.4",
+ "185.79.62.5",
+ "185.79.96.67",
+ "185.79.156.78",
+ "185.79.156.88",
+ "185.79.156.92",
+ "185.79.156.105",
+ "185.79.156.107",
+ "185.79.156.122",
+ "185.79.156.132",
+ "185.79.156.148",
+ "185.79.156.149",
+ "185.79.156.151",
+ "185.79.156.155",
+ "185.79.156.160",
+ "185.79.156.165",
+ "185.79.156.172",
+ "185.79.156.173",
+ "185.79.156.174",
+ "185.79.156.199",
+ "185.79.156.214",
+ "185.79.156.228",
+ "185.79.156.229",
+ "185.79.156.234",
+ "185.79.157.2",
+ "185.79.157.3",
+ "185.79.157.5",
+ "185.79.157.7",
+ "185.79.157.16",
+ "185.79.157.23",
+ "185.79.157.60",
+ "185.79.157.153",
+ "185.79.157.161",
+ "185.79.157.188",
+ "185.79.157.192",
+ "185.79.157.195",
+ "185.79.157.199",
+ "185.79.157.205",
+ "185.79.157.208",
+ "185.79.157.232",
+ "185.79.157.247",
+ "185.79.157.254",
+ "185.79.158.8",
+ "185.79.158.22",
+ "185.79.158.23",
+ "185.79.158.33",
+ "185.79.158.75",
+ "185.79.158.165",
+ "185.79.158.166",
+ "185.79.158.169",
+ "185.79.158.212",
+ "185.79.159.136",
+ "185.81.96.5",
+ "185.81.96.10",
+ "185.81.96.15",
+ "185.81.96.16",
+ "185.81.96.20",
+ "185.81.96.27",
+ "185.81.96.28",
+ "185.81.96.31",
+ "185.81.96.35",
+ "185.81.96.38",
+ "185.81.96.42",
+ "185.81.96.103",
+ "185.81.96.114",
+ "185.81.96.129",
+ "185.81.96.195",
+ "185.81.96.211",
+ "185.81.96.221",
+ "185.81.96.240",
+ "185.81.97.5",
+ "185.81.97.17",
+ "185.81.97.25",
+ "185.81.97.26",
+ "185.81.97.28",
+ "185.81.97.55",
+ "185.81.97.56",
+ "185.81.97.59",
+ "185.81.97.69",
+ "185.81.97.77",
+ "185.81.97.89",
+ "185.81.97.148",
+ "185.81.97.155",
+ "185.81.97.163",
+ "185.81.97.165",
+ "185.81.97.175",
+ "185.81.97.181",
+ "185.81.97.191",
+ "185.81.97.193",
+ "185.81.97.222",
+ "185.81.97.235",
+ "185.81.97.250",
+ "185.81.99.46",
+ "185.81.99.76",
+ "185.81.99.119",
+ "185.81.99.120",
+ "185.81.99.123",
+ "185.81.99.135",
+ "185.81.99.140",
+ "185.81.99.151",
+ "185.81.99.156",
+ "185.81.99.171",
+ "185.81.99.185",
+ "185.81.99.222",
+ "185.81.99.223",
+ "185.81.99.228",
+ "185.81.99.239",
+ "185.82.136.19",
+ "185.83.88.19",
+ "185.83.88.23",
+ "185.83.88.24",
+ "185.83.88.27",
+ "185.83.91.3",
+ "185.83.112.67",
+ "185.83.112.99",
+ "185.83.112.110",
+ "185.83.112.212",
+ "185.83.113.28",
+ "185.83.113.39",
+ "185.83.113.46",
+ "185.83.113.57",
+ "185.83.113.59",
+ "185.83.113.77",
+ "185.83.113.78",
+ "185.83.113.80",
+ "185.83.113.92",
+ "185.83.113.104",
+ "185.83.113.123",
+ "185.83.113.124",
+ "185.83.113.142",
+ "185.83.113.172",
+ "185.83.113.176",
+ "185.83.113.178",
+ "185.83.113.180",
+ "185.83.113.184",
+ "185.83.113.192",
+ "185.83.113.198",
+ "185.83.113.210",
+ "185.83.113.213",
+ "185.83.113.214",
+ "185.83.113.216",
+ "185.83.113.217",
+ "185.83.113.218",
+ "185.83.113.219",
+ "185.83.113.220",
+ "185.83.113.225",
+ "185.83.113.226",
+ "185.83.113.227",
+ "185.83.113.228",
+ "185.83.113.230",
+ "185.83.113.231",
+ "185.83.113.234",
+ "185.83.113.236",
+ "185.83.113.241",
+ "185.83.113.244",
+ "185.83.113.246",
+ "185.83.113.247",
+ "185.83.113.251",
+ "185.83.113.252",
+ "185.83.114.57",
+ "185.83.114.67",
+ "185.83.114.69",
+ "185.83.114.75",
+ "185.83.114.110",
+ "185.83.114.116",
+ "185.83.114.118",
+ "185.83.114.122",
+ "185.83.114.128",
+ "185.83.114.142",
+ "185.83.114.148",
+ "185.83.114.153",
+ "185.83.114.159",
+ "185.83.114.162",
+ "185.83.114.172",
+ "185.83.114.186",
+ "185.83.114.244",
+ "185.83.114.251",
+ "185.83.115.42",
+ "185.83.115.43",
+ "185.83.115.44",
+ "185.83.115.46",
+ "185.83.115.182",
+ "185.83.181.58",
+ "185.83.181.100",
+ "185.83.181.101",
+ "185.83.181.120",
+ "185.83.181.121",
+ "185.83.181.190",
+ "185.83.182.19",
+ "185.83.182.22",
+ "185.83.182.29",
+ "185.83.182.85",
+ "185.83.182.107",
+ "185.83.182.120",
+ "185.83.182.172",
+ "185.83.183.3",
+ "185.83.183.4",
+ "185.83.183.5",
+ "185.83.183.8",
+ "185.83.183.14",
+ "185.83.183.17",
+ "185.83.183.19",
+ "185.83.183.23",
+ "185.83.183.24",
+ "185.83.183.27",
+ "185.83.183.30",
+ "185.83.183.37",
+ "185.83.183.38",
+ "185.83.183.39",
+ "185.83.183.41",
+ "185.83.183.44",
+ "185.83.183.45",
+ "185.83.183.46",
+ "185.83.183.49",
+ "185.83.183.56",
+ "185.83.183.57",
+ "185.83.183.59",
+ "185.83.183.92",
+ "185.83.183.94",
+ "185.83.183.97",
+ "185.83.183.99",
+ "185.83.183.100",
+ "185.83.183.102",
+ "185.83.183.107",
+ "185.83.183.114",
+ "185.83.183.115",
+ "185.83.183.116",
+ "185.83.183.128",
+ "185.83.183.130",
+ "185.83.183.131",
+ "185.83.183.132",
+ "185.83.183.134",
+ "185.83.183.135",
+ "185.83.183.136",
+ "185.83.183.139",
+ "185.83.183.147",
+ "185.83.183.152",
+ "185.83.183.153",
+ "185.83.183.154",
+ "185.83.183.159",
+ "185.83.183.161",
+ "185.83.183.163",
+ "185.83.183.164",
+ "185.83.183.184",
+ "185.83.183.187",
+ "185.83.183.195",
+ "185.83.183.197",
+ "185.83.183.199",
+ "185.83.183.200",
+ "185.83.183.202",
+ "185.83.183.203",
+ "185.83.183.205",
+ "185.83.183.207",
+ "185.83.183.210",
+ "185.83.183.215",
+ "185.83.183.216",
+ "185.83.183.217",
+ "185.83.183.218",
+ "185.83.183.220",
+ "185.83.183.221",
+ "185.83.183.223",
+ "185.83.183.225",
+ "185.83.183.228",
+ "185.83.183.229",
+ "185.83.183.234",
+ "185.83.183.236",
+ "185.83.183.240",
+ "185.83.183.241",
+ "185.83.183.242",
+ "185.83.183.244",
+ "185.83.183.245",
+ "185.83.183.246",
+ "185.83.183.247",
+ "185.83.183.248",
+ "185.83.183.249",
+ "185.83.183.254",
+ "185.83.197.81",
+ "185.83.197.83",
+ "185.83.197.84",
+ "185.83.197.87",
+ "185.83.198.46",
+ "185.83.199.97",
+ "185.83.208.2",
+ "185.83.208.3",
+ "185.83.208.10",
+ "185.83.208.13",
+ "185.83.208.14",
+ "185.83.208.15",
+ "185.83.208.23",
+ "185.83.208.24",
+ "185.83.208.25",
+ "185.83.208.26",
+ "185.83.208.35",
+ "185.83.208.39",
+ "185.83.208.43",
+ "185.83.208.44",
+ "185.83.208.45",
+ "185.83.208.106",
+ "185.83.208.109",
+ "185.83.208.111",
+ "185.83.208.112",
+ "185.83.208.114",
+ "185.83.208.115",
+ "185.83.208.116",
+ "185.83.208.118",
+ "185.83.208.119",
+ "185.83.208.136",
+ "185.83.208.140",
+ "185.83.208.150",
+ "185.83.208.158",
+ "185.83.208.160",
+ "185.83.208.162",
+ "185.83.208.167",
+ "185.83.208.169",
+ "185.83.208.172",
+ "185.83.208.173",
+ "185.83.208.174",
+ "185.83.208.175",
+ "185.83.208.177",
+ "185.83.208.182",
+ "185.83.208.184",
+ "185.83.208.188",
+ "185.83.208.189",
+ "185.83.208.201",
+ "185.83.208.204",
+ "185.83.208.205",
+ "185.83.208.207",
+ "185.83.208.208",
+ "185.83.208.209",
+ "185.83.208.226",
+ "185.83.208.234",
+ "185.83.208.249",
+ "185.83.209.9",
+ "185.83.209.10",
+ "185.83.209.34",
+ "185.83.209.35",
+ "185.83.209.36",
+ "185.83.209.37",
+ "185.83.209.38",
+ "185.83.209.39",
+ "185.83.210.2",
+ "185.83.210.3",
+ "185.83.210.5",
+ "185.83.210.6",
+ "185.83.210.7",
+ "185.83.210.9",
+ "185.83.210.14",
+ "185.83.210.34",
+ "185.83.210.66",
+ "185.83.210.67",
+ "185.83.210.68",
+ "185.83.210.70",
+ "185.83.210.82",
+ "185.83.210.98",
+ "185.83.210.136",
+ "185.83.210.138",
+ "185.83.210.143",
+ "185.83.210.184",
+ "185.84.158.6",
+ "185.84.158.79",
+ "185.84.220.5",
+ "185.84.222.22",
+ "185.86.36.97",
+ "185.86.36.98",
+ "185.86.36.99",
+ "185.86.36.100",
+ "185.86.36.101",
+ "185.86.36.102",
+ "185.86.36.103",
+ "185.86.36.104",
+ "185.86.36.105",
+ "185.86.36.106",
+ "185.86.36.107",
+ "185.86.36.108",
+ "185.86.36.109",
+ "185.86.36.161",
+ "185.86.36.185",
+ "185.86.36.201",
+ "185.86.36.202",
+ "185.86.180.71",
+ "185.86.180.218",
+ "185.86.181.21",
+ "185.86.181.28",
+ "185.86.181.29",
+ "185.86.181.30",
+ "185.86.181.102",
+ "185.86.181.106",
+ "185.86.181.108",
+ "185.86.181.117",
+ "185.86.181.146",
+ "185.86.181.182",
+ "185.86.181.183",
+ "185.86.181.184",
+ "185.86.181.214",
+ "185.86.181.235",
+ "185.86.181.237",
+ "185.86.181.238",
+ "185.88.152.3",
+ "185.88.152.4",
+ "185.88.152.12",
+ "185.88.152.16",
+ "185.88.152.22",
+ "185.88.152.26",
+ "185.88.152.27",
+ "185.88.152.31",
+ "185.88.152.40",
+ "185.88.152.41",
+ "185.88.152.42",
+ "185.88.152.44",
+ "185.88.152.45",
+ "185.88.152.46",
+ "185.88.152.63",
+ "185.88.152.64",
+ "185.88.152.66",
+ "185.88.152.68",
+ "185.88.152.70",
+ "185.88.152.76",
+ "185.88.152.77",
+ "185.88.152.78",
+ "185.88.152.81",
+ "185.88.152.85",
+ "185.88.152.86",
+ "185.88.152.87",
+ "185.88.152.88",
+ "185.88.152.92",
+ "185.88.152.93",
+ "185.88.152.94",
+ "185.88.152.97",
+ "185.88.152.98",
+ "185.88.152.103",
+ "185.88.152.109",
+ "185.88.152.110",
+ "185.88.152.113",
+ "185.88.152.115",
+ "185.88.152.117",
+ "185.88.152.123",
+ "185.88.152.124",
+ "185.88.152.126",
+ "185.88.152.127",
+ "185.88.152.129",
+ "185.88.152.130",
+ "185.88.152.134",
+ "185.88.152.138",
+ "185.88.152.140",
+ "185.88.152.142",
+ "185.88.152.154",
+ "185.88.152.156",
+ "185.88.152.161",
+ "185.88.152.162",
+ "185.88.152.163",
+ "185.88.152.173",
+ "185.88.152.178",
+ "185.88.152.186",
+ "185.88.152.187",
+ "185.88.152.192",
+ "185.88.152.193",
+ "185.88.152.197",
+ "185.88.152.199",
+ "185.88.152.201",
+ "185.88.152.202",
+ "185.88.152.206",
+ "185.88.152.213",
+ "185.88.152.215",
+ "185.88.152.218",
+ "185.88.152.222",
+ "185.88.152.223",
+ "185.88.152.228",
+ "185.88.152.232",
+ "185.88.152.236",
+ "185.88.152.238",
+ "185.88.152.242",
+ "185.88.152.248",
+ "185.88.152.250",
+ "185.88.152.254",
+ "185.88.153.10",
+ "185.88.153.15",
+ "185.88.153.18",
+ "185.88.153.20",
+ "185.88.153.29",
+ "185.88.153.31",
+ "185.88.153.33",
+ "185.88.153.34",
+ "185.88.153.39",
+ "185.88.153.42",
+ "185.88.153.43",
+ "185.88.153.50",
+ "185.88.153.52",
+ "185.88.153.64",
+ "185.88.153.66",
+ "185.88.153.67",
+ "185.88.153.70",
+ "185.88.153.71",
+ "185.88.153.72",
+ "185.88.153.75",
+ "185.88.153.76",
+ "185.88.153.80",
+ "185.88.153.82",
+ "185.88.153.83",
+ "185.88.153.85",
+ "185.88.153.88",
+ "185.88.153.90",
+ "185.88.153.98",
+ "185.88.153.99",
+ "185.88.153.103",
+ "185.88.153.104",
+ "185.88.153.108",
+ "185.88.153.111",
+ "185.88.153.112",
+ "185.88.153.115",
+ "185.88.153.116",
+ "185.88.153.117",
+ "185.88.153.118",
+ "185.88.153.119",
+ "185.88.153.122",
+ "185.88.153.123",
+ "185.88.153.124",
+ "185.88.153.128",
+ "185.88.153.130",
+ "185.88.153.146",
+ "185.88.153.147",
+ "185.88.153.150",
+ "185.88.153.153",
+ "185.88.153.162",
+ "185.88.153.166",
+ "185.88.153.169",
+ "185.88.153.170",
+ "185.88.153.172",
+ "185.88.153.173",
+ "185.88.153.179",
+ "185.88.153.180",
+ "185.88.153.186",
+ "185.88.153.189",
+ "185.88.153.191",
+ "185.88.153.196",
+ "185.88.153.198",
+ "185.88.153.199",
+ "185.88.153.214",
+ "185.88.153.218",
+ "185.88.153.219",
+ "185.88.153.222",
+ "185.88.153.227",
+ "185.88.153.228",
+ "185.88.153.233",
+ "185.88.153.234",
+ "185.88.153.237",
+ "185.88.153.240",
+ "185.88.153.241",
+ "185.88.153.243",
+ "185.88.153.249",
+ "185.88.153.254",
+ "185.88.154.2",
+ "185.88.154.22",
+ "185.88.154.23",
+ "185.88.154.26",
+ "185.88.154.27",
+ "185.88.154.29",
+ "185.88.154.32",
+ "185.88.154.35",
+ "185.88.154.37",
+ "185.88.154.38",
+ "185.88.154.40",
+ "185.88.154.41",
+ "185.88.154.47",
+ "185.88.154.55",
+ "185.88.154.56",
+ "185.88.154.62",
+ "185.88.154.71",
+ "185.88.154.76",
+ "185.88.154.78",
+ "185.88.154.85",
+ "185.88.154.101",
+ "185.88.154.108",
+ "185.88.154.111",
+ "185.88.154.116",
+ "185.88.154.121",
+ "185.88.154.123",
+ "185.88.154.124",
+ "185.88.154.125",
+ "185.88.154.126",
+ "185.88.154.128",
+ "185.88.154.129",
+ "185.88.154.130",
+ "185.88.154.133",
+ "185.88.154.134",
+ "185.88.154.138",
+ "185.88.154.151",
+ "185.88.154.153",
+ "185.88.154.160",
+ "185.88.154.167",
+ "185.88.154.174",
+ "185.88.154.175",
+ "185.88.154.181",
+ "185.88.154.183",
+ "185.88.154.187",
+ "185.88.154.189",
+ "185.88.154.192",
+ "185.88.154.195",
+ "185.88.154.197",
+ "185.88.154.198",
+ "185.88.154.215",
+ "185.88.154.221",
+ "185.88.154.224",
+ "185.88.154.225",
+ "185.88.154.233",
+ "185.88.154.235",
+ "185.88.154.240",
+ "185.88.154.242",
+ "185.88.154.248",
+ "185.88.155.7",
+ "185.88.155.53",
+ "185.88.155.98",
+ "185.88.155.122",
+ "185.88.155.125",
+ "185.88.155.150",
+ "185.88.155.166",
+ "185.88.155.167",
+ "185.88.155.172",
+ "185.88.155.189",
+ "185.88.155.192",
+ "185.88.176.138",
+ "185.88.176.152",
+ "185.88.176.210",
+ "185.88.176.211",
+ "185.88.176.212",
+ "185.88.176.213",
+ "185.88.176.218",
+ "185.88.176.219",
+ "185.88.176.221",
+ "185.88.176.222",
+ "185.88.177.2",
+ "185.88.177.3",
+ "185.88.177.5",
+ "185.88.177.6",
+ "185.88.177.7",
+ "185.88.177.8",
+ "185.88.177.9",
+ "185.88.177.17",
+ "185.88.177.18",
+ "185.88.177.19",
+ "185.88.177.20",
+ "185.88.177.22",
+ "185.88.177.25",
+ "185.88.177.26",
+ "185.88.177.27",
+ "185.88.177.33",
+ "185.88.177.34",
+ "185.88.177.35",
+ "185.88.177.50",
+ "185.88.177.55",
+ "185.88.177.56",
+ "185.88.177.57",
+ "185.88.177.60",
+ "185.88.177.64",
+ "185.88.177.67",
+ "185.88.177.68",
+ "185.88.177.69",
+ "185.88.177.70",
+ "185.88.177.72",
+ "185.88.177.79",
+ "185.88.177.81",
+ "185.88.177.88",
+ "185.88.177.90",
+ "185.88.177.92",
+ "185.88.177.94",
+ "185.88.177.103",
+ "185.88.177.104",
+ "185.88.177.105",
+ "185.88.177.110",
+ "185.88.177.111",
+ "185.88.177.112",
+ "185.88.177.113",
+ "185.88.177.117",
+ "185.88.177.118",
+ "185.88.177.120",
+ "185.88.177.122",
+ "185.88.177.123",
+ "185.88.177.124",
+ "185.88.177.135",
+ "185.88.177.138",
+ "185.88.177.139",
+ "185.88.177.140",
+ "185.88.177.141",
+ "185.88.177.142",
+ "185.88.177.143",
+ "185.88.177.144",
+ "185.88.177.145",
+ "185.88.177.146",
+ "185.88.177.147",
+ "185.88.177.148",
+ "185.88.177.149",
+ "185.88.177.150",
+ "185.88.177.151",
+ "185.88.177.152",
+ "185.88.177.153",
+ "185.88.177.154",
+ "185.88.177.155",
+ "185.88.177.156",
+ "185.88.177.157",
+ "185.88.177.159",
+ "185.88.177.162",
+ "185.88.177.163",
+ "185.88.177.164",
+ "185.88.177.165",
+ "185.88.177.167",
+ "185.88.177.173",
+ "185.88.177.175",
+ "185.88.177.181",
+ "185.88.177.182",
+ "185.88.177.183",
+ "185.88.177.184",
+ "185.88.177.185",
+ "185.88.177.188",
+ "185.88.177.199",
+ "185.88.177.206",
+ "185.88.177.214",
+ "185.88.177.222",
+ "185.88.177.223",
+ "185.88.177.226",
+ "185.88.177.227",
+ "185.88.177.228",
+ "185.88.177.231",
+ "185.88.177.232",
+ "185.88.177.233",
+ "185.88.177.236",
+ "185.88.177.242",
+ "185.88.177.243",
+ "185.88.177.244",
+ "185.88.177.246",
+ "185.88.177.247",
+ "185.88.177.248",
+ "185.88.177.250",
+ "185.88.177.252",
+ "185.88.178.5",
+ "185.88.178.6",
+ "185.88.178.7",
+ "185.88.178.9",
+ "185.88.178.11",
+ "185.88.178.15",
+ "185.88.178.16",
+ "185.88.178.17",
+ "185.88.178.18",
+ "185.88.178.20",
+ "185.88.178.27",
+ "185.88.178.28",
+ "185.88.178.30",
+ "185.88.178.35",
+ "185.88.178.38",
+ "185.88.178.39",
+ "185.88.178.40",
+ "185.88.178.42",
+ "185.88.178.44",
+ "185.88.178.45",
+ "185.88.178.47",
+ "185.88.178.49",
+ "185.88.178.52",
+ "185.88.178.55",
+ "185.88.178.56",
+ "185.88.178.58",
+ "185.88.178.66",
+ "185.88.178.67",
+ "185.88.178.68",
+ "185.88.178.69",
+ "185.88.178.71",
+ "185.88.178.72",
+ "185.88.178.73",
+ "185.88.178.75",
+ "185.88.178.76",
+ "185.88.178.77",
+ "185.88.178.81",
+ "185.88.178.89",
+ "185.88.178.90",
+ "185.88.178.91",
+ "185.88.178.98",
+ "185.88.178.101",
+ "185.88.178.102",
+ "185.88.178.103",
+ "185.88.178.106",
+ "185.88.178.107",
+ "185.88.178.108",
+ "185.88.178.109",
+ "185.88.178.110",
+ "185.88.178.113",
+ "185.88.178.115",
+ "185.88.178.117",
+ "185.88.178.118",
+ "185.88.178.119",
+ "185.88.178.122",
+ "185.88.178.123",
+ "185.88.178.125",
+ "185.88.178.132",
+ "185.88.178.158",
+ "185.88.178.177",
+ "185.88.178.179",
+ "185.88.178.196",
+ "185.88.178.197",
+ "185.88.178.199",
+ "185.88.178.202",
+ "185.88.178.206",
+ "185.88.179.68",
+ "185.88.179.71",
+ "185.88.179.72",
+ "185.88.179.73",
+ "185.88.179.74",
+ "185.88.179.76",
+ "185.88.179.78",
+ "185.88.179.83",
+ "185.88.179.85",
+ "185.88.179.87",
+ "185.88.179.88",
+ "185.88.179.90",
+ "185.88.179.91",
+ "185.88.179.92",
+ "185.88.179.146",
+ "185.88.179.148",
+ "185.88.179.149",
+ "185.88.179.196",
+ "185.88.179.197",
+ "185.88.179.198",
+ "185.88.179.199",
+ "185.88.179.200",
+ "185.88.179.201",
+ "185.88.179.202",
+ "185.88.179.203",
+ "185.88.179.204",
+ "185.88.179.206",
+ "185.88.179.211",
+ "185.88.179.212",
+ "185.88.179.213",
+ "185.88.179.217",
+ "185.88.179.218",
+ "185.88.179.219",
+ "185.88.179.226",
+ "185.88.179.230",
+ "185.88.179.231",
+ "185.88.179.236",
+ "185.88.179.237",
+ "185.88.179.238",
+ "185.88.179.252",
+ "185.88.179.253",
+ "185.88.255.10",
+ "185.89.22.2",
+ "185.89.22.6",
+ "185.89.22.14",
+ "185.89.22.100",
+ "185.89.22.138",
+ "185.89.22.186",
+ "185.89.22.194",
+ "185.89.22.210",
+ "185.89.22.234",
+ "185.89.112.20",
+ "185.89.112.26",
+ "185.89.113.121",
+ "185.89.115.195",
+ "185.94.96.2",
+ "185.94.96.6",
+ "185.94.96.10",
+ "185.94.96.22",
+ "185.94.96.34",
+ "185.94.96.38",
+ "185.94.96.42",
+ "185.94.96.46",
+ "185.94.96.56",
+ "185.94.96.58",
+ "185.94.96.76",
+ "185.94.96.87",
+ "185.94.96.89",
+ "185.94.96.98",
+ "185.94.96.100",
+ "185.94.96.101",
+ "185.94.96.102",
+ "185.94.96.106",
+ "185.94.96.110",
+ "185.94.96.118",
+ "185.94.96.130",
+ "185.94.96.134",
+ "185.94.96.138",
+ "185.94.96.146",
+ "185.94.96.154",
+ "185.94.96.158",
+ "185.94.96.162",
+ "185.94.96.174",
+ "185.94.96.178",
+ "185.94.96.186",
+ "185.94.96.190",
+ "185.94.96.194",
+ "185.94.96.196",
+ "185.94.96.197",
+ "185.94.96.204",
+ "185.94.96.207",
+ "185.94.96.210",
+ "185.94.96.214",
+ "185.94.96.216",
+ "185.94.96.217",
+ "185.94.96.218",
+ "185.94.96.226",
+ "185.94.96.229",
+ "185.94.96.231",
+ "185.94.96.233",
+ "185.94.96.237",
+ "185.94.96.242",
+ "185.94.97.2",
+ "185.94.97.5",
+ "185.94.97.6",
+ "185.94.97.7",
+ "185.94.97.8",
+ "185.94.97.9",
+ "185.94.97.10",
+ "185.94.97.13",
+ "185.94.97.14",
+ "185.94.97.18",
+ "185.94.97.30",
+ "185.94.97.34",
+ "185.94.97.37",
+ "185.94.97.46",
+ "185.94.97.50",
+ "185.94.97.54",
+ "185.94.97.62",
+ "185.94.97.74",
+ "185.94.97.85",
+ "185.94.97.87",
+ "185.94.97.90",
+ "185.94.97.92",
+ "185.94.97.98",
+ "185.94.97.102",
+ "185.94.97.150",
+ "185.94.97.198",
+ "185.94.97.206",
+ "185.94.97.210",
+ "185.94.97.222",
+ "185.94.97.227",
+ "185.94.97.229",
+ "185.94.97.230",
+ "185.94.97.231",
+ "185.94.97.233",
+ "185.94.97.235",
+ "185.94.97.236",
+ "185.94.97.254",
+ "185.94.98.3",
+ "185.94.98.4",
+ "185.94.98.6",
+ "185.94.98.11",
+ "185.94.98.17",
+ "185.94.98.34",
+ "185.94.98.42",
+ "185.94.98.44",
+ "185.94.98.45",
+ "185.94.98.54",
+ "185.94.98.69",
+ "185.94.98.74",
+ "185.94.98.78",
+ "185.94.98.90",
+ "185.94.98.92",
+ "185.94.98.93",
+ "185.94.98.94",
+ "185.94.98.110",
+ "185.94.98.114",
+ "185.94.98.117",
+ "185.94.98.118",
+ "185.94.98.119",
+ "185.94.98.121",
+ "185.94.98.122",
+ "185.94.98.123",
+ "185.94.98.126",
+ "185.94.98.130",
+ "185.94.98.133",
+ "185.94.98.134",
+ "185.94.98.146",
+ "185.94.98.151",
+ "185.94.98.156",
+ "185.94.98.171",
+ "185.94.98.172",
+ "185.94.98.194",
+ "185.94.98.197",
+ "185.94.98.198",
+ "185.94.98.199",
+ "185.94.98.201",
+ "185.94.98.202",
+ "185.94.98.203",
+ "185.94.98.205",
+ "185.94.98.206",
+ "185.94.98.209",
+ "185.94.98.216",
+ "185.94.98.218",
+ "185.94.98.227",
+ "185.94.98.229",
+ "185.94.98.230",
+ "185.94.98.234",
+ "185.94.98.236",
+ "185.94.98.237",
+ "185.94.98.242",
+ "185.94.98.250",
+ "185.94.98.251",
+ "185.94.98.252",
+ "185.94.98.253",
+ "185.94.99.11",
+ "185.94.99.13",
+ "185.94.99.15",
+ "185.94.99.18",
+ "185.94.99.27",
+ "185.94.99.36",
+ "185.94.99.45",
+ "185.94.99.50",
+ "185.94.99.70",
+ "185.94.99.82",
+ "185.94.99.93",
+ "185.94.99.100",
+ "185.94.99.103",
+ "185.94.99.105",
+ "185.94.99.106",
+ "185.94.99.130",
+ "185.94.99.138",
+ "185.94.99.142",
+ "185.94.99.162",
+ "185.94.99.166",
+ "185.94.99.170",
+ "185.94.99.171",
+ "185.94.99.172",
+ "185.94.99.174",
+ "185.94.99.178",
+ "185.94.99.181",
+ "185.94.99.195",
+ "185.94.99.201",
+ "185.94.99.202",
+ "185.94.99.203",
+ "185.94.99.204",
+ "185.94.99.209",
+ "185.94.99.211",
+ "185.94.99.215",
+ "185.94.99.219",
+ "185.94.99.220",
+ "185.94.99.226",
+ "185.94.99.228",
+ "185.94.99.229",
+ "185.94.99.230",
+ "185.94.99.231",
+ "185.94.99.232",
+ "185.94.99.233",
+ "185.94.99.234",
+ "185.94.99.235",
+ "185.94.99.236",
+ "185.94.99.237",
+ "185.94.99.238",
+ "185.94.99.239",
+ "185.94.99.240",
+ "185.94.99.241",
+ "185.94.99.243",
+ "185.94.99.244",
+ "185.94.99.246",
+ "185.94.99.247",
+ "185.94.99.248",
+ "185.94.99.249",
+ "185.94.99.250",
+ "185.94.99.251",
+ "185.94.99.253",
+ "185.94.99.254",
+ "185.95.152.11",
+ "185.95.152.12",
+ "185.95.152.155",
+ "185.95.154.130",
+ "185.95.155.164",
+ "185.95.155.167",
+ "185.95.180.131",
+ "185.95.180.230",
+ "185.97.116.107",
+ "185.97.116.131",
+ "185.97.116.166",
+ "185.97.116.180",
+ "185.97.116.204",
+ "185.97.116.205",
+ "185.97.117.54",
+ "185.97.117.66",
+ "185.97.117.159",
+ "185.97.118.139",
+ "185.97.119.4",
+ "185.97.119.111",
+ "185.98.113.34",
+ "185.98.113.113",
+ "185.98.113.115",
+ "185.98.113.141",
+ "185.98.113.142",
+ "185.98.114.114",
+ "185.98.114.116",
+ "185.100.45.85",
+ "185.100.47.7",
+ "185.100.47.8",
+ "185.100.47.11",
+ "185.100.47.16",
+ "185.100.47.82",
+ "185.103.129.109",
+ "185.103.129.113",
+ "185.103.130.201",
+ "185.103.130.202",
+ "185.103.201.147",
+ "185.103.250.250",
+ "185.104.243.9",
+ "185.105.101.58",
+ "185.105.121.10",
+ "185.105.121.11",
+ "185.105.184.40",
+ "185.105.184.41",
+ "185.105.184.42",
+ "185.105.184.52",
+ "185.105.184.53",
+ "185.105.184.70",
+ "185.105.184.76",
+ "185.105.184.89",
+ "185.105.184.91",
+ "185.105.184.108",
+ "185.105.184.121",
+ "185.105.184.205",
+ "185.105.184.206",
+ "185.105.184.227",
+ "185.105.185.25",
+ "185.105.185.28",
+ "185.105.185.36",
+ "185.105.185.41",
+ "185.105.185.149",
+ "185.105.185.151",
+ "185.105.185.155",
+ "185.105.187.14",
+ "185.105.187.160",
+ "185.105.187.186",
+ "185.105.187.189",
+ "185.105.187.226",
+ "185.105.187.242",
+ "185.105.187.243",
+ "185.105.237.96",
+ "185.105.237.252",
+ "185.105.237.253",
+ "185.105.238.196",
+ "185.105.238.200",
+ "185.105.238.210",
+ "185.105.238.253",
+ "185.105.239.10",
+ "185.105.239.11",
+ "185.105.239.29",
+ "185.105.239.50",
+ "185.105.239.68",
+ "185.105.239.78",
+ "185.105.239.79",
+ "185.105.239.97",
+ "185.105.239.102",
+ "185.105.239.104",
+ "185.105.239.107",
+ "185.105.239.115",
+ "185.105.239.119",
+ "185.105.239.123",
+ "185.105.239.129",
+ "185.105.239.132",
+ "185.105.239.139",
+ "185.105.239.141",
+ "185.105.239.169",
+ "185.105.239.172",
+ "185.105.239.175",
+ "185.105.239.178",
+ "185.105.239.187",
+ "185.105.239.189",
+ "185.105.239.191",
+ "185.105.239.194",
+ "185.105.239.198",
+ "185.105.239.201",
+ "185.105.239.208",
+ "185.105.239.211",
+ "185.105.239.214",
+ "185.105.239.216",
+ "185.105.239.217",
+ "185.105.239.220",
+ "185.105.239.231",
+ "185.105.239.232",
+ "185.105.239.236",
+ "185.106.144.149",
+ "185.106.146.179",
+ "185.106.146.180",
+ "185.107.32.115",
+ "185.107.32.117",
+ "185.107.32.120",
+ "185.107.32.122",
+ "185.109.61.27",
+ "185.109.75.241",
+ "185.109.75.242",
+ "185.109.80.137",
+ "185.109.82.15",
+ "185.109.244.91",
+ "185.109.244.94",
+ "185.109.250.245",
+ "185.110.29.251",
+ "185.110.219.23",
+ "185.110.219.139",
+ "185.110.236.10",
+ "185.110.236.120",
+ "185.110.236.122",
+ "185.110.244.7",
+ "185.110.244.23",
+ "185.110.244.98",
+ "185.110.244.105",
+ "185.110.244.112",
+ "185.110.244.120",
+ "185.110.244.150",
+ "185.110.244.151",
+ "185.110.245.16",
+ "185.110.245.19",
+ "185.110.245.26",
+ "185.110.245.30",
+ "185.110.245.83",
+ "185.110.245.94",
+ "185.110.245.100",
+ "185.110.245.140",
+ "185.110.245.178",
+ "185.110.245.187",
+ "185.110.245.197",
+ "185.110.245.213",
+ "185.110.247.9",
+ "185.110.247.11",
+ "185.110.247.16",
+ "185.110.247.63",
+ "185.110.247.72",
+ "185.110.247.93",
+ "185.110.247.101",
+ "185.110.247.110",
+ "185.110.247.118",
+ "185.110.247.154",
+ "185.110.247.179",
+ "185.110.247.195",
+ "185.110.247.213",
+ "185.110.253.2",
+ "185.111.83.58",
+ "185.112.32.43",
+ "185.112.32.45",
+ "185.112.32.52",
+ "185.112.32.56",
+ "185.112.32.62",
+ "185.112.32.212",
+ "185.112.33.51",
+ "185.112.33.54",
+ "185.112.33.60",
+ "185.112.33.107",
+ "185.112.33.110",
+ "185.112.33.219",
+ "185.112.33.220",
+ "185.112.33.221",
+ "185.112.33.222",
+ "185.112.34.83",
+ "185.112.34.92",
+ "185.112.34.139",
+ "185.112.34.181",
+ "185.112.34.235",
+ "185.112.34.236",
+ "185.112.35.2",
+ "185.112.35.20",
+ "185.112.35.38",
+ "185.112.35.194",
+ "185.112.35.195",
+ "185.112.35.196",
+ "185.112.35.197",
+ "185.112.39.18",
+ "185.112.39.33",
+ "185.112.39.112",
+ "185.112.149.98",
+ "185.112.149.116",
+ "185.112.149.117",
+ "185.112.149.119",
+ "185.112.150.7",
+ "185.112.150.13",
+ "185.112.150.54",
+ "185.112.150.55",
+ "185.112.150.56",
+ "185.112.150.92",
+ "185.112.150.134",
+ "185.112.150.149",
+ "185.112.150.204",
+ "185.112.150.242",
+ "185.112.150.246",
+ "185.112.151.97",
+ "185.112.151.198",
+ "185.112.151.213",
+ "185.112.151.214",
+ "185.112.151.231",
+ "185.112.151.232",
+ "185.112.151.249",
+ "185.112.151.254",
+ "185.113.9.3",
+ "185.113.9.5",
+ "185.113.9.6",
+ "185.113.9.7",
+ "185.113.9.9",
+ "185.113.9.10",
+ "185.113.9.13",
+ "185.113.9.16",
+ "185.113.9.18",
+ "185.113.9.20",
+ "185.113.9.22",
+ "185.113.9.24",
+ "185.113.9.33",
+ "185.113.9.34",
+ "185.113.9.35",
+ "185.113.9.37",
+ "185.113.9.38",
+ "185.113.9.43",
+ "185.113.9.44",
+ "185.113.9.45",
+ "185.113.9.46",
+ "185.113.9.47",
+ "185.113.9.48",
+ "185.113.9.49",
+ "185.113.9.50",
+ "185.113.9.52",
+ "185.113.9.53",
+ "185.113.9.54",
+ "185.113.9.55",
+ "185.113.9.57",
+ "185.113.9.61",
+ "185.113.9.65",
+ "185.113.9.66",
+ "185.113.9.68",
+ "185.113.9.71",
+ "185.113.9.73",
+ "185.113.9.74",
+ "185.113.9.75",
+ "185.113.9.76",
+ "185.113.9.77",
+ "185.113.9.80",
+ "185.113.9.82",
+ "185.113.9.86",
+ "185.113.9.87",
+ "185.113.9.88",
+ "185.113.9.90",
+ "185.113.9.91",
+ "185.113.9.92",
+ "185.113.9.94",
+ "185.113.9.97",
+ "185.113.9.102",
+ "185.113.9.106",
+ "185.113.9.108",
+ "185.113.9.110",
+ "185.113.9.111",
+ "185.113.9.118",
+ "185.113.9.120",
+ "185.113.9.122",
+ "185.113.9.123",
+ "185.113.9.125",
+ "185.113.9.133",
+ "185.113.9.135",
+ "185.113.9.144",
+ "185.113.9.151",
+ "185.113.9.157",
+ "185.113.9.162",
+ "185.113.9.163",
+ "185.113.9.165",
+ "185.113.9.170",
+ "185.113.9.171",
+ "185.113.9.172",
+ "185.113.9.173",
+ "185.113.9.174",
+ "185.113.9.176",
+ "185.113.9.178",
+ "185.113.9.181",
+ "185.113.9.186",
+ "185.113.9.189",
+ "185.113.9.190",
+ "185.113.9.194",
+ "185.113.9.196",
+ "185.113.9.197",
+ "185.113.9.205",
+ "185.113.9.210",
+ "185.113.9.213",
+ "185.113.9.214",
+ "185.113.9.215",
+ "185.113.9.216",
+ "185.113.9.220",
+ "185.113.9.222",
+ "185.113.9.225",
+ "185.113.9.226",
+ "185.113.9.229",
+ "185.113.9.231",
+ "185.113.9.236",
+ "185.113.9.237",
+ "185.113.9.238",
+ "185.113.9.239",
+ "185.113.9.241",
+ "185.113.9.242",
+ "185.113.9.245",
+ "185.113.9.251",
+ "185.113.56.68",
+ "185.113.56.123",
+ "185.113.56.124",
+ "185.113.56.126",
+ "185.113.59.131",
+ "185.113.59.181",
+ "185.113.115.23",
+ "185.113.115.33",
+ "185.113.115.34",
+ "185.114.188.20",
+ "185.114.188.34",
+ "185.115.168.163",
+ "185.116.20.54",
+ "185.116.23.23",
+ "185.116.24.2",
+ "185.116.24.100",
+ "185.116.112.12",
+ "185.116.160.10",
+ "185.116.160.18",
+ "185.116.160.19",
+ "185.116.160.22",
+ "185.116.160.26",
+ "185.116.160.27",
+ "185.116.160.28",
+ "185.116.160.32",
+ "185.116.160.38",
+ "185.116.160.39",
+ "185.116.160.41",
+ "185.116.160.44",
+ "185.116.160.51",
+ "185.116.160.55",
+ "185.116.160.68",
+ "185.116.160.83",
+ "185.116.160.91",
+ "185.116.160.107",
+ "185.116.160.110",
+ "185.116.160.111",
+ "185.116.160.113",
+ "185.116.160.121",
+ "185.116.160.130",
+ "185.116.160.132",
+ "185.116.160.139",
+ "185.116.160.140",
+ "185.116.160.141",
+ "185.116.160.142",
+ "185.116.160.154",
+ "185.116.160.233",
+ "185.116.161.5",
+ "185.116.161.7",
+ "185.116.161.15",
+ "185.116.161.24",
+ "185.116.161.32",
+ "185.116.161.34",
+ "185.116.161.39",
+ "185.116.161.42",
+ "185.116.161.49",
+ "185.116.161.59",
+ "185.116.161.60",
+ "185.116.161.61",
+ "185.116.161.67",
+ "185.116.161.80",
+ "185.116.161.87",
+ "185.116.161.89",
+ "185.116.161.90",
+ "185.116.161.93",
+ "185.116.161.94",
+ "185.116.161.95",
+ "185.116.161.96",
+ "185.116.161.98",
+ "185.116.161.99",
+ "185.116.161.103",
+ "185.116.161.105",
+ "185.116.161.106",
+ "185.116.161.109",
+ "185.116.161.116",
+ "185.116.161.125",
+ "185.116.161.126",
+ "185.116.161.135",
+ "185.116.161.156",
+ "185.116.161.157",
+ "185.116.161.167",
+ "185.116.161.184",
+ "185.116.161.230",
+ "185.116.161.231",
+ "185.116.161.232",
+ "185.116.161.248",
+ "185.116.162.11",
+ "185.116.162.16",
+ "185.116.162.20",
+ "185.116.162.22",
+ "185.116.162.23",
+ "185.116.162.24",
+ "185.116.163.1",
+ "185.116.163.2",
+ "185.116.163.4",
+ "185.116.163.6",
+ "185.116.163.12",
+ "185.116.163.14",
+ "185.116.163.16",
+ "185.116.163.18",
+ "185.116.163.19",
+ "185.116.163.20",
+ "185.116.163.21",
+ "185.116.163.24",
+ "185.116.163.27",
+ "185.116.163.31",
+ "185.116.163.43",
+ "185.116.163.46",
+ "185.116.163.49",
+ "185.116.163.56",
+ "185.116.163.61",
+ "185.116.163.63",
+ "185.116.163.64",
+ "185.116.163.69",
+ "185.116.163.73",
+ "185.116.163.78",
+ "185.116.163.101",
+ "185.116.163.102",
+ "185.116.163.103",
+ "185.116.163.115",
+ "185.116.163.117",
+ "185.116.163.123",
+ "185.116.163.144",
+ "185.116.163.149",
+ "185.116.163.150",
+ "185.116.163.161",
+ "185.116.163.180",
+ "185.116.163.184",
+ "185.116.163.186",
+ "185.116.163.204",
+ "185.116.163.215",
+ "185.116.163.225",
+ "185.117.139.47",
+ "185.117.139.77",
+ "185.118.14.244",
+ "185.118.152.195",
+ "185.118.152.197",
+ "185.119.4.216",
+ "185.119.5.15",
+ "185.119.5.16",
+ "185.119.241.241",
+ "185.120.160.3",
+ "185.120.160.4",
+ "185.120.160.5",
+ "185.120.160.6",
+ "185.120.162.76",
+ "185.120.168.30",
+ "185.120.201.133",
+ "185.120.201.141",
+ "185.120.217.242",
+ "185.120.220.29",
+ "185.120.220.75",
+ "185.120.220.76",
+ "185.120.220.77",
+ "185.120.220.110",
+ "185.120.220.114",
+ "185.120.220.139",
+ "185.120.220.164",
+ "185.120.220.166",
+ "185.120.220.179",
+ "185.120.220.180",
+ "185.120.220.181",
+ "185.120.220.182",
+ "185.120.220.188",
+ "185.120.220.200",
+ "185.120.221.44",
+ "185.120.221.46",
+ "185.120.221.106",
+ "185.120.221.108",
+ "185.120.221.110",
+ "185.120.221.195",
+ "185.120.221.244",
+ "185.120.221.247",
+ "185.120.221.248",
+ "185.120.221.250",
+ "185.120.221.252",
+ "185.120.221.253",
+ "185.120.221.254",
+ "185.120.222.106",
+ "185.120.222.107",
+ "185.120.222.108",
+ "185.120.222.109",
+ "185.120.222.110",
+ "185.120.222.132",
+ "185.120.222.133",
+ "185.120.222.135",
+ "185.120.222.137",
+ "185.120.222.140",
+ "185.120.222.141",
+ "185.120.222.142",
+ "185.120.222.144",
+ "185.120.222.146",
+ "185.120.222.147",
+ "185.120.222.148",
+ "185.120.222.149",
+ "185.120.222.151",
+ "185.120.222.152",
+ "185.120.222.153",
+ "185.120.222.154",
+ "185.120.222.155",
+ "185.120.222.156",
+ "185.120.222.157",
+ "185.120.222.158",
+ "185.120.222.159",
+ "185.120.222.160",
+ "185.120.222.162",
+ "185.120.222.163",
+ "185.120.222.164",
+ "185.120.222.167",
+ "185.120.222.168",
+ "185.120.222.169",
+ "185.120.222.171",
+ "185.120.222.172",
+ "185.120.222.173",
+ "185.120.222.175",
+ "185.120.222.177",
+ "185.120.222.178",
+ "185.120.222.179",
+ "185.120.222.180",
+ "185.120.222.181",
+ "185.120.222.182",
+ "185.120.222.183",
+ "185.120.222.186",
+ "185.120.222.187",
+ "185.120.222.188",
+ "185.120.222.190",
+ "185.120.222.191",
+ "185.120.222.192",
+ "185.120.222.193",
+ "185.120.222.194",
+ "185.120.222.195",
+ "185.120.222.196",
+ "185.120.222.197",
+ "185.120.222.199",
+ "185.120.222.200",
+ "185.120.222.201",
+ "185.120.222.202",
+ "185.120.222.203",
+ "185.120.222.205",
+ "185.120.222.207",
+ "185.120.222.208",
+ "185.120.222.210",
+ "185.120.222.212",
+ "185.120.222.213",
+ "185.120.222.214",
+ "185.120.222.215",
+ "185.120.222.216",
+ "185.120.222.220",
+ "185.120.222.221",
+ "185.120.222.222",
+ "185.120.222.223",
+ "185.120.222.224",
+ "185.120.222.225",
+ "185.120.222.226",
+ "185.120.222.227",
+ "185.120.222.228",
+ "185.120.222.236",
+ "185.120.222.237",
+ "185.120.222.238",
+ "185.120.222.240",
+ "185.120.222.241",
+ "185.120.222.243",
+ "185.120.222.244",
+ "185.120.222.246",
+ "185.120.222.249",
+ "185.120.222.250",
+ "185.120.222.252",
+ "185.120.239.45",
+ "185.120.248.116",
+ "185.120.250.9",
+ "185.121.130.187",
+ "185.122.80.68",
+ "185.122.81.4",
+ "185.123.68.2",
+ "185.123.68.36",
+ "185.124.112.19",
+ "185.124.112.25",
+ "185.124.115.18",
+ "185.124.157.91",
+ "185.124.172.8",
+ "185.124.172.9",
+ "185.124.174.19",
+ "185.126.2.239",
+ "185.126.3.244",
+ "185.126.4.18",
+ "185.126.4.52",
+ "185.126.4.53",
+ "185.126.4.54",
+ "185.126.4.55",
+ "185.126.4.59",
+ "185.126.4.61",
+ "185.126.4.70",
+ "185.126.4.104",
+ "185.126.4.130",
+ "185.126.4.133",
+ "185.126.4.134",
+ "185.126.4.135",
+ "185.126.4.222",
+ "185.126.5.50",
+ "185.126.5.62",
+ "185.126.6.204",
+ "185.126.6.206",
+ "185.126.6.219",
+ "185.126.6.220",
+ "185.126.6.234",
+ "185.126.6.235",
+ "185.126.7.6",
+ "185.126.7.7",
+ "185.126.7.8",
+ "185.126.7.18",
+ "185.126.7.20",
+ "185.126.8.35",
+ "185.126.8.52",
+ "185.126.8.58",
+ "185.126.8.77",
+ "185.126.8.158",
+ "185.126.8.234",
+ "185.126.9.181",
+ "185.126.9.188",
+ "185.126.9.189",
+ "185.126.10.58",
+ "185.126.10.100",
+ "185.126.10.130",
+ "185.126.10.131",
+ "185.126.10.133",
+ "185.126.10.135",
+ "185.126.10.139",
+ "185.126.10.141",
+ "185.126.10.182",
+ "185.126.10.220",
+ "185.126.10.221",
+ "185.126.10.222",
+ "185.126.11.84",
+ "185.126.11.130",
+ "185.126.11.131",
+ "185.126.11.132",
+ "185.126.11.133",
+ "185.126.11.135",
+ "185.126.11.142",
+ "185.126.11.211",
+ "185.126.11.212",
+ "185.126.11.213",
+ "185.126.11.219",
+ "185.126.11.221",
+ "185.126.14.11",
+ "185.126.14.12",
+ "185.126.14.20",
+ "185.126.14.21",
+ "185.126.14.99",
+ "185.126.14.100",
+ "185.126.14.139",
+ "185.126.14.210",
+ "185.126.14.243",
+ "185.126.14.246",
+ "185.126.14.248",
+ "185.126.15.215",
+ "185.126.16.27",
+ "185.126.16.55",
+ "185.126.40.242",
+ "185.126.133.37",
+ "185.126.200.14",
+ "185.126.200.21",
+ "185.126.200.32",
+ "185.126.200.39",
+ "185.126.200.45",
+ "185.126.200.65",
+ "185.126.200.127",
+ "185.126.200.159",
+ "185.126.200.200",
+ "185.126.200.212",
+ "185.126.201.29",
+ "185.126.201.183",
+ "185.126.201.198",
+ "185.126.201.246",
+ "185.126.202.44",
+ "185.126.202.52",
+ "185.126.202.62",
+ "185.126.202.99",
+ "185.126.202.100",
+ "185.126.202.110",
+ "185.126.202.120",
+ "185.126.202.122",
+ "185.126.202.124",
+ "185.126.202.156",
+ "185.126.202.175",
+ "185.126.202.235",
+ "185.126.202.236",
+ "185.126.202.247",
+ "185.126.203.22",
+ "185.126.203.23",
+ "185.126.203.24",
+ "185.126.203.61",
+ "185.126.203.103",
+ "185.126.203.147",
+ "185.126.203.148",
+ "185.126.203.150",
+ "185.126.203.178",
+ "185.126.203.210",
+ "185.126.203.211",
+ "185.126.203.252",
+ "185.128.80.27",
+ "185.128.80.28",
+ "185.128.80.30",
+ "185.128.80.33",
+ "185.128.80.34",
+ "185.128.80.35",
+ "185.128.80.39",
+ "185.128.80.40",
+ "185.128.80.41",
+ "185.128.80.42",
+ "185.128.80.46",
+ "185.128.80.48",
+ "185.128.80.50",
+ "185.128.80.53",
+ "185.128.80.65",
+ "185.128.80.79",
+ "185.128.80.81",
+ "185.128.81.35",
+ "185.128.81.37",
+ "185.128.81.45",
+ "185.128.81.60",
+ "185.128.81.70",
+ "185.128.81.78",
+ "185.128.81.80",
+ "185.128.81.90",
+ "185.128.81.95",
+ "185.128.81.100",
+ "185.128.81.101",
+ "185.128.81.120",
+ "185.128.81.125",
+ "185.128.81.130",
+ "185.128.81.135",
+ "185.128.81.140",
+ "185.128.81.155",
+ "185.128.81.160",
+ "185.128.81.193",
+ "185.128.81.220",
+ "185.128.82.5",
+ "185.128.82.90",
+ "185.128.83.10",
+ "185.128.136.7",
+ "185.128.136.48",
+ "185.128.136.49",
+ "185.128.136.60",
+ "185.128.136.163",
+ "185.128.136.167",
+ "185.128.136.169",
+ "185.128.136.185",
+ "185.128.136.186",
+ "185.128.136.188",
+ "185.128.137.154",
+ "185.128.137.187",
+ "185.128.137.192",
+ "185.128.137.193",
+ "185.128.137.212",
+ "185.128.138.1",
+ "185.128.138.13",
+ "185.128.138.14",
+ "185.128.138.129",
+ "185.128.138.130",
+ "185.128.138.132",
+ "185.128.138.142",
+ "185.128.138.172",
+ "185.128.138.174",
+ "185.128.138.196",
+ "185.128.138.199",
+ "185.128.138.206",
+ "185.128.138.214",
+ "185.128.138.218",
+ "185.128.138.249",
+ "185.128.138.250",
+ "185.128.138.251",
+ "185.128.139.26",
+ "185.128.139.29",
+ "185.128.139.45",
+ "185.128.139.48",
+ "185.128.139.57",
+ "185.128.139.61",
+ "185.128.139.65",
+ "185.128.139.84",
+ "185.128.139.116",
+ "185.128.139.119",
+ "185.128.139.149",
+ "185.128.139.168",
+ "185.128.139.188",
+ "185.128.139.194",
+ "185.128.139.216",
+ "185.128.139.222",
+ "185.129.83.20",
+ "185.129.83.32",
+ "185.129.116.109",
+ "185.129.116.115",
+ "185.129.116.147",
+ "185.129.116.242",
+ "185.129.117.204",
+ "185.129.118.51",
+ "185.129.118.62",
+ "185.129.118.72",
+ "185.129.118.125",
+ "185.129.118.207",
+ "185.129.119.12",
+ "185.129.119.36",
+ "185.129.119.55",
+ "185.129.119.59",
+ "185.129.119.105",
+ "185.129.119.202",
+ "185.129.119.210",
+ "185.129.168.15",
+ "185.129.168.16",
+ "185.129.168.27",
+ "185.129.168.28",
+ "185.129.168.31",
+ "185.129.168.35",
+ "185.129.168.50",
+ "185.129.168.51",
+ "185.129.168.53",
+ "185.129.168.60",
+ "185.129.168.62",
+ "185.129.168.65",
+ "185.129.168.68",
+ "185.129.168.72",
+ "185.129.168.75",
+ "185.129.168.81",
+ "185.129.168.85",
+ "185.129.168.86",
+ "185.129.168.90",
+ "185.129.168.97",
+ "185.129.168.99",
+ "185.129.168.104",
+ "185.129.168.114",
+ "185.129.168.120",
+ "185.129.168.125",
+ "185.129.168.128",
+ "185.129.168.132",
+ "185.129.168.133",
+ "185.129.168.139",
+ "185.129.168.143",
+ "185.129.168.144",
+ "185.129.168.148",
+ "185.129.168.188",
+ "185.129.168.191",
+ "185.129.168.192",
+ "185.129.168.194",
+ "185.129.168.217",
+ "185.129.168.220",
+ "185.129.168.229",
+ "185.129.168.232",
+ "185.129.168.233",
+ "185.129.168.241",
+ "185.129.168.249",
+ "185.129.168.250",
+ "185.129.168.251",
+ "185.129.168.253",
+ "185.129.169.21",
+ "185.129.169.22",
+ "185.129.169.25",
+ "185.129.169.26",
+ "185.129.169.27",
+ "185.129.169.35",
+ "185.129.169.37",
+ "185.129.169.40",
+ "185.129.169.44",
+ "185.129.169.49",
+ "185.129.169.53",
+ "185.129.169.65",
+ "185.129.169.71",
+ "185.129.169.76",
+ "185.129.169.79",
+ "185.129.169.84",
+ "185.129.169.88",
+ "185.129.169.89",
+ "185.129.169.107",
+ "185.129.169.109",
+ "185.129.169.110",
+ "185.129.169.111",
+ "185.129.169.112",
+ "185.129.169.121",
+ "185.129.169.125",
+ "185.129.169.130",
+ "185.129.169.136",
+ "185.129.169.138",
+ "185.129.169.145",
+ "185.129.169.147",
+ "185.129.169.149",
+ "185.129.169.156",
+ "185.129.169.163",
+ "185.129.169.175",
+ "185.129.169.187",
+ "185.129.169.196",
+ "185.129.169.198",
+ "185.129.169.199",
+ "185.129.169.206",
+ "185.129.169.208",
+ "185.129.169.209",
+ "185.129.169.210",
+ "185.129.169.212",
+ "185.129.169.231",
+ "185.129.169.238",
+ "185.129.169.240",
+ "185.129.169.241",
+ "185.129.169.243",
+ "185.129.169.244",
+ "185.129.169.245",
+ "185.129.169.247",
+ "185.129.169.248",
+ "185.129.169.250",
+ "185.129.169.251",
+ "185.129.169.253",
+ "185.129.170.31",
+ "185.129.170.46",
+ "185.129.170.75",
+ "185.129.170.77",
+ "185.129.170.89",
+ "185.129.170.90",
+ "185.129.170.100",
+ "185.129.170.116",
+ "185.129.170.138",
+ "185.129.170.150",
+ "185.129.171.10",
+ "185.129.171.15",
+ "185.129.171.22",
+ "185.129.171.56",
+ "185.129.171.57",
+ "185.129.171.61",
+ "185.129.171.75",
+ "185.129.171.80",
+ "185.129.171.83",
+ "185.129.171.89",
+ "185.129.171.93",
+ "185.129.171.102",
+ "185.129.171.117",
+ "185.129.171.127",
+ "185.129.197.4",
+ "185.129.203.240",
+ "185.129.230.35",
+ "185.130.50.5",
+ "185.130.50.6",
+ "185.130.50.7",
+ "185.130.50.8",
+ "185.130.50.9",
+ "185.130.50.10",
+ "185.130.50.15",
+ "185.130.50.19",
+ "185.130.50.37",
+ "185.130.50.38",
+ "185.130.50.39",
+ "185.130.50.40",
+ "185.130.50.41",
+ "185.130.50.42",
+ "185.130.50.43",
+ "185.130.50.44",
+ "185.130.50.45",
+ "185.130.50.46",
+ "185.130.50.47",
+ "185.130.50.50",
+ "185.130.50.51",
+ "185.130.50.63",
+ "185.130.50.64",
+ "185.130.50.65",
+ "185.130.50.66",
+ "185.130.50.68",
+ "185.130.50.69",
+ "185.130.50.70",
+ "185.130.50.71",
+ "185.130.50.72",
+ "185.130.50.77",
+ "185.130.50.78",
+ "185.130.50.80",
+ "185.130.50.81",
+ "185.130.50.83",
+ "185.130.50.84",
+ "185.130.50.85",
+ "185.130.50.89",
+ "185.130.50.91",
+ "185.130.50.93",
+ "185.130.50.97",
+ "185.130.50.99",
+ "185.130.50.100",
+ "185.130.50.101",
+ "185.130.50.109",
+ "185.130.50.110",
+ "185.130.50.112",
+ "185.130.50.115",
+ "185.130.50.116",
+ "185.130.50.117",
+ "185.130.50.118",
+ "185.130.50.119",
+ "185.130.50.133",
+ "185.130.50.139",
+ "185.130.50.140",
+ "185.130.50.143",
+ "185.130.50.144",
+ "185.130.50.146",
+ "185.130.50.149",
+ "185.130.50.150",
+ "185.130.50.160",
+ "185.130.50.166",
+ "185.130.50.169",
+ "185.130.50.171",
+ "185.130.50.180",
+ "185.130.50.184",
+ "185.130.50.188",
+ "185.130.50.192",
+ "185.130.50.201",
+ "185.130.50.222",
+ "185.130.50.224",
+ "185.130.50.233",
+ "185.130.50.239",
+ "185.130.50.242",
+ "185.130.50.251",
+ "185.130.76.2",
+ "185.130.76.4",
+ "185.130.76.72",
+ "185.130.76.74",
+ "185.130.78.123",
+ "185.130.78.142",
+ "185.130.79.21",
+ "185.130.79.253",
+ "185.131.28.254",
+ "185.131.92.31",
+ "185.131.116.150",
+ "185.131.116.173",
+ "185.132.124.53",
+ "185.132.124.198",
+ "185.132.124.199",
+ "185.132.212.29",
+ "185.132.212.129",
+ "185.132.212.130",
+ "185.132.212.135",
+ "185.132.212.136",
+ "185.132.213.19",
+ "185.132.213.61",
+ "185.132.213.62",
+ "185.132.213.63",
+ "185.132.213.64",
+ "185.134.97.210",
+ "185.135.47.10",
+ "185.135.47.11",
+ "185.135.47.12",
+ "185.135.47.13",
+ "185.135.47.14",
+ "185.135.47.15",
+ "185.135.47.16",
+ "185.135.47.17",
+ "185.135.47.18",
+ "185.135.47.21",
+ "185.135.47.22",
+ "185.135.47.23",
+ "185.135.47.24",
+ "185.135.47.25",
+ "185.135.47.30",
+ "185.135.47.52",
+ "185.135.47.57",
+ "185.135.47.60",
+ "185.135.47.61",
+ "185.135.47.64",
+ "185.135.47.74",
+ "185.135.47.107",
+ "185.135.47.108",
+ "185.135.47.120",
+ "185.136.133.72",
+ "185.136.180.2",
+ "185.136.181.99",
+ "185.136.181.105",
+ "185.136.181.197",
+ "185.137.24.10",
+ "185.137.24.18",
+ "185.137.24.83",
+ "185.137.24.100",
+ "185.137.24.165",
+ "185.137.24.202",
+ "185.137.24.206",
+ "185.137.24.245",
+ "185.137.25.41",
+ "185.137.25.72",
+ "185.137.25.74",
+ "185.137.25.78",
+ "185.137.25.79",
+ "185.137.25.102",
+ "185.137.25.146",
+ "185.137.25.213",
+ "185.137.25.214",
+ "185.137.25.215",
+ "185.137.25.216",
+ "185.137.25.223",
+ "185.137.25.234",
+ "185.137.26.14",
+ "185.137.26.50",
+ "185.137.26.58",
+ "185.137.26.165",
+ "185.137.26.184",
+ "185.137.26.185",
+ "185.137.26.186",
+ "185.137.26.189",
+ "185.137.26.190",
+ "185.137.26.197",
+ "185.137.26.227",
+ "185.137.26.237",
+ "185.137.26.243",
+ "185.137.26.244",
+ "185.137.27.3",
+ "185.137.27.4",
+ "185.137.27.22",
+ "185.137.27.27",
+ "185.137.27.40",
+ "185.137.27.42",
+ "185.137.27.43",
+ "185.137.27.44",
+ "185.137.27.45",
+ "185.137.27.46",
+ "185.137.27.86",
+ "185.137.27.138",
+ "185.137.27.164",
+ "185.137.27.179",
+ "185.137.27.188",
+ "185.137.27.217",
+ "185.137.27.227",
+ "185.139.64.9",
+ "185.139.64.21",
+ "185.140.4.4",
+ "185.140.4.5",
+ "185.140.5.127",
+ "185.140.5.232",
+ "185.140.5.244",
+ "185.140.240.238",
+ "185.141.36.54",
+ "185.141.36.82",
+ "185.141.48.53",
+ "185.141.48.54",
+ "185.141.104.69",
+ "185.141.104.107",
+ "185.141.104.118",
+ "185.141.104.126",
+ "185.141.104.136",
+ "185.141.104.141",
+ "185.141.104.142",
+ "185.141.104.211",
+ "185.141.104.242",
+ "185.141.105.27",
+ "185.141.105.100",
+ "185.141.105.105",
+ "185.141.105.107",
+ "185.141.105.109",
+ "185.141.105.113",
+ "185.141.105.119",
+ "185.141.105.138",
+ "185.141.105.139",
+ "185.141.105.217",
+ "185.141.105.230",
+ "185.141.105.232",
+ "185.141.105.233",
+ "185.141.106.39",
+ "185.141.106.64",
+ "185.141.106.68",
+ "185.141.106.71",
+ "185.141.106.82",
+ "185.141.106.84",
+ "185.141.106.117",
+ "185.141.106.121",
+ "185.141.106.126",
+ "185.141.106.149",
+ "185.141.106.150",
+ "185.141.106.153",
+ "185.141.106.154",
+ "185.141.106.169",
+ "185.141.106.225",
+ "185.141.106.228",
+ "185.141.106.230",
+ "185.141.106.231",
+ "185.141.106.232",
+ "185.141.106.238",
+ "185.141.106.240",
+ "185.141.106.243",
+ "185.141.107.17",
+ "185.141.107.27",
+ "185.141.107.38",
+ "185.141.107.50",
+ "185.141.107.51",
+ "185.141.107.163",
+ "185.141.107.197",
+ "185.141.107.228",
+ "185.141.107.244",
+ "185.141.132.11",
+ "185.141.132.23",
+ "185.141.132.44",
+ "185.141.132.45",
+ "185.141.132.46",
+ "185.141.132.47",
+ "185.141.132.60",
+ "185.141.132.89",
+ "185.141.132.92",
+ "185.141.132.95",
+ "185.141.132.127",
+ "185.141.132.216",
+ "185.141.132.218",
+ "185.141.133.3",
+ "185.141.133.5",
+ "185.141.133.6",
+ "185.141.133.18",
+ "185.141.133.19",
+ "185.141.133.28",
+ "185.141.133.50",
+ "185.141.133.66",
+ "185.141.133.67",
+ "185.141.133.76",
+ "185.141.133.120",
+ "185.141.133.145",
+ "185.141.133.216",
+ "185.141.133.217",
+ "185.141.133.218",
+ "185.141.134.49",
+ "185.141.134.64",
+ "185.141.134.68",
+ "185.141.134.74",
+ "185.141.134.77",
+ "185.141.134.88",
+ "185.141.134.93",
+ "185.141.134.114",
+ "185.141.134.151",
+ "185.141.134.191",
+ "185.141.134.206",
+ "185.141.134.221",
+ "185.141.135.113",
+ "185.141.135.115",
+ "185.141.168.117",
+ "185.141.168.122",
+ "185.141.168.123",
+ "185.141.168.124",
+ "185.141.168.130",
+ "185.141.168.133",
+ "185.141.168.134",
+ "185.141.168.135",
+ "185.141.168.136",
+ "185.141.168.137",
+ "185.141.168.138",
+ "185.141.168.139",
+ "185.141.168.140",
+ "185.141.168.141",
+ "185.141.169.42",
+ "185.141.169.155",
+ "185.141.169.220",
+ "185.141.169.226",
+ "185.141.169.227",
+ "185.141.169.228",
+ "185.141.169.229",
+ "185.141.169.230",
+ "185.141.169.231",
+ "185.141.169.232",
+ "185.141.169.234",
+ "185.141.169.235",
+ "185.141.169.236",
+ "185.141.169.237",
+ "185.141.169.238",
+ "185.141.169.239",
+ "185.141.169.241",
+ "185.141.169.242",
+ "185.141.169.243",
+ "185.141.169.244",
+ "185.141.169.245",
+ "185.141.169.246",
+ "185.141.169.247",
+ "185.141.170.2",
+ "185.141.170.74",
+ "185.141.170.99",
+ "185.141.170.132",
+ "185.141.170.195",
+ "185.141.171.30",
+ "185.141.212.11",
+ "185.141.212.139",
+ "185.141.212.140",
+ "185.141.212.141",
+ "185.141.212.142",
+ "185.141.212.170",
+ "185.141.212.171",
+ "185.141.212.172",
+ "185.141.212.173",
+ "185.141.212.174",
+ "185.141.213.4",
+ "185.141.213.5",
+ "185.141.213.12",
+ "185.141.213.61",
+ "185.141.213.133",
+ "185.141.213.166",
+ "185.141.213.167",
+ "185.141.213.172",
+ "185.141.213.180",
+ "185.141.213.181",
+ "185.141.213.244",
+ "185.141.213.248",
+ "185.141.213.249",
+ "185.141.213.250",
+ "185.141.213.251",
+ "185.141.214.71",
+ "185.142.95.68",
+ "185.142.95.69",
+ "185.142.156.11",
+ "185.142.156.12",
+ "185.142.156.85",
+ "185.142.156.214",
+ "185.142.156.227",
+ "185.142.156.235",
+ "185.142.157.5",
+ "185.142.157.12",
+ "185.142.157.29",
+ "185.142.157.37",
+ "185.142.157.39",
+ "185.142.157.53",
+ "185.142.157.75",
+ "185.142.157.81",
+ "185.142.157.95",
+ "185.142.157.96",
+ "185.142.157.119",
+ "185.142.157.120",
+ "185.142.157.121",
+ "185.142.157.123",
+ "185.142.157.124",
+ "185.142.157.151",
+ "185.142.157.168",
+ "185.142.157.231",
+ "185.142.157.246",
+ "185.142.157.251",
+ "185.142.158.28",
+ "185.142.158.98",
+ "185.142.158.99",
+ "185.142.158.140",
+ "185.142.158.141",
+ "185.142.158.162",
+ "185.142.159.172",
+ "185.142.159.195",
+ "185.142.159.210",
+ "185.142.159.212",
+ "185.142.159.229",
+ "185.142.159.230",
+ "185.142.159.232",
+ "185.142.159.234",
+ "185.142.159.235",
+ "185.142.159.243",
+ "185.142.159.251",
+ "185.143.207.131",
+ "185.143.207.246",
+ "185.143.232.253",
+ "185.143.233.253",
+ "185.143.234.253",
+ "185.143.235.253",
+ "185.144.65.6",
+ "185.145.11.246",
+ "185.145.186.32",
+ "185.145.186.130",
+ "185.147.40.115",
+ "185.147.40.160",
+ "185.147.84.105",
+ "185.147.85.105",
+ "185.147.160.21",
+ "185.147.160.22",
+ "185.147.160.107",
+ "185.147.160.109",
+ "185.147.161.170",
+ "185.147.162.26",
+ "185.147.162.68",
+ "185.147.162.130",
+ "185.147.162.132",
+ "185.147.162.195",
+ "185.147.163.46",
+ "185.147.163.62",
+ "185.147.163.168",
+ "185.147.163.169",
+ "185.147.163.196",
+ "185.147.163.202",
+ "185.147.176.189",
+ "185.147.176.221",
+ "185.147.177.111",
+ "185.147.177.112",
+ "185.147.177.113",
+ "185.147.177.224",
+ "185.147.177.232",
+ "185.149.192.18",
+ "185.149.192.28",
+ "185.149.192.30",
+ "185.149.192.32",
+ "185.149.192.33",
+ "185.149.192.47",
+ "185.149.192.54",
+ "185.149.192.132",
+ "185.149.192.133",
+ "185.149.192.134",
+ "185.149.192.150",
+ "185.149.192.155",
+ "185.149.192.218",
+ "185.153.208.77",
+ "185.155.9.40",
+ "185.155.14.130",
+ "185.155.15.140",
+ "185.155.236.2",
+ "185.155.236.3",
+ "185.155.236.4",
+ "185.158.172.3",
+ "185.158.173.8",
+ "185.158.173.165",
+ "185.159.153.2",
+ "185.159.153.3",
+ "185.159.153.5",
+ "185.159.153.6",
+ "185.159.153.10",
+ "185.159.153.12",
+ "185.159.153.13",
+ "185.159.153.15",
+ "185.159.153.16",
+ "185.159.153.17",
+ "185.159.153.19",
+ "185.159.153.20",
+ "185.159.153.21",
+ "185.159.153.23",
+ "185.159.153.24",
+ "185.159.153.25",
+ "185.159.153.26",
+ "185.159.153.27",
+ "185.159.153.29",
+ "185.159.153.30",
+ "185.159.153.31",
+ "185.159.153.32",
+ "185.159.153.33",
+ "185.159.153.34",
+ "185.159.153.35",
+ "185.159.153.36",
+ "185.159.153.38",
+ "185.159.153.39",
+ "185.159.153.40",
+ "185.159.153.42",
+ "185.159.153.44",
+ "185.159.153.45",
+ "185.159.153.46",
+ "185.159.153.47",
+ "185.159.153.48",
+ "185.159.153.50",
+ "185.159.153.51",
+ "185.159.153.52",
+ "185.159.153.53",
+ "185.159.153.54",
+ "185.159.153.55",
+ "185.159.153.56",
+ "185.159.153.57",
+ "185.159.153.58",
+ "185.159.153.59",
+ "185.159.153.60",
+ "185.159.153.61",
+ "185.159.153.64",
+ "185.159.153.66",
+ "185.159.153.67",
+ "185.159.153.68",
+ "185.159.153.69",
+ "185.159.153.70",
+ "185.159.153.71",
+ "185.159.153.72",
+ "185.159.153.73",
+ "185.159.153.74",
+ "185.159.153.75",
+ "185.159.153.77",
+ "185.159.153.78",
+ "185.159.153.79",
+ "185.159.153.80",
+ "185.159.153.81",
+ "185.159.153.82",
+ "185.159.153.83",
+ "185.159.153.84",
+ "185.159.153.85",
+ "185.159.153.86",
+ "185.159.153.87",
+ "185.159.153.88",
+ "185.159.153.89",
+ "185.159.153.90",
+ "185.159.153.91",
+ "185.159.153.92",
+ "185.159.153.93",
+ "185.159.153.98",
+ "185.159.153.99",
+ "185.159.153.100",
+ "185.159.153.102",
+ "185.159.153.103",
+ "185.159.153.104",
+ "185.159.153.105",
+ "185.159.153.106",
+ "185.159.153.108",
+ "185.159.153.110",
+ "185.159.153.111",
+ "185.159.153.112",
+ "185.159.153.113",
+ "185.159.153.114",
+ "185.159.153.115",
+ "185.159.153.116",
+ "185.159.153.119",
+ "185.159.153.120",
+ "185.159.153.121",
+ "185.159.153.122",
+ "185.159.153.123",
+ "185.159.153.124",
+ "185.159.153.125",
+ "185.159.153.126",
+ "185.159.153.127",
+ "185.159.153.128",
+ "185.159.153.129",
+ "185.159.153.131",
+ "185.159.153.132",
+ "185.159.153.133",
+ "185.159.153.134",
+ "185.159.153.135",
+ "185.159.153.136",
+ "185.159.153.137",
+ "185.159.153.140",
+ "185.159.153.141",
+ "185.159.153.142",
+ "185.159.153.145",
+ "185.159.153.147",
+ "185.159.153.148",
+ "185.159.153.149",
+ "185.159.153.150",
+ "185.159.153.151",
+ "185.159.153.152",
+ "185.159.153.153",
+ "185.159.153.154",
+ "185.159.153.156",
+ "185.159.153.157",
+ "185.159.153.158",
+ "185.159.153.159",
+ "185.159.153.160",
+ "185.159.153.161",
+ "185.159.153.162",
+ "185.159.153.163",
+ "185.159.153.165",
+ "185.159.153.166",
+ "185.159.153.171",
+ "185.159.153.172",
+ "185.159.153.174",
+ "185.159.153.175",
+ "185.159.153.176",
+ "185.159.153.177",
+ "185.159.153.186",
+ "185.159.153.187",
+ "185.159.153.189",
+ "185.159.153.191",
+ "185.159.153.193",
+ "185.159.153.194",
+ "185.159.153.196",
+ "185.159.153.199",
+ "185.159.153.200",
+ "185.159.153.201",
+ "185.159.153.202",
+ "185.159.153.203",
+ "185.159.153.204",
+ "185.159.153.205",
+ "185.159.153.207",
+ "185.159.153.208",
+ "185.159.153.211",
+ "185.159.153.214",
+ "185.159.153.216",
+ "185.159.153.218",
+ "185.159.153.219",
+ "185.159.153.220",
+ "185.159.153.226",
+ "185.159.153.227",
+ "185.159.153.228",
+ "185.159.153.235",
+ "185.159.153.253",
+ "185.159.154.2",
+ "185.159.154.3",
+ "185.159.154.4",
+ "185.159.154.5",
+ "185.159.154.7",
+ "185.159.154.9",
+ "185.159.154.10",
+ "185.159.154.14",
+ "185.159.154.16",
+ "185.159.154.17",
+ "185.159.154.19",
+ "185.159.154.20",
+ "185.159.154.21",
+ "185.159.154.22",
+ "185.159.154.23",
+ "185.159.154.25",
+ "185.159.154.26",
+ "185.159.154.27",
+ "185.159.154.28",
+ "185.159.154.29",
+ "185.159.154.30",
+ "185.159.154.31",
+ "185.159.154.32",
+ "185.159.154.33",
+ "185.159.154.34",
+ "185.159.154.35",
+ "185.159.154.36",
+ "185.159.154.37",
+ "185.159.154.38",
+ "185.159.154.39",
+ "185.159.154.40",
+ "185.159.154.41",
+ "185.159.154.42",
+ "185.159.154.43",
+ "185.159.154.44",
+ "185.159.154.45",
+ "185.159.154.46",
+ "185.159.154.47",
+ "185.159.154.48",
+ "185.159.154.49",
+ "185.159.154.50",
+ "185.159.154.51",
+ "185.159.154.52",
+ "185.159.154.53",
+ "185.159.154.54",
+ "185.159.154.55",
+ "185.159.154.56",
+ "185.159.154.57",
+ "185.159.154.61",
+ "185.159.154.63",
+ "185.159.154.64",
+ "185.159.154.65",
+ "185.159.154.66",
+ "185.159.154.67",
+ "185.159.154.68",
+ "185.159.154.69",
+ "185.159.154.70",
+ "185.159.154.71",
+ "185.159.154.72",
+ "185.159.154.73",
+ "185.159.154.74",
+ "185.159.154.75",
+ "185.159.154.79",
+ "185.159.154.81",
+ "185.159.154.82",
+ "185.159.154.84",
+ "185.159.154.85",
+ "185.159.154.86",
+ "185.159.154.87",
+ "185.159.154.88",
+ "185.159.154.89",
+ "185.159.154.90",
+ "185.159.154.91",
+ "185.159.154.92",
+ "185.159.154.93",
+ "185.159.154.94",
+ "185.159.154.98",
+ "185.159.154.99",
+ "185.159.154.100",
+ "185.159.154.102",
+ "185.159.154.104",
+ "185.159.154.105",
+ "185.159.154.106",
+ "185.159.154.107",
+ "185.159.154.108",
+ "185.159.154.109",
+ "185.159.154.111",
+ "185.159.154.114",
+ "185.159.154.115",
+ "185.159.154.118",
+ "185.159.154.120",
+ "185.159.154.124",
+ "185.159.154.125",
+ "185.159.154.127",
+ "185.159.154.128",
+ "185.159.154.130",
+ "185.159.154.132",
+ "185.159.154.133",
+ "185.159.154.134",
+ "185.159.154.137",
+ "185.159.154.143",
+ "185.159.154.147",
+ "185.159.154.149",
+ "185.159.154.150",
+ "185.159.154.151",
+ "185.159.154.152",
+ "185.159.154.153",
+ "185.159.154.154",
+ "185.159.154.157",
+ "185.159.154.159",
+ "185.159.154.161",
+ "185.159.154.162",
+ "185.159.154.163",
+ "185.159.154.164",
+ "185.159.154.165",
+ "185.159.154.167",
+ "185.159.154.168",
+ "185.159.154.169",
+ "185.159.154.170",
+ "185.159.154.171",
+ "185.159.154.172",
+ "185.159.154.173",
+ "185.159.154.177",
+ "185.159.154.178",
+ "185.159.154.179",
+ "185.159.154.180",
+ "185.159.154.181",
+ "185.159.154.188",
+ "185.159.154.189",
+ "185.159.154.190",
+ "185.159.154.191",
+ "185.159.154.192",
+ "185.159.154.197",
+ "185.159.154.198",
+ "185.159.154.199",
+ "185.159.154.200",
+ "185.159.154.201",
+ "185.159.154.202",
+ "185.159.154.204",
+ "185.159.154.207",
+ "185.159.154.208",
+ "185.159.154.209",
+ "185.159.154.210",
+ "185.159.154.211",
+ "185.159.154.212",
+ "185.159.154.213",
+ "185.159.154.214",
+ "185.159.154.215",
+ "185.159.154.219",
+ "185.159.154.221",
+ "185.159.154.222",
+ "185.159.154.224",
+ "185.159.154.225",
+ "185.159.154.226",
+ "185.159.154.227",
+ "185.159.154.228",
+ "185.159.154.242",
+ "185.159.154.245",
+ "185.159.154.249",
+ "185.159.154.250",
+ "185.159.154.251",
+ "185.159.154.252",
+ "185.159.154.253",
+ "185.159.155.2",
+ "185.159.155.3",
+ "185.159.179.1",
+ "185.159.179.2",
+ "185.159.179.71",
+ "185.159.179.72",
+ "185.159.179.74",
+ "185.159.179.75",
+ "185.159.179.80",
+ "185.160.104.84",
+ "185.160.105.54",
+ "185.160.205.18",
+ "185.161.39.242",
+ "185.161.112.33",
+ "185.161.112.34",
+ "185.161.112.35",
+ "185.161.112.247",
+ "185.161.113.253",
+ "185.161.121.152",
+ "185.164.72.4",
+ "185.164.72.5",
+ "185.164.72.7",
+ "185.164.72.10",
+ "185.164.72.14",
+ "185.164.72.18",
+ "185.164.72.23",
+ "185.164.72.24",
+ "185.164.72.25",
+ "185.164.72.27",
+ "185.164.72.36",
+ "185.164.72.44",
+ "185.164.72.46",
+ "185.164.72.53",
+ "185.164.72.56",
+ "185.164.72.62",
+ "185.164.72.70",
+ "185.164.72.71",
+ "185.164.72.72",
+ "185.164.72.77",
+ "185.164.72.82",
+ "185.164.72.83",
+ "185.164.72.85",
+ "185.164.72.89",
+ "185.164.72.92",
+ "185.164.72.97",
+ "185.164.72.99",
+ "185.164.72.107",
+ "185.164.72.108",
+ "185.164.72.118",
+ "185.164.72.119",
+ "185.164.72.128",
+ "185.164.72.131",
+ "185.164.72.135",
+ "185.164.72.140",
+ "185.164.72.142",
+ "185.164.72.149",
+ "185.164.72.157",
+ "185.164.72.160",
+ "185.164.72.170",
+ "185.164.72.173",
+ "185.164.72.174",
+ "185.164.72.179",
+ "185.164.72.185",
+ "185.164.72.194",
+ "185.164.72.195",
+ "185.164.72.199",
+ "185.164.72.215",
+ "185.164.72.219",
+ "185.164.72.225",
+ "185.164.72.227",
+ "185.164.72.237",
+ "185.164.72.249",
+ "185.164.72.252",
+ "185.164.73.9",
+ "185.164.73.14",
+ "185.164.73.18",
+ "185.164.73.21",
+ "185.164.73.22",
+ "185.164.73.30",
+ "185.164.73.34",
+ "185.164.73.38",
+ "185.164.73.47",
+ "185.164.73.49",
+ "185.164.73.53",
+ "185.164.73.57",
+ "185.164.73.64",
+ "185.164.73.65",
+ "185.164.73.73",
+ "185.164.73.75",
+ "185.164.73.76",
+ "185.164.73.81",
+ "185.164.73.87",
+ "185.164.73.94",
+ "185.164.73.103",
+ "185.164.73.104",
+ "185.164.73.108",
+ "185.164.73.109",
+ "185.164.73.115",
+ "185.164.73.119",
+ "185.164.73.121",
+ "185.164.73.123",
+ "185.164.73.125",
+ "185.164.73.133",
+ "185.164.73.135",
+ "185.164.73.140",
+ "185.164.73.141",
+ "185.164.73.152",
+ "185.164.73.158",
+ "185.164.73.160",
+ "185.164.73.164",
+ "185.164.73.168",
+ "185.164.73.171",
+ "185.164.73.174",
+ "185.164.73.177",
+ "185.164.73.180",
+ "185.164.73.187",
+ "185.164.73.190",
+ "185.164.73.191",
+ "185.164.73.205",
+ "185.164.73.224",
+ "185.164.73.229",
+ "185.164.73.243",
+ "185.164.253.26",
+ "185.165.28.12",
+ "185.165.28.33",
+ "185.165.28.34",
+ "185.165.28.251",
+ "185.165.28.252",
+ "185.165.29.17",
+ "185.165.29.28",
+ "185.165.29.33",
+ "185.165.29.50",
+ "185.165.29.65",
+ "185.165.29.128",
+ "185.165.29.136",
+ "185.165.29.175",
+ "185.165.29.176",
+ "185.165.29.177",
+ "185.165.29.179",
+ "185.165.29.182",
+ "185.165.29.186",
+ "185.165.29.189",
+ "185.165.29.194",
+ "185.165.29.206",
+ "185.165.29.211",
+ "185.165.29.220",
+ "185.165.29.223",
+ "185.165.29.240",
+ "185.165.29.242",
+ "185.165.29.247",
+ "185.165.30.93",
+ "185.165.30.94",
+ "185.165.116.1",
+ "185.165.116.13",
+ "185.165.116.19",
+ "185.165.116.20",
+ "185.165.116.21",
+ "185.165.116.22",
+ "185.165.116.23",
+ "185.165.116.24",
+ "185.165.116.26",
+ "185.165.116.30",
+ "185.165.116.31",
+ "185.165.116.32",
+ "185.165.116.34",
+ "185.165.116.36",
+ "185.165.116.41",
+ "185.165.116.43",
+ "185.165.116.47",
+ "185.165.116.49",
+ "185.165.116.52",
+ "185.165.116.57",
+ "185.165.116.58",
+ "185.165.116.60",
+ "185.165.116.62",
+ "185.165.116.63",
+ "185.165.116.66",
+ "185.165.116.72",
+ "185.165.116.75",
+ "185.165.116.79",
+ "185.165.116.80",
+ "185.165.116.85",
+ "185.165.116.90",
+ "185.165.116.93",
+ "185.165.116.102",
+ "185.165.116.116",
+ "185.165.116.133",
+ "185.165.116.134",
+ "185.165.116.135",
+ "185.165.116.136",
+ "185.165.116.139",
+ "185.165.116.140",
+ "185.165.116.144",
+ "185.165.116.145",
+ "185.165.116.149",
+ "185.165.116.152",
+ "185.165.116.155",
+ "185.165.116.156",
+ "185.165.116.158",
+ "185.165.116.159",
+ "185.165.116.161",
+ "185.165.116.164",
+ "185.165.116.168",
+ "185.165.116.173",
+ "185.165.116.182",
+ "185.165.116.195",
+ "185.165.116.196",
+ "185.165.116.198",
+ "185.165.116.202",
+ "185.165.116.204",
+ "185.165.116.210",
+ "185.165.116.213",
+ "185.165.116.214",
+ "185.165.116.219",
+ "185.165.116.235",
+ "185.165.116.253",
+ "185.165.117.1",
+ "185.165.117.11",
+ "185.165.117.120",
+ "185.165.117.244",
+ "185.165.118.1",
+ "185.165.118.35",
+ "185.165.118.49",
+ "185.165.118.51",
+ "185.165.118.58",
+ "185.165.118.59",
+ "185.165.118.72",
+ "185.165.118.74",
+ "185.165.118.80",
+ "185.165.118.92",
+ "185.165.118.98",
+ "185.165.118.138",
+ "185.165.118.193",
+ "185.165.118.195",
+ "185.165.118.197",
+ "185.165.118.201",
+ "185.165.118.205",
+ "185.165.118.210",
+ "185.165.118.211",
+ "185.165.118.215",
+ "185.165.118.216",
+ "185.165.118.224",
+ "185.165.118.227",
+ "185.165.118.228",
+ "185.165.118.235",
+ "185.165.118.237",
+ "185.165.119.1",
+ "185.165.119.59",
+ "185.165.119.60",
+ "185.165.119.63",
+ "185.166.63.43",
+ "185.166.104.53",
+ "185.166.104.54",
+ "185.167.73.25",
+ "185.167.75.25",
+ "185.167.124.244",
+ "185.169.6.18",
+ "185.169.6.44",
+ "185.169.6.58",
+ "185.169.6.94",
+ "185.169.6.106",
+ "185.169.6.146",
+ "185.169.6.154",
+ "185.169.6.166",
+ "185.169.6.174",
+ "185.169.6.194",
+ "185.169.6.196",
+ "185.169.6.211",
+ "185.169.6.226",
+ "185.169.20.106",
+ "185.169.20.107",
+ "185.169.21.62",
+ "185.170.8.5",
+ "185.170.8.11",
+ "185.170.8.195",
+ "185.170.8.236",
+ "185.170.8.241",
+ "185.170.8.248",
+ "185.170.8.254",
+ "185.170.236.26",
+ "185.170.236.27",
+ "185.170.236.28",
+ "185.170.236.30",
+ "185.171.53.3",
+ "185.171.53.4",
+ "185.171.53.57",
+ "185.171.53.58",
+ "185.171.53.60",
+ "185.171.53.61",
+ "185.171.53.62",
+ "185.171.53.66",
+ "185.171.53.70",
+ "185.171.53.75",
+ "185.171.53.149",
+ "185.171.53.158",
+ "185.171.53.163",
+ "185.171.53.164",
+ "185.171.53.171",
+ "185.171.53.174",
+ "185.171.53.186",
+ "185.172.212.26",
+ "185.172.212.210",
+ "185.172.213.2",
+ "185.172.213.3",
+ "185.172.213.4",
+ "185.172.213.5",
+ "185.172.213.6",
+ "185.172.213.7",
+ "185.172.213.51",
+ "185.173.104.18",
+ "185.173.104.41",
+ "185.173.104.44",
+ "185.173.104.46",
+ "185.173.104.48",
+ "185.173.104.50",
+ "185.173.104.59",
+ "185.173.104.68",
+ "185.173.104.72",
+ "185.173.104.74",
+ "185.173.104.78",
+ "185.173.104.81",
+ "185.173.104.83",
+ "185.173.104.87",
+ "185.173.104.88",
+ "185.173.104.90",
+ "185.173.104.95",
+ "185.173.104.102",
+ "185.173.104.107",
+ "185.173.104.119",
+ "185.173.104.129",
+ "185.173.104.134",
+ "185.173.104.141",
+ "185.173.104.146",
+ "185.173.104.148",
+ "185.173.104.151",
+ "185.173.104.152",
+ "185.173.104.167",
+ "185.173.104.177",
+ "185.173.104.179",
+ "185.173.104.181",
+ "185.173.104.202",
+ "185.173.104.206",
+ "185.173.104.207",
+ "185.173.104.211",
+ "185.173.104.228",
+ "185.173.104.229",
+ "185.173.104.230",
+ "185.173.104.235",
+ "185.173.104.238",
+ "185.173.104.246",
+ "185.173.105.6",
+ "185.173.105.22",
+ "185.173.105.26",
+ "185.173.105.122",
+ "185.173.105.126",
+ "185.173.105.134",
+ "185.173.105.154",
+ "185.173.105.170",
+ "185.173.105.210",
+ "185.173.105.211",
+ "185.173.105.218",
+ "185.173.105.219",
+ "185.173.105.221",
+ "185.173.106.22",
+ "185.173.106.32",
+ "185.173.106.54",
+ "185.173.106.56",
+ "185.173.106.90",
+ "185.173.106.105",
+ "185.173.106.109",
+ "185.173.106.155",
+ "185.173.106.164",
+ "185.173.106.171",
+ "185.173.106.172",
+ "185.173.106.177",
+ "185.173.106.188",
+ "185.173.106.196",
+ "185.173.106.199",
+ "185.173.106.200",
+ "185.173.106.207",
+ "185.173.106.238",
+ "185.173.106.239",
+ "185.173.107.40",
+ "185.173.107.68",
+ "185.173.107.125",
+ "185.173.107.154",
+ "185.173.107.158",
+ "185.173.107.171",
+ "185.173.107.179",
+ "185.173.107.207",
+ "185.173.107.212",
+ "185.173.129.48",
+ "185.173.129.137",
+ "185.173.129.143",
+ "185.173.129.200",
+ "185.173.129.208",
+ "185.173.130.100",
+ "185.173.130.149",
+ "185.173.130.160",
+ "185.173.130.249",
+ "185.173.168.3",
+ "185.173.168.14",
+ "185.173.168.18",
+ "185.173.168.57",
+ "185.173.168.59",
+ "185.173.168.107",
+ "185.173.168.175",
+ "185.173.168.183",
+ "185.173.168.185",
+ "185.173.168.209",
+ "185.173.168.210",
+ "185.173.168.244",
+ "185.173.168.245",
+ "185.173.168.246",
+ "185.173.168.247",
+ "185.173.168.248",
+ "185.173.168.249",
+ "185.173.168.252",
+ "185.173.168.254",
+ "185.173.169.169",
+ "185.173.169.254",
+ "185.173.170.11",
+ "185.173.171.251",
+ "185.173.171.252",
+ "185.173.171.253",
+ "185.173.171.254",
+ "185.174.250.20",
+ "185.174.250.51",
+ "185.174.250.52",
+ "185.174.251.22",
+ "185.175.76.140",
+ "185.176.58.58",
+ "185.177.158.4",
+ "185.178.220.15",
+ "185.178.220.55",
+ "185.179.90.10",
+ "185.179.90.54",
+ "185.179.90.61",
+ "185.179.90.66",
+ "185.179.90.75",
+ "185.179.90.125",
+ "185.179.90.130",
+ "185.179.90.150",
+ "185.179.90.179",
+ "185.179.90.227",
+ "185.179.168.9",
+ "185.179.168.12",
+ "185.179.168.24",
+ "185.179.168.30",
+ "185.179.168.50",
+ "185.179.168.51",
+ "185.179.168.56",
+ "185.179.168.168",
+ "185.179.169.13",
+ "185.179.169.90",
+ "185.179.171.127",
+ "185.179.220.9",
+ "185.180.128.92",
+ "185.180.129.219",
+ "185.181.180.14",
+ "185.181.180.54",
+ "185.181.180.62",
+ "185.181.180.116",
+ "185.181.180.119",
+ "185.181.180.120",
+ "185.181.180.122",
+ "185.181.180.123",
+ "185.181.180.130",
+ "185.181.180.156",
+ "185.181.180.205",
+ "185.181.180.206",
+ "185.181.180.208",
+ "185.181.180.209",
+ "185.181.180.222",
+ "185.181.180.237",
+ "185.181.180.244",
+ "185.181.181.2",
+ "185.181.181.5",
+ "185.181.181.9",
+ "185.181.181.30",
+ "185.181.181.85",
+ "185.181.181.87",
+ "185.181.181.88",
+ "185.181.181.166",
+ "185.181.181.183",
+ "185.181.181.187",
+ "185.181.181.188",
+ "185.181.182.15",
+ "185.181.182.17",
+ "185.181.182.52",
+ "185.181.182.64",
+ "185.181.182.75",
+ "185.181.182.84",
+ "185.181.182.85",
+ "185.181.182.88",
+ "185.181.182.91",
+ "185.181.182.95",
+ "185.181.182.102",
+ "185.181.182.107",
+ "185.181.182.128",
+ "185.181.182.133",
+ "185.181.182.157",
+ "185.181.182.161",
+ "185.181.182.173",
+ "185.181.182.177",
+ "185.181.182.178",
+ "185.181.182.190",
+ "185.181.182.202",
+ "185.181.182.206",
+ "185.181.182.224",
+ "185.181.182.230",
+ "185.181.183.25",
+ "185.181.183.38",
+ "185.181.183.47",
+ "185.181.183.56",
+ "185.181.183.58",
+ "185.181.183.87",
+ "185.181.183.94",
+ "185.181.183.109",
+ "185.181.183.111",
+ "185.181.183.112",
+ "185.181.183.114",
+ "185.181.183.125",
+ "185.181.183.144",
+ "185.181.183.145",
+ "185.181.183.157",
+ "185.181.183.166",
+ "185.182.222.85",
+ "185.182.222.219",
+ "185.185.16.116",
+ "185.185.240.4",
+ "185.186.50.44",
+ "185.186.50.67",
+ "185.186.50.108",
+ "185.186.50.124",
+ "185.186.50.130",
+ "185.186.50.243",
+ "185.186.50.245",
+ "185.186.50.247",
+ "185.186.51.10",
+ "185.186.51.115",
+ "185.186.51.243",
+ "185.186.240.240",
+ "185.186.241.3",
+ "185.186.241.8",
+ "185.186.241.10",
+ "185.186.241.133",
+ "185.186.242.21",
+ "185.186.242.135",
+ "185.186.242.141",
+ "185.186.242.157",
+ "185.186.243.250",
+ "185.187.48.3",
+ "185.187.50.4",
+ "185.187.50.37",
+ "185.187.50.40",
+ "185.187.51.250",
+ "185.187.86.5",
+ "185.187.86.10",
+ "185.188.104.10",
+ "185.188.104.11",
+ "185.188.104.12",
+ "185.188.104.13",
+ "185.188.105.10",
+ "185.188.105.11",
+ "185.188.105.12",
+ "185.188.106.10",
+ "185.188.106.11",
+ "185.190.39.7",
+ "185.190.39.18",
+ "185.190.39.27",
+ "185.190.39.31",
+ "185.190.39.34",
+ "185.190.39.40",
+ "185.190.39.46",
+ "185.190.39.63",
+ "185.190.39.69",
+ "185.190.39.75",
+ "185.190.39.85",
+ "185.190.39.91",
+ "185.190.39.93",
+ "185.190.39.103",
+ "185.190.39.113",
+ "185.190.39.120",
+ "185.190.39.133",
+ "185.190.39.137",
+ "185.190.39.143",
+ "185.190.39.145",
+ "185.190.39.148",
+ "185.190.39.154",
+ "185.190.39.159",
+ "185.190.39.166",
+ "185.190.39.172",
+ "185.190.39.176",
+ "185.190.39.179",
+ "185.190.39.189",
+ "185.190.39.193",
+ "185.190.39.195",
+ "185.190.39.213",
+ "185.190.39.222",
+ "185.190.39.225",
+ "185.190.39.227",
+ "185.190.39.231",
+ "185.190.39.232",
+ "185.190.39.235",
+ "185.190.39.241",
+ "185.190.39.251",
+ "185.191.76.3",
+ "185.191.76.5",
+ "185.191.76.8",
+ "185.191.76.9",
+ "185.191.76.10",
+ "185.191.76.11",
+ "185.191.76.12",
+ "185.191.76.13",
+ "185.191.76.19",
+ "185.191.76.27",
+ "185.191.76.30",
+ "185.191.76.84",
+ "185.191.76.142",
+ "185.191.76.147",
+ "185.191.76.148",
+ "185.191.76.149",
+ "185.191.76.150",
+ "185.191.76.163",
+ "185.191.76.210",
+ "185.191.77.50",
+ "185.191.77.54",
+ "185.191.77.122",
+ "185.191.77.138",
+ "185.191.77.142",
+ "185.191.77.197",
+ "185.191.77.210",
+ "185.191.77.221",
+ "185.191.77.229",
+ "185.191.77.235",
+ "185.191.77.236",
+ "185.191.77.237",
+ "185.191.77.241",
+ "185.191.77.244",
+ "185.191.77.245",
+ "185.191.77.249",
+ "185.191.77.250",
+ "185.191.77.251",
+ "185.191.77.252",
+ "185.191.78.22",
+ "185.191.78.74",
+ "185.191.78.187",
+ "185.191.78.214",
+ "185.191.78.226",
+ "185.191.78.227",
+ "185.191.78.228",
+ "185.191.78.231",
+ "185.191.79.8",
+ "185.191.79.10",
+ "185.191.79.13",
+ "185.191.79.14",
+ "185.191.79.17",
+ "185.191.79.22",
+ "185.191.79.23",
+ "185.191.79.55",
+ "185.191.79.102",
+ "185.191.79.138",
+ "185.191.79.208",
+ "185.191.79.211",
+ "185.192.10.3",
+ "185.192.112.2",
+ "185.192.112.3",
+ "185.192.112.5",
+ "185.192.112.7",
+ "185.192.112.8",
+ "185.192.112.9",
+ "185.192.112.13",
+ "185.192.112.14",
+ "185.192.112.15",
+ "185.192.112.19",
+ "185.192.112.20",
+ "185.192.112.21",
+ "185.192.112.22",
+ "185.192.112.24",
+ "185.192.112.26",
+ "185.192.112.29",
+ "185.192.112.30",
+ "185.192.112.31",
+ "185.192.112.38",
+ "185.192.112.41",
+ "185.192.112.44",
+ "185.192.112.49",
+ "185.192.112.53",
+ "185.192.112.55",
+ "185.192.112.56",
+ "185.192.112.57",
+ "185.192.112.58",
+ "185.192.112.64",
+ "185.192.112.68",
+ "185.192.112.70",
+ "185.192.112.75",
+ "185.192.112.79",
+ "185.192.112.81",
+ "185.192.112.82",
+ "185.192.112.83",
+ "185.192.112.84",
+ "185.192.112.87",
+ "185.192.112.88",
+ "185.192.112.93",
+ "185.192.112.96",
+ "185.192.112.97",
+ "185.192.112.98",
+ "185.192.112.99",
+ "185.192.112.101",
+ "185.192.112.103",
+ "185.192.112.104",
+ "185.192.112.108",
+ "185.192.112.109",
+ "185.192.112.110",
+ "185.192.112.114",
+ "185.192.112.117",
+ "185.192.112.118",
+ "185.192.112.119",
+ "185.192.112.125",
+ "185.192.112.126",
+ "185.192.112.130",
+ "185.192.112.131",
+ "185.192.112.132",
+ "185.192.112.133",
+ "185.192.112.137",
+ "185.192.112.138",
+ "185.192.112.139",
+ "185.192.112.144",
+ "185.192.112.145",
+ "185.192.112.146",
+ "185.192.112.152",
+ "185.192.112.153",
+ "185.192.112.157",
+ "185.192.112.161",
+ "185.192.112.162",
+ "185.192.112.163",
+ "185.192.112.164",
+ "185.192.112.201",
+ "185.192.112.202",
+ "185.192.112.203",
+ "185.192.112.205",
+ "185.192.112.207",
+ "185.192.112.208",
+ "185.192.112.209",
+ "185.192.112.211",
+ "185.192.112.212",
+ "185.192.112.213",
+ "185.192.112.214",
+ "185.192.112.215",
+ "185.192.112.216",
+ "185.192.112.217",
+ "185.192.112.218",
+ "185.192.112.219",
+ "185.192.112.221",
+ "185.192.112.223",
+ "185.192.112.224",
+ "185.192.112.225",
+ "185.192.112.227",
+ "185.192.112.229",
+ "185.192.112.230",
+ "185.192.112.231",
+ "185.192.112.241",
+ "185.192.112.243",
+ "185.192.112.244",
+ "185.192.112.245",
+ "185.192.112.246",
+ "185.192.112.247",
+ "185.192.112.248",
+ "185.192.112.251",
+ "185.192.112.253",
+ "185.192.112.254",
+ "185.192.113.6",
+ "185.192.113.11",
+ "185.192.113.12",
+ "185.192.113.14",
+ "185.192.113.15",
+ "185.192.113.16",
+ "185.192.113.17",
+ "185.192.113.18",
+ "185.192.113.20",
+ "185.192.113.23",
+ "185.192.113.25",
+ "185.192.113.26",
+ "185.192.113.30",
+ "185.192.113.31",
+ "185.192.113.32",
+ "185.192.113.34",
+ "185.192.113.35",
+ "185.192.113.43",
+ "185.192.113.44",
+ "185.192.113.47",
+ "185.192.113.49",
+ "185.192.113.82",
+ "185.192.113.86",
+ "185.192.113.90",
+ "185.192.113.92",
+ "185.192.113.102",
+ "185.192.113.103",
+ "185.192.113.110",
+ "185.192.113.111",
+ "185.192.113.112",
+ "185.192.113.114",
+ "185.192.113.115",
+ "185.192.113.117",
+ "185.192.113.118",
+ "185.192.113.119",
+ "185.192.113.122",
+ "185.192.113.123",
+ "185.192.113.124",
+ "185.192.113.126",
+ "185.192.113.127",
+ "185.192.113.128",
+ "185.192.113.129",
+ "185.192.113.130",
+ "185.192.113.133",
+ "185.192.113.140",
+ "185.192.113.141",
+ "185.192.113.143",
+ "185.192.113.145",
+ "185.192.113.150",
+ "185.192.113.151",
+ "185.192.113.152",
+ "185.192.113.153",
+ "185.192.113.157",
+ "185.192.113.159",
+ "185.192.113.163",
+ "185.192.113.164",
+ "185.192.113.174",
+ "185.192.113.175",
+ "185.192.113.177",
+ "185.192.113.183",
+ "185.192.113.185",
+ "185.192.113.186",
+ "185.192.113.193",
+ "185.192.113.201",
+ "185.192.113.203",
+ "185.192.113.206",
+ "185.192.113.209",
+ "185.192.113.242",
+ "185.192.113.251",
+ "185.192.113.252",
+ "185.192.114.12",
+ "185.192.114.13",
+ "185.192.114.15",
+ "185.192.114.16",
+ "185.192.114.17",
+ "185.192.114.20",
+ "185.192.114.23",
+ "185.192.114.24",
+ "185.192.114.25",
+ "185.192.114.26",
+ "185.192.114.28",
+ "185.192.114.30",
+ "185.192.114.39",
+ "185.192.114.40",
+ "185.192.114.41",
+ "185.192.114.47",
+ "185.192.114.48",
+ "185.192.114.49",
+ "185.192.114.53",
+ "185.192.114.54",
+ "185.192.114.65",
+ "185.192.114.83",
+ "185.192.114.101",
+ "185.192.114.102",
+ "185.192.114.103",
+ "185.192.114.104",
+ "185.192.114.105",
+ "185.192.114.108",
+ "185.192.114.112",
+ "185.192.114.114",
+ "185.192.114.116",
+ "185.192.114.117",
+ "185.192.114.118",
+ "185.192.114.123",
+ "185.192.114.126",
+ "185.192.114.127",
+ "185.192.114.129",
+ "185.192.114.130",
+ "185.192.114.133",
+ "185.192.114.135",
+ "185.192.114.140",
+ "185.192.114.148",
+ "185.192.114.153",
+ "185.192.114.154",
+ "185.192.114.158",
+ "185.192.114.159",
+ "185.192.114.162",
+ "185.192.114.165",
+ "185.192.114.172",
+ "185.192.114.201",
+ "185.192.114.203",
+ "185.192.114.204",
+ "185.192.114.205",
+ "185.192.114.209",
+ "185.192.114.211",
+ "185.192.114.254",
+ "185.193.47.15",
+ "185.193.47.16",
+ "185.194.79.2",
+ "185.194.79.3",
+ "185.194.79.4",
+ "185.196.148.112",
+ "185.198.160.2",
+ "185.198.160.3",
+ "185.201.49.149",
+ "185.201.49.228",
+ "185.201.50.101",
+ "185.201.50.104",
+ "185.201.50.105",
+ "185.201.50.220",
+ "185.202.59.66",
+ "185.204.197.12",
+ "185.204.197.13",
+ "185.204.197.15",
+ "185.204.197.16",
+ "185.204.197.19",
+ "185.204.197.21",
+ "185.204.197.24",
+ "185.204.197.28",
+ "185.204.197.33",
+ "185.204.197.41",
+ "185.204.197.42",
+ "185.204.197.60",
+ "185.204.197.71",
+ "185.204.197.85",
+ "185.204.197.96",
+ "185.204.197.97",
+ "185.204.197.98",
+ "185.204.197.99",
+ "185.204.197.106",
+ "185.204.197.110",
+ "185.204.197.116",
+ "185.204.197.120",
+ "185.204.197.123",
+ "185.204.197.129",
+ "185.204.197.132",
+ "185.204.197.133",
+ "185.204.197.140",
+ "185.204.197.145",
+ "185.204.197.155",
+ "185.204.197.160",
+ "185.204.197.164",
+ "185.204.197.169",
+ "185.204.197.171",
+ "185.204.197.172",
+ "185.204.197.178",
+ "185.204.197.182",
+ "185.204.197.186",
+ "185.204.197.187",
+ "185.204.197.188",
+ "185.204.197.195",
+ "185.204.197.198",
+ "185.204.197.199",
+ "185.204.197.203",
+ "185.204.197.204",
+ "185.204.197.210",
+ "185.204.197.215",
+ "185.204.197.216",
+ "185.204.197.225",
+ "185.204.197.232",
+ "185.204.197.235",
+ "185.204.197.239",
+ "185.204.197.248",
+ "185.205.203.85",
+ "185.205.203.153",
+ "185.205.203.189",
+ "185.205.203.230",
+ "185.205.203.253",
+ "185.206.92.90",
+ "185.206.92.250",
+ "185.206.92.253",
+ "185.206.93.158",
+ "185.206.93.186",
+ "185.206.93.230",
+ "185.206.94.60",
+ "185.206.94.193",
+ "185.206.95.17",
+ "185.206.95.33",
+ "185.206.95.87",
+ "185.206.95.198",
+ "185.206.229.76",
+ "185.206.229.79",
+ "185.206.229.81",
+ "185.206.229.82",
+ "185.206.229.99",
+ "185.206.229.100",
+ "185.206.229.109",
+ "185.206.229.134",
+ "185.206.229.137",
+ "185.206.229.142",
+ "185.206.229.210",
+ "185.206.231.5",
+ "185.206.238.18",
+ "185.206.238.20",
+ "185.206.238.23",
+ "185.206.238.42",
+ "185.206.238.146",
+ "185.206.238.147",
+ "185.206.238.170",
+ "185.207.72.6",
+ "185.207.73.6",
+ "185.208.77.86",
+ "185.208.78.38",
+ "185.208.78.214",
+ "185.208.79.6",
+ "185.208.79.48",
+ "185.208.79.49",
+ "185.208.79.65",
+ "185.208.79.68",
+ "185.208.79.72",
+ "185.208.79.82",
+ "185.208.79.99",
+ "185.208.79.104",
+ "185.208.79.106",
+ "185.208.79.128",
+ "185.208.79.129",
+ "185.208.79.191",
+ "185.208.79.199",
+ "185.208.79.206",
+ "185.208.79.209",
+ "185.208.79.210",
+ "185.208.79.221",
+ "185.208.79.230",
+ "185.208.79.243",
+ "185.208.149.56",
+ "185.208.149.142",
+ "185.208.174.5",
+ "185.208.174.7",
+ "185.208.174.8",
+ "185.208.174.16",
+ "185.208.174.22",
+ "185.208.174.23",
+ "185.208.174.28",
+ "185.208.174.33",
+ "185.208.174.35",
+ "185.208.174.37",
+ "185.208.174.42",
+ "185.208.174.45",
+ "185.208.174.48",
+ "185.208.174.51",
+ "185.208.174.59",
+ "185.208.174.60",
+ "185.208.174.61",
+ "185.208.174.64",
+ "185.208.174.65",
+ "185.208.174.67",
+ "185.208.174.69",
+ "185.208.174.76",
+ "185.208.174.79",
+ "185.208.174.85",
+ "185.208.174.88",
+ "185.208.174.95",
+ "185.208.174.97",
+ "185.208.174.99",
+ "185.208.174.100",
+ "185.208.174.103",
+ "185.208.174.113",
+ "185.208.174.115",
+ "185.208.174.116",
+ "185.208.174.124",
+ "185.208.174.128",
+ "185.208.174.129",
+ "185.208.174.130",
+ "185.208.174.134",
+ "185.208.174.135",
+ "185.208.174.136",
+ "185.208.174.139",
+ "185.208.174.141",
+ "185.208.174.144",
+ "185.208.174.147",
+ "185.208.174.152",
+ "185.208.174.155",
+ "185.208.174.156",
+ "185.208.174.159",
+ "185.208.174.164",
+ "185.208.174.165",
+ "185.208.174.166",
+ "185.208.174.167",
+ "185.208.174.173",
+ "185.208.174.176",
+ "185.208.174.180",
+ "185.208.174.181",
+ "185.208.174.182",
+ "185.208.174.183",
+ "185.208.174.190",
+ "185.208.174.198",
+ "185.208.174.200",
+ "185.208.174.201",
+ "185.208.174.205",
+ "185.208.174.206",
+ "185.208.174.214",
+ "185.208.174.219",
+ "185.208.174.220",
+ "185.208.174.222",
+ "185.208.174.225",
+ "185.208.174.231",
+ "185.208.174.242",
+ "185.208.174.249",
+ "185.208.174.251",
+ "185.208.175.4",
+ "185.208.175.15",
+ "185.208.175.17",
+ "185.208.175.18",
+ "185.208.175.21",
+ "185.208.175.24",
+ "185.208.175.31",
+ "185.208.175.41",
+ "185.208.175.43",
+ "185.208.175.53",
+ "185.208.175.59",
+ "185.208.175.60",
+ "185.208.175.64",
+ "185.208.175.67",
+ "185.208.175.69",
+ "185.208.175.70",
+ "185.208.175.71",
+ "185.208.175.75",
+ "185.208.175.82",
+ "185.208.175.84",
+ "185.208.175.92",
+ "185.208.175.93",
+ "185.208.175.94",
+ "185.208.175.97",
+ "185.208.175.98",
+ "185.208.175.104",
+ "185.208.175.108",
+ "185.208.175.109",
+ "185.208.175.115",
+ "185.208.175.118",
+ "185.208.175.123",
+ "185.208.175.125",
+ "185.208.175.126",
+ "185.208.175.131",
+ "185.208.175.132",
+ "185.208.175.139",
+ "185.208.175.140",
+ "185.208.175.144",
+ "185.208.175.149",
+ "185.208.175.151",
+ "185.208.175.158",
+ "185.208.175.163",
+ "185.208.175.170",
+ "185.208.175.172",
+ "185.208.175.174",
+ "185.208.175.176",
+ "185.208.175.182",
+ "185.208.175.186",
+ "185.208.175.189",
+ "185.208.175.191",
+ "185.208.175.192",
+ "185.208.175.193",
+ "185.208.175.195",
+ "185.208.175.197",
+ "185.208.175.205",
+ "185.208.175.206",
+ "185.208.175.210",
+ "185.208.175.214",
+ "185.208.175.217",
+ "185.208.175.220",
+ "185.208.175.223",
+ "185.208.175.228",
+ "185.208.175.239",
+ "185.208.175.246",
+ "185.208.175.250",
+ "185.208.175.251",
+ "185.208.180.23",
+ "185.208.180.35",
+ "185.208.180.44",
+ "185.208.180.52",
+ "185.208.180.60",
+ "185.208.180.91",
+ "185.208.180.92",
+ "185.208.180.94",
+ "185.208.180.132",
+ "185.208.180.133",
+ "185.208.180.134",
+ "185.208.180.135",
+ "185.208.180.136",
+ "185.208.180.137",
+ "185.208.180.139",
+ "185.208.180.141",
+ "185.208.180.149",
+ "185.208.180.151",
+ "185.208.180.153",
+ "185.208.180.155",
+ "185.208.180.157",
+ "185.208.180.166",
+ "185.208.180.169",
+ "185.208.180.171",
+ "185.208.180.244",
+ "185.208.180.249",
+ "185.208.180.251",
+ "185.208.180.253",
+ "185.208.181.34",
+ "185.208.181.130",
+ "185.208.181.211",
+ "185.208.181.252",
+ "185.208.181.253",
+ "185.208.181.254",
+ "185.208.182.20",
+ "185.208.182.24",
+ "185.208.182.28",
+ "185.208.182.42",
+ "185.208.182.53",
+ "185.208.182.60",
+ "185.208.182.78",
+ "185.208.182.139",
+ "185.208.182.140",
+ "185.208.182.142",
+ "185.208.182.152",
+ "185.208.182.153",
+ "185.208.182.154",
+ "185.208.182.159",
+ "185.208.182.178",
+ "185.208.182.212",
+ "185.208.182.214",
+ "185.208.182.251",
+ "185.208.182.252",
+ "185.208.183.21",
+ "185.208.183.29",
+ "185.208.183.35",
+ "185.208.183.126",
+ "185.208.183.133",
+ "185.208.183.245",
+ "185.209.42.88",
+ "185.209.42.151",
+ "185.209.42.219",
+ "185.209.42.224",
+ "185.210.200.253",
+ "185.210.200.254",
+ "185.211.56.3",
+ "185.211.56.4",
+ "185.211.56.14",
+ "185.211.56.22",
+ "185.211.56.24",
+ "185.211.56.25",
+ "185.211.56.33",
+ "185.211.56.40",
+ "185.211.56.43",
+ "185.211.56.44",
+ "185.211.56.59",
+ "185.211.56.63",
+ "185.211.56.64",
+ "185.211.56.76",
+ "185.211.56.82",
+ "185.211.56.84",
+ "185.211.56.96",
+ "185.211.56.99",
+ "185.211.56.112",
+ "185.211.56.130",
+ "185.211.56.132",
+ "185.211.56.134",
+ "185.211.56.147",
+ "185.211.56.163",
+ "185.211.56.165",
+ "185.211.56.168",
+ "185.211.56.169",
+ "185.211.56.183",
+ "185.211.56.188",
+ "185.211.56.210",
+ "185.211.56.233",
+ "185.211.56.254",
+ "185.211.57.7",
+ "185.211.57.18",
+ "185.211.57.24",
+ "185.211.57.34",
+ "185.211.57.53",
+ "185.211.57.54",
+ "185.211.57.69",
+ "185.211.57.76",
+ "185.211.57.78",
+ "185.211.57.84",
+ "185.211.57.89",
+ "185.211.57.98",
+ "185.211.57.106",
+ "185.211.57.107",
+ "185.211.57.129",
+ "185.211.57.140",
+ "185.211.57.163",
+ "185.211.57.172",
+ "185.211.57.176",
+ "185.211.57.181",
+ "185.211.57.191",
+ "185.211.57.193",
+ "185.211.57.197",
+ "185.211.57.217",
+ "185.211.57.222",
+ "185.211.58.8",
+ "185.211.58.37",
+ "185.211.58.41",
+ "185.211.58.44",
+ "185.211.58.83",
+ "185.211.58.84",
+ "185.211.58.91",
+ "185.211.58.192",
+ "185.211.58.198",
+ "185.211.58.214",
+ "185.211.58.216",
+ "185.211.58.217",
+ "185.211.58.235",
+ "185.211.58.242",
+ "185.211.58.243",
+ "185.211.59.7",
+ "185.211.59.27",
+ "185.211.59.41",
+ "185.211.59.56",
+ "185.211.59.84",
+ "185.211.59.103",
+ "185.211.59.111",
+ "185.211.59.121",
+ "185.211.59.127",
+ "185.211.59.128",
+ "185.211.59.131",
+ "185.211.59.141",
+ "185.211.59.142",
+ "185.211.59.143",
+ "185.211.59.144",
+ "185.211.59.151",
+ "185.211.59.163",
+ "185.211.59.168",
+ "185.211.59.175",
+ "185.211.59.184",
+ "185.211.59.196",
+ "185.211.59.198",
+ "185.211.59.202",
+ "185.211.59.204",
+ "185.211.59.211",
+ "185.211.59.216",
+ "185.211.59.232",
+ "185.211.88.6",
+ "185.211.89.14",
+ "185.211.90.9",
+ "185.212.51.67",
+ "185.212.51.69",
+ "185.212.51.70",
+ "185.212.51.72",
+ "185.212.51.75",
+ "185.212.51.76",
+ "185.212.51.78",
+ "185.212.51.79",
+ "185.212.51.81",
+ "185.212.51.110",
+ "185.212.51.114",
+ "185.212.51.211",
+ "185.212.51.242",
+ "185.212.194.28",
+ "185.212.194.53",
+ "185.212.194.66",
+ "185.212.194.141",
+ "185.212.194.146",
+ "185.212.194.161",
+ "185.212.195.160",
+ "185.213.8.40",
+ "185.213.9.40",
+ "185.213.10.18",
+ "185.213.10.22",
+ "185.213.10.29",
+ "185.213.10.35",
+ "185.213.10.37",
+ "185.213.10.38",
+ "185.213.10.39",
+ "185.213.10.40",
+ "185.213.10.41",
+ "185.213.10.42",
+ "185.213.10.43",
+ "185.213.10.44",
+ "185.213.10.45",
+ "185.213.10.46",
+ "185.213.10.70",
+ "185.213.10.100",
+ "185.213.10.116",
+ "185.213.10.167",
+ "185.213.10.172",
+ "185.213.10.227",
+ "185.213.10.230",
+ "185.213.10.234",
+ "185.213.10.237",
+ "185.213.11.19",
+ "185.213.11.20",
+ "185.213.11.21",
+ "185.213.11.22",
+ "185.213.11.34",
+ "185.213.11.60",
+ "185.213.11.82",
+ "185.213.11.84",
+ "185.213.11.85",
+ "185.213.11.201",
+ "185.213.11.202",
+ "185.213.11.217",
+ "185.213.164.7",
+ "185.213.164.12",
+ "185.213.164.15",
+ "185.213.164.24",
+ "185.213.164.26",
+ "185.213.164.28",
+ "185.213.164.29",
+ "185.213.164.31",
+ "185.213.164.38",
+ "185.213.164.39",
+ "185.213.164.40",
+ "185.213.164.41",
+ "185.213.164.42",
+ "185.213.164.43",
+ "185.213.164.50",
+ "185.213.164.53",
+ "185.213.164.56",
+ "185.213.164.59",
+ "185.213.164.62",
+ "185.213.164.65",
+ "185.213.164.68",
+ "185.213.164.69",
+ "185.213.164.71",
+ "185.213.164.78",
+ "185.213.164.84",
+ "185.213.164.96",
+ "185.213.164.112",
+ "185.213.164.113",
+ "185.213.164.120",
+ "185.213.164.121",
+ "185.213.164.124",
+ "185.213.164.128",
+ "185.213.164.130",
+ "185.213.164.131",
+ "185.213.164.137",
+ "185.213.164.138",
+ "185.213.164.144",
+ "185.213.164.149",
+ "185.213.164.155",
+ "185.213.164.160",
+ "185.213.164.167",
+ "185.213.164.168",
+ "185.213.164.185",
+ "185.213.164.187",
+ "185.213.164.188",
+ "185.213.164.189",
+ "185.213.164.192",
+ "185.213.164.195",
+ "185.213.164.220",
+ "185.213.164.221",
+ "185.213.164.230",
+ "185.213.164.231",
+ "185.213.164.232",
+ "185.213.164.235",
+ "185.213.164.239",
+ "185.213.164.245",
+ "185.213.164.252",
+ "185.213.165.10",
+ "185.213.165.12",
+ "185.213.165.16",
+ "185.213.165.18",
+ "185.213.165.24",
+ "185.213.165.39",
+ "185.213.165.44",
+ "185.213.165.47",
+ "185.213.165.51",
+ "185.213.165.59",
+ "185.213.165.63",
+ "185.213.165.68",
+ "185.213.165.74",
+ "185.213.165.76",
+ "185.213.165.79",
+ "185.213.165.81",
+ "185.213.165.94",
+ "185.213.165.100",
+ "185.213.165.119",
+ "185.213.165.127",
+ "185.213.165.134",
+ "185.213.165.143",
+ "185.213.165.148",
+ "185.213.165.162",
+ "185.213.165.165",
+ "185.213.165.173",
+ "185.213.165.179",
+ "185.213.165.181",
+ "185.213.165.185",
+ "185.213.165.188",
+ "185.213.165.191",
+ "185.213.165.197",
+ "185.213.165.205",
+ "185.213.165.208",
+ "185.213.165.209",
+ "185.213.165.217",
+ "185.213.165.229",
+ "185.213.165.231",
+ "185.213.165.234",
+ "185.213.165.235",
+ "185.213.165.236",
+ "185.213.165.237",
+ "185.213.195.127",
+ "185.213.195.190",
+ "185.215.125.6",
+ "185.215.126.9",
+ "185.215.126.220",
+ "185.215.154.123",
+ "185.215.229.2",
+ "185.217.6.82",
+ "185.217.6.87",
+ "185.217.6.89",
+ "185.217.6.118",
+ "185.218.139.28",
+ "185.218.139.30",
+ "185.218.139.36",
+ "185.218.139.45",
+ "185.218.139.74",
+ "185.218.139.103",
+ "185.218.139.138",
+ "185.218.139.150",
+ "185.218.139.162",
+ "185.218.139.196",
+ "185.218.139.201",
+ "185.218.139.205",
+ "185.218.139.223",
+ "185.218.139.225",
+ "185.218.139.229",
+ "185.218.139.248",
+ "185.218.139.252",
+ "185.218.139.253",
+ "185.221.239.27",
+ "185.221.239.85",
+ "185.221.239.97",
+ "185.221.239.105",
+ "185.221.239.108",
+ "185.221.239.112",
+ "185.221.239.131",
+ "185.221.239.137",
+ "185.221.239.144",
+ "185.221.239.150",
+ "185.221.239.161",
+ "185.221.239.192",
+ "185.221.239.198",
+ "185.221.239.219",
+ "185.221.239.235",
+ "185.221.239.245",
+ "185.222.163.16",
+ "185.222.163.28",
+ "185.222.163.82",
+ "185.222.163.90",
+ "185.222.163.91",
+ "185.222.163.92",
+ "185.222.163.94",
+ "185.222.163.107",
+ "185.222.163.112",
+ "185.222.163.117",
+ "185.222.163.123",
+ "185.222.163.124",
+ "185.222.163.125",
+ "185.222.163.131",
+ "185.222.163.141",
+ "185.222.163.144",
+ "185.222.163.145",
+ "185.222.163.146",
+ "185.222.163.147",
+ "185.222.163.148",
+ "185.222.163.149",
+ "185.222.163.150",
+ "185.222.163.153",
+ "185.222.163.174",
+ "185.222.163.181",
+ "185.222.163.186",
+ "185.222.163.202",
+ "185.222.163.210",
+ "185.222.182.90",
+ "185.222.183.90",
+ "185.225.80.15",
+ "185.225.80.17",
+ "185.225.80.40",
+ "185.225.80.41",
+ "185.225.80.42",
+ "185.225.80.46",
+ "185.225.80.50",
+ "185.225.80.55",
+ "185.225.80.57",
+ "185.225.80.60",
+ "185.225.80.112",
+ "185.225.80.132",
+ "185.225.80.133",
+ "185.225.80.134",
+ "185.225.80.136",
+ "185.225.80.137",
+ "185.225.82.115",
+ "185.225.83.236",
+ "185.226.117.3",
+ "185.226.117.66",
+ "185.226.117.240",
+ "185.226.118.54",
+ "185.226.118.108",
+ "185.226.118.201",
+ "185.226.119.17",
+ "185.226.119.48",
+ "185.226.134.182",
+ "185.226.141.41",
+ "185.226.141.141",
+ "185.226.143.43",
+ "185.226.143.143",
+ "185.229.28.6",
+ "185.229.28.28",
+ "185.229.28.29",
+ "185.229.28.135",
+ "185.229.28.136",
+ "185.229.28.162",
+ "185.229.28.163",
+ "185.229.29.147",
+ "185.229.29.148",
+ "185.229.29.149",
+ "185.229.29.150",
+ "185.229.133.6",
+ "185.229.133.44",
+ "185.229.204.52",
+ "185.229.204.107",
+ "185.229.204.108",
+ "185.229.204.120",
+ "185.229.204.123",
+ "185.229.204.124",
+ "185.229.204.125",
+ "185.229.204.141",
+ "185.229.204.151",
+ "185.229.204.155",
+ "185.229.204.231",
+ "185.231.65.27",
+ "185.231.112.9",
+ "185.231.112.10",
+ "185.231.112.26",
+ "185.231.112.34",
+ "185.231.112.45",
+ "185.231.112.46",
+ "185.231.112.53",
+ "185.231.112.56",
+ "185.231.112.61",
+ "185.231.112.68",
+ "185.231.112.88",
+ "185.231.112.103",
+ "185.231.112.110",
+ "185.231.112.115",
+ "185.231.112.116",
+ "185.231.112.117",
+ "185.231.112.131",
+ "185.231.112.134",
+ "185.231.112.138",
+ "185.231.112.143",
+ "185.231.112.158",
+ "185.231.112.159",
+ "185.231.112.164",
+ "185.231.112.167",
+ "185.231.112.178",
+ "185.231.112.182",
+ "185.231.112.190",
+ "185.231.112.191",
+ "185.231.112.192",
+ "185.231.112.198",
+ "185.231.112.203",
+ "185.231.112.208",
+ "185.231.112.210",
+ "185.231.112.213",
+ "185.231.112.215",
+ "185.231.112.221",
+ "185.231.112.231",
+ "185.231.112.239",
+ "185.231.112.241",
+ "185.231.112.244",
+ "185.231.113.22",
+ "185.231.114.218",
+ "185.231.115.15",
+ "185.231.115.16",
+ "185.231.115.18",
+ "185.231.115.23",
+ "185.231.115.31",
+ "185.231.115.32",
+ "185.231.115.34",
+ "185.231.115.47",
+ "185.231.115.50",
+ "185.231.115.54",
+ "185.231.115.58",
+ "185.231.115.67",
+ "185.231.115.73",
+ "185.231.115.91",
+ "185.231.115.103",
+ "185.231.115.112",
+ "185.231.115.125",
+ "185.231.115.127",
+ "185.231.115.130",
+ "185.231.115.135",
+ "185.231.115.143",
+ "185.231.115.147",
+ "185.231.115.170",
+ "185.231.115.174",
+ "185.231.115.175",
+ "185.231.115.177",
+ "185.231.115.178",
+ "185.231.115.183",
+ "185.231.115.187",
+ "185.231.115.193",
+ "185.231.115.197",
+ "185.231.115.202",
+ "185.231.115.203",
+ "185.231.115.206",
+ "185.231.115.216",
+ "185.231.115.226",
+ "185.231.115.235",
+ "185.231.115.238",
+ "185.231.115.247",
+ "185.231.115.252",
+ "185.231.180.29",
+ "185.231.180.181",
+ "185.231.180.203",
+ "185.231.180.228",
+ "185.231.181.14",
+ "185.231.181.143",
+ "185.231.181.159",
+ "185.231.181.206",
+ "185.231.181.221",
+ "185.231.182.207",
+ "185.231.182.208",
+ "185.231.183.19",
+ "185.231.183.238",
+ "185.232.154.69",
+ "185.234.192.17",
+ "185.234.195.13",
+ "185.235.136.20",
+ "185.235.196.9",
+ "185.235.196.10",
+ "185.235.196.11",
+ "185.235.196.12",
+ "185.235.196.13",
+ "185.235.196.14",
+ "185.235.196.16",
+ "185.235.196.17",
+ "185.235.196.18",
+ "185.235.196.19",
+ "185.235.196.20",
+ "185.235.196.22",
+ "185.235.196.25",
+ "185.235.196.38",
+ "185.235.196.39",
+ "185.235.196.48",
+ "185.235.196.49",
+ "185.235.196.52",
+ "185.235.196.53",
+ "185.235.196.136",
+ "185.235.196.242",
+ "185.235.196.243",
+ "185.235.196.244",
+ "185.235.196.245",
+ "185.235.197.6",
+ "185.235.197.8",
+ "185.235.197.31",
+ "185.235.197.216",
+ "185.235.198.200",
+ "185.235.245.12",
+ "185.235.245.30",
+ "185.235.245.49",
+ "185.235.245.51",
+ "185.235.245.91",
+ "185.235.245.239",
+ "185.235.245.246",
+ "185.235.245.247",
+ "185.236.36.21",
+ "185.236.37.15",
+ "185.236.37.179",
+ "185.236.37.198",
+ "185.236.38.92",
+ "185.237.84.10",
+ "185.237.84.11",
+ "185.237.85.4",
+ "185.237.85.5",
+ "185.237.85.9",
+ "185.237.85.10",
+ "185.237.85.16",
+ "185.237.85.21",
+ "185.237.85.26",
+ "185.237.85.40",
+ "185.237.85.42",
+ "185.237.85.47",
+ "185.237.85.54",
+ "185.237.85.55",
+ "185.237.85.56",
+ "185.237.85.95",
+ "185.237.85.96",
+ "185.237.85.97",
+ "185.237.85.114",
+ "185.237.85.117",
+ "185.237.85.118",
+ "185.237.85.252",
+ "185.237.87.84",
+ "185.237.87.85",
+ "185.237.87.139",
+ "185.238.140.195",
+ "185.238.143.229",
+ "185.239.0.12",
+ "185.239.0.22",
+ "185.239.0.53",
+ "185.239.0.86",
+ "185.239.0.127",
+ "185.239.0.190",
+ "185.239.0.232",
+ "185.239.0.239",
+ "185.239.0.246",
+ "185.239.1.179",
+ "185.239.2.31",
+ "185.239.3.47",
+ "185.239.3.86",
+ "185.239.3.112",
+ "185.239.3.117",
+ "185.239.3.124",
+ "185.239.3.151",
+ "185.239.3.152",
+ "185.239.3.187",
+ "185.239.3.199",
+ "185.239.3.208",
+ "185.239.3.220",
+ "185.239.3.222",
+ "185.239.3.224",
+ "185.239.3.236",
+ "185.239.104.106",
+ "185.239.105.144",
+ "185.239.106.86",
+ "185.243.48.4",
+ "185.243.48.13",
+ "185.243.48.15",
+ "185.243.48.28",
+ "185.243.48.31",
+ "185.243.48.45",
+ "185.243.48.52",
+ "185.243.48.57",
+ "185.243.48.58",
+ "185.243.48.70",
+ "185.243.48.78",
+ "185.243.48.102",
+ "185.243.48.109",
+ "185.243.48.126",
+ "185.243.48.127",
+ "185.243.48.131",
+ "185.243.48.132",
+ "185.243.48.134",
+ "185.243.48.135",
+ "185.243.48.140",
+ "185.243.48.145",
+ "185.243.48.159",
+ "185.243.48.170",
+ "185.243.48.173",
+ "185.243.48.176",
+ "185.243.48.181",
+ "185.243.48.189",
+ "185.243.48.196",
+ "185.243.48.198",
+ "185.243.48.199",
+ "185.243.48.200",
+ "185.243.48.202",
+ "185.243.48.204",
+ "185.243.48.211",
+ "185.243.48.215",
+ "185.243.48.226",
+ "185.243.48.227",
+ "185.243.48.231",
+ "185.243.48.233",
+ "185.243.48.237",
+ "185.243.48.242",
+ "185.243.48.243",
+ "185.243.48.251",
+ "185.243.51.50",
+ "185.243.51.58",
+ "185.246.6.178",
+ "185.246.6.179",
+ "185.252.28.13",
+ "185.252.28.16",
+ "185.252.28.19",
+ "185.252.28.20",
+ "185.252.28.21",
+ "185.252.28.30",
+ "185.252.28.31",
+ "185.252.28.32",
+ "185.252.28.34",
+ "185.252.28.42",
+ "185.252.28.44",
+ "185.252.28.46",
+ "185.252.28.47",
+ "185.252.28.56",
+ "185.252.28.63",
+ "185.252.28.68",
+ "185.252.28.77",
+ "185.252.28.86",
+ "185.252.28.105",
+ "185.252.28.106",
+ "185.252.28.116",
+ "185.252.28.117",
+ "185.252.28.120",
+ "185.252.28.123",
+ "185.252.28.124",
+ "185.252.28.127",
+ "185.252.28.128",
+ "185.252.28.129",
+ "185.252.28.130",
+ "185.252.28.136",
+ "185.252.28.137",
+ "185.252.28.138",
+ "185.252.28.140",
+ "185.252.28.150",
+ "185.252.28.165",
+ "185.252.28.166",
+ "185.252.28.170",
+ "185.252.28.178",
+ "185.252.28.179",
+ "185.252.28.180",
+ "185.252.28.182",
+ "185.252.28.186",
+ "185.252.28.188",
+ "185.252.28.192",
+ "185.252.28.194",
+ "185.252.28.195",
+ "185.252.28.200",
+ "185.252.28.207",
+ "185.252.28.210",
+ "185.252.28.211",
+ "185.252.28.228",
+ "185.252.28.229",
+ "185.252.28.230",
+ "185.252.29.11",
+ "185.252.29.14",
+ "185.252.29.17",
+ "185.252.29.18",
+ "185.252.29.27",
+ "185.252.29.29",
+ "185.252.29.31",
+ "185.252.29.32",
+ "185.252.29.35",
+ "185.252.29.47",
+ "185.252.29.50",
+ "185.252.29.53",
+ "185.252.29.54",
+ "185.252.29.60",
+ "185.252.29.62",
+ "185.252.29.68",
+ "185.252.29.72",
+ "185.252.29.74",
+ "185.252.29.99",
+ "185.252.29.102",
+ "185.252.29.121",
+ "185.252.29.133",
+ "185.252.29.141",
+ "185.252.29.143",
+ "185.252.29.145",
+ "185.252.29.151",
+ "185.252.29.154",
+ "185.252.29.160",
+ "185.252.29.161",
+ "185.252.29.162",
+ "185.252.29.234",
+ "185.252.29.235",
+ "185.252.29.239",
+ "185.252.30.39",
+ "185.252.30.40",
+ "185.252.30.41",
+ "185.252.30.42",
+ "185.252.30.43",
+ "185.252.30.175",
+ "185.252.30.188",
+ "185.252.30.200",
+ "185.252.30.206",
+ "185.252.31.4",
+ "185.252.31.5",
+ "185.252.31.8",
+ "185.252.31.10",
+ "185.252.31.19",
+ "185.252.31.21",
+ "185.252.31.22",
+ "185.252.31.27",
+ "185.252.31.28",
+ "185.252.31.32",
+ "185.252.31.33",
+ "185.252.31.40",
+ "185.252.31.42",
+ "185.252.31.43",
+ "185.252.31.62",
+ "185.252.31.63",
+ "185.252.31.65",
+ "185.252.31.99",
+ "185.252.31.103",
+ "185.252.31.105",
+ "185.252.31.116",
+ "185.252.31.119",
+ "185.252.31.120",
+ "185.252.31.138",
+ "185.252.31.140",
+ "185.252.31.142",
+ "185.252.31.146",
+ "185.252.31.161",
+ "185.252.31.164",
+ "185.252.31.165",
+ "185.252.31.166",
+ "185.252.31.201",
+ "185.252.31.203",
+ "185.252.31.213",
+ "185.252.31.223",
+ "185.252.86.15",
+ "185.252.86.17",
+ "185.252.86.20",
+ "185.252.86.30",
+ "185.252.86.31",
+ "185.252.86.34",
+ "185.252.86.36",
+ "185.252.86.38",
+ "185.252.86.43",
+ "185.252.86.49",
+ "185.252.86.56",
+ "185.252.86.75",
+ "185.252.86.77",
+ "185.252.86.79",
+ "185.252.86.81",
+ "185.252.86.102",
+ "185.252.86.107",
+ "185.252.86.110",
+ "185.252.86.120",
+ "185.252.86.121",
+ "185.252.86.125",
+ "185.252.86.126",
+ "185.252.86.145",
+ "185.252.86.164",
+ "185.252.86.165",
+ "185.252.86.168",
+ "185.252.86.171",
+ "185.252.86.181",
+ "185.252.86.183",
+ "185.252.86.185",
+ "185.252.200.157",
+ "185.254.165.5",
+ "185.255.88.3",
+ "185.255.88.11",
+ "185.255.88.12",
+ "185.255.88.13",
+ "185.255.88.15",
+ "185.255.88.18",
+ "185.255.88.19",
+ "185.255.88.24",
+ "185.255.88.36",
+ "185.255.88.42",
+ "185.255.88.59",
+ "185.255.88.61",
+ "185.255.88.63",
+ "185.255.88.64",
+ "185.255.88.66",
+ "185.255.88.68",
+ "185.255.88.74",
+ "185.255.88.79",
+ "185.255.88.85",
+ "185.255.88.102",
+ "185.255.88.106",
+ "185.255.88.107",
+ "185.255.88.109",
+ "185.255.88.110",
+ "185.255.88.112",
+ "185.255.88.113",
+ "185.255.88.115",
+ "185.255.88.117",
+ "185.255.88.118",
+ "185.255.88.119",
+ "185.255.88.123",
+ "185.255.88.124",
+ "185.255.88.126",
+ "185.255.88.130",
+ "185.255.88.131",
+ "185.255.88.132",
+ "185.255.88.134",
+ "185.255.88.135",
+ "185.255.88.136",
+ "185.255.88.137",
+ "185.255.88.139",
+ "185.255.88.140",
+ "185.255.88.142",
+ "185.255.88.145",
+ "185.255.88.148",
+ "185.255.88.149",
+ "185.255.88.150",
+ "185.255.88.152",
+ "185.255.88.156",
+ "185.255.88.157",
+ "185.255.88.160",
+ "185.255.88.161",
+ "185.255.88.164",
+ "185.255.88.167",
+ "185.255.88.169",
+ "185.255.88.171",
+ "185.255.88.172",
+ "185.255.88.173",
+ "185.255.88.174",
+ "185.255.88.175",
+ "185.255.88.176",
+ "185.255.88.177",
+ "185.255.88.182",
+ "185.255.88.188",
+ "185.255.88.190",
+ "185.255.88.191",
+ "185.255.88.194",
+ "185.255.88.198",
+ "185.255.88.200",
+ "185.255.88.203",
+ "185.255.88.207",
+ "185.255.88.212",
+ "185.255.88.214",
+ "185.255.88.216",
+ "185.255.88.217",
+ "185.255.88.218",
+ "185.255.88.219",
+ "185.255.89.6",
+ "185.255.89.7",
+ "185.255.89.8",
+ "185.255.89.10",
+ "185.255.89.12",
+ "185.255.89.13",
+ "185.255.89.14",
+ "185.255.89.15",
+ "185.255.89.18",
+ "185.255.89.26",
+ "185.255.89.37",
+ "185.255.89.38",
+ "185.255.89.40",
+ "185.255.89.46",
+ "185.255.89.57",
+ "185.255.89.60",
+ "185.255.89.66",
+ "185.255.89.86",
+ "185.255.89.90",
+ "185.255.89.94",
+ "185.255.89.102",
+ "185.255.89.103",
+ "185.255.89.104",
+ "185.255.89.106",
+ "185.255.89.110",
+ "185.255.89.112",
+ "185.255.89.116",
+ "185.255.89.118",
+ "185.255.89.119",
+ "185.255.89.120",
+ "185.255.89.122",
+ "185.255.89.123",
+ "185.255.89.126",
+ "185.255.89.128",
+ "185.255.89.131",
+ "185.255.89.132",
+ "185.255.89.134",
+ "185.255.89.139",
+ "185.255.89.142",
+ "185.255.89.143",
+ "185.255.89.147",
+ "185.255.89.149",
+ "185.255.89.150",
+ "185.255.89.151",
+ "185.255.89.152",
+ "185.255.89.153",
+ "185.255.89.157",
+ "185.255.89.160",
+ "185.255.89.166",
+ "185.255.89.168",
+ "185.255.89.171",
+ "185.255.89.173",
+ "185.255.89.181",
+ "185.255.89.191",
+ "185.255.89.199",
+ "185.255.89.200",
+ "185.255.89.205",
+ "185.255.89.207",
+ "185.255.89.210",
+ "185.255.89.216",
+ "185.255.89.229",
+ "185.255.89.233",
+ "185.255.89.237",
+ "185.255.89.243",
+ "185.255.89.244",
+ "185.255.90.15",
+ "185.255.90.17",
+ "185.255.90.41",
+ "185.255.90.48",
+ "185.255.90.82",
+ "185.255.90.104",
+ "185.255.90.105",
+ "185.255.90.109",
+ "185.255.90.123",
+ "185.255.90.125",
+ "185.255.90.129",
+ "185.255.90.137",
+ "185.255.90.148",
+ "185.255.90.152",
+ "185.255.90.159",
+ "185.255.90.162",
+ "185.255.90.163",
+ "185.255.90.202",
+ "185.255.90.205",
+ "185.255.91.15",
+ "185.255.91.20",
+ "185.255.91.32",
+ "185.255.91.36",
+ "185.255.91.48",
+ "185.255.91.58",
+ "185.255.91.60",
+ "185.255.91.80",
+ "185.255.91.116",
+ "185.255.91.120",
+ "185.255.91.132",
+ "185.255.91.140",
+ "185.255.91.144",
+ "185.255.91.147",
+ "185.255.91.160",
+ "185.255.91.173",
+ "185.255.91.182",
+ "185.255.91.190",
+ "185.255.91.208",
+ "185.255.91.212",
+ "185.255.91.213",
+ "185.255.91.215",
+ "185.255.91.219",
+ "185.255.91.227",
+ "185.255.91.229",
+ "185.255.91.232",
+ "185.255.91.234",
+ "185.255.91.235",
+ "185.255.91.237",
+ "185.255.91.242",
+ "185.255.91.243",
+ "185.255.91.244",
+ "185.255.208.144",
+ "185.255.208.221",
+ "185.255.208.222",
+ "185.255.208.243",
+ "185.255.209.48",
+ "188.0.240.12",
+ "188.0.240.13",
+ "188.0.240.42",
+ "188.0.240.43",
+ "188.0.240.44",
+ "188.0.240.85",
+ "188.0.240.130",
+ "188.0.240.131",
+ "188.0.240.134",
+ "188.0.240.186",
+ "188.0.240.187",
+ "188.0.240.188",
+ "188.0.240.189",
+ "188.0.240.190",
+ "188.0.240.194",
+ "188.0.240.195",
+ "188.0.240.217",
+ "188.0.241.19",
+ "188.0.241.76",
+ "188.0.241.77",
+ "188.0.241.78",
+ "188.0.241.101",
+ "188.0.241.248",
+ "188.0.248.66",
+ "188.0.248.233",
+ "188.0.253.168",
+ "188.75.65.222",
+ "188.75.78.130",
+ "188.75.78.136",
+ "188.75.78.138",
+ "188.75.78.162",
+ "188.75.78.164",
+ "188.75.78.172",
+ "188.75.78.174",
+ "188.75.78.184",
+ "188.75.78.187",
+ "188.75.78.189",
+ "188.75.80.176",
+ "188.75.82.172",
+ "188.75.82.173",
+ "188.75.95.22",
+ "188.75.95.66",
+ "188.75.106.66",
+ "188.75.106.69",
+ "188.75.106.70",
+ "188.75.106.178",
+ "188.75.106.179",
+ "188.75.106.184",
+ "188.75.106.185",
+ "188.121.96.94",
+ "188.121.97.2",
+ "188.121.99.119",
+ "188.121.99.121",
+ "188.121.99.199",
+ "188.121.100.85",
+ "188.121.100.96",
+ "188.121.100.104",
+ "188.121.100.200",
+ "188.121.100.251",
+ "188.121.101.238",
+ "188.121.102.172",
+ "188.121.102.175",
+ "188.121.102.244",
+ "188.121.103.36",
+ "188.121.103.186",
+ "188.121.103.193",
+ "188.121.104.41",
+ "188.121.105.164",
+ "188.121.105.234",
+ "188.121.107.156",
+ "188.121.109.173",
+ "188.121.110.50",
+ "188.121.110.163",
+ "188.121.110.254",
+ "188.121.112.58",
+ "188.121.112.78",
+ "188.121.112.92",
+ "188.121.112.127",
+ "188.121.112.198",
+ "188.121.113.10",
+ "188.121.113.74",
+ "188.121.113.102",
+ "188.121.113.191",
+ "188.121.113.210",
+ "188.121.113.213",
+ "188.121.114.188",
+ "188.121.114.240",
+ "188.121.114.247",
+ "188.121.115.45",
+ "188.121.115.61",
+ "188.121.116.50",
+ "188.121.116.80",
+ "188.121.116.139",
+ "188.121.116.237",
+ "188.121.116.252",
+ "188.121.117.27",
+ "188.121.117.64",
+ "188.121.117.146",
+ "188.121.117.170",
+ "188.121.118.14",
+ "188.121.118.52",
+ "188.121.118.134",
+ "188.121.118.179",
+ "188.121.119.37",
+ "188.121.119.58",
+ "188.121.119.90",
+ "188.121.119.103",
+ "188.121.119.202",
+ "188.121.120.171",
+ "188.121.122.33",
+ "188.121.123.26",
+ "188.121.123.159",
+ "188.121.124.11",
+ "188.121.125.89",
+ "188.121.132.140",
+ "188.121.157.234",
+ "188.121.158.211",
+ "188.136.136.9",
+ "188.136.136.18",
+ "188.136.136.44",
+ "188.136.137.137",
+ "188.136.137.138",
+ "188.136.138.16",
+ "188.136.138.17",
+ "188.136.138.18",
+ "188.136.138.19",
+ "188.136.138.21",
+ "188.136.138.23",
+ "188.136.138.30",
+ "188.136.138.31",
+ "188.136.138.32",
+ "188.136.138.33",
+ "188.136.138.35",
+ "188.136.138.36",
+ "188.136.138.37",
+ "188.136.138.38",
+ "188.136.138.39",
+ "188.136.138.40",
+ "188.136.138.41",
+ "188.136.138.42",
+ "188.136.138.43",
+ "188.136.138.44",
+ "188.136.138.100",
+ "188.136.142.225",
+ "188.136.154.151",
+ "188.136.172.3",
+ "188.136.172.170",
+ "188.136.194.102",
+ "188.136.208.245",
+ "188.191.176.47",
+ "188.191.176.48",
+ "188.208.144.158",
+ "188.208.149.251",
+ "188.209.7.172",
+ "188.209.8.200",
+ "188.209.9.1",
+ "188.209.67.214",
+ "188.209.68.97",
+ "188.209.72.9",
+ "188.209.79.76",
+ "188.209.152.106",
+ "188.210.112.2",
+ "188.210.115.164",
+ "188.210.115.245",
+ "188.210.120.63",
+ "188.210.121.66",
+ "188.211.36.201",
+ "188.211.36.224",
+ "188.211.66.248",
+ "188.211.69.120",
+ "188.211.72.197",
+ "188.211.74.26",
+ "188.211.79.18",
+ "188.211.79.68",
+ "188.211.81.31",
+ "188.211.83.163",
+ "188.211.85.185",
+ "188.211.86.127",
+ "188.211.91.220",
+ "188.211.98.243",
+ "188.211.100.56",
+ "188.211.100.115",
+ "188.211.102.37",
+ "188.211.102.179",
+ "188.211.102.212",
+ "188.211.108.253",
+ "188.211.111.51",
+ "188.211.113.70",
+ "188.211.119.60",
+ "188.211.124.229",
+ "188.212.22.5",
+ "188.212.22.7",
+ "188.212.22.10",
+ "188.212.22.17",
+ "188.212.22.19",
+ "188.212.22.20",
+ "188.212.22.22",
+ "188.212.22.23",
+ "188.212.22.36",
+ "188.212.22.38",
+ "188.212.22.39",
+ "188.212.22.40",
+ "188.212.22.41",
+ "188.212.22.46",
+ "188.212.22.53",
+ "188.212.22.54",
+ "188.212.22.59",
+ "188.212.22.81",
+ "188.212.22.82",
+ "188.212.22.99",
+ "188.212.22.106",
+ "188.212.22.116",
+ "188.212.22.122",
+ "188.212.22.130",
+ "188.212.22.131",
+ "188.212.22.133",
+ "188.212.22.134",
+ "188.212.22.152",
+ "188.212.22.158",
+ "188.212.22.163",
+ "188.212.22.164",
+ "188.212.22.167",
+ "188.212.22.171",
+ "188.212.22.178",
+ "188.212.22.179",
+ "188.212.22.180",
+ "188.212.22.187",
+ "188.212.22.190",
+ "188.212.22.195",
+ "188.212.22.198",
+ "188.212.22.199",
+ "188.212.22.200",
+ "188.212.22.201",
+ "188.212.22.205",
+ "188.212.22.213",
+ "188.212.22.214",
+ "188.212.22.216",
+ "188.212.22.226",
+ "188.212.22.227",
+ "188.212.22.228",
+ "188.212.22.229",
+ "188.212.22.230",
+ "188.212.22.234",
+ "188.212.22.235",
+ "188.212.22.236",
+ "188.212.22.237",
+ "188.212.22.238",
+ "188.212.22.242",
+ "188.212.22.243",
+ "188.212.22.248",
+ "188.212.22.249",
+ "188.212.22.251",
+ "188.212.22.252",
+ "188.212.22.253",
+ "188.212.22.254",
+ "188.212.86.72",
+ "188.212.148.101",
+ "188.212.163.97",
+ "188.213.65.54",
+ "188.213.65.140",
+ "188.213.65.141",
+ "188.213.65.156",
+ "188.213.66.6",
+ "188.213.66.9",
+ "188.213.66.12",
+ "188.213.66.13",
+ "188.213.66.14",
+ "188.213.66.16",
+ "188.213.66.17",
+ "188.213.66.18",
+ "188.213.66.21",
+ "188.213.66.23",
+ "188.213.66.24",
+ "188.213.66.26",
+ "188.213.66.30",
+ "188.213.66.91",
+ "188.213.66.139",
+ "188.213.66.141",
+ "188.213.66.156",
+ "188.213.66.157",
+ "188.213.66.158",
+ "188.213.66.172",
+ "188.213.68.3",
+ "188.213.68.4",
+ "188.213.68.5",
+ "188.213.68.7",
+ "188.213.68.12",
+ "188.213.68.13",
+ "188.213.68.99",
+ "188.213.72.13",
+ "188.213.72.71",
+ "188.213.72.84",
+ "188.213.72.85",
+ "188.213.75.5",
+ "188.213.75.51",
+ "188.213.154.188",
+ "188.213.187.132",
+ "188.213.188.41",
+ "188.213.188.123",
+ "188.213.196.191",
+ "188.213.196.202",
+ "188.213.198.4",
+ "188.213.198.90",
+ "188.213.198.236",
+ "188.213.199.7",
+ "188.213.199.80",
+ "188.213.199.141",
+ "188.213.209.31",
+ "188.213.209.49",
+ "188.215.160.93",
+ "188.215.174.178",
+ "188.240.212.208",
+ "188.240.212.209",
+ "188.240.212.210",
+ "188.240.212.211",
+ "188.240.212.212",
+ "188.240.212.213",
+ "188.240.212.214",
+ "188.240.212.215",
+ "193.3.31.11",
+ "193.3.31.12",
+ "193.3.31.20",
+ "193.3.182.25",
+ "193.3.182.59",
+ "193.3.231.146",
+ "193.3.231.150",
+ "193.3.231.158",
+ "193.3.231.194",
+ "193.3.231.210",
+ "193.3.231.218",
+ "193.3.231.222",
+ "193.3.231.230",
+ "193.3.231.254",
+ "193.5.44.11",
+ "193.5.44.12",
+ "193.5.44.14",
+ "193.5.44.26",
+ "193.5.44.30",
+ "193.5.44.58",
+ "193.5.44.62",
+ "193.5.44.67",
+ "193.5.44.80",
+ "193.5.44.86",
+ "193.5.44.88",
+ "193.5.44.92",
+ "193.5.44.94",
+ "193.5.44.105",
+ "193.5.44.107",
+ "193.5.44.110",
+ "193.5.44.115",
+ "193.5.44.152",
+ "193.5.44.158",
+ "193.5.44.159",
+ "193.5.44.161",
+ "193.5.44.192",
+ "193.5.44.237",
+ "193.8.139.55",
+ "193.8.139.56",
+ "193.19.147.244",
+ "193.19.147.245",
+ "193.35.62.1",
+ "193.35.230.4",
+ "193.35.230.5",
+ "193.35.230.6",
+ "193.35.230.7",
+ "193.35.230.8",
+ "193.35.230.10",
+ "193.35.230.13",
+ "193.35.230.14",
+ "193.35.230.15",
+ "193.35.230.16",
+ "193.35.230.17",
+ "193.35.230.18",
+ "193.35.230.19",
+ "193.35.230.20",
+ "193.35.230.21",
+ "193.35.230.22",
+ "193.35.230.23",
+ "193.35.230.24",
+ "193.35.230.25",
+ "193.35.230.26",
+ "193.35.230.27",
+ "193.35.230.28",
+ "193.35.230.29",
+ "193.35.230.30",
+ "193.35.230.31",
+ "193.35.230.32",
+ "193.37.37.38",
+ "193.37.37.243",
+ "193.39.9.3",
+ "193.39.9.32",
+ "193.39.9.54",
+ "193.39.9.92",
+ "193.39.9.105",
+ "193.39.9.107",
+ "193.39.9.117",
+ "193.39.9.162",
+ "193.39.9.166",
+ "193.39.9.188",
+ "193.39.9.191",
+ "193.39.9.214",
+ "193.39.9.236",
+ "193.39.9.250",
+ "193.56.61.66",
+ "193.56.61.67",
+ "193.56.118.1",
+ "193.58.119.50",
+ "193.58.119.130",
+ "193.58.119.198",
+ "193.58.119.234",
+ "193.58.119.247",
+ "193.84.255.2",
+ "193.84.255.20",
+ "193.84.255.66",
+ "193.84.255.95",
+ "193.105.2.90",
+ "193.105.2.91",
+ "193.105.6.15",
+ "193.105.6.30",
+ "193.105.6.118",
+ "193.105.6.120",
+ "193.105.6.121",
+ "193.105.6.131",
+ "193.105.6.133",
+ "193.105.6.235",
+ "193.105.234.13",
+ "193.105.234.17",
+ "193.105.234.19",
+ "193.105.234.20",
+ "193.105.234.29",
+ "193.105.234.38",
+ "193.105.234.58",
+ "193.105.234.68",
+ "193.105.234.81",
+ "193.105.234.85",
+ "193.105.234.87",
+ "193.105.234.88",
+ "193.105.234.90",
+ "193.105.234.93",
+ "193.105.234.96",
+ "193.105.234.100",
+ "193.105.234.104",
+ "193.105.234.105",
+ "193.105.234.111",
+ "193.105.234.115",
+ "193.105.234.119",
+ "193.105.234.131",
+ "193.105.234.143",
+ "193.105.234.144",
+ "193.105.234.151",
+ "193.105.234.164",
+ "193.105.234.165",
+ "193.105.234.167",
+ "193.105.234.180",
+ "193.105.234.191",
+ "193.105.234.207",
+ "193.105.234.216",
+ "193.105.234.223",
+ "193.105.234.229",
+ "193.105.234.230",
+ "193.105.234.231",
+ "193.105.234.234",
+ "193.105.234.237",
+ "193.105.234.243",
+ "193.107.48.72",
+ "193.107.48.203",
+ "193.107.48.222",
+ "193.111.234.35",
+ "193.111.234.40",
+ "193.111.234.61",
+ "193.111.234.72",
+ "193.111.234.114",
+ "193.111.234.147",
+ "193.111.234.152",
+ "193.111.234.153",
+ "193.111.234.196",
+ "193.111.235.7",
+ "193.111.235.77",
+ "193.111.235.103",
+ "193.111.235.115",
+ "193.111.235.160",
+ "193.111.235.179",
+ "193.111.236.99",
+ "193.111.236.101",
+ "193.111.236.103",
+ "193.134.100.12",
+ "193.134.100.60",
+ "193.134.100.148",
+ "193.134.100.155",
+ "193.134.101.20",
+ "193.134.101.172",
+ "193.134.101.173",
+ "193.141.64.5",
+ "193.141.64.7",
+ "193.141.64.10",
+ "193.141.64.11",
+ "193.141.64.23",
+ "193.141.64.32",
+ "193.141.64.35",
+ "193.141.64.38",
+ "193.141.64.44",
+ "193.141.64.47",
+ "193.141.64.48",
+ "193.141.64.55",
+ "193.141.64.61",
+ "193.141.64.66",
+ "193.141.64.68",
+ "193.141.64.88",
+ "193.141.64.90",
+ "193.141.64.103",
+ "193.141.64.107",
+ "193.141.64.109",
+ "193.141.64.110",
+ "193.141.64.111",
+ "193.141.64.115",
+ "193.141.64.117",
+ "193.141.64.118",
+ "193.141.64.119",
+ "193.141.64.120",
+ "193.141.64.121",
+ "193.141.64.122",
+ "193.141.64.123",
+ "193.141.64.125",
+ "193.141.64.126",
+ "193.141.64.128",
+ "193.141.64.129",
+ "193.141.64.130",
+ "193.141.64.134",
+ "193.141.64.140",
+ "193.141.64.142",
+ "193.141.64.143",
+ "193.141.64.146",
+ "193.141.64.149",
+ "193.141.64.152",
+ "193.141.64.153",
+ "193.141.64.154",
+ "193.141.64.157",
+ "193.141.64.158",
+ "193.141.64.160",
+ "193.141.64.174",
+ "193.141.64.182",
+ "193.141.64.191",
+ "193.141.64.192",
+ "193.141.64.212",
+ "193.141.64.213",
+ "193.141.64.215",
+ "193.141.64.217",
+ "193.141.64.221",
+ "193.141.64.231",
+ "193.141.64.239",
+ "193.141.64.241",
+ "193.141.64.242",
+ "193.141.64.247",
+ "193.141.64.248",
+ "193.141.65.17",
+ "193.141.65.24",
+ "193.141.65.26",
+ "193.141.65.28",
+ "193.141.65.34",
+ "193.141.65.42",
+ "193.141.65.45",
+ "193.141.65.56",
+ "193.141.65.67",
+ "193.141.65.68",
+ "193.141.65.73",
+ "193.141.65.78",
+ "193.141.65.81",
+ "193.141.65.82",
+ "193.141.65.92",
+ "193.141.65.94",
+ "193.141.65.97",
+ "193.141.65.99",
+ "193.141.65.100",
+ "193.141.65.101",
+ "193.141.65.106",
+ "193.141.65.107",
+ "193.141.65.112",
+ "193.141.65.115",
+ "193.141.65.125",
+ "193.141.65.129",
+ "193.141.65.131",
+ "193.141.65.142",
+ "193.141.65.146",
+ "193.141.65.155",
+ "193.141.65.160",
+ "193.141.65.167",
+ "193.141.65.168",
+ "193.141.65.169",
+ "193.141.65.178",
+ "193.141.65.185",
+ "193.141.65.186",
+ "193.141.65.188",
+ "193.141.65.221",
+ "193.141.65.222",
+ "193.141.65.224",
+ "193.141.65.228",
+ "193.141.65.234",
+ "193.141.65.244",
+ "193.141.65.253",
+ "193.148.64.119",
+ "193.148.65.65",
+ "193.148.66.1",
+ "193.148.66.11",
+ "193.148.66.66",
+ "193.148.66.190",
+ "193.151.128.225",
+ "193.151.130.4",
+ "193.151.131.113",
+ "193.151.131.151",
+ "193.151.134.65",
+ "193.151.134.90",
+ "193.151.134.104",
+ "193.151.134.156",
+ "193.151.134.206",
+ "193.151.135.112",
+ "193.151.135.182",
+ "193.151.136.80",
+ "193.151.137.194",
+ "193.151.140.11",
+ "193.151.144.140",
+ "193.151.144.201",
+ "193.151.145.107",
+ "193.151.145.125",
+ "193.151.146.234",
+ "193.151.149.64",
+ "193.151.149.160",
+ "193.151.153.95",
+ "193.151.153.225",
+ "193.151.154.24",
+ "193.151.155.149",
+ "193.151.157.12",
+ "193.151.157.13",
+ "193.151.157.14",
+ "193.151.157.15",
+ "193.151.157.16",
+ "193.151.157.17",
+ "193.151.157.19",
+ "193.151.157.20",
+ "193.151.157.29",
+ "193.151.157.30",
+ "193.151.159.58",
+ "193.151.159.59",
+ "193.151.159.60",
+ "193.151.159.61",
+ "193.151.159.62",
+ "193.151.159.226",
+ "193.151.159.227",
+ "193.151.159.228",
+ "193.151.159.245",
+ "193.151.159.246",
+ "193.151.159.247",
+ "193.151.159.253",
+ "193.151.159.254",
+ "193.162.129.10",
+ "193.162.129.11",
+ "193.162.129.14",
+ "193.162.129.35",
+ "193.162.129.59",
+ "193.162.129.63",
+ "193.162.129.77",
+ "193.162.129.78",
+ "193.162.129.156",
+ "193.162.129.170",
+ "193.162.129.212",
+ "193.162.129.216",
+ "193.162.129.217",
+ "193.162.129.223",
+ "193.162.129.224",
+ "193.162.129.226",
+ "193.162.129.233",
+ "193.162.129.242",
+ "193.162.129.248",
+ "193.176.97.94",
+ "193.178.200.3",
+ "193.178.200.5",
+ "193.186.32.5",
+ "193.186.32.7",
+ "193.186.32.32",
+ "193.186.32.45",
+ "193.186.32.56",
+ "193.186.32.58",
+ "193.186.32.59",
+ "193.186.32.81",
+ "193.186.32.87",
+ "193.186.32.105",
+ "193.186.32.106",
+ "193.186.32.108",
+ "193.186.32.109",
+ "193.186.32.111",
+ "193.186.32.113",
+ "193.186.32.123",
+ "193.186.32.139",
+ "193.186.32.141",
+ "193.186.32.145",
+ "193.186.32.148",
+ "193.186.32.152",
+ "193.186.32.155",
+ "193.186.32.156",
+ "193.186.32.162",
+ "193.186.32.170",
+ "193.186.32.178",
+ "193.186.32.184",
+ "193.186.32.197",
+ "193.186.32.199",
+ "193.186.32.201",
+ "193.186.32.203",
+ "193.186.32.216",
+ "193.186.32.222",
+ "193.186.32.227",
+ "193.186.32.239",
+ "193.186.32.242",
+ "193.186.32.246",
+ "193.186.32.247",
+ "193.186.32.248",
+ "193.186.32.249",
+ "193.186.32.251",
+ "193.186.32.252",
+ "193.200.148.9",
+ "193.200.148.66",
+ "193.222.51.1",
+ "193.228.90.2",
+ "193.228.90.3",
+ "193.228.90.4",
+ "193.228.90.5",
+ "193.228.90.6",
+ "193.228.90.7",
+ "193.228.90.8",
+ "193.228.90.13",
+ "193.228.90.19",
+ "193.228.90.20",
+ "193.228.90.21",
+ "193.228.90.23",
+ "193.228.90.25",
+ "193.228.90.27",
+ "193.228.90.28",
+ "193.228.90.35",
+ "193.228.90.37",
+ "193.228.90.39",
+ "193.228.90.40",
+ "193.228.90.42",
+ "193.228.90.43",
+ "193.228.90.46",
+ "193.228.90.48",
+ "193.228.90.57",
+ "193.228.90.63",
+ "193.228.90.64",
+ "193.228.90.70",
+ "193.228.90.72",
+ "193.228.90.76",
+ "193.228.90.78",
+ "193.228.90.82",
+ "193.228.90.87",
+ "193.228.90.90",
+ "193.228.90.91",
+ "193.228.90.92",
+ "193.228.90.93",
+ "193.228.90.99",
+ "193.228.90.101",
+ "193.228.90.102",
+ "193.228.90.111",
+ "193.228.90.112",
+ "193.228.90.113",
+ "193.228.90.119",
+ "193.228.90.120",
+ "193.228.90.130",
+ "193.228.90.131",
+ "193.228.90.132",
+ "193.228.90.136",
+ "193.228.90.139",
+ "193.228.90.141",
+ "193.228.90.144",
+ "193.228.90.145",
+ "193.228.90.147",
+ "193.228.90.148",
+ "193.228.90.156",
+ "193.228.90.161",
+ "193.228.90.180",
+ "193.228.90.182",
+ "193.228.90.185",
+ "193.228.90.186",
+ "193.228.90.188",
+ "193.228.90.189",
+ "193.228.90.191",
+ "193.228.90.198",
+ "193.228.90.199",
+ "193.228.90.238",
+ "193.228.90.244",
+ "193.228.90.245",
+ "193.228.90.253",
+ "193.228.90.254",
+ "193.228.169.51",
+ "193.228.169.234",
+ "193.242.125.12",
+ "193.242.125.15",
+ "193.242.125.25",
+ "193.242.125.28",
+ "193.242.125.29",
+ "193.242.125.35",
+ "193.242.125.38",
+ "193.242.125.47",
+ "193.242.125.51",
+ "193.242.125.61",
+ "193.242.125.63",
+ "193.242.125.65",
+ "193.242.125.69",
+ "193.242.125.73",
+ "193.242.125.83",
+ "193.242.125.93",
+ "193.242.125.112",
+ "193.242.125.124",
+ "193.242.125.135",
+ "193.242.125.141",
+ "193.242.125.156",
+ "193.242.125.186",
+ "193.242.125.189",
+ "193.242.125.197",
+ "193.242.125.198",
+ "193.242.125.217",
+ "193.242.125.221",
+ "193.242.125.223",
+ "193.242.125.232",
+ "193.242.125.241",
+ "193.242.125.251",
+ "193.242.125.254",
+ "193.242.208.10",
+ "193.242.208.21",
+ "193.242.208.94",
+ "193.242.208.110",
+ "193.242.208.124",
+ "193.242.208.128",
+ "193.242.208.166",
+ "193.242.208.185",
+ "193.242.208.245",
+ "193.246.200.118",
+ "193.246.200.121",
+ "194.1.155.45",
+ "194.5.175.15",
+ "194.5.175.22",
+ "194.5.175.24",
+ "194.5.175.29",
+ "194.5.175.33",
+ "194.5.175.35",
+ "194.5.175.37",
+ "194.5.175.38",
+ "194.5.175.42",
+ "194.5.175.44",
+ "194.5.175.46",
+ "194.5.175.52",
+ "194.5.175.61",
+ "194.5.175.73",
+ "194.5.175.74",
+ "194.5.175.75",
+ "194.5.175.76",
+ "194.5.175.81",
+ "194.5.175.89",
+ "194.5.175.90",
+ "194.5.175.104",
+ "194.5.175.113",
+ "194.5.175.114",
+ "194.5.175.115",
+ "194.5.175.117",
+ "194.5.175.119",
+ "194.5.175.132",
+ "194.5.175.139",
+ "194.5.175.144",
+ "194.5.175.145",
+ "194.5.175.146",
+ "194.5.175.154",
+ "194.5.175.157",
+ "194.5.175.158",
+ "194.5.175.164",
+ "194.5.175.169",
+ "194.5.175.170",
+ "194.5.175.178",
+ "194.5.175.181",
+ "194.5.175.183",
+ "194.5.175.186",
+ "194.5.175.190",
+ "194.5.175.200",
+ "194.5.175.202",
+ "194.5.175.216",
+ "194.5.175.217",
+ "194.5.175.236",
+ "194.5.175.242",
+ "194.5.175.244",
+ "194.5.175.246",
+ "194.5.175.247",
+ "194.5.175.249",
+ "194.5.175.251",
+ "194.5.176.46",
+ "194.5.176.203",
+ "194.5.176.206",
+ "194.5.177.120",
+ "194.5.178.48",
+ "194.5.178.81",
+ "194.5.179.79",
+ "194.5.179.181",
+ "194.5.188.18",
+ "194.5.188.40",
+ "194.5.188.41",
+ "194.5.188.42",
+ "194.5.188.53",
+ "194.5.188.56",
+ "194.5.188.59",
+ "194.5.188.63",
+ "194.5.188.66",
+ "194.5.188.76",
+ "194.5.188.79",
+ "194.5.188.83",
+ "194.5.188.93",
+ "194.5.188.112",
+ "194.5.188.124",
+ "194.5.188.126",
+ "194.5.188.128",
+ "194.5.188.132",
+ "194.5.188.136",
+ "194.5.188.147",
+ "194.5.188.148",
+ "194.5.188.159",
+ "194.5.188.161",
+ "194.5.188.169",
+ "194.5.188.183",
+ "194.5.188.193",
+ "194.5.188.194",
+ "194.5.188.198",
+ "194.5.188.208",
+ "194.5.188.214",
+ "194.5.188.216",
+ "194.5.188.222",
+ "194.5.188.225",
+ "194.5.188.226",
+ "194.5.188.230",
+ "194.5.188.231",
+ "194.5.188.236",
+ "194.5.188.237",
+ "194.5.188.240",
+ "194.5.188.241",
+ "194.5.188.242",
+ "194.5.188.243",
+ "194.5.188.246",
+ "194.5.188.247",
+ "194.5.188.251",
+ "194.5.188.252",
+ "194.5.195.14",
+ "194.5.195.20",
+ "194.5.195.23",
+ "194.5.195.24",
+ "194.5.195.33",
+ "194.5.195.37",
+ "194.5.195.50",
+ "194.5.195.53",
+ "194.5.195.62",
+ "194.5.195.66",
+ "194.5.195.69",
+ "194.5.195.76",
+ "194.5.195.79",
+ "194.5.195.80",
+ "194.5.195.89",
+ "194.5.195.91",
+ "194.5.195.92",
+ "194.5.195.93",
+ "194.5.195.96",
+ "194.5.195.100",
+ "194.5.195.101",
+ "194.5.195.104",
+ "194.5.195.117",
+ "194.5.195.120",
+ "194.5.195.126",
+ "194.5.195.129",
+ "194.5.195.133",
+ "194.5.195.134",
+ "194.5.195.143",
+ "194.5.195.146",
+ "194.5.195.152",
+ "194.5.195.153",
+ "194.5.195.154",
+ "194.5.195.155",
+ "194.5.195.156",
+ "194.5.195.158",
+ "194.5.195.161",
+ "194.5.195.162",
+ "194.5.195.163",
+ "194.5.195.164",
+ "194.5.195.167",
+ "194.5.195.168",
+ "194.5.195.172",
+ "194.5.195.175",
+ "194.5.195.176",
+ "194.5.195.185",
+ "194.5.195.188",
+ "194.5.195.191",
+ "194.5.195.192",
+ "194.5.195.200",
+ "194.5.195.205",
+ "194.5.195.215",
+ "194.5.195.219",
+ "194.5.195.221",
+ "194.5.195.226",
+ "194.5.195.227",
+ "194.5.195.234",
+ "194.5.195.244",
+ "194.5.195.247",
+ "194.5.195.248",
+ "194.5.195.249",
+ "194.5.205.10",
+ "194.5.205.11",
+ "194.5.205.12",
+ "194.5.205.16",
+ "194.5.205.31",
+ "194.5.205.32",
+ "194.5.205.34",
+ "194.5.205.36",
+ "194.5.205.37",
+ "194.5.205.39",
+ "194.5.205.40",
+ "194.5.205.64",
+ "194.5.205.70",
+ "194.5.205.85",
+ "194.5.205.86",
+ "194.5.205.88",
+ "194.5.205.89",
+ "194.5.205.91",
+ "194.5.205.92",
+ "194.5.205.93",
+ "194.5.205.97",
+ "194.5.205.110",
+ "194.5.205.117",
+ "194.5.205.121",
+ "194.5.205.128",
+ "194.5.205.149",
+ "194.5.205.150",
+ "194.5.205.158",
+ "194.5.205.161",
+ "194.5.205.163",
+ "194.5.205.166",
+ "194.5.205.168",
+ "194.5.205.169",
+ "194.5.205.170",
+ "194.5.205.172",
+ "194.5.205.176",
+ "194.5.205.178",
+ "194.5.205.179",
+ "194.5.205.181",
+ "194.5.205.191",
+ "194.5.205.192",
+ "194.5.205.193",
+ "194.5.205.200",
+ "194.5.205.203",
+ "194.5.205.213",
+ "194.5.205.214",
+ "194.5.205.231",
+ "194.5.205.237",
+ "194.5.205.239",
+ "194.5.205.247",
+ "194.5.205.249",
+ "194.5.205.250",
+ "194.9.56.58",
+ "194.9.56.62",
+ "194.9.56.102",
+ "194.9.56.124",
+ "194.9.56.138",
+ "194.9.57.212",
+ "194.9.80.10",
+ "194.9.80.19",
+ "194.9.80.45",
+ "194.9.80.58",
+ "194.9.80.75",
+ "194.9.80.153",
+ "194.9.80.154",
+ "194.9.80.155",
+ "194.9.80.156",
+ "194.9.80.157",
+ "194.9.80.158",
+ "194.9.80.160",
+ "194.9.80.193",
+ "194.9.80.202",
+ "194.9.81.51",
+ "194.9.81.131",
+ "194.31.108.2",
+ "194.31.108.3",
+ "194.31.108.4",
+ "194.31.108.7",
+ "194.31.108.8",
+ "194.31.108.9",
+ "194.31.108.14",
+ "194.31.108.15",
+ "194.31.108.16",
+ "194.31.108.24",
+ "194.31.108.27",
+ "194.31.108.28",
+ "194.31.108.83",
+ "194.31.108.88",
+ "194.31.194.2",
+ "194.31.194.36",
+ "194.31.194.37",
+ "194.31.194.42",
+ "194.31.194.100",
+ "194.31.194.105",
+ "194.31.194.114",
+ "194.31.194.125",
+ "194.31.194.130",
+ "194.31.194.143",
+ "194.31.194.145",
+ "194.31.194.146",
+ "194.31.194.148",
+ "194.31.194.158",
+ "194.31.194.163",
+ "194.31.194.178",
+ "194.31.194.194",
+ "194.31.194.195",
+ "194.31.194.205",
+ "194.31.194.217",
+ "194.31.194.221",
+ "194.33.105.28",
+ "194.33.105.69",
+ "194.33.105.71",
+ "194.33.105.72",
+ "194.33.105.134",
+ "194.33.105.139",
+ "194.33.105.152",
+ "194.33.105.168",
+ "194.33.105.169",
+ "194.33.105.206",
+ "194.33.105.209",
+ "194.33.105.222",
+ "194.33.105.232",
+ "194.33.105.234",
+ "194.33.106.103",
+ "194.33.107.107",
+ "194.33.107.108",
+ "194.33.107.240",
+ "194.34.162.150",
+ "194.34.163.53",
+ "194.34.163.54",
+ "194.36.174.2",
+ "194.36.174.31",
+ "194.36.174.56",
+ "194.36.174.57",
+ "194.36.174.64",
+ "194.36.174.78",
+ "194.36.174.80",
+ "194.36.174.108",
+ "194.36.174.110",
+ "194.36.174.111",
+ "194.36.174.151",
+ "194.36.174.152",
+ "194.36.174.153",
+ "194.36.174.161",
+ "194.36.174.162",
+ "194.36.174.167",
+ "194.36.174.172",
+ "194.36.174.175",
+ "194.36.174.190",
+ "194.36.174.200",
+ "194.36.174.209",
+ "194.36.174.231",
+ "194.39.254.42",
+ "194.39.254.43",
+ "194.39.254.50",
+ "194.39.254.51",
+ "194.39.254.52",
+ "194.39.254.53",
+ "194.39.254.59",
+ "194.41.48.20",
+ "194.41.51.34",
+ "194.48.198.15",
+ "194.48.198.16",
+ "194.48.198.18",
+ "194.48.198.29",
+ "194.48.198.37",
+ "194.48.198.38",
+ "194.48.198.40",
+ "194.48.198.65",
+ "194.48.198.70",
+ "194.48.198.74",
+ "194.48.198.75",
+ "194.48.198.85",
+ "194.48.198.92",
+ "194.48.198.93",
+ "194.48.198.95",
+ "194.48.198.100",
+ "194.48.198.105",
+ "194.48.198.108",
+ "194.48.198.121",
+ "194.48.198.133",
+ "194.48.198.145",
+ "194.48.198.147",
+ "194.48.198.164",
+ "194.48.198.178",
+ "194.48.198.193",
+ "194.48.198.206",
+ "194.48.198.208",
+ "194.48.198.216",
+ "194.48.198.226",
+ "194.48.198.232",
+ "194.48.198.234",
+ "194.48.198.239",
+ "194.48.198.244",
+ "194.48.198.248",
+ "194.53.122.10",
+ "194.53.122.11",
+ "194.53.122.13",
+ "194.53.122.14",
+ "194.53.122.15",
+ "194.53.122.16",
+ "194.53.122.17",
+ "194.53.122.18",
+ "194.53.122.19",
+ "194.53.122.20",
+ "194.53.122.21",
+ "194.53.122.25",
+ "194.53.122.26",
+ "194.53.122.27",
+ "194.53.122.28",
+ "194.53.122.29",
+ "194.53.122.30",
+ "194.53.122.31",
+ "194.53.122.32",
+ "194.53.122.33",
+ "194.53.122.34",
+ "194.53.122.35",
+ "194.53.122.36",
+ "194.53.122.37",
+ "194.53.122.38",
+ "194.53.122.39",
+ "194.53.122.40",
+ "194.53.122.42",
+ "194.53.122.43",
+ "194.53.122.44",
+ "194.53.122.45",
+ "194.53.122.46",
+ "194.53.122.47",
+ "194.53.122.48",
+ "194.53.122.49",
+ "194.53.122.50",
+ "194.53.122.51",
+ "194.53.122.52",
+ "194.53.122.53",
+ "194.53.122.54",
+ "194.53.122.55",
+ "194.53.122.56",
+ "194.53.122.57",
+ "194.53.122.58",
+ "194.53.122.59",
+ "194.53.122.60",
+ "194.53.122.62",
+ "194.53.122.63",
+ "194.53.122.64",
+ "194.53.122.65",
+ "194.53.122.66",
+ "194.53.122.67",
+ "194.53.122.68",
+ "194.53.122.69",
+ "194.53.122.71",
+ "194.53.122.72",
+ "194.53.122.73",
+ "194.53.122.74",
+ "194.53.122.77",
+ "194.53.122.78",
+ "194.53.122.79",
+ "194.53.122.80",
+ "194.53.122.81",
+ "194.53.122.82",
+ "194.53.122.84",
+ "194.53.122.85",
+ "194.53.122.86",
+ "194.53.122.87",
+ "194.53.122.88",
+ "194.53.122.89",
+ "194.53.122.90",
+ "194.53.122.91",
+ "194.53.122.92",
+ "194.53.122.93",
+ "194.53.122.94",
+ "194.53.122.95",
+ "194.53.122.96",
+ "194.53.122.97",
+ "194.53.122.98",
+ "194.53.122.99",
+ "194.53.122.100",
+ "194.53.122.102",
+ "194.53.122.103",
+ "194.53.122.104",
+ "194.53.122.105",
+ "194.53.122.106",
+ "194.53.122.107",
+ "194.53.122.108",
+ "194.53.122.109",
+ "194.53.122.110",
+ "194.53.122.111",
+ "194.53.122.112",
+ "194.53.122.113",
+ "194.53.122.114",
+ "194.53.122.115",
+ "194.53.122.116",
+ "194.53.122.117",
+ "194.53.122.118",
+ "194.53.122.120",
+ "194.53.122.121",
+ "194.53.122.122",
+ "194.53.122.124",
+ "194.53.122.125",
+ "194.53.122.127",
+ "194.53.122.128",
+ "194.53.122.129",
+ "194.53.122.130",
+ "194.53.122.131",
+ "194.53.122.132",
+ "194.53.122.133",
+ "194.53.122.134",
+ "194.53.122.135",
+ "194.53.122.136",
+ "194.53.122.137",
+ "194.53.122.138",
+ "194.53.122.139",
+ "194.53.122.140",
+ "194.53.122.142",
+ "194.53.122.144",
+ "194.53.122.145",
+ "194.53.122.146",
+ "194.53.122.147",
+ "194.53.122.148",
+ "194.53.122.149",
+ "194.53.122.151",
+ "194.53.122.152",
+ "194.53.122.153",
+ "194.53.122.154",
+ "194.53.122.155",
+ "194.53.122.156",
+ "194.53.122.157",
+ "194.53.122.158",
+ "194.53.122.159",
+ "194.53.122.160",
+ "194.53.122.161",
+ "194.53.122.162",
+ "194.53.122.163",
+ "194.53.122.164",
+ "194.53.122.165",
+ "194.53.122.166",
+ "194.53.122.167",
+ "194.53.122.168",
+ "194.53.122.169",
+ "194.53.122.170",
+ "194.53.122.171",
+ "194.53.122.172",
+ "194.53.122.173",
+ "194.53.122.174",
+ "194.53.122.175",
+ "194.53.122.176",
+ "194.53.122.177",
+ "194.53.122.179",
+ "194.53.122.180",
+ "194.53.122.181",
+ "194.53.122.182",
+ "194.53.122.183",
+ "194.53.122.184",
+ "194.53.122.185",
+ "194.53.122.186",
+ "194.53.122.187",
+ "194.53.122.188",
+ "194.53.122.189",
+ "194.53.122.190",
+ "194.53.122.191",
+ "194.53.122.192",
+ "194.53.122.193",
+ "194.53.122.194",
+ "194.53.122.195",
+ "194.53.122.196",
+ "194.53.122.197",
+ "194.53.122.198",
+ "194.53.122.199",
+ "194.53.122.200",
+ "194.53.122.201",
+ "194.53.122.202",
+ "194.53.122.203",
+ "194.53.122.204",
+ "194.53.122.205",
+ "194.53.122.206",
+ "194.53.122.207",
+ "194.53.122.208",
+ "194.53.122.209",
+ "194.53.122.210",
+ "194.53.122.211",
+ "194.53.122.212",
+ "194.53.122.213",
+ "194.53.122.214",
+ "194.53.122.215",
+ "194.53.122.216",
+ "194.53.122.217",
+ "194.53.122.218",
+ "194.53.122.219",
+ "194.53.122.220",
+ "194.53.122.221",
+ "194.53.122.222",
+ "194.53.122.223",
+ "194.53.122.225",
+ "194.53.122.226",
+ "194.53.122.227",
+ "194.53.122.228",
+ "194.53.122.229",
+ "194.53.122.230",
+ "194.53.122.231",
+ "194.53.122.232",
+ "194.53.122.233",
+ "194.53.122.234",
+ "194.53.122.235",
+ "194.53.122.236",
+ "194.53.122.237",
+ "194.53.122.238",
+ "194.53.122.239",
+ "194.53.122.240",
+ "194.53.122.241",
+ "194.53.122.242",
+ "194.53.122.243",
+ "194.53.122.244",
+ "194.53.122.245",
+ "194.53.122.246",
+ "194.53.122.247",
+ "194.53.122.249",
+ "194.53.122.250",
+ "194.56.148.22",
+ "194.56.148.76",
+ "194.56.148.179",
+ "194.56.148.222",
+ "194.59.170.5",
+ "194.59.170.6",
+ "194.59.170.15",
+ "194.59.170.19",
+ "194.59.170.21",
+ "194.59.170.22",
+ "194.59.170.23",
+ "194.59.170.24",
+ "194.59.170.25",
+ "194.59.170.26",
+ "194.59.170.27",
+ "194.59.170.28",
+ "194.59.170.29",
+ "194.59.170.30",
+ "194.59.170.49",
+ "194.59.170.60",
+ "194.59.170.61",
+ "194.59.170.75",
+ "194.59.170.82",
+ "194.59.170.83",
+ "194.59.170.90",
+ "194.59.170.100",
+ "194.59.170.115",
+ "194.59.170.117",
+ "194.59.170.119",
+ "194.59.170.120",
+ "194.59.170.132",
+ "194.59.170.138",
+ "194.59.170.144",
+ "194.59.170.146",
+ "194.59.170.154",
+ "194.59.170.166",
+ "194.59.170.174",
+ "194.59.170.192",
+ "194.59.170.207",
+ "194.59.170.228",
+ "194.59.170.232",
+ "194.59.170.243",
+ "194.59.171.11",
+ "194.59.171.53",
+ "194.59.171.153",
+ "194.59.171.154",
+ "194.59.171.185",
+ "194.59.214.2",
+ "194.59.214.3",
+ "194.59.214.4",
+ "194.59.214.7",
+ "194.59.214.10",
+ "194.59.214.30",
+ "194.59.214.31",
+ "194.59.214.35",
+ "194.59.214.36",
+ "194.59.214.37",
+ "194.59.214.38",
+ "194.59.214.55",
+ "194.59.214.71",
+ "194.59.214.74",
+ "194.59.214.75",
+ "194.59.214.76",
+ "194.59.214.85",
+ "194.59.214.91",
+ "194.59.214.92",
+ "194.59.214.93",
+ "194.59.214.99",
+ "194.59.214.100",
+ "194.59.214.102",
+ "194.59.214.103",
+ "194.59.214.104",
+ "194.59.214.105",
+ "194.59.214.106",
+ "194.59.214.108",
+ "194.59.214.110",
+ "194.59.214.116",
+ "194.59.214.120",
+ "194.59.214.121",
+ "194.59.214.123",
+ "194.59.214.124",
+ "194.59.214.125",
+ "194.59.214.129",
+ "194.59.214.148",
+ "194.59.214.160",
+ "194.59.214.161",
+ "194.59.214.162",
+ "194.59.214.163",
+ "194.59.214.164",
+ "194.59.214.165",
+ "194.59.214.166",
+ "194.59.214.174",
+ "194.59.214.176",
+ "194.59.214.195",
+ "194.59.214.200",
+ "194.59.214.202",
+ "194.59.214.203",
+ "194.59.214.205",
+ "194.59.214.209",
+ "194.59.214.210",
+ "194.59.215.11",
+ "194.59.215.36",
+ "194.59.215.37",
+ "194.59.215.49",
+ "194.59.215.51",
+ "194.59.215.242",
+ "194.59.215.246",
+ "194.60.209.91",
+ "194.60.210.66",
+ "194.60.210.67",
+ "194.60.230.25",
+ "194.60.230.28",
+ "194.60.230.50",
+ "194.60.230.53",
+ "194.60.230.55",
+ "194.60.230.58",
+ "194.60.230.75",
+ "194.60.230.78",
+ "194.60.230.84",
+ "194.60.230.88",
+ "194.60.230.92",
+ "194.60.230.148",
+ "194.60.230.161",
+ "194.60.230.174",
+ "194.60.230.194",
+ "194.60.230.195",
+ "194.60.230.203",
+ "194.60.230.208",
+ "194.60.231.12",
+ "194.60.231.30",
+ "194.60.231.34",
+ "194.60.231.47",
+ "194.60.231.77",
+ "194.60.231.84",
+ "194.60.231.112",
+ "194.60.231.122",
+ "194.60.231.149",
+ "194.60.231.156",
+ "194.60.231.157",
+ "194.60.231.182",
+ "194.60.231.196",
+ "194.60.231.234",
+ "194.62.17.18",
+ "194.62.17.22",
+ "194.62.17.26",
+ "194.62.17.43",
+ "194.62.17.50",
+ "194.62.17.59",
+ "194.62.17.60",
+ "194.62.17.70",
+ "194.62.17.146",
+ "194.62.17.155",
+ "194.62.17.174",
+ "194.62.17.178",
+ "194.62.17.190",
+ "194.62.17.203",
+ "194.62.17.206",
+ "194.62.17.212",
+ "194.62.17.234",
+ "194.62.17.254",
+ "194.62.43.5",
+ "194.62.43.6",
+ "194.62.43.14",
+ "194.62.43.15",
+ "194.62.43.44",
+ "194.62.43.45",
+ "194.62.43.55",
+ "194.62.43.58",
+ "194.62.43.66",
+ "194.62.43.67",
+ "194.62.43.80",
+ "194.62.43.83",
+ "194.62.43.91",
+ "194.62.43.92",
+ "194.62.43.94",
+ "194.62.43.99",
+ "194.62.43.100",
+ "194.62.43.101",
+ "194.62.43.102",
+ "194.62.43.104",
+ "194.62.43.108",
+ "194.62.43.123",
+ "194.62.43.126",
+ "194.62.43.129",
+ "194.62.43.139",
+ "194.62.43.140",
+ "194.62.43.141",
+ "194.62.43.146",
+ "194.62.43.155",
+ "194.62.43.175",
+ "194.62.43.180",
+ "194.62.43.183",
+ "194.62.43.184",
+ "194.62.43.194",
+ "194.62.43.207",
+ "194.62.43.208",
+ "194.62.43.216",
+ "194.62.43.218",
+ "194.62.43.227",
+ "194.62.43.233",
+ "194.62.43.236",
+ "194.62.43.237",
+ "194.62.43.238",
+ "194.62.43.240",
+ "194.62.43.241",
+ "194.143.140.9",
+ "194.143.141.9",
+ "194.146.151.18",
+ "194.146.151.19",
+ "194.146.151.20",
+ "194.146.151.22",
+ "194.147.142.10",
+ "194.147.142.29",
+ "194.147.142.35",
+ "194.147.142.39",
+ "194.147.142.41",
+ "194.147.142.44",
+ "194.147.142.57",
+ "194.147.142.64",
+ "194.147.142.67",
+ "194.147.142.71",
+ "194.147.142.72",
+ "194.147.142.78",
+ "194.147.142.79",
+ "194.147.142.82",
+ "194.147.142.94",
+ "194.147.142.100",
+ "194.147.142.104",
+ "194.147.142.122",
+ "194.147.142.123",
+ "194.147.142.125",
+ "194.147.142.131",
+ "194.147.142.136",
+ "194.147.142.153",
+ "194.147.142.174",
+ "194.147.142.180",
+ "194.147.142.186",
+ "194.147.142.192",
+ "194.147.142.195",
+ "194.147.142.200",
+ "194.147.142.213",
+ "194.147.142.218",
+ "194.147.142.233",
+ "194.147.142.239",
+ "194.147.142.242",
+ "194.147.142.243",
+ "194.147.142.250",
+ "194.147.164.49",
+ "194.147.222.37",
+ "194.147.222.53",
+ "194.147.222.68",
+ "194.147.222.76",
+ "194.147.222.82",
+ "194.147.222.84",
+ "194.147.222.85",
+ "194.147.222.86",
+ "194.147.222.87",
+ "194.147.222.94",
+ "194.147.222.96",
+ "194.147.222.131",
+ "194.147.222.137",
+ "194.147.222.143",
+ "194.147.222.144",
+ "194.147.222.146",
+ "194.147.222.150",
+ "194.147.222.153",
+ "194.147.222.162",
+ "194.147.222.176",
+ "194.147.222.228",
+ "194.147.222.229",
+ "194.147.222.230",
+ "194.150.68.28",
+ "194.150.68.29",
+ "194.150.68.44",
+ "194.150.68.45",
+ "194.150.68.51",
+ "194.150.69.119",
+ "194.150.69.164",
+ "194.150.70.11",
+ "194.150.70.12",
+ "194.150.71.198",
+ "194.150.71.230",
+ "194.180.11.12",
+ "194.180.11.14",
+ "194.180.11.17",
+ "194.180.11.26",
+ "194.180.11.28",
+ "194.180.11.37",
+ "194.180.11.43",
+ "194.180.11.56",
+ "194.180.11.64",
+ "194.180.11.79",
+ "194.180.11.85",
+ "194.180.11.94",
+ "194.180.11.110",
+ "194.180.11.117",
+ "194.180.11.118",
+ "194.180.11.128",
+ "194.180.11.134",
+ "194.180.11.142",
+ "194.180.11.148",
+ "194.180.11.153",
+ "194.180.11.177",
+ "194.180.11.185",
+ "194.180.11.204",
+ "194.180.11.206",
+ "194.180.11.212",
+ "194.180.11.213",
+ "194.180.11.216",
+ "194.180.11.217",
+ "194.180.11.219",
+ "194.180.11.225",
+ "194.180.11.226",
+ "194.180.11.229",
+ "194.180.11.233",
+ "194.180.11.236",
+ "194.180.11.243",
+ "194.180.11.254",
+ "194.225.16.3",
+ "194.225.24.20",
+ "194.225.25.15",
+ "194.225.25.16",
+ "194.225.40.49",
+ "194.225.40.114",
+ "194.225.50.6",
+ "194.225.62.66",
+ "194.225.62.80",
+ "194.225.62.98",
+ "194.225.62.107",
+ "194.225.73.141",
+ "194.225.73.151",
+ "194.225.90.4",
+ "194.225.90.5",
+ "194.225.92.15",
+ "194.225.92.17",
+ "194.225.100.42",
+ "194.225.100.43",
+ "194.225.106.21",
+ "194.225.106.22",
+ "194.225.115.9",
+ "194.225.115.10",
+ "194.225.117.10",
+ "194.225.131.64",
+ "194.225.133.40",
+ "194.225.136.3",
+ "194.225.136.4",
+ "194.225.144.2",
+ "194.225.144.3",
+ "194.225.152.10",
+ "194.225.152.12",
+ "194.225.166.7",
+ "194.225.166.8",
+ "194.225.183.61",
+ "194.225.183.62",
+ "194.225.228.4",
+ "194.225.228.5",
+ "195.24.233.75",
+ "195.28.11.3",
+ "195.28.11.27",
+ "195.28.11.35",
+ "195.28.11.37",
+ "195.28.11.47",
+ "195.28.11.58",
+ "195.28.11.60",
+ "195.28.11.63",
+ "195.28.11.64",
+ "195.28.11.67",
+ "195.28.11.68",
+ "195.28.11.70",
+ "195.28.11.99",
+ "195.28.11.104",
+ "195.28.11.109",
+ "195.28.11.156",
+ "195.28.11.179",
+ "195.28.11.220",
+ "195.28.11.236",
+ "195.28.11.249",
+ "195.28.11.250",
+ "195.28.11.251",
+ "195.28.11.253",
+ "195.28.169.201",
+ "195.28.169.248",
+ "195.28.169.253",
+ "195.62.4.20",
+ "195.62.4.21",
+ "195.62.4.22",
+ "195.62.4.24",
+ "195.62.4.25",
+ "195.62.4.26",
+ "195.88.189.70",
+ "195.88.189.71",
+ "195.88.189.74",
+ "195.88.189.76",
+ "195.88.189.77",
+ "195.88.189.79",
+ "195.88.189.81",
+ "195.88.189.84",
+ "195.88.189.86",
+ "195.88.189.91",
+ "195.88.189.98",
+ "195.88.189.101",
+ "195.88.189.110",
+ "195.88.189.111",
+ "195.88.189.112",
+ "195.88.208.7",
+ "195.88.208.9",
+ "195.88.208.15",
+ "195.88.208.17",
+ "195.88.208.28",
+ "195.88.208.49",
+ "195.88.208.50",
+ "195.88.208.53",
+ "195.88.208.67",
+ "195.88.208.82",
+ "195.88.208.107",
+ "195.88.208.111",
+ "195.88.208.112",
+ "195.88.208.115",
+ "195.88.208.123",
+ "195.88.208.125",
+ "195.88.208.130",
+ "195.88.208.134",
+ "195.88.208.139",
+ "195.88.208.141",
+ "195.88.208.143",
+ "195.88.208.147",
+ "195.88.208.149",
+ "195.88.208.157",
+ "195.88.208.164",
+ "195.88.208.167",
+ "195.88.208.180",
+ "195.88.208.181",
+ "195.88.208.198",
+ "195.88.208.204",
+ "195.88.208.207",
+ "195.88.208.210",
+ "195.88.208.216",
+ "195.88.208.236",
+ "195.88.208.237",
+ "195.88.208.241",
+ "195.96.128.24",
+ "195.96.128.130",
+ "195.96.128.144",
+ "195.96.128.148",
+ "195.110.38.129",
+ "195.110.38.141",
+ "195.110.38.156",
+ "195.110.38.190",
+ "195.110.38.203",
+ "195.110.38.205",
+ "195.110.38.214",
+ "195.110.38.217",
+ "195.110.38.223",
+ "195.110.38.230",
+ "195.110.38.232",
+ "195.110.38.234",
+ "195.110.38.244",
+ "195.110.38.245",
+ "195.110.38.246",
+ "195.110.38.248",
+ "195.110.39.192",
+ "195.110.39.194",
+ "195.110.39.195",
+ "195.110.39.198",
+ "195.110.39.199",
+ "195.110.39.220",
+ "195.110.39.221",
+ "195.110.39.222",
+ "195.110.39.223",
+ "195.114.4.16",
+ "195.114.4.21",
+ "195.114.4.23",
+ "195.114.4.25",
+ "195.114.4.117",
+ "195.114.4.180",
+ "195.114.4.182",
+ "195.114.5.243",
+ "195.114.8.10",
+ "195.146.59.62",
+ "195.146.59.249",
+ "195.146.59.253",
+ "195.146.60.2",
+ "195.177.255.4",
+ "195.177.255.15",
+ "195.177.255.30",
+ "195.177.255.47",
+ "195.177.255.54",
+ "195.177.255.60",
+ "195.177.255.64",
+ "195.177.255.74",
+ "195.177.255.89",
+ "195.177.255.90",
+ "195.177.255.95",
+ "195.177.255.103",
+ "195.177.255.120",
+ "195.177.255.125",
+ "195.177.255.126",
+ "195.177.255.132",
+ "195.177.255.136",
+ "195.177.255.141",
+ "195.177.255.142",
+ "195.177.255.164",
+ "195.177.255.169",
+ "195.177.255.170",
+ "195.177.255.180",
+ "195.177.255.184",
+ "195.177.255.187",
+ "195.177.255.201",
+ "195.177.255.205",
+ "195.177.255.208",
+ "195.177.255.217",
+ "195.177.255.226",
+ "195.177.255.253",
+ "195.181.12.184",
+ "195.181.41.225",
+ "195.181.41.229",
+ "195.181.81.185",
+ "195.181.84.14",
+ "195.181.91.99",
+ "195.191.74.141",
+ "195.200.77.125",
+ "195.200.77.134",
+ "195.200.77.135",
+ "195.200.77.136",
+ "195.200.77.194",
+ "195.200.77.227",
+ "195.200.77.230",
+ "195.200.77.242",
+ "195.200.77.243",
+ "195.200.77.244",
+ "195.200.77.245",
+ "195.200.77.251",
+ "195.211.44.16",
+ "195.211.44.17",
+ "195.211.44.21",
+ "195.211.44.24",
+ "195.211.44.41",
+ "195.211.44.69",
+ "195.211.44.76",
+ "195.211.44.96",
+ "195.211.44.104",
+ "195.211.44.107",
+ "195.211.44.120",
+ "195.211.44.136",
+ "195.211.44.138",
+ "195.211.44.160",
+ "195.211.44.161",
+ "195.211.44.162",
+ "195.211.44.173",
+ "195.211.44.211",
+ "195.211.44.216",
+ "195.211.44.218",
+ "195.211.44.223",
+ "195.211.44.227",
+ "195.211.44.232",
+ "195.211.44.235",
+ "195.211.45.169",
+ "195.211.45.184",
+ "195.211.45.190",
+ "195.211.45.230",
+ "195.211.45.239",
+ "195.211.45.240",
+ "195.211.45.255",
+ "195.211.46.64",
+ "195.211.46.65",
+ "195.211.46.111",
+ "195.211.46.117",
+ "195.211.46.211",
+ "195.211.46.212",
+ "195.211.46.242",
+ "195.211.47.24",
+ "195.211.47.27",
+ "195.211.47.65",
+ "195.211.47.199",
+ "195.211.47.213",
+ "195.211.47.220",
+ "195.214.235.3",
+ "195.214.235.4",
+ "195.214.235.5",
+ "195.214.235.11",
+ "195.214.235.12",
+ "195.214.235.13",
+ "195.214.235.14",
+ "195.214.235.19",
+ "195.214.235.20",
+ "195.214.235.21",
+ "195.214.235.22",
+ "195.214.235.46",
+ "195.214.235.56",
+ "195.214.235.57",
+ "195.214.235.62",
+ "195.214.235.92",
+ "195.214.235.99",
+ "195.214.235.100",
+ "195.214.235.101",
+ "195.214.235.102",
+ "195.214.235.114",
+ "195.214.235.116",
+ "195.214.235.117",
+ "195.214.235.118",
+ "195.214.235.119",
+ "195.214.235.121",
+ "195.214.235.122",
+ "195.214.235.123",
+ "195.214.235.124",
+ "195.214.235.141",
+ "195.214.235.142",
+ "195.214.235.147",
+ "195.214.235.148",
+ "195.214.235.163",
+ "195.214.235.164",
+ "195.214.235.171",
+ "195.214.235.172",
+ "195.214.235.179",
+ "195.214.235.180",
+ "195.214.235.181",
+ "195.214.235.182",
+ "195.214.235.206",
+ "195.214.235.216",
+ "195.226.223.3",
+ "195.226.223.6",
+ "195.226.223.11",
+ "195.226.223.13",
+ "195.226.223.14",
+ "195.226.223.44",
+ "195.226.223.70",
+ "195.226.223.100",
+ "195.226.223.131",
+ "195.226.223.134",
+ "195.226.223.135",
+ "195.226.223.140",
+ "195.226.223.147",
+ "195.226.223.155",
+ "195.226.223.157",
+ "195.226.223.211",
+ "195.226.223.213",
+ "195.230.107.2",
+ "195.230.107.49",
+ "195.230.107.130",
+ "195.234.191.130",
+ "195.234.191.133",
+ "195.234.191.137",
+ "195.234.191.138",
+ "195.234.191.141",
+ "195.234.191.144",
+ "195.234.191.197",
+ "195.234.191.200",
+ "195.238.231.8",
+ "195.238.231.55",
+ "195.238.231.56",
+ "195.238.231.132",
+ "195.238.231.133",
+ "195.238.231.134",
+ "195.238.231.146",
+ "195.238.231.187",
+ "195.238.231.234",
+ "195.238.231.245",
+ "195.238.240.2",
+ "195.238.240.5",
+ "195.238.240.19",
+ "195.238.240.22",
+ "195.238.240.91",
+ "195.238.240.215",
+ "195.245.70.210",
+ "212.16.64.74",
+ "212.16.68.4",
+ "212.16.70.4",
+ "212.16.70.8",
+ "212.16.70.19",
+ "212.16.76.19",
+ "212.16.76.72",
+ "212.16.76.117",
+ "212.16.76.119",
+ "212.16.76.120",
+ "212.16.76.250",
+ "212.16.82.16",
+ "212.16.84.147",
+ "212.16.84.148",
+ "212.16.86.4",
+ "212.16.86.15",
+ "212.16.88.21",
+ "212.16.88.22",
+ "212.16.89.20",
+ "212.16.89.25",
+ "212.16.95.143",
+ "212.23.201.8",
+ "212.23.201.10",
+ "212.23.201.13",
+ "212.23.201.15",
+ "212.23.201.27",
+ "212.23.201.29",
+ "212.23.201.30",
+ "212.23.201.36",
+ "212.23.201.41",
+ "212.23.201.44",
+ "212.23.201.50",
+ "212.23.201.53",
+ "212.23.201.57",
+ "212.23.201.58",
+ "212.23.201.70",
+ "212.23.201.72",
+ "212.23.201.73",
+ "212.23.201.74",
+ "212.23.201.75",
+ "212.23.201.76",
+ "212.23.201.86",
+ "212.23.201.91",
+ "212.23.201.92",
+ "212.23.201.93",
+ "212.23.201.95",
+ "212.23.201.98",
+ "212.23.201.101",
+ "212.23.201.103",
+ "212.23.201.104",
+ "212.23.201.107",
+ "212.23.201.114",
+ "212.23.201.116",
+ "212.23.201.118",
+ "212.23.201.122",
+ "212.23.201.123",
+ "212.23.201.133",
+ "212.23.201.135",
+ "212.23.201.143",
+ "212.23.201.147",
+ "212.23.201.151",
+ "212.23.201.154",
+ "212.23.201.158",
+ "212.23.201.159",
+ "212.23.201.162",
+ "212.23.201.165",
+ "212.23.201.168",
+ "212.23.201.170",
+ "212.23.201.172",
+ "212.23.201.174",
+ "212.23.201.176",
+ "212.23.201.177",
+ "212.23.201.182",
+ "212.23.201.186",
+ "212.23.201.192",
+ "212.23.201.196",
+ "212.23.201.203",
+ "212.23.201.205",
+ "212.23.201.208",
+ "212.23.201.216",
+ "212.23.201.218",
+ "212.23.201.220",
+ "212.23.201.225",
+ "212.23.201.232",
+ "212.23.201.248",
+ "212.23.201.251",
+ "212.23.216.25",
+ "212.23.216.55",
+ "212.23.216.56",
+ "212.23.216.60",
+ "212.23.216.100",
+ "212.23.216.117",
+ "212.23.216.121",
+ "212.23.216.125",
+ "212.23.216.150",
+ "212.23.216.152",
+ "212.33.194.26",
+ "212.33.194.27",
+ "212.33.194.28",
+ "212.33.194.29",
+ "212.33.194.30",
+ "212.33.194.58",
+ "212.33.194.60",
+ "212.33.194.108",
+ "212.33.194.148",
+ "212.33.194.149",
+ "212.33.195.66",
+ "212.33.195.80",
+ "212.33.195.85",
+ "212.33.195.86",
+ "212.33.195.88",
+ "212.33.195.91",
+ "212.33.195.92",
+ "212.33.195.93",
+ "212.33.195.94",
+ "212.33.195.165",
+ "212.33.195.166",
+ "212.33.195.168",
+ "212.33.195.252",
+ "212.33.197.69",
+ "212.33.197.71",
+ "212.33.197.82",
+ "212.33.197.85",
+ "212.33.197.92",
+ "212.33.197.94",
+ "212.33.197.100",
+ "212.33.197.124",
+ "212.33.197.131",
+ "212.33.198.15",
+ "212.33.198.57",
+ "212.33.198.60",
+ "212.33.198.90",
+ "212.33.198.227",
+ "212.33.201.26",
+ "212.33.201.27",
+ "212.33.201.55",
+ "212.33.201.133",
+ "212.33.201.143",
+ "212.33.201.167",
+ "212.33.201.215",
+ "212.33.201.220",
+ "212.33.202.21",
+ "212.33.202.24",
+ "212.33.202.76",
+ "212.33.202.97",
+ "212.33.202.107",
+ "212.33.202.113",
+ "212.33.202.122",
+ "212.33.202.153",
+ "212.33.202.167",
+ "212.33.202.192",
+ "212.33.202.213",
+ "212.33.202.214",
+ "212.33.202.215",
+ "212.33.202.216",
+ "212.33.202.227",
+ "212.33.203.10",
+ "212.33.203.92",
+ "212.33.203.186",
+ "212.33.203.187",
+ "212.33.203.188",
+ "212.33.203.189",
+ "212.33.203.190",
+ "212.33.203.226",
+ "212.33.204.93",
+ "212.33.205.21",
+ "212.33.205.55",
+ "212.33.205.81",
+ "212.33.205.82",
+ "212.33.205.95",
+ "212.33.205.96",
+ "212.33.205.99",
+ "212.33.205.110",
+ "212.33.205.186",
+ "212.33.205.223",
+ "212.33.205.254",
+ "212.33.206.11",
+ "212.33.206.20",
+ "212.33.206.46",
+ "212.33.206.55",
+ "212.33.206.93",
+ "212.33.206.138",
+ "212.33.206.140",
+ "212.33.206.156",
+ "212.33.206.168",
+ "212.33.206.199",
+ "212.33.206.205",
+ "212.33.206.239",
+ "212.33.217.224",
+ "212.33.222.179",
+ "212.80.5.205",
+ "212.80.8.70",
+ "212.80.8.84",
+ "212.80.8.103",
+ "212.80.8.105",
+ "212.80.8.115",
+ "212.80.8.212",
+ "212.80.9.228",
+ "212.80.9.229",
+ "212.80.9.230",
+ "212.80.9.231",
+ "212.80.9.235",
+ "212.80.10.252",
+ "212.80.10.253",
+ "212.80.16.72",
+ "212.80.18.83",
+ "212.80.18.182",
+ "212.80.18.213",
+ "212.80.19.2",
+ "212.80.19.12",
+ "212.80.19.244",
+ "212.80.20.92",
+ "212.80.20.93",
+ "212.80.20.101",
+ "212.80.20.132",
+ "212.80.20.134",
+ "212.80.20.165",
+ "212.80.21.10",
+ "212.80.21.68",
+ "212.80.21.157",
+ "212.80.21.179",
+ "212.80.21.184",
+ "212.80.22.18",
+ "212.80.22.22",
+ "212.80.25.138",
+ "212.80.25.217",
+ "212.80.27.250",
+ "212.80.30.189",
+ "212.80.30.190",
+ "212.86.64.99",
+ "212.86.64.100",
+ "212.86.64.193",
+ "212.86.66.11",
+ "212.86.66.50",
+ "212.86.66.90",
+ "212.86.66.96",
+ "212.86.67.138",
+ "212.86.67.147",
+ "212.86.67.149",
+ "212.86.74.64",
+ "212.86.74.148",
+ "212.86.76.69",
+ "212.86.77.54",
+ "212.86.79.180",
+ "212.86.79.184",
+ "212.86.79.188",
+ "212.86.79.189",
+ "212.120.192.7",
+ "212.120.192.10",
+ "212.120.192.13",
+ "212.120.192.21",
+ "212.120.198.165",
+ "212.120.200.58",
+ "212.120.201.176",
+ "212.120.205.150",
+ "212.120.208.80",
+ "212.120.211.206",
+ "212.120.214.42",
+ "212.120.214.61",
+ "212.120.214.230",
+ "212.120.223.248",
+ "213.108.240.52",
+ "213.108.240.53",
+ "213.108.240.54",
+ "213.108.240.67",
+ "213.108.240.82",
+ "213.108.240.86",
+ "213.108.240.91",
+ "213.108.240.131",
+ "213.108.240.132",
+ "213.108.240.134",
+ "213.108.240.136",
+ "213.108.240.141",
+ "213.108.240.143",
+ "213.108.240.144",
+ "213.108.240.145",
+ "213.108.240.151",
+ "213.108.240.152",
+ "213.108.240.155",
+ "213.108.240.157",
+ "213.108.240.158",
+ "213.108.240.162",
+ "213.108.240.167",
+ "213.108.240.169",
+ "213.108.240.170",
+ "213.108.240.173",
+ "213.108.240.180",
+ "213.108.240.194",
+ "213.108.240.204",
+ "213.108.240.205",
+ "213.108.241.73",
+ "213.108.241.106",
+ "213.108.241.110",
+ "213.108.241.132",
+ "213.108.241.133",
+ "213.108.241.135",
+ "213.108.241.140",
+ "213.108.241.145",
+ "213.108.241.146",
+ "213.108.241.155",
+ "213.108.241.196",
+ "213.108.241.199",
+ "213.108.241.200",
+ "213.108.241.216",
+ "213.108.241.235",
+ "213.108.241.237",
+ "213.108.241.243",
+ "213.108.242.211",
+ "213.108.242.215",
+ "213.108.242.216",
+ "213.108.242.217",
+ "213.108.242.219",
+ "213.108.242.250",
+ "213.109.199.133",
+ "213.176.1.165",
+ "213.176.1.194",
+ "213.176.5.20",
+ "213.176.5.21",
+ "213.176.6.146",
+ "213.176.6.153",
+ "213.176.6.198",
+ "213.176.7.126",
+ "213.176.7.151",
+ "213.176.28.37",
+ "213.176.28.45",
+ "213.176.28.91",
+ "213.176.28.143",
+ "213.176.28.149",
+ "213.176.28.151",
+ "213.176.28.170",
+ "213.176.28.199",
+ "213.176.28.231",
+ "213.176.28.245",
+ "213.176.28.247",
+ "213.176.29.6",
+ "213.176.29.7",
+ "213.176.29.8",
+ "213.176.29.9",
+ "213.176.29.26",
+ "213.176.29.31",
+ "213.176.29.32",
+ "213.176.29.33",
+ "213.176.29.34",
+ "213.176.29.35",
+ "213.176.29.58",
+ "213.176.29.63",
+ "213.176.29.66",
+ "213.176.29.75",
+ "213.176.29.78",
+ "213.176.29.85",
+ "213.176.29.87",
+ "213.176.29.88",
+ "213.176.29.89",
+ "213.176.29.107",
+ "213.176.29.108",
+ "213.176.29.115",
+ "213.176.29.121",
+ "213.176.29.124",
+ "213.176.29.125",
+ "213.176.29.126",
+ "213.176.29.128",
+ "213.176.29.132",
+ "213.176.29.133",
+ "213.176.29.141",
+ "213.176.29.142",
+ "213.176.29.145",
+ "213.176.29.151",
+ "213.176.29.158",
+ "213.176.29.159",
+ "213.176.29.161",
+ "213.176.29.162",
+ "213.176.29.163",
+ "213.176.29.189",
+ "213.176.29.192",
+ "213.176.29.201",
+ "213.176.29.207",
+ "213.176.29.208",
+ "213.176.29.209",
+ "213.176.29.212",
+ "213.176.29.214",
+ "213.176.29.219",
+ "213.176.29.229",
+ "213.176.29.236",
+ "213.176.29.243",
+ "213.176.29.244",
+ "213.176.29.246",
+ "213.176.31.7",
+ "213.176.31.66",
+ "213.176.31.74",
+ "213.176.31.98",
+ "213.176.31.99",
+ "213.176.31.110",
+ "213.176.31.122",
+ "213.176.31.154",
+ "213.176.31.214",
+ "213.176.120.9",
+ "213.176.120.34",
+ "213.176.120.40",
+ "213.176.120.114",
+ "213.176.120.130",
+ "213.176.121.78",
+ "213.176.123.5",
+ "213.195.22.3",
+ "213.195.22.4",
+ "213.195.22.106",
+ "213.195.22.238",
+ "213.195.56.113",
+ "213.195.58.167",
+ "213.207.192.19",
+ "213.207.198.66",
+ "213.207.203.90",
+ "213.207.203.211",
+ "213.207.204.10",
+ "213.207.204.66",
+ "213.207.209.21",
+ "213.207.250.50",
+ "213.207.250.59",
+ "213.207.250.90",
+ "213.232.124.4",
+ "213.232.124.10",
+ "213.232.124.34",
+ "213.232.124.78",
+ "213.232.124.154",
+ "213.232.124.222",
+ "213.232.125.115",
+ "213.232.125.186",
+ "213.232.126.49",
+ "213.232.126.180",
+ "213.232.126.235",
+ "213.232.126.236",
+ "213.232.126.237",
+ "213.233.161.81",
+ "213.233.161.190",
+ "213.233.173.10",
+ "213.233.176.155",
+ "213.233.176.156",
+ "213.233.177.172",
+ "213.233.177.219",
+ "213.233.177.221",
+ "213.233.178.82",
+ "213.233.178.102",
+ "213.233.178.133",
+ "213.233.178.226",
+ "213.233.182.147",
+ "213.233.182.236",
+ "213.233.184.221",
+ "217.11.18.100",
+ "217.11.18.190",
+ "217.11.19.10",
+ "217.11.20.217",
+ "217.11.20.227",
+ "217.11.21.11",
+ "217.11.23.6",
+ "217.11.24.166",
+ "217.11.27.116",
+ "217.11.27.117",
+ "217.11.28.51",
+ "217.11.28.53",
+ "217.11.29.178",
+ "217.11.29.184",
+ "217.11.29.186",
+ "217.11.29.187",
+ "217.11.29.188",
+ "217.11.29.190",
+ "217.11.29.191",
+ "217.20.252.9",
+ "217.20.252.12",
+ "217.20.252.20",
+ "217.20.252.24",
+ "217.20.252.42",
+ "217.20.252.68",
+ "217.20.252.249",
+ "217.24.147.254",
+ "217.26.222.2",
+ "217.26.222.234",
+ "217.60.243.221",
+ "217.60.243.244",
+ "217.66.200.240",
+ "217.66.215.114",
+ "217.114.40.18",
+ "217.114.40.19",
+ "217.114.40.32",
+ "217.114.40.34",
+ "217.114.40.43",
+ "217.114.40.49",
+ "217.114.40.54",
+ "217.114.40.75",
+ "217.114.40.104",
+ "217.114.40.107",
+ "217.114.40.112",
+ "217.114.40.203",
+ "217.114.40.206",
+ "217.114.40.215",
+ "217.114.40.216",
+ "217.114.40.246",
+ "217.114.46.156",
+ "217.114.46.157",
+ "217.144.104.6",
+ "217.144.104.7",
+ "217.144.104.9",
+ "217.144.104.11",
+ "217.144.104.13",
+ "217.144.104.14",
+ "217.144.104.15",
+ "217.144.104.16",
+ "217.144.104.18",
+ "217.144.104.19",
+ "217.144.104.21",
+ "217.144.104.22",
+ "217.144.104.23",
+ "217.144.104.25",
+ "217.144.104.26",
+ "217.144.104.27",
+ "217.144.104.35",
+ "217.144.104.37",
+ "217.144.104.42",
+ "217.144.104.44",
+ "217.144.104.47",
+ "217.144.104.49",
+ "217.144.104.50",
+ "217.144.104.54",
+ "217.144.104.56",
+ "217.144.104.58",
+ "217.144.104.64",
+ "217.144.104.65",
+ "217.144.104.68",
+ "217.144.104.69",
+ "217.144.104.70",
+ "217.144.104.74",
+ "217.144.104.78",
+ "217.144.104.80",
+ "217.144.104.82",
+ "217.144.104.83",
+ "217.144.104.84",
+ "217.144.104.87",
+ "217.144.104.88",
+ "217.144.104.92",
+ "217.144.104.95",
+ "217.144.104.97",
+ "217.144.104.100",
+ "217.144.104.101",
+ "217.144.104.102",
+ "217.144.104.106",
+ "217.144.104.111",
+ "217.144.104.112",
+ "217.144.104.113",
+ "217.144.104.119",
+ "217.144.104.120",
+ "217.144.104.122",
+ "217.144.104.123",
+ "217.144.104.127",
+ "217.144.104.128",
+ "217.144.104.129",
+ "217.144.104.130",
+ "217.144.104.131",
+ "217.144.104.133",
+ "217.144.104.134",
+ "217.144.104.136",
+ "217.144.104.139",
+ "217.144.104.141",
+ "217.144.104.142",
+ "217.144.104.146",
+ "217.144.104.155",
+ "217.144.104.159",
+ "217.144.104.160",
+ "217.144.104.161",
+ "217.144.104.162",
+ "217.144.104.163",
+ "217.144.104.166",
+ "217.144.104.168",
+ "217.144.104.170",
+ "217.144.104.173",
+ "217.144.104.174",
+ "217.144.104.177",
+ "217.144.104.178",
+ "217.144.104.179",
+ "217.144.104.180",
+ "217.144.104.182",
+ "217.144.104.184",
+ "217.144.104.185",
+ "217.144.104.189",
+ "217.144.104.190",
+ "217.144.104.191",
+ "217.144.104.193",
+ "217.144.104.197",
+ "217.144.104.203",
+ "217.144.104.205",
+ "217.144.104.210",
+ "217.144.104.212",
+ "217.144.104.214",
+ "217.144.104.217",
+ "217.144.104.218",
+ "217.144.104.222",
+ "217.144.104.225",
+ "217.144.104.226",
+ "217.144.104.227",
+ "217.144.104.234",
+ "217.144.104.235",
+ "217.144.104.242",
+ "217.144.104.243",
+ "217.144.104.249",
+ "217.144.104.250",
+ "217.144.104.254",
+ "217.144.105.39",
+ "217.144.105.42",
+ "217.144.105.49",
+ "217.144.105.52",
+ "217.144.105.57",
+ "217.144.105.58",
+ "217.144.105.61",
+ "217.144.105.63",
+ "217.144.105.73",
+ "217.144.105.77",
+ "217.144.105.79",
+ "217.144.105.80",
+ "217.144.105.84",
+ "217.144.105.90",
+ "217.144.105.94",
+ "217.144.105.101",
+ "217.144.105.156",
+ "217.144.105.163",
+ "217.144.105.168",
+ "217.144.105.169",
+ "217.144.105.175",
+ "217.144.105.176",
+ "217.144.105.181",
+ "217.144.105.195",
+ "217.144.105.197",
+ "217.144.105.198",
+ "217.144.105.200",
+ "217.144.105.205",
+ "217.144.105.206",
+ "217.144.105.207",
+ "217.144.105.209",
+ "217.144.105.210",
+ "217.144.105.212",
+ "217.144.105.217",
+ "217.144.105.218",
+ "217.144.105.221",
+ "217.144.105.226",
+ "217.144.105.230",
+ "217.144.105.233",
+ "217.144.105.252",
+ "217.144.105.254",
+ "217.144.106.7",
+ "217.144.106.11",
+ "217.144.106.16",
+ "217.144.106.17",
+ "217.144.106.18",
+ "217.144.106.20",
+ "217.144.106.21",
+ "217.144.106.22",
+ "217.144.106.26",
+ "217.144.106.30",
+ "217.144.106.31",
+ "217.144.106.32",
+ "217.144.106.36",
+ "217.144.106.39",
+ "217.144.106.40",
+ "217.144.106.44",
+ "217.144.106.48",
+ "217.144.106.50",
+ "217.144.106.54",
+ "217.144.106.55",
+ "217.144.106.59",
+ "217.144.106.61",
+ "217.144.106.62",
+ "217.144.106.68",
+ "217.144.106.93",
+ "217.144.106.94",
+ "217.144.106.100",
+ "217.144.106.104",
+ "217.144.106.110",
+ "217.144.106.111",
+ "217.144.106.113",
+ "217.144.106.115",
+ "217.144.106.116",
+ "217.144.106.117",
+ "217.144.106.118",
+ "217.144.106.125",
+ "217.144.106.126",
+ "217.144.106.132",
+ "217.144.106.138",
+ "217.144.106.141",
+ "217.144.106.143",
+ "217.144.106.153",
+ "217.144.106.155",
+ "217.144.106.157",
+ "217.144.106.201",
+ "217.144.106.202",
+ "217.144.106.203",
+ "217.144.106.204",
+ "217.144.106.205",
+ "217.144.106.208",
+ "217.144.106.212",
+ "217.144.106.218",
+ "217.144.106.222",
+ "217.144.106.227",
+ "217.144.106.236",
+ "217.144.106.242",
+ "217.144.106.252",
+ "217.144.107.2",
+ "217.144.107.4",
+ "217.144.107.5",
+ "217.144.107.6",
+ "217.144.107.15",
+ "217.144.107.20",
+ "217.144.107.22",
+ "217.144.107.52",
+ "217.144.107.55",
+ "217.144.107.61",
+ "217.144.107.70",
+ "217.144.107.83",
+ "217.144.107.85",
+ "217.144.107.94",
+ "217.144.107.96",
+ "217.144.107.98",
+ "217.144.107.104",
+ "217.144.107.111",
+ "217.144.107.113",
+ "217.144.107.119",
+ "217.144.107.126",
+ "217.144.107.127",
+ "217.144.107.130",
+ "217.144.107.132",
+ "217.144.107.139",
+ "217.144.107.147",
+ "217.144.107.148",
+ "217.144.107.149",
+ "217.144.107.159",
+ "217.144.107.160",
+ "217.144.107.161",
+ "217.144.107.162",
+ "217.144.107.163",
+ "217.144.107.166",
+ "217.144.107.169",
+ "217.144.107.171",
+ "217.144.107.174",
+ "217.144.107.176",
+ "217.144.107.181",
+ "217.144.107.182",
+ "217.144.107.183",
+ "217.144.107.184",
+ "217.144.107.186",
+ "217.144.107.194",
+ "217.144.107.195",
+ "217.144.107.197",
+ "217.144.107.200",
+ "217.144.107.203",
+ "217.144.107.205",
+ "217.144.107.208",
+ "217.144.107.226",
+ "217.144.107.228",
+ "217.144.107.230",
+ "217.144.107.235",
+ "217.144.107.239",
+ "217.144.107.241",
+ "217.144.107.242",
+ "217.144.107.246",
+ "217.144.107.247",
+ "217.146.209.50",
+ "217.170.251.26",
+ "217.170.252.10",
+ "217.170.252.47",
+ "217.170.252.155",
+ "217.170.253.10",
+ "217.172.98.71",
+ "217.172.98.72",
+ "217.172.98.74",
+ "217.172.98.75",
+ "217.172.98.77",
+ "217.172.98.78",
+ "217.172.98.79",
+ "217.172.98.87",
+ "217.172.98.90",
+ "217.172.98.91",
+ "217.172.98.92",
+ "217.172.98.93",
+ "217.172.98.95",
+ "217.172.98.96",
+ "217.172.98.97",
+ "217.172.98.98",
+ "217.172.98.102",
+ "217.172.98.108",
+ "217.172.98.109",
+ "217.172.98.111",
+ "217.172.98.116",
+ "217.172.98.124",
+ "217.172.98.132",
+ "217.172.98.138",
+ "217.172.98.147",
+ "217.172.98.148",
+ "217.172.98.149",
+ "217.172.98.158",
+ "217.172.98.160",
+ "217.172.98.161",
+ "217.172.98.162",
+ "217.172.98.163",
+ "217.172.98.169",
+ "217.172.98.172",
+ "217.172.98.175",
+ "217.172.98.228",
+ "217.172.98.231",
+ "217.172.98.233",
+ "217.172.98.234",
+ "217.172.98.237",
+ "217.172.98.241",
+ "217.172.98.251",
+ "217.172.126.251",
+ "217.198.190.5",
+ "217.198.190.56",
+ "217.198.190.66",
+ "217.198.190.100",
+ "217.198.190.125",
+ "217.198.190.132",
+ "217.198.190.145",
+ "217.198.190.146",
+ "217.198.190.147",
+ "217.198.190.150",
+ "217.198.190.151",
+ "217.198.190.153",
+ "217.198.190.156",
+ "217.198.190.162",
+ "217.198.190.178",
+ "217.198.190.209",
+ "217.198.190.212",
+ "217.198.190.214",
+ "217.198.190.215",
+ "217.198.190.225",
+ "217.218.2.100",
+ "217.218.6.5",
+ "217.218.7.4",
+ "217.218.7.5",
+ "217.218.9.140",
+ "217.218.9.141",
+ "217.218.11.11",
+ "217.218.11.12",
+ "217.218.12.58",
+ "217.218.13.168",
+ "217.218.21.104",
+ "217.218.21.122",
+ "217.218.21.124",
+ "217.218.26.220",
+ "217.218.32.74",
+ "217.218.40.5",
+ "217.218.40.6",
+ "217.218.46.11",
+ "217.218.53.153",
+ "217.218.54.16",
+ "217.218.56.21",
+ "217.218.56.210",
+ "217.218.56.249",
+ "217.218.60.101",
+ "217.218.62.65",
+ "217.218.62.66",
+ "217.218.70.10",
+ "217.218.71.153",
+ "217.218.75.202",
+ "217.218.82.85",
+ "217.218.82.140",
+ "217.218.85.234",
+ "217.218.86.50",
+ "217.218.98.56",
+ "217.218.98.157",
+ "217.218.102.174",
+ "217.218.106.140",
+ "217.218.106.141",
+ "217.218.113.50",
+ "217.218.114.8",
+ "217.218.124.10",
+ "217.218.126.162",
+ "217.218.127.126",
+ "217.218.127.127",
+ "217.218.155.154",
+ "217.218.155.155",
+ "217.218.168.3",
+ "217.218.171.210",
+ "217.218.179.31",
+ "217.218.179.39",
+ "217.218.200.218",
+ "217.218.204.123",
+ "217.218.204.124",
+ "217.218.204.125",
+ "217.218.209.221",
+ "217.218.212.140",
+ "217.218.214.4",
+ "217.218.214.16",
+ "217.218.215.25",
+ "217.218.215.78",
+ "217.218.215.140",
+ "217.218.227.241",
+ "217.218.227.242",
+ "217.218.227.243",
+ "217.218.227.244",
+ "217.218.227.247",
+ "217.218.227.248",
+ "217.218.227.249",
+ "217.218.227.250",
+ "217.218.227.251",
+ "217.218.227.252",
+ "217.218.227.253",
+ "217.218.227.254",
+ "217.218.230.194",
+ "217.218.234.252",
+ "217.218.242.66",
+ "217.218.242.67",
+ "217.218.251.178",
+ "217.219.29.73",
+ "217.219.29.107",
+ "217.219.31.147",
+ "217.219.33.33",
+ "217.219.33.34",
+ "217.219.33.35",
+ "217.219.33.69",
+ "217.219.34.30",
+ "217.219.39.116",
+ "217.219.42.18",
+ "217.219.42.134",
+ "217.219.66.2",
+ "217.219.66.3",
+ "217.219.66.8",
+ "217.219.67.130",
+ "217.219.68.45",
+ "217.219.70.92",
+ "217.219.70.197",
+ "217.219.78.138",
+ "217.219.78.144",
+ "217.219.78.152",
+ "217.219.78.153",
+ "217.219.78.154",
+ "217.219.78.156",
+ "217.219.78.200",
+ "217.219.79.82",
+ "217.219.85.3",
+ "217.219.85.4",
+ "217.219.85.5",
+ "217.219.87.100",
+ "217.219.91.132",
+ "217.219.91.135",
+ "217.219.93.2",
+ "217.219.120.82",
+ "217.219.121.35",
+ "217.219.121.36",
+ "217.219.124.203",
+ "217.219.129.246",
+ "217.219.135.200",
+ "217.219.136.95",
+ "217.219.137.210",
+ "217.219.138.140",
+ "217.219.138.205",
+ "217.219.139.219",
+ "217.219.147.197",
+ "217.219.148.251",
+ "217.219.157.69",
+ "217.219.157.78",
+ "217.219.157.82",
+ "217.219.157.112",
+ "217.219.157.115",
+ "217.219.157.122",
+ "217.219.157.123",
+ "217.219.157.124",
+ "217.219.157.125",
+ "217.219.157.126",
+ "217.219.158.99",
+ "217.219.162.163",
+ "217.219.162.165",
+ "217.219.165.2",
+ "217.219.165.3",
+ "217.219.168.164",
+ "217.219.169.170",
+ "217.219.173.3",
+ "217.219.182.42",
+ "217.219.187.3",
+ "217.219.192.197",
+ "217.219.199.52",
+ "217.219.202.3",
+ "217.219.204.10",
+ "217.219.217.179",
+ "217.219.223.3",
+ "217.219.223.4",
+ "217.219.223.195",
+ "217.219.226.98",
+ "217.219.226.103",
+ "217.219.227.30",
+ "217.219.244.3",
+ "217.219.244.33",
+ "217.219.251.131",
+ "217.219.254.5",
+ "193.134.100.123",
+ "2.179.113.235",
+ "2.179.114.71",
+ "2.187.34.221",
+ "2.179.162.163",
+ "2.182.52.30",
+ "2.179.162.72",
+ "2.190.249.146",
+ "2.176.245.137",
+ "2.176.254.42",
+ "2.177.48.37",
+ "2.177.52.221",
+ "2.177.95.39",
+ "2.177.104.14",
+ "2.177.105.80",
+ "2.177.150.72",
+ "2.177.168.52",
+ "2.178.31.22",
+ "2.182.152.219",
+ "2.182.154.12",
+ "2.190.33.197",
+ "2.190.45.194",
+ "2.190.87.30",
+ "2.190.90.36",
+ "2.190.227.52",
+ "2.190.240.232",
+ "2.191.7.159",
+ "2.191.74.29",
+ "2.191.78.44",
+ "2.191.83.211",
+ "2.191.181.170",
+ "2.177.164.134",
+ "2.180.26.106",
+ "2.190.155.142",
+ "2.176.238.212",
+ "2.177.45.68",
+ "2.177.54.23",
+ "2.177.114.60",
+ "2.178.137.218",
+ "2.190.158.13",
+ "2.190.176.218",
+ "2.176.234.128",
+ "2.176.247.54",
+ "2.176.250.245",
+ "2.177.45.25",
+ "2.177.92.255",
+ "2.177.109.58",
+ "2.177.158.21",
+ "2.177.219.23",
+ "2.178.142.224",
+ "2.178.215.98",
+ "2.178.245.98",
+ "2.178.253.51",
+ "2.179.105.155",
+ "2.179.164.199",
+ "2.179.164.237",
+ "2.184.156.151",
+ "2.190.25.70",
+ "2.190.96.211",
+ "2.190.160.70",
+ "2.190.188.156",
+ "2.190.195.246",
+ "2.191.5.173",
+ "2.191.19.31",
+ "2.191.116.58",
+ "2.176.176.154",
+ "2.176.244.30",
+ "2.177.211.193",
+ "2.180.33.238",
+ "2.182.226.202",
+ "2.183.9.23",
+ "2.183.29.240",
+ "2.190.201.38",
+ "2.190.202.101",
+ "2.191.1.229",
+ "2.176.242.22",
+ "2.177.51.166",
+ "2.177.106.45",
+ "2.177.150.38",
+ "2.178.83.133",
+ "2.180.43.33",
+ "2.182.223.152",
+ "2.186.115.37",
+ "2.189.139.181",
+ "2.189.139.227",
+ "2.189.139.226",
+ "2.189.164.30",
+ "2.190.201.62",
+ "2.191.79.18",
+ "2.191.105.26",
+ "2.191.115.143",
+ "2.191.126.83",
+ "2.191.187.230",
+ "2.177.115.69",
+ "2.178.245.83",
+ "2.182.54.48",
+ "2.191.65.217",
+ "2.189.139.212",
+ "2.191.13.49",
+ "2.191.67.102",
+ "2.176.235.174",
+ "2.176.237.127",
+ "2.176.242.7",
+ "2.177.41.82",
+ "2.177.98.70",
+ "2.177.152.179",
+ "2.178.16.146",
+ "2.178.71.207",
+ "2.179.64.79",
+ "2.179.67.90",
+ "2.179.229.254",
+ "2.180.29.142",
+ "2.180.30.167",
+ "2.182.153.70",
+ "2.190.194.227",
+ "2.191.16.108",
+ "2.176.198.213",
+ "2.176.232.208",
+ "2.176.238.75",
+ "2.176.242.124",
+ "2.177.92.52",
+ "2.177.108.109",
+ "2.177.153.8",
+ "2.177.172.249",
+ "2.177.175.40",
+ "2.177.219.183",
+ "2.177.223.28",
+ "2.178.23.43",
+ "2.178.80.11",
+ "2.178.189.61",
+ "2.179.109.19",
+ "2.179.117.179",
+ "2.182.154.9",
+ "2.182.225.237",
+ "2.189.139.231",
+ "2.190.42.94",
+ "2.190.138.115",
+ "2.190.216.245",
+ "2.191.5.137",
+ "2.191.9.130",
+ "2.177.106.125",
+ "2.177.110.187",
+ "2.177.158.155",
+ "2.177.216.60",
+ "2.178.13.244",
+ "2.178.142.152",
+ "2.178.186.226",
+ "2.180.29.17",
+ "2.189.148.130",
+ "2.177.151.229",
+ "2.177.152.199",
+ "2.177.176.61",
+ "2.178.74.99",
+ "2.183.29.242",
+ "2.184.237.51",
+ "2.189.139.228",
+ "2.191.73.34",
+ "2.177.227.61",
+ "2.178.30.208",
+ "2.178.129.235",
+ "2.178.140.0",
+ "2.178.204.102",
+ "2.180.26.19",
+ "2.190.100.38",
+ "2.190.131.48",
+ "2.190.218.64",
+ "2.190.225.30",
+ "2.191.79.57",
+ "2.191.114.208",
+ "2.191.119.217",
+ "2.191.123.60",
+ "2.176.128.105",
+ "2.176.174.251",
+ "2.176.246.7",
+ "2.177.41.184",
+ "2.177.42.153",
+ "2.177.47.149",
+ "2.177.68.208",
+ "2.177.111.71",
+ "2.177.221.131",
+ "2.178.17.165",
+ "2.178.133.2",
+ "2.179.124.171",
+ "2.182.222.226",
+ "2.189.139.146",
+ "2.189.148.93",
+ "2.189.148.149",
+ "2.190.38.43",
+ "2.190.38.168",
+ "2.191.21.72",
+ "2.191.66.80",
+ "2.177.37.77",
+ "2.177.108.126",
+ "2.177.211.148",
+ "2.177.231.29",
+ "2.189.148.122",
+ "2.189.148.121",
+ "2.189.148.127",
+ "2.189.148.128",
+ "2.191.2.86",
+ "2.191.127.125",
+ "2.177.228.72",
+ "2.179.113.178",
+ "2.179.161.147",
+ "2.177.169.30",
+ "2.191.16.201",
+ "2.191.73.58",
+ "2.176.179.89",
+ "2.177.43.209",
+ "2.177.115.49",
+ "2.177.159.38",
+ "2.177.231.47",
+ "2.182.214.198",
+ "2.189.148.91",
+ "2.189.148.89",
+ "2.189.148.90",
+ "2.189.148.132",
+ "2.190.73.186",
+ "2.190.93.129",
+ "2.178.78.5",
+ "2.190.38.244",
+ "2.177.38.182",
+ "2.177.165.101",
+ "2.178.145.58",
+ "2.180.202.254",
+ "2.182.88.204",
+ "2.186.122.108",
+ "2.190.93.101",
+ "2.190.151.62",
+ "2.177.110.46",
+ "2.182.152.182",
+ "2.187.128.167",
+ "2.180.218.207",
+ "2.180.42.227",
+ "2.181.236.27",
+ "2.181.250.52",
+ "2.183.201.25",
+ "2.184.16.254",
+ "2.185.102.157",
+ "2.185.147.195",
+ "2.186.12.123",
+ "2.187.39.139",
+ "2.187.147.65",
+ "2.190.159.73",
+ "2.191.63.230",
+ "2.191.125.110",
+ "2.182.215.189",
+ "2.189.148.118",
+ "2.189.148.254",
+ "2.176.244.117",
+ "2.189.122.179",
+ "2.189.139.162",
+ "2.189.139.184",
+ "2.190.207.58",
+ "2.191.47.177",
+ "2.185.108.199",
+ "2.190.93.162",
+ "2.177.157.104",
+ "2.181.85.90",
+ "2.189.148.92",
+ "2.189.148.119",
+ "2.191.187.56",
+ "2.188.226.244",
+ "2.180.5.196",
+ "2.189.10.143",
+ "2.177.99.255",
+ "2.180.19.106",
+ "2.189.148.129",
+ "2.190.153.37",
+ "2.180.33.248",
+ "2.182.214.99",
+ "2.189.139.20",
+ "2.180.165.148",
+ "2.189.139.22",
+ "2.190.203.58",
+ "2.179.165.76",
+ "2.191.81.12",
+ "2.181.1.163",
+ "2.178.10.185",
+ "2.179.113.3",
+ "2.190.153.144",
+ "2.191.118.46",
+ "2.179.108.17",
+ "2.188.73.132",
+ "2.184.60.90",
+ "2.178.194.150",
+ "2.191.69.61",
+ "2.144.243.102",
+ "2.176.77.239",
+ "2.176.139.231",
+ "2.176.155.226",
+ "2.176.198.253",
+ "2.176.199.97",
+ "2.176.199.228",
+ "2.176.202.231",
+ "2.176.207.137",
+ "2.176.207.237",
+ "2.176.208.185",
+ "2.176.212.136",
+ "2.176.212.148",
+ "2.176.213.17",
+ "2.176.214.75",
+ "2.176.214.67",
+ "2.176.214.140",
+ "2.176.215.74",
+ "2.176.215.104",
+ "2.176.215.116",
+ "2.176.226.183",
+ "2.176.255.109",
+ "2.176.255.225",
+ "2.177.18.194",
+ "2.177.21.242",
+ "2.177.29.172",
+ "2.177.42.65",
+ "2.177.64.236",
+ "2.177.65.11",
+ "2.177.73.173",
+ "2.177.74.143",
+ "2.177.78.163",
+ "2.177.82.240",
+ "2.177.84.65",
+ "2.177.84.84",
+ "2.177.86.86",
+ "2.177.87.89",
+ "2.177.88.150",
+ "2.177.88.129",
+ "2.177.88.183",
+ "2.177.89.83",
+ "2.177.94.139",
+ "2.177.97.172",
+ "2.177.118.29",
+ "2.177.130.106",
+ "2.177.140.113",
+ "2.177.149.223",
+ "2.177.151.13",
+ "2.177.151.42",
+ "2.177.151.74",
+ "2.177.151.137",
+ "2.177.154.57",
+ "2.177.219.36",
+ "2.177.220.103",
+ "2.177.221.181",
+ "2.177.229.250",
+ "2.177.232.104",
+ "2.177.233.99",
+ "2.177.243.139",
+ "2.177.244.82",
+ "2.178.32.142",
+ "2.178.35.0",
+ "2.178.43.119",
+ "2.178.56.53",
+ "2.178.56.149",
+ "2.178.79.195",
+ "2.178.110.158",
+ "2.178.110.133",
+ "2.178.111.164",
+ "2.178.111.252",
+ "2.178.114.114",
+ "2.178.115.36",
+ "2.178.115.143",
+ "2.178.122.163",
+ "2.178.129.61",
+ "2.178.156.168",
+ "2.178.166.203",
+ "2.178.169.72",
+ "2.178.170.193",
+ "2.178.176.212",
+ "2.178.178.16",
+ "2.178.178.217",
+ "2.178.224.25",
+ "2.179.43.185",
+ "2.179.44.186",
+ "2.179.46.75",
+ "2.179.91.125",
+ "2.179.100.200",
+ "2.179.100.165",
+ "2.179.102.161",
+ "2.179.102.166",
+ "2.179.110.20",
+ "2.179.111.182",
+ "2.179.124.77",
+ "2.179.124.180",
+ "2.180.155.152",
+ "2.180.168.204",
+ "2.181.34.56",
+ "2.181.89.209",
+ "2.181.90.137",
+ "2.181.224.89",
+ "2.181.231.135",
+ "2.182.48.18",
+ "2.182.48.64",
+ "2.182.49.108",
+ "2.182.50.207",
+ "2.182.51.240",
+ "2.182.109.74",
+ "2.182.127.113",
+ "2.182.181.171",
+ "85.185.41.64",
+ "85.185.62.143",
+ "85.185.75.75",
+ "85.185.166.18",
+ "85.185.166.170",
+ "85.185.210.194",
+ "85.185.235.44",
+ "85.185.241.82",
+ "85.185.242.34",
+ "85.185.247.208",
+ "85.204.82.68",
+ "86.104.111.7",
+ "86.104.111.126",
+ "86.105.44.162",
+ "86.107.148.106",
+ "86.107.149.130",
+ "86.107.149.136",
+ "87.107.48.137",
+ "87.107.49.52",
+ "87.107.55.204",
+ "87.107.73.83",
+ "87.107.73.82",
+ "87.107.82.198",
+ "87.107.139.210",
+ "87.107.185.6",
+ "87.251.147.166",
+ "185.206.231.51",
+ "188.121.146.34",
+ "185.8.175.222",
+ "185.192.113.13",
+ "185.213.165.177",
+ "188.136.174.82",
+ "188.136.174.210",
+ "185.110.231.1",
+ "185.121.131.178",
+ "188.0.240.4",
+ "188.211.98.218",
+ "46.100.12.247",
+ "46.100.60.230",
+ "46.100.134.33",
+ "185.46.218.250",
+ "185.46.219.53",
+ "31.7.90.122",
+ "188.75.65.182",
+ "188.75.95.21",
+ "188.211.55.158",
+ "46.245.72.221",
+ "46.245.118.148",
+ "178.252.191.18",
+ "185.111.83.55",
+ "185.112.39.5",
+ "185.112.36.217",
+ "37.114.251.107",
+ "185.172.0.242",
+ "185.169.6.245",
+ "185.206.95.135",
+ "178.236.106.230",
+ "185.46.217.124",
+ "185.46.218.130",
+ "185.44.36.5",
+ "31.7.73.126",
+ "37.255.149.138",
+ "46.100.94.121",
+ "46.245.122.21",
+ "185.79.158.138",
+ "185.112.38.182",
+ "185.112.36.185",
+ "46.34.166.162",
+ "46.100.1.109",
+ "185.140.4.30",
+ "46.245.118.164",
+ "46.245.118.163",
+ "185.193.209.13",
+ "185.175.79.173",
+ "185.193.209.44",
+ "185.214.37.82",
+ "185.193.209.38",
+ "188.211.125.25",
+ "178.239.149.193",
+ "37.153.128.137",
+ "185.110.28.118",
+ "37.255.222.132",
+ "37.255.203.116",
+ "185.162.41.202",
+ "185.193.209.25",
+ "185.186.240.233",
+ "185.193.209.12",
+ "185.175.79.140",
+ "185.193.209.33",
+ "188.210.154.132",
+ "188.211.101.233",
+ "188.211.68.59",
+ "188.209.31.92",
+ "46.245.118.162",
+ "46.245.122.28",
+ "178.131.30.4",
+ "178.131.89.13",
+ "178.131.95.154",
+ "178.131.158.148",
+ "178.131.165.9",
+ "178.131.155.93",
+ "178.173.144.210",
+ "178.173.196.71",
+ "178.239.149.225",
+ "178.239.149.1",
+ "178.239.156.19",
+ "185.83.88.105",
+ "185.110.30.64",
+ "185.112.36.181",
+ "185.112.38.56",
+ "5.201.132.213",
+ "5.201.133.136",
+ "5.201.141.56",
+ "5.201.145.207",
+ "37.153.128.140",
+ "37.255.198.6",
+ "37.202.153.179",
+ "46.38.132.238",
+ "185.106.137.92",
+ "188.75.65.179",
+ "188.75.65.181",
+ "188.211.73.133",
+ "188.210.156.33",
+ "188.213.154.236",
+ "188.211.104.243",
+ "188.213.147.34",
+ "188.211.103.49",
+ "46.245.78.85",
+ "178.131.79.145",
+ "178.131.31.79",
+ "178.173.140.145",
+ "178.173.217.221",
+ "185.193.209.37",
+ "185.193.209.24",
+ "188.211.113.172",
+ "178.131.95.2",
+ "178.131.94.35",
+ "45.142.191.36",
+ "188.75.65.180",
+ "188.75.65.178",
+ "188.211.101.239",
+ "188.211.73.123",
+ "188.211.99.131",
+ "188.209.66.119",
+ "178.131.27.231",
+ "178.131.165.97",
+ "178.131.101.41",
+ "178.131.147.208",
+ "178.131.191.141",
+ "178.173.138.218",
+ "178.173.184.189",
+ "178.173.215.59",
+ "185.193.209.15",
+ "185.193.209.3",
+ "185.193.209.23",
+ "185.175.78.199",
+ "188.208.144.51",
+ "188.209.79.123",
+ "188.211.127.238",
+ "46.235.76.161",
+ "178.131.75.107",
+ "178.131.91.5",
+ "178.131.89.197",
+ "178.131.93.191",
+ "178.236.104.186",
+ "37.153.130.202",
+ "46.100.60.44",
+ "46.245.4.4",
+ "178.131.100.139",
+ "178.131.153.91",
+ "185.120.214.240",
+ "178.173.185.216",
+ "185.162.41.59",
+ "188.211.101.127",
+ "178.131.81.219",
+ "178.131.76.141",
+ "178.131.183.169",
+ "178.173.215.53",
+ "5.201.128.211",
+ "5.201.129.159",
+ "5.201.132.11",
+ "37.143.146.56",
+ "37.148.2.225",
+ "188.211.104.216",
+ "178.131.93.225",
+ "45.8.160.217",
+ "178.131.21.179",
+ "178.131.111.182",
+ "178.131.147.249",
+ "178.131.111.183",
+ "46.34.164.62",
+ "185.175.78.97",
+ "188.211.115.34",
+ "37.202.188.182",
+ "188.210.124.67",
+ "178.131.132.168",
+ "185.3.212.58",
+ "188.209.65.12",
+ "188.211.80.86",
+ "188.211.122.188",
+ "178.131.85.186",
+ "178.131.181.76",
+ "188.211.93.212",
+ "188.211.113.28",
+ "37.148.10.14",
+ "178.131.91.185",
+ "185.193.209.45",
+ "37.148.5.188",
+ "185.193.209.28",
+ "178.131.89.60",
+ "5.201.137.183",
+ "185.162.40.190",
+ "5.201.136.198",
+ "185.176.34.216",
+ "178.131.93.104",
+ "178.131.190.233",
+ "188.121.147.14",
+ "2.144.6.75",
+ "2.144.234.8",
+ "2.176.0.149",
+ "2.176.1.2",
+ "2.176.3.199",
+ "2.176.4.253",
+ "2.176.5.147",
+ "2.176.10.31",
+ "2.176.13.185",
+ "2.176.14.103",
+ "2.176.14.183",
+ "2.176.19.229",
+ "2.176.21.116",
+ "2.176.22.40",
+ "2.176.23.196",
+ "2.176.26.161",
+ "2.176.28.124",
+ "2.176.32.50",
+ "2.176.32.152",
+ "2.176.33.3",
+ "2.176.33.49",
+ "2.176.33.252",
+ "2.176.37.116",
+ "2.176.38.115",
+ "2.176.40.17",
+ "2.176.46.159",
+ "2.176.48.151",
+ "2.176.49.16",
+ "2.176.51.21",
+ "2.176.54.114",
+ "2.176.57.203",
+ "2.176.59.199",
+ "2.176.63.26",
+ "2.176.63.164",
+ "2.176.64.13",
+ "2.176.64.62",
+ "2.176.67.195",
+ "2.176.68.200",
+ "2.176.69.30",
+ "2.176.70.163",
+ "2.176.70.194",
+ "2.176.70.255",
+ "2.176.72.122",
+ "2.176.73.187",
+ "2.176.75.51",
+ "2.176.79.19",
+ "2.176.79.205",
+ "2.176.82.84",
+ "2.176.89.185",
+ "2.176.91.175",
+ "2.176.96.244",
+ "2.176.97.95",
+ "2.176.110.198",
+ "2.176.111.242",
+ "2.176.112.190",
+ "2.176.114.152",
+ "2.176.115.171",
+ "2.176.116.29",
+ "2.176.118.141",
+ "2.176.125.63",
+ "2.176.125.180",
+ "2.176.127.4",
+ "2.176.128.63",
+ "2.176.128.77",
+ "2.176.128.112",
+ "2.176.128.228",
+ "2.176.129.91",
+ "2.176.129.231",
+ "2.176.130.105",
+ "2.176.131.65",
+ "2.176.131.77",
+ "2.176.132.230",
+ "2.176.137.87",
+ "2.176.138.199",
+ "2.176.139.170",
+ "2.176.142.146",
+ "2.176.144.136",
+ "2.176.144.166",
+ "2.176.144.243",
+ "2.176.145.7",
+ "2.176.146.150",
+ "2.176.146.196",
+ "2.176.148.38",
+ "2.176.148.44",
+ "2.176.150.91",
+ "2.176.152.223",
+ "2.176.153.246",
+ "2.176.155.87",
+ "2.176.157.202",
+ "2.176.158.62",
+ "2.176.158.249",
+ "2.176.159.236",
+ "2.176.164.204",
+ "2.176.170.96",
+ "2.176.172.196",
+ "2.176.174.221",
+ "2.176.180.253",
+ "2.176.182.199",
+ "2.176.186.237",
+ "2.176.192.190",
+ "2.176.194.95",
+ "2.176.194.219",
+ "2.176.194.252",
+ "2.176.195.55",
+ "2.176.195.166",
+ "2.176.196.6",
+ "2.176.198.119",
+ "2.176.198.194",
+ "2.176.199.32",
+ "2.176.200.173",
+ "2.176.200.224",
+ "2.176.203.56",
+ "2.176.203.132",
+ "2.176.204.68",
+ "2.176.207.44",
+ "2.176.208.140",
+ "2.176.210.13",
+ "2.176.214.194",
+ "2.176.217.128",
+ "2.176.218.15",
+ "2.176.218.38",
+ "2.176.218.157",
+ "2.176.219.106",
+ "2.176.220.0",
+ "2.176.220.41",
+ "2.176.220.74",
+ "2.176.220.159",
+ "2.176.220.232",
+ "2.176.223.22",
+ "2.176.225.123",
+ "2.176.228.243",
+ "2.176.235.178",
+ "2.176.236.18",
+ "2.176.236.73",
+ "2.176.237.101",
+ "2.176.239.112",
+ "2.176.239.166",
+ "2.176.240.214",
+ "2.176.241.29",
+ "2.176.241.192",
+ "2.176.243.199",
+ "2.176.246.103",
+ "2.176.246.118",
+ "2.176.249.144",
+ "2.176.250.140",
+ "2.176.251.152",
+ "2.176.252.239",
+ "2.176.253.59",
+ "2.177.0.4",
+ "2.177.0.102",
+ "2.177.1.27",
+ "2.177.2.24",
+ "2.177.2.191",
+ "2.177.4.142",
+ "2.177.4.190",
+ "2.177.5.6",
+ "2.177.5.226",
+ "2.177.7.132",
+ "2.177.8.24",
+ "2.177.9.2",
+ "2.177.9.92",
+ "2.177.11.190",
+ "2.177.13.184",
+ "2.177.14.233",
+ "2.177.16.78",
+ "2.177.17.153",
+ "2.177.20.69",
+ "2.177.21.120",
+ "2.177.21.132",
+ "2.177.21.177",
+ "2.177.22.81",
+ "2.177.22.101",
+ "2.177.23.57",
+ "2.177.24.65",
+ "2.177.24.180",
+ "2.177.26.202",
+ "2.177.28.36",
+ "2.177.35.28",
+ "2.177.35.203",
+ "2.177.35.241",
+ "2.177.37.57",
+ "2.177.44.216",
+ "2.177.45.132",
+ "2.177.46.215",
+ "2.177.48.88",
+ "2.177.51.76",
+ "2.177.51.229",
+ "2.177.55.110",
+ "2.177.56.122",
+ "2.177.60.52",
+ "2.177.60.86",
+ "2.177.60.149",
+ "2.177.65.54",
+ "2.177.67.107",
+ "2.177.67.109",
+ "2.177.68.140",
+ "2.177.69.213",
+ "2.177.72.120",
+ "2.177.72.160",
+ "2.177.73.27",
+ "2.177.73.194",
+ "2.177.75.6",
+ "2.177.77.139",
+ "2.177.78.50",
+ "2.177.79.209",
+ "2.177.80.105",
+ "2.177.81.171",
+ "2.177.85.139",
+ "2.177.86.104",
+ "2.177.88.168",
+ "2.177.89.205",
+ "2.177.97.64",
+ "2.177.100.34",
+ "2.177.102.82",
+ "2.177.104.97",
+ "2.177.105.74",
+ "2.177.109.182",
+ "2.177.110.188",
+ "2.177.112.34",
+ "2.177.113.111",
+ "2.177.115.30",
+ "2.177.115.139",
+ "2.177.116.83",
+ "2.177.116.163",
+ "2.177.117.151",
+ "2.177.120.18",
+ "2.177.121.15",
+ "2.177.124.17",
+ "2.177.125.26",
+ "2.177.125.210",
+ "2.177.126.89",
+ "2.177.129.25",
+ "2.177.130.99",
+ "2.177.131.124",
+ "2.177.132.3",
+ "2.177.132.150",
+ "2.177.133.146",
+ "2.177.133.241",
+ "2.177.137.23",
+ "2.177.138.130",
+ "2.177.138.241",
+ "2.177.141.203",
+ "2.177.142.59",
+ "2.177.143.254",
+ "2.177.144.14",
+ "2.177.144.176",
+ "2.177.145.91",
+ "2.177.145.107",
+ "2.177.146.124",
+ "2.177.146.253",
+ "2.177.147.104",
+ "2.177.147.146",
+ "2.177.148.14",
+ "2.177.148.18",
+ "2.177.150.204",
+ "2.177.150.232",
+ "2.177.153.97",
+ "2.177.153.117",
+ "2.177.154.117",
+ "2.177.154.163",
+ "2.177.155.114",
+ "2.177.157.64",
+ "2.177.160.50",
+ "2.177.160.134",
+ "2.177.162.103",
+ "2.177.162.117",
+ "2.177.163.247",
+ "2.177.165.197",
+ "2.177.166.204",
+ "2.177.166.244",
+ "2.177.171.61",
+ "2.177.171.185",
+ "2.177.172.140",
+ "2.177.172.168",
+ "2.177.174.32",
+ "2.177.174.65",
+ "2.177.174.80",
+ "2.177.175.61",
+ "2.177.176.87",
+ "2.177.179.220",
+ "2.177.180.217",
+ "2.177.181.160",
+ "2.177.181.248",
+ "2.177.181.252",
+ "2.177.182.225",
+ "2.177.182.249",
+ "2.177.185.220",
+ "2.177.187.117",
+ "2.177.187.218",
+ "2.177.188.154",
+ "2.177.190.97",
+ "2.177.194.12",
+ "2.177.194.227",
+ "2.177.195.220",
+ "2.177.196.18",
+ "2.177.197.5",
+ "2.177.198.140",
+ "2.177.199.1",
+ "2.177.199.219",
+ "2.177.200.176",
+ "2.177.202.44",
+ "2.177.202.188",
+ "2.177.205.239",
+ "2.177.206.194",
+ "2.177.208.38",
+ "2.177.208.191",
+ "2.177.209.17",
+ "2.177.212.13",
+ "2.177.212.85",
+ "2.177.214.26",
+ "2.177.214.42",
+ "2.177.214.238",
+ "2.177.217.0",
+ "2.177.217.81",
+ "2.177.218.70",
+ "2.177.221.170",
+ "2.177.221.178",
+ "2.177.224.225",
+ "2.177.225.4",
+ "2.177.225.205",
+ "2.177.226.0",
+ "2.177.226.178",
+ "2.177.230.72",
+ "2.177.231.76",
+ "2.177.231.200",
+ "2.177.233.62",
+ "2.177.236.2",
+ "2.177.236.30",
+ "2.177.236.221",
+ "2.177.237.95",
+ "2.177.240.71",
+ "2.177.243.171",
+ "2.177.244.185",
+ "2.177.245.168",
+ "2.177.245.206",
+ "2.177.245.207",
+ "2.177.246.141",
+ "2.177.250.215",
+ "2.177.250.239",
+ "2.177.251.74",
+ "2.178.0.88",
+ "2.178.1.123",
+ "2.178.2.120",
+ "2.178.2.138",
+ "2.178.12.135",
+ "2.178.15.73",
+ "2.178.17.73",
+ "2.178.18.219",
+ "2.178.20.173",
+ "2.178.21.53",
+ "2.178.25.0",
+ "2.178.28.209",
+ "2.178.28.241",
+ "2.178.29.173",
+ "2.178.34.223",
+ "2.178.37.140",
+ "2.178.41.120",
+ "2.178.43.178",
+ "2.178.44.137",
+ "2.178.48.99",
+ "2.178.48.207",
+ "2.178.50.81",
+ "2.178.53.39",
+ "2.178.54.58",
+ "2.178.58.202",
+ "2.178.59.38",
+ "2.178.67.118",
+ "2.178.68.83",
+ "2.178.70.36",
+ "2.178.71.48",
+ "2.178.72.192",
+ "2.178.75.5",
+ "2.178.79.202",
+ "2.178.80.60",
+ "2.178.80.166",
+ "2.178.81.3",
+ "2.178.87.134",
+ "2.178.89.141",
+ "2.178.92.217",
+ "2.178.95.100",
+ "2.178.98.24",
+ "2.178.99.137",
+ "2.178.99.171",
+ "2.178.100.51",
+ "2.178.101.158",
+ "2.178.103.59",
+ "2.178.104.72",
+ "2.178.106.47",
+ "2.178.111.162",
+ "2.178.114.185",
+ "2.178.116.7",
+ "2.178.118.23",
+ "2.178.118.113",
+ "2.178.120.176",
+ "2.178.121.69",
+ "2.178.123.81",
+ "2.178.125.192",
+ "2.178.127.86",
+ "2.178.131.81",
+ "2.178.131.208",
+ "2.178.134.227",
+ "2.178.141.17",
+ "2.178.147.116",
+ "2.178.149.161",
+ "2.178.150.176",
+ "2.178.152.155",
+ "2.178.162.109",
+ "2.178.165.47",
+ "2.178.167.203",
+ "2.178.168.166",
+ "2.178.176.44",
+ "2.178.180.145",
+ "2.178.183.88",
+ "2.178.185.208",
+ "2.178.188.32",
+ "2.178.195.84",
+ "2.178.195.119",
+ "2.178.201.117",
+ "2.178.203.141",
+ "2.178.208.230",
+ "2.178.214.202",
+ "2.178.220.103",
+ "2.178.229.49",
+ "2.178.230.103",
+ "2.178.232.133",
+ "2.178.232.202",
+ "2.178.232.209",
+ "2.178.233.77",
+ "2.178.234.139",
+ "2.178.236.87",
+ "2.178.241.103",
+ "2.178.247.85",
+ "2.179.20.77",
+ "2.179.21.89",
+ "2.179.21.253",
+ "2.179.22.24",
+ "2.179.46.173",
+ "2.179.47.241",
+ "2.179.67.96",
+ "2.179.70.156",
+ "2.179.71.6",
+ "2.179.71.183",
+ "2.179.78.139",
+ "2.179.80.86",
+ "2.179.83.31",
+ "2.179.83.40",
+ "2.179.84.26",
+ "2.179.84.223",
+ "2.179.86.198",
+ "2.179.96.57",
+ "2.179.96.164",
+ "2.179.96.196",
+ "2.179.100.5",
+ "2.179.100.90",
+ "2.179.101.193",
+ "2.179.103.136",
+ "2.179.103.247",
+ "2.179.105.36",
+ "2.179.106.42",
+ "2.179.115.152",
+ "2.179.115.171",
+ "2.179.117.25",
+ "2.179.117.157",
+ "2.179.117.227",
+ "2.179.118.254",
+ "2.179.121.31",
+ "2.179.124.214",
+ "2.179.125.87",
+ "2.179.126.163",
+ "2.179.127.65",
+ "2.179.162.144",
+ "2.179.163.232",
+ "2.179.167.231",
+ "2.179.178.115",
+ "2.179.186.238",
+ "2.179.193.146",
+ "2.179.194.45",
+ "2.179.194.138",
+ "2.179.211.167",
+ "2.179.212.14",
+ "2.179.217.132",
+ "2.179.232.21",
+ "2.179.252.135",
+ "2.180.0.177",
+ "2.180.1.91",
+ "2.180.1.95",
+ "2.180.3.207",
+ "2.180.6.135",
+ "2.180.8.54",
+ "2.180.8.97",
+ "2.180.15.75",
+ "2.180.21.43",
+ "2.180.21.218",
+ "2.180.22.62",
+ "2.180.22.233",
+ "2.180.24.112",
+ "2.180.25.192",
+ "2.180.29.94",
+ "2.180.31.174",
+ "2.180.32.48",
+ "2.180.32.211",
+ "2.180.33.137",
+ "2.180.35.195",
+ "2.180.35.227",
+ "2.180.36.43",
+ "2.180.39.39",
+ "2.180.41.242",
+ "2.180.42.127",
+ "2.180.43.95",
+ "2.180.47.53",
+ "2.181.1.61",
+ "2.181.30.184",
+ "2.181.31.165",
+ "2.181.35.20",
+ "2.181.35.134",
+ "2.181.60.180",
+ "2.181.80.158",
+ "2.181.81.16",
+ "2.181.85.245",
+ "2.181.89.248",
+ "2.181.93.51",
+ "2.181.101.208",
+ "2.181.102.4",
+ "2.181.109.155",
+ "2.181.177.81",
+ "2.181.224.175",
+ "2.181.224.244",
+ "2.181.232.2",
+ "2.181.232.233",
+ "2.181.237.83",
+ "2.181.238.104",
+ "2.181.245.168",
+ "2.181.247.131",
+ "2.181.249.200",
+ "2.181.251.228",
+ "2.181.255.52",
+ "2.182.51.83",
+ "2.182.51.102",
+ "2.182.51.211",
+ "2.182.52.8",
+ "2.182.53.4",
+ "2.182.53.28",
+ "2.182.54.16",
+ "2.182.55.126",
+ "2.182.59.207",
+ "2.182.64.250",
+ "2.182.65.3",
+ "2.182.67.56",
+ "2.182.67.151",
+ "2.182.67.168",
+ "2.182.67.197",
+ "2.182.68.82",
+ "2.182.68.142",
+ "2.182.70.153",
+ "2.182.73.35",
+ "2.182.75.49",
+ "2.182.75.133",
+ "2.182.75.162",
+ "2.182.75.254",
+ "2.182.77.238",
+ "2.182.84.145",
+ "2.182.85.146",
+ "2.182.86.49",
+ "2.182.88.229",
+ "2.182.90.64",
+ "2.182.90.230",
+ "2.182.93.10",
+ "2.182.93.122",
+ "2.182.93.241",
+ "2.182.95.158",
+ "2.182.95.239",
+ "2.182.116.229",
+ "2.182.118.163",
+ "2.182.119.115",
+ "2.182.127.44",
+ "2.182.127.71",
+ "2.182.166.5",
+ "2.182.184.150",
+ "2.182.190.134",
+ "2.182.191.10",
+ "2.182.192.22",
+ "2.182.192.106",
+ "2.182.196.132",
+ "2.182.197.46",
+ "2.182.201.6",
+ "2.182.208.44",
+ "2.182.215.172",
+ "2.182.217.172",
+ "2.182.217.217",
+ "2.182.218.73",
+ "2.182.221.90",
+ "2.182.222.208",
+ "2.182.226.35",
+ "2.182.226.205",
+ "2.182.227.83",
+ "2.182.228.6",
+ "2.182.228.77",
+ "2.182.228.197",
+ "2.182.229.125",
+ "2.182.231.26",
+ "2.182.234.126",
+ "2.182.234.153",
+ "2.182.234.201",
+ "2.182.235.5",
+ "2.182.235.216",
+ "2.182.241.138",
+ "2.182.249.72",
+ "2.182.251.205",
+ "2.183.8.116",
+ "2.183.88.79",
+ "2.183.89.135",
+ "2.183.99.60",
+ "2.183.99.80",
+ "2.183.115.168",
+ "2.183.123.1",
+ "2.183.142.201",
+ "2.183.143.93",
+ "2.183.195.164",
+ "2.183.198.32",
+ "2.183.200.141",
+ "2.183.202.66",
+ "2.183.202.70",
+ "2.183.202.71",
+ "2.183.203.130",
+ "2.183.203.186",
+ "2.184.2.165",
+ "2.184.2.184",
+ "2.184.3.191",
+ "2.184.15.56",
+ "2.184.16.149",
+ "2.184.16.208",
+ "2.184.18.54",
+ "2.184.18.130",
+ "2.184.22.102",
+ "2.184.29.224",
+ "2.184.30.140",
+ "2.184.31.224",
+ "2.184.31.226",
+ "2.184.53.203",
+ "2.184.55.72",
+ "2.184.57.76",
+ "2.184.70.111",
+ "2.184.156.10",
+ "2.184.156.166",
+ "2.184.157.37",
+ "2.184.158.58",
+ "2.184.158.225",
+ "2.184.159.1",
+ "2.184.159.172",
+ "2.184.182.83",
+ "2.184.204.101",
+ "2.184.216.242",
+ "2.184.238.105",
+ "2.184.238.193",
+ "2.184.239.43",
+ "2.185.17.16",
+ "2.185.17.227",
+ "2.185.66.102",
+ "2.185.97.114",
+ "2.185.100.126",
+ "2.185.102.55",
+ "2.185.104.61",
+ "2.185.109.51",
+ "2.185.109.210",
+ "2.185.110.156",
+ "2.185.113.54",
+ "2.185.116.135",
+ "2.185.122.111",
+ "2.185.141.99",
+ "2.185.143.19",
+ "2.185.143.54",
+ "2.185.144.8",
+ "2.185.144.53",
+ "2.185.144.86",
+ "2.185.146.24",
+ "2.185.148.251",
+ "2.185.175.77",
+ "2.185.230.179",
+ "2.185.232.154",
+ "2.185.232.162",
+ "2.185.233.7",
+ "2.185.233.26",
+ "2.185.237.103",
+ "2.185.243.230",
+ "2.185.244.248",
+ "2.185.247.84",
+ "2.185.251.200",
+ "2.185.252.143",
+ "2.186.13.114",
+ "2.186.15.84",
+ "2.186.112.159",
+ "2.186.116.88",
+ "2.186.116.124",
+ "2.186.118.250",
+ "2.186.120.77",
+ "2.186.121.189",
+ "2.186.122.128",
+ "2.186.229.13",
+ "2.187.2.155",
+ "2.187.9.112",
+ "2.187.20.133",
+ "2.187.32.176",
+ "2.187.34.93",
+ "2.187.36.108",
+ "2.187.56.151",
+ "2.187.57.2",
+ "2.187.59.40",
+ "2.187.129.147",
+ "2.187.138.186",
+ "2.187.146.168",
+ "2.187.148.114",
+ "2.187.151.18",
+ "2.187.188.92",
+ "2.187.189.189",
+ "2.187.249.102",
+ "2.187.250.158",
+ "2.188.72.139",
+ "2.188.162.210",
+ "2.188.167.197",
+ "2.188.168.191",
+ "2.188.174.129",
+ "2.188.174.149",
+ "2.188.174.154",
+ "2.188.210.1",
+ "2.188.210.9",
+ "2.188.210.11",
+ "2.188.210.60",
+ "2.188.212.190",
+ "2.188.218.178",
+ "2.188.226.186",
+ "2.188.226.249",
+ "2.188.230.202",
+ "2.188.236.66",
+ "2.188.236.68",
+ "2.188.236.69",
+ "2.189.20.134",
+ "2.189.20.221",
+ "2.189.33.59",
+ "2.189.89.26",
+ "2.189.103.0",
+ "2.189.103.1",
+ "2.189.103.2",
+ "2.189.103.3",
+ "2.189.103.5",
+ "2.189.103.6",
+ "2.189.103.7",
+ "2.189.103.8",
+ "2.189.103.10",
+ "2.189.103.11",
+ "2.189.103.13",
+ "2.189.103.16",
+ "2.189.103.17",
+ "2.189.103.18",
+ "2.189.103.19",
+ "2.189.103.20",
+ "2.189.103.21",
+ "2.189.103.22",
+ "2.189.103.23",
+ "2.189.103.24",
+ "2.189.103.25",
+ "2.189.103.26",
+ "2.189.103.27",
+ "2.189.103.28",
+ "2.189.103.30",
+ "2.189.103.32",
+ "2.189.103.33",
+ "2.189.103.34",
+ "2.189.103.35",
+ "2.189.103.36",
+ "2.189.103.37",
+ "2.189.103.39",
+ "2.189.103.40",
+ "2.189.103.41",
+ "2.189.103.42",
+ "2.189.103.43",
+ "2.189.103.44",
+ "2.189.103.45",
+ "2.189.103.46",
+ "2.189.103.47",
+ "2.189.103.48",
+ "2.189.103.49",
+ "2.189.103.50",
+ "2.189.103.51",
+ "2.189.103.52",
+ "2.189.103.53",
+ "2.189.103.55",
+ "2.189.103.56",
+ "2.189.103.57",
+ "2.189.103.59",
+ "2.189.103.60",
+ "2.189.103.61",
+ "2.189.103.63",
+ "2.189.103.64",
+ "2.189.103.65",
+ "2.189.103.67",
+ "2.189.103.68",
+ "2.189.103.69",
+ "2.189.103.72",
+ "2.189.103.73",
+ "2.189.103.74",
+ "2.189.103.75",
+ "2.189.103.76",
+ "2.189.103.78",
+ "2.189.103.79",
+ "2.189.103.80",
+ "2.189.103.81",
+ "2.189.103.82",
+ "2.189.103.84",
+ "2.189.103.85",
+ "2.189.103.86",
+ "2.189.103.87",
+ "2.189.103.88",
+ "2.189.103.89",
+ "2.189.103.90",
+ "2.189.103.91",
+ "2.189.103.92",
+ "2.189.103.93",
+ "2.189.103.95",
+ "2.189.103.96",
+ "2.189.103.97",
+ "2.189.103.98",
+ "2.189.103.99",
+ "2.189.103.100",
+ "2.189.103.101",
+ "2.189.103.102",
+ "2.189.103.105",
+ "2.189.103.106",
+ "2.189.103.107",
+ "2.189.103.108",
+ "2.189.103.109",
+ "2.189.103.110",
+ "2.189.103.111",
+ "2.189.103.112",
+ "2.189.103.113",
+ "2.189.103.114",
+ "2.189.103.115",
+ "2.189.103.116",
+ "2.189.103.117",
+ "2.189.103.118",
+ "2.189.103.119",
+ "2.189.103.120",
+ "2.189.103.121",
+ "2.189.103.122",
+ "2.189.103.123",
+ "2.189.103.124",
+ "2.189.103.125",
+ "2.189.103.128",
+ "2.189.103.129",
+ "2.189.103.130",
+ "2.189.103.131",
+ "2.189.103.132",
+ "2.189.103.134",
+ "2.189.103.135",
+ "2.189.103.136",
+ "2.189.103.138",
+ "2.189.103.139",
+ "2.189.103.140",
+ "2.189.103.141",
+ "2.189.103.142",
+ "2.189.103.143",
+ "2.189.103.144",
+ "2.189.103.145",
+ "2.189.103.146",
+ "2.189.103.147",
+ "2.189.103.148",
+ "2.189.103.149",
+ "2.189.103.150",
+ "2.189.103.152",
+ "2.189.103.153",
+ "2.189.103.154",
+ "2.189.103.155",
+ "2.189.103.156",
+ "2.189.103.158",
+ "2.189.103.159",
+ "2.189.103.160",
+ "2.189.103.161",
+ "2.189.103.162",
+ "2.189.103.163",
+ "2.189.103.164",
+ "2.189.103.166",
+ "2.189.103.167",
+ "2.189.103.168",
+ "2.189.103.169",
+ "2.189.103.170",
+ "2.189.103.171",
+ "2.189.103.172",
+ "2.189.103.173",
+ "2.189.103.174",
+ "2.189.103.176",
+ "2.189.103.177",
+ "2.189.103.178",
+ "2.189.103.179",
+ "2.189.103.180",
+ "2.189.103.181",
+ "2.189.103.182",
+ "2.189.103.183",
+ "2.189.103.184",
+ "2.189.103.186",
+ "2.189.103.187",
+ "2.189.103.188",
+ "2.189.103.189",
+ "2.189.103.190",
+ "2.189.103.192",
+ "2.189.103.193",
+ "2.189.103.194",
+ "2.189.103.195",
+ "2.189.103.196",
+ "2.189.103.197",
+ "2.189.103.198",
+ "2.189.103.199",
+ "2.189.103.200",
+ "2.189.103.202",
+ "2.189.103.203",
+ "2.189.103.204",
+ "2.189.103.205",
+ "2.189.103.206",
+ "2.189.103.208",
+ "2.189.103.209",
+ "2.189.103.210",
+ "2.189.103.212",
+ "2.189.103.213",
+ "2.189.103.214",
+ "2.189.103.215",
+ "2.189.103.216",
+ "2.189.103.217",
+ "2.189.103.219",
+ "2.189.103.220",
+ "2.189.103.222",
+ "2.189.103.223",
+ "2.189.103.224",
+ "2.189.103.225",
+ "2.189.103.226",
+ "2.189.103.227",
+ "2.189.103.228",
+ "2.189.103.229",
+ "2.189.103.230",
+ "2.189.103.232",
+ "2.189.103.233",
+ "2.189.103.234",
+ "2.189.103.235",
+ "2.189.103.236",
+ "2.189.103.238",
+ "2.189.103.239",
+ "2.189.103.240",
+ "2.189.103.241",
+ "2.189.103.242",
+ "2.189.103.244",
+ "2.189.103.245",
+ "2.189.103.246",
+ "2.189.103.247",
+ "2.189.103.248",
+ "2.189.103.249",
+ "2.189.103.250",
+ "2.189.103.251",
+ "2.189.103.252",
+ "2.189.103.253",
+ "2.189.103.254",
+ "2.189.103.255",
+ "2.189.142.24",
+ "2.189.144.51",
+ "2.189.146.0",
+ "2.189.146.1",
+ "2.189.146.2",
+ "2.189.146.3",
+ "2.189.146.4",
+ "2.189.146.5",
+ "2.189.146.6",
+ "2.189.146.7",
+ "2.189.146.8",
+ "2.189.146.9",
+ "2.189.146.10",
+ "2.189.146.11",
+ "2.189.146.12",
+ "2.189.146.13",
+ "2.189.146.14",
+ "2.189.146.15",
+ "2.189.146.16",
+ "2.189.146.17",
+ "2.189.146.19",
+ "2.189.146.20",
+ "2.189.146.21",
+ "2.189.146.22",
+ "2.189.146.24",
+ "2.189.146.25",
+ "2.189.146.26",
+ "2.189.146.27",
+ "2.189.146.28",
+ "2.189.146.30",
+ "2.189.146.31",
+ "2.189.146.32",
+ "2.189.146.33",
+ "2.189.146.34",
+ "2.189.146.35",
+ "2.189.146.36",
+ "2.189.146.37",
+ "2.189.146.38",
+ "2.189.146.39",
+ "2.189.146.40",
+ "2.189.146.41",
+ "2.189.146.42",
+ "2.189.146.43",
+ "2.189.146.44",
+ "2.189.146.45",
+ "2.189.146.46",
+ "2.189.146.47",
+ "2.189.146.49",
+ "2.189.146.50",
+ "2.189.146.51",
+ "2.189.146.52",
+ "2.189.146.53",
+ "2.189.146.54",
+ "2.189.146.55",
+ "2.189.146.57",
+ "2.189.146.58",
+ "2.189.146.59",
+ "2.189.146.60",
+ "2.189.146.61",
+ "2.189.146.62",
+ "2.189.146.63",
+ "2.189.146.64",
+ "2.189.146.65",
+ "2.189.146.66",
+ "2.189.146.68",
+ "2.189.146.69",
+ "2.189.146.70",
+ "2.189.146.71",
+ "2.189.146.72",
+ "2.189.146.73",
+ "2.189.146.74",
+ "2.189.146.76",
+ "2.189.146.77",
+ "2.189.146.79",
+ "2.189.146.80",
+ "2.189.146.81",
+ "2.189.146.82",
+ "2.189.146.83",
+ "2.189.146.84",
+ "2.189.146.85",
+ "2.189.146.86",
+ "2.189.146.87",
+ "2.189.146.88",
+ "2.189.146.89",
+ "2.189.146.90",
+ "2.189.146.91",
+ "2.189.146.92",
+ "2.189.146.93",
+ "2.189.146.95",
+ "2.189.146.96",
+ "2.189.146.98",
+ "2.189.146.99",
+ "2.189.146.100",
+ "2.189.146.101",
+ "2.189.146.103",
+ "2.189.146.104",
+ "2.189.146.105",
+ "2.189.146.106",
+ "2.189.146.109",
+ "2.189.146.110",
+ "2.189.146.111",
+ "2.189.146.112",
+ "2.189.146.114",
+ "2.189.146.115",
+ "2.189.146.116",
+ "2.189.146.117",
+ "2.189.146.119",
+ "2.189.146.120",
+ "2.189.146.121",
+ "2.189.146.122",
+ "2.189.146.123",
+ "2.189.146.124",
+ "2.189.146.125",
+ "2.189.146.126",
+ "2.189.146.127",
+ "2.189.146.128",
+ "2.189.146.130",
+ "2.189.146.131",
+ "2.189.146.134",
+ "2.189.146.135",
+ "2.189.146.136",
+ "2.189.146.137",
+ "2.189.146.138",
+ "2.189.146.141",
+ "2.189.146.142",
+ "2.189.146.143",
+ "2.189.146.144",
+ "2.189.146.145",
+ "2.189.146.146",
+ "2.189.146.148",
+ "2.189.146.150",
+ "2.189.146.151",
+ "2.189.146.153",
+ "2.189.146.154",
+ "2.189.146.155",
+ "2.189.146.156",
+ "2.189.146.157",
+ "2.189.146.158",
+ "2.189.146.159",
+ "2.189.146.160",
+ "2.189.146.161",
+ "2.189.146.162",
+ "2.189.146.163",
+ "2.189.146.164",
+ "2.189.146.165",
+ "2.189.146.166",
+ "2.189.146.169",
+ "2.189.146.170",
+ "2.189.146.171",
+ "2.189.146.172",
+ "2.189.146.173",
+ "2.189.146.174",
+ "2.189.146.176",
+ "2.189.146.177",
+ "2.189.146.178",
+ "2.189.146.179",
+ "2.189.146.180",
+ "2.189.146.181",
+ "2.189.146.183",
+ "2.189.146.184",
+ "2.189.146.185",
+ "2.189.146.186",
+ "2.189.146.188",
+ "2.189.146.189",
+ "2.189.146.190",
+ "2.189.146.191",
+ "2.189.146.192",
+ "2.189.146.193",
+ "2.189.146.194",
+ "2.189.146.195",
+ "2.189.146.196",
+ "2.189.146.197",
+ "2.189.146.198",
+ "2.189.146.200",
+ "2.189.146.201",
+ "2.189.146.202",
+ "2.189.146.203",
+ "2.189.146.204",
+ "2.189.146.205",
+ "2.189.146.206",
+ "2.189.146.207",
+ "2.189.146.208",
+ "2.189.146.209",
+ "2.189.146.210",
+ "2.189.146.211",
+ "2.189.146.212",
+ "2.189.146.213",
+ "2.189.146.214",
+ "2.189.146.215",
+ "2.189.146.216",
+ "2.189.146.217",
+ "2.189.146.218",
+ "2.189.146.219",
+ "2.189.146.220",
+ "2.189.146.221",
+ "2.189.146.222",
+ "2.189.146.223",
+ "2.189.146.224",
+ "2.189.146.225",
+ "2.189.146.226",
+ "2.189.146.227",
+ "2.189.146.228",
+ "2.189.146.229",
+ "2.189.146.230",
+ "2.189.146.231",
+ "2.189.146.232",
+ "2.189.146.233",
+ "2.189.146.234",
+ "2.189.146.235",
+ "2.189.146.236",
+ "2.189.146.238",
+ "2.189.146.239",
+ "2.189.146.240",
+ "2.189.146.241",
+ "2.189.146.243",
+ "2.189.146.244",
+ "2.189.146.245",
+ "2.189.146.246",
+ "2.189.146.247",
+ "2.189.146.248",
+ "2.189.146.249",
+ "2.189.146.250",
+ "2.189.146.251",
+ "2.189.146.252",
+ "2.189.146.254",
+ "2.189.146.255",
+ "2.189.147.203",
+ "2.189.167.182",
+ "2.189.248.85",
+ "2.189.253.227",
+ "2.190.0.219",
+ "2.190.3.109",
+ "2.190.4.52",
+ "2.190.6.196",
+ "2.190.7.228",
+ "2.190.9.118",
+ "2.190.11.141",
+ "2.190.15.136",
+ "2.190.19.245",
+ "2.190.20.60",
+ "2.190.23.236",
+ "2.190.26.141",
+ "2.190.27.169",
+ "2.190.27.197",
+ "2.190.37.39",
+ "2.190.38.55",
+ "2.190.38.87",
+ "2.190.38.142",
+ "2.190.38.211",
+ "2.190.39.77",
+ "2.190.39.130",
+ "2.190.40.156",
+ "2.190.42.21",
+ "2.190.42.183",
+ "2.190.45.166",
+ "2.190.46.116",
+ "2.190.51.254",
+ "2.190.52.74",
+ "2.190.53.198",
+ "2.190.59.26",
+ "2.190.59.204",
+ "2.190.60.248",
+ "2.190.63.200",
+ "2.190.64.4",
+ "2.190.64.131",
+ "2.190.65.190",
+ "2.190.76.222",
+ "2.190.78.34",
+ "2.190.78.187",
+ "2.190.78.200",
+ "2.190.80.240",
+ "2.190.85.139",
+ "2.190.87.233",
+ "2.190.98.198",
+ "2.190.99.4",
+ "2.190.100.201",
+ "2.190.101.82",
+ "2.190.102.90",
+ "2.190.102.135",
+ "2.190.103.7",
+ "2.190.104.114",
+ "2.190.109.119",
+ "2.190.110.193",
+ "2.190.111.127",
+ "2.190.113.4",
+ "2.190.113.163",
+ "2.190.119.48",
+ "2.190.122.249",
+ "2.190.124.53",
+ "2.190.124.161",
+ "2.190.125.194",
+ "2.190.127.59",
+ "2.190.128.73",
+ "2.190.129.19",
+ "2.190.130.21",
+ "2.190.130.101",
+ "2.190.131.105",
+ "2.190.131.202",
+ "2.190.136.56",
+ "2.190.136.169",
+ "2.190.137.45",
+ "2.190.138.190",
+ "2.190.139.44",
+ "2.190.140.121",
+ "2.190.141.59",
+ "2.190.142.75",
+ "2.190.144.94",
+ "2.190.146.240",
+ "2.190.148.66",
+ "2.190.148.218",
+ "2.190.149.244",
+ "2.190.152.106",
+ "2.190.154.170",
+ "2.190.155.54",
+ "2.190.155.103",
+ "2.190.158.27",
+ "2.190.160.83",
+ "2.190.160.127",
+ "2.190.162.121",
+ "2.190.162.212",
+ "2.190.163.198",
+ "2.190.163.219",
+ "2.190.164.173",
+ "2.190.166.177",
+ "2.190.168.116",
+ "2.190.170.245",
+ "2.190.172.131",
+ "2.190.173.242",
+ "2.190.175.7",
+ "2.190.176.19",
+ "2.190.176.114",
+ "2.190.176.170",
+ "2.190.177.8",
+ "2.190.177.128",
+ "2.190.178.171",
+ "2.190.179.93",
+ "2.190.180.3",
+ "2.190.180.123",
+ "2.190.183.211",
+ "2.190.184.51",
+ "2.190.184.94",
+ "2.190.184.245",
+ "2.190.187.101",
+ "2.190.188.246",
+ "2.190.190.162",
+ "2.190.197.84",
+ "2.190.200.30",
+ "2.190.201.140",
+ "2.190.202.90",
+ "2.190.207.43",
+ "2.190.211.126",
+ "2.190.213.109",
+ "2.190.221.31",
+ "2.190.223.151",
+ "2.190.224.23",
+ "2.190.225.129",
+ "2.190.227.220",
+ "2.190.230.241",
+ "2.190.233.13",
+ "2.190.235.238",
+ "2.190.238.96",
+ "2.190.239.255",
+ "2.190.240.70",
+ "2.190.240.227",
+ "2.190.245.242",
+ "2.190.247.236",
+ "2.190.249.207",
+ "2.190.250.172",
+ "2.190.251.210",
+ "2.190.254.120",
+ "2.190.254.154",
+ "2.190.255.53",
+ "2.191.0.6",
+ "2.191.0.224",
+ "2.191.1.50",
+ "2.191.1.113",
+ "2.191.1.242",
+ "2.191.4.59",
+ "2.191.5.65",
+ "2.191.7.180",
+ "2.191.10.52",
+ "2.191.12.81",
+ "2.191.16.31",
+ "2.191.17.99",
+ "2.191.18.29",
+ "2.191.18.142",
+ "2.191.18.180",
+ "2.191.19.78",
+ "2.191.20.194",
+ "2.191.21.17",
+ "2.191.22.179",
+ "2.191.23.246",
+ "2.191.24.148",
+ "2.191.24.199",
+ "2.191.24.212",
+ "2.191.25.48",
+ "2.191.25.243",
+ "2.191.26.247",
+ "2.191.31.63",
+ "2.191.31.199",
+ "2.191.31.237",
+ "2.191.33.102",
+ "2.191.33.218",
+ "2.191.36.95",
+ "2.191.38.0",
+ "2.191.38.215",
+ "2.191.39.12",
+ "2.191.39.33",
+ "2.191.44.159",
+ "2.191.46.156",
+ "2.191.47.193",
+ "2.191.47.212",
+ "2.191.48.80",
+ "2.191.50.18",
+ "2.191.50.221",
+ "2.191.51.19",
+ "2.191.51.147",
+ "2.191.52.111",
+ "2.191.53.176",
+ "2.191.53.235",
+ "2.191.55.88",
+ "2.191.55.143",
+ "2.191.57.193",
+ "2.191.60.111",
+ "2.191.60.174",
+ "2.191.64.245",
+ "2.191.65.114",
+ "2.191.67.13",
+ "2.191.67.122",
+ "2.191.67.132",
+ "2.191.68.132",
+ "2.191.72.96",
+ "2.191.75.140",
+ "2.191.77.110",
+ "2.191.79.203",
+ "2.191.81.104",
+ "2.191.83.222",
+ "2.191.85.229",
+ "2.191.88.158",
+ "2.191.88.227",
+ "2.191.89.5",
+ "2.191.89.181",
+ "2.191.90.111",
+ "2.191.92.21",
+ "2.191.93.51",
+ "2.191.96.43",
+ "2.191.98.55",
+ "2.191.98.216",
+ "2.191.102.103",
+ "2.191.102.147",
+ "2.191.102.197",
+ "2.191.104.0",
+ "2.191.109.200",
+ "2.191.110.107",
+ "2.191.111.70",
+ "2.191.111.155",
+ "2.191.111.206",
+ "2.191.112.240",
+ "2.191.117.110",
+ "2.191.122.151",
+ "2.191.123.43",
+ "2.191.123.207",
+ "2.191.123.233",
+ "2.191.125.122",
+ "2.191.126.113",
+ "2.191.127.237",
+ "2.191.128.179",
+ "2.191.129.228",
+ "2.191.130.41",
+ "2.191.130.94",
+ "2.191.136.130",
+ "2.191.142.36",
+ "2.191.147.12",
+ "2.191.150.45",
+ "2.191.152.160",
+ "2.191.152.233",
+ "2.191.153.212",
+ "2.191.153.213",
+ "2.191.155.105",
+ "2.191.156.224",
+ "2.191.158.7",
+ "2.191.159.18",
+ "2.191.161.238",
+ "2.191.162.18",
+ "2.191.165.91",
+ "2.191.166.250",
+ "2.191.167.59",
+ "2.191.167.133",
+ "2.191.167.183",
+ "2.191.169.113",
+ "2.191.173.112",
+ "2.191.173.135",
+ "2.191.174.192",
+ "2.191.177.52",
+ "2.191.180.74",
+ "2.191.181.20",
+ "2.191.181.136",
+ "2.191.190.126",
+ "2.191.196.245",
+ "2.191.199.52",
+ "2.191.203.66",
+ "2.191.207.176",
+ "2.191.212.121",
+ "2.191.215.7",
+ "2.191.221.159",
+ "2.191.230.3",
+ "2.191.231.150",
+ "5.22.198.2",
+ "5.22.199.225",
+ "5.22.199.227",
+ "5.22.199.233",
+ "5.61.24.140",
+ "5.61.25.140",
+ "5.62.161.12",
+ "5.62.164.234",
+ "5.62.167.252",
+ "5.62.168.205",
+ "5.62.168.209",
+ "5.62.169.32",
+ "5.62.170.171",
+ "5.62.171.239",
+ "5.62.172.230",
+ "5.62.177.52",
+ "5.62.180.232",
+ "5.62.184.217",
+ "5.62.185.88",
+ "5.62.185.142",
+ "5.62.187.24",
+ "5.62.190.208",
+ "5.74.1.46",
+ "5.74.2.235",
+ "5.74.4.38",
+ "5.74.4.133",
+ "5.74.5.163",
+ "5.74.8.73",
+ "5.74.10.109",
+ "5.74.10.150",
+ "5.74.10.215",
+ "5.74.11.204",
+ "5.74.13.185",
+ "5.74.14.152",
+ "5.74.14.155",
+ "5.74.15.104",
+ "5.74.15.181",
+ "5.74.15.246",
+ "5.74.16.146",
+ "5.74.17.89",
+ "5.74.18.0",
+ "5.74.21.244",
+ "5.74.23.161",
+ "5.74.25.63",
+ "5.74.25.64",
+ "5.74.26.88",
+ "5.74.26.94",
+ "5.74.31.226",
+ "5.74.32.237",
+ "5.74.33.49",
+ "5.74.42.117",
+ "5.74.44.120",
+ "5.74.45.152",
+ "5.74.46.132",
+ "5.74.47.40",
+ "5.74.48.79",
+ "5.74.48.107",
+ "5.74.48.243",
+ "5.74.49.7",
+ "5.74.49.68",
+ "5.74.51.101",
+ "5.74.51.243",
+ "5.74.53.164",
+ "5.74.56.24",
+ "5.74.68.122",
+ "5.74.69.14",
+ "5.74.70.57",
+ "5.74.70.206",
+ "5.74.72.139",
+ "5.74.72.153",
+ "5.74.73.211",
+ "5.74.81.76",
+ "5.74.81.109",
+ "5.74.81.245",
+ "5.74.82.14",
+ "5.74.83.74",
+ "5.74.84.91",
+ "5.74.85.195",
+ "5.74.86.234",
+ "5.74.87.26",
+ "5.74.89.115",
+ "5.74.90.185",
+ "5.74.93.95",
+ "5.74.94.194",
+ "5.74.96.192",
+ "5.74.101.232",
+ "5.74.102.212",
+ "5.74.103.201",
+ "5.74.104.46",
+ "5.74.104.251",
+ "5.74.105.6",
+ "5.74.105.160",
+ "5.74.106.186",
+ "5.74.107.255",
+ "5.74.108.196",
+ "5.74.111.225",
+ "5.74.112.152",
+ "5.74.114.57",
+ "5.74.114.157",
+ "5.74.119.110",
+ "5.74.122.30",
+ "5.74.122.185",
+ "5.74.124.110",
+ "5.74.124.128",
+ "5.74.129.51",
+ "5.74.137.139",
+ "5.74.140.172",
+ "5.74.141.173",
+ "5.74.143.207",
+ "5.74.144.104",
+ "5.74.145.28",
+ "5.74.146.231",
+ "5.74.150.112",
+ "5.74.151.182",
+ "5.74.152.5",
+ "5.74.153.178",
+ "5.74.159.57",
+ "5.74.167.27",
+ "5.74.172.121",
+ "5.74.172.152",
+ "5.74.174.105",
+ "5.74.176.41",
+ "5.74.180.83",
+ "5.74.180.115",
+ "5.74.184.161",
+ "5.74.184.196",
+ "5.74.185.175",
+ "5.74.185.189",
+ "5.74.186.120",
+ "5.74.187.88",
+ "5.74.190.109",
+ "5.74.191.121",
+ "5.74.192.203",
+ "5.74.197.119",
+ "5.74.200.185",
+ "5.74.210.56",
+ "5.74.212.34",
+ "5.74.213.219",
+ "5.74.217.255",
+ "5.74.218.230",
+ "5.74.224.78",
+ "5.74.227.206",
+ "5.74.227.218",
+ "5.74.229.87",
+ "5.74.230.51",
+ "5.74.232.30",
+ "5.74.233.67",
+ "5.74.234.125",
+ "5.74.234.204",
+ "5.74.239.116",
+ "5.74.245.238",
+ "5.74.249.28",
+ "5.74.249.161",
+ "5.74.250.248",
+ "5.74.251.44",
+ "5.74.255.5",
+ "5.74.255.195",
+ "5.106.18.195",
+ "5.106.19.94",
+ "5.106.19.219",
+ "5.134.193.5",
+ "5.134.196.186",
+ "5.159.48.64",
+ "5.159.48.65",
+ "5.159.48.66",
+ "5.159.48.67",
+ "5.159.48.68",
+ "5.159.48.69",
+ "5.159.48.70",
+ "5.159.48.71",
+ "5.159.50.80",
+ "5.159.50.81",
+ "5.159.50.82",
+ "5.159.50.83",
+ "5.159.50.84",
+ "5.159.50.85",
+ "5.159.50.86",
+ "5.159.50.87",
+ "5.159.51.208",
+ "5.159.51.209",
+ "5.159.51.210",
+ "5.159.51.211",
+ "5.159.51.212",
+ "5.159.51.213",
+ "5.159.51.214",
+ "5.159.52.128",
+ "5.159.52.130",
+ "5.159.52.131",
+ "5.159.52.133",
+ "5.159.52.134",
+ "5.159.52.135",
+ "5.159.52.240",
+ "5.159.52.242",
+ "5.159.52.243",
+ "5.159.53.57",
+ "5.159.53.59",
+ "5.159.53.60",
+ "5.159.53.61",
+ "5.159.53.63",
+ "5.159.55.32",
+ "5.159.55.33",
+ "5.159.55.34",
+ "5.159.55.35",
+ "5.159.55.36",
+ "5.159.55.37",
+ "5.159.55.38",
+ "5.159.55.39",
+ "5.160.4.2",
+ "5.160.4.3",
+ "5.160.4.4",
+ "5.160.4.5",
+ "5.160.4.7",
+ "5.160.4.8",
+ "5.160.4.9",
+ "5.160.4.10",
+ "5.160.4.11",
+ "5.160.4.12",
+ "5.160.12.122",
+ "5.160.13.202",
+ "5.160.24.22",
+ "5.160.25.130",
+ "5.160.36.9",
+ "5.160.45.254",
+ "5.160.56.246",
+ "5.160.62.1",
+ "5.160.65.254",
+ "5.160.92.121",
+ "5.160.92.226",
+ "5.160.92.227",
+ "5.160.92.228",
+ "5.160.92.229",
+ "5.160.92.230",
+ "5.160.94.34",
+ "5.160.96.225",
+ "5.160.109.184",
+ "5.160.123.194",
+ "5.160.126.138",
+ "5.160.136.10",
+ "5.160.148.66",
+ "5.160.148.67",
+ "5.160.148.68",
+ "5.160.148.69",
+ "5.160.148.70",
+ "5.160.148.71",
+ "5.160.148.72",
+ "5.160.148.74",
+ "5.160.148.77",
+ "5.160.163.134",
+ "5.160.171.205",
+ "5.160.178.11",
+ "5.160.186.158",
+ "5.160.224.230",
+ "5.160.236.206",
+ "5.190.6.209",
+ "5.190.15.14",
+ "5.190.15.24",
+ "5.190.19.169",
+ "5.190.31.223",
+ "5.190.35.66",
+ "5.190.35.97",
+ "5.190.38.2",
+ "5.190.38.49",
+ "5.190.69.7",
+ "5.190.112.72",
+ "5.190.113.6",
+ "5.190.113.140",
+ "5.190.113.183",
+ "5.190.128.8",
+ "5.190.128.129",
+ "5.190.160.53",
+ "5.190.160.57",
+ "5.190.220.34",
+ "5.198.177.232",
+ "5.200.65.62",
+ "5.200.72.170",
+ "5.200.72.171",
+ "5.200.72.172",
+ "5.200.72.173",
+ "5.200.74.42",
+ "5.200.74.50",
+ "5.200.92.86",
+ "5.200.92.244",
+ "5.200.128.20",
+ "5.200.132.3",
+ "5.200.134.101",
+ "5.200.146.99",
+ "5.200.163.136",
+ "5.200.164.247",
+ "5.200.170.71",
+ "5.200.171.36",
+ "5.200.176.48",
+ "5.200.184.32",
+ "5.200.187.76",
+ "5.200.194.128",
+ "5.200.195.164",
+ "5.200.197.185",
+ "5.200.198.18",
+ "5.200.201.89",
+ "5.200.210.162",
+ "5.200.215.15",
+ "5.200.240.130",
+ "5.200.242.159",
+ "5.200.244.61",
+ "5.201.137.96",
+ "5.201.179.171",
+ "5.201.188.29",
+ "5.201.190.178",
+ "5.202.7.227",
+ "5.202.8.189",
+ "5.202.18.102",
+ "5.202.31.165",
+ "5.202.31.223",
+ "5.202.33.71",
+ "5.202.37.55",
+ "5.202.44.204",
+ "5.202.45.176",
+ "5.202.46.130",
+ "5.202.50.117",
+ "5.202.53.129",
+ "5.202.56.141",
+ "5.202.60.116",
+ "5.202.67.98",
+ "5.202.68.103",
+ "5.202.84.189",
+ "5.202.101.56",
+ "5.202.101.146",
+ "5.202.104.46",
+ "5.202.105.105",
+ "5.202.130.8",
+ "5.202.130.15",
+ "5.202.131.150",
+ "5.202.133.117",
+ "5.202.134.189",
+ "5.202.134.199",
+ "5.202.168.111",
+ "5.202.168.119",
+ "5.202.168.152",
+ "5.202.169.223",
+ "5.202.170.19",
+ "5.202.171.163",
+ "5.202.171.191",
+ "5.202.172.103",
+ "5.202.172.114",
+ "5.202.172.183",
+ "5.202.174.52",
+ "5.202.176.249",
+ "5.202.180.114",
+ "5.202.192.33",
+ "5.202.193.131",
+ "5.202.195.45",
+ "5.202.195.51",
+ "5.202.195.180",
+ "5.202.197.82",
+ "5.202.198.47",
+ "5.202.243.73",
+ "5.202.244.49",
+ "5.202.244.217",
+ "5.202.248.100",
+ "5.202.248.115",
+ "5.202.251.74",
+ "5.202.252.251",
+ "5.232.193.40",
+ "5.232.195.40",
+ "5.232.199.145",
+ "5.232.201.225",
+ "5.232.208.59",
+ "5.232.208.178",
+ "5.232.210.50",
+ "5.232.210.132",
+ "5.232.210.222",
+ "5.232.214.197",
+ "5.233.44.62",
+ "5.233.46.93",
+ "5.233.48.136",
+ "5.233.48.194",
+ "5.233.52.86",
+ "5.233.53.56",
+ "5.233.55.148",
+ "5.233.58.136",
+ "5.233.58.144",
+ "5.233.59.44",
+ "5.233.59.230",
+ "5.233.61.98",
+ "5.233.64.200",
+ "5.233.67.248",
+ "5.233.69.125",
+ "5.233.74.76",
+ "5.233.75.240",
+ "5.233.75.250",
+ "5.233.77.37",
+ "5.233.81.193",
+ "5.233.85.66",
+ "5.233.91.53",
+ "5.233.93.115",
+ "5.233.93.131",
+ "5.233.94.60",
+ "5.233.97.234",
+ "5.233.106.189",
+ "5.233.181.73",
+ "5.233.250.11",
+ "5.233.250.69",
+ "5.234.0.79",
+ "5.234.33.50",
+ "5.234.34.57",
+ "5.234.196.166",
+ "5.234.199.241",
+ "5.234.200.92",
+ "5.234.200.137",
+ "5.234.202.94",
+ "5.234.202.190",
+ "5.234.204.177",
+ "5.234.204.253",
+ "5.234.207.165",
+ "5.234.208.89",
+ "5.234.210.1",
+ "5.234.219.151",
+ "5.235.156.18",
+ "5.235.158.237",
+ "5.235.160.167",
+ "5.235.163.89",
+ "5.235.163.98",
+ "5.235.165.39",
+ "5.235.168.186",
+ "5.235.183.5",
+ "5.235.183.159",
+ "5.235.184.199",
+ "5.235.186.254",
+ "5.235.204.78",
+ "5.235.208.203",
+ "5.235.225.63",
+ "5.235.237.139",
+ "5.236.27.202",
+ "5.236.36.77",
+ "5.236.37.103",
+ "5.236.37.159",
+ "5.236.52.142",
+ "5.236.68.129",
+ "5.236.73.237",
+ "5.236.74.210",
+ "5.236.84.190",
+ "5.236.84.192",
+ "5.236.85.62",
+ "5.236.107.158",
+ "5.236.118.91",
+ "5.236.118.105",
+ "5.236.119.175",
+ "5.236.119.229",
+ "5.236.120.190",
+ "5.236.120.193",
+ "5.236.120.235",
+ "5.236.123.214",
+ "5.236.124.167",
+ "5.236.126.76",
+ "5.236.126.227",
+ "5.236.194.234",
+ "5.236.195.148",
+ "5.236.209.26",
+ "5.236.229.2",
+ "5.236.230.82",
+ "5.236.231.10",
+ "5.236.232.140",
+ "5.236.232.215",
+ "5.236.232.238",
+ "5.236.234.18",
+ "5.236.235.10",
+ "5.236.235.199",
+ "5.236.237.236",
+ "5.236.239.22",
+ "5.236.241.109",
+ "5.236.241.133",
+ "5.236.245.47",
+ "5.236.245.86",
+ "5.236.245.163",
+ "5.236.246.226",
+ "5.236.249.2",
+ "5.236.250.105",
+ "5.236.250.176",
+ "5.236.251.135",
+ "5.237.48.134",
+ "5.237.51.190",
+ "5.237.172.191",
+ "5.237.174.161",
+ "5.237.190.133",
+ "5.237.206.248",
+ "5.237.213.90",
+ "5.237.245.132",
+ "5.237.255.27",
+ "5.238.0.89",
+ "5.238.7.139",
+ "5.238.24.206",
+ "5.238.30.209",
+ "5.238.31.104",
+ "5.238.65.35",
+ "5.238.78.40",
+ "5.238.88.24",
+ "5.238.89.91",
+ "5.238.97.239",
+ "5.238.110.3",
+ "5.238.110.167",
+ "5.238.110.213",
+ "5.238.130.4",
+ "5.238.133.19",
+ "5.238.134.79",
+ "5.238.135.96",
+ "5.238.141.127",
+ "5.238.143.185",
+ "5.238.150.47",
+ "5.238.150.53",
+ "5.238.150.56",
+ "5.238.151.220",
+ "5.238.152.177",
+ "5.238.152.198",
+ "5.238.152.219",
+ "5.238.154.229",
+ "5.238.156.79",
+ "5.238.156.165",
+ "5.238.157.70",
+ "5.238.157.199",
+ "5.238.158.245",
+ "5.238.159.131",
+ "5.238.160.36",
+ "5.238.165.192",
+ "5.238.169.30",
+ "5.238.171.5",
+ "5.238.172.60",
+ "5.238.173.41",
+ "5.238.175.197",
+ "5.238.177.107",
+ "5.238.178.33",
+ "5.238.179.239",
+ "5.238.181.231",
+ "5.238.181.255",
+ "5.238.182.247",
+ "5.238.185.124",
+ "5.238.187.1",
+ "5.238.187.140",
+ "5.238.193.30",
+ "5.238.193.244",
+ "5.238.200.210",
+ "5.238.201.203",
+ "5.238.203.199",
+ "5.238.204.198",
+ "5.238.207.195",
+ "5.238.212.93",
+ "5.238.212.230",
+ "5.238.215.18",
+ "5.238.217.118",
+ "5.238.219.142",
+ "5.238.220.91",
+ "5.238.220.102",
+ "5.238.220.140",
+ "5.238.220.186",
+ "5.238.220.220",
+ "5.238.220.248",
+ "5.238.221.65",
+ "5.238.223.141",
+ "5.238.223.191",
+ "5.238.224.243",
+ "5.238.225.34",
+ "5.238.229.124",
+ "5.238.232.103",
+ "5.238.232.177",
+ "5.238.236.69",
+ "5.238.238.240",
+ "5.238.240.163",
+ "5.238.241.173",
+ "5.238.242.42",
+ "5.238.242.208",
+ "5.238.243.13",
+ "5.238.245.212",
+ "5.238.246.10",
+ "5.238.246.172",
+ "5.238.247.166",
+ "5.238.248.237",
+ "5.238.251.105",
+ "5.238.253.179",
+ "5.238.255.209",
+ "5.239.1.48",
+ "5.239.2.189",
+ "5.239.7.66",
+ "5.239.8.61",
+ "5.239.8.91",
+ "5.239.9.27",
+ "5.239.9.95",
+ "5.239.15.238",
+ "5.239.16.146",
+ "5.239.18.169",
+ "5.239.19.59",
+ "5.239.21.123",
+ "5.239.21.243",
+ "5.239.23.168",
+ "5.239.28.79",
+ "5.239.28.187",
+ "5.239.28.190",
+ "5.239.32.187",
+ "5.239.33.153",
+ "5.239.39.141",
+ "5.239.43.186",
+ "5.239.44.114",
+ "5.239.45.55",
+ "5.239.45.119",
+ "5.239.46.122",
+ "5.239.50.227",
+ "5.239.52.92",
+ "5.239.53.98",
+ "5.239.56.200",
+ "5.239.57.135",
+ "5.239.58.62",
+ "5.239.59.64",
+ "5.239.59.107",
+ "5.239.60.67",
+ "5.239.62.104",
+ "5.239.63.8",
+ "5.239.64.243",
+ "5.239.67.160",
+ "5.239.67.218",
+ "5.239.68.12",
+ "5.239.72.145",
+ "5.239.75.70",
+ "5.239.77.124",
+ "5.239.77.235",
+ "5.239.78.153",
+ "5.239.81.155",
+ "5.239.82.24",
+ "5.239.82.141",
+ "5.239.84.50",
+ "5.239.86.80",
+ "5.239.86.114",
+ "5.239.86.213",
+ "5.239.86.250",
+ "5.239.87.163",
+ "5.239.88.27",
+ "5.239.88.97",
+ "5.239.89.181",
+ "5.239.95.160",
+ "5.239.97.128",
+ "5.239.97.243",
+ "5.239.106.96",
+ "5.239.107.197",
+ "5.239.114.119",
+ "5.239.114.191",
+ "5.239.115.200",
+ "5.239.118.70",
+ "5.239.120.171",
+ "5.239.121.241",
+ "5.239.122.71",
+ "5.239.123.122",
+ "5.239.146.31",
+ "5.239.156.62",
+ "5.239.160.78",
+ "5.239.229.90",
+ "5.239.229.93",
+ "5.239.229.141",
+ "5.239.230.163",
+ "5.239.231.128",
+ "5.239.232.233",
+ "5.239.234.104",
+ "5.239.234.118",
+ "5.239.234.251",
+ "5.239.237.197",
+ "5.239.240.243",
+ "5.239.241.88",
+ "31.7.65.42",
+ "31.7.65.43",
+ "31.7.65.44",
+ "31.7.65.46",
+ "31.7.89.106",
+ "31.7.89.126",
+ "31.7.90.115",
+ "31.24.201.82",
+ "31.25.92.29",
+ "31.25.92.100",
+ "31.25.92.161",
+ "31.25.129.114",
+ "31.25.132.114",
+ "31.25.135.146",
+ "31.47.51.23",
+ "31.47.51.149",
+ "31.171.222.82",
+ "31.184.141.30",
+ "31.184.188.88",
+ "37.32.47.176",
+ "37.32.121.210",
+ "37.32.121.225",
+ "37.32.125.194",
+ "37.75.244.6",
+ "37.75.244.51",
+ "37.75.245.24",
+ "37.75.245.59",
+ "37.75.245.130",
+ "37.75.245.132",
+ "37.75.245.133",
+ "37.75.246.1",
+ "37.75.246.50",
+ "37.75.246.52",
+ "37.75.246.53",
+ "37.143.147.31",
+ "37.148.0.71",
+ "37.148.17.66",
+ "37.148.25.167",
+ "37.148.58.95",
+ "37.148.81.211",
+ "37.148.86.227",
+ "37.152.164.50",
+ "37.153.128.176",
+ "37.153.130.55",
+ "37.156.8.33",
+ "37.156.8.85",
+ "37.156.9.190",
+ "37.156.11.70",
+ "37.156.12.28",
+ "37.156.13.215",
+ "37.156.15.184",
+ "37.156.15.246",
+ "37.156.30.206",
+ "37.156.144.81",
+ "37.191.78.213",
+ "37.191.78.214",
+ "37.202.156.75",
+ "37.202.156.98",
+ "37.202.157.22",
+ "37.202.170.112",
+ "37.202.171.204",
+ "37.202.189.21",
+ "37.228.139.163",
+ "37.228.139.164",
+ "37.228.139.165",
+ "37.228.139.166",
+ "37.255.128.218",
+ "37.255.128.220",
+ "37.255.129.56",
+ "37.255.132.26",
+ "37.255.134.87",
+ "37.255.134.143",
+ "37.255.149.128",
+ "37.255.149.221",
+ "37.255.173.50",
+ "37.255.176.18",
+ "37.255.192.204",
+ "37.255.195.143",
+ "37.255.196.74",
+ "37.255.196.175",
+ "37.255.208.116",
+ "37.255.210.1",
+ "37.255.211.212",
+ "37.255.213.72",
+ "37.255.213.226",
+ "37.255.217.2",
+ "37.255.220.2",
+ "37.255.220.101",
+ "37.255.222.28",
+ "37.255.222.121",
+ "37.255.223.74",
+ "37.255.226.13",
+ "37.255.231.150",
+ "37.255.235.76",
+ "37.255.236.74",
+ "37.255.238.0",
+ "37.255.238.113",
+ "37.255.238.136",
+ "37.255.238.156",
+ "37.255.240.167",
+ "37.255.241.74",
+ "37.255.242.142",
+ "37.255.242.252",
+ "37.255.255.243",
+ "45.9.253.179",
+ "45.87.4.91",
+ "45.87.4.130",
+ "45.94.212.5",
+ "45.132.175.121",
+ "45.135.241.251",
+ "45.138.135.75",
+ "45.142.191.27",
+ "45.142.191.196",
+ "45.142.191.197",
+ "45.142.191.202",
+ "45.142.191.203",
+ "45.159.150.79",
+ "46.32.31.195",
+ "46.34.161.193",
+ "46.34.166.142",
+ "46.34.166.236",
+ "46.51.37.142",
+ "46.100.2.195",
+ "46.100.3.123",
+ "46.100.8.118",
+ "46.100.10.122",
+ "46.100.10.123",
+ "46.100.10.237",
+ "46.100.11.36",
+ "46.100.11.103",
+ "46.100.11.168",
+ "46.100.32.107",
+ "46.100.32.206",
+ "46.100.33.20",
+ "46.100.40.43",
+ "46.100.41.93",
+ "46.100.42.58",
+ "46.100.45.65",
+ "46.100.45.228",
+ "46.100.45.234",
+ "46.100.47.174",
+ "46.100.49.96",
+ "46.100.50.129",
+ "46.100.52.76",
+ "46.100.53.30",
+ "46.100.53.68",
+ "46.100.55.77",
+ "46.100.56.65",
+ "46.100.57.133",
+ "46.100.58.82",
+ "46.100.58.238",
+ "46.100.59.62",
+ "46.100.59.121",
+ "46.100.60.8",
+ "46.100.60.29",
+ "46.100.60.125",
+ "46.100.60.151",
+ "46.100.61.40",
+ "46.100.61.74",
+ "46.100.61.171",
+ "46.100.61.247",
+ "46.100.62.89",
+ "46.100.75.205",
+ "46.100.92.38",
+ "46.100.92.64",
+ "46.100.93.209",
+ "46.100.94.175",
+ "46.100.99.218",
+ "46.100.106.113",
+ "46.100.116.237",
+ "46.100.132.82",
+ "46.100.132.250",
+ "46.100.146.123",
+ "46.100.147.227",
+ "46.100.148.51",
+ "46.100.149.144",
+ "46.100.164.204",
+ "46.100.165.3",
+ "46.100.165.41",
+ "46.100.165.154",
+ "46.100.167.151",
+ "46.100.167.203",
+ "46.100.168.233",
+ "46.100.169.22",
+ "46.100.169.38",
+ "46.100.169.142",
+ "46.100.171.14",
+ "46.100.171.105",
+ "46.100.187.239",
+ "46.100.196.108",
+ "46.100.216.23",
+ "46.100.219.91",
+ "46.100.220.219",
+ "46.100.220.225",
+ "46.100.221.40",
+ "46.100.221.85",
+ "46.100.231.142",
+ "46.100.243.137",
+ "46.100.248.35",
+ "46.102.130.37",
+ "46.143.245.4",
+ "46.148.34.220",
+ "46.148.38.10",
+ "46.148.38.19",
+ "46.148.38.43",
+ "46.148.39.101",
+ "46.148.40.49",
+ "46.148.43.190",
+ "46.148.44.204",
+ "46.167.133.214",
+ "46.167.136.35",
+ "46.167.140.202",
+ "46.167.144.122",
+ "46.167.144.253",
+ "46.167.145.195",
+ "46.167.147.150",
+ "46.167.151.122",
+ "46.167.151.238",
+ "46.167.159.23",
+ "46.209.22.231",
+ "46.209.30.46",
+ "46.209.44.2",
+ "46.209.51.158",
+ "46.209.106.204",
+ "46.209.223.243",
+ "46.209.255.243",
+ "46.235.76.19",
+ "46.235.77.78",
+ "46.245.2.181",
+ "46.245.12.52",
+ "46.245.13.243",
+ "46.245.14.45",
+ "46.245.14.119",
+ "46.245.15.57",
+ "46.245.23.49",
+ "46.245.26.167",
+ "46.245.27.5",
+ "46.245.31.147",
+ "46.245.40.26",
+ "46.245.43.146",
+ "46.245.43.156",
+ "46.245.45.95",
+ "46.245.45.132",
+ "46.245.46.94",
+ "46.245.76.247",
+ "46.245.76.249",
+ "46.245.78.84",
+ "46.245.78.86",
+ "46.245.87.3",
+ "46.245.89.48",
+ "46.245.89.51",
+ "46.245.89.52",
+ "46.245.89.53",
+ "46.245.89.55",
+ "46.245.89.56",
+ "46.245.89.57",
+ "46.245.91.72",
+ "46.245.91.73",
+ "46.245.91.74",
+ "46.245.91.75",
+ "46.245.91.78",
+ "46.245.91.80",
+ "46.245.94.190",
+ "46.245.114.114",
+ "46.249.120.224",
+ "46.249.120.227",
+ "46.249.120.228",
+ "46.249.120.244",
+ "46.249.121.42",
+ "46.249.121.227",
+ "46.249.122.28",
+ "46.249.122.86",
+ "46.249.122.87",
+ "46.249.122.90",
+ "46.249.122.91",
+ "46.249.124.1",
+ "46.249.126.177",
+ "62.60.162.236",
+ "62.60.163.244",
+ "62.60.207.217",
+ "62.60.223.196",
+ "62.220.112.249",
+ "66.79.99.200",
+ "66.79.112.89",
+ "66.79.113.200",
+ "77.36.146.37",
+ "77.36.243.5",
+ "77.81.34.180",
+ "77.81.34.221",
+ "77.81.35.43",
+ "77.81.37.184",
+ "77.81.40.10",
+ "77.81.41.69",
+ "77.81.46.254",
+ "77.81.146.230",
+ "77.81.147.29",
+ "77.81.148.90",
+ "77.81.148.172",
+ "77.81.148.187",
+ "77.81.150.212",
+ "77.81.153.245",
+ "77.81.154.53",
+ "77.81.156.52",
+ "77.81.158.150",
+ "77.81.158.173",
+ "77.81.158.250",
+ "77.104.90.154",
+ "77.104.93.43",
+ "77.104.115.152",
+ "77.104.115.161",
+ "77.104.126.13",
+ "77.104.126.136",
+ "77.238.106.88",
+ "77.238.106.108",
+ "77.238.106.154",
+ "77.238.107.79",
+ "77.238.109.90",
+ "78.38.26.128",
+ "78.38.26.132",
+ "78.38.26.134",
+ "78.38.26.135",
+ "78.38.26.151",
+ "78.38.26.155",
+ "78.38.26.159",
+ "78.38.26.164",
+ "78.38.26.181",
+ "78.38.26.183",
+ "78.38.26.188",
+ "78.38.26.210",
+ "78.38.26.226",
+ "78.38.27.3",
+ "78.38.29.31",
+ "78.38.30.118",
+ "78.38.34.90",
+ "78.38.88.75",
+ "78.38.89.48",
+ "78.38.90.169",
+ "78.38.91.170",
+ "78.38.105.11",
+ "78.38.110.82",
+ "78.38.123.58",
+ "78.38.126.189",
+ "78.38.152.39",
+ "78.38.153.189",
+ "78.38.166.50",
+ "78.38.166.161",
+ "78.38.168.165",
+ "78.38.169.230",
+ "78.38.183.35",
+ "78.38.194.203",
+ "78.38.195.162",
+ "78.38.195.168",
+ "78.38.210.89",
+ "78.38.210.119",
+ "78.38.210.206",
+ "78.38.217.110",
+ "78.38.243.235",
+ "78.39.11.74",
+ "78.39.26.103",
+ "78.39.28.149",
+ "78.39.29.203",
+ "78.39.29.208",
+ "78.39.31.90",
+ "78.39.57.167",
+ "78.39.81.36",
+ "78.39.83.6",
+ "78.39.83.21",
+ "78.39.83.133",
+ "78.39.88.109",
+ "78.39.88.157",
+ "78.39.88.243",
+ "78.39.89.85",
+ "78.39.89.162",
+ "78.39.90.151",
+ "78.39.91.177",
+ "78.39.91.192",
+ "78.39.92.139",
+ "78.39.93.201",
+ "78.39.94.33",
+ "78.39.94.34",
+ "78.39.95.51",
+ "78.39.97.3",
+ "78.39.99.16",
+ "78.39.99.18",
+ "78.39.99.19",
+ "78.39.99.20",
+ "78.39.99.21",
+ "78.39.99.22",
+ "78.39.99.23",
+ "78.39.99.114",
+ "78.39.99.118",
+ "78.39.112.154",
+ "78.39.119.115",
+ "78.39.119.205",
+ "78.39.120.28",
+ "78.39.120.135",
+ "78.39.120.208",
+ "78.39.122.39",
+ "78.39.123.99",
+ "78.39.123.105",
+ "78.39.126.216",
+ "78.39.134.132",
+ "78.39.139.32",
+ "78.39.140.106",
+ "78.39.140.166",
+ "78.39.142.2",
+ "78.39.145.18",
+ "78.39.173.132",
+ "78.39.201.210",
+ "78.39.228.64",
+ "78.39.228.77",
+ "78.39.231.68",
+ "78.39.233.249",
+ "78.39.234.58",
+ "78.39.235.85",
+ "78.39.250.120",
+ "78.110.122.102",
+ "78.157.34.223",
+ "78.157.35.16",
+ "78.157.35.31",
+ "78.157.35.40",
+ "78.157.37.240",
+ "78.157.38.175",
+ "78.157.39.84",
+ "78.157.39.112",
+ "78.157.39.127",
+ "78.157.41.112",
+ "78.157.41.120",
+ "78.157.43.176",
+ "78.157.43.183",
+ "78.157.45.48",
+ "78.157.45.136",
+ "78.157.45.224",
+ "78.157.45.231",
+ "78.157.45.240",
+ "78.157.45.247",
+ "78.157.46.80",
+ "78.157.47.115",
+ "78.157.48.23",
+ "78.157.48.127",
+ "78.157.48.128",
+ "78.157.50.23",
+ "78.157.57.32",
+ "78.157.57.60",
+ "78.157.57.67",
+ "78.157.57.194",
+ "78.157.57.227",
+ "78.157.57.237",
+ "78.157.58.31",
+ "78.157.58.36",
+ "78.157.58.40",
+ "78.157.58.168",
+ "78.157.61.40",
+ "78.158.191.228",
+ "79.127.2.107",
+ "79.127.3.107",
+ "79.127.3.122",
+ "79.127.4.41",
+ "79.127.4.154",
+ "79.127.5.25",
+ "79.127.5.209",
+ "79.127.6.78",
+ "79.127.6.134",
+ "79.127.6.165",
+ "79.127.7.120",
+ "79.127.13.189",
+ "79.127.14.88",
+ "79.127.69.121",
+ "79.127.69.125",
+ "79.127.75.51",
+ "79.127.75.52",
+ "79.127.75.54",
+ "79.127.77.51",
+ "79.127.77.52",
+ "79.127.77.53",
+ "79.127.77.54",
+ "79.127.101.13",
+ "79.127.125.18",
+ "79.127.126.91",
+ "79.175.182.42",
+ "79.175.186.60",
+ "79.175.186.61",
+ "80.75.5.26",
+ "80.75.8.70",
+ "80.191.16.186",
+ "80.191.17.246",
+ "80.191.38.128",
+ "80.191.39.11",
+ "80.191.39.185",
+ "80.191.40.137",
+ "80.191.40.152",
+ "80.191.51.51",
+ "80.191.52.19",
+ "80.191.64.104",
+ "80.191.71.89",
+ "80.191.71.136",
+ "80.191.77.163",
+ "80.191.86.234",
+ "80.191.87.143",
+ "80.191.100.159",
+ "80.191.102.86",
+ "80.191.107.5",
+ "80.191.189.166",
+ "80.191.192.249",
+ "80.191.194.187",
+ "80.191.195.227",
+ "80.191.203.4",
+ "80.191.220.134",
+ "80.191.221.10",
+ "80.191.222.119",
+ "80.191.230.86",
+ "80.191.235.130",
+ "80.191.240.70",
+ "80.191.250.61",
+ "80.191.253.225",
+ "80.210.6.100",
+ "80.210.7.254",
+ "80.210.8.120",
+ "80.210.9.170",
+ "80.210.9.226",
+ "80.210.12.253",
+ "80.210.17.204",
+ "80.210.18.80",
+ "80.210.18.226",
+ "80.210.21.43",
+ "80.210.22.3",
+ "80.210.22.27",
+ "80.210.22.73",
+ "80.210.22.115",
+ "80.210.22.181",
+ "80.210.22.219",
+ "80.210.24.197",
+ "80.210.25.137",
+ "80.210.26.129",
+ "80.210.27.23",
+ "80.210.30.51",
+ "80.210.30.117",
+ "80.210.32.0",
+ "80.210.32.240",
+ "80.210.35.177",
+ "80.210.35.231",
+ "80.210.37.24",
+ "80.210.41.3",
+ "80.210.41.114",
+ "80.210.42.127",
+ "80.210.42.186",
+ "80.210.44.69",
+ "80.210.45.21",
+ "80.210.45.71",
+ "80.210.48.164",
+ "80.210.48.185",
+ "80.210.50.88",
+ "80.210.50.152",
+ "80.210.50.199",
+ "80.210.51.52",
+ "80.210.52.182",
+ "80.210.54.72",
+ "80.210.58.171",
+ "80.210.59.165",
+ "80.210.60.166",
+ "80.210.63.101",
+ "80.210.139.23",
+ "80.210.141.56",
+ "80.210.160.201",
+ "80.210.164.153",
+ "80.210.183.27",
+ "80.210.193.176",
+ "80.210.196.185",
+ "80.210.242.220",
+ "80.210.245.84",
+ "80.210.246.86",
+ "80.253.152.178",
+ "80.253.152.180",
+ "81.12.1.28",
+ "81.12.5.227",
+ "81.12.47.52",
+ "81.12.70.146",
+ "81.12.72.234",
+ "81.12.74.5",
+ "81.12.76.64",
+ "81.12.76.65",
+ "81.12.76.66",
+ "81.12.76.67",
+ "81.12.76.68",
+ "81.12.76.69",
+ "81.12.76.70",
+ "81.12.76.71",
+ "81.12.76.73",
+ "81.12.76.74",
+ "81.12.76.75",
+ "81.12.76.77",
+ "81.12.76.79",
+ "81.12.84.247",
+ "81.12.87.101",
+ "81.12.99.218",
+ "81.12.118.214",
+ "81.12.124.117",
+ "81.12.124.158",
+ "81.12.127.50",
+ "81.16.112.49",
+ "81.16.112.111",
+ "81.16.113.186",
+ "81.16.114.44",
+ "81.16.114.199",
+ "81.16.117.49",
+ "81.16.121.150",
+ "81.16.121.241",
+ "81.16.124.53",
+ "81.16.124.73",
+ "81.16.124.165",
+ "81.16.125.185",
+ "81.16.125.235",
+ "81.16.126.254",
+ "81.28.32.40",
+ "81.28.33.58",
+ "81.28.52.31",
+ "81.28.61.73",
+ "81.29.248.99",
+ "81.29.248.100",
+ "81.29.248.101",
+ "81.29.248.102",
+ "81.29.248.103",
+ "81.29.248.104",
+ "81.29.248.105",
+ "81.29.248.107",
+ "81.90.146.46",
+ "81.91.136.210",
+ "81.91.144.18",
+ "81.91.146.22",
+ "81.91.151.30",
+ "81.91.152.222",
+ "81.91.153.9",
+ "81.91.155.78",
+ "81.91.156.186",
+ "81.91.157.178",
+ "81.91.159.58",
+ "81.163.6.45",
+ "82.99.232.78",
+ "82.99.253.49",
+ "84.47.236.218",
+ "84.47.236.242",
+ "84.241.1.127",
+ "84.241.2.181",
+ "84.241.2.187",
+ "84.241.3.56",
+ "84.241.3.94",
+ "84.241.3.202",
+ "84.241.4.78",
+ "84.241.5.178",
+ "84.241.6.65",
+ "84.241.6.132",
+ "84.241.6.191",
+ "84.241.6.244",
+ "84.241.8.128",
+ "84.241.8.189",
+ "84.241.9.10",
+ "84.241.12.44",
+ "84.241.12.173",
+ "84.241.12.174",
+ "84.241.14.53",
+ "84.241.14.215",
+ "84.241.14.220",
+ "84.241.14.228",
+ "84.241.15.29",
+ "84.241.15.191",
+ "84.241.16.37",
+ "84.241.16.46",
+ "84.241.16.203",
+ "84.241.16.229",
+ "84.241.18.174",
+ "84.241.18.236",
+ "84.241.18.254",
+ "84.241.19.114",
+ "84.241.22.145",
+ "84.241.23.155",
+ "84.241.24.107",
+ "84.241.24.201",
+ "84.241.24.246",
+ "84.241.25.93",
+ "84.241.25.250",
+ "84.241.26.234",
+ "84.241.27.32",
+ "84.241.27.173",
+ "84.241.28.126",
+ "84.241.28.170",
+ "84.241.28.209",
+ "84.241.29.33",
+ "84.241.29.55",
+ "84.241.29.213",
+ "84.241.30.49",
+ "84.241.30.140",
+ "84.241.36.194",
+ "84.241.38.77",
+ "84.241.38.166",
+ "84.241.41.13",
+ "84.241.42.191",
+ "84.241.44.145",
+ "84.241.44.198",
+ "84.241.45.83",
+ "84.241.45.218",
+ "84.241.49.40",
+ "84.241.52.13",
+ "84.241.52.15",
+ "84.241.56.122",
+ "84.241.60.91",
+ "85.9.87.50",
+ "85.9.87.51",
+ "85.9.94.3",
+ "85.9.94.229",
+ "85.9.105.38",
+ "85.9.105.41",
+ "85.9.115.105",
+ "85.9.120.237",
+ "85.9.121.104",
+ "85.9.122.69",
+ "85.133.133.206",
+ "85.133.136.202",
+ "85.133.137.98",
+ "85.133.173.138",
+ "85.133.173.139",
+ "85.133.173.141",
+ "85.133.173.142",
+ "85.133.176.48",
+ "85.133.184.233",
+ "85.133.186.106",
+ "85.133.187.69",
+ "85.133.190.170",
+ "85.133.221.190",
+ "85.133.221.191",
+ "85.133.228.178",
+ "85.133.229.121",
+ "85.133.229.202",
+ "85.185.3.100",
+ "85.185.12.173",
+ "85.185.13.60",
+ "85.185.13.148",
+ "85.185.14.43",
+ "85.185.43.176",
+ "85.185.43.224",
+ "85.185.49.27",
+ "85.185.54.100",
+ "85.185.62.32",
+ "85.185.75.218",
+ "85.185.78.181",
+ "85.185.81.226",
+ "85.185.81.227",
+ "85.185.85.6",
+ "85.185.87.105",
+ "85.185.88.134",
+ "85.185.98.57",
+ "85.185.111.80",
+ "85.185.123.177",
+ "85.185.133.193",
+ "85.185.138.250",
+ "85.185.139.34",
+ "85.185.139.42",
+ "85.185.185.172",
+ "85.185.187.2",
+ "85.185.190.109",
+ "85.185.201.197",
+ "85.185.201.198",
+ "85.185.201.227",
+ "85.185.201.230",
+ "85.185.206.161",
+ "85.185.208.82",
+ "85.185.212.150",
+ "85.185.235.18",
+ "85.185.238.111",
+ "85.185.239.154",
+ "85.185.239.155",
+ "85.185.239.157",
+ "85.198.26.3",
+ "85.198.28.2",
+ "85.198.29.80",
+ "85.198.30.54",
+ "85.198.30.223",
+ "85.198.31.15",
+ "85.198.31.107",
+ "85.198.31.113",
+ "85.204.88.255",
+ "85.204.208.159",
+ "86.104.38.94",
+ "86.104.83.86",
+ "86.104.88.202",
+ "86.104.96.231",
+ "86.104.98.191",
+ "86.104.98.195",
+ "86.104.98.239",
+ "86.104.100.245",
+ "86.104.101.72",
+ "86.104.105.166",
+ "86.104.106.34",
+ "86.104.107.4",
+ "86.104.109.105",
+ "86.104.111.197",
+ "86.105.43.13",
+ "86.105.44.251",
+ "86.105.45.105",
+ "86.105.46.122",
+ "86.105.47.176",
+ "86.105.134.249",
+ "86.105.138.65",
+ "86.107.93.69",
+ "86.107.145.246",
+ "86.107.148.66",
+ "86.107.149.221",
+ "86.107.152.218",
+ "86.107.155.195",
+ "86.107.155.228",
+ "86.107.156.242",
+ "86.107.157.82",
+ "87.107.17.22",
+ "87.107.18.26",
+ "87.107.18.178",
+ "87.107.18.180",
+ "87.107.48.10",
+ "87.107.55.66",
+ "87.107.87.8",
+ "87.107.87.9",
+ "87.107.87.10",
+ "87.107.87.11",
+ "87.107.105.43",
+ "87.107.105.145",
+ "87.107.136.130",
+ "87.107.141.35",
+ "87.107.141.136",
+ "87.236.38.97",
+ "87.236.38.99",
+ "87.236.38.226",
+ "87.236.214.214",
+ "87.236.215.179",
+ "87.248.145.213",
+ "87.248.150.229",
+ "87.248.151.36",
+ "87.251.141.125",
+ "88.218.16.4",
+ "89.32.197.10",
+ "89.33.129.156",
+ "89.37.152.90",
+ "89.37.153.30",
+ "89.37.153.57",
+ "89.37.155.10",
+ "89.37.155.119",
+ "89.37.219.25",
+ "89.38.103.224",
+ "89.38.244.110",
+ "89.38.246.130",
+ "89.39.9.15",
+ "89.39.9.200",
+ "89.39.11.125",
+ "89.39.11.190",
+ "89.40.78.167",
+ "89.40.79.39",
+ "89.40.79.93",
+ "89.40.79.94",
+ "89.40.246.181",
+ "89.40.247.32",
+ "89.41.40.219",
+ "89.41.41.95",
+ "89.42.69.188",
+ "89.42.98.141",
+ "89.43.7.182",
+ "89.43.144.209",
+ "89.43.220.123",
+ "89.43.222.29",
+ "89.43.224.58",
+ "89.43.224.123",
+ "89.43.226.208",
+ "89.43.227.25",
+ "89.43.227.182",
+ "89.43.230.205",
+ "89.43.231.153",
+ "89.44.132.254",
+ "89.44.176.90",
+ "89.46.95.145",
+ "89.46.216.48",
+ "89.46.216.49",
+ "89.46.216.50",
+ "89.46.216.51",
+ "89.46.216.53",
+ "89.46.218.208",
+ "89.46.218.209",
+ "89.46.218.210",
+ "89.46.218.211",
+ "89.46.218.212",
+ "89.46.218.213",
+ "89.46.218.214",
+ "89.46.218.215",
+ "89.46.219.39",
+ "89.46.219.200",
+ "89.46.219.201",
+ "89.46.219.202",
+ "89.46.219.203",
+ "89.46.219.204",
+ "89.46.219.205",
+ "89.46.219.206",
+ "89.46.219.207",
+ "89.144.136.152",
+ "89.144.148.155",
+ "89.144.157.144",
+ "89.144.157.219",
+ "89.144.167.45",
+ "89.219.64.165",
+ "89.219.66.125",
+ "89.219.68.58",
+ "89.219.69.122",
+ "89.219.69.188",
+ "89.219.71.91",
+ "89.219.71.206",
+ "89.219.74.95",
+ "89.219.74.246",
+ "89.219.76.55",
+ "89.219.76.168",
+ "89.219.76.250",
+ "89.219.76.253",
+ "89.219.77.179",
+ "89.219.78.137",
+ "89.219.78.248",
+ "89.219.79.28",
+ "89.219.79.34",
+ "89.219.81.20",
+ "89.219.82.36",
+ "89.219.82.192",
+ "89.219.84.16",
+ "89.219.88.172",
+ "89.219.92.79",
+ "89.219.95.236",
+ "89.219.98.186",
+ "89.219.102.81",
+ "89.219.102.145",
+ "89.219.102.228",
+ "89.219.104.103",
+ "89.219.105.36",
+ "89.219.105.147",
+ "89.219.105.208",
+ "89.219.106.180",
+ "89.219.106.245",
+ "89.219.107.242",
+ "89.219.108.30",
+ "89.219.108.87",
+ "89.219.108.119",
+ "89.219.108.162",
+ "89.219.114.19",
+ "89.219.114.67",
+ "89.219.116.81",
+ "89.219.117.55",
+ "89.219.118.124",
+ "89.219.120.196",
+ "89.219.121.97",
+ "89.219.121.202",
+ "89.219.122.163",
+ "89.219.124.77",
+ "89.219.124.182",
+ "89.219.124.190",
+ "89.219.125.219",
+ "89.219.125.241",
+ "89.219.195.28",
+ "89.219.197.140",
+ "89.219.198.174",
+ "89.219.200.215",
+ "89.219.202.170",
+ "89.219.204.225",
+ "89.219.205.242",
+ "89.219.206.64",
+ "89.219.206.217",
+ "89.219.208.93",
+ "89.219.209.192",
+ "89.219.210.23",
+ "89.219.210.59",
+ "89.219.210.101",
+ "89.219.211.41",
+ "89.219.211.114",
+ "89.219.211.122",
+ "89.219.213.9",
+ "89.219.215.18",
+ "89.219.216.120",
+ "89.219.219.5",
+ "89.219.220.133",
+ "89.219.224.139",
+ "89.219.224.145",
+ "89.219.225.30",
+ "89.219.226.171",
+ "89.219.227.18",
+ "89.219.227.30",
+ "89.219.229.128",
+ "89.219.230.93",
+ "89.219.235.240",
+ "89.219.238.107",
+ "89.219.240.85",
+ "89.219.240.218",
+ "89.219.241.130",
+ "89.219.241.141",
+ "89.219.244.22",
+ "89.219.244.236",
+ "89.219.246.68",
+ "89.219.246.152",
+ "89.219.246.183",
+ "89.219.249.214",
+ "89.219.251.90",
+ "89.219.251.219",
+ "89.219.251.248",
+ "89.219.253.157",
+ "89.219.254.24",
+ "89.219.254.58",
+ "89.221.84.53",
+ "89.221.84.111",
+ "89.221.85.46",
+ "89.221.85.61",
+ "89.221.85.149",
+ "89.221.85.194",
+ "89.221.85.206",
+ "89.221.85.225",
+ "89.221.85.235",
+ "89.221.85.241",
+ "89.221.85.242",
+ "89.221.85.253",
+ "89.221.86.62",
+ "89.221.86.159",
+ "89.221.86.186",
+ "89.235.70.70",
+ "89.235.102.11",
+ "89.235.109.20",
+ "91.92.121.161",
+ "91.92.121.180",
+ "91.92.121.214",
+ "91.92.122.157",
+ "91.92.125.104",
+ "91.92.125.118",
+ "91.92.125.195",
+ "91.92.129.240",
+ "91.92.130.175",
+ "91.92.131.18",
+ "91.92.131.52",
+ "91.92.131.133",
+ "91.92.133.152",
+ "91.92.149.40",
+ "91.92.150.170",
+ "91.92.157.114",
+ "91.92.157.168",
+ "91.92.164.143",
+ "91.92.180.196",
+ "91.92.181.171",
+ "91.92.181.193",
+ "91.92.182.158",
+ "91.92.185.37",
+ "91.92.186.76",
+ "91.92.186.135",
+ "91.92.188.251",
+ "91.92.191.47",
+ "91.92.191.125",
+ "91.92.205.45",
+ "91.92.207.143",
+ "91.92.207.179",
+ "91.92.209.91",
+ "91.92.212.107",
+ "91.92.212.182",
+ "91.92.214.181",
+ "91.92.215.243",
+ "91.106.67.30",
+ "91.106.80.65",
+ "91.106.80.127",
+ "91.106.83.24",
+ "91.106.83.29",
+ "91.106.90.177",
+ "91.106.94.136",
+ "91.108.138.179",
+ "91.108.150.42",
+ "91.185.129.168",
+ "91.185.130.76",
+ "91.185.140.53",
+ "91.185.141.74",
+ "91.185.144.212",
+ "91.185.147.40",
+ "91.186.193.26",
+ "91.186.193.57",
+ "91.199.18.60",
+ "91.222.206.170",
+ "91.222.206.206",
+ "91.232.72.92",
+ "91.232.72.108",
+ "91.232.72.116",
+ "91.232.72.118",
+ "91.232.72.126",
+ "91.232.74.194",
+ "91.234.39.83",
+ "91.242.44.34",
+ "91.243.165.178",
+ "91.243.172.186",
+ "92.114.17.4",
+ "92.119.58.85",
+ "92.119.58.126",
+ "92.242.193.66",
+ "92.242.206.6",
+ "92.242.219.186",
+ "92.246.144.29",
+ "93.114.111.108",
+ "93.114.111.175",
+ "93.115.121.162",
+ "93.115.125.255",
+ "93.115.127.45",
+ "93.115.144.17",
+ "93.115.144.80",
+ "93.115.145.41",
+ "93.115.145.221",
+ "93.115.145.237",
+ "93.115.146.70",
+ "93.115.146.140",
+ "93.115.146.168",
+ "93.115.146.217",
+ "93.115.147.35",
+ "93.115.147.60",
+ "93.115.147.79",
+ "93.115.147.92",
+ "93.115.147.105",
+ "93.115.147.149",
+ "93.115.147.162",
+ "93.115.148.33",
+ "93.115.148.245",
+ "93.115.149.187",
+ "93.115.149.243",
+ "93.115.219.124",
+ "93.117.1.197",
+ "93.117.32.98",
+ "93.117.38.186",
+ "93.117.41.59",
+ "93.117.42.205",
+ "93.117.127.64",
+ "93.117.127.230",
+ "93.118.96.209",
+ "93.118.107.27",
+ "93.118.107.167",
+ "93.118.108.1",
+ "93.118.108.20",
+ "93.118.108.97",
+ "93.118.108.201",
+ "93.118.110.78",
+ "93.118.114.252",
+ "93.118.115.17",
+ "93.118.116.160",
+ "93.118.119.64",
+ "93.118.119.238",
+ "93.118.120.51",
+ "93.118.120.135",
+ "93.118.123.87",
+ "93.118.124.218",
+ "93.118.126.1",
+ "93.118.127.126",
+ "93.118.127.147",
+ "93.118.127.234",
+ "93.118.128.93",
+ "93.118.128.173",
+ "93.118.132.228",
+ "93.118.136.52",
+ "93.118.139.177",
+ "93.118.139.247",
+ "93.118.140.25",
+ "93.118.140.163",
+ "93.118.141.13",
+ "93.118.141.183",
+ "93.118.142.99",
+ "93.118.142.181",
+ "93.118.143.242",
+ "93.118.145.14",
+ "93.118.145.65",
+ "93.118.146.80",
+ "93.118.146.143",
+ "93.118.146.178",
+ "93.118.147.1",
+ "93.118.148.211",
+ "93.118.148.214",
+ "93.118.150.2",
+ "93.118.151.69",
+ "93.118.151.170",
+ "93.118.152.54",
+ "93.118.152.147",
+ "93.118.152.220",
+ "93.118.153.212",
+ "93.118.154.127",
+ "93.118.156.8",
+ "93.118.159.179",
+ "93.118.160.4",
+ "93.118.160.31",
+ "93.118.161.97",
+ "93.118.161.126",
+ "93.118.162.200",
+ "93.118.163.83",
+ "93.118.163.99",
+ "93.118.163.126",
+ "93.118.163.166",
+ "93.118.164.241",
+ "93.118.166.232",
+ "93.118.180.65",
+ "93.126.7.16",
+ "93.126.9.38",
+ "93.126.10.1",
+ "93.126.11.129",
+ "93.126.12.160",
+ "93.126.18.28",
+ "93.126.18.95",
+ "93.126.18.133",
+ "93.126.19.141",
+ "93.126.19.239",
+ "93.126.25.34",
+ "93.126.56.30",
+ "94.101.133.19",
+ "94.139.183.164",
+ "94.182.2.70",
+ "94.182.2.132",
+ "94.182.2.222",
+ "94.182.4.172",
+ "94.182.5.199",
+ "94.182.18.14",
+ "94.182.18.209",
+ "94.182.18.226",
+ "94.182.23.57",
+ "94.182.24.206",
+ "94.182.27.105",
+ "94.182.31.70",
+ "94.182.31.129",
+ "94.182.34.88",
+ "94.182.35.165",
+ "94.182.35.190",
+ "94.182.35.249",
+ "94.182.39.166",
+ "94.182.48.5",
+ "94.182.50.48",
+ "94.182.53.166",
+ "94.182.53.245",
+ "94.182.56.16",
+ "94.182.63.24",
+ "94.182.94.190",
+ "94.182.110.250",
+ "94.182.189.29",
+ "94.182.189.246",
+ "94.182.192.210",
+ "94.182.192.239",
+ "94.182.193.14",
+ "94.182.193.62",
+ "94.182.193.89",
+ "94.182.193.142",
+ "94.182.193.197",
+ "94.182.193.211",
+ "94.182.194.132",
+ "94.182.196.113",
+ "94.182.196.165",
+ "94.182.197.49",
+ "94.182.197.50",
+ "94.182.200.10",
+ "94.182.202.193",
+ "94.182.211.97",
+ "94.182.211.247",
+ "94.182.214.205",
+ "94.182.216.18",
+ "94.182.216.205",
+ "94.182.225.225",
+ "94.183.0.137",
+ "94.183.0.195",
+ "94.183.1.160",
+ "94.183.6.134",
+ "94.183.7.152",
+ "94.183.7.159",
+ "94.183.19.200",
+ "94.183.21.110",
+ "94.183.23.251",
+ "94.183.24.50",
+ "94.183.27.70",
+ "94.183.27.128",
+ "94.183.27.173",
+ "94.183.27.209",
+ "94.183.28.216",
+ "94.183.30.24",
+ "94.183.30.72",
+ "94.183.30.131",
+ "94.183.30.132",
+ "94.183.30.162",
+ "94.183.30.197",
+ "94.183.31.117",
+ "94.183.32.24",
+ "94.183.32.107",
+ "94.183.46.99",
+ "94.183.60.235",
+ "94.183.62.94",
+ "94.183.62.120",
+ "94.183.67.63",
+ "94.183.67.107",
+ "94.183.71.93",
+ "94.183.72.37",
+ "94.183.72.133",
+ "94.183.75.164",
+ "94.183.83.164",
+ "94.183.85.12",
+ "94.183.89.83",
+ "94.183.90.176",
+ "94.183.91.88",
+ "94.183.91.145",
+ "94.183.92.218",
+ "94.183.93.40",
+ "94.183.97.3",
+ "94.183.97.61",
+ "94.183.99.183",
+ "94.183.102.135",
+ "94.183.103.185",
+ "94.183.109.61",
+ "94.183.116.21",
+ "94.183.118.4",
+ "94.183.118.45",
+ "94.183.121.12",
+ "94.183.123.138",
+ "94.183.124.229",
+ "94.183.126.175",
+ "94.183.127.101",
+ "94.183.127.111",
+ "94.183.127.124",
+ "94.183.131.36",
+ "94.183.133.129",
+ "94.183.145.252",
+ "94.183.149.144",
+ "94.183.160.229",
+ "94.184.21.255",
+ "94.184.178.254",
+ "94.232.173.145",
+ "94.232.175.245",
+ "95.38.11.5",
+ "95.38.33.72",
+ "95.38.33.190",
+ "95.38.34.61",
+ "95.38.46.178",
+ "95.38.48.195",
+ "95.38.48.247",
+ "95.38.49.44",
+ "95.38.49.132",
+ "95.38.49.150",
+ "95.38.49.158",
+ "95.38.52.10",
+ "95.38.52.44",
+ "95.38.52.224",
+ "95.38.66.32",
+ "95.38.66.42",
+ "95.38.67.74",
+ "95.38.67.163",
+ "95.38.78.14",
+ "95.38.132.238",
+ "95.38.135.134",
+ "95.38.143.22",
+ "95.38.148.64",
+ "95.38.149.46",
+ "95.38.149.51",
+ "95.38.149.96",
+ "95.38.169.186",
+ "95.38.192.58",
+ "95.38.192.133",
+ "95.38.192.135",
+ "95.38.192.178",
+ "95.38.196.157",
+ "95.38.196.169",
+ "95.38.196.202",
+ "95.38.196.243",
+ "95.38.199.230",
+ "95.80.141.50",
+ "95.80.168.237",
+ "95.80.171.57",
+ "95.80.175.41",
+ "95.130.56.177",
+ "95.130.59.34",
+ "95.130.225.119",
+ "95.130.225.124",
+ "95.130.225.186",
+ "95.130.225.229",
+ "95.130.225.239",
+ "95.130.225.241",
+ "95.156.252.19",
+ "95.215.160.179",
+ "103.215.220.90",
+ "109.72.197.58",
+ "109.95.71.36",
+ "109.109.44.37",
+ "109.109.44.172",
+ "109.109.52.175",
+ "109.122.235.120",
+ "109.122.237.78",
+ "109.125.129.234",
+ "109.125.130.85",
+ "109.125.132.133",
+ "109.125.132.208",
+ "109.125.132.231",
+ "109.125.134.92",
+ "109.125.135.16",
+ "109.125.140.186",
+ "109.125.147.46",
+ "109.125.160.46",
+ "109.125.168.20",
+ "109.201.13.188",
+ "109.201.15.9",
+ "109.230.82.114",
+ "109.230.83.233",
+ "109.230.89.157",
+ "109.230.90.106",
+ "109.230.90.174",
+ "109.230.93.162",
+ "109.230.94.222",
+ "109.230.94.246",
+ "109.230.204.66",
+ "109.230.204.91",
+ "109.230.204.154",
+ "109.230.204.174",
+ "109.230.204.175",
+ "109.232.2.63",
+ "109.238.189.4",
+ "109.238.189.50",
+ "128.65.176.22",
+ "128.65.179.91",
+ "128.65.180.193",
+ "128.65.183.63",
+ "128.65.184.21",
+ "128.65.184.26",
+ "128.65.184.184",
+ "128.65.188.19",
+ "128.65.188.30",
+ "128.65.189.79",
+ "151.232.3.161",
+ "151.232.48.49",
+ "151.232.60.225",
+ "151.232.101.57",
+ "151.232.207.122",
+ "151.233.2.157",
+ "151.233.18.251",
+ "151.233.47.165",
+ "151.233.50.228",
+ "151.233.53.38",
+ "151.233.58.9",
+ "151.234.0.199",
+ "151.234.1.48",
+ "151.234.2.254",
+ "151.234.3.120",
+ "151.234.23.25",
+ "151.234.28.19",
+ "151.234.31.125",
+ "151.234.31.243",
+ "151.234.72.243",
+ "151.234.87.99",
+ "151.234.125.227",
+ "151.234.187.125",
+ "151.234.211.218",
+ "151.234.245.230",
+ "151.235.1.157",
+ "151.235.6.95",
+ "151.235.7.132",
+ "151.235.8.27",
+ "151.235.8.47",
+ "151.235.23.185",
+ "151.235.32.61",
+ "151.235.35.236",
+ "151.235.38.166",
+ "151.235.91.218",
+ "151.235.95.23",
+ "151.235.98.215",
+ "151.235.99.142",
+ "151.235.99.169",
+ "151.235.101.1",
+ "151.235.101.23",
+ "151.235.102.98",
+ "151.235.106.149",
+ "151.235.106.162",
+ "151.235.107.85",
+ "151.235.108.124",
+ "151.235.109.61",
+ "151.235.109.246",
+ "151.235.110.118",
+ "151.235.110.157",
+ "151.235.111.147",
+ "151.235.112.216",
+ "151.235.114.9",
+ "151.235.115.208",
+ "151.235.118.241",
+ "151.235.120.110",
+ "151.235.121.214",
+ "151.235.123.9",
+ "151.235.126.249",
+ "151.235.129.206",
+ "151.235.134.175",
+ "151.235.185.215",
+ "151.235.187.44",
+ "151.235.190.76",
+ "151.235.217.72",
+ "151.235.240.128",
+ "151.235.246.224",
+ "151.235.250.125",
+ "159.20.96.249",
+ "159.20.103.83",
+ "159.20.111.37",
+ "171.22.25.51",
+ "176.65.184.254",
+ "176.65.224.62",
+ "176.65.226.105",
+ "176.65.226.111",
+ "176.65.227.214",
+ "176.65.228.94",
+ "176.65.231.45",
+ "176.65.241.43",
+ "176.65.241.44",
+ "176.65.241.45",
+ "176.65.241.46",
+ "176.65.252.69",
+ "176.65.252.81",
+ "176.65.252.227",
+ "176.65.253.46",
+ "176.65.253.55",
+ "176.65.253.106",
+ "176.65.253.200",
+ "176.65.254.61",
+ "176.65.254.112",
+ "176.65.254.160",
+ "176.122.210.113",
+ "176.223.80.171",
+ "176.223.83.46",
+ "178.131.66.247",
+ "178.131.72.214",
+ "178.131.101.153",
+ "178.131.113.81",
+ "178.131.134.93",
+ "178.131.135.230",
+ "178.173.131.62",
+ "178.173.131.163",
+ "178.173.131.188",
+ "178.173.137.44",
+ "178.173.137.132",
+ "178.173.137.249",
+ "178.173.137.251",
+ "178.173.138.33",
+ "178.173.138.59",
+ "178.173.138.157",
+ "178.173.138.171",
+ "178.173.138.255",
+ "178.173.139.95",
+ "178.173.140.171",
+ "178.173.141.90",
+ "178.173.143.103",
+ "178.173.143.116",
+ "178.173.143.161",
+ "178.173.146.129",
+ "178.173.147.73",
+ "178.173.147.227",
+ "178.173.161.10",
+ "178.173.163.7",
+ "178.173.163.158",
+ "178.173.163.202",
+ "178.173.169.16",
+ "178.173.169.199",
+ "178.173.169.228",
+ "178.173.170.142",
+ "178.173.173.88",
+ "178.173.173.255",
+ "178.173.174.48",
+ "178.173.174.136",
+ "178.173.174.229",
+ "178.173.175.6",
+ "178.173.175.56",
+ "178.173.175.110",
+ "178.173.175.152",
+ "178.173.175.209",
+ "178.173.182.45",
+ "178.173.182.72",
+ "178.173.182.87",
+ "178.173.182.148",
+ "178.173.182.177",
+ "178.173.184.37",
+ "178.173.184.112",
+ "178.173.184.122",
+ "178.173.185.11",
+ "178.173.185.49",
+ "178.173.185.86",
+ "178.173.185.222",
+ "178.173.185.241",
+ "178.173.192.30",
+ "178.173.193.32",
+ "178.173.193.54",
+ "178.173.193.77",
+ "178.173.193.82",
+ "178.173.195.75",
+ "178.173.195.203",
+ "178.173.196.39",
+ "178.173.196.161",
+ "178.173.197.84",
+ "178.173.197.192",
+ "178.173.197.228",
+ "178.173.198.82",
+ "178.173.198.112",
+ "178.173.198.238",
+ "178.173.199.32",
+ "178.173.199.53",
+ "178.173.199.105",
+ "178.173.199.109",
+ "178.173.199.113",
+ "178.173.199.200",
+ "178.173.200.68",
+ "178.173.210.19",
+ "178.173.210.29",
+ "178.173.210.152",
+ "178.173.210.176",
+ "178.173.211.216",
+ "178.173.212.43",
+ "178.173.212.126",
+ "178.173.212.209",
+ "178.173.213.152",
+ "178.173.213.211",
+ "178.173.213.226",
+ "178.173.214.151",
+ "178.173.214.164",
+ "178.173.215.117",
+ "178.173.215.158",
+ "178.173.215.208",
+ "178.173.215.210",
+ "178.173.216.5",
+ "178.173.216.75",
+ "178.173.216.112",
+ "178.173.217.59",
+ "178.173.218.46",
+ "178.173.219.53",
+ "178.173.219.114",
+ "178.173.220.21",
+ "178.173.220.47",
+ "178.173.220.206",
+ "178.173.221.227",
+ "178.173.222.165",
+ "178.236.98.110",
+ "178.236.99.12",
+ "178.236.99.239",
+ "178.236.100.37",
+ "178.236.103.15",
+ "178.236.103.18",
+ "178.236.103.127",
+ "178.236.104.163",
+ "178.236.105.85",
+ "178.236.105.154",
+ "178.236.106.237",
+ "178.236.107.152",
+ "178.236.108.124",
+ "178.236.111.3",
+ "178.236.111.114",
+ "178.238.195.238",
+ "178.239.144.40",
+ "178.239.156.36",
+ "178.239.156.113",
+ "178.239.156.130",
+ "178.239.156.133",
+ "178.239.157.98",
+ "178.239.157.100",
+ "178.239.157.101",
+ "178.239.157.102",
+ "178.239.157.103",
+ "178.239.157.104",
+ "178.252.141.229",
+ "178.252.147.125",
+ "178.252.151.158",
+ "178.252.152.72",
+ "178.252.153.250",
+ "178.252.171.227",
+ "178.252.171.230",
+ "178.252.177.32",
+ "178.252.177.33",
+ "178.252.177.35",
+ "178.252.177.36",
+ "178.252.177.37",
+ "178.252.177.38",
+ "178.252.177.39",
+ "178.252.177.40",
+ "178.252.177.42",
+ "178.252.177.43",
+ "178.252.177.44",
+ "178.252.177.45",
+ "185.3.201.0",
+ "185.3.201.1",
+ "185.3.201.2",
+ "185.3.201.3",
+ "185.3.201.4",
+ "185.3.201.5",
+ "185.3.201.6",
+ "185.3.201.7",
+ "185.3.201.8",
+ "185.3.201.9",
+ "185.3.201.10",
+ "185.3.201.11",
+ "185.3.201.12",
+ "185.3.201.13",
+ "185.3.201.14",
+ "185.3.201.15",
+ "185.3.201.16",
+ "185.3.201.17",
+ "185.3.201.18",
+ "185.3.201.19",
+ "185.3.201.20",
+ "185.3.201.21",
+ "185.3.201.22",
+ "185.3.201.23",
+ "185.3.201.24",
+ "185.3.201.25",
+ "185.3.201.26",
+ "185.3.201.27",
+ "185.3.201.28",
+ "185.3.201.29",
+ "185.3.201.31",
+ "185.3.201.32",
+ "185.3.201.33",
+ "185.3.201.35",
+ "185.3.201.36",
+ "185.3.201.38",
+ "185.3.201.40",
+ "185.3.201.41",
+ "185.3.201.42",
+ "185.3.201.43",
+ "185.3.201.44",
+ "185.3.201.45",
+ "185.3.201.46",
+ "185.3.201.47",
+ "185.3.201.48",
+ "185.3.201.49",
+ "185.3.201.51",
+ "185.3.201.52",
+ "185.3.201.53",
+ "185.3.201.55",
+ "185.3.201.56",
+ "185.3.201.57",
+ "185.3.201.58",
+ "185.3.201.59",
+ "185.3.201.60",
+ "185.3.201.61",
+ "185.3.201.62",
+ "185.3.201.63",
+ "185.3.201.64",
+ "185.3.201.65",
+ "185.3.201.66",
+ "185.3.201.67",
+ "185.3.201.68",
+ "185.3.201.69",
+ "185.3.201.70",
+ "185.3.201.71",
+ "185.3.201.72",
+ "185.3.201.73",
+ "185.3.201.74",
+ "185.3.201.75",
+ "185.3.201.76",
+ "185.3.201.77",
+ "185.3.201.78",
+ "185.3.201.79",
+ "185.3.201.80",
+ "185.3.201.81",
+ "185.3.201.82",
+ "185.3.201.83",
+ "185.3.201.84",
+ "185.3.201.85",
+ "185.3.201.86",
+ "185.3.201.87",
+ "185.3.201.88",
+ "185.3.201.89",
+ "185.3.201.90",
+ "185.3.201.91",
+ "185.3.201.92",
+ "185.3.201.93",
+ "185.3.201.94",
+ "185.3.201.95",
+ "185.3.201.96",
+ "185.3.201.97",
+ "185.3.201.98",
+ "185.3.201.99",
+ "185.3.201.100",
+ "185.3.201.101",
+ "185.3.201.102",
+ "185.3.201.103",
+ "185.3.201.104",
+ "185.3.201.105",
+ "185.3.201.106",
+ "185.3.201.107",
+ "185.3.201.109",
+ "185.3.201.112",
+ "185.3.201.114",
+ "185.3.201.115",
+ "185.3.201.116",
+ "185.3.201.117",
+ "185.3.201.118",
+ "185.3.201.120",
+ "185.3.201.121",
+ "185.3.201.122",
+ "185.3.201.123",
+ "185.3.201.124",
+ "185.3.201.125",
+ "185.3.201.126",
+ "185.3.201.127",
+ "185.3.201.129",
+ "185.3.201.130",
+ "185.3.201.131",
+ "185.3.201.132",
+ "185.3.201.133",
+ "185.3.201.134",
+ "185.3.201.135",
+ "185.3.202.0",
+ "185.3.202.1",
+ "185.3.202.2",
+ "185.3.202.8",
+ "185.3.202.10",
+ "185.3.202.11",
+ "185.3.202.12",
+ "185.3.202.13",
+ "185.3.202.15",
+ "185.3.202.16",
+ "185.3.202.17",
+ "185.3.202.18",
+ "185.3.202.19",
+ "185.3.202.20",
+ "185.3.202.21",
+ "185.3.202.22",
+ "185.3.202.23",
+ "185.3.202.24",
+ "185.3.202.27",
+ "185.3.202.28",
+ "185.3.202.29",
+ "185.3.202.30",
+ "185.3.202.31",
+ "185.3.202.32",
+ "185.3.202.33",
+ "185.3.202.34",
+ "185.3.202.35",
+ "185.3.202.37",
+ "185.3.202.38",
+ "185.3.202.39",
+ "185.3.202.40",
+ "185.3.202.41",
+ "185.3.202.43",
+ "185.3.202.44",
+ "185.3.202.45",
+ "185.3.202.47",
+ "185.3.202.48",
+ "185.3.202.49",
+ "185.3.202.50",
+ "185.3.202.51",
+ "185.3.202.52",
+ "185.3.202.53",
+ "185.3.202.54",
+ "185.3.202.55",
+ "185.3.202.56",
+ "185.3.202.58",
+ "185.3.202.60",
+ "185.3.202.61",
+ "185.3.202.62",
+ "185.3.202.64",
+ "185.3.202.65",
+ "185.3.202.66",
+ "185.3.202.67",
+ "185.3.202.68",
+ "185.3.202.69",
+ "185.3.202.70",
+ "185.3.202.71",
+ "185.3.202.73",
+ "185.3.202.75",
+ "185.3.202.76",
+ "185.3.202.77",
+ "185.3.202.78",
+ "185.3.202.79",
+ "185.3.202.81",
+ "185.3.202.82",
+ "185.3.202.83",
+ "185.3.202.84",
+ "185.3.202.85",
+ "185.3.202.86",
+ "185.3.202.88",
+ "185.3.202.89",
+ "185.3.202.90",
+ "185.3.202.91",
+ "185.3.202.92",
+ "185.3.202.93",
+ "185.3.202.94",
+ "185.3.202.95",
+ "185.3.202.97",
+ "185.3.202.98",
+ "185.3.202.101",
+ "185.3.202.102",
+ "185.3.202.103",
+ "185.3.202.104",
+ "185.3.202.105",
+ "185.3.202.106",
+ "185.3.202.107",
+ "185.3.202.109",
+ "185.3.202.110",
+ "185.3.202.111",
+ "185.3.202.112",
+ "185.3.202.113",
+ "185.3.202.114",
+ "185.3.202.117",
+ "185.3.202.118",
+ "185.3.202.119",
+ "185.3.202.120",
+ "185.3.202.121",
+ "185.3.202.122",
+ "185.3.202.123",
+ "185.3.202.124",
+ "185.3.202.126",
+ "185.3.202.127",
+ "185.3.202.128",
+ "185.3.202.130",
+ "185.3.202.131",
+ "185.3.202.132",
+ "185.3.202.133",
+ "185.3.202.134",
+ "185.3.202.135",
+ "185.3.202.136",
+ "185.3.202.137",
+ "185.3.202.138",
+ "185.3.202.139",
+ "185.3.202.140",
+ "185.3.202.141",
+ "185.3.202.142",
+ "185.3.202.145",
+ "185.3.202.146",
+ "185.3.202.147",
+ "185.3.202.149",
+ "185.3.202.150",
+ "185.3.202.151",
+ "185.3.202.152",
+ "185.3.202.153",
+ "185.3.202.155",
+ "185.3.202.156",
+ "185.3.202.157",
+ "185.3.202.161",
+ "185.3.202.163",
+ "185.3.202.164",
+ "185.3.202.165",
+ "185.3.202.166",
+ "185.3.202.167",
+ "185.3.202.168",
+ "185.3.202.169",
+ "185.3.202.170",
+ "185.3.202.171",
+ "185.3.202.173",
+ "185.3.202.175",
+ "185.3.202.176",
+ "185.3.202.177",
+ "185.3.202.178",
+ "185.3.202.179",
+ "185.3.202.181",
+ "185.3.202.182",
+ "185.3.202.183",
+ "185.3.202.185",
+ "185.3.202.186",
+ "185.3.202.189",
+ "185.3.202.190",
+ "185.3.202.191",
+ "185.3.202.192",
+ "185.3.202.194",
+ "185.3.202.195",
+ "185.3.202.196",
+ "185.3.202.197",
+ "185.3.202.198",
+ "185.3.202.199",
+ "185.3.202.200",
+ "185.3.202.201",
+ "185.3.202.202",
+ "185.3.202.203",
+ "185.3.202.204",
+ "185.3.202.205",
+ "185.3.202.206",
+ "185.3.202.207",
+ "185.3.202.208",
+ "185.3.202.209",
+ "185.3.202.210",
+ "185.3.202.211",
+ "185.3.202.212",
+ "185.3.202.213",
+ "185.3.202.214",
+ "185.3.202.215",
+ "185.3.202.217",
+ "185.3.202.218",
+ "185.3.202.219",
+ "185.3.202.220",
+ "185.3.202.222",
+ "185.3.202.224",
+ "185.3.202.225",
+ "185.3.202.226",
+ "185.3.202.227",
+ "185.3.202.228",
+ "185.3.202.229",
+ "185.3.202.230",
+ "185.3.202.231",
+ "185.3.202.232",
+ "185.3.202.233",
+ "185.3.202.234",
+ "185.3.202.235",
+ "185.3.202.236",
+ "185.3.202.237",
+ "185.3.202.238",
+ "185.3.202.239",
+ "185.3.202.240",
+ "185.3.202.241",
+ "185.3.202.242",
+ "185.3.202.243",
+ "185.3.202.244",
+ "185.3.202.245",
+ "185.3.202.246",
+ "185.3.202.247",
+ "185.3.202.248",
+ "185.3.202.249",
+ "185.3.202.250",
+ "185.3.202.252",
+ "185.3.202.253",
+ "185.3.202.254",
+ "185.3.203.8",
+ "185.3.203.9",
+ "185.3.203.11",
+ "185.3.203.13",
+ "185.3.203.15",
+ "185.3.203.36",
+ "185.3.203.37",
+ "185.3.203.38",
+ "185.3.203.39",
+ "185.3.203.40",
+ "185.3.203.41",
+ "185.3.203.42",
+ "185.3.203.43",
+ "185.3.203.44",
+ "185.3.203.45",
+ "185.3.203.46",
+ "185.3.203.48",
+ "185.3.203.50",
+ "185.3.203.51",
+ "185.3.203.52",
+ "185.3.203.53",
+ "185.3.203.54",
+ "185.3.203.57",
+ "185.3.203.60",
+ "185.3.203.61",
+ "185.3.203.62",
+ "185.3.203.64",
+ "185.3.203.65",
+ "185.3.203.66",
+ "185.3.203.67",
+ "185.3.203.69",
+ "185.3.203.70",
+ "185.3.203.71",
+ "185.3.203.72",
+ "185.3.203.73",
+ "185.3.203.74",
+ "185.3.203.75",
+ "185.3.203.76",
+ "185.3.203.78",
+ "185.3.203.79",
+ "185.3.203.80",
+ "185.3.203.81",
+ "185.3.203.82",
+ "185.3.203.83",
+ "185.3.203.86",
+ "185.3.203.87",
+ "185.3.203.88",
+ "185.3.203.89",
+ "185.3.203.90",
+ "185.3.203.94",
+ "185.3.203.95",
+ "185.3.203.96",
+ "185.3.203.97",
+ "185.3.203.98",
+ "185.3.203.99",
+ "185.3.203.101",
+ "185.3.203.103",
+ "185.3.203.104",
+ "185.3.203.105",
+ "185.3.203.106",
+ "185.3.203.107",
+ "185.3.203.108",
+ "185.3.203.109",
+ "185.3.203.110",
+ "185.3.203.111",
+ "185.3.203.113",
+ "185.3.203.114",
+ "185.3.203.115",
+ "185.3.203.116",
+ "185.3.203.119",
+ "185.3.203.120",
+ "185.3.203.121",
+ "185.3.203.122",
+ "185.3.203.123",
+ "185.3.203.124",
+ "185.3.203.125",
+ "185.3.203.127",
+ "185.14.80.238",
+ "185.18.213.184",
+ "185.20.163.2",
+ "185.21.68.25",
+ "185.22.31.186",
+ "185.42.225.202",
+ "185.42.225.203",
+ "185.42.226.217",
+ "185.44.113.194",
+ "185.46.108.90",
+ "185.46.108.100",
+ "185.46.110.117",
+ "185.46.218.30",
+ "185.46.218.233",
+ "185.49.96.145",
+ "185.49.97.109",
+ "185.49.97.238",
+ "185.53.141.35",
+ "185.53.143.185",
+ "185.56.92.177",
+ "185.56.93.73",
+ "185.56.93.121",
+ "185.66.226.12",
+ "185.66.228.17",
+ "185.71.195.160",
+ "185.72.27.113",
+ "185.72.27.114",
+ "185.72.27.182",
+ "185.72.80.60",
+ "185.72.81.119",
+ "185.83.88.119",
+ "185.83.88.208",
+ "185.83.182.89",
+ "185.83.196.247",
+ "185.86.183.33",
+ "185.86.183.217",
+ "185.92.41.251",
+ "185.100.45.101",
+ "185.100.47.205",
+ "185.103.87.182",
+ "185.103.129.198",
+ "185.103.131.129",
+ "185.106.137.91",
+ "185.106.138.219",
+ "185.106.146.146",
+ "185.109.60.222",
+ "185.109.63.58",
+ "185.109.63.59",
+ "185.109.63.60",
+ "185.109.63.61",
+ "185.109.63.146",
+ "185.109.80.243",
+ "185.109.251.165",
+ "185.110.219.78",
+ "185.110.219.88",
+ "185.110.253.9",
+ "185.111.81.2",
+ "185.112.36.123",
+ "185.112.36.172",
+ "185.112.36.255",
+ "185.112.37.174",
+ "185.112.38.213",
+ "185.112.39.14",
+ "185.112.39.30",
+ "185.112.39.181",
+ "185.115.150.52",
+ "185.115.169.71",
+ "185.115.169.95",
+ "185.115.169.101",
+ "185.115.169.104",
+ "185.115.169.193",
+ "185.115.169.220",
+ "185.117.139.165",
+ "185.117.139.168",
+ "185.117.139.169",
+ "185.117.139.173",
+ "185.119.164.1",
+ "185.120.219.38",
+ "185.120.230.33",
+ "185.120.237.47",
+ "185.120.238.5",
+ "185.121.129.166",
+ "185.126.2.134",
+ "185.126.4.33",
+ "185.126.6.3",
+ "185.126.10.9",
+ "185.126.10.33",
+ "185.126.11.241",
+ "185.128.138.138",
+ "185.129.199.5",
+ "185.129.199.129",
+ "185.129.199.201",
+ "185.129.216.1",
+ "185.129.216.115",
+ "185.129.216.151",
+ "185.129.217.142",
+ "185.131.30.5",
+ "185.131.30.145",
+ "185.131.30.163",
+ "185.131.30.246",
+ "185.131.103.238",
+ "185.132.80.141",
+ "185.132.80.188",
+ "185.134.99.46",
+ "185.136.174.247",
+ "185.136.192.65",
+ "185.136.194.35",
+ "185.136.194.37",
+ "185.136.194.40",
+ "185.136.194.41",
+ "185.136.194.234",
+ "185.137.25.75",
+ "185.137.25.208",
+ "185.137.108.87",
+ "185.141.36.130",
+ "185.141.39.45",
+ "185.142.95.10",
+ "185.145.184.159",
+ "185.147.40.12",
+ "185.147.41.75",
+ "185.147.41.88",
+ "185.147.161.27",
+ "185.147.161.30",
+ "185.155.10.129",
+ "185.155.10.178",
+ "185.155.10.202",
+ "185.155.11.23",
+ "185.155.14.246",
+ "185.155.15.164",
+ "185.161.39.174",
+ "185.161.112.1",
+ "185.161.112.5",
+ "185.161.112.8",
+ "185.161.112.38",
+ "185.161.112.41",
+ "185.161.114.190",
+ "185.162.42.113",
+ "185.164.73.155",
+ "185.169.20.113",
+ "185.170.239.185",
+ "185.172.2.162",
+ "185.172.68.18",
+ "185.172.68.66",
+ "185.172.68.98",
+ "185.172.68.100",
+ "185.172.68.101",
+ "185.172.68.103",
+ "185.172.68.246",
+ "185.172.71.115",
+ "185.172.213.123",
+ "185.174.132.180",
+ "185.174.132.243",
+ "185.176.59.227",
+ "185.177.158.84",
+ "185.177.159.231",
+ "185.179.168.242",
+ "185.179.171.216",
+ "185.180.130.229",
+ "185.180.131.223",
+ "185.191.76.116",
+ "185.191.76.119",
+ "185.191.78.184",
+ "185.193.209.34",
+ "185.193.209.35",
+ "185.193.209.36",
+ "185.193.209.39",
+ "185.193.209.40",
+ "185.193.209.41",
+ "185.193.209.42",
+ "185.193.209.43",
+ "185.193.209.46",
+ "185.208.148.19",
+ "185.213.165.116",
+ "185.221.194.141",
+ "185.221.194.214",
+ "185.224.177.117",
+ "185.224.179.59",
+ "185.225.80.200",
+ "185.225.83.200",
+ "185.225.243.82",
+ "185.225.243.85",
+ "185.225.243.92",
+ "185.225.243.93",
+ "185.229.31.60",
+ "185.235.197.122",
+ "185.235.197.210",
+ "185.235.197.218",
+ "185.237.84.18",
+ "185.237.87.97",
+ "185.237.87.228",
+ "185.255.208.31",
+ "185.255.210.156",
+ "185.255.210.160",
+ "185.255.210.168",
+ "185.255.210.194",
+ "188.0.252.93",
+ "188.75.64.118",
+ "188.75.65.218",
+ "188.75.65.219",
+ "188.75.65.220",
+ "188.75.65.221",
+ "188.121.128.138",
+ "188.121.129.219",
+ "188.121.144.154",
+ "188.121.145.94",
+ "188.121.147.246",
+ "188.121.150.39",
+ "188.121.157.50",
+ "188.121.159.178",
+ "188.136.133.81",
+ "188.136.133.82",
+ "188.136.133.83",
+ "188.136.142.185",
+ "188.136.143.166",
+ "188.136.144.98",
+ "188.136.144.109",
+ "188.136.152.9",
+ "188.136.152.15",
+ "188.136.152.100",
+ "188.136.156.1",
+ "188.136.156.2",
+ "188.136.156.3",
+ "188.136.156.4",
+ "188.136.156.6",
+ "188.136.156.9",
+ "188.136.156.15",
+ "188.136.156.18",
+ "188.136.156.20",
+ "188.136.156.21",
+ "188.136.156.22",
+ "188.136.156.23",
+ "188.136.156.24",
+ "188.136.156.26",
+ "188.136.156.27",
+ "188.136.156.28",
+ "188.136.156.29",
+ "188.136.162.118",
+ "188.136.172.48",
+ "188.136.174.223",
+ "188.136.194.198",
+ "188.136.208.249",
+ "188.208.57.96",
+ "188.208.57.189",
+ "188.208.62.218",
+ "188.209.9.21",
+ "188.209.9.46",
+ "188.209.14.56",
+ "188.209.14.143",
+ "188.209.14.176",
+ "188.209.24.18",
+ "188.209.24.179",
+ "188.209.36.183",
+ "188.209.39.46",
+ "188.209.41.118",
+ "188.209.43.141",
+ "188.209.44.22",
+ "188.209.44.25",
+ "188.209.64.53",
+ "188.209.64.97",
+ "188.209.65.5",
+ "188.209.65.16",
+ "188.209.66.78",
+ "188.209.70.28",
+ "188.209.71.132",
+ "188.209.75.85",
+ "188.209.77.106",
+ "188.209.79.35",
+ "188.209.79.214",
+ "188.210.80.12",
+ "188.210.80.133",
+ "188.210.82.71",
+ "188.210.83.33",
+ "188.210.85.91",
+ "188.210.85.158",
+ "188.210.85.198",
+ "188.210.85.235",
+ "188.210.86.7",
+ "188.210.86.167",
+ "188.210.87.171",
+ "188.210.87.228",
+ "188.210.97.73",
+ "188.210.102.225",
+ "188.210.103.74",
+ "188.210.104.175",
+ "188.210.110.19",
+ "188.210.112.48",
+ "188.210.112.62",
+ "188.210.112.148",
+ "188.210.113.85",
+ "188.210.118.27",
+ "188.210.120.214",
+ "188.210.121.198",
+ "188.210.123.34",
+ "188.210.153.243",
+ "188.210.160.92",
+ "188.210.173.224",
+ "188.211.32.154",
+ "188.211.36.157",
+ "188.211.48.173",
+ "188.211.53.136",
+ "188.211.53.150",
+ "188.211.57.184",
+ "188.211.59.63",
+ "188.211.61.93",
+ "188.211.61.110",
+ "188.211.61.148",
+ "188.211.62.19",
+ "188.211.63.80",
+ "188.211.66.239",
+ "188.211.69.229",
+ "188.211.74.122",
+ "188.211.74.173",
+ "188.211.74.230",
+ "188.211.77.214",
+ "188.211.78.196",
+ "188.211.80.11",
+ "188.211.81.41",
+ "188.211.81.72",
+ "188.211.82.229",
+ "188.211.84.82",
+ "188.211.84.110",
+ "188.211.86.57",
+ "188.211.86.140",
+ "188.211.86.142",
+ "188.211.87.47",
+ "188.211.92.127",
+ "188.211.95.111",
+ "188.211.100.21",
+ "188.211.100.255",
+ "188.211.104.251",
+ "188.211.106.164",
+ "188.211.108.44",
+ "188.211.109.83",
+ "188.211.111.253",
+ "188.211.114.45",
+ "188.211.118.152",
+ "188.211.119.147",
+ "188.211.121.217",
+ "188.211.123.8",
+ "188.211.123.252",
+ "188.211.124.104",
+ "188.211.124.169",
+ "188.211.124.189",
+ "188.211.125.201",
+ "188.211.127.59",
+ "188.212.73.15",
+ "188.212.81.13",
+ "188.212.82.127",
+ "188.212.85.27",
+ "188.212.90.17",
+ "188.212.144.128",
+ "188.212.144.224",
+ "188.212.145.97",
+ "188.212.145.143",
+ "188.212.148.5",
+ "188.212.149.44",
+ "188.212.245.103",
+ "188.213.147.209",
+ "188.213.148.89",
+ "188.213.150.39",
+ "188.213.155.38",
+ "188.213.157.159",
+ "188.213.158.155",
+ "188.213.159.229",
+ "188.213.177.216",
+ "188.213.181.60",
+ "188.213.183.209",
+ "188.213.185.56",
+ "188.213.188.237",
+ "188.213.209.185",
+ "188.214.187.38",
+ "188.240.212.0",
+ "188.240.212.1",
+ "188.240.212.2",
+ "188.240.212.3",
+ "188.240.212.48",
+ "188.240.212.49",
+ "188.240.212.50",
+ "188.240.212.51",
+ "188.240.212.52",
+ "188.240.212.53",
+ "188.240.212.54",
+ "188.240.212.55",
+ "188.240.254.107",
+ "193.24.120.212",
+ "193.56.61.180",
+ "193.134.100.5",
+ "193.134.100.6",
+ "193.134.100.7",
+ "193.134.100.8",
+ "193.134.100.9",
+ "193.134.100.10",
+ "193.134.100.11",
+ "193.134.100.26",
+ "193.134.100.27",
+ "193.134.100.116",
+ "193.134.100.117",
+ "193.134.100.118",
+ "193.151.157.201",
+ "193.200.148.28",
+ "193.200.148.79",
+ "193.228.91.116",
+ "193.228.168.209",
+ "193.228.169.115",
+ "193.228.169.116",
+ "193.228.169.165",
+ "194.9.56.64",
+ "194.9.57.12",
+ "194.9.57.139",
+ "194.33.105.89",
+ "194.36.174.129",
+ "194.60.231.237",
+ "194.147.164.139",
+ "194.147.165.188",
+ "194.150.68.122",
+ "194.150.70.218",
+ "194.150.70.219",
+ "194.150.70.221",
+ "194.150.71.157",
+ "194.225.101.4",
+ "194.225.101.8",
+ "194.225.101.10",
+ "194.225.101.23",
+ "194.225.101.25",
+ "194.225.101.28",
+ "194.225.101.29",
+ "194.225.101.33",
+ "194.225.136.233",
+ "194.225.149.241",
+ "195.8.114.144",
+ "195.88.189.60",
+ "195.146.59.174",
+ "195.146.59.175",
+ "195.181.1.32",
+ "195.181.3.10",
+ "195.181.11.166",
+ "195.181.11.227",
+ "195.181.13.168",
+ "195.181.26.210",
+ "195.181.27.26",
+ "195.181.27.67",
+ "195.181.30.106",
+ "195.181.30.206",
+ "195.181.37.54",
+ "195.181.39.210",
+ "195.181.40.4",
+ "195.181.40.5",
+ "195.181.58.162",
+ "195.181.86.242",
+ "195.181.114.229",
+ "212.16.64.129",
+ "212.16.86.176",
+ "212.33.210.119",
+ "212.33.218.42",
+ "212.80.19.122",
+ "212.80.19.137",
+ "212.86.73.128",
+ "212.86.75.15",
+ "212.86.94.173",
+ "212.120.194.186",
+ "212.120.196.162",
+ "212.120.198.180",
+ "212.120.199.78",
+ "212.120.200.252",
+ "212.120.215.52",
+ "212.120.216.120",
+ "212.120.220.62",
+ "212.120.222.90",
+ "212.120.223.134",
+ "213.109.199.99",
+ "213.109.248.89",
+ "213.109.248.198",
+ "213.109.250.70",
+ "213.109.251.121",
+ "213.109.251.128",
+ "213.176.122.52",
+ "213.176.122.93",
+ "213.195.56.65",
+ "213.207.204.105",
+ "213.207.204.106",
+ "217.11.27.141",
+ "217.11.27.142",
+ "217.11.29.254",
+ "217.24.144.199",
+ "217.24.148.89",
+ "217.24.152.78",
+ "217.24.155.243",
+ "217.24.157.45",
+ "217.60.241.77",
+ "217.66.213.130",
+ "217.146.222.230",
+ "217.170.246.241",
+ "217.170.251.124",
+ "217.170.254.224",
+ "217.170.254.225",
+ "217.170.254.239",
+ "217.170.255.2",
+ "217.172.104.107",
+ "217.172.104.155",
+ "217.172.105.44",
+ "217.172.105.112",
+ "217.172.107.99",
+ "217.172.110.58",
+ "217.172.124.7",
+ "217.218.33.138",
+ "217.218.33.139",
+ "217.218.44.62",
+ "217.218.56.114",
+ "217.218.60.89",
+ "217.218.60.95",
+ "217.218.65.22",
+ "217.218.68.93",
+ "217.218.72.159",
+ "217.218.77.64",
+ "217.218.87.32",
+ "217.218.88.43",
+ "217.218.118.210",
+ "217.218.121.141",
+ "217.218.121.183",
+ "217.218.125.178",
+ "217.218.126.239",
+ "217.218.129.118",
+ "217.218.137.200",
+ "217.218.138.96",
+ "217.218.164.81",
+ "217.218.194.163",
+ "217.218.195.27",
+ "217.218.219.157",
+ "217.218.223.149",
+ "217.218.224.38",
+ "217.218.224.212",
+ "217.218.229.234",
+ "217.218.229.236",
+ "217.218.231.95",
+ "217.218.235.107",
+ "217.218.242.10",
+ "217.218.248.213",
+ "217.218.253.81",
+ "217.219.27.59",
+ "217.219.31.73",
+ "217.219.34.42",
+ "217.219.34.49",
+ "217.219.35.99",
+ "217.219.39.119",
+ "217.219.45.4",
+ "217.219.45.18",
+ "217.219.45.19",
+ "217.219.66.192",
+ "217.219.66.194",
+ "217.219.66.195",
+ "217.219.66.196",
+ "217.219.66.231",
+ "217.219.66.233",
+ "217.219.66.234",
+ "217.219.66.235",
+ "217.219.66.236",
+ "217.219.66.237",
+ "217.219.66.238",
+ "217.219.66.239",
+ "217.219.71.186",
+ "217.219.71.190",
+ "217.219.72.11",
+ "217.219.75.225",
+ "217.219.81.66",
+ "217.219.82.195",
+ "217.219.113.141",
+ "217.219.131.139",
+ "217.219.146.65",
+ "217.219.146.71",
+ "217.219.146.72",
+ "217.219.146.74",
+ "217.219.146.117",
+ "217.219.156.146",
+ "217.219.163.2",
+ "217.219.163.12",
+ "217.219.163.20",
+ "217.219.163.22",
+ "217.219.163.29",
+ "217.219.163.58",
+ "217.219.163.151",
+ "217.219.163.162",
+ "217.219.163.173",
+ "217.219.173.237",
+ "217.219.199.51",
+ "217.219.213.28",
+ "217.219.213.125",
+ "217.219.221.147",
+ "217.219.222.194",
+ "217.219.224.130",
+ "217.219.236.215",
+ "217.219.237.17",
+ "217.219.238.116",
+ "217.219.239.69",
+ "217.219.242.142",
+ "217.219.242.195",
+ "217.219.245.124",
+ "217.219.245.171"
+ ],
+ "IT": [
+ "95.141.39.218"
+ ],
+ "KE": [
+ "102.22.108.2",
+ "102.22.108.13",
+ "102.22.108.14",
+ "102.22.108.20",
+ "102.22.108.21",
+ "102.22.108.22",
+ "102.22.108.23",
+ "102.22.108.25",
+ "102.22.109.1",
+ "102.22.109.225",
+ "102.23.136.215"
+ ],
+ "NL": [
+ "80.80.80.80",
+ "80.80.81.81",
+ "146.70.86.142"
+ ],
+ "RU": [
+ "77.88.8.8",
+ "77.88.8.1",
+ "185.234.14.114",
+ "185.234.14.34",
+ "185.234.14.43",
+ "185.234.14.65",
+ "185.234.14.94",
+ "185.234.14.101",
+ "185.234.14.102",
+ "185.234.14.111",
+ "185.234.14.129",
+ "185.234.14.137",
+ "194.50.169.217"
+ ],
+ "SE": [
+ "192.36.148.17"
+ ],
+ "SL": [
+ "102.23.140.2",
+ "102.23.140.42"
+ ],
+ "SZ": [
+ "102.23.132.42",
+ "102.23.133.10",
+ "102.23.133.12"
+ ],
+ "TR": [
+ "103.130.146.35",
+ "103.130.146.36",
+ "103.130.146.37",
+ "103.130.146.43",
+ "103.130.146.195",
+ "103.130.146.198",
+ "103.130.146.206",
+ "103.130.146.235",
+ "103.130.146.238",
+ "185.220.226.0",
+ "185.220.226.1",
+ "185.220.226.2",
+ "185.220.226.3",
+ "185.220.226.4",
+ "185.220.226.5",
+ "185.220.226.6",
+ "185.220.226.7",
+ "185.220.226.8",
+ "185.220.226.10",
+ "185.220.226.11",
+ "185.220.226.12",
+ "185.220.226.13",
+ "185.220.226.15",
+ "185.220.226.17",
+ "185.220.226.18",
+ "185.220.226.19",
+ "185.220.226.21",
+ "185.220.226.24",
+ "185.220.226.25",
+ "185.220.226.26",
+ "185.220.226.27",
+ "185.220.226.29",
+ "185.220.226.30",
+ "185.220.226.31",
+ "185.220.226.33",
+ "185.220.226.34",
+ "185.220.226.35",
+ "185.220.226.36",
+ "185.220.226.37",
+ "185.220.226.38",
+ "185.220.226.39",
+ "185.220.226.40",
+ "185.220.226.42",
+ "185.220.226.43",
+ "185.220.226.44",
+ "185.220.226.45",
+ "185.220.226.46",
+ "185.220.226.47",
+ "185.220.226.48",
+ "185.220.226.49",
+ "185.220.226.50",
+ "185.220.226.51",
+ "185.220.226.52",
+ "185.220.226.53",
+ "185.220.226.54",
+ "185.220.226.55",
+ "185.220.226.56",
+ "185.220.226.57",
+ "185.220.226.58",
+ "185.220.226.59",
+ "185.220.226.60",
+ "185.220.226.61",
+ "185.220.226.62",
+ "185.220.226.63",
+ "185.220.226.64",
+ "185.220.226.65",
+ "185.220.226.66",
+ "185.220.226.68",
+ "185.220.226.69",
+ "185.220.226.70",
+ "185.220.226.71",
+ "185.220.226.72",
+ "185.220.226.73",
+ "185.220.226.75",
+ "185.220.226.76",
+ "185.220.226.77",
+ "185.220.226.78",
+ "185.220.226.79",
+ "185.220.226.80",
+ "185.220.226.81",
+ "185.220.226.83",
+ "185.220.226.84",
+ "185.220.226.85",
+ "185.220.226.86",
+ "185.220.226.87",
+ "185.220.226.88",
+ "185.220.226.89",
+ "185.220.226.90",
+ "185.220.226.92",
+ "185.220.226.93",
+ "185.220.226.94",
+ "185.220.226.95",
+ "185.220.226.96",
+ "185.220.226.97",
+ "185.220.226.98",
+ "185.220.226.99",
+ "185.220.226.100",
+ "185.220.226.101",
+ "185.220.226.103",
+ "185.220.226.104",
+ "185.220.226.105",
+ "185.220.226.106",
+ "185.220.226.108",
+ "185.220.226.110",
+ "185.220.226.111",
+ "185.220.226.112",
+ "185.220.226.114",
+ "185.220.226.115",
+ "185.220.226.116",
+ "185.220.226.117",
+ "185.220.226.118",
+ "185.220.226.121",
+ "185.220.226.122",
+ "185.220.226.123",
+ "185.220.226.124",
+ "185.220.226.125",
+ "185.220.226.126",
+ "185.220.226.127",
+ "185.220.226.128",
+ "185.220.226.130",
+ "185.220.226.131",
+ "185.220.226.132",
+ "185.220.226.133",
+ "185.220.226.134",
+ "185.220.226.135",
+ "185.220.226.136",
+ "185.220.226.137",
+ "185.220.226.138",
+ "185.220.226.139",
+ "185.220.226.140",
+ "185.220.226.141",
+ "185.220.226.142",
+ "185.220.226.143",
+ "185.220.226.144",
+ "185.220.226.145",
+ "185.220.226.146",
+ "185.220.226.147",
+ "185.220.226.148",
+ "185.220.226.150",
+ "185.220.226.151",
+ "185.220.226.152",
+ "185.220.226.153",
+ "185.220.226.154",
+ "185.220.226.155",
+ "185.220.226.156",
+ "185.220.226.157",
+ "185.220.226.158",
+ "185.220.226.159",
+ "185.220.226.160",
+ "185.220.226.161",
+ "185.220.226.162",
+ "185.220.226.163",
+ "185.220.226.164",
+ "185.220.226.165",
+ "185.220.226.166",
+ "185.220.226.167",
+ "185.220.226.168",
+ "185.220.226.169",
+ "185.220.226.170",
+ "185.220.226.171",
+ "185.220.226.172",
+ "185.220.226.173",
+ "185.220.226.174",
+ "185.220.226.175",
+ "185.220.226.176",
+ "185.220.226.177",
+ "185.220.226.178",
+ "185.220.226.179",
+ "185.220.226.181",
+ "185.220.226.182",
+ "185.220.226.183",
+ "185.220.226.184",
+ "185.220.226.185",
+ "185.220.226.186",
+ "185.220.226.187",
+ "185.220.226.188",
+ "185.220.226.189",
+ "185.220.226.190",
+ "185.220.226.191",
+ "185.220.226.192",
+ "185.220.226.193",
+ "185.220.226.195",
+ "185.220.226.198",
+ "185.220.226.199",
+ "185.220.226.200",
+ "185.220.226.201",
+ "185.220.226.202",
+ "185.220.226.203",
+ "185.220.226.204",
+ "185.220.226.205",
+ "185.220.226.206",
+ "185.220.226.207",
+ "185.220.226.208",
+ "185.220.226.209",
+ "185.220.226.211",
+ "185.220.226.212",
+ "185.220.226.213",
+ "185.220.226.214",
+ "185.220.226.215",
+ "185.220.226.216",
+ "185.220.226.217",
+ "185.220.226.218",
+ "185.220.226.219",
+ "185.220.226.220",
+ "185.220.226.221",
+ "185.220.226.222",
+ "185.220.226.223",
+ "185.220.226.224",
+ "185.220.226.225",
+ "185.220.226.226",
+ "185.220.226.227",
+ "185.220.226.228",
+ "185.220.226.230",
+ "185.220.226.231",
+ "185.220.226.232",
+ "185.220.226.233",
+ "185.220.226.234",
+ "185.220.226.236",
+ "185.220.226.237",
+ "185.220.226.239",
+ "185.220.226.240",
+ "185.220.226.241",
+ "185.220.226.242",
+ "185.220.226.244",
+ "185.220.226.247",
+ "185.220.226.248",
+ "185.220.226.249",
+ "185.220.226.250",
+ "185.220.226.251",
+ "185.220.226.252",
+ "185.220.226.253",
+ "185.220.226.255",
+ "212.18.108.187",
+ "212.18.108.235",
+ "193.111.76.3",
+ "193.111.76.10",
+ "212.18.108.115",
+ "212.18.108.131",
+ "212.18.108.132",
+ "212.18.108.173",
+ "212.18.108.174",
+ "212.18.108.188",
+ "212.18.108.189",
+ "212.18.108.190",
+ "212.18.108.203",
+ "212.18.108.205",
+ "212.18.108.211",
+ "212.18.108.212",
+ "212.18.108.214",
+ "212.18.108.228",
+ "212.18.108.237"
+ ],
+ "TW": [
+ "101.101.101.101",
+ "101.102.103.104"
+ ],
+ "US": [
+ "8.8.8.8",
+ "8.8.4.4",
+ "208.67.220.220",
+ "4.2.2.1",
+ "4.2.2.2",
+ "4.4.4.4",
+ "156.154.70.1",
+ "156.154.71.1",
+ "149.112.112.112",
+ "9.9.9.10",
+ "149.112.112.10",
+ "9.9.9.11",
+ "149.112.112.11",
+ "194.242.2.2",
+ "194.242.2.3",
+ "76.76.19.19",
+ "76.223.122.150",
+ "76.76.26.0",
+ "8.26.56.26",
+ "8.20.247.20",
+ "185.228.168.9",
+ "185.228.169.9",
+ "185.228.168.168",
+ "185.228.169.168",
+ "185.228.168.10",
+ "185.228.169.11",
+ "64.6.64.6",
+ "64.6.65.6",
+ "195.46.39.39",
+ "195.46.39.40",
+ "45.81.18.141",
+ "207.246.121.77",
+ "45.81.16.103",
+ "45.81.17.18",
+ "45.81.17.19",
+ "45.81.17.20",
+ "45.81.17.23",
+ "45.81.17.24",
+ "45.81.17.27",
+ "45.81.17.28",
+ "45.81.17.29",
+ "45.81.17.30",
+ "45.81.17.133",
+ "45.81.17.135",
+ "45.81.17.190",
+ "45.81.18.107",
+ "45.81.18.123",
+ "87.248.131.23",
+ "87.248.131.45",
+ "87.248.131.67",
+ "87.248.131.125",
+ "87.248.131.164",
+ "87.248.131.207",
+ "87.248.131.112",
+ "87.248.131.176",
+ "12.15.19.238",
+ "12.15.19.241",
+ "45.81.16.36",
+ "45.81.16.155",
+ "45.81.16.217",
+ "45.81.17.109",
+ "45.81.17.159",
+ "45.81.17.160",
+ "45.81.17.177",
+ "45.81.17.182",
+ "45.81.17.183",
+ "45.81.17.184",
+ "45.81.17.196",
+ "45.81.17.197",
+ "45.81.17.199",
+ "45.81.18.104",
+ "45.81.18.109",
+ "87.248.131.2",
+ "87.248.131.33",
+ "87.248.131.148",
+ "87.248.131.158",
+ "87.248.131.161",
+ "87.248.131.223",
+ "87.248.131.244"
+ ],
+ "ZA": [
+ "102.22.81.183",
+ "102.22.81.133",
+ "102.133.234.155",
+ "102.215.240.26",
+ "102.215.240.45",
+ "102.215.240.66",
+ "102.215.240.72",
+ "102.215.240.74",
+ "102.215.240.81",
+ "102.215.240.120",
+ "102.215.240.121",
+ "102.215.240.216",
+ "102.215.242.125",
+ "102.215.242.149",
+ "102.215.242.182",
+ "102.215.243.18",
+ "102.215.243.98",
+ "102.22.72.46",
+ "102.22.80.182",
+ "102.22.80.183",
+ "102.22.80.250",
+ "102.22.81.11",
+ "102.22.81.13",
+ "102.22.81.19",
+ "102.22.81.20",
+ "102.22.81.34",
+ "102.22.81.37",
+ "102.22.81.41",
+ "102.22.81.42",
+ "102.22.81.45",
+ "102.22.81.52",
+ "102.22.81.74",
+ "102.22.81.75",
+ "102.22.81.85",
+ "102.22.81.99",
+ "102.22.81.110",
+ "102.22.81.122",
+ "102.22.81.140",
+ "102.22.81.141",
+ "102.22.81.151",
+ "102.22.81.171",
+ "102.22.81.175",
+ "102.22.81.193",
+ "102.22.81.195",
+ "102.22.81.201",
+ "102.22.81.211",
+ "102.22.81.212",
+ "102.22.81.213",
+ "102.22.81.225",
+ "102.22.81.249",
+ "102.22.81.254",
+ "102.22.82.4",
+ "102.22.82.5",
+ "102.22.82.17",
+ "102.22.82.45",
+ "102.22.82.53",
+ "102.22.82.56",
+ "102.22.82.59",
+ "102.22.82.70",
+ "102.22.82.71",
+ "102.22.82.94",
+ "102.22.82.95",
+ "102.22.82.129",
+ "102.22.82.214",
+ "102.22.82.221",
+ "102.22.82.227",
+ "102.22.82.233",
+ "102.22.82.242",
+ "102.22.83.12",
+ "102.22.83.14",
+ "102.22.83.46",
+ "102.22.83.71",
+ "102.22.83.72",
+ "102.22.83.78",
+ "102.22.83.102",
+ "102.22.83.103",
+ "102.22.83.113",
+ "102.22.83.114",
+ "102.22.83.139",
+ "102.22.83.142",
+ "102.22.83.149",
+ "102.22.83.155",
+ "102.22.83.207",
+ "102.22.124.69",
+ "102.22.124.70",
+ "102.22.127.147",
+ "102.22.195.106",
+ "102.22.195.246",
+ "102.22.207.4",
+ "102.22.207.42",
+ "102.22.237.8",
+ "102.22.237.9",
+ "102.22.247.162",
+ "102.22.254.116",
+ "102.22.254.232",
+ "102.23.163.244",
+ "102.23.168.24",
+ "102.23.196.253",
+ "102.23.198.210",
+ "102.23.208.4",
+ "102.23.208.30",
+ "102.23.226.27",
+ "102.23.226.70",
+ "102.23.226.71",
+ "102.23.230.23",
+ "102.23.231.69",
+ "102.23.231.82",
+ "102.23.231.84",
+ "102.23.231.87",
+ "102.23.231.172",
+ "102.23.231.253",
+ "102.23.237.76",
+ "102.23.252.83",
+ "102.37.16.226",
+ "102.37.21.224",
+ "102.37.109.39",
+ "102.37.113.11",
+ "102.37.113.89",
+ "102.37.116.18",
+ "102.37.118.18",
+ "102.37.142.149",
+ "102.37.144.57",
+ "102.37.145.202",
+ "102.37.158.250",
+ "102.37.176.63",
+ "102.37.213.24",
+ "102.37.214.202",
+ "102.37.216.211",
+ "102.37.217.70",
+ "102.37.217.174",
+ "102.37.218.157",
+ "102.37.220.188",
+ "102.133.128.244",
+ "102.133.129.203",
+ "102.133.132.86",
+ "102.133.132.90",
+ "102.133.136.51",
+ "102.133.136.53",
+ "102.133.136.58",
+ "102.133.136.65",
+ "102.133.138.26",
+ "102.133.138.30",
+ "102.133.138.66",
+ "102.133.139.5",
+ "102.133.139.31",
+ "102.133.139.152",
+ "102.133.139.153",
+ "102.133.139.154",
+ "102.133.146.143",
+ "102.133.160.77",
+ "102.133.171.26",
+ "102.133.227.168",
+ "102.133.235.79",
+ "102.215.242.87"
+ ],
+ "ZM": [
+ "102.23.121.15",
+ "102.23.121.16",
+ "102.23.122.120",
+ "102.23.122.251",
+ "102.23.123.90",
+ "102.23.123.91"
+ ]
+}
\ No newline at end of file
diff --git a/protocol/hiddify/dnstt/tester.go b/protocol/hiddify/dnstt/tester.go
new file mode 100644
index 0000000000..2c399444ff
--- /dev/null
+++ b/protocol/hiddify/dnstt/tester.go
@@ -0,0 +1,375 @@
+package dnstt
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "math/rand/v2"
+ "net"
+ "net/http"
+ "sort"
+ "strconv"
+ "sync"
+ "time"
+
+ dnstt "github.com/net2share/vaydns/client"
+ "github.com/sagernet/sing-box/adapter"
+
+ "github.com/sagernet/sing-box/dns/transport"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/batch"
+
+ "github.com/miekg/dns"
+)
+
+type History struct {
+ ResolverRate map[string]int `json:"resolver_rate"`
+}
+
+func (h *Outbound) loadHistory() *History {
+ history := &History{ResolverRate: make(map[string]int)}
+
+ if h.cache == nil {
+ return history
+ }
+
+ savedBinary := h.cache.LoadBinary("dnstt_resolvers" + h.options.RecordType)
+ if savedBinary == nil {
+ return history
+ }
+ if err := json.Unmarshal(savedBinary.Content, history); err != nil {
+ return history
+ }
+
+ return history
+}
+
+func (h *Outbound) saveHistory(his *History) {
+ if h.cache == nil {
+ return
+ }
+
+ content, err := json.Marshal(his)
+ if err != nil {
+ h.logger.Error("failed to marshal outbound monitoring history: ", err)
+ return
+ }
+ h.cache.SaveBinary("dnstt_resolvers"+h.options.RecordType, &adapter.SavedBinary{
+ LastUpdated: time.Now(),
+ Content: content,
+ })
+}
+
+func (h *Outbound) startTestResolver() error {
+ history := h.loadHistory()
+ defer h.saveHistory(history)
+
+ b, _ := batch.New(h.ctx, batch.WithConcurrencyNum[any](100))
+
+ candidates := h.candidateResolvers
+ rand.Shuffle(len(candidates), func(i, j int) {
+ candidates[i], candidates[j] = candidates[j], candidates[i]
+ })
+
+ sort.Slice(candidates, func(i, j int) bool {
+ a := candidates[i]
+ b := candidates[j]
+
+ // Auto first
+ if a.Auto != b.Auto {
+ return a.Auto
+ }
+
+ // Then by rate descending
+ rateA := history.ResolverRate[a.Resolver.ResolverAddr]
+ rateB := history.ResolverRate[b.Resolver.ResolverAddr]
+
+ return rateA > rateB
+ })
+ historyMutex := sync.Mutex{}
+
+ for _, r := range candidates {
+ resolver := r.Resolver
+
+ select {
+ case <-h.ctx.Done():
+ return h.ctx.Err()
+ default:
+ }
+
+ b.Go(resolver.ResolverAddr, func() (any, error) {
+ h.mu.Lock()
+ resCount := len(h.resolvers)
+ h.mu.Unlock()
+ if resCount > 10 {
+ return nil, nil
+ }
+
+ // stop if context cancelled
+ select {
+ case <-h.ctx.Done():
+ return nil, h.ctx.Err()
+ default:
+ }
+
+ rate, err := h.testTunnelResolver(resolver)
+
+ // update history safely
+ historyMutex.Lock()
+ defer historyMutex.Unlock()
+
+ if err == nil {
+ h.logger.InfoContext(h.ctx, "resolver ", resolver.ResolverAddr, " is working and added to the pool")
+
+ if history.ResolverRate[resolver.ResolverAddr] < 0 {
+ history.ResolverRate[resolver.ResolverAddr] = 0
+ }
+ history.ResolverRate[resolver.ResolverAddr] += rate
+ if history.ResolverRate[resolver.ResolverAddr] > 10 {
+ history.ResolverRate[resolver.ResolverAddr] = 10
+ }
+
+ h.addResolver(resolver)
+ if h.IsReady() {
+ h.saveHistory(history)
+ }
+
+ } else {
+ h.logger.WarnContext(h.ctx, "resolver ", resolver.ResolverAddr, " failed: ", err)
+
+ history.ResolverRate[resolver.ResolverAddr] += rate
+ if history.ResolverRate[resolver.ResolverAddr] < -10 {
+ history.ResolverRate[resolver.ResolverAddr] = -10
+ }
+ }
+
+ return nil, nil
+ })
+ }
+
+ return b.Wait()
+}
+func getDnsRecordType(record string) uint16 {
+ switch record {
+ case "a":
+ return dns.TypeA
+ case "aaaa":
+ return dns.TypeAAAA
+ case "cname":
+ return dns.TypeCNAME
+ case "mx":
+ return dns.TypeMX
+ case "ns":
+ return dns.TypeNS
+ case "ptr":
+ return dns.TypePTR
+ case "soa":
+ return dns.TypeSOA
+ case "srv":
+ return dns.TypeSRV
+ case "txt":
+ return dns.TypeTXT
+ default:
+ return dns.TypeA
+ }
+}
+
+func (h *Outbound) testTunnelResolver(resolver dnstt.Resolver) (rate int, err error) {
+ domain := h.options.PreTestDomain
+ record := h.options.PreTestRecordType
+ h.logger.DebugContext(h.ctx, "testing resolver ", resolver.ResolverAddr, " with domain ", domain, " and record type ", record)
+ resp, err := h.Resolve(resolver, domain, getDnsRecordType(record))
+ h.logger.DebugContext(h.ctx, "resolver ", resolver.ResolverAddr, " response ", fmt.Sprint(resp), " error ", err)
+ if err != nil {
+ return -4, err
+ }
+ // ips := make([]string, 0)
+ if resp == nil || len(resp.Answer) == 0 {
+ return -3, fmt.Errorf("no record found in response from resolver %s", resolver.ResolverAddr)
+ }
+ // for _, ans := range resp.Answer {
+ // if a, ok := ans.(*dns.A); ok {
+ // if a.A.IsLoopback() || a.A.IsPrivate() {
+ // continue
+ // }
+ // ips = append(ips, a.A.String())
+ // }
+ // }
+ // }
+ // if len(ips) == 0 {
+ // return fmt.Errorf("no A record found in response from resolver %s", resolver.ResolverAddr)
+ // }
+
+ ctx, cancel := context.WithTimeout(h.ctx, 5*time.Second)
+ defer cancel()
+ tunnel, err := h.createDnsttTunnel(ctx, []dnstt.Resolver{resolver})
+ if err != nil {
+ h.logger.WarnContext(h.ctx, "failed to establish tunnel to resolver ", resolver.ResolverAddr, ": ", err)
+ return -2, err
+ }
+ defer tunnel.Close()
+ h.logger.InfoContext(h.ctx, "successfully established tunnel to resolver ", resolver.ResolverAddr)
+ conn, err := tunnel.OpenStream()
+ if err != nil {
+ h.logger.WarnContext(h.ctx, "failed to open stream to resolver ", resolver.ResolverAddr, ": ", err)
+ return -1, err
+
+ }
+ h.logger.InfoContext(h.ctx, "successfully opened stream to resolver ", resolver.ResolverAddr)
+ conn.Close()
+ return 1, nil
+
+}
+
+func buildDNSQuery(name string, qtype uint16) *dns.Msg {
+ m := new(dns.Msg)
+ m.SetQuestion(dns.Fqdn(name), qtype)
+ m.RecursionDesired = true
+
+ return m
+}
+
+func (h *Outbound) ResolveUDP(resolver dnstt.Resolver, name string, qtype uint16) (*dns.Msg, error) {
+ host, portStr, err := net.SplitHostPort(resolver.ResolverAddr)
+ if err != nil {
+ return nil, err
+ }
+
+ portInt, err := strconv.Atoi(portStr)
+ if err != nil {
+ return nil, err
+ }
+ trans, err := transport.NewUDP(
+ h.ctx,
+ h.logger,
+ "resolver"+resolver.ResolverAddr,
+ option.RemoteDNSServerOptions{
+ DNSServerAddressOptions: option.DNSServerAddressOptions{
+ Server: host,
+ ServerPort: uint16(portInt),
+ },
+ },
+ )
+ if err != nil {
+ return nil, err
+ }
+ // h.logger.InfoContext(h.ctx, "resolving name ", name, " of type ", qtype, " using resolver ", resolver.ResolverAddr)
+
+ msg := buildDNSQuery(name, qtype)
+ trans.Start(adapter.StartStateStart)
+ ctx, cancel := context.WithTimeout(h.ctx, 5*time.Second)
+ defer cancel()
+ resp, err := trans.Exchange(ctx, msg)
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+func (h *Outbound) Resolve(resolver dnstt.Resolver, name string, qtype uint16) (*dns.Msg, error) {
+ if resolver.ResolverType == dnstt.ResolverTypeUDP {
+ return h.ResolveUDP(resolver, name, qtype)
+ }
+ conn, r, err := h.getTCPBasedResolverConnection(resolver, 5*time.Second)
+ msg := buildDNSQuery(name, qtype)
+
+ data, err := msg.Pack()
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = conn.WriteTo(data, r)
+ if err != nil {
+ return nil, err
+ }
+ buf := make([]byte, 4096)
+
+ n, _, err := conn.ReadFrom(buf)
+ if err != nil {
+ return nil, err
+ }
+
+ resp := new(dns.Msg)
+ err = resp.Unpack(buf[:n])
+ if err != nil {
+ return nil, err
+ }
+ return resp, nil
+}
+
+func (h *Outbound) getTCPBasedResolverConnection(r dnstt.Resolver, timeout time.Duration) (net.PacketConn, *net.UDPAddr, error) {
+
+ h.logger.InfoContext(h.ctx, "getting resolver connection ", r.ResolverAddr)
+ switch r.ResolverType {
+ case dnstt.ResolverTypeUDP:
+ addr, err := net.ResolveUDPAddr("udp", r.ResolverAddr)
+ if err != nil {
+ return nil, nil, err
+ }
+ // t.remoteAddr = addr
+ if r.UDPSharedSocket {
+ lc := net.ListenConfig{Control: r.DialerControl}
+ conn, err := lc.ListenPacket(context.Background(), "udp", ":0")
+ if err != nil {
+ return nil, nil, err
+ }
+ h.logger.InfoContext(h.ctx, "resolver connection established ", r.ResolverAddr)
+ return conn, addr, nil
+ } else {
+ workers := r.UDPWorkers
+ if workers <= 0 {
+ workers = dnstt.DefaultUDPWorkers
+ }
+
+ if timeout <= 0 {
+ timeout = dnstt.DefaultUDPResponseTimeout
+ }
+ conn, _, err := dnstt.NewUDPPacketConn(addr, r.DialerControl, workers, timeout, !r.UDPAcceptErrors, 512, "block")
+ if err != nil {
+ return nil, nil, err
+ }
+ h.logger.InfoContext(h.ctx, "resolver connection established ", r.ResolverAddr)
+ // t.forgedStats = forgedStats
+ return conn, addr, nil
+ }
+
+ case dnstt.ResolverTypeDOH:
+ // t.remoteAddr = turbotunnel.DummyAddr{}
+ var rt http.RoundTripper
+ if r.RoundTripper != nil {
+ rt = r.RoundTripper
+ } else if r.UTLSClientHelloID != nil {
+ rt = dnstt.NewUTLSRoundTripper(nil, r.UTLSClientHelloID)
+ } else {
+ rt = http.DefaultTransport
+ }
+ conn, err := dnstt.NewHTTPPacketConn(rt, r.ResolverAddr, 8, 512, "block")
+ if err != nil {
+ return nil, nil, err
+ }
+ return conn, nil, nil
+
+ case dnstt.ResolverTypeDOT:
+ // t.remoteAddr = turbotunnel.DummyAddr{}
+ var dialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
+ if r.UTLSClientHelloID != nil {
+ id := r.UTLSClientHelloID
+ dialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return dnstt.UTLSDialContext(ctx, network, addr, nil, id)
+ }
+ } else {
+ dialTLSContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return tls.DialWithDialer(&net.Dialer{}, network, addr, nil)
+ }
+ }
+ conn, err := dnstt.NewTLSPacketConn(r.ResolverAddr, dialTLSContext, 512, "block")
+ if err != nil {
+ return nil, nil, err
+ }
+ return conn, nil, nil
+
+ default:
+ return nil, nil, fmt.Errorf("unsupported resolver type: %s", r.ResolverType)
+ }
+}
diff --git a/protocol/hiddify/dnstt/tools.go b/protocol/hiddify/dnstt/tools.go
new file mode 100644
index 0000000000..88c6fda7eb
--- /dev/null
+++ b/protocol/hiddify/dnstt/tools.go
@@ -0,0 +1,90 @@
+package dnstt
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ _ "embed"
+
+ dnstt "github.com/net2share/vaydns/client"
+ "github.com/sagernet/sing-box/option"
+)
+
+var (
+ //go:embed resolvers_by_country.json
+ resolvers_bytes []byte
+ countryResolvers map[string][]string
+ resolverCountry map[string]string
+)
+
+func loadResolvers() {
+ json.Unmarshal(resolvers_bytes, &countryResolvers)
+ resolverCountry = make(map[string]string)
+ for country, resolvers := range countryResolvers {
+ for _, resolver := range resolvers {
+ resolverCountry[resolver] = country
+ }
+ }
+}
+
+type ResolverS struct {
+ Resolver dnstt.Resolver
+ Auto bool
+}
+
+func getConfigResolvers(options option.DnsttOptions) ([]ResolverS, error) {
+ resolvers := []ResolverS{}
+ for _, resolverAddr := range options.Resolvers {
+ if resolverAddr == "" || resolverAddr == "auto" {
+ for ip, _ := range resolverCountry {
+ resolver, err := getResolver(options, fmt.Sprint(ip, ":53"))
+
+ if err != nil {
+ return nil, fmt.Errorf("invalid resolver address %s: %w", ip, err)
+ }
+ resolvers = append(resolvers, ResolverS{
+ Resolver: resolver,
+ Auto: true,
+ })
+ }
+ continue
+ }
+ resolver, err := getResolver(options, resolverAddr)
+ if err != nil {
+ return nil, fmt.Errorf("invalid resolver address %s: %w", resolverAddr, err)
+ }
+ resolvers = append(resolvers, ResolverS{
+ Resolver: resolver,
+ Auto: false,
+ })
+
+ }
+ return resolvers, nil
+}
+func getResolver(options option.DnsttOptions, s string) (dnstt.Resolver, error) {
+ var resolver dnstt.Resolver
+ var err error
+ if _, ok := strings.CutPrefix(s, "https://"); ok {
+ resolver, err = dnstt.NewResolver(dnstt.ResolverTypeDOH, s)
+ } else if dot, ok := strings.CutPrefix(s, "dot://"); ok {
+ resolver, err = dnstt.NewResolver(dnstt.ResolverTypeDOT, dot)
+ } else {
+ resolver, err = dnstt.NewResolver(dnstt.ResolverTypeUDP, s)
+ }
+ if err != nil {
+ return resolver, err
+ }
+ resolver.UDPAcceptErrors = options.UdpAcceptErrors
+ resolver.UDPSharedSocket = options.UdpSharedSocket
+ if options.UdpTimeout != nil {
+ resolver.UDPTimeout = options.UdpTimeout.Build()
+ }
+ if options.UdpWorkers != nil {
+ resolver.UDPWorkers = *options.UdpWorkers
+ }
+ if options.UTLSClientHelloID != "" {
+ resolver.UTLSClientHelloID = dnstt.UTLSLookup(options.UTLSClientHelloID)
+ }
+ return resolver, nil
+}
diff --git a/protocol/hiddify/gooserelay/outbound.go b/protocol/hiddify/gooserelay/outbound.go
new file mode 100644
index 0000000000..91922d3ab5
--- /dev/null
+++ b/protocol/hiddify/gooserelay/outbound.go
@@ -0,0 +1,275 @@
+// Package gooserelay wraps the GooseRelayVPN carrier as a sing-box outbound.
+//
+// Traffic is multiplexed over a domain-fronted HTTPS connection to a Google
+// Apps Script endpoint, which forwards encrypted frames to the user's VPS.
+// The carrier handles per-endpoint health and round-robin internally; this
+// outbound only manages the lifecycle and wraps each session as a net.Conn.
+package gooserelay
+
+import (
+ "context"
+ "encoding/hex"
+ "fmt"
+ "net"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/kianmhz/GooseRelayVPN/goose"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/uot"
+)
+
+const (
+ defaultGoogleHost = "216.239.38.120:443"
+ defaultDiagnoseTimeout = 10 * time.Second
+)
+
+var defaultSNIHosts = []string{"www.google.com"}
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.GooseRelayOptions](registry, C.TypeGooseRelay, New)
+}
+
+var _ adapter.Outbound = (*Outbound)(nil)
+
+type Outbound struct {
+ outbound.Adapter
+ ctx context.Context
+ logger logger.ContextLogger
+ options option.GooseRelayOptions
+ client *goose.Client
+ uotClient *uot.Client
+
+ mu sync.Mutex
+ runCancel context.CancelFunc
+ started int
+}
+
+func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.GooseRelayOptions) (adapter.Outbound, error) {
+ if len(options.ScriptKeys) == 0 {
+ return nil, E.New("script_keys is required")
+ }
+ if options.TunnelKey == "" {
+ return nil, E.New("tunnel_key is required")
+ }
+ if len(options.TunnelKey) != 64 {
+ return nil, E.New("tunnel_key must be 64 hex characters (AES-256)")
+ }
+ if _, err := hex.DecodeString(options.TunnelKey); err != nil {
+ return nil, E.Cause(err, "tunnel_key not valid hex")
+ }
+
+ googleHost := options.GoogleHost
+ if googleHost == "" {
+ googleHost = defaultGoogleHost
+ }
+ sniHosts := options.SNI
+ if len(sniHosts) == 0 {
+ sniHosts = defaultSNIHosts
+ }
+
+ scriptURLs := make([]string, 0, len(options.ScriptKeys))
+ for i, key := range options.ScriptKeys {
+ key = strings.TrimSpace(key)
+ if key == "" {
+ return nil, E.New("script_keys[", i, "] is empty")
+ }
+ if strings.ContainsAny(key, "/?#") {
+ return nil, E.New("script_keys[", i, "] contains a URL separator (/?#); paste the deployment ID only")
+ }
+ scriptURLs = append(scriptURLs, fmt.Sprintf("https://script.google.com/macros/s/%s/exec", key))
+ }
+
+ client, err := goose.New(goose.Config{
+ ScriptURLs: scriptURLs,
+ Fronting: goose.FrontingConfig{GoogleIP: googleHost, SNIHosts: sniHosts},
+ AESKeyHex: options.TunnelKey,
+ DebugTiming: options.DebugTiming,
+ })
+ if err != nil {
+ return nil, E.Cause(err, "construct goose client")
+ }
+
+ out := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeGooseRelay, tag, []string{N.NetworkTCP}, options.DialerOptions),
+ ctx: ctx,
+ logger: logger,
+ options: options,
+ client: client,
+ }
+ if options.UDPOverTCP != nil && options.UDPOverTCP.Enabled {
+ out.uotClient = &uot.Client{
+ Dialer: singDialerAdapter{out: out},
+ Version: options.UDPOverTCP.Version,
+ }
+ }
+ return out, nil
+}
+
+func (h *Outbound) PostStart() error {
+ runCtx, cancel := context.WithCancel(h.ctx)
+ h.mu.Lock()
+ h.runCancel = cancel
+ h.mu.Unlock()
+
+ go func() {
+ if err := h.client.Run(runCtx); err != nil && runCtx.Err() == nil {
+ h.logger.ErrorContext(runCtx, "carrier run exited: ", err)
+ }
+ }()
+ go h.diagnoseAndMarkReady(runCtx)
+ return nil
+}
+
+// diagnoseAndMarkReady probes every configured script_key concurrently using a
+// throwaway one-endpoint carrier per probe, and flips h.started:
+// - +1 (ready) as soon as ANY endpoint passes Diagnose,
+// - -1 (failed) only if ALL endpoints fail.
+//
+// Throwaway probes are cheap: carrier.New only allocates HTTP clients and
+// returns; no goroutines are launched until Run is called, which we never do
+// for probes. Cancelling probeCtx on first success aborts the remaining
+// in-flight HTTP requests.
+func (h *Outbound) diagnoseAndMarkReady(runCtx context.Context) {
+ budget := defaultDiagnoseTimeout
+ if h.options.HandshakeTimeout != nil {
+ if d := h.options.HandshakeTimeout.Build(); d > 0 {
+ budget = d
+ }
+ }
+ probeCtx, cancel := context.WithTimeout(runCtx, budget)
+ defer cancel()
+
+ googleHost := h.options.GoogleHost
+ if googleHost == "" {
+ googleHost = defaultGoogleHost
+ }
+ sniHosts := h.options.SNI
+ if len(sniHosts) == 0 {
+ sniHosts = defaultSNIHosts
+ }
+ fronting := goose.FrontingConfig{GoogleIP: googleHost, SNIHosts: sniHosts}
+
+ type probeResult struct {
+ key string
+ err error
+ }
+ keys := h.options.ScriptKeys
+ results := make(chan probeResult, len(keys))
+ for _, key := range keys {
+ go func(k string) {
+ trimmed := strings.TrimSpace(k)
+ probe, err := goose.New(goose.Config{
+ ScriptURLs: []string{fmt.Sprintf("https://script.google.com/macros/s/%s/exec", trimmed)},
+ Fronting: fronting,
+ AESKeyHex: h.options.TunnelKey,
+ })
+ if err != nil {
+ results <- probeResult{trimmed, err}
+ return
+ }
+ results <- probeResult{trimmed, probe.Diagnose(probeCtx)}
+ }(key)
+ }
+
+ for i := 0; i < len(keys); i++ {
+ select {
+ case r := <-results:
+ if r.err == nil {
+ h.mu.Lock()
+ h.started = 1
+ h.mu.Unlock()
+ h.logger.InfoContext(runCtx, "goose-relay ready (first healthy endpoint: ", r.key, ")")
+ return
+ }
+ h.logger.WarnContext(probeCtx, "goose-relay endpoint ", r.key, " diagnose failed: ", r.err)
+ case <-runCtx.Done():
+ return
+ }
+ }
+
+ h.mu.Lock()
+ h.started = -1
+ h.mu.Unlock()
+ h.logger.ErrorContext(runCtx, "goose-relay: all ", len(keys), " endpoints failed diagnose")
+}
+
+func (h *Outbound) IsReady() bool {
+ h.mu.Lock()
+ defer h.mu.Unlock()
+ return h.started > 0
+}
+
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if !h.IsReady() {
+ return nil, E.New("outbound is not started")
+ }
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ default:
+ return nil, E.New("network ", network, " not supported by goose-relay")
+ }
+ return h.client.Dial(destination.String()), nil
+}
+
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ if h.uotClient == nil {
+ return nil, E.New("UDP over TCP is not enabled for this outbound")
+ }
+ if !h.IsReady() {
+ return nil, E.New("outbound is not started")
+ }
+ return h.uotClient.ListenPacket(ctx, destination)
+}
+
+func (h *Outbound) DisplayType() string {
+ str := C.ProxyDisplayName(h.Type())
+ h.mu.Lock()
+ state := h.started
+ h.mu.Unlock()
+ switch {
+ case state == 0:
+ return str + " ⚠️ Connecting..."
+ case state < 0:
+ return str + " ❌ Failed!"
+ default:
+ return fmt.Sprint(str, " ✔️ ", len(h.options.ScriptKeys), " endpoints")
+ }
+}
+
+func (h *Outbound) Close() error {
+ h.mu.Lock()
+ cancel := h.runCancel
+ h.runCancel = nil
+ h.mu.Unlock()
+ if cancel != nil {
+ shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 2*time.Second)
+ h.client.Shutdown(shutdownCtx)
+ shutdownCancel()
+ cancel()
+ }
+ return nil
+}
+
+// singDialerAdapter bridges Outbound back to N.Dialer so uot.Client can dial
+// its underlying TCP carrier session via DialContext.
+type singDialerAdapter struct {
+ out *Outbound
+}
+
+func (a singDialerAdapter) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ return a.out.DialContext(ctx, network, destination)
+}
+
+func (a singDialerAdapter) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ return nil, E.New("not supported")
+}
diff --git a/protocol/hiddify/gooserelay/outbound_test.go b/protocol/hiddify/gooserelay/outbound_test.go
new file mode 100644
index 0000000000..411c14dd70
--- /dev/null
+++ b/protocol/hiddify/gooserelay/outbound_test.go
@@ -0,0 +1,127 @@
+package gooserelay_test
+
+import (
+ "context"
+ "strings"
+ "testing"
+
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/protocol/hiddify/gooserelay"
+)
+
+const validHexKey = "0000000000000000000000000000000000000000000000000000000000000000"
+
+func TestNew_OptionValidation(t *testing.T) {
+ t.Parallel()
+
+ cases := []struct {
+ name string
+ opts option.GooseRelayOptions
+ wantErr string // substring expected in the error; "" = expect success
+ wantSkip bool
+ }{
+ {
+ name: "missing script_keys",
+ opts: option.GooseRelayOptions{TunnelKey: validHexKey},
+ wantErr: "script_keys is required",
+ },
+ {
+ name: "missing tunnel_key",
+ opts: option.GooseRelayOptions{ScriptKeys: []string{"abc"}},
+ wantErr: "tunnel_key is required",
+ },
+ {
+ name: "tunnel_key wrong length",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc"},
+ TunnelKey: "deadbeef",
+ },
+ wantErr: "64 hex characters",
+ },
+ {
+ name: "tunnel_key not hex",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc"},
+ TunnelKey: strings.Repeat("Z", 64),
+ },
+ wantErr: "not valid hex",
+ },
+ {
+ name: "empty entry in script_keys",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc", " "},
+ TunnelKey: validHexKey,
+ },
+ wantErr: "script_keys[1] is empty",
+ },
+ {
+ name: "script_keys contains URL separator /",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc/def"},
+ TunnelKey: validHexKey,
+ },
+ wantErr: "URL separator",
+ },
+ {
+ name: "script_keys contains URL separator ?",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc?evil=1"},
+ TunnelKey: validHexKey,
+ },
+ wantErr: "URL separator",
+ },
+ {
+ name: "script_keys contains URL separator #",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"abc#frag"},
+ TunnelKey: validHexKey,
+ },
+ wantErr: "URL separator",
+ },
+ {
+ name: "valid minimal options",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"AKfycbxFakeDeploymentID"},
+ TunnelKey: validHexKey,
+ },
+ wantErr: "",
+ },
+ {
+ name: "valid with custom GoogleHost and SNI defaults applied",
+ opts: option.GooseRelayOptions{
+ ScriptKeys: []string{"AKfycbxFakeDeploymentID"},
+ TunnelKey: validHexKey,
+ GoogleHost: "1.2.3.4:443",
+ },
+ wantErr: "",
+ },
+ }
+
+ logger := log.NewNOPFactory().Logger()
+ for _, tc := range cases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ t.Parallel()
+ if tc.wantSkip {
+ t.Skip()
+ }
+ out, err := gooserelay.New(context.Background(), nil, logger, "goose-test", tc.opts)
+ if tc.wantErr == "" {
+ if err != nil {
+ t.Fatalf("expected success, got error: %v", err)
+ }
+ if out == nil {
+ t.Fatal("expected non-nil outbound on success")
+ }
+ return
+ }
+ if err == nil {
+ t.Fatalf("expected error containing %q, got nil", tc.wantErr)
+ }
+ if !strings.Contains(err.Error(), tc.wantErr) {
+ t.Fatalf("expected error containing %q, got: %v", tc.wantErr, err)
+ }
+ })
+ }
+}
diff --git a/protocol/hiddify/hinvalid/outbound.go b/protocol/hiddify/hinvalid/outbound.go
new file mode 100644
index 0000000000..11d38b35f2
--- /dev/null
+++ b/protocol/hiddify/hinvalid/outbound.go
@@ -0,0 +1,50 @@
+package hinvalid
+
+import (
+ "context"
+ "net"
+ "syscall"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.HInvalidOptions](registry, C.TypeHInvalidConfig, New)
+}
+
+var _ adapter.Outbound = (*Outbound)(nil)
+
+type Outbound struct {
+ outbound.Adapter
+ logger logger.ContextLogger
+ InvalidOptions option.HInvalidOptions
+}
+
+func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, invalidOptions option.HInvalidOptions) (adapter.Outbound, error) {
+ return &Outbound{
+ Adapter: outbound.NewAdapter(C.TypeHInvalidConfig, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
+ logger: logger,
+ InvalidOptions: invalidOptions,
+ }, nil
+}
+
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ h.logger.InfoContext(ctx, "blocked connection to ", destination)
+ return nil, syscall.EPERM
+}
+
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ h.logger.InfoContext(ctx, "blocked packet connection to ", destination)
+ return nil, syscall.EPERM
+}
+
+func (h *Outbound) DisplayType() string {
+ return C.ProxyDisplayName(h.Tag()) + " " + h.InvalidOptions.Err.Error()
+}
diff --git a/protocol/hiddify/xray/outbound.go b/protocol/hiddify/xray/outbound.go
new file mode 100644
index 0000000000..f60526d56d
--- /dev/null
+++ b/protocol/hiddify/xray/outbound.go
@@ -0,0 +1,43 @@
+package xray
+
+import (
+ "context"
+ "net"
+ "syscall"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.XrayOutboundOptions](registry, C.TypeXray, New)
+}
+
+type Outbound struct {
+ outbound.Adapter
+ logger logger.ContextLogger
+}
+
+func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.XrayOutboundOptions) (adapter.Outbound, error) {
+ // return &Outbound{
+ // Adapter: outbound.NewAdapter(C.TypeBlock, tag, []string{N.NetworkTCP, N.NetworkUDP}, nil),
+ // logger: logger,
+ // }, nil
+ return nil, E.New("Xray is not implemented yet")
+}
+
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ h.logger.InfoContext(ctx, "blocked connection to ", destination)
+ return nil, syscall.EPERM
+}
+
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ h.logger.InfoContext(ctx, "blocked packet connection to ", destination)
+ return nil, syscall.EPERM
+}
diff --git a/protocol/http/inbound.go b/protocol/http/inbound.go
index e8a9a3daa5..fe573ea1e0 100644
--- a/protocol/http/inbound.go
+++ b/protocol/http/inbound.go
@@ -86,7 +86,7 @@ func (h *Inbound) Close() error {
)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
if h.tlsConfig != nil {
tlsConn, err := tls.ServerHandshake(ctx, conn, h.tlsConfig)
if err != nil {
@@ -96,7 +96,7 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
}
conn = tlsConn
}
- err := http.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
+ err := http.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, adapter.NewUpstreamHandler(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
if err != nil {
N.CloseOnHandshakeFailure(conn, onClose, err)
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
diff --git a/protocol/hysteria/inbound.go b/protocol/hysteria/inbound.go
index 98d7cb8106..6fd4fe9716 100644
--- a/protocol/hysteria/inbound.go
+++ b/protocol/hysteria/inbound.go
@@ -77,15 +77,9 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
ReceiveBPS: receiveBps,
XPlusPassword: options.Obfs,
TLSConfig: tlsConfig,
+ QUICOptions: buildInboundQUICOptions(options),
UDPTimeout: udpTimeout,
Handler: inbound,
-
- // Legacy options
-
- ConnReceiveWindow: options.ReceiveWindowConn,
- StreamReceiveWindow: options.ReceiveWindowClient,
- MaxIncomingStreams: int64(options.MaxConnClient),
- DisableMTUDiscovery: options.DisableMTUDiscovery,
})
if err != nil {
return nil, err
diff --git a/protocol/hysteria/outbound.go b/protocol/hysteria/outbound.go
index bcadd878ab..bd6c5e4a37 100644
--- a/protocol/hysteria/outbound.go
+++ b/protocol/hysteria/outbound.go
@@ -70,21 +70,19 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
}
client, err := hysteria.NewClient(hysteria.ClientOptions{
- Context: ctx,
- Dialer: outboundDialer,
- Logger: logger,
- ServerAddress: options.ServerOptions.Build(),
- ServerPorts: options.ServerPorts,
- HopInterval: time.Duration(options.HopInterval),
- SendBPS: sendBps,
- ReceiveBPS: receiveBps,
- XPlusPassword: options.Obfs,
- Password: password,
- TLSConfig: tlsConfig,
- UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
- ConnReceiveWindow: options.ReceiveWindowConn,
- StreamReceiveWindow: options.ReceiveWindow,
- DisableMTUDiscovery: options.DisableMTUDiscovery,
+ Context: ctx,
+ Dialer: outboundDialer,
+ Logger: logger,
+ ServerAddress: options.ServerOptions.Build(),
+ ServerPorts: options.ServerPorts,
+ HopInterval: time.Duration(options.HopInterval),
+ SendBPS: sendBps,
+ ReceiveBPS: receiveBps,
+ XPlusPassword: options.Obfs,
+ Password: password,
+ TLSConfig: tlsConfig,
+ QUICOptions: buildOutboundQUICOptions(options),
+ UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
})
if err != nil {
return nil, err
diff --git a/protocol/hysteria/quic.go b/protocol/hysteria/quic.go
new file mode 100644
index 0000000000..5d6e039c3f
--- /dev/null
+++ b/protocol/hysteria/quic.go
@@ -0,0 +1,49 @@
+package hysteria
+
+import (
+ "github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
+)
+
+func buildBaseQUICOptions(options option.QUICOptions) qtls.QUICOptions {
+ return qtls.QUICOptions{
+ IdleTimeout: options.IdleTimeout.Build(),
+ KeepAlivePeriod: options.KeepAlivePeriod.Build(),
+ StreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ InitialPacketSize: options.InitialPacketSize,
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ }
+}
+
+func buildInboundQUICOptions(options option.HysteriaInboundOptions) qtls.QUICOptions {
+ quicOptions := buildBaseQUICOptions(options.QUICOptions)
+ if quicOptions.ConnectionReceiveWindow == 0 {
+ quicOptions.ConnectionReceiveWindow = options.ReceiveWindowConn //nolint:staticcheck
+ }
+ if quicOptions.StreamReceiveWindow == 0 {
+ quicOptions.StreamReceiveWindow = options.ReceiveWindowClient //nolint:staticcheck
+ }
+ if quicOptions.MaxConcurrentStreams == 0 {
+ quicOptions.MaxConcurrentStreams = options.MaxConnClient //nolint:staticcheck
+ }
+ if !quicOptions.DisablePathMTUDiscovery {
+ quicOptions.DisablePathMTUDiscovery = options.DisableMTUDiscovery //nolint:staticcheck
+ }
+ return quicOptions
+}
+
+func buildOutboundQUICOptions(options option.HysteriaOutboundOptions) qtls.QUICOptions {
+ quicOptions := buildBaseQUICOptions(options.QUICOptions)
+ if quicOptions.ConnectionReceiveWindow == 0 {
+ quicOptions.ConnectionReceiveWindow = options.ReceiveWindowConn //nolint:staticcheck
+ }
+ if quicOptions.StreamReceiveWindow == 0 {
+ quicOptions.StreamReceiveWindow = options.ReceiveWindow //nolint:staticcheck
+ }
+ if !quicOptions.DisablePathMTUDiscovery {
+ quicOptions.DisablePathMTUDiscovery = options.DisableMTUDiscovery //nolint:staticcheck
+ }
+ return quicOptions
+}
diff --git a/protocol/hysteria2/inbound.go b/protocol/hysteria2/inbound.go
index bb5980701f..b706b49202 100644
--- a/protocol/hysteria2/inbound.go
+++ b/protocol/hysteria2/inbound.go
@@ -5,6 +5,7 @@ import (
"net"
"net/http"
"net/http/httputil"
+ "net/netip"
"net/url"
"time"
@@ -15,13 +16,16 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
"github.com/sagernet/sing-quic/hysteria"
"github.com/sagernet/sing-quic/hysteria2"
+ "github.com/sagernet/sing-quic/hysteria2/realm"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
)
func RegisterInbound(registry *inbound.Registry) {
@@ -48,6 +52,8 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
return nil, err
}
var salamanderPassword string
+ var geckoPassword string
+ var geckoMinPacketSize, geckoMaxPacketSize int
if options.Obfs != nil {
if options.Obfs.Password == "" {
return nil, E.New("missing obfs password")
@@ -55,6 +61,10 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
switch options.Obfs.Type {
case hysteria2.ObfsTypeSalamander:
salamanderPassword = options.Obfs.Password
+ case hysteria2.ObfsTypeGecko:
+ geckoPassword = options.Obfs.Password
+ geckoMinPacketSize = options.Obfs.GeckoOptions.MinPacketSize
+ geckoMaxPacketSize = options.Obfs.GeckoOptions.MaxPacketSize
default:
return nil, E.New("unknown obfs type: ", options.Obfs.Type)
}
@@ -113,18 +123,62 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
} else {
udpTimeout = C.UDPTimeout
}
- service, err := hysteria2.NewService[int](hysteria2.ServiceOptions{
- Context: ctx,
- Logger: logger,
- BrutalDebug: options.BrutalDebug,
- SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
- ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
- SalamanderPassword: salamanderPassword,
- TLSConfig: tlsConfig,
+ var realmOptions *realm.Options
+ if options.Realm != nil {
+ queryOptions, err := adapter.DNSQueryOptionsFrom(ctx, options.Realm.STUNDomainResolver)
+ if err != nil {
+ return nil, err
+ }
+ httpClientTransport, err := service.FromContext[adapter.HTTPClientManager](ctx).ResolveTransport(ctx, logger, common.PtrValueOrDefault(options.Realm.HTTPClient))
+ if err != nil {
+ return nil, E.Cause(err, "create realm http client")
+ }
+ dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
+ realmOptions = &realm.Options{
+ ServerURL: options.Realm.ServerURL,
+ Token: options.Realm.Token,
+ RealmID: options.Realm.RealmID,
+ STUNServers: options.Realm.STUNServers,
+ HTTPClient: &http.Client{Transport: httpClientTransport},
+ Resolver: func(ctx context.Context, host string, ipv4, ipv6 bool) ([]netip.Addr, error) {
+ dnsOptions := queryOptions
+ switch {
+ case ipv4 && !ipv6:
+ dnsOptions.Strategy = C.DomainStrategyIPv4Only
+ case !ipv4 && ipv6:
+ dnsOptions.Strategy = C.DomainStrategyIPv6Only
+ }
+ return dnsRouter.Lookup(ctx, host, dnsOptions)
+ },
+ Logger: logger,
+ }
+ }
+ hysteriaService, err := hysteria2.NewService[int](hysteria2.ServiceOptions{
+ Context: ctx,
+ Logger: logger,
+ BrutalDebug: options.BrutalDebug,
+ SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
+ ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
+ SalamanderPassword: salamanderPassword,
+ GeckoPassword: geckoPassword,
+ GeckoMinPacketSize: geckoMinPacketSize,
+ GeckoMaxPacketSize: geckoMaxPacketSize,
+ TLSConfig: tlsConfig,
+ QUICOptions: qtls.QUICOptions{
+ IdleTimeout: options.IdleTimeout.Build(),
+ KeepAlivePeriod: options.KeepAlivePeriod.Build(),
+ StreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ InitialPacketSize: options.InitialPacketSize,
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ },
IgnoreClientBandwidth: options.IgnoreClientBandwidth,
UDPTimeout: udpTimeout,
Handler: inbound,
MasqueradeHandler: masqueradeHandler,
+ BBRProfile: options.BBRProfile,
+ RealmOptions: realmOptions,
})
if err != nil {
return nil, err
@@ -137,8 +191,8 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
userNameList = append(userNameList, user.Name)
userPasswordList = append(userPasswordList, user.Password)
}
- service.UpdateUsers(userList, userPasswordList)
- inbound.service = service
+ hysteriaService.UpdateUsers(userList, userPasswordList)
+ inbound.service = hysteriaService
inbound.userNameList = userNameList
return inbound, nil
}
@@ -204,6 +258,10 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
return h.service.Start(packetConn)
}
+func (h *Inbound) InterfaceUpdated() {
+ h.service.Reset()
+}
+
func (h *Inbound) Close() error {
return common.Close(
h.listener,
diff --git a/protocol/hysteria2/outbound.go b/protocol/hysteria2/outbound.go
index d4382fdcdf..7651a0c653 100644
--- a/protocol/hysteria2/outbound.go
+++ b/protocol/hysteria2/outbound.go
@@ -3,6 +3,9 @@ package hysteria2
import (
"context"
"net"
+ "net/http"
+ "net/netip"
+ "net/url"
"os"
"time"
@@ -14,14 +17,17 @@ import (
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-box/protocol/tuic"
+ qtls "github.com/sagernet/sing-quic"
"github.com/sagernet/sing-quic/hysteria"
"github.com/sagernet/sing-quic/hysteria2"
+ "github.com/sagernet/sing-quic/hysteria2/realm"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/bufio"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
)
func RegisterOutbound(registry *outbound.Registry) {
@@ -44,11 +50,17 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
if options.TLS == nil || !options.TLS.Enabled {
return nil, C.ErrTLSRequired
}
- tlsConfig, err := tls.NewClient(ctx, logger, options.Server, common.PtrValueOrDefault(options.TLS))
+ tlsServerAddress, tlsOptions, err := outboundTLSOptions(options)
+ if err != nil {
+ return nil, err
+ }
+ tlsConfig, err := tls.NewClient(ctx, logger, tlsServerAddress, tlsOptions)
if err != nil {
return nil, err
}
var salamanderPassword string
+ var geckoPassword string
+ var geckoMinPacketSize, geckoMaxPacketSize int
if options.Obfs != nil {
if options.Obfs.Password == "" {
return nil, E.New("missing obfs password")
@@ -56,14 +68,52 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
switch options.Obfs.Type {
case hysteria2.ObfsTypeSalamander:
salamanderPassword = options.Obfs.Password
+ case hysteria2.ObfsTypeGecko:
+ geckoPassword = options.Obfs.Password
+ geckoMinPacketSize = options.Obfs.GeckoOptions.MinPacketSize
+ geckoMaxPacketSize = options.Obfs.GeckoOptions.MaxPacketSize
default:
return nil, E.New("unknown obfs type: ", options.Obfs.Type)
}
}
- outboundDialer, err := dialer.New(ctx, options.DialerOptions, options.ServerIsDomain())
+ outboundDialer, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: options.ServerIsDomain(),
+ })
if err != nil {
return nil, err
}
+ var realmOptions *realm.Options
+ if options.Realm != nil {
+ queryOptions, err := adapter.DNSQueryOptionsFrom(ctx, options.DialerOptions.DomainResolver)
+ if err != nil {
+ return nil, err
+ }
+ httpClientTransport, err := service.FromContext[adapter.HTTPClientManager](ctx).ResolveTransport(ctx, logger, common.PtrValueOrDefault(options.Realm.HTTPClient))
+ if err != nil {
+ return nil, E.Cause(err, "create realm http client")
+ }
+ dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
+ realmOptions = &realm.Options{
+ ServerURL: options.Realm.ServerURL,
+ Token: options.Realm.Token,
+ RealmID: options.Realm.RealmID,
+ STUNServers: options.Realm.STUNServers,
+ HTTPClient: &http.Client{Transport: httpClientTransport},
+ Resolver: func(ctx context.Context, host string, ipv4, ipv6 bool) ([]netip.Addr, error) {
+ dnsOptions := queryOptions
+ switch {
+ case ipv4 && !ipv6:
+ dnsOptions.Strategy = C.DomainStrategyIPv4Only
+ case !ipv4 && ipv6:
+ dnsOptions.Strategy = C.DomainStrategyIPv6Only
+ }
+ return dnsRouter.Lookup(ctx, host, dnsOptions)
+ },
+ Logger: logger,
+ }
+ }
networkList := options.Network.Build()
client, err := hysteria2.NewClient(hysteria2.ClientOptions{
Context: ctx,
@@ -73,12 +123,27 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
ServerAddress: options.ServerOptions.Build(),
ServerPorts: options.ServerPorts,
HopInterval: time.Duration(options.HopInterval),
+ HopIntervalMax: time.Duration(options.HopIntervalMax),
SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
SalamanderPassword: salamanderPassword,
+ GeckoPassword: geckoPassword,
+ GeckoMinPacketSize: geckoMinPacketSize,
+ GeckoMaxPacketSize: geckoMaxPacketSize,
Password: options.Password,
TLSConfig: tlsConfig,
- UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
+ QUICOptions: qtls.QUICOptions{
+ IdleTimeout: options.IdleTimeout.Build(),
+ KeepAlivePeriod: options.KeepAlivePeriod.Build(),
+ StreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ InitialPacketSize: options.InitialPacketSize,
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ },
+ UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
+ BBRProfile: options.BBRProfile,
+ RealmOptions: realmOptions,
})
if err != nil {
return nil, err
@@ -90,6 +155,25 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
}, nil
}
+func outboundTLSOptions(options option.Hysteria2OutboundOptions) (string, option.OutboundTLSOptions, error) {
+ tlsOptions := common.PtrValueOrDefault(options.TLS)
+ if options.Realm == nil {
+ return options.Server, tlsOptions, nil
+ }
+ if options.Server != "" || options.ServerPort != 0 || len(options.ServerPorts) > 0 {
+ return "", tlsOptions, E.New("realm conflicts with server, server_port, and server_ports")
+ }
+ serverURL, err := url.Parse(options.Realm.ServerURL)
+ if err != nil {
+ return "", tlsOptions, E.Cause(err, "parse realm server_url")
+ }
+ serverName := serverURL.Hostname()
+ if serverName == "" {
+ return "", tlsOptions, E.New("missing host in realm server_url")
+ }
+ return serverName, tlsOptions, nil
+}
+
func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
switch N.NetworkName(network) {
case N.NetworkTCP:
diff --git a/protocol/hysteria2/realm.go b/protocol/hysteria2/realm.go
new file mode 100644
index 0000000000..5b7a82e84f
--- /dev/null
+++ b/protocol/hysteria2/realm.go
@@ -0,0 +1,161 @@
+package hysteria2
+
+import (
+ "context"
+ "errors"
+ "net"
+ "net/http"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ boxService "github.com/sagernet/sing-box/adapter/service"
+ "github.com/sagernet/sing-box/common/listener"
+ "github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ N "github.com/sagernet/sing/common/network"
+ aTLS "github.com/sagernet/sing/common/tls"
+ sHTTP "github.com/sagernet/sing/protocol/http"
+
+ "github.com/go-chi/chi/v5"
+ "github.com/go-chi/chi/v5/middleware"
+ "github.com/go-chi/render"
+ "golang.org/x/net/http2"
+ "golang.org/x/net/http2/h2c"
+)
+
+func RegisterRealmService(registry *boxService.Registry) {
+ boxService.Register[option.HysteriaRealmServiceOptions](registry, C.TypeHysteriaRealm, NewRealmService)
+}
+
+type RealmService struct {
+ boxService.Adapter
+ ctx context.Context
+ cancel context.CancelFunc
+ logger log.ContextLogger
+ listener *listener.Listener
+ tlsConfig tls.ServerConfig
+ httpServer *http.Server
+ server *server
+}
+
+func NewRealmService(ctx context.Context, logger log.ContextLogger, tag string, options option.HysteriaRealmServiceOptions) (adapter.Service, error) {
+ if len(options.Users) == 0 {
+ return nil, E.New("missing users")
+ }
+ tokenMap := make(map[string]*realmUser, len(options.Users))
+ for i, user := range options.Users {
+ if user.Name == "" {
+ return nil, E.New("missing name for user[", i, "]")
+ }
+ if user.Token == "" {
+ return nil, E.New("missing token for user[", i, "]")
+ }
+ tokenMap[user.Token] = &realmUser{
+ name: user.Name,
+ maxRealms: user.MaxRealms,
+ }
+ }
+ server := newServer(logger, tokenMap)
+ ctx, cancel := context.WithCancel(ctx)
+ chiRouter := chi.NewRouter()
+ chiRouter.Use(middleware.RequestSize(maxRequestBodyBytes))
+ chiRouter.Use(func(handler http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ logger.DebugContext(r.Context(), r.Method, " ", r.RequestURI, " ", sHTTP.SourceAddress(r))
+ handler.ServeHTTP(w, r)
+ })
+ })
+ chiRouter.Route("/v1/{id}", func(r chi.Router) {
+ r.Use(validateRealmID)
+ r.With(server.authUser).Post("/", server.handleRegister)
+ r.With(server.authSession).Delete("/", server.handleDeregister)
+ r.With(server.authSession).Get("/events", server.handleEvents)
+ r.With(server.authSession).Post("/heartbeat", server.handleHeartbeat)
+ r.With(server.authUser).Post("/connect", server.handleConnect)
+ r.With(server.authSession).Post("/connects/{nonce}", server.handleConnectResponse)
+ })
+ chiRouter.NotFound(func(w http.ResponseWriter, r *http.Request) {
+ render.Status(r, http.StatusNotFound)
+ render.JSON(w, r, render.M{"error": "not_found", "message": "unknown path"})
+ })
+ chiRouter.MethodNotAllowed(func(w http.ResponseWriter, r *http.Request) {
+ render.Status(r, http.StatusMethodNotAllowed)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "method not allowed"})
+ })
+ s := &RealmService{
+ Adapter: boxService.NewAdapter(C.TypeHysteriaRealm, tag),
+ ctx: ctx,
+ cancel: cancel,
+ logger: logger,
+ listener: listener.New(listener.Options{
+ Context: ctx,
+ Logger: logger,
+ Network: []string{N.NetworkTCP},
+ Listen: options.ListenOptions,
+ }),
+ httpServer: &http.Server{
+ Handler: h2c.NewHandler(chiRouter, &http2.Server{
+ IdleTimeout: time.Duration(options.IdleTimeout),
+ ReadIdleTimeout: time.Duration(options.KeepAlivePeriod),
+ MaxUploadBufferPerStream: int32(options.StreamReceiveWindow.Value()),
+ MaxUploadBufferPerConnection: int32(options.ConnectionReceiveWindow.Value()),
+ MaxConcurrentStreams: uint32(options.MaxConcurrentStreams),
+ }),
+ ConnContext: func(ctx context.Context, _ net.Conn) context.Context {
+ return log.ContextWithNewID(ctx)
+ },
+ },
+ server: server,
+ }
+ if options.TLS != nil {
+ tlsConfig, err := tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
+ if err != nil {
+ return nil, err
+ }
+ s.tlsConfig = tlsConfig
+ }
+ return s, nil
+}
+
+func (s *RealmService) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ if s.tlsConfig != nil {
+ err := s.tlsConfig.Start()
+ if err != nil {
+ return E.Cause(err, "create TLS config")
+ }
+ }
+ tcpListener, err := s.listener.ListenTCP()
+ if err != nil {
+ return err
+ }
+ if s.tlsConfig != nil {
+ if !common.Contains(s.tlsConfig.NextProtos(), http2.NextProtoTLS) {
+ s.tlsConfig.SetNextProtos(append([]string{"h2"}, s.tlsConfig.NextProtos()...))
+ }
+ tcpListener = aTLS.NewListener(tcpListener, s.tlsConfig)
+ }
+ go func() {
+ err = s.httpServer.Serve(tcpListener)
+ if err != nil && !errors.Is(err, http.ErrServerClosed) {
+ s.logger.Error("serve error: ", err)
+ }
+ }()
+ return nil
+}
+
+func (s *RealmService) Close() error {
+ s.cancel()
+ err := common.Close(common.PtrOrNil(s.httpServer))
+ s.server.closeAll()
+ return E.Errors(err, common.Close(
+ common.PtrOrNil(s.listener),
+ s.tlsConfig,
+ ))
+}
diff --git a/protocol/hysteria2/realm_server.go b/protocol/hysteria2/realm_server.go
new file mode 100644
index 0000000000..5143b86b6e
--- /dev/null
+++ b/protocol/hysteria2/realm_server.go
@@ -0,0 +1,536 @@
+package hysteria2
+
+import (
+ "context"
+ "crypto/rand"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/netip"
+ "regexp"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/log"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "github.com/go-chi/chi/v5"
+ "github.com/go-chi/render"
+)
+
+const (
+ sessionTTL = time.Minute
+ realmNamePattern = `^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$`
+ maxRequestBodyBytes = 4 << 10
+ maxAddresses = 8
+ nonceHexLength = 32
+ obfsHexLength = 64
+ eventChannelSize = 16
+ maxPendingAttempts = 16
+ connectResponseTimeout = 10 * time.Second
+)
+
+var realmPattern = regexp.MustCompile(realmNamePattern)
+
+type contextKey int
+
+const (
+ contextKeyUser contextKey = iota
+ contextKeySession
+)
+
+type realmUser struct {
+ name string
+ maxRealms int
+}
+
+type realmSession struct {
+ id string
+ realmID string
+ username string
+ addresses []string
+ expires time.Time
+ events chan realmEvent
+ timer *time.Timer
+ done chan struct{}
+ closed bool
+ pending map[string]chan punchResponsePayload
+}
+
+type realmEvent struct {
+ kind string
+ data any
+}
+
+type punchEvent struct {
+ Addresses []string `json:"addresses"`
+ Nonce string `json:"nonce"`
+ Obfs string `json:"obfs"`
+}
+
+type punchResponsePayload struct {
+ addresses []string
+}
+
+type server struct {
+ access sync.Mutex
+ realms map[string]*realmSession
+ sessions map[string]*realmSession
+ userCounts map[string]int
+ logger log.ContextLogger
+ tokenMap map[string]*realmUser
+}
+
+func newServer(logger log.ContextLogger, tokenMap map[string]*realmUser) *server {
+ return &server{
+ realms: make(map[string]*realmSession),
+ sessions: make(map[string]*realmSession),
+ userCounts: make(map[string]int),
+ logger: logger,
+ tokenMap: tokenMap,
+ }
+}
+
+func validateRealmID(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ id := chi.URLParam(r, "id")
+ if !realmPattern.MatchString(id) {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "invalid realm name"})
+ return
+ }
+ next.ServeHTTP(w, r)
+ })
+}
+
+func (s *server) authBearer(name string, key contextKey, lookup func(r *http.Request, token string) (any, bool)) func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ header := r.Header.Get("Authorization")
+ bearer, token, found := strings.Cut(header, " ")
+ if bearer != "Bearer" || !found {
+ render.Status(r, http.StatusUnauthorized)
+ render.JSON(w, r, render.M{"error": "invalid_token", "message": "invalid " + name + " token"})
+ return
+ }
+ value, authenticated := lookup(r, token)
+ if !authenticated {
+ render.Status(r, http.StatusUnauthorized)
+ render.JSON(w, r, render.M{"error": "invalid_token", "message": "invalid " + name + " token"})
+ return
+ }
+ next.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), key, value)))
+ })
+ }
+}
+
+func (s *server) authUser(next http.Handler) http.Handler {
+ return s.authBearer("realm", contextKeyUser, func(_ *http.Request, token string) (any, bool) {
+ user, authenticated := s.tokenMap[token]
+ return user, authenticated
+ })(next)
+}
+
+func (s *server) authSession(next http.Handler) http.Handler {
+ return s.authBearer("session", contextKeySession, func(r *http.Request, token string) (any, bool) {
+ sess := s.getSessionByToken(token)
+ if sess == nil || sess.realmID != chi.URLParam(r, "id") {
+ return nil, false
+ }
+ return sess, true
+ })(next)
+}
+
+func (s *server) getSessionByToken(token string) *realmSession {
+ s.access.Lock()
+ defer s.access.Unlock()
+ sess := s.sessions[token]
+ if sess == nil || sess.closed || time.Now().After(sess.expires) {
+ return nil
+ }
+ return sess
+}
+
+func (s *server) removeSessionLocked(sess *realmSession) {
+ if sess.closed {
+ return
+ }
+ sess.closed = true
+ close(sess.done)
+ if s.realms[sess.realmID] == sess {
+ delete(s.realms, sess.realmID)
+ }
+ if _, found := s.sessions[sess.id]; found {
+ s.userCounts[sess.username]--
+ if s.userCounts[sess.username] <= 0 {
+ delete(s.userCounts, sess.username)
+ }
+ }
+ delete(s.sessions, sess.id)
+ sess.timer.Stop()
+ close(sess.events)
+ for nonce, ch := range sess.pending {
+ close(ch)
+ delete(sess.pending, nonce)
+ }
+}
+
+func (s *server) removeSession(sess *realmSession) {
+ s.access.Lock()
+ defer s.access.Unlock()
+ s.removeSessionLocked(sess)
+}
+
+func (s *server) removeExpiredSession(sess *realmSession) bool {
+ s.access.Lock()
+ defer s.access.Unlock()
+ if sess.closed || !time.Now().After(sess.expires) {
+ return false
+ }
+ s.removeSessionLocked(sess)
+ return true
+}
+
+func (s *server) closeAll() {
+ s.access.Lock()
+ defer s.access.Unlock()
+ for _, sess := range s.sessions {
+ s.removeSessionLocked(sess)
+ }
+}
+
+func (s *server) registerPending(sess *realmSession, nonce string) (chan punchResponsePayload, bool) {
+ s.access.Lock()
+ defer s.access.Unlock()
+ if sess.closed || len(sess.pending) >= maxPendingAttempts {
+ return nil, false
+ }
+ if _, exists := sess.pending[nonce]; exists {
+ return nil, false
+ }
+ ch := make(chan punchResponsePayload, 1)
+ sess.pending[nonce] = ch
+ return ch, true
+}
+
+func (s *server) deliverPending(sess *realmSession, nonce string, payload punchResponsePayload) bool {
+ s.access.Lock()
+ defer s.access.Unlock()
+ if sess.closed {
+ return false
+ }
+ ch, found := sess.pending[nonce]
+ if !found {
+ return false
+ }
+ delete(sess.pending, nonce)
+ select {
+ case ch <- payload:
+ default:
+ }
+ return true
+}
+
+func (s *server) cancelPending(sess *realmSession, nonce string) {
+ s.access.Lock()
+ defer s.access.Unlock()
+ delete(sess.pending, nonce)
+}
+
+func (s *server) sendEvent(sess *realmSession, ev realmEvent) bool {
+ s.access.Lock()
+ defer s.access.Unlock()
+ if sess.closed {
+ return false
+ }
+ select {
+ case sess.events <- ev:
+ return true
+ default:
+ return false
+ }
+}
+
+func (s *server) handleRegister(w http.ResponseWriter, r *http.Request) {
+ user := r.Context().Value(contextKeyUser).(*realmUser)
+ id := chi.URLParam(r, "id")
+ var req struct {
+ Addresses []string `json:"addresses"`
+ }
+ err := render.DecodeJSON(r.Body, &req)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "invalid json"})
+ return
+ }
+ err = validateAddresses(req.Addresses)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ s.access.Lock()
+ if _, exists := s.realms[id]; exists {
+ s.access.Unlock()
+ render.Status(r, http.StatusConflict)
+ render.JSON(w, r, render.M{"error": "realm_taken", "message": "realm already registered"})
+ return
+ }
+ if user.maxRealms > 0 && s.userCounts[user.name] >= user.maxRealms {
+ s.access.Unlock()
+ render.Status(r, http.StatusTooManyRequests)
+ render.JSON(w, r, render.M{"error": "realm_limit_reached", "message": "per-user realm limit reached"})
+ return
+ }
+ var b [16]byte
+ _, err = rand.Read(b[:])
+ if err != nil {
+ s.access.Unlock()
+ render.Status(r, http.StatusInternalServerError)
+ render.JSON(w, r, render.M{"error": "internal", "message": "entropy failure"})
+ return
+ }
+ sess := &realmSession{
+ id: hex.EncodeToString(b[:]),
+ realmID: id,
+ username: user.name,
+ addresses: append([]string(nil), req.Addresses...),
+ expires: time.Now().Add(sessionTTL),
+ events: make(chan realmEvent, eventChannelSize),
+ done: make(chan struct{}),
+ pending: make(map[string]chan punchResponsePayload),
+ }
+ s.realms[id] = sess
+ s.sessions[sess.id] = sess
+ s.userCounts[user.name]++
+ sess.timer = time.AfterFunc(sessionTTL, func() {
+ if s.removeExpiredSession(sess) {
+ s.logger.Debug("[", sess.username, "] session expired realm=", sess.realmID)
+ }
+ })
+ s.access.Unlock()
+ s.logger.InfoContext(r.Context(), "[", user.name, "] registered realm=", id)
+ render.JSON(w, r, render.M{
+ "session_id": sess.id,
+ "ttl": int(sessionTTL.Seconds()),
+ })
+}
+
+func (s *server) handleDeregister(w http.ResponseWriter, r *http.Request) {
+ sess := r.Context().Value(contextKeySession).(*realmSession)
+ s.logger.InfoContext(r.Context(), "[", sess.username, "] deregistered realm=", sess.realmID)
+ s.removeSession(sess)
+ render.NoContent(w, r)
+}
+
+func (s *server) handleHeartbeat(w http.ResponseWriter, r *http.Request) {
+ sess := r.Context().Value(contextKeySession).(*realmSession)
+ var req struct {
+ Addresses []string `json:"addresses"`
+ }
+ err := render.DecodeJSON(r.Body, &req)
+ if err != nil && !errors.Is(err, io.EOF) {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "invalid json"})
+ return
+ }
+ if req.Addresses != nil {
+ err = validateAddresses(req.Addresses)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ }
+ s.access.Lock()
+ sess.expires = time.Now().Add(sessionTTL)
+ if req.Addresses != nil {
+ sess.addresses = append([]string(nil), req.Addresses...)
+ }
+ sess.timer.Reset(sessionTTL)
+ s.access.Unlock()
+ s.logger.DebugContext(r.Context(), "[", sess.username, "] heartbeat realm=", sess.realmID)
+ s.sendEvent(sess, realmEvent{kind: "heartbeat_ack", data: render.M{"ttl": int(sessionTTL.Seconds())}})
+ render.JSON(w, r, render.M{"ttl": int(sessionTTL.Seconds())})
+}
+
+func (s *server) handleEvents(w http.ResponseWriter, r *http.Request) {
+ sess := r.Context().Value(contextKeySession).(*realmSession)
+ flusher, supportsFlusher := w.(http.Flusher)
+ if !supportsFlusher {
+ render.Status(r, http.StatusInternalServerError)
+ render.JSON(w, r, render.M{"error": "internal", "message": "streaming unsupported"})
+ return
+ }
+ w.Header().Set("Content-Type", "text/event-stream")
+ w.Header().Set("Cache-Control", "no-cache")
+ w.Header().Set("Connection", "keep-alive")
+ w.WriteHeader(http.StatusOK)
+ flusher.Flush()
+ ctx := r.Context()
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case ev, open := <-sess.events:
+ if !open {
+ return
+ }
+ data, _ := json.Marshal(ev.data)
+ fmt.Fprintf(w, "event: %s\ndata: %s\n\n", ev.kind, data)
+ flusher.Flush()
+ }
+ }
+}
+
+func (s *server) handleConnect(w http.ResponseWriter, r *http.Request) {
+ user := r.Context().Value(contextKeyUser).(*realmUser)
+ id := chi.URLParam(r, "id")
+ var req struct {
+ Addresses []string `json:"addresses"`
+ Nonce string `json:"nonce"`
+ Obfs string `json:"obfs"`
+ }
+ err := render.DecodeJSON(r.Body, &req)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "invalid json"})
+ return
+ }
+ err = validateAddresses(req.Addresses)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ err = validateHexField("nonce", req.Nonce, nonceHexLength)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ err = validateHexField("obfs", req.Obfs, obfsHexLength)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ s.access.Lock()
+ // Any authenticated realm user may connect to a registered realm. The user name
+ // is for logging and per-user registration quota, not an ownership boundary here.
+ sess := s.realms[id]
+ if sess == nil || sess.closed || time.Now().After(sess.expires) {
+ s.access.Unlock()
+ render.Status(r, http.StatusNotFound)
+ render.JSON(w, r, render.M{"error": "realm_not_found", "message": "realm not registered"})
+ return
+ }
+ serverAddresses := append([]string(nil), sess.addresses...)
+ s.access.Unlock()
+
+ respCh, ready := s.registerPending(sess, req.Nonce)
+ if !ready {
+ render.Status(r, http.StatusServiceUnavailable)
+ render.JSON(w, r, render.M{"error": "rate_limited", "message": "too many in-flight connect attempts"})
+ return
+ }
+ defer s.cancelPending(sess, req.Nonce)
+
+ if !s.sendEvent(sess, realmEvent{kind: "punch", data: punchEvent{Addresses: req.Addresses, Nonce: req.Nonce, Obfs: req.Obfs}}) {
+ render.Status(r, http.StatusServiceUnavailable)
+ render.JSON(w, r, render.M{"error": "rate_limited", "message": "server event buffer full"})
+ return
+ }
+ s.logger.DebugContext(r.Context(), "[", user.name, "] connect realm=", id)
+
+ timer := time.NewTimer(connectResponseTimeout)
+ defer timer.Stop()
+ select {
+ case payload, open := <-respCh:
+ if !open {
+ render.Status(r, http.StatusNotFound)
+ render.JSON(w, r, render.M{"error": "realm_not_found", "message": "realm not registered"})
+ return
+ }
+ if len(payload.addresses) > 0 {
+ serverAddresses = payload.addresses
+ }
+ case <-timer.C:
+ case <-sess.done:
+ render.Status(r, http.StatusNotFound)
+ render.JSON(w, r, render.M{"error": "realm_not_found", "message": "realm not registered"})
+ return
+ case <-r.Context().Done():
+ return
+ }
+ render.JSON(w, r, render.M{
+ "addresses": serverAddresses,
+ "nonce": req.Nonce,
+ "obfs": req.Obfs,
+ })
+}
+
+func (s *server) handleConnectResponse(w http.ResponseWriter, r *http.Request) {
+ sess := r.Context().Value(contextKeySession).(*realmSession)
+ nonce := chi.URLParam(r, "nonce")
+ err := validateHexField("nonce", nonce, nonceHexLength)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ var req struct {
+ Addresses []string `json:"addresses"`
+ }
+ err = render.DecodeJSON(r.Body, &req)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": "invalid json"})
+ return
+ }
+ err = validateAddresses(req.Addresses)
+ if err != nil {
+ render.Status(r, http.StatusBadRequest)
+ render.JSON(w, r, render.M{"error": "bad_request", "message": err.Error()})
+ return
+ }
+ delivered := s.deliverPending(sess, nonce, punchResponsePayload{addresses: append([]string(nil), req.Addresses...)})
+ if !delivered {
+ render.Status(r, http.StatusNotFound)
+ render.JSON(w, r, render.M{"error": "attempt_not_found", "message": "no pending attempt for nonce"})
+ return
+ }
+ s.logger.DebugContext(r.Context(), "[", sess.username, "] connect-response realm=", sess.realmID)
+ render.NoContent(w, r)
+}
+
+func validateAddresses(addresses []string) error {
+ if len(addresses) == 0 {
+ return E.New("at least one address required")
+ }
+ if len(addresses) > maxAddresses {
+ return E.New("too many addresses (max ", maxAddresses, ")")
+ }
+ for _, address := range addresses {
+ _, err := netip.ParseAddrPort(address)
+ if err != nil {
+ return E.New("invalid address: ", address)
+ }
+ }
+ return nil
+}
+
+func validateHexField(name, value string, length int) error {
+ if len(value) != length {
+ return E.New(name, " must be ", length, " hex characters")
+ }
+ _, err := hex.DecodeString(value)
+ if err != nil {
+ return E.New(name, " must be valid hex")
+ }
+ return nil
+}
diff --git a/protocol/masque/config.go b/protocol/masque/config.go
new file mode 100644
index 0000000000..11aa52daf7
--- /dev/null
+++ b/protocol/masque/config.go
@@ -0,0 +1,89 @@
+package masque
+
+import (
+ "crypto/ecdsa"
+ "crypto/x509"
+ "encoding/base64"
+ "encoding/pem"
+ "fmt"
+ "net"
+)
+
+type Config struct {
+ PrivateKey string `json:"private_key"` // Base64-encoded ECDSA private key
+ EndpointV4 string `json:"endpoint_v4"` // IPv4 address of the endpoint
+ EndpointV6 string `json:"endpoint_v6"` // IPv6 address of the endpoint
+ EndpointH2V4 string `json:"endpoint_h2_v4"` // IPv4 address used in HTTP/2 mode
+ EndpointH2V6 string `json:"endpoint_h2_v6"` // IPv6 address used in HTTP/2 mode
+ EndpointPubKey string `json:"endpoint_pub_key"` // PEM-encoded ECDSA public key of the endpoint to verify against
+ License string `json:"license"` // Application license key
+ ID string `json:"id"` // Device unique identifier
+ AccessToken string `json:"access_token"` // Authentication token for API access
+ IPv4 string `json:"ipv4"` // Assigned IPv4 address
+ IPv6 string `json:"ipv6"` // Assigned IPv6 address
+}
+
+func (c *Config) GetEcPrivateKey() (*ecdsa.PrivateKey, error) {
+ privKeyB64, err := base64.StdEncoding.DecodeString(c.PrivateKey)
+ if err != nil {
+ return nil, fmt.Errorf("failed to decode private key: %v", err)
+ }
+ privKey, err := x509.ParseECPrivateKey(privKeyB64)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse private key: %v", err)
+ }
+ return privKey, nil
+}
+
+func (c *Config) GetEcEndpointPublicKey() (*ecdsa.PublicKey, error) {
+ endpointPubKeyB64, _ := pem.Decode([]byte(c.EndpointPubKey))
+ if endpointPubKeyB64 == nil {
+ return nil, fmt.Errorf("failed to decode endpoint public key")
+ }
+
+ pubKey, err := x509.ParsePKIXPublicKey(endpointPubKeyB64.Bytes)
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse public key: %v", err)
+ }
+
+ ecPubKey, ok := pubKey.(*ecdsa.PublicKey)
+ if !ok {
+ return nil, fmt.Errorf("failed to assert public key as ECDSA")
+ }
+
+ return ecPubKey, nil
+}
+
+func (c *Config) SelectEndpointFromConfig(useHTTP2 bool, useIPv6 bool, port int) (net.Addr, error) {
+ if useHTTP2 {
+ if useIPv6 {
+ if c.EndpointH2V6 == "" {
+ return nil, fmt.Errorf("--http2 with --ipv6 requires config endpoint_h2_v6 to be set")
+ }
+ ip := net.ParseIP(c.EndpointH2V6)
+ if ip == nil {
+ return nil, fmt.Errorf("invalid endpoint_h2_v6 value %q", c.EndpointH2V6)
+ }
+
+ return &net.TCPAddr{IP: ip, Port: port}, nil
+ }
+ v4 := c.EndpointH2V4
+ ip := net.ParseIP(v4)
+ if ip == nil {
+ return nil, fmt.Errorf("invalid endpoint_h2_v4 value %q")
+ }
+ return &net.TCPAddr{IP: ip, Port: port}, nil
+ }
+ if useIPv6 {
+ ip := net.ParseIP(c.EndpointV6)
+ if ip == nil {
+ return nil, fmt.Errorf("invalid endpoint_v6 value %q", c.EndpointV6)
+ }
+ return &net.UDPAddr{IP: ip, Port: port}, nil
+ }
+ ip := net.ParseIP(c.EndpointV4)
+ if ip == nil {
+ return nil, fmt.Errorf("invalid endpoint_v4 value %q", c.EndpointV4)
+ }
+ return &net.UDPAddr{IP: ip, Port: port}, nil
+}
diff --git a/protocol/masque/outbound.go b/protocol/masque/outbound.go
new file mode 100644
index 0000000000..41e3a1008a
--- /dev/null
+++ b/protocol/masque/outbound.go
@@ -0,0 +1,300 @@
+package masque
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "net"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/cloudflare"
+ "github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/transport/masque"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.MASQUEOutboundOptions](registry, C.TypeMASQUE, NewOutbound)
+}
+
+type Outbound struct {
+ outbound.Adapter
+ ctx context.Context
+ dnsRouter adapter.DNSRouter
+ logger logger.ContextLogger
+ options option.MASQUEOutboundOptions
+ tunnel *masque.Tunnel
+ startHandler func()
+
+ await chan struct{}
+}
+
+func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.MASQUEOutboundOptions) (adapter.Outbound, error) {
+ outbound := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeMASQUE, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, options.DialerOptions),
+ ctx: ctx,
+ dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
+ logger: logger,
+ options: options,
+ await: make(chan struct{}),
+ }
+ outbound.startHandler = func() {
+ defer close(outbound.await)
+ cacheFile := service.FromContext[adapter.CacheFile](ctx)
+ var appConfig *Config
+ var err error
+ if !options.Profile.Recreate && cacheFile != nil && cacheFile.StoreMASQUEConfig() {
+ savedProfile := cacheFile.LoadBinary(tag)
+ if savedProfile != nil {
+ if err = json.Unmarshal(savedProfile.Content, &appConfig); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ }
+ }
+ if appConfig == nil {
+ appConfig, err = outbound.createConfig()
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ if cacheFile != nil && cacheFile.StoreMASQUEConfig() {
+ content, err := json.Marshal(appConfig)
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ cacheFile.SaveBinary(tag, &adapter.SavedBinary{
+ LastUpdated: time.Now(),
+ Content: content,
+ LastEtag: "",
+ })
+ }
+ }
+ privKey, err := appConfig.GetEcPrivateKey()
+ if err != nil {
+ logger.ErrorContext(ctx, E.New("failed to get private key: ", err))
+ return
+ }
+ peerPubKey, err := appConfig.GetEcEndpointPublicKey()
+ if err != nil {
+ logger.ErrorContext(ctx, E.New("failed to get public key: ", err))
+ return
+ }
+ cert, err := masque.GenerateCert(privKey, &privKey.PublicKey)
+ if err != nil {
+ logger.ErrorContext(ctx, E.New("failed to generate cert: ", err))
+ return
+ }
+ tlsConfig, err := tls.NewMASQUEClient(ctx, logger, "consumer-masque.cloudflareclient.com", cert, privKey, peerPubKey, options.MASQUEOutboundTLSOptions)
+ if err != nil {
+ logger.ErrorContext(ctx, E.New("failed to prepare TLS config: ", err))
+ return
+ }
+ endpoint, err := appConfig.SelectEndpointFromConfig(options.UseHTTP2, options.UseIPv6, 443)
+ if err != nil {
+ logger.ErrorContext(ctx, E.New("failed to select endpoint: ", err))
+ return
+ }
+ var udpTimeout time.Duration
+ if options.UDPTimeout != 0 {
+ udpTimeout = time.Duration(options.UDPTimeout)
+ } else {
+ udpTimeout = C.UDPTimeout
+ }
+ var udpKeepalivePeriod time.Duration
+ if options.UDPKeepalivePeriod != 0 {
+ udpKeepalivePeriod = time.Duration(options.UDPKeepalivePeriod)
+ } else {
+ udpKeepalivePeriod = time.Second * 30
+ }
+ outboundDialer, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: false,
+ ResolverOnDetour: true,
+ })
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ tunnel, err := masque.NewTunnel(
+ ctx,
+ logger,
+ masque.TunnelOptions{
+ Dialer: outboundDialer,
+ Address: []netip.Prefix{
+ netip.MustParsePrefix(appConfig.IPv4 + "/32"),
+ netip.MustParsePrefix(appConfig.IPv6 + "/128"),
+ },
+ Endpoint: endpoint,
+ TLSConfig: tlsConfig,
+ UseHTTP2: options.UseHTTP2,
+ UDPTimeout: udpTimeout,
+ UDPKeepalivePeriod: udpKeepalivePeriod,
+ UDPInitialPacketSize: options.UDPInitialPacketSize,
+ ReconnectDelay: options.ReconnectDelay.Build(),
+ })
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ outbound.tunnel = tunnel
+ if err = outbound.tunnel.Start(false); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ if err = outbound.tunnel.Start(true); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ }
+ return outbound, nil
+}
+
+func (w *Outbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStatePostStart {
+ return nil
+ }
+ go w.startHandler()
+ return nil
+}
+
+func (w *Outbound) Close() error {
+ if err := w.isTunnelInitialized(w.ctx); err != nil {
+ return err
+ }
+ return w.tunnel.Close()
+}
+
+func (w *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if err := w.isTunnelInitialized(ctx); err != nil {
+ return nil, err
+ }
+ switch network {
+ case N.NetworkTCP:
+ w.logger.InfoContext(ctx, "outbound connection to ", destination)
+ case N.NetworkUDP:
+ w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ }
+ if destination.IsDomain() {
+ destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return N.DialSerial(ctx, w.tunnel, network, destination, destinationAddresses)
+ } else if !destination.Addr.IsValid() {
+ return nil, E.New("invalid destination: ", destination)
+ }
+ return w.tunnel.DialContext(ctx, network, destination)
+}
+
+func (w *Outbound) ListenPacketWithDestination(ctx context.Context, destination M.Socksaddr) (net.PacketConn, netip.Addr, error) {
+ if err := w.isTunnelInitialized(ctx); err != nil {
+ return nil, netip.Addr{}, err
+ }
+ w.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ if destination.IsDomain() {
+ destinationAddresses, err := w.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, netip.Addr{}, err
+ }
+ return N.ListenSerial(ctx, w.tunnel, destination, destinationAddresses)
+ }
+ packetConn, err := w.tunnel.ListenPacket(ctx, destination)
+ if err != nil {
+ return nil, netip.Addr{}, err
+ }
+ if destination.IsIP() {
+ return packetConn, destination.Addr, nil
+ }
+ return packetConn, netip.Addr{}, nil
+}
+
+func (w *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ packetConn, destinationAddress, err := w.ListenPacketWithDestination(ctx, destination)
+ if err != nil {
+ return nil, err
+ }
+ if destinationAddress.IsValid() && destination != M.SocksaddrFrom(destinationAddress, destination.Port) {
+ return bufio.NewNATPacketConn(bufio.NewPacketConn(packetConn), M.SocksaddrFrom(destinationAddress, destination.Port), destination), nil
+ }
+ return packetConn, nil
+}
+
+func (w *Outbound) isTunnelInitialized(ctx context.Context) error {
+ select {
+ case <-w.await:
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ if w.tunnel == nil {
+ return E.New("tunnel not initialized")
+ }
+ return nil
+}
+
+func (w *Outbound) createConfig() (*Config, error) {
+ opts := make([]cloudflare.CloudflareApiOption, 0, 1)
+ if w.options.Profile.Detour != "" {
+ detour, ok := service.FromContext[adapter.OutboundManager](w.ctx).Outbound(w.options.Profile.Detour)
+ if !ok {
+ return nil, E.New("outbound detour not found: ", w.options.Profile.Detour)
+ }
+ opts = append(opts, cloudflare.WithDialContext(func(ctx context.Context, network, addr string) (net.Conn, error) {
+ return detour.DialContext(ctx, network, M.ParseSocksaddr(addr))
+ }))
+ }
+ api := cloudflare.NewCloudflareApi(opts...)
+ var profile *cloudflare.CloudflareProfile
+ var err error
+ if w.options.Profile.AuthToken != "" && w.options.Profile.ID != "" {
+ profile, err = api.GetProfile4471(w.ctx, w.options.Profile.AuthToken, w.options.Profile.ID)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ wgPrivateKey, err := wgtypes.GeneratePrivateKey()
+ if err != nil {
+ return nil, err
+ }
+ profile, err = api.CreateProfile(w.ctx, wgPrivateKey.PublicKey().String())
+ if err != nil {
+ return nil, err
+ }
+ }
+ privateKey, publicKey, err := masque.GenerateEcKeyPair()
+ if err != nil {
+ return nil, E.New("failed to generate key pair: ", err)
+ }
+ updatedProfile, err := api.EnrollKey(w.ctx, profile.Token, profile.ID, cloudflare.KeyTypeMasque, cloudflare.TunTypeMasque, base64.StdEncoding.EncodeToString(publicKey))
+ if err != nil {
+ return nil, err
+ }
+ return &Config{
+ PrivateKey: base64.StdEncoding.EncodeToString(privateKey),
+ EndpointV4: updatedProfile.Config.Peers[0].Endpoint.V4[:len(updatedProfile.Config.Peers[0].Endpoint.V4)-2],
+ EndpointV6: updatedProfile.Config.Peers[0].Endpoint.V6[1 : len(updatedProfile.Config.Peers[0].Endpoint.V6)-3],
+ EndpointH2V4: cloudflare.DefaultEndpointH2V4,
+ EndpointH2V6: cloudflare.DefaultEndpointH2V6,
+ EndpointPubKey: updatedProfile.Config.Peers[0].PublicKey,
+ License: updatedProfile.Account.License,
+ ID: updatedProfile.ID,
+ AccessToken: profile.Token,
+ IPv4: updatedProfile.Config.Interface.Addresses.V4,
+ IPv6: updatedProfile.Config.Interface.Addresses.V6,
+ }, nil
+}
diff --git a/protocol/mieru/common.go b/protocol/mieru/common.go
new file mode 100644
index 0000000000..2aaee81191
--- /dev/null
+++ b/protocol/mieru/common.go
@@ -0,0 +1,94 @@
+package mieru
+
+import (
+ "fmt"
+ "strings"
+
+ mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
+ "github.com/sagernet/sing-box/option"
+)
+
+func validateMieruTransport(transport []option.MieruPortBinding) error {
+
+ for _, pr := range transport {
+ if getTransportProtocol(pr.Protocol) == nil {
+ return fmt.Errorf("transport must be TCP or UDP")
+ }
+ if pr.Port != 0 && pr.PortRange != "" {
+ return fmt.Errorf("invalid format: both port and port_range should not be set")
+ }
+ if pr.Port == 0 && pr.PortRange == "" {
+ return fmt.Errorf("invalid format: either port or port_range must be set")
+ }
+ if pr.Port != 0 {
+ continue
+ }
+ begin, end, err := beginAndEndPortFromPortRange(pr.PortRange)
+ if err != nil {
+ return fmt.Errorf("invalid server_ports format")
+ }
+
+ if begin < 1 || begin > 65535 {
+ return fmt.Errorf("begin port must be between 1 and 65535")
+ }
+ if end < 1 || end > 65535 {
+ return fmt.Errorf("end port must be between 1 and 65535")
+ }
+ if begin > end {
+ return fmt.Errorf("begin port must be less than or equal to end port")
+ }
+
+ }
+ return nil
+}
+
+func beginAndEndPortFromPortRange(portRange string) (int, int, error) {
+ var begin, end int
+
+ _, err := fmt.Sscanf(portRange, "%d-%d", &begin, &end)
+ return begin, end, err
+
+}
+
+func getTransportProtocol(transport string) *mierupb.TransportProtocol {
+ switch strings.ToUpper(transport) {
+ case "TCP":
+ return mierupb.TransportProtocol_TCP.Enum()
+ case "UDP":
+ return mierupb.TransportProtocol_UDP.Enum()
+ default:
+ return nil
+ }
+}
+
+func getHandshakeMode(handshakeMode string) *mierupb.HandshakeMode {
+ switch strings.ToUpper(handshakeMode) {
+ case "", "DEFAULT", "HANDSHAKE_DEFAULT":
+ return mierupb.HandshakeMode_HANDSHAKE_DEFAULT.Enum()
+ case "NO_WAIT", "NOWAIT", "HANDSHAKE_NO_WAIT":
+ return mierupb.HandshakeMode_HANDSHAKE_NO_WAIT.Enum()
+ case "STANDARD", "HANDSHAKE_STANDARD":
+ return mierupb.HandshakeMode_HANDSHAKE_STANDARD.Enum()
+ default:
+ return nil
+ }
+}
+
+func getMultiplexingLevel(multiplexingLevel string) *mierupb.MultiplexingLevel {
+ switch strings.ToUpper(multiplexingLevel) {
+ case "", "DEFAULT", "MULTIPLEXING_DEFAULT":
+ return mierupb.MultiplexingLevel_MULTIPLEXING_DEFAULT.Enum()
+
+ case "LOW", "MULTIPLEXING_LOW":
+ return mierupb.MultiplexingLevel_MULTIPLEXING_LOW.Enum()
+
+ case "MEDIUM", "MULTIPLEXING_MEDIUM", "MIDDLE", "MULTIPLEXING_MIDDLE":
+ return mierupb.MultiplexingLevel_MULTIPLEXING_MIDDLE.Enum()
+
+ case "HIGH", "MULTIPLEXING_HIGH":
+ return mierupb.MultiplexingLevel_MULTIPLEXING_HIGH.Enum()
+
+ default:
+ return nil
+ }
+}
diff --git a/protocol/mieru/inbound.go b/protocol/mieru/inbound.go
new file mode 100644
index 0000000000..b0f6590e10
--- /dev/null
+++ b/protocol/mieru/inbound.go
@@ -0,0 +1,319 @@
+package mieru
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "net"
+ "net/netip"
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ "github.com/sagernet/sing-box/common/listener"
+ "github.com/sagernet/sing-box/common/uot"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ mierucommon "github.com/enfein/mieru/v3/apis/common"
+ mieruconstant "github.com/enfein/mieru/v3/apis/constant"
+ mierumodel "github.com/enfein/mieru/v3/apis/model"
+ mieruserver "github.com/enfein/mieru/v3/apis/server"
+ mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
+ "google.golang.org/protobuf/proto"
+)
+
+func RegisterInbound(registry *inbound.Registry) {
+ inbound.Register[option.MieruInboundOptions](registry, C.TypeMieru, NewInbound)
+}
+
+type Inbound struct {
+ inbound.Adapter
+ ctx context.Context
+ router adapter.ConnectionRouterEx
+ logger log.ContextLogger
+ listener *listener.Listener
+ server mieruserver.Server
+ userNames []string
+
+ mu sync.Mutex
+}
+
+func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.MieruInboundOptions) (adapter.Inbound, error) {
+ config, userNames, err := buildMieruServerConfig(ctx, options)
+ if err != nil {
+ return nil, fmt.Errorf("failed to build mieru server config: %w", err)
+ }
+
+ s := mieruserver.NewServer()
+ if err := s.Store(config); err != nil {
+ return nil, fmt.Errorf("failed to store mieru server config: %w", err)
+ }
+
+ inboundInstance := &Inbound{
+ Adapter: inbound.NewAdapter(C.TypeMieru, tag),
+ ctx: ctx,
+ router: uot.NewRouter(router, logger),
+ logger: logger,
+ server: s,
+ userNames: userNames,
+ }
+ inboundInstance.listener = listener.New(listener.Options{
+ Context: ctx,
+ Logger: logger,
+ Network: options.Network.Build(),
+ Listen: options.ListenOptions,
+ })
+
+ return inboundInstance, nil
+}
+
+func (h *Inbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+
+ h.mu.Lock()
+ defer h.mu.Unlock()
+
+ if err := h.server.Start(); err != nil {
+ return fmt.Errorf("failed to start mieru server: %w", err)
+ }
+
+ h.logger.Info("mieru server is started")
+ go h.acceptLoop()
+ return nil
+}
+
+func (h *Inbound) Close() error {
+ h.mu.Lock()
+ defer h.mu.Unlock()
+
+ if h.server.IsRunning() {
+ return h.server.Stop()
+ }
+ return nil
+}
+
+func (h *Inbound) acceptLoop() {
+ for {
+ conn, request, err := h.server.Accept()
+ if err != nil {
+ if !h.server.IsRunning() {
+ return
+ }
+ h.logger.Debug("failed to accept mieru connection: ", err)
+ continue
+ }
+ go h.handleConnection(conn, request)
+ }
+}
+
+func (h *Inbound) handleConnection(conn net.Conn, request *mierumodel.Request) {
+ ctx := log.ContextWithNewID(h.ctx)
+
+ // Send fake SOCKS5 response back to proxy client.
+ resp := &mierumodel.Response{
+ Reply: mieruconstant.Socks5ReplySuccess,
+ BindAddr: mierumodel.AddrSpec{
+ IP: net.IPv4zero,
+ Port: 0,
+ },
+ }
+ if err := resp.WriteToSocks5(conn); err != nil {
+ conn.Close()
+ h.logger.DebugContext(ctx, "failed to write mieru response: ", err)
+ return
+ }
+
+ // Build metadata.
+ var metadata adapter.InboundContext
+ metadata.Inbound = h.Tag()
+ metadata.InboundType = h.Type()
+ //nolint:staticcheck
+ metadata.InboundDetour = h.listener.ListenOptions().Detour
+ //nolint:staticcheck
+ metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
+
+ // Parse source address.
+ if remoteAddr := conn.RemoteAddr(); remoteAddr != nil {
+ metadata.Source = M.SocksaddrFromNet(remoteAddr)
+ }
+
+ // Parse destination from request.
+ if request.DstAddr.FQDN != "" {
+ metadata.Destination = M.Socksaddr{
+ Fqdn: request.DstAddr.FQDN,
+ Port: uint16(request.DstAddr.Port),
+ }
+ } else if request.DstAddr.IP != nil {
+ addr, _ := netip.AddrFromSlice(request.DstAddr.IP)
+ metadata.Destination = M.Socksaddr{
+ Addr: addr.Unmap(),
+ Port: uint16(request.DstAddr.Port),
+ }
+ }
+
+ // Get username from connection.
+ if userCtx, ok := conn.(mierucommon.UserContext); ok {
+ metadata.User = userCtx.UserName()
+ }
+
+ // Handle request.
+ switch request.Command {
+ case mieruconstant.Socks5ConnectCmd:
+ h.logger.InfoContext(ctx, "inbound TCP connection from ", metadata.Source, " to ", metadata.Destination)
+ if metadata.User != "" {
+ h.logger.InfoContext(ctx, "[", metadata.User, "] inbound TCP connection")
+ }
+ h.router.RouteConnectionEx(ctx, conn, metadata, nil)
+ case mieruconstant.Socks5UDPAssociateCmd:
+ h.logger.InfoContext(ctx, "inbound UDP connection from ", metadata.Source, " to ", metadata.Destination)
+ if metadata.User != "" {
+ h.logger.InfoContext(ctx, "[", metadata.User, "] inbound UDP connection")
+ }
+ h.handleUDP(ctx, conn, metadata)
+ default:
+ conn.Close()
+ h.logger.WarnContext(ctx, "unsupported mieru command: ", request.Command)
+ }
+}
+
+func (h *Inbound) handleUDP(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) {
+ pc := mierucommon.NewPacketOverStreamTunnel(conn)
+ packetConn := &mieruPacketConn{
+ PacketConn: pc,
+ destination: metadata.Destination,
+ }
+ h.router.RoutePacketConnectionEx(ctx, packetConn, metadata, nil)
+}
+
+// mieruPacketConn wraps mieru's PacketConn to implement N.PacketConn
+type mieruPacketConn struct {
+ net.PacketConn
+ destination M.Socksaddr
+}
+
+var _ N.PacketConn = (*mieruPacketConn)(nil)
+
+// ReadPacket parses the SOCKS5 UDP header and returns the destination address.
+func (c *mieruPacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error) {
+ n, _, err := c.PacketConn.ReadFrom(buffer.FreeBytes())
+ if err != nil {
+ return M.Socksaddr{}, err
+ }
+ buffer.Truncate(n)
+ if buffer.Len() < 3 {
+ return M.Socksaddr{}, io.ErrShortBuffer
+ }
+
+ // Skip RSV (2 bytes) and FRAG (1 byte).
+ buffer.Advance(3)
+
+ var addr mierumodel.AddrSpec
+ if err := addr.ReadFromSocks5(buffer); err != nil {
+ return M.Socksaddr{}, err
+ }
+ if addr.FQDN != "" {
+ destination = M.Socksaddr{
+ Fqdn: addr.FQDN,
+ Port: uint16(addr.Port),
+ }
+ } else if addr.IP != nil {
+ netAddr, _ := netip.AddrFromSlice(addr.IP)
+ destination = M.Socksaddr{
+ Addr: netAddr.Unmap(),
+ Port: uint16(addr.Port),
+ }
+ }
+ return destination, nil
+}
+
+// WritePacket writes the SOCKS5 UDP header and the payload.
+func (c *mieruPacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
+ header := buf.NewSize(3 + M.MaxSocksaddrLength)
+ defer header.Release()
+
+ // RSV (2 bytes) + FRAG (1 byte)
+ common.Must(header.WriteZeroN(3))
+
+ var addr mierumodel.AddrSpec
+ if destination.IsFqdn() {
+ addr.FQDN = destination.Fqdn
+ } else {
+ addr.IP = destination.Addr.AsSlice()
+ }
+ addr.Port = int(destination.Port)
+ if err := addr.WriteToSocks5(header); err != nil {
+ return err
+ }
+
+ packet := buf.NewSize(header.Len() + buffer.Len())
+ defer packet.Release()
+ common.Must1(packet.Write(header.Bytes()))
+ common.Must1(packet.Write(buffer.Bytes()))
+ _, err := c.PacketConn.WriteTo(packet.Bytes(), nil)
+ return err
+}
+
+func buildMieruServerConfig(_ context.Context, options option.MieruInboundOptions) (*mieruserver.ServerConfig, []string, error) {
+ if err := validateMieruInboundOptions(options); err != nil {
+ return nil, nil, fmt.Errorf("failed to validate mieru options: %w", err)
+ }
+
+ portBindings := []*mierupb.PortBinding{}
+
+ for _, pr := range options.PortBindings {
+ intport := int32(pr.Port)
+ portBindings = append(portBindings, &mierupb.PortBinding{
+ PortRange: &pr.PortRange,
+ Port: &intport,
+ Protocol: getTransportProtocol(pr.Protocol),
+ })
+ }
+
+ var users []*mierupb.User
+ var userNames []string
+ for _, user := range options.Users {
+ users = append(users, &mierupb.User{
+ Name: proto.String(user.Name),
+ Password: proto.String(user.Password),
+ })
+ userNames = append(userNames, user.Name)
+ }
+
+ return &mieruserver.ServerConfig{
+ Config: &mierupb.ServerConfig{
+ PortBindings: portBindings,
+ Users: users,
+ },
+ }, userNames, nil
+}
+
+func validateMieruInboundOptions(options option.MieruInboundOptions) error {
+ if options.ListenPort == 0 && len(options.PortBindings) == 0 {
+ return fmt.Errorf("either server_port or transport must be set")
+ }
+ if options.ListenPort != 0 && (len(options.PortBindings) != 1 || options.PortBindings[0].Port != options.ListenPort) {
+ return fmt.Errorf("Transport of Server Port is not defined!")
+ }
+ if len(options.Users) == 0 {
+ return E.New("users is empty")
+ }
+ for _, user := range options.Users {
+ if user.Name == "" {
+ return E.New("username is empty")
+ }
+ if user.Password == "" {
+ return E.New("password is empty")
+ }
+ }
+
+ return validateMieruTransport(options.PortBindings)
+}
diff --git a/protocol/mieru/outbound.go b/protocol/mieru/outbound.go
new file mode 100644
index 0000000000..927a01ab0d
--- /dev/null
+++ b/protocol/mieru/outbound.go
@@ -0,0 +1,236 @@
+package mieru
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "os"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+
+ mieruclient "github.com/enfein/mieru/v3/apis/client"
+ mierucommon "github.com/enfein/mieru/v3/apis/common"
+ mierumodel "github.com/enfein/mieru/v3/apis/model"
+ mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
+ "google.golang.org/protobuf/proto"
+)
+
+type Outbound struct {
+ outbound.Adapter
+ dialer N.Dialer
+ logger log.ContextLogger
+ client mieruclient.Client
+}
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register(registry, C.TypeMieru, NewOutbound)
+}
+
+func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.MieruOutboundOptions) (adapter.Outbound, error) {
+ outboundDialer, err := dialer.New(ctx, options.DialerOptions, M.IsDomainName(options.Server))
+ if err != nil {
+ return nil, err
+ }
+
+ config, err := buildMieruClientConfig(options, mieruDialer{dialer: outboundDialer})
+ if err != nil {
+ return nil, fmt.Errorf("failed to build mieru client config: %w", err)
+ }
+ c := mieruclient.NewClient()
+ if err := c.Store(config); err != nil {
+ return nil, fmt.Errorf("failed to store mieru client config: %w", err)
+ }
+ if err := c.Start(); err != nil {
+ return nil, fmt.Errorf("failed to start mieru client: %w", err)
+ }
+ logger.InfoContext(ctx, "mieru client is started")
+
+ return &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeMieru, tag, options.Network.Build(), options.DialerOptions),
+ dialer: outboundDialer,
+ logger: logger,
+ client: c,
+ }, nil
+}
+
+func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = o.Tag()
+ metadata.Destination = destination
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ o.logger.InfoContext(ctx, "outbound connection to ", destination)
+ d, err := socksAddrToNetAddrSpec(destination, "tcp")
+ if err != nil {
+ return nil, E.Cause(err, "failed to convert destination address")
+ }
+ return o.client.DialContext(ctx, d)
+ case N.NetworkUDP:
+ o.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
+ d, err := socksAddrToNetAddrSpec(destination, "udp")
+ if err != nil {
+ return nil, E.Cause(err, "failed to convert destination address")
+ }
+ streamConn, err := o.client.DialContext(ctx, d)
+ if err != nil {
+ return nil, err
+ }
+ return &streamer{
+ PacketConn: mierucommon.NewUDPAssociateWrapper(mierucommon.NewPacketOverStreamTunnel(streamConn)),
+ Remote: destination,
+ }, nil
+ default:
+ return nil, os.ErrInvalid
+ }
+}
+
+func (o *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = o.Tag()
+ metadata.Destination = destination
+ o.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
+ d, err := socksAddrToNetAddrSpec(destination, "udp")
+ if err != nil {
+ return nil, E.Cause(err, "failed to convert destination address")
+ }
+ streamConn, err := o.client.DialContext(ctx, d)
+ if err != nil {
+ return nil, err
+ }
+ return mierucommon.NewUDPAssociateWrapper(mierucommon.NewPacketOverStreamTunnel(streamConn)), nil
+}
+
+func (o *Outbound) Close() error {
+ return common.Close(o.client)
+}
+
+// mieruDialer is an adapter to mieru dialer interface.
+type mieruDialer struct {
+ dialer N.Dialer
+}
+
+func (md mieruDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
+ addr := M.ParseSocksaddr(address)
+ return md.dialer.DialContext(ctx, network, addr)
+}
+
+func (md mieruDialer) ListenPacket(ctx context.Context, network, laddr, raddr string) (net.PacketConn, error) {
+ addr := M.ParseSocksaddr(raddr)
+ return md.dialer.ListenPacket(ctx, addr)
+}
+
+var (
+ _ mierucommon.Dialer = (*mieruDialer)(nil)
+ _ mierucommon.PacketDialer = (*mieruDialer)(nil)
+)
+
+// streamer converts a net.PacketConn to a net.Conn.
+type streamer struct {
+ net.PacketConn
+ Remote net.Addr
+}
+
+var _ net.Conn = (*streamer)(nil)
+
+func (s *streamer) Read(b []byte) (n int, err error) {
+ n, _, err = s.PacketConn.ReadFrom(b)
+ return
+}
+
+func (s *streamer) Write(b []byte) (n int, err error) {
+ return s.WriteTo(b, s.Remote)
+}
+
+func (s *streamer) RemoteAddr() net.Addr {
+ return s.Remote
+}
+
+// socksAddrToNetAddrSpec converts a Socksaddr object to NetAddrSpec, and overrides the network.
+func socksAddrToNetAddrSpec(sa M.Socksaddr, network string) (mierumodel.NetAddrSpec, error) {
+ var nas mierumodel.NetAddrSpec
+ if err := nas.From(sa); err != nil {
+ return nas, err
+ }
+ nas.Net = network
+ return nas, nil
+}
+
+func buildMieruClientConfig(options option.MieruOutboundOptions, dialer mieruDialer) (*mieruclient.ClientConfig, error) {
+ if err := validateMieruOptions(options); err != nil {
+ return nil, fmt.Errorf("failed to validate mieru options: %w", err)
+ }
+
+ server := &mierupb.ServerEndpoint{}
+ for _, pr := range options.PortBindings {
+ intport := int32(pr.Port)
+
+ server.PortBindings = append(server.PortBindings, &mierupb.PortBinding{
+ PortRange: proto.String(pr.PortRange),
+ Port: &intport,
+ Protocol: getTransportProtocol(pr.Protocol),
+ })
+ }
+ if M.IsDomainName(options.Server) {
+ server.DomainName = proto.String(options.Server)
+ } else {
+ server.IpAddress = proto.String(options.Server)
+ }
+ config := &mieruclient.ClientConfig{
+ Profile: &mierupb.ClientProfile{
+ ProfileName: proto.String("sing-box"),
+ User: &mierupb.User{
+ Name: proto.String(options.UserName),
+ Password: proto.String(options.Password),
+ },
+ Servers: []*mierupb.ServerEndpoint{server},
+ HandshakeMode: getHandshakeMode(options.HandshakeMode),
+ Multiplexing: &mierupb.MultiplexingConfig{
+ Level: getMultiplexingLevel(options.Multiplexing),
+ },
+ },
+ Dialer: dialer,
+ PacketDialer: dialer,
+ DNSConfig: &mierucommon.ClientDNSConfig{
+ BypassDialerDNS: true,
+ },
+ }
+ if multiplexing, ok := mierupb.MultiplexingLevel_value[options.Multiplexing]; ok {
+ config.Profile.Multiplexing = &mierupb.MultiplexingConfig{
+ Level: mierupb.MultiplexingLevel(multiplexing).Enum(),
+ }
+ }
+ return config, nil
+}
+func validateMieruOptions(options option.MieruOutboundOptions) error {
+ if options.Server == "" {
+ return fmt.Errorf("server is empty")
+ }
+ if options.ServerPort == 0 && len(options.PortBindings) == 0 {
+ return fmt.Errorf("either server_port or transport must be set")
+ }
+ if options.ServerPort != 0 && (len(options.PortBindings) != 1 || options.PortBindings[0].Port != options.ServerPort) {
+ return fmt.Errorf("Transport of Server Port is not defined!")
+ }
+ if options.UserName == "" {
+ return fmt.Errorf("username is empty")
+ }
+ if options.Password == "" {
+ return fmt.Errorf("password is empty")
+ }
+ if getMultiplexingLevel(options.Multiplexing) == nil {
+ return fmt.Errorf("invalid multiplexing level: %s", options.Multiplexing)
+ }
+ if getHandshakeMode(options.HandshakeMode) == nil {
+ return fmt.Errorf("invalid handshake mode: %s", options.HandshakeMode)
+ }
+ return validateMieruTransport(options.PortBindings)
+}
diff --git a/protocol/mixed/inbound.go b/protocol/mixed/inbound.go
index 64c3edb5b6..d35319473a 100644
--- a/protocol/mixed/inbound.go
+++ b/protocol/mixed/inbound.go
@@ -98,7 +98,7 @@ func (h *Inbound) Close() error {
)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
err := h.newConnection(ctx, conn, metadata, onClose)
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
@@ -125,9 +125,9 @@ func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata ada
}
switch headerBytes[0] {
case socks4.Version, socks5.Version:
- return socks.HandleConnectionEx(ctx, conn, reader, h.authenticator, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), h.listener, h.udpTimeout, metadata.Source, onClose)
+ return socks.HandleConnectionEx(ctx, conn, reader, h.authenticator, adapter.NewUpstreamHandler(metadata, h.newUserConnection, h.streamUserPacketConnection), h.listener, h.udpTimeout, metadata.Source, onClose)
default:
- return http.HandleConnectionEx(ctx, conn, reader, h.authenticator, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
+ return http.HandleConnectionEx(ctx, conn, reader, h.authenticator, adapter.NewUpstreamHandler(metadata, h.newUserConnection, h.streamUserPacketConnection), metadata.Source, onClose)
}
}
diff --git a/protocol/psiphon/outbound.go b/protocol/psiphon/outbound.go
new file mode 100644
index 0000000000..04c860ab76
--- /dev/null
+++ b/protocol/psiphon/outbound.go
@@ -0,0 +1,325 @@
+package psiphon
+
+import (
+ "context"
+ "net"
+ "path/filepath"
+ "sync"
+ "time"
+
+ "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+const (
+ defaultPropagationChannelID = "FFFFFFFFFFFFFFFF"
+ defaultSponsorID = "FFFFFFFFFFFFFFFF"
+ defaultNetworkID = "test"
+ defaultClientPlatform = "Android_4.0.4_com.example.exampleClientLibraryApp"
+ defaultRemoteServerListURL = "https://s3.amazonaws.com//psiphon/web/mjr4-p23r-puwl/server_list_compressed"
+ defaultRemoteServerListFilename = "remote_server_list"
+ defaultSignaturePublicKey = "MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAgEAt7Ls+/39r+T6zNW7GiVpJfzq/xvL9SBH5rIFnk0RXYEYavax3WS6HOD35eTAqn8AniOwiH+DOkvgSKF2caqk/y1dfq47Pdymtwzp9ikpB1C5OfAysXzBiwVJlCdajBKvBZDerV1cMvRzCKvKwRmvDmHgphQQ7WfXIGbRbmmk6opMBh3roE42KcotLFtqp0RRwLtcBRNtCdsrVsjiI1Lqz/lH+T61sGjSjQ3CHMuZYSQJZo/KrvzgQXpkaCTdbObxHqb6/+i1qaVOfEsvjoiyzTxJADvSytVtcTjijhPEV6XskJVHE1Zgl+7rATr/pDQkw6DPCNBS1+Y6fy7GstZALQXwEDN/qhQI9kWkHijT8ns+i1vGg00Mk/6J75arLhqcodWsdeG/M/moWgqQAnlZAGVtJI1OgeF5fsPpXu4kctOfuZlGjVZXQNW34aOzm8r8S0eVZitPlbhcPiR4gT/aSMz/wd8lZlzZYsje/Jr8u/YtlwjjreZrGRmG8KMOzukV3lLmMppXFMvl4bxv6YFEmIuTsOhbLTwFgh7KYNjodLj/LsqRVfwz31PgWQFTEPICV7GCvgVlPRxnofqKSjgTWI4mxDhBpVcATvaoBl1L/6WLbFvBsoAUBItWwctO2xalKxF5szhGm8lccoc5MZr8kfE0uxMgsxz4er68iCID+rsCAQM="
+ defaultDataDirectory = "data/psiphon"
+ defaultEstablishTunnelTimeout = time.Minute
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.PsiphonOutboundOptions](registry, C.TypePsiphon, NewOutbound)
+}
+
+var _ adapter.Outbound = (*Outbound)(nil)
+var _ adapter.InterfaceUpdateListener = (*Outbound)(nil)
+
+type Outbound struct {
+ outbound.Adapter
+ dnsRouter adapter.DNSRouter
+ logger logger.ContextLogger
+ dialer N.Dialer
+
+ ctx context.Context
+
+ mu sync.RWMutex
+ reconnectCh chan struct{}
+ psiphon *Psiphon
+}
+
+type tunnelOwner struct{ notify func() }
+
+func (tunnelOwner) SignalSeededNewSLOK() {}
+func (o tunnelOwner) SignalTunnelFailure(*psiphon.Tunnel) {
+ if o.notify != nil {
+ o.notify()
+ }
+}
+
+func NewOutbound(ctx context.Context, _ adapter.Router, logger log.ContextLogger, tag string, options option.PsiphonOutboundOptions) (adapter.Outbound, error) {
+ outboundDialer, err := dialer.New(ctx, options.DialerOptions, false)
+ if err != nil {
+ return nil, err
+ }
+
+ timeout := time.Duration(options.EstablishTunnelTimeout)
+ if timeout <= 0 {
+ timeout = defaultEstablishTunnelTimeout
+ }
+ config := buildConfig(options, timeout)
+ psiphon, err := NewPsiphon(ctx, logger, config, tag)
+ if err != nil {
+
+ return nil, err
+ }
+ outbound := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypePsiphon, tag, []string{N.NetworkTCP}, options.DialerOptions),
+ dialer: outboundDialer,
+ psiphon: psiphon,
+ logger: logger,
+ ctx: ctx,
+ dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
+ reconnectCh: make(chan struct{}, 1),
+ }
+
+ return outbound, nil
+
+}
+func (h *Outbound) PreStart() error {
+ return h.psiphon.PreStart()
+}
+func (h *Outbound) Start() error {
+
+ go h.run()
+ return nil
+}
+
+// func (h *Outbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+// // return h.psiphon.Dial(dst, innerConn)
+// }
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ // h.logger.Debug("diallign outboud ", h.Tag(), " to ", destination)
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = h.Tag()
+ metadata.Destination = destination
+
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ h.logger.InfoContext(ctx, "outbound connection to ", destination)
+ // h.mu.RLock()
+ // current := h.tunnel
+ // h.mu.RUnlock()
+ // if current == nil || !current.IsActivated() {
+ // return nil, E.New("psiphon tunnel is not established")
+ // }
+ case N.NetworkUDP:
+ return nil, E.New("UDP is not supported by psiphon outbound")
+ default:
+ return nil, E.Extend(N.ErrUnknownNetwork, network)
+ }
+ dst := destination.String()
+ // if destination.IsFqdn() {
+ // destinationAddresses, err := h.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ // if err != nil || len(destinationAddresses) == 0 {
+ // return nil, err
+ // }
+ // dst = fmt.Sprintf("%s:%d", destinationAddresses[0].String(), destination.Port)
+ // // return N.DialSerial(ctx, h.client, network, destination, destinationAddresses)
+ // }
+ h.logger.Debug("dialed destination ", destination, "(", dst, ") through outbound ", h.Tag(), ", now dialing through psiphon tunnel")
+
+ // innerConn, err := h.dialer.DialContext(ctx, "tcp", destination)
+ // if err != nil {
+ // return nil, E.New(err, "failed to dial destination ", destination, " through outbound ", h.Tag())
+ // }
+ return h.psiphon.Dial(dst, nil)
+
+ // dialConf := psiphon.DialConfig{
+ // // CustomDialer: *h.dialer,
+ // ResolveIP: func(context.Context, string) ([]net.IP, error) {
+ // if !destination.IsFqdn() {
+ // return []net.IP{netipAddrToIP(destination.Addr)}, nil
+ // }
+ // res, err := h.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ // if err != nil {
+ // return nil, err
+ // }
+
+ // ips := make([]net.IP, 0, len(res))
+ // for _, r := range res {
+ // ips = append(ips, netipAddrToIP(r))
+ // }
+ // return ips, nil
+
+ // // return []net.IP{
+ // // net.IPv4(1, 1, 1, 1),
+ // // }, nil
+ // // return nil, E.New("psiphon outbound does not support custom DNS resolution")
+ // },
+ // }
+ // return psiphon.DialTCP(ctx, destination.String(), &dialConf)
+
+}
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ return nil, E.New("UDP is not supported by psiphon outbound")
+}
+
+func (h *Outbound) Close() error {
+
+ h.psiphon.Close()
+
+ return nil
+}
+
+func buildConfig(options option.PsiphonOutboundOptions, timeout time.Duration) *psiphon.Config {
+ dataDir := options.DataDirectory
+ if dataDir == "" {
+ dataDir = defaultDataDirectory
+ }
+ allowDefaultDNS := true
+ if options.AllowDefaultDNSResolverWithBindToDevice != nil {
+ allowDefaultDNS = *options.AllowDefaultDNSResolverWithBindToDevice
+ }
+ remoteListFilename := options.RemoteServerListDownloadFilename
+ if remoteListFilename == "" {
+ remoteListFilename = defaultRemoteServerListFilename
+ }
+ remoteListURL := options.RemoteServerListURL
+ if remoteListURL == "" {
+ remoteListURL = defaultRemoteServerListURL
+ }
+ signatureKey := options.RemoteServerListSignaturePublicKey
+ if signatureKey == "" {
+ signatureKey = defaultSignaturePublicKey
+ }
+ propagationChannelID := options.PropagationChannelID
+ if propagationChannelID == "" {
+ propagationChannelID = defaultPropagationChannelID
+ }
+ sponsorID := options.SponsorID
+ if sponsorID == "" {
+ sponsorID = defaultSponsorID
+ }
+ networkID := options.NetworkID
+ if networkID == "" {
+ networkID = defaultNetworkID
+ }
+ clientPlatform := options.ClientPlatform
+ if clientPlatform == "" {
+ clientPlatform = defaultClientPlatform
+ }
+ establishTimeoutSeconds := durationToSecondsPtr(timeout)
+ config := &psiphon.Config{
+ DataRootDirectory: dataDir,
+ EgressRegion: options.EgressRegion,
+ PropagationChannelId: propagationChannelID,
+ RemoteServerListDownloadFilename: remoteListFilename,
+ RemoteServerListSignaturePublicKey: signatureKey,
+ RemoteServerListUrl: remoteListURL,
+ SponsorId: sponsorID,
+ NetworkID: networkID,
+ ClientPlatform: clientPlatform,
+ ClientVersion: options.ClientVersion,
+ AllowDefaultDNSResolverWithBindToDevice: allowDefaultDNS,
+ EstablishTunnelTimeoutSeconds: establishTimeoutSeconds,
+ DisableLocalHTTPProxy: true,
+ DisableLocalSocksProxy: true,
+ MigrateDataStoreDirectory: dataDir,
+ MigrateObfuscatedServerListDownloadDirectory: dataDir,
+ MigrateRemoteServerListDownloadFilename: filepath.Join(dataDir, "server_list_compressed"),
+ }
+ if options.UpstreamProxyURL != "" {
+ config.UpstreamProxyURL = options.UpstreamProxyURL
+ }
+ return config
+}
+
+func durationToSecondsPtr(duration time.Duration) *int {
+ seconds := int(duration / time.Second)
+ if seconds < 1 {
+ seconds = 1
+ }
+ return &seconds
+}
+
+func (h *Outbound) run() {
+ h.connectOnce()
+ // defer h.closeDataStore()
+ // for {
+ // if h.ctx.Err() != nil {
+ // return
+ // }
+ // if h.psiphon.IsConnected() {
+ // h.logger.Debug("psiphon tunnel is active")
+ // select {
+ // case <-h.ctx.Done():
+ // return
+ // case <-h.reconnectCh:
+ // h.resetTunnel()
+ // }
+ // continue
+ // }
+ // h.logger.Debug("psiphon tunnel is not active, trying to connect")
+ // if err := h.connectOnce(); err != nil {
+ // h.logger.Warn("psiphon connect failed: ", err)
+ // select {
+ // case <-h.ctx.Done():
+ // return
+ // case <-time.After(5 * time.Second):
+ // }
+ // continue
+ // }
+ // }
+}
+
+func (p *Outbound) DisplayType() string {
+ str := "⚠️ Connecting..."
+ if p.psiphon.IsConnected() {
+ str = "✔️ Connected"
+ }
+ return C.ProxyDisplayName(p.Type()) + " " + str
+}
+
+func (h *Outbound) connectOnce() error {
+ return h.psiphon.Start()
+}
+
+// func (h *Outbound) connectOnce() error {
+// ti := time.Now().Add(h.timeout)
+// tunnel, err := psiphon.ConnectTunnel(h.ctx, h.config, ti, &psiphon.DialParameters{
+
+// })
+// if err != nil {
+// return err
+// }
+// owner := tunnelOwner{notify: h.requestReconnect}
+// if err = tunnel.Activate(h.ctx, owner, false); err != nil {
+// tunnel.Close(true)
+// return err
+// }
+// h.mu.Lock()
+// h.tunnel = tunnel
+// h.mu.Unlock()
+// return nil
+// }
+
+func (h *Outbound) requestReconnect() {
+ select {
+ case h.reconnectCh <- struct{}{}:
+ default:
+ }
+}
+func (h *Outbound) IsReady() bool {
+ return h.psiphon.IsConnected()
+}
+
+func (h *Outbound) InterfaceUpdated() {
+ h.logger.Info("Network Changed... Restarting Psiphon Tunnel")
+ h.psiphon.controller.NetworkChanged()
+}
diff --git a/protocol/psiphon/psiphon.go b/protocol/psiphon/psiphon.go
new file mode 100644
index 0000000000..b1746b8587
--- /dev/null
+++ b/protocol/psiphon/psiphon.go
@@ -0,0 +1,245 @@
+package psiphon
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+
+ "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon"
+ "github.com/sagernet/sing-box/common/monitoring"
+ "github.com/sagernet/sing/common/logger"
+)
+
+var Countries = []string{
+ "AT",
+ "AU",
+ "BE",
+ "BG",
+ "CA",
+ "CH",
+ "CZ",
+ "DE",
+ "DK",
+ "EE",
+ "ES",
+ "FI",
+ "FR",
+ "GB",
+ "HR",
+ "HU",
+ "IE",
+ "IN",
+ "IT",
+ "JP",
+ "LV",
+ "NL",
+ "NO",
+ "PL",
+ "PT",
+ "RO",
+ "RS",
+ "SE",
+ "SG",
+ "SK",
+ "US",
+}
+
+// NoticeEvent represents the notices emitted by tunnel core. It will be passed to
+// noticeReceiver, if supplied.
+// NOTE: Ordinary users of this library should never need this.
+type NoticeEvent struct {
+ Data map[string]interface{} `json:"data"`
+ Type string `json:"noticeType"`
+ Timestamp string `json:"timestamp"`
+}
+
+type Psiphon struct {
+ controller *psiphon.Controller
+ logger logger.ContextLogger
+ config *psiphon.Config
+ ctx context.Context
+ cancel context.CancelFunc
+ dataStoreOpened bool
+ connected bool
+ tag string
+}
+
+func (p *Psiphon) Dial(address string, conn net.Conn) (net.Conn, error) {
+ if ctl := p.controller; ctl != nil {
+ return ctl.Dial(address, conn)
+ }
+ return nil, errors.New("controller not initialized")
+}
+
+func (p *Psiphon) PreStart() error {
+ if err := os.MkdirAll(p.config.DataRootDirectory, 0o755); err != nil {
+ return err
+ }
+ if err := p.config.Commit(true); err != nil {
+ return err
+ }
+ if err := psiphon.OpenDataStore(p.config); err != nil {
+ return err
+ }
+ p.dataStoreOpened = true
+ if err := psiphon.ImportEmbeddedServerEntries(p.ctx, p.config, "", ""); err != nil {
+ p.closeDataStore()
+ return err
+ }
+ return nil
+}
+func (p *Psiphon) closeDataStore() {
+ if p.dataStoreOpened {
+ psiphon.CloseDataStore()
+ p.dataStoreOpened = false
+ }
+}
+
+func (p *Psiphon) State() string {
+ if p.controller == nil || !p.connected {
+ return "connecting..."
+ }
+
+ return "connected"
+}
+func (p *Psiphon) IsConnected() bool {
+ if p.controller == nil || !p.connected {
+ return false
+ }
+ return true
+}
+
+func (p *Psiphon) Close() error {
+ p.connected = false
+ psiphon.ResetNoticeWriter()
+ p.cancel()
+ p.closeDataStore()
+ return nil
+}
+func NewPsiphon(ctx context.Context, l logger.ContextLogger, config *psiphon.Config, tag string) (*Psiphon, error) {
+ p := Psiphon{
+ logger: l,
+ config: config,
+ ctx: ctx,
+ tag: tag,
+ }
+ return &p, nil
+}
+func (p *Psiphon) Start() error {
+
+ ctx, cancel := context.WithCancel(p.ctx)
+ p.cancel = cancel
+ // config.Commit must be called before calling config.SetParameters
+ // or attempting to connect.
+ if err := p.config.Commit(true); err != nil {
+ return errors.New("config.Commit failed")
+ }
+
+ connected := make(chan struct{}, 1)
+ errored := make(chan error, 1)
+
+ psiphon.SetNoticeWriter(psiphon.NewNoticeReceiver(func(notice []byte) {
+ var event NoticeEvent
+ if err := json.Unmarshal(notice, &event); err != nil {
+ return
+ }
+
+ go func(event NoticeEvent) {
+ p.logger.Debug(fmt.Sprint("Notic ", event.Type, " data ", event.Data))
+ switch event.Type {
+ case "EstablishTunnelTimeout":
+ select {
+ case errored <- errors.New("clientlib: tunnel establishment timeout"):
+ default:
+ }
+ case "Tunnels":
+ if event.Data["count"].(float64) > 0 {
+ select {
+ case connected <- struct{}{}:
+ p.connected = true
+ monitoring.Get(p.ctx).TestNow(p.tag)
+ default:
+ }
+ }
+ }
+ }(event)
+ }))
+
+ if err := psiphon.OpenDataStore(p.config); err != nil {
+ return errors.New("failed to open data store")
+ }
+
+ if err := psiphon.ImportEmbeddedServerEntries(ctx, p.config, "", ""); err != nil {
+ return err
+ }
+
+ controller, err := psiphon.NewController(p.config)
+
+ if err != nil {
+ return errors.New("psiphon.NewController failed")
+ }
+ p.controller = controller
+
+ go func() {
+ controller.Run(ctx) // Run will block until the controller is stopped
+
+ select {
+ case errored <- errors.New("controller.Run exited unexpectedly"):
+ default:
+ }
+ }()
+ p.logger.Debug("Waiting for success or failure of tunnel connection...")
+ select {
+ case <-ctx.Done():
+ p.logger.Debug("Context done while waiting for success or failure of tunnel connection")
+ p.Close()
+ return ctx.Err()
+ case <-connected:
+ p.logger.Debug("Tunnel connection established")
+ return nil
+ case err := <-errored:
+ p.logger.Debug("Tunnel connection failed: ", err)
+ p.Close()
+ return err
+ }
+
+}
+
+// func RunPsiphon(ctx context.Context, l logger.ContextLogger, wgBind netip.AddrPort, dir string, localSocksAddr netip.AddrPort, country string) error {
+// host := ""
+// if !netip.MustParsePrefix("127.0.0.0/8").Contains(localSocksAddr.Addr()) {
+// host = "any"
+// }
+
+// timeout := 60
+// config := psiphon.Config{
+// EgressRegion: country,
+// ListenInterface: host,
+// LocalSocksProxyPort: int(localSocksAddr.Port()),
+// UpstreamProxyURL: fmt.Sprintf("socks5://%s", wgBind),
+// DisableLocalHTTPProxy: true,
+// PropagationChannelId: "FFFFFFFFFFFFFFFF",
+// RemoteServerListDownloadFilename: "remote_server_list",
+// RemoteServerListSignaturePublicKey: "MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAgEAt7Ls+/39r+T6zNW7GiVpJfzq/xvL9SBH5rIFnk0RXYEYavax3WS6HOD35eTAqn8AniOwiH+DOkvgSKF2caqk/y1dfq47Pdymtwzp9ikpB1C5OfAysXzBiwVJlCdajBKvBZDerV1cMvRzCKvKwRmvDmHgphQQ7WfXIGbRbmmk6opMBh3roE42KcotLFtqp0RRwLtcBRNtCdsrVsjiI1Lqz/lH+T61sGjSjQ3CHMuZYSQJZo/KrvzgQXpkaCTdbObxHqb6/+i1qaVOfEsvjoiyzTxJADvSytVtcTjijhPEV6XskJVHE1Zgl+7rATr/pDQkw6DPCNBS1+Y6fy7GstZALQXwEDN/qhQI9kWkHijT8ns+i1vGg00Mk/6J75arLhqcodWsdeG/M/moWgqQAnlZAGVtJI1OgeF5fsPpXu4kctOfuZlGjVZXQNW34aOzm8r8S0eVZitPlbhcPiR4gT/aSMz/wd8lZlzZYsje/Jr8u/YtlwjjreZrGRmG8KMOzukV3lLmMppXFMvl4bxv6YFEmIuTsOhbLTwFgh7KYNjodLj/LsqRVfwz31PgWQFTEPICV7GCvgVlPRxnofqKSjgTWI4mxDhBpVcATvaoBl1L/6WLbFvBsoAUBItWwctO2xalKxF5szhGm8lccoc5MZr8kfE0uxMgsxz4er68iCID+rsCAQM=",
+// RemoteServerListUrl: "https://s3.amazonaws.com//psiphon/web/mjr4-p23r-puwl/server_list_compressed",
+// SponsorId: "FFFFFFFFFFFFFFFF",
+// NetworkID: "test",
+// ClientPlatform: "Android_4.0.4_com.example.exampleClientLibraryApp",
+// AllowDefaultDNSResolverWithBindToDevice: true,
+// EstablishTunnelTimeoutSeconds: &timeout,
+// DataRootDirectory: dir,
+// MigrateDataStoreDirectory: dir,
+// MigrateObfuscatedServerListDownloadDirectory: dir,
+// MigrateRemoteServerListDownloadFilename: filepath.Join(dir, "server_list_compressed"),
+// }
+
+// l.Info("starting handshake")
+// if _, err := StartTunnel(ctx, l, &config); err != nil {
+// return fmt.Errorf("Unable to start psiphon: %w", err)
+// }
+// l.Info("psiphon started successfully")
+// return nil
+// }
diff --git a/protocol/redirect/redirect.go b/protocol/redirect/redirect.go
index e04db8c4df..ff52bd7b4b 100644
--- a/protocol/redirect/redirect.go
+++ b/protocol/redirect/redirect.go
@@ -53,7 +53,7 @@ func (h *Redirect) Close() error {
return h.listener.Close()
}
-func (h *Redirect) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Redirect) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
destination, err := redir.GetOriginalDestination(conn)
if err != nil {
conn.Close()
diff --git a/protocol/redirect/tproxy.go b/protocol/redirect/tproxy.go
index f0b82bb132..5f24162629 100644
--- a/protocol/redirect/tproxy.go
+++ b/protocol/redirect/tproxy.go
@@ -71,7 +71,7 @@ func (t *TProxy) Close() error {
return t.listener.Close()
}
-func (t *TProxy) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (t *TProxy) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
metadata.Inbound = t.Tag()
metadata.InboundType = t.Type()
metadata.Destination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
@@ -91,7 +91,7 @@ func (t *TProxy) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, s
t.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}
-func (t *TProxy) NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr) {
+func (t *TProxy) NewPacket(buffer *buf.Buffer, oob []byte, source M.Socksaddr) {
destination, err := redir.GetOriginalDestinationFromOOB(oob)
if err != nil {
t.logger.Warn("process packet from ", source, ": get tproxy destination: ", err)
diff --git a/protocol/shadowsocks/inbound.go b/protocol/shadowsocks/inbound.go
index 52e2c52472..fc77c423ca 100644
--- a/protocol/shadowsocks/inbound.go
+++ b/protocol/shadowsocks/inbound.go
@@ -13,6 +13,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ obfs "github.com/sagernet/sing-box/transport/simple-obfs"
"github.com/sagernet/sing-shadowsocks"
"github.com/sagernet/sing-shadowsocks/shadowaead"
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
@@ -53,14 +54,21 @@ type Inbound struct {
logger logger.ContextLogger
listener *listener.Listener
service shadowsocks.Service
+ obfsMode string
}
func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*Inbound, error) {
+ switch options.ObfsMode {
+ case "", "http", "tls":
+ default:
+ return nil, E.New("shadowsocks: unsupported obfs mode: ", options.ObfsMode)
+ }
inbound := &Inbound{
- Adapter: inbound.NewAdapter(C.TypeShadowsocks, tag),
- ctx: ctx,
- router: uot.NewRouter(router, logger),
- logger: logger,
+ Adapter: inbound.NewAdapter(C.TypeShadowsocks, tag),
+ ctx: ctx,
+ router: uot.NewRouter(router, logger),
+ logger: logger,
+ obfsMode: options.ObfsMode,
}
var err error
inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
@@ -75,11 +83,11 @@ func newInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
}
switch {
case options.Method == shadowsocks.MethodNone:
- inbound.service = shadowsocks.NewNoneService(int64(udpTimeout.Seconds()), adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound))
+ inbound.service = shadowsocks.NewNoneService(int64(udpTimeout.Seconds()), adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound))
case common.Contains(shadowaead.List, options.Method):
- inbound.service, err = shadowaead.NewService(options.Method, nil, options.Password, int64(udpTimeout.Seconds()), adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound))
+ inbound.service, err = shadowaead.NewService(options.Method, nil, options.Password, int64(udpTimeout.Seconds()), adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound))
case common.Contains(shadowaead_2022.List, options.Method):
- inbound.service, err = shadowaead_2022.NewServiceWithPassword(options.Method, options.Password, int64(udpTimeout.Seconds()), adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound), ntp.TimeFuncFromContext(ctx))
+ inbound.service, err = shadowaead_2022.NewServiceWithPassword(options.Method, options.Password, int64(udpTimeout.Seconds()), adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound), ntp.TimeFuncFromContext(ctx))
default:
err = E.New("unsupported method: ", options.Method)
}
@@ -107,7 +115,13 @@ func (h *Inbound) Close() error {
}
//nolint:staticcheck
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ switch h.obfsMode {
+ case "http":
+ conn = obfs.NewHTTPObfsServer(conn)
+ case "tls":
+ conn = obfs.NewTLSObfsServer(conn)
+ }
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
@@ -120,7 +134,7 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
}
//nolint:staticcheck
-func (h *Inbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
+func (h *Inbound) NewPacket(buffer *buf.Buffer, source M.Socksaddr) {
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
if err != nil {
h.logger.Error(E.Cause(err, "process packet from ", source))
diff --git a/protocol/shadowsocks/inbound_multi.go b/protocol/shadowsocks/inbound_multi.go
index 7ff9264693..1da2bd9dc7 100644
--- a/protocol/shadowsocks/inbound_multi.go
+++ b/protocol/shadowsocks/inbound_multi.go
@@ -14,6 +14,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ obfs "github.com/sagernet/sing-box/transport/simple-obfs"
"github.com/sagernet/sing-shadowsocks"
"github.com/sagernet/sing-shadowsocks/shadowaead"
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
@@ -42,14 +43,21 @@ type MultiInbound struct {
service shadowsocks.MultiService[int]
users []option.ShadowsocksUser
tracker adapter.SSMTracker
+ obfsMode string
}
func newMultiInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*MultiInbound, error) {
+ switch options.ObfsMode {
+ case "", "http", "tls":
+ default:
+ return nil, E.New("shadowsocks: unsupported obfs mode: ", options.ObfsMode)
+ }
inbound := &MultiInbound{
- Adapter: inbound.NewAdapter(C.TypeShadowsocks, tag),
- ctx: ctx,
- router: uot.NewRouter(router, logger),
- logger: logger,
+ Adapter: inbound.NewAdapter(C.TypeShadowsocks, tag),
+ ctx: ctx,
+ router: uot.NewRouter(router, logger),
+ logger: logger,
+ obfsMode: options.ObfsMode,
}
var err error
inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
@@ -68,14 +76,14 @@ func newMultiInbound(ctx context.Context, router adapter.Router, logger log.Cont
options.Method,
options.Password,
int64(udpTimeout.Seconds()),
- adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
+ adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
ntp.TimeFuncFromContext(ctx),
)
} else if common.Contains(shadowaead.List, options.Method) {
service, err = shadowaead.NewMultiService[int](
options.Method,
int64(udpTimeout.Seconds()),
- adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
+ adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
)
} else {
return nil, E.New("unsupported method: " + options.Method)
@@ -138,7 +146,13 @@ func (h *MultiInbound) UpdateUsers(users []string, uPSKs []string) error {
}
//nolint:staticcheck
-func (h *MultiInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *MultiInbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ switch h.obfsMode {
+ case "http":
+ conn = obfs.NewHTTPObfsServer(conn)
+ case "tls":
+ conn = obfs.NewTLSObfsServer(conn)
+ }
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
@@ -151,7 +165,7 @@ func (h *MultiInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metad
}
//nolint:staticcheck
-func (h *MultiInbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
+func (h *MultiInbound) NewPacket(buffer *buf.Buffer, source M.Socksaddr) {
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
if err != nil {
h.logger.Error(E.Cause(err, "process packet from ", source))
diff --git a/protocol/shadowsocks/inbound_relay.go b/protocol/shadowsocks/inbound_relay.go
index d7d7bcff72..7fe4534300 100644
--- a/protocol/shadowsocks/inbound_relay.go
+++ b/protocol/shadowsocks/inbound_relay.go
@@ -14,6 +14,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ obfs "github.com/sagernet/sing-box/transport/simple-obfs"
"github.com/sagernet/sing-shadowsocks/shadowaead_2022"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth"
@@ -35,15 +36,22 @@ type RelayInbound struct {
listener *listener.Listener
service *shadowaead_2022.RelayService[int]
destinations []option.ShadowsocksDestination
+ obfsMode string
}
func newRelayInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.ShadowsocksInboundOptions) (*RelayInbound, error) {
+ switch options.ObfsMode {
+ case "", "http", "tls":
+ default:
+ return nil, E.New("shadowsocks: unsupported obfs mode: ", options.ObfsMode)
+ }
inbound := &RelayInbound{
Adapter: inbound.NewAdapter(C.TypeShadowsocks, tag),
ctx: ctx,
router: uot.NewRouter(router, logger),
logger: logger,
destinations: options.Destinations,
+ obfsMode: options.ObfsMode,
}
var err error
inbound.router, err = mux.NewRouterWithOptions(inbound.router, logger, common.PtrValueOrDefault(options.Multiplex))
@@ -60,7 +68,7 @@ func newRelayInbound(ctx context.Context, router adapter.Router, logger log.Cont
options.Method,
options.Password,
int64(udpTimeout.Seconds()),
- adapter.NewUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
+ adapter.NewLegacyUpstreamHandler(adapter.InboundContext{}, inbound.newConnection, inbound.newPacketConnection, inbound),
)
if err != nil {
return nil, err
@@ -98,7 +106,13 @@ func (h *RelayInbound) Close() error {
}
//nolint:staticcheck
-func (h *RelayInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *RelayInbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ switch h.obfsMode {
+ case "http":
+ conn = obfs.NewHTTPObfsServer(conn)
+ case "tls":
+ conn = obfs.NewTLSObfsServer(conn)
+ }
err := h.service.NewConnection(ctx, conn, adapter.UpstreamMetadata(metadata))
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
@@ -111,7 +125,7 @@ func (h *RelayInbound) NewConnectionEx(ctx context.Context, conn net.Conn, metad
}
//nolint:staticcheck
-func (h *RelayInbound) NewPacketEx(buffer *buf.Buffer, source M.Socksaddr) {
+func (h *RelayInbound) NewPacket(buffer *buf.Buffer, source M.Socksaddr) {
err := h.service.NewPacket(h.ctx, &stubPacketConn{h.listener.PacketWriter()}, buffer, M.Metadata{Source: source})
if err != nil {
h.logger.Error(E.Cause(err, "process packet from ", source))
diff --git a/protocol/shadowtls/inbound.go b/protocol/shadowtls/inbound.go
index 17afa26831..98d9ab0381 100644
--- a/protocol/shadowtls/inbound.go
+++ b/protocol/shadowtls/inbound.go
@@ -108,7 +108,7 @@ func (h *Inbound) Close() error {
return h.listener.Close()
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
err := h.service.NewConnection(adapter.WithContext(log.ContextWithNewID(ctx), &metadata), conn, metadata.Source, metadata.Destination, onClose)
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
diff --git a/protocol/snell/inbound.go b/protocol/snell/inbound.go
new file mode 100644
index 0000000000..ee2e6efe83
--- /dev/null
+++ b/protocol/snell/inbound.go
@@ -0,0 +1,308 @@
+package snellprotocol
+
+import (
+ "context"
+ "net"
+ "sync"
+
+ snell "github.com/reF1nd/sing-snell"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ "github.com/sagernet/sing-box/common/listener"
+ "github.com/sagernet/sing-box/common/uot"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ obfs "github.com/sagernet/sing-box/transport/simple-obfs"
+ "github.com/sagernet/sing/common/auth"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ udpnat "github.com/sagernet/sing/common/udpnat2"
+)
+
+func RegisterInbound(registry *inbound.Registry) {
+ inbound.Register[option.SnellInboundOptions](registry, C.TypeSnell, NewInbound)
+}
+
+type Inbound struct {
+ inbound.Adapter
+ ctx context.Context
+ router adapter.ConnectionRouterEx
+ logger logger.ContextLogger
+ listener *listener.Listener
+ service *snell.Service
+ obfsMode string
+ obfsHost string
+ // v5 QUIC proxy state
+ psk []byte
+ userPSKs [][]byte // non-nil in multi-user mode; used for QUIC proxy auth
+ version int
+ udpNat *udpnat.Service
+ quicSessions sync.Map // key: netip.AddrPort → *snell.QUICProxySession
+ // multi-user state
+ users []option.SnellUser
+}
+
+func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SnellInboundOptions) (adapter.Inbound, error) {
+ if options.PSK == "" && len(options.Users) == 0 {
+ return nil, E.New("snell: psk or users is required")
+ }
+ if options.PSK != "" && len(options.Users) > 0 {
+ return nil, E.New("snell: psk and users are mutually exclusive")
+ }
+
+ switch options.ObfsMode {
+ case "", "http":
+ case "tls":
+ ver := options.Version
+ if ver == 0 {
+ ver = snell.DefaultVersion
+ }
+ if ver >= snell.Version4 {
+ return nil, E.New("snell: obfs_mode TLS is insecure and not supported for v4/v5; use ShadowTLS instead")
+ }
+ default:
+ return nil, E.New("snell: unsupported obfs mode: ", options.ObfsMode)
+ }
+
+ i := &Inbound{
+ Adapter: inbound.NewAdapter(C.TypeSnell, tag),
+ ctx: ctx,
+ router: uot.NewRouter(router, logger),
+ logger: logger,
+ obfsMode: options.ObfsMode,
+ obfsHost: options.ObfsHost,
+ psk: []byte(options.PSK),
+ version: options.Version,
+ users: options.Users,
+ }
+
+ networks := []string{N.NetworkTCP}
+ if options.Version >= snell.Version5 {
+ networks = append(networks, N.NetworkUDP)
+ i.udpNat = udpnat.New((*inboundUDPHandler)(i), i.preparePacketConnection, snell.QUICProxySessionIdleTimeout, false)
+ }
+ var serviceConfig snell.ServiceConfig
+ if len(options.Users) > 0 {
+ users := make([]snell.User, len(options.Users))
+ userPSKs := make([][]byte, len(options.Users))
+ for j, u := range options.Users {
+ users[j] = snell.User{Name: u.Name, PSK: []byte(u.PSK)}
+ userPSKs[j] = []byte(u.PSK)
+ }
+ i.userPSKs = userPSKs
+ serviceConfig = snell.ServiceConfig{
+ Users: users,
+ Version: options.Version,
+ UDPEnabled: true,
+ Handler: (*inboundHandler)(i),
+ UDPHandler: (*inboundUDPHandler)(i),
+ Logger: logger,
+ }
+ } else {
+ serviceConfig = snell.ServiceConfig{
+ PSK: []byte(options.PSK),
+ Version: options.Version,
+ UDPEnabled: true,
+ Handler: (*inboundHandler)(i),
+ UDPHandler: (*inboundUDPHandler)(i),
+ Logger: logger,
+ }
+ }
+ service, err := snell.NewService(serviceConfig)
+ if err != nil {
+ return nil, err
+ }
+ i.service = service
+
+ i.listener = listener.New(listener.Options{
+ Context: ctx,
+ Logger: logger,
+ Network: networks,
+ Listen: options.ListenOptions,
+ ConnectionHandler: i,
+ PacketHandler: (*inboundPacketHandler)(i),
+ })
+ return i, nil
+}
+
+func (h *Inbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ return h.listener.Start()
+}
+
+func (h *Inbound) Close() error {
+ return h.listener.Close()
+}
+
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ switch h.obfsMode {
+ case "http":
+ conn = obfs.NewHTTPObfsServer(conn)
+ case "tls":
+ conn = obfs.NewTLSObfsServer(conn)
+ }
+ err := h.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, metadata.Source, onClose)
+ if err != nil {
+ N.CloseOnHandshakeFailure(conn, onClose, err)
+ h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
+ }
+}
+
+type inboundHandler Inbound
+
+func (h *inboundHandler) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Inbound = h.Tag()
+ metadata.InboundType = h.Type()
+ //nolint:staticcheck
+ metadata.InboundDetour = h.listener.ListenOptions().Detour
+ //nolint:staticcheck
+ metadata.Source = source
+ metadata.Destination = destination.Unwrap()
+ if userIdx, loaded := auth.UserFromContext[int](ctx); loaded && userIdx < len(h.users) {
+ metadata.User = h.users[userIdx].Name
+ }
+ h.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
+}
+
+type inboundUDPHandler Inbound
+
+func (h *inboundUDPHandler) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
+ var metadata adapter.InboundContext
+ metadata.Inbound = h.Tag()
+ metadata.InboundType = h.Type()
+ //nolint:staticcheck
+ metadata.InboundDetour = h.listener.ListenOptions().Detour
+ //nolint:staticcheck
+ metadata.Source = source
+ metadata.Destination = destination.Unwrap()
+ if userIdx, loaded := auth.UserFromContext[int](ctx); loaded && userIdx < len(h.users) {
+ metadata.User = h.users[userIdx].Name
+ }
+ h.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
+ h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
+}
+
+// preparePacketConnection is the udpnat PrepareFunc for QUIC proxy sessions.
+// It returns a PacketWriter that sends raw UDP responses back to the client.
+// In multi-user mode, userData is *snell.QUICProxySession and carries the
+// matched UserIndex which is injected into the context for auth_user routing.
+func (h *Inbound) preparePacketConnection(source M.Socksaddr, destination M.Socksaddr, userData any) (bool, context.Context, N.PacketWriter, N.CloseHandlerFunc) {
+ ctx := log.ContextWithNewID(h.ctx)
+ if qsess, ok := userData.(*snell.QUICProxySession); ok && qsess != nil && qsess.UserIndex >= 0 {
+ ctx = auth.ContextWithUser(ctx, qsess.UserIndex)
+ }
+ return true, ctx, &quicProxyResponseWriter{
+ writer: h.listener.PacketWriter(),
+ clientAddr: source,
+ }, func(err error) {
+ h.quicSessions.Delete(source.AddrPort())
+ }
+}
+
+// quicProxyResponseWriter rewrites the destination to the original client
+// address so that responses from the outbound go back to the right client.
+type quicProxyResponseWriter struct {
+ writer N.PacketWriter
+ clientAddr M.Socksaddr
+}
+
+func (w *quicProxyResponseWriter) WritePacket(buffer *buf.Buffer, _ M.Socksaddr) error {
+ return w.writer.WritePacket(buffer, w.clientAddr)
+}
+
+// inboundPacketHandler handles raw UDP datagrams from the listener for
+// Snell v5 QUIC proxy mode. It decrypts the Snell framing to recover the
+// original UDP payload and target, then feeds it into udpnat so that
+// routing rules, domain sniffing and detour all apply normally.
+type inboundPacketHandler Inbound
+
+func (h *inboundPacketHandler) NewPacket(buffer *buf.Buffer, source M.Socksaddr) {
+ defer buffer.Release()
+ if h.udpNat == nil {
+ return
+ }
+ data := buffer.Bytes()
+ if len(data) == 0 {
+ return
+ }
+
+ val, hasSession := h.quicSessions.Load(source.AddrPort())
+ if hasSession {
+ qsess := val.(*snell.QUICProxySession)
+ qsess.Touch()
+
+ var payload []byte
+ if snell.IsQUICLooking(data[0]) {
+ // Raw QUIC short-header — forward as-is
+ payload = data
+ } else {
+ // Duplicate init frame — decrypt to recover raw UDP payload
+ var err error
+ payload, err = qsess.DecodeDuplicateInit(data)
+ if err != nil {
+ h.logger.Error("quic proxy: decode duplicate init: ", err)
+ return
+ }
+ }
+ if len(payload) > 0 {
+ // Pass qsess as userData so that if the udpnat entry was evicted
+ // (timeout race between the two maps), PrepareFunc correctly
+ // re-injects the user context on re-creation.
+ h.udpNat.NewPacket([][]byte{payload}, source, qsess.Target(), qsess)
+ }
+ return
+ }
+
+ // No existing session
+ if snell.IsQUICLooking(data[0]) {
+ // QUIC-looking without a session context — discard
+ h.logger.Debug("quic proxy: discarding QUIC-looking packet without session from ", source)
+ return
+ }
+
+ // Parse Snell QUIC proxy init frame. In multi-user mode try every PSK;
+ // in single-user mode use h.psk directly.
+ var qsess *snell.QUICProxySession
+ var firstPayload []byte
+ if len(h.userPSKs) > 0 {
+ var err error
+ qsess, firstPayload, err = snell.ParseQUICProxyInitMulti(h.userPSKs, data)
+ if err != nil {
+ h.logger.Error("quic proxy: parse init from ", source, ": ", err)
+ return
+ }
+ } else {
+ var err error
+ qsess, firstPayload, err = snell.ParseQUICProxyInit(h.psk, data)
+ if err != nil {
+ h.logger.Error("quic proxy: parse init from ", source, ": ", err)
+ return
+ }
+ }
+
+ // LoadOrStore so that if two concurrent goroutines both parse an init
+ // frame from the same source (very rare: same client port, same instant),
+ // only one session wins and both payloads are queued under the same
+ // crypto/user context. This avoids a benign but unnecessary duplicate
+ // firstPayload delivery that a plain Store+NewPacket would cause.
+ if actual, loaded := h.quicSessions.LoadOrStore(source.AddrPort(), qsess); loaded {
+ qsess = actual.(*snell.QUICProxySession)
+ }
+
+ target := qsess.Target()
+ h.logger.Info("quic proxy: new session from ", source, " to ", target)
+
+ if len(firstPayload) > 0 {
+ // Pass qsess as userData so preparePacketConnection can inject the
+ // matched user index into the context for auth_user rule matching.
+ h.udpNat.NewPacket([][]byte{firstPayload}, source, target, qsess)
+ }
+}
diff --git a/protocol/snell/outbound.go b/protocol/snell/outbound.go
new file mode 100644
index 0000000000..4083853f89
--- /dev/null
+++ b/protocol/snell/outbound.go
@@ -0,0 +1,373 @@
+package snellprotocol
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "os"
+ "sync"
+ "time"
+
+ snell "github.com/reF1nd/sing-snell"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ obfs "github.com/sagernet/sing-box/transport/simple-obfs"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.SnellOutboundOptions](registry, C.TypeSnell, NewOutbound)
+}
+
+type Outbound struct {
+ outbound.Adapter
+ logger log.ContextLogger
+ dialer N.Dialer
+ client *snell.Client
+ pool *snell.Pool
+ serverAddr M.Socksaddr
+ obfsMode string
+ obfsHost string
+ serverPort string
+ psk []byte
+ version int
+}
+
+func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SnellOutboundOptions) (adapter.Outbound, error) {
+ if options.PSK == "" {
+ return nil, E.New("snell: psk is required")
+ }
+
+ switch options.ObfsMode {
+ case "", "http":
+ case "tls":
+ ver := options.Version
+ if ver == 0 {
+ ver = snell.DefaultVersion
+ }
+ if ver >= snell.Version4 {
+ return nil, E.New("snell: obfs_mode TLS is insecure and not supported for v4/v5; use ShadowTLS instead")
+ }
+ default:
+ return nil, E.New("snell: unsupported obfs mode: ", options.ObfsMode)
+ }
+
+ serverAddr := options.ServerOptions.Build()
+
+ outboundDialer, err := dialer.New(ctx, options.DialerOptions, options.ServerIsDomain())
+ if err != nil {
+ return nil, err
+ }
+
+ version := options.Version
+ if version == 0 {
+ version = snell.DefaultVersion
+ }
+
+ // Build network list. If the user specified an explicit `network` field use
+ // that; otherwise apply the protocol default: v3/v4/v5 enable TCP+UDP by
+ // default, while v1/v2 default to TCP-only (no UDP support).
+ var networks []string
+ if string(options.Network) != "" {
+ networks = options.Network.Build()
+ for _, net := range networks {
+ if net == N.NetworkUDP && version < snell.Version3 {
+ return nil, E.New("snell: UDP requires version 3 or above")
+ }
+ }
+ } else if version >= snell.Version3 {
+ networks = []string{N.NetworkTCP, N.NetworkUDP}
+ } else {
+ networks = []string{N.NetworkTCP}
+ }
+
+ client, err := snell.NewClient([]byte(options.PSK), version)
+ if err != nil {
+ return nil, err
+ }
+
+ o := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSnell, tag, networks, options.DialerOptions),
+ logger: logger,
+ dialer: outboundDialer,
+ client: client,
+ serverAddr: serverAddr,
+ obfsMode: options.ObfsMode,
+ obfsHost: options.ObfsHost,
+ serverPort: fmt.Sprintf("%d", serverAddr.Port),
+ psk: []byte(options.PSK),
+ version: version,
+ }
+
+ // Connection reuse (v4+): build a pool whose factory dials + encrypts a
+ // fresh stream. The pool is only active when reuse is explicitly enabled.
+ if options.Reuse && version >= snell.Version4 {
+ o.pool = snell.NewPool(func(ctx context.Context) (net.Conn, error) {
+ rawConn, err := outboundDialer.DialContext(ctx, N.NetworkTCP, serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ return client.WrapStream(o.applyObfs(rawConn)), nil
+ })
+ }
+
+ return o, nil
+}
+
+func (h *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = h.Tag()
+ metadata.Destination = destination
+
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ h.logger.InfoContext(ctx, "outbound connection to ", destination)
+ if h.pool != nil {
+ return h.client.DialContextWithPool(ctx, h.pool, destination)
+ }
+ rawConn, err := h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ conn := h.applyObfs(rawConn)
+ return h.client.DialContext(ctx, conn, destination)
+ case N.NetworkUDP:
+ h.logger.InfoContext(ctx, "outbound UDP connection to ", destination)
+ if h.version >= snell.Version5 {
+ pc := newV5LazyPacketConn(ctx, h, destination, metadata.Protocol == C.ProtocolQUIC)
+ return &packetConnWrapper{PacketConn: pc, destination: destination}, nil
+ }
+ rawConn, err := h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ conn := h.applyObfs(rawConn)
+ udpStream, err := h.client.DialUDP(ctx, conn)
+ if err != nil {
+ return nil, err
+ }
+ pc := snell.NewClientPacketConn(udpStream)
+ return &packetConnWrapper{PacketConn: pc, destination: destination}, nil
+ }
+ return nil, os.ErrInvalid
+}
+
+func (h *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = h.Tag()
+ metadata.Destination = destination
+
+ h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+
+ if h.version >= snell.Version5 {
+ return newV5LazyPacketConn(ctx, h, destination, metadata.Protocol == C.ProtocolQUIC), nil
+ }
+
+ rawConn, err := h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ conn := h.applyObfs(rawConn)
+ udpStream, err := h.client.DialUDP(ctx, conn)
+ if err != nil {
+ return nil, err
+ }
+ return snell.NewClientPacketConn(udpStream), nil
+}
+
+// dialUDPOverTCP creates a UDP-over-TCP tunnel (v3/v4/v5 fallback for non-QUIC UDP).
+func (h *Outbound) dialUDPOverTCP(ctx context.Context) (net.PacketConn, error) {
+ rawConn, err := h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ conn := h.applyObfs(rawConn)
+ udpStream, err := h.client.DialUDP(ctx, conn)
+ if err != nil {
+ return nil, err
+ }
+ return snell.NewClientPacketConn(udpStream), nil
+}
+
+// dialQUICProxy creates a QUIC proxy PacketConn (v5 only).
+// initPayload is the first QUIC Initial packet; it is sent as part of the init frame.
+func (h *Outbound) dialQUICProxy(ctx context.Context, destination M.Socksaddr, initPayload []byte) (net.PacketConn, error) {
+ rawConn, err := h.dialer.DialContext(ctx, N.NetworkUDP, h.serverAddr)
+ if err != nil {
+ return nil, err
+ }
+ return snell.NewQUICProxyPacketConn(rawConn, h.psk, destination, initPayload)
+}
+
+// v5LazyPacketConn defers connection establishment to the first WriteTo call,
+// allowing mode selection between QUIC proxy and UDP-over-TCP.
+//
+// Mode selection priority:
+// 1. sniffQUIC == true (router sniff identified QUIC before reaching this outbound)
+// 2. first payload byte >= 0xc0 (QUIC long-header, e.g. Initial / Handshake / 0-RTT)
+//
+// Using sniff as primary handles the 0-RTT resumption case where the first packet
+// is a short-header (0x40-0x7f) and would otherwise be misclassified.
+type v5LazyPacketConn struct {
+ outbound *Outbound
+ ctx context.Context
+ destination M.Socksaddr
+ // sniffQUIC is set when the router's sniff result identified this flow as QUIC.
+ // It takes priority over the first-byte heuristic.
+ sniffQUIC bool
+
+ once sync.Once
+ initCh chan struct{} // closed once conn is ready
+ conn net.PacketConn
+ connErr error
+ firstWriteQUIC bool // true when dialQUICProxy consumed initPayload
+}
+
+func newV5LazyPacketConn(ctx context.Context, ob *Outbound, dst M.Socksaddr, sniffQUIC bool) *v5LazyPacketConn {
+ return &v5LazyPacketConn{
+ outbound: ob,
+ ctx: ctx,
+ destination: dst,
+ sniffQUIC: sniffQUIC,
+ initCh: make(chan struct{}),
+ }
+}
+
+func (c *v5LazyPacketConn) initConn(p []byte, addr net.Addr) {
+ useQUIC := c.sniffQUIC || (len(p) > 0 && snell.IsQUICInitial(p[0]))
+ if useQUIC {
+ // Always use c.destination (resolved at ListenPacket/DialContext time, after
+ // FakeIP reverse-lookup and routing) as the QUIC proxy target.
+ // Do NOT use addr here, which carries the fake IP in TUN+FakeIP scenarios.
+ conn, err := c.outbound.dialQUICProxy(c.ctx, c.destination, p)
+ c.conn = conn
+ c.connErr = err
+ c.firstWriteQUIC = (err == nil)
+ } else {
+ conn, err := c.outbound.dialUDPOverTCP(c.ctx)
+ c.conn = conn
+ c.connErr = err
+ }
+ close(c.initCh)
+}
+
+func (c *v5LazyPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) {
+ var firstWriteQUIC bool
+ c.once.Do(func() {
+ c.initConn(p, addr)
+ firstWriteQUIC = c.firstWriteQUIC
+ })
+ <-c.initCh
+ if c.connErr != nil {
+ return 0, c.connErr
+ }
+ // For QUIC proxy first write, the payload was already sent inside dialQUICProxy.
+ if firstWriteQUIC {
+ return len(p), nil
+ }
+ return c.conn.WriteTo(p, addr)
+}
+
+func (c *v5LazyPacketConn) ReadFrom(p []byte) (int, net.Addr, error) {
+ <-c.initCh
+ if c.connErr != nil {
+ return 0, nil, c.connErr
+ }
+ return c.conn.ReadFrom(p)
+}
+
+func (c *v5LazyPacketConn) Close() error {
+ select {
+ case <-c.initCh:
+ if c.conn != nil {
+ return c.conn.Close()
+ }
+ return nil
+ default:
+ // conn not yet initialized; nothing to close
+ return nil
+ }
+}
+
+func (c *v5LazyPacketConn) LocalAddr() net.Addr {
+ select {
+ case <-c.initCh:
+ if c.conn != nil {
+ return c.conn.LocalAddr()
+ }
+ default:
+ }
+ return &net.UDPAddr{}
+}
+
+func (c *v5LazyPacketConn) SetDeadline(t time.Time) error {
+ select {
+ case <-c.initCh:
+ if c.conn != nil {
+ return c.conn.SetDeadline(t)
+ }
+ default:
+ }
+ return nil
+}
+
+func (c *v5LazyPacketConn) SetReadDeadline(t time.Time) error {
+ select {
+ case <-c.initCh:
+ if c.conn != nil {
+ return c.conn.SetReadDeadline(t)
+ }
+ default:
+ }
+ return nil
+}
+
+func (c *v5LazyPacketConn) SetWriteDeadline(t time.Time) error {
+ select {
+ case <-c.initCh:
+ if c.conn != nil {
+ return c.conn.SetWriteDeadline(t)
+ }
+ default:
+ }
+ return nil
+}
+
+func (h *Outbound) applyObfs(conn net.Conn) net.Conn {
+ obfsHost := h.obfsHost
+ if obfsHost == "" {
+ obfsHost = "bing.com"
+ }
+ switch h.obfsMode {
+ case "http":
+ return obfs.NewHTTPObfs(conn, obfsHost, h.serverPort)
+ case "tls":
+ return obfs.NewTLSObfs(conn, obfsHost)
+ }
+ return conn
+}
+
+// packetConnWrapper wraps net.PacketConn as net.Conn so it can be used in DialContext for UDP networks.
+type packetConnWrapper struct {
+ net.PacketConn
+ destination M.Socksaddr
+}
+
+func (w *packetConnWrapper) Read(p []byte) (int, error) {
+ n, _, err := w.PacketConn.ReadFrom(p)
+ return n, err
+}
+
+func (w *packetConnWrapper) Write(p []byte) (int, error) {
+ return w.PacketConn.WriteTo(p, w.destination)
+}
+
+func (w *packetConnWrapper) RemoteAddr() net.Addr {
+ return w.destination
+}
diff --git a/protocol/socks/inbound.go b/protocol/socks/inbound.go
index 68e0ef5845..0f570b51f8 100644
--- a/protocol/socks/inbound.go
+++ b/protocol/socks/inbound.go
@@ -70,8 +70,8 @@ func (h *Inbound) Close() error {
return h.listener.Close()
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
- err := socks.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection), h.listener, h.udpTimeout, metadata.Source, onClose)
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ err := socks.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), h.authenticator, adapter.NewUpstreamHandler(metadata, h.newUserConnection, h.streamUserPacketConnection), h.listener, h.udpTimeout, metadata.Source, onClose)
N.CloseOnHandshakeFailure(conn, onClose, err)
if err != nil {
if E.IsClosedOrCanceled(err) {
diff --git a/protocol/ssh/inbound.go b/protocol/ssh/inbound.go
new file mode 100644
index 0000000000..3db6661986
--- /dev/null
+++ b/protocol/ssh/inbound.go
@@ -0,0 +1,222 @@
+package ssh
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/inbound"
+ "github.com/sagernet/sing-box/common/listener"
+ "github.com/sagernet/sing-box/common/uot"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+
+ N "github.com/sagernet/sing/common/network"
+ "golang.org/x/crypto/ssh"
+)
+
+// RegisterInbound registers SSH inbound type
+func RegisterInbound(registry *inbound.Registry) {
+ inbound.Register[option.SSHInboundOptions](registry, C.TypeSSH, NewInbound)
+}
+
+// Inbound represents SSH inbound
+type Inbound struct {
+ inbound.Adapter
+ ctx context.Context
+ router adapter.ConnectionRouterEx
+ logger logger.ContextLogger
+ listener *listener.Listener
+ users map[string]option.SSHUser
+ config *ssh.ServerConfig
+}
+
+// NewInbound creates new SSH inbound
+func NewInbound(
+ ctx context.Context,
+ router adapter.Router,
+ logger log.ContextLogger,
+ tag string,
+ options option.SSHInboundOptions,
+) (adapter.Inbound, error) {
+
+ users := map[string]option.SSHUser{}
+ for _, u := range options.Users {
+ users[u.User] = u
+ }
+
+ serverConfig := &ssh.ServerConfig{}
+
+ // Password auth
+ serverConfig.PasswordCallback = func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
+ u, ok := users[c.User()]
+ logger.Debug("checking user pass ", c.User())
+ if !ok || u.Password == "" {
+ return nil, fmt.Errorf("invalid user")
+ }
+ if u.Password != string(pass) {
+ return nil, fmt.Errorf("invalid password")
+ }
+ return &ssh.Permissions{}, nil
+ }
+
+ // PublicKey auth
+ serverConfig.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
+ u, ok := users[c.User()]
+ logger.Debug("checking user pub ", c.User())
+ if !ok || u.PublicKey == "" {
+ return nil, fmt.Errorf("invalid user")
+ }
+
+ parsedKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(u.PublicKey))
+ if err != nil {
+ return nil, err
+ }
+
+ // Compare by Marshal (KeysEqual may not exist)
+ if string(parsedKey.Marshal()) == string(key.Marshal()) {
+ return &ssh.Permissions{}, nil
+ }
+ return nil, fmt.Errorf("invalid key")
+ }
+
+ // HostKeys
+ for _, key := range options.HostKey {
+ privBytes := []byte(key)
+ priv, err := ssh.ParsePrivateKey(privBytes)
+ if err != nil {
+ return nil, err
+ }
+ serverConfig.AddHostKey(priv)
+ }
+
+ in := &Inbound{
+ Adapter: inbound.NewAdapter(C.TypeSSH, tag),
+ ctx: ctx,
+ router: uot.NewRouter(router, logger), // UDP over TCP
+ logger: logger,
+
+ users: users,
+ config: serverConfig,
+ }
+ in.listener = listener.New(listener.Options{
+ Context: ctx,
+ Logger: logger,
+ Listen: options.ListenOptions,
+ Network: []string{"tcp"},
+ ConnectionHandler: in,
+ },
+ )
+
+ return in, nil
+}
+
+// Start listener
+func (h *Inbound) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+
+ if err := h.listener.Start(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+//nolint:staticcheck
+func (h *Inbound) NewConnection(ctx context.Context, rawConn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ ctx = log.ContextWithNewID(ctx)
+ h.logger.Debug("getting connection", fmt.Sprint(metadata))
+ sshConn, chans, reqs, err := ssh.NewServerConn(rawConn, h.config)
+ if err != nil {
+ h.logger.Debug("error connection", err)
+ rawConn.Close()
+ return
+ }
+ defer sshConn.Close()
+ h.logger.Debug("user:", sshConn.User())
+
+ go ssh.DiscardRequests(reqs)
+
+ for newChannel := range chans {
+ h.logger.Debug("channel connection", fmt.Sprintf("%+v", newChannel))
+ if newChannel.ChannelType() != "direct-tcpip" {
+ h.logger.Debug("not direct-tcpip connection", fmt.Sprintf("%+v", newChannel.ChannelType()))
+ newChannel.Reject(ssh.UnknownChannelType, "unsupported")
+ continue
+ }
+ forward := forwardData{}
+ if err := ssh.Unmarshal(newChannel.ExtraData(), &forward); err != nil {
+ newChannel.Reject(ssh.ConnectionFailed, "error parsing forward data: "+err.Error())
+ return
+ }
+ channel, requests, err := newChannel.Accept()
+ if err != nil {
+ continue
+ }
+ go ssh.DiscardRequests(requests)
+
+ h.logger.Debug("Forwarding to ", forward.DestAddr, ":", forward.DestPort)
+
+ go h.routeChannel(ctx, channel, forward, sshConn.User())
+ }
+}
+
+type forwardData struct {
+ DestAddr string
+ DestPort uint32
+
+ OriginAddr string
+ OriginPort uint32
+}
+
+// Close listener
+func (h *Inbound) Close() error {
+ return h.listener.Close()
+}
+
+// routeChannel routes channel to router
+func (h *Inbound) routeChannel(ctx context.Context, channel ssh.Channel, d forwardData, user string) {
+ var metadata adapter.InboundContext
+ metadata.Inbound = h.Tag()
+ metadata.InboundType = h.Type()
+ metadata.User = user
+ metadata.Destination = M.Socksaddr{
+ Port: uint16(d.DestPort),
+ }
+ if ip, err := netip.ParseAddr(d.DestAddr); err == nil {
+ metadata.Destination.Addr = ip
+ } else {
+ metadata.Destination.Fqdn = d.DestAddr
+ }
+
+ h.logger.InfoContext(ctx, "[", user, "] SSH inbound connection")
+ // Wrap channel to net.Conn
+ con := &channelConn{Channel: channel} // localAddr: &net.TCPAddr{IP: net.ParseIP(d.OriginAddr), Port: int(d.OriginPort)},
+ // remoteAddr: &net.TCPAddr{IP: net.ParseIP(d.DestAddr), Port: int(d.DestPort)},
+
+ h.router.RouteConnectionEx(ctx, con, metadata, func(it error) {
+ channel.Close()
+ })
+}
+
+// ----------------- helper: wrap ssh.Channel to net.Conn -----------------
+type channelConn struct {
+ ssh.Channel
+ localAddr net.Addr
+ remoteAddr net.Addr
+}
+
+func (c *channelConn) LocalAddr() net.Addr { return c.localAddr }
+func (c *channelConn) RemoteAddr() net.Addr { return c.remoteAddr }
+func (c *channelConn) SetDeadline(t time.Time) error { return nil }
+func (c *channelConn) SetReadDeadline(t time.Time) error { return nil }
+func (c *channelConn) SetWriteDeadline(t time.Time) error { return nil }
diff --git a/protocol/ssh/outbound.go b/protocol/ssh/outbound.go
index b2f9680747..f93eaac536 100644
--- a/protocol/ssh/outbound.go
+++ b/protocol/ssh/outbound.go
@@ -15,6 +15,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/outbound"
"github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/monitoring"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@@ -23,6 +24,7 @@ import (
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/uot"
"golang.org/x/crypto/ssh"
)
@@ -47,6 +49,8 @@ type Outbound struct {
clientAccess sync.Mutex
clientConn net.Conn
client *ssh.Client
+ uotClient *uot.Client
+ connectionErr string
}
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.SSHOutboundOptions) (adapter.Outbound, error) {
@@ -54,8 +58,9 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
if err != nil {
return nil, err
}
+
outbound := &Outbound{
- Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, tag, []string{N.NetworkTCP}, options.DialerOptions),
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeSSH, tag, options.Network.Build(), options.DialerOptions),
ctx: ctx,
logger: logger,
dialer: outboundDialer,
@@ -108,6 +113,13 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
outbound.hostKey = append(outbound.hostKey, key)
}
}
+ uotOptions := common.PtrValueOrDefault(options.UDPOverTCP)
+ if uotOptions.Enabled {
+ outbound.uotClient = &uot.Client{
+ Dialer: outbound,
+ Version: uotOptions.Version,
+ }
+ }
return outbound, nil
}
@@ -152,6 +164,7 @@ func (s *Outbound) connect() (*ssh.Client, error) {
return nil
}
}
+
return E.New("host key mismatch, server send ", key.Type(), " ", base64.StdEncoding.EncodeToString(serverKey))
},
}
@@ -178,6 +191,14 @@ func (s *Outbound) connect() (*ssh.Client, error) {
return client, nil
}
+func (s *Outbound) PostStart() error {
+ s.connect()
+ if s.IsReady() {
+ monitoring.Get(s.ctx).TestNow(s.Tag())
+ }
+ return nil
+}
+
func (s *Outbound) InterfaceUpdated() {
common.Close(s.clientConn)
}
@@ -187,10 +208,28 @@ func (s *Outbound) Close() error {
}
func (s *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = s.Tag()
+ metadata.Destination = destination
client, err := s.connect()
if err != nil {
+ s.connectionErr = err.Error()
return nil, err
}
+ s.connectionErr = ""
+
+ switch N.NetworkName(network) {
+
+ case N.NetworkTCP:
+ s.logger.InfoContext(ctx, "outbound connection to ", destination)
+ case N.NetworkUDP:
+ if s.uotClient != nil {
+ s.logger.InfoContext(ctx, "outbound UoT connect packet connection to ", destination)
+ return s.uotClient.DialContext(ctx, network, destination)
+ } else {
+ s.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ }
+ }
conn, err := client.Dial(network, destination.String())
if err != nil {
return nil, err
@@ -199,6 +238,16 @@ func (s *Outbound) DialContext(ctx context.Context, network string, destination
}
func (s *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ ctx, metadata := adapter.ExtendContext(ctx)
+ metadata.Outbound = s.Tag()
+ metadata.Destination = destination
+ if s.uotClient != nil {
+ s.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
+ return s.uotClient.ListenPacket(ctx, destination)
+ } else {
+ s.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ }
+
return nil, os.ErrInvalid
}
@@ -217,3 +266,19 @@ func (c *chanConnWrapper) SetReadDeadline(t time.Time) error {
func (c *chanConnWrapper) SetWriteDeadline(t time.Time) error {
return os.ErrInvalid
}
+
+func (s *Outbound) IsReady() bool {
+ return s.client != nil
+}
+func (s *Outbound) ProxyDisplayName() string {
+ str := C.ProxyDisplayName(s.Type())
+ if !s.IsReady() {
+ if s.connectionErr != "" {
+ str += " ❌ "
+ str += s.connectionErr
+ } else {
+ str += " ⚠️ Connecting..."
+ }
+ }
+ return s.connectionErr
+}
diff --git a/protocol/tailscale/certificate_provider.go b/protocol/tailscale/certificate_provider.go
new file mode 100644
index 0000000000..8170943b12
--- /dev/null
+++ b/protocol/tailscale/certificate_provider.go
@@ -0,0 +1,95 @@
+//go:build with_gvisor
+
+package tailscale
+
+import (
+ "context"
+ "crypto/tls"
+ "net"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
+ "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+ "github.com/sagernet/tailscale/client/local"
+)
+
+func RegisterCertificateProvider(registry *certificate.Registry) {
+ certificate.Register[option.TailscaleCertificateProviderOptions](registry, C.TypeTailscale, NewCertificateProvider)
+}
+
+var _ adapter.CertificateProviderService = (*CertificateProvider)(nil)
+
+type CertificateProvider struct {
+ certificate.Adapter
+ endpointTag string
+ endpoint *Endpoint
+ dialer N.Dialer
+ localClient *local.Client
+}
+
+func NewCertificateProvider(ctx context.Context, _ log.ContextLogger, tag string, options option.TailscaleCertificateProviderOptions) (adapter.CertificateProviderService, error) {
+ if options.Endpoint == "" {
+ return nil, E.New("missing tailscale endpoint tag")
+ }
+ endpointManager := service.FromContext[adapter.EndpointManager](ctx)
+ rawEndpoint, loaded := endpointManager.Get(options.Endpoint)
+ if !loaded {
+ return nil, E.New("endpoint not found: ", options.Endpoint)
+ }
+ endpoint, isTailscale := rawEndpoint.(*Endpoint)
+ if !isTailscale {
+ return nil, E.New("endpoint is not Tailscale: ", options.Endpoint)
+ }
+ providerDialer, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: option.DialerOptions{},
+ RemoteIsDomain: true,
+ })
+ if err != nil {
+ return nil, E.Cause(err, "create tailscale certificate provider dialer")
+ }
+ return &CertificateProvider{
+ Adapter: certificate.NewAdapter(C.TypeTailscale, tag),
+ endpointTag: options.Endpoint,
+ endpoint: endpoint,
+ dialer: providerDialer,
+ }, nil
+}
+
+func (p *CertificateProvider) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ localClient, err := p.endpoint.Server().LocalClient()
+ if err != nil {
+ return E.Cause(err, "initialize tailscale local client for endpoint ", p.endpointTag)
+ }
+ originalDial := localClient.Dial
+ localClient.Dial = func(ctx context.Context, network, addr string) (net.Conn, error) {
+ if originalDial != nil && addr == "local-tailscaled.sock:80" {
+ return originalDial(ctx, network, addr)
+ }
+ return p.dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
+ }
+ p.localClient = localClient
+ return nil
+}
+
+func (p *CertificateProvider) Close() error {
+ return nil
+}
+
+func (p *CertificateProvider) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ localClient := p.localClient
+ if localClient == nil {
+ return nil, E.New("Tailscale is not ready yet")
+ }
+ return localClient.GetCertificate(clientHello)
+}
diff --git a/protocol/tailscale/dns_transport.go b/protocol/tailscale/dns_transport.go
index 4195235cf5..25b5aabe07 100644
--- a/protocol/tailscale/dns_transport.go
+++ b/protocol/tailscale/dns_transport.go
@@ -4,6 +4,7 @@ package tailscale
import (
"context"
+ "errors"
"net"
"net/http"
"net/netip"
@@ -28,6 +29,7 @@ import (
"github.com/sagernet/sing/service"
nDNS "github.com/sagernet/tailscale/net/dns"
"github.com/sagernet/tailscale/types/dnstype"
+ "github.com/sagernet/tailscale/util/dnsname"
"github.com/sagernet/tailscale/wgengine/router"
"github.com/sagernet/tailscale/wgengine/wgcfg"
@@ -46,6 +48,7 @@ type DNSTransport struct {
logger logger.ContextLogger
endpointTag string
acceptDefaultResolvers bool
+ acceptSearchDomain bool
dnsRouter adapter.DNSRouter
endpointManager adapter.EndpointManager
endpoint *Endpoint
@@ -53,6 +56,7 @@ type DNSTransport struct {
routePrefixes []netip.Prefix
routes map[string][]adapter.DNSTransport
hosts map[string][]netip.Addr
+ searchDomains []string
defaultResolvers []adapter.DNSTransport
}
@@ -66,6 +70,7 @@ func NewDNSTransport(ctx context.Context, logger log.ContextLogger, tag string,
logger: logger,
endpointTag: options.Endpoint,
acceptDefaultResolvers: options.AcceptDefaultResolvers,
+ acceptSearchDomain: options.AcceptSearchDomain,
dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
endpointManager: service.FromContext[adapter.EndpointManager](ctx),
}, nil
@@ -129,6 +134,9 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
for domain, addresses := range dnsConfig.Hosts {
hosts[domain.WithTrailingDot()] = addresses
}
+ searchDomains := common.Map(dnsConfig.SearchDomains, func(it dnsname.FQDN) string {
+ return it.WithTrailingDot()
+ })
var defaultResolvers []adapter.DNSTransport
for _, resolver := range dnsConfig.DefaultResolvers {
myResolver, err := t.createResolver(directDialerOnce, resolver)
@@ -143,6 +151,7 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
t.routePrefixes = routePrefixes
t.routes = routes
t.hosts = hosts
+ t.searchDomains = searchDomains
t.defaultResolvers = defaultResolvers
t.access.Unlock()
@@ -151,18 +160,19 @@ func (t *DNSTransport) updateDNSServers(routeConfig *router.Config, dnsConfig *n
}
if len(defaultResolvers) > 0 {
- t.logger.Info("updated ", len(routes), " routes, ", len(hosts), " hosts, default resolvers: ",
+ t.logger.Info("updated ", len(routes), " routes, ", len(hosts), " hosts, ", len(searchDomains), " search domains, default resolvers: ",
strings.Join(common.Map(dnsConfig.DefaultResolvers, func(it *dnstype.Resolver) string { return it.Addr }), " "))
} else {
- t.logger.Info("updated ", len(routes), " routes, ", len(hosts), " hosts")
+ t.logger.Info("updated ", len(routes), " routes, ", len(hosts), " hosts, ", len(searchDomains), " search domains")
}
return nil
}
func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dnstype.Resolver) (adapter.DNSTransport, error) {
serverURL, parseURLErr := url.Parse(resolver.Addr)
+ isHTTPScheme := parseURLErr == nil && (serverURL.Scheme == "http" || serverURL.Scheme == "https")
var myDialer N.Dialer
- if parseURLErr == nil && serverURL.Scheme == "http" {
+ if isHTTPScheme && serverURL.Scheme == "http" {
myDialer = t.endpoint
} else {
myDialer = directDialer()
@@ -170,36 +180,39 @@ func (t *DNSTransport) createResolver(directDialer func() N.Dialer, resolver *dn
if len(resolver.BootstrapResolution) > 0 {
bootstrapTransport := transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, M.SocksaddrFrom(resolver.BootstrapResolution[0], 53))
myDialer = dialer.NewResolveDialer(t.ctx, myDialer, false, "", adapter.DNSQueryOptions{Transport: bootstrapTransport}, 0)
- }
- if serverAddr := M.ParseSocksaddr(resolver.Addr); serverAddr.IsValid() {
- if serverAddr.Port == 0 {
- serverAddr.Port = 53
- }
- return transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, serverAddr), nil
- } else if parseURLErr != nil {
- return nil, E.Cause(parseURLErr, "parse resolver address")
} else {
+ myDialer = dialer.NewResolveDialer(t.ctx, myDialer, false, "", t.endpoint.queryOptions, 0)
+ }
+ if isHTTPScheme {
+ serverAddr := M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
switch serverURL.Scheme {
case "https":
- serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
if serverAddr.Port == 0 {
serverAddr.Port = 443
}
tlsConfig := common.Must1(tls.NewClient(t.ctx, t.logger, serverAddr.AddrString(), option.OutboundTLSOptions{
- ALPN: []string{http2.NextProtoTLS, "http/1.1"},
+ Enabled: true,
+ ALPN: []string{http2.NextProtoTLS, "http/1.1"},
}))
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, tlsConfig), nil
case "http":
- serverAddr = M.ParseSocksaddrHostPortStr(serverURL.Hostname(), serverURL.Port())
if serverAddr.Port == 0 {
serverAddr.Port = 80
}
return transport.NewHTTPSRaw(t.TransportAdapter, t.logger, myDialer, serverURL, http.Header{}, serverAddr, nil), nil
- // case "tls":
- default:
- return nil, E.New("unknown resolver scheme: ", serverURL.Scheme)
}
}
+ serverAddr := M.ParseSocksaddr(resolver.Addr)
+ if !serverAddr.IsValid() {
+ if parseURLErr != nil {
+ return nil, E.Cause(parseURLErr, "parse resolver address")
+ }
+ return nil, E.New("invalid resolver address: ", resolver.Addr)
+ }
+ if serverAddr.Port == 0 {
+ serverAddr.Port = 53
+ }
+ return transport.NewUDPRaw(t.logger, t.TransportAdapter, myDialer, serverAddr), nil
}
func buildRoutePrefixes(routeConfig *router.Config) []netip.Prefix {
@@ -246,17 +259,85 @@ func (t *DNSTransport) Raw() bool {
return true
}
+func (t *DNSTransport) PreferredDomain(domain string) bool {
+ t.access.RLock()
+ hosts := t.hosts
+ routes := t.routes
+ t.access.RUnlock()
+ if _, loaded := hosts[domain]; loaded {
+ return true
+ }
+ for suffix := range routes {
+ if strings.HasSuffix(domain, suffix) {
+ return true
+ }
+ }
+ return false
+}
+
func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
if len(message.Question) != 1 {
return nil, os.ErrInvalid
}
+ if t.acceptSearchDomain && mDNS.CountLabel(message.Question[0].Name) == 1 {
+ return t.exchangeWithSearchDomains(ctx, message)
+ }
+ t.access.RLock()
+ acceptDefaultResolvers := t.acceptDefaultResolvers
+ t.access.RUnlock()
+ return t.exchangeOnce(ctx, message, acceptDefaultResolvers)
+}
+
+func (t *DNSTransport) exchangeWithSearchDomains(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
+ t.access.RLock()
+ searchDomains := t.searchDomains
+ t.access.RUnlock()
+ originalQuestion := message.Question[0]
+ singleLabel := strings.TrimSuffix(originalQuestion.Name, ".")
+ var lastErr error
+ for _, searchDomain := range searchDomains {
+ expandedName := singleLabel + "." + searchDomain
+ question := originalQuestion
+ question.Name = expandedName
+ rewritten := *message
+ rewritten.Question = []mDNS.Question{question}
+ response, err := t.exchangeOnce(ctx, &rewritten, false)
+ if err == nil {
+ if response.Rcode == mDNS.RcodeNameError {
+ continue
+ }
+ restoreOriginalQuestion(response, expandedName, originalQuestion)
+ return response, nil
+ }
+ if errors.Is(err, dns.RcodeNameError) {
+ continue
+ }
+ lastErr = err
+ }
+ if lastErr != nil {
+ return nil, lastErr
+ }
+ return nil, dns.RcodeNameError
+}
+
+// RFC 1035 §4.1.1 requires the response Question to match the request byte-for-byte,
+// and stub resolvers discard Answer RRs whose owner name does not match the question.
+func restoreOriginalQuestion(response *mDNS.Msg, expandedName string, originalQuestion mDNS.Question) {
+ response.Question = []mDNS.Question{originalQuestion}
+ for _, rr := range response.Answer {
+ if strings.EqualFold(rr.Header().Name, expandedName) {
+ rr.Header().Name = originalQuestion.Name
+ }
+ }
+}
+
+func (t *DNSTransport) exchangeOnce(ctx context.Context, message *mDNS.Msg, allowDefaultResolvers bool) (*mDNS.Msg, error) {
question := message.Question[0]
t.access.RLock()
hosts := t.hosts
routes := t.routes
defaultResolvers := t.defaultResolvers
- acceptDefaultResolvers := t.acceptDefaultResolvers
t.access.RUnlock()
addresses, hostsLoaded := hosts[question.Name]
@@ -302,7 +383,7 @@ func (t *DNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.M
return nil, lastErr
}
}
- if acceptDefaultResolvers {
+ if allowDefaultResolvers {
if len(defaultResolvers) > 0 {
var lastErr error
for _, resolver := range defaultResolvers {
diff --git a/protocol/tailscale/endpoint.go b/protocol/tailscale/endpoint.go
index 7e5d3542fa..3a742c165f 100644
--- a/protocol/tailscale/endpoint.go
+++ b/protocol/tailscale/endpoint.go
@@ -28,9 +28,10 @@ import (
"github.com/sagernet/sing-box/adapter/endpoint"
"github.com/sagernet/sing-box/common/dialer"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/dns"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing-box/route/rule"
+ R "github.com/sagernet/sing-box/route/rule"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing-tun/ping"
"github.com/sagernet/sing/common"
@@ -51,6 +52,7 @@ import (
"github.com/sagernet/tailscale/net/netns"
"github.com/sagernet/tailscale/net/tsaddr"
tsTUN "github.com/sagernet/tailscale/net/tstun"
+ "github.com/sagernet/tailscale/tailcfg"
"github.com/sagernet/tailscale/tsnet"
"github.com/sagernet/tailscale/types/ipproto"
"github.com/sagernet/tailscale/types/nettype"
@@ -60,6 +62,7 @@ import (
"github.com/sagernet/tailscale/wgengine/router"
"github.com/sagernet/tailscale/wgengine/wgcfg"
+ mDNS "github.com/miekg/dns"
"go4.org/netipx"
)
@@ -82,6 +85,7 @@ type Endpoint struct {
ctx context.Context
router adapter.Router
logger logger.ContextLogger
+ queryOptions adapter.DNSQueryOptions
dnsRouter adapter.DNSRouter
network adapter.NetworkManager
platformInterface adapter.PlatformInterface
@@ -117,45 +121,6 @@ type Endpoint struct {
fallbackTCPCloser func()
}
-func (t *Endpoint) registerNetstackHandlers() {
- netstack := t.server.ExportNetstack()
- if netstack == nil {
- return
- }
- previousTCP := netstack.GetTCPHandlerForFlow
- netstack.GetTCPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
- if previousTCP != nil {
- handler, intercept = previousTCP(src, dst)
- if handler != nil || !intercept {
- return handler, intercept
- }
- }
- return func(conn net.Conn) {
- ctx := log.ContextWithNewID(t.ctx)
- source := M.SocksaddrFrom(src.Addr(), src.Port())
- destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
- t.NewConnectionEx(ctx, conn, source, destination, nil)
- }, true
- }
-
- previousUDP := netstack.GetUDPHandlerForFlow
- netstack.GetUDPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
- if previousUDP != nil {
- handler, intercept = previousUDP(src, dst)
- if handler != nil || !intercept {
- return handler, intercept
- }
- }
- return func(conn nettype.ConnPacketConn) {
- ctx := log.ContextWithNewID(t.ctx)
- source := M.SocksaddrFrom(src.Addr(), src.Port())
- destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
- packetConn := bufio.NewUnbindPacketConnWithAddr(conn, destination)
- t.NewPacketConnectionEx(ctx, packetConn, source, destination, nil)
- }, true
- }
-}
-
func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TailscaleEndpointOptions) (adapter.Endpoint, error) {
stateDirectory := options.StateDirectory
if stateDirectory == "" {
@@ -207,47 +172,48 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
if err != nil {
return nil, err
}
+ dialerQueryOptions := outboundDialer.(dialer.ResolveDialer).QueryOptions()
dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
- server := &tsnet.Server{
- Dir: stateDirectory,
- Hostname: hostname,
- Logf: func(format string, args ...any) {
- logger.Trace(fmt.Sprintf(format, args...))
- },
- UserLogf: func(format string, args ...any) {
- logger.Debug(fmt.Sprintf(format, args...))
- },
- Ephemeral: options.Ephemeral,
- AuthKey: options.AuthKey,
- ControlURL: options.ControlURL,
- AdvertiseTags: options.AdvertiseTags,
- Dialer: &endpointDialer{Dialer: outboundDialer, logger: logger},
- LookupHook: func(ctx context.Context, host string) ([]netip.Addr, error) {
- return dnsRouter.Lookup(ctx, host, outboundDialer.(dialer.ResolveDialer).QueryOptions())
- },
- DNS: &dnsConfigurtor{},
- HTTPClient: &http.Client{
- Transport: &http.Transport{
- ForceAttemptHTTP2: true,
- DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
- return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(address))
- },
- TLSClientConfig: &tls.Config{
- RootCAs: adapter.RootPoolFromContext(ctx),
- Time: ntp.TimeFuncFromContext(ctx),
+ return &Endpoint{
+ Adapter: endpoint.NewAdapter(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, nil),
+ ctx: ctx,
+ router: router,
+ logger: logger,
+ dnsRouter: dnsRouter,
+ queryOptions: dialerQueryOptions,
+ network: service.FromContext[adapter.NetworkManager](ctx),
+ platformInterface: service.FromContext[adapter.PlatformInterface](ctx),
+ server: &tsnet.Server{
+ Dir: stateDirectory,
+ Hostname: hostname,
+ Logf: func(format string, args ...any) {
+ logger.Trace(fmt.Sprintf(format, args...))
+ },
+ UserLogf: func(format string, args ...any) {
+ logger.Debug(fmt.Sprintf(format, args...))
+ },
+ Ephemeral: options.Ephemeral,
+ AuthKey: options.AuthKey,
+ ControlURL: options.ControlURL,
+ AdvertiseTags: options.AdvertiseTags,
+ Dialer: &endpointDialer{Dialer: outboundDialer, logger: logger},
+ LookupHook: func(ctx context.Context, host string) ([]netip.Addr, error) {
+ return dnsRouter.Lookup(ctx, host, dialerQueryOptions)
+ },
+ DNS: &dnsConfigurtor{},
+ HTTPClient: &http.Client{
+ Transport: &http.Transport{
+ ForceAttemptHTTP2: true,
+ DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
+ return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(address))
+ },
+ TLSClientConfig: &tls.Config{
+ RootCAs: adapter.RootPoolFromContext(ctx),
+ Time: ntp.TimeFuncFromContext(ctx),
+ },
},
},
},
- }
- return &Endpoint{
- Adapter: endpoint.NewAdapter(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, nil),
- ctx: ctx,
- router: router,
- logger: logger,
- dnsRouter: dnsRouter,
- network: service.FromContext[adapter.NetworkManager](ctx),
- platformInterface: service.FromContext[adapter.PlatformInterface](ctx),
- server: server,
acceptRoutes: options.AcceptRoutes,
exitNode: options.ExitNode,
exitNodeAllowLANAccess: options.ExitNodeAllowLANAccess,
@@ -265,6 +231,8 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
func (t *Endpoint) Start(stage adapter.StartStage) error {
switch stage {
+ case adapter.StartStateInitialize:
+ t.server.PeerDNSQueryHandler = (*peerDNSQueryHandler)(t)
case adapter.StartStateStart:
return t.start()
case adapter.StartStatePostStart:
@@ -394,7 +362,41 @@ func (t *Endpoint) postStart() error {
ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
t.stack = ipStack
t.icmpForwarder = icmpForwarder
- t.registerNetstackHandlers()
+ netstack := t.server.ExportNetstack()
+ if netstack != nil {
+ previousTCP := netstack.GetTCPHandlerForFlow
+ netstack.GetTCPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(net.Conn), intercept bool) {
+ if previousTCP != nil {
+ handler, intercept = previousTCP(src, dst)
+ if handler != nil || !intercept {
+ return handler, intercept
+ }
+ }
+ return func(conn net.Conn) {
+ ctx := log.ContextWithNewID(t.ctx)
+ source := M.SocksaddrFrom(src.Addr(), src.Port())
+ destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
+ t.NewConnectionEx(ctx, conn, source, destination, nil)
+ }, true
+ }
+
+ previousUDP := netstack.GetUDPHandlerForFlow
+ netstack.GetUDPHandlerForFlow = func(src, dst netip.AddrPort) (handler func(nettype.ConnPacketConn), intercept bool) {
+ if previousUDP != nil {
+ handler, intercept = previousUDP(src, dst)
+ if handler != nil || !intercept {
+ return handler, intercept
+ }
+ }
+ return func(conn nettype.ConnPacketConn) {
+ ctx := log.ContextWithNewID(t.ctx)
+ source := M.SocksaddrFrom(src.Addr(), src.Port())
+ destination := M.SocksaddrFrom(dst.Addr(), dst.Port())
+ packetConn := bufio.NewUnbindPacketConnWithAddr(conn, destination)
+ t.NewPacketConnectionEx(ctx, packetConn, source, destination, nil)
+ }, true
+ }
+ }
localBackend := t.server.ExportLocalBackend()
perfs := &ipn.MaskedPrefs{
@@ -485,6 +487,49 @@ func (t *Endpoint) watchState() {
}
}
+func (t *Endpoint) SetTailscaleExitNode(ctx context.Context, stableID string) error {
+ if !t.started.Load() {
+ return E.New("Tailscale is not ready yet")
+ }
+ if t.advertiseExitNode && stableID != "" {
+ return E.New("cannot advertise an exit node and use an exit node at the same time")
+ }
+ perfs := &ipn.MaskedPrefs{
+ Prefs: ipn.Prefs{
+ ExitNodeID: tailcfg.StableNodeID(stableID),
+ ExitNodeAllowLANAccess: t.exitNodeAllowLANAccess,
+ },
+ ExitNodeIDSet: true,
+ ExitNodeIPSet: true,
+ ExitNodeAllowLANAccessSet: true,
+ }
+ if stableID != "" {
+ status, err := common.Must1(t.server.LocalClient()).Status(ctx)
+ if err != nil {
+ return E.Cause(err, "get tailscale status")
+ }
+ found := false
+ for _, peer := range status.Peer {
+ if peer.ID != tailcfg.StableNodeID(stableID) {
+ continue
+ }
+ if !peer.ExitNodeOption {
+ return E.New("peer does not offer exit node: ", stableID)
+ }
+ found = true
+ break
+ }
+ if !found {
+ return E.New("peer not found: ", stableID)
+ }
+ }
+ _, err := t.server.ExportLocalBackend().EditPrefs(perfs)
+ if err != nil {
+ return E.Cause(err, "update prefs")
+ }
+ return nil
+}
+
func (t *Endpoint) Close() error {
var err error
t.started.Store(false)
@@ -683,9 +728,9 @@ func (t *Endpoint) PrepareConnection(network string, source M.Socksaddr, destina
}, routeContext, timeout, false)
if err != nil {
switch {
- case rule.IsBypassed(err):
+ case R.IsBypassed(err):
err = nil
- case rule.IsRejected(err):
+ case R.IsRejected(err):
t.logger.Trace("reject ", network, " connection from ", source.AddrString(), " to ", destination.AddrString())
default:
if network == N.NetworkICMP {
@@ -879,3 +924,30 @@ func (c *dnsConfigurtor) GetBaseConfig() (tsDNS.OSConfig, error) {
func (c *dnsConfigurtor) Close() error {
return nil
}
+
+type peerDNSQueryHandler Endpoint
+
+func (t *peerDNSQueryHandler) HandlePeerDNSQuery(ctx context.Context, query []byte, sourceAddress netip.AddrPort, allowName func(name string) bool) ([]byte, error) {
+ var message mDNS.Msg
+ err := message.Unpack(query)
+ if err != nil {
+ return nil, err
+ }
+ for _, question := range message.Question {
+ if allowName != nil && !allowName(question.Name) {
+ return dns.FixedResponseStatus(&message, mDNS.RcodeRefused).Pack()
+ }
+ }
+ var metadata adapter.InboundContext
+ metadata.Inbound = t.Tag()
+ metadata.InboundType = t.Type()
+ metadata.Source = M.SocksaddrFromNetIP(sourceAddress)
+ response, err := t.dnsRouter.Exchange(adapter.WithContext(ctx, &metadata), &message, adapter.DNSQueryOptions{})
+ if err != nil {
+ if !R.IsRejected(err) && !E.IsClosedOrCanceled(err) {
+ t.logger.ErrorContext(ctx, E.Cause(err, "process peer DNS query"))
+ }
+ return nil, err
+ }
+ return response.Pack()
+}
diff --git a/protocol/tailscale/hostinfo_tvos.go b/protocol/tailscale/hostinfo_tvos.go
new file mode 100644
index 0000000000..d8e391bb58
--- /dev/null
+++ b/protocol/tailscale/hostinfo_tvos.go
@@ -0,0 +1,16 @@
+//go:build with_gvisor && tvos
+
+package tailscale
+
+import (
+ _ "unsafe"
+
+ "github.com/sagernet/tailscale/types/lazy"
+)
+
+//go:linkname isAppleTV github.com/sagernet/tailscale/version.isAppleTV
+var isAppleTV lazy.SyncValue[bool]
+
+func init() {
+ isAppleTV.Set(true)
+}
diff --git a/protocol/tailscale/ping.go b/protocol/tailscale/ping.go
new file mode 100644
index 0000000000..8bb0476b27
--- /dev/null
+++ b/protocol/tailscale/ping.go
@@ -0,0 +1,55 @@
+//go:build with_gvisor
+
+package tailscale
+
+import (
+ "context"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/tailscale/ipn/ipnstate"
+ "github.com/sagernet/tailscale/tailcfg"
+)
+
+func (t *Endpoint) StartTailscalePing(ctx context.Context, peerIP string, fn func(*adapter.TailscalePingResult)) error {
+ ip, err := netip.ParseAddr(peerIP)
+ if err != nil {
+ return err
+ }
+ localClient, err := t.server.LocalClient()
+ if err != nil {
+ return err
+ }
+ ticker := time.NewTicker(time.Second)
+ defer ticker.Stop()
+ for {
+ result, pingErr := localClient.Ping(ctx, ip, tailcfg.PingDisco)
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
+ if pingErr != nil {
+ fn(&adapter.TailscalePingResult{
+ Error: pingErr.Error(),
+ })
+ } else {
+ fn(convertPingResult(result))
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-ticker.C:
+ }
+ }
+}
+
+func convertPingResult(result *ipnstate.PingResult) *adapter.TailscalePingResult {
+ return &adapter.TailscalePingResult{
+ LatencyMs: result.LatencySeconds * 1000,
+ IsDirect: result.Endpoint != "",
+ Endpoint: result.Endpoint,
+ DERPRegionID: int32(result.DERPRegionID),
+ DERPRegionCode: result.DERPRegionCode,
+ Error: result.Err,
+ }
+}
diff --git a/protocol/tailscale/status.go b/protocol/tailscale/status.go
new file mode 100644
index 0000000000..7441d1761a
--- /dev/null
+++ b/protocol/tailscale/status.go
@@ -0,0 +1,135 @@
+//go:build with_gvisor
+
+package tailscale
+
+import (
+ "context"
+ "slices"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/tailscale/ipn"
+ "github.com/sagernet/tailscale/ipn/ipnstate"
+)
+
+var _ adapter.TailscaleEndpoint = (*Endpoint)(nil)
+
+func (t *Endpoint) SubscribeTailscaleStatus(ctx context.Context, fn func(*adapter.TailscaleEndpointStatus)) error {
+ localBackend := t.server.ExportLocalBackend()
+ sendStatus := func() {
+ status := localBackend.Status()
+ fn(convertTailscaleStatus(status))
+ }
+ sendStatus()
+ localBackend.WatchNotifications(ctx, ipn.NotifyInitialState|ipn.NotifyInitialNetMap|ipn.NotifyRateLimit, nil, func(roNotify *ipn.Notify) (keepGoing bool) {
+ select {
+ case <-ctx.Done():
+ return false
+ default:
+ }
+ if roNotify.State != nil || roNotify.NetMap != nil || roNotify.BrowseToURL != nil || roNotify.Prefs != nil {
+ sendStatus()
+ }
+ return true
+ })
+ return ctx.Err()
+}
+
+func convertTailscaleStatus(status *ipnstate.Status) *adapter.TailscaleEndpointStatus {
+ result := &adapter.TailscaleEndpointStatus{
+ BackendState: status.BackendState,
+ AuthURL: status.AuthURL,
+ }
+ if status.CurrentTailnet != nil {
+ result.NetworkName = status.CurrentTailnet.Name
+ result.MagicDNSSuffix = status.CurrentTailnet.MagicDNSSuffix
+ }
+ if status.Self != nil {
+ result.Self = convertTailscalePeer(status.Self)
+ }
+ groupIndex := make(map[int64]*adapter.TailscaleUserGroup)
+ for _, peerKey := range status.Peers() {
+ peer := status.Peer[peerKey]
+ userID := int64(peer.UserID)
+ group, loaded := groupIndex[userID]
+ if !loaded {
+ group = &adapter.TailscaleUserGroup{
+ UserID: userID,
+ }
+ if profile, hasProfile := status.User[peer.UserID]; hasProfile {
+ group.LoginName = profile.LoginName
+ group.DisplayName = profile.DisplayName
+ group.ProfilePicURL = profile.ProfilePicURL
+ }
+ groupIndex[userID] = group
+ result.UserGroups = append(result.UserGroups, group)
+ }
+ group.Peers = append(group.Peers, convertTailscalePeer(peer))
+ }
+ for _, group := range result.UserGroups {
+ slices.SortStableFunc(group.Peers, func(a, b *adapter.TailscalePeer) int {
+ if a.Online != b.Online {
+ if a.Online {
+ return -1
+ }
+ return 1
+ }
+ return 0
+ })
+ }
+ if status.ExitNodeStatus != nil {
+ for _, peerKey := range status.Peers() {
+ peer := status.Peer[peerKey]
+ if peer.ID == status.ExitNodeStatus.ID {
+ result.ExitNode = convertTailscalePeer(peer)
+ break
+ }
+ }
+ if result.ExitNode == nil {
+ ips := make([]string, 0, len(status.ExitNodeStatus.TailscaleIPs))
+ for _, prefix := range status.ExitNodeStatus.TailscaleIPs {
+ ips = append(ips, prefix.Addr().String())
+ }
+ result.ExitNode = &adapter.TailscalePeer{
+ StableID: string(status.ExitNodeStatus.ID),
+ TailscaleIPs: ips,
+ Online: status.ExitNodeStatus.Online,
+ ExitNode: true,
+ }
+ }
+ }
+ return result
+}
+
+func convertTailscalePeer(peer *ipnstate.PeerStatus) *adapter.TailscalePeer {
+ ips := make([]string, len(peer.TailscaleIPs))
+ for i, ip := range peer.TailscaleIPs {
+ ips[i] = ip.String()
+ }
+ var keyExpiry int64
+ if peer.KeyExpiry != nil {
+ keyExpiry = peer.KeyExpiry.Unix()
+ }
+ var lastSeen int64
+ if !peer.LastSeen.IsZero() {
+ lastSeen = peer.LastSeen.Unix()
+ }
+ return &adapter.TailscalePeer{
+ StableID: string(peer.ID),
+ HostName: peer.HostName,
+ DNSName: peer.DNSName,
+ OS: peer.OS,
+ TailscaleIPs: ips,
+ SSHHostKeys: peer.SSH_HostKeys,
+ Online: peer.Online,
+ ExitNode: peer.ExitNode,
+ ExitNodeOption: peer.ExitNodeOption,
+ ShareeNode: peer.ShareeNode,
+ Expired: peer.Expired,
+ Active: peer.Active,
+ RxBytes: peer.RxBytes,
+ TxBytes: peer.TxBytes,
+ UserID: int64(peer.UserID),
+ KeyExpiry: keyExpiry,
+ LastSeen: lastSeen,
+ }
+}
diff --git a/protocol/tor/outbound.go b/protocol/tor/outbound.go
index 9a0e2d6506..6f0c3fd6d9 100644
--- a/protocol/tor/outbound.go
+++ b/protocol/tor/outbound.go
@@ -10,6 +10,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/outbound"
"github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/common/proxybridge"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
@@ -34,7 +35,7 @@ type Outbound struct {
outbound.Adapter
ctx context.Context
logger logger.ContextLogger
- proxy *ProxyListener
+ proxy *proxybridge.Bridge
startConf *tor.StartConf
options map[string]string
events chan control.Event
@@ -79,11 +80,15 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
if err != nil {
return nil, err
}
+ proxy, err := proxybridge.New(ctx, logger, "proxy", outboundDialer)
+ if err != nil {
+ return nil, err
+ }
return &Outbound{
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTor, tag, []string{N.NetworkTCP}, options.DialerOptions),
ctx: ctx,
logger: logger,
- proxy: NewProxyListener(ctx, logger, outboundDialer),
+ proxy: proxy,
startConf: &startConf,
options: options.Options,
}, nil
@@ -117,10 +122,6 @@ func (t *Outbound) start() error {
return err
}
go t.recvLoop()
- err = t.proxy.Start()
- if err != nil {
- return err
- }
proxyPort := "127.0.0.1:" + F.ToString(t.proxy.Port())
proxyUsername := t.proxy.Username()
proxyPassword := t.proxy.Password()
diff --git a/protocol/tor/proxy.go b/protocol/tor/proxy.go
deleted file mode 100644
index 378e74fc8c..0000000000
--- a/protocol/tor/proxy.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package tor
-
-import (
- std_bufio "bufio"
- "context"
- "crypto/rand"
- "encoding/hex"
- "net"
-
- "github.com/sagernet/sing-box/adapter"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing/common"
- "github.com/sagernet/sing/common/auth"
- E "github.com/sagernet/sing/common/exceptions"
- M "github.com/sagernet/sing/common/metadata"
- N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/protocol/socks"
- "github.com/sagernet/sing/service"
-)
-
-type ProxyListener struct {
- ctx context.Context
- logger log.ContextLogger
- dialer N.Dialer
- connection adapter.ConnectionManager
- tcpListener *net.TCPListener
- username string
- password string
- authenticator *auth.Authenticator
-}
-
-func NewProxyListener(ctx context.Context, logger log.ContextLogger, dialer N.Dialer) *ProxyListener {
- var usernameB [64]byte
- var passwordB [64]byte
- rand.Read(usernameB[:])
- rand.Read(passwordB[:])
- username := hex.EncodeToString(usernameB[:])
- password := hex.EncodeToString(passwordB[:])
- return &ProxyListener{
- ctx: ctx,
- logger: logger,
- dialer: dialer,
- connection: service.FromContext[adapter.ConnectionManager](ctx),
- authenticator: auth.NewAuthenticator([]auth.User{{Username: username, Password: password}}),
- username: username,
- password: password,
- }
-}
-
-func (l *ProxyListener) Start() error {
- tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{
- IP: net.IPv4(127, 0, 0, 1),
- })
- if err != nil {
- return err
- }
- l.tcpListener = tcpListener
- go l.acceptLoop()
- return nil
-}
-
-func (l *ProxyListener) Port() uint16 {
- if l.tcpListener == nil {
- panic("start listener first")
- }
- return M.SocksaddrFromNet(l.tcpListener.Addr()).Port
-}
-
-func (l *ProxyListener) Username() string {
- return l.username
-}
-
-func (l *ProxyListener) Password() string {
- return l.password
-}
-
-func (l *ProxyListener) Close() error {
- return common.Close(l.tcpListener)
-}
-
-func (l *ProxyListener) acceptLoop() {
- for {
- tcpConn, err := l.tcpListener.AcceptTCP()
- if err != nil {
- return
- }
- ctx := log.ContextWithNewID(l.ctx)
- go func() {
- hErr := l.accept(ctx, tcpConn)
- if hErr != nil {
- if E.IsClosedOrCanceled(hErr) {
- l.logger.DebugContext(ctx, E.Cause(hErr, "proxy connection closed"))
- return
- }
- l.logger.ErrorContext(ctx, E.Cause(hErr, "proxy"))
- }
- }()
- }
-}
-
-func (l *ProxyListener) accept(ctx context.Context, conn *net.TCPConn) error {
- return socks.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), l.authenticator, l, nil, 0, M.SocksaddrFromNet(conn.RemoteAddr()), nil)
-}
-
-func (l *ProxyListener) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
- var metadata adapter.InboundContext
- metadata.Source = source
- metadata.Destination = destination
- metadata.Network = N.NetworkTCP
- l.logger.InfoContext(ctx, "proxy connection to ", metadata.Destination)
- l.connection.NewConnection(ctx, l.dialer, conn, metadata, onClose)
-}
-
-func (l *ProxyListener) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
- var metadata adapter.InboundContext
- metadata.Source = source
- metadata.Destination = destination
- metadata.Network = N.NetworkUDP
- l.logger.InfoContext(ctx, "proxy packet connection to ", metadata.Destination)
- l.connection.NewPacketConnection(ctx, l.dialer, conn, metadata, onClose)
-}
diff --git a/protocol/trojan/inbound.go b/protocol/trojan/inbound.go
index 6e11c08897..920589b413 100644
--- a/protocol/trojan/inbound.go
+++ b/protocol/trojan/inbound.go
@@ -84,9 +84,9 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
}
inbound.fallbackAddrTLSNextProto = fallbackAddrNextProto
}
- fallbackHandler = adapter.NewUpstreamContextHandlerEx(inbound.fallbackConnection, nil)
+ fallbackHandler = adapter.NewUpstreamContextHandler(inbound.fallbackConnection, nil)
}
- service := trojan.NewService[int](adapter.NewUpstreamContextHandlerEx(inbound.newConnection, inbound.newPacketConnection), fallbackHandler, logger)
+ service := trojan.NewService[int](adapter.NewUpstreamContextHandler(inbound.newConnection, inbound.newPacketConnection), fallbackHandler, logger)
err := service.UpdateUsers(common.MapIndexed(options.Users, func(index int, it option.TrojanUser) int {
return index
}), common.Map(options.Users, func(it option.TrojanUser) string {
@@ -164,7 +164,7 @@ func (h *Inbound) Close() error {
)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
if h.tlsConfig != nil && h.transport == nil {
tlsConn, err := tls.ServerHandshake(ctx, conn, h.tlsConfig)
if err != nil {
@@ -258,5 +258,5 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
metadata.InboundDetour = h.listener.ListenOptions().Detour
//nolint:staticcheck
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
- (*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
+ (*Inbound)(h).NewConnection(ctx, conn, metadata, onClose)
}
diff --git a/protocol/tuic/inbound.go b/protocol/tuic/inbound.go
index 600c7f93a2..531d426361 100644
--- a/protocol/tuic/inbound.go
+++ b/protocol/tuic/inbound.go
@@ -13,6 +13,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
"github.com/sagernet/sing-quic/tuic"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/auth"
@@ -64,9 +65,18 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
udpTimeout = C.UDPTimeout
}
service, err := tuic.NewService[int](tuic.ServiceOptions{
- Context: ctx,
- Logger: logger,
- TLSConfig: tlsConfig,
+ Context: ctx,
+ Logger: logger,
+ TLSConfig: tlsConfig,
+ QUICOptions: qtls.QUICOptions{
+ IdleTimeout: options.IdleTimeout.Build(),
+ KeepAlivePeriod: options.KeepAlivePeriod.Build(),
+ StreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ InitialPacketSize: options.InitialPacketSize,
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ },
CongestionControl: options.CongestionControl,
AuthTimeout: time.Duration(options.AuthTimeout),
ZeroRTTHandshake: options.ZeroRTTHandshake,
diff --git a/protocol/tuic/outbound.go b/protocol/tuic/outbound.go
index 94d3cb774c..694c845152 100644
--- a/protocol/tuic/outbound.go
+++ b/protocol/tuic/outbound.go
@@ -13,6 +13,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
"github.com/sagernet/sing-quic/tuic"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/bufio"
@@ -65,10 +66,19 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
return nil, err
}
client, err := tuic.NewClient(tuic.ClientOptions{
- Context: ctx,
- Dialer: outboundDialer,
- ServerAddress: options.ServerOptions.Build(),
- TLSConfig: tlsConfig,
+ Context: ctx,
+ Dialer: outboundDialer,
+ ServerAddress: options.ServerOptions.Build(),
+ TLSConfig: tlsConfig,
+ QUICOptions: qtls.QUICOptions{
+ IdleTimeout: options.IdleTimeout.Build(),
+ KeepAlivePeriod: options.KeepAlivePeriod.Build(),
+ StreamReceiveWindow: options.StreamReceiveWindow.Value(),
+ ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
+ MaxConcurrentStreams: options.MaxConcurrentStreams,
+ InitialPacketSize: options.InitialPacketSize,
+ DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
+ },
UUID: userUUID,
Password: options.Password,
CongestionControl: options.CongestionControl,
diff --git a/protocol/tun/hook.go b/protocol/tun/hook.go
deleted file mode 100644
index 1afa643f2d..0000000000
--- a/protocol/tun/hook.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package tun
-
-var HookBeforeCreatePlatformInterface func()
diff --git a/protocol/tun/inbound.go b/protocol/tun/inbound.go
index 6820831a5c..65e87bfdc5 100644
--- a/protocol/tun/inbound.go
+++ b/protocol/tun/inbound.go
@@ -42,6 +42,7 @@ type Inbound struct {
logger log.ContextLogger
tunOptions tun.Options
udpTimeout time.Duration
+ dnsHijackAddress []netip.Addr
stack string
tunIf tun.Tun
tunStack tun.Stack
@@ -160,6 +161,22 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
if nfQueue == 0 {
nfQueue = tun.DefaultAutoRedirectNFQueue
}
+ var includeMACAddress []net.HardwareAddr
+ for i, macString := range options.IncludeMACAddress {
+ mac, macErr := net.ParseMAC(macString)
+ if macErr != nil {
+ return nil, E.Cause(macErr, "parse include_mac_address[", i, "]")
+ }
+ includeMACAddress = append(includeMACAddress, mac)
+ }
+ var excludeMACAddress []net.HardwareAddr
+ for i, macString := range options.ExcludeMACAddress {
+ mac, macErr := net.ParseMAC(macString)
+ if macErr != nil {
+ return nil, E.Cause(macErr, "parse exclude_mac_address[", i, "]")
+ }
+ excludeMACAddress = append(excludeMACAddress, mac)
+ }
networkManager := service.FromContext[adapter.NetworkManager](ctx)
multiPendingPackets := C.IsDarwin && ((options.Stack == "gvisor" && tunMTU < 32768) || (options.Stack != "gvisor" && options.MTU <= 9000))
inbound := &Inbound{
@@ -174,6 +191,8 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
GSO: enableGSO,
Inet4Address: inet4Address,
Inet6Address: inet6Address,
+ DNSMode: options.DNSMode,
+ DNSAddress: options.DNSAddress,
AutoRoute: options.AutoRoute,
IPRoute2TableIndex: tableIndex,
IPRoute2RuleIndex: ruleIndex,
@@ -197,6 +216,8 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
IncludeAndroidUser: options.IncludeAndroidUser,
IncludePackage: options.IncludePackage,
ExcludePackage: options.ExcludePackage,
+ IncludeMACAddress: includeMACAddress,
+ ExcludeMACAddress: excludeMACAddress,
InterfaceMonitor: networkManager.InterfaceMonitor(),
EXP_MultiPendingPackets: multiPendingPackets,
},
@@ -292,6 +313,12 @@ func (t *Inbound) Tag() string {
func (t *Inbound) Start(stage adapter.StartStage) error {
switch stage {
+ case adapter.StartStateInitialize:
+ if t.tunOptions.DNSModeOrDefault() != tun.DNSModeDisabled && len(t.tunOptions.DNSAddress) == 0 {
+ inet4DNSAddress, _ := t.tunOptions.Inet4DNSAddress()
+ inet6DNSAddress, _ := t.tunOptions.Inet6DNSAddress()
+ t.dnsHijackAddress = append(inet4DNSAddress, inet6DNSAddress...)
+ }
case adapter.StartStateStart:
if C.IsAndroid && t.platformInterface == nil {
t.tunOptions.BuildAndroidRules(t.networkManager.PackageManager())
@@ -355,9 +382,6 @@ func (t *Inbound) Start(stage adapter.StartStage) error {
if t.platformInterface != nil && t.platformInterface.UsePlatformInterface() {
tunInterface, err = t.platformInterface.OpenInterface(&tunOptions, t.platformOptions)
} else {
- if HookBeforeCreatePlatformInterface != nil {
- HookBeforeCreatePlatformInterface()
- }
tunInterface, err = tun.New(tunOptions)
}
monitor.Finish()
@@ -472,9 +496,17 @@ func (t *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, source M.S
metadata.InboundType = C.TypeTun
metadata.Source = source
metadata.Destination = destination
-
- t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
- t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ for _, dnsHijackAddress := range t.dnsHijackAddress {
+ if destination.Addr == dnsHijackAddress {
+ metadata.Protocol = C.ProtocolDNS
+ }
+ }
+ if metadata.Protocol == C.ProtocolDNS {
+ t.logger.InfoContext(ctx, "inbound DNS connection from ", metadata.Source)
+ } else {
+ t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
+ t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ }
t.router.RouteConnectionEx(ctx, conn, metadata, onClose)
}
@@ -485,9 +517,17 @@ func (t *Inbound) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn,
metadata.InboundType = C.TypeTun
metadata.Source = source
metadata.Destination = destination
-
- t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
- t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
+ for _, dnsHijackAddress := range t.dnsHijackAddress {
+ if destination.Addr == dnsHijackAddress {
+ metadata.Protocol = C.ProtocolDNS
+ }
+ }
+ if metadata.Protocol == C.ProtocolDNS {
+ t.logger.InfoContext(ctx, "inbound DNS packet connection from ", metadata.Source)
+ } else {
+ t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
+ t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
+ }
t.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}
@@ -530,9 +570,17 @@ func (t *autoRedirectHandler) NewConnectionEx(ctx context.Context, conn net.Conn
metadata.InboundType = C.TypeTun
metadata.Source = source
metadata.Destination = destination
-
- t.logger.InfoContext(ctx, "inbound redirect connection from ", metadata.Source)
- t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ for _, dnsHijackAddress := range t.dnsHijackAddress {
+ if destination.Addr == dnsHijackAddress {
+ metadata.Protocol = C.ProtocolDNS
+ }
+ }
+ if metadata.Protocol == C.ProtocolDNS {
+ t.logger.InfoContext(ctx, "inbound redirect DNS connection from ", metadata.Source)
+ } else {
+ t.logger.InfoContext(ctx, "inbound redirect connection from ", metadata.Source)
+ t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
+ }
t.router.RouteConnectionEx(ctx, conn, metadata, onClose)
}
diff --git a/protocol/tunnel/client.go b/protocol/tunnel/client.go
new file mode 100644
index 0000000000..45255c1f81
--- /dev/null
+++ b/protocol/tunnel/client.go
@@ -0,0 +1,152 @@
+package tunnel
+
+import (
+ "context"
+ "net"
+ "os"
+ "time"
+
+ "github.com/gofrs/uuid/v5"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterClientEndpoint(registry *endpoint.Registry) {
+ endpoint.Register[option.TunnelClientEndpointOptions](registry, C.TypeTunnelClient, NewClientEndpoint)
+}
+
+type ClientEndpoint struct {
+ outbound.Adapter
+ ctx context.Context
+ outbound adapter.Outbound
+ router adapter.ConnectionRouterEx
+ logger logger.ContextLogger
+ uuid uuid.UUID
+ key uuid.UUID
+}
+
+func NewClientEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunnelClientEndpointOptions) (adapter.Endpoint, error) {
+ clientUUID, err := uuid.FromString(options.UUID)
+ if err != nil {
+ return nil, err
+ }
+ clientKey, err := uuid.FromString(options.Key)
+ if err != nil {
+ return nil, err
+ }
+ client := &ClientEndpoint{
+ Adapter: outbound.NewAdapter(C.TypeTunnelClient, tag, []string{N.NetworkTCP}, []string{}),
+ ctx: ctx,
+ router: router,
+ logger: logger,
+ uuid: clientUUID,
+ key: clientKey,
+ }
+ outboundRegistry := service.FromContext[adapter.OutboundRegistry](ctx)
+ outbound, err := outboundRegistry.CreateOutbound(ctx, router, logger, options.Outbound.Tag, options.Outbound.Type, options.Outbound.Options)
+ if err != nil {
+ return nil, err
+ }
+ client.outbound = outbound
+ return client, nil
+}
+
+func (c *ClientEndpoint) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStatePostStart {
+ return nil
+ }
+ for range 5 {
+ go func() {
+ for {
+ select {
+ case <-c.ctx.Done():
+ return
+ default:
+ err := c.startInboundConn()
+ if err != nil {
+ c.logger.ErrorContext(c.ctx, err)
+ time.Sleep(time.Second * 5)
+ }
+ }
+ }
+ }()
+ }
+ return nil
+}
+
+func (c *ClientEndpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if network != N.NetworkTCP {
+ return nil, os.ErrInvalid
+ }
+ var destinationUUID *uuid.UUID
+ if metadata := adapter.ContextFrom(ctx); metadata != nil {
+ if metadata.TunnelDestination != "" {
+ uuid, err := uuid.FromString(metadata.TunnelDestination)
+ if err != nil {
+ return nil, err
+ }
+ destinationUUID = &uuid
+ }
+ }
+ if destinationUUID == nil {
+ return nil, E.New("tunnel destination not set")
+ }
+ if *destinationUUID == c.uuid {
+ return nil, E.New("routing loop")
+ }
+ conn, err := c.outbound.DialContext(ctx, N.NetworkTCP, Destination)
+ if err != nil {
+ return nil, err
+ }
+ err = WriteRequest(conn, &Request{UUID: c.key, Command: CommandTCP, DestinationUUID: *destinationUUID, Destination: destination})
+ return conn, err
+}
+
+func (c *ClientEndpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ return nil, os.ErrInvalid
+}
+
+func (c *ClientEndpoint) Close() error {
+ return common.Close(c.outbound)
+}
+
+func (c *ClientEndpoint) startInboundConn() error {
+ conn, err := c.outbound.DialContext(c.ctx, N.NetworkTCP, Destination)
+ if err != nil {
+ return err
+ }
+ err = WriteRequest(conn, &Request{UUID: c.key, Command: CommandInbound, Destination: Destination})
+ if err != nil {
+ return err
+ }
+ request, err := ReadRequest(conn)
+ if err != nil {
+ return err
+ }
+ go c.connHandler(conn, request)
+ return nil
+}
+
+func (c *ClientEndpoint) connHandler(conn net.Conn, request *Request) {
+ metadata := adapter.InboundContext{
+ Source: M.ParseSocksaddr(conn.RemoteAddr().String()),
+ Destination: request.Destination,
+ }
+ if request.UUID == c.uuid {
+ c.logger.ErrorContext(c.ctx, "routing loop")
+ conn.Close()
+ return
+ }
+ metadata.TunnelSource = request.UUID.String()
+ c.router.RouteConnectionEx(c.ctx, conn, metadata, func(it error) {})
+}
diff --git a/protocol/tunnel/protocol.go b/protocol/tunnel/protocol.go
new file mode 100644
index 0000000000..19e6f1cd62
--- /dev/null
+++ b/protocol/tunnel/protocol.go
@@ -0,0 +1,91 @@
+package tunnel
+
+import (
+ "encoding/binary"
+ "io"
+
+ "github.com/gofrs/uuid/v5"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+)
+
+const (
+ Version = 0
+)
+
+const (
+ CommandInbound = 1
+ CommandTCP = 2
+)
+
+var Destination = M.Socksaddr{
+ Fqdn: "sp.tunnel.sing-box.arpa",
+ Port: 444,
+}
+
+var AddressSerializer = M.NewSerializer(
+ M.AddressFamilyByte(0x01, M.AddressFamilyIPv4),
+ M.AddressFamilyByte(0x03, M.AddressFamilyIPv6),
+ M.AddressFamilyByte(0x02, M.AddressFamilyFqdn),
+ M.PortThenAddress(),
+)
+
+type Request struct {
+ UUID uuid.UUID
+ Command byte
+ DestinationUUID uuid.UUID
+ Destination M.Socksaddr
+}
+
+func ReadRequest(reader io.Reader) (*Request, error) {
+ var request Request
+ var version uint8
+ err := binary.Read(reader, binary.BigEndian, &version)
+ if err != nil {
+ return nil, err
+ }
+ if version != Version {
+ return nil, E.New("unknown version: ", version)
+ }
+ _, err = io.ReadFull(reader, request.UUID[:])
+ if err != nil {
+ return nil, err
+ }
+ err = binary.Read(reader, binary.BigEndian, &request.Command)
+ if err != nil {
+ return nil, err
+ }
+ _, err = io.ReadFull(reader, request.DestinationUUID[:])
+ if err != nil {
+ return nil, err
+ }
+ request.Destination, err = AddressSerializer.ReadAddrPort(reader)
+ if err != nil {
+ return nil, err
+ }
+ return &request, nil
+}
+
+func WriteRequest(writer io.Writer, request *Request) error {
+ var requestLen int
+ requestLen += 1 // version
+ requestLen += 16 // UUID
+ requestLen += 16 // destinationUUID
+ requestLen += 1 // command
+ requestLen += AddressSerializer.AddrPortLen(request.Destination)
+ buffer := buf.NewSize(requestLen)
+ defer buffer.Release()
+ common.Must(
+ buffer.WriteByte(Version),
+ common.Error(buffer.Write(request.UUID[:])),
+ buffer.WriteByte(request.Command),
+ common.Error(buffer.Write(request.DestinationUUID[:])),
+ )
+ err := AddressSerializer.WriteAddrPort(buffer, request.Destination)
+ if err != nil {
+ return err
+ }
+ return common.Error(writer.Write(buffer.Bytes()))
+}
diff --git a/protocol/tunnel/router.go b/protocol/tunnel/router.go
new file mode 100644
index 0000000000..e2e708b542
--- /dev/null
+++ b/protocol/tunnel/router.go
@@ -0,0 +1,41 @@
+package tunnel
+
+import (
+ "context"
+ "net"
+ "os"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+)
+
+type Router struct {
+ adapter.Router
+ logger logger.ContextLogger
+ handler func(context.Context, net.Conn, adapter.InboundContext, N.CloseHandlerFunc) error
+}
+
+func NewRouter(router adapter.Router, logger logger.ContextLogger, handler func(context.Context, net.Conn, adapter.InboundContext, N.CloseHandlerFunc) error) *Router {
+ return &Router{Router: router, logger: logger, handler: handler}
+}
+
+func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
+ return r.handler(ctx, conn, metadata, func(error) {})
+}
+
+func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
+ return os.ErrInvalid
+}
+
+func (r *Router) RouteConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ if err := r.handler(ctx, conn, metadata, onClose); err != nil {
+ r.logger.ErrorContext(ctx, err)
+ N.CloseOnHandshakeFailure(conn, onClose, err)
+ }
+}
+
+func (r *Router) RoutePacketConnectionEx(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ r.logger.ErrorContext(ctx, os.ErrInvalid)
+ N.CloseOnHandshakeFailure(conn, onClose, os.ErrInvalid)
+}
diff --git a/protocol/tunnel/server.go b/protocol/tunnel/server.go
new file mode 100644
index 0000000000..d447be8c65
--- /dev/null
+++ b/protocol/tunnel/server.go
@@ -0,0 +1,203 @@
+package tunnel
+
+import (
+ "context"
+ "net"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/gofrs/uuid/v5"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterServerEndpoint(registry *endpoint.Registry) {
+ endpoint.Register[option.TunnelServerEndpointOptions](registry, C.TypeTunnelServer, NewServerEndpoint)
+}
+
+type ServerEndpoint struct {
+ outbound.Adapter
+ logger logger.ContextLogger
+ inbound adapter.Inbound
+ router adapter.Router
+ uuid uuid.UUID
+ users map[uuid.UUID]uuid.UUID
+ keys map[uuid.UUID]uuid.UUID
+ conns map[uuid.UUID]chan net.Conn
+ timeout time.Duration
+
+ mtx sync.Mutex
+}
+
+func NewServerEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.TunnelServerEndpointOptions) (adapter.Endpoint, error) {
+ serverUUID, err := uuid.FromString(options.UUID)
+ if err != nil {
+ return nil, err
+ }
+ server := &ServerEndpoint{
+ Adapter: outbound.NewAdapter(C.TypeTunnelServer, tag, []string{N.NetworkTCP}, []string{}),
+ logger: logger,
+ router: router,
+ uuid: serverUUID,
+ }
+ inboundRegistry := service.FromContext[adapter.InboundRegistry](ctx)
+ inbound, err := inboundRegistry.Create(ctx, NewRouter(router, logger, server.connHandler), logger, options.Inbound.Tag, options.Inbound.Type, options.Inbound.Options)
+ if err != nil {
+ return nil, err
+ }
+ server.inbound = inbound
+ server.users = make(map[uuid.UUID]uuid.UUID, len(options.Users))
+ server.keys = make(map[uuid.UUID]uuid.UUID, len(options.Users))
+ server.conns = make(map[uuid.UUID]chan net.Conn)
+ for _, user := range options.Users {
+ key, err := uuid.FromString(user.Key)
+ if err != nil {
+ return nil, err
+ }
+ uuid, err := uuid.FromString(user.UUID)
+ if err != nil {
+ return nil, err
+ }
+ server.users[key] = uuid
+ server.keys[uuid] = key
+ server.conns[uuid] = make(chan net.Conn, 10)
+ }
+ if options.ConnectTimeout != 0 {
+ server.timeout = time.Duration(options.ConnectTimeout)
+ } else {
+ server.timeout = C.TCPConnectTimeout
+ }
+ return server, nil
+}
+
+func (s *ServerEndpoint) Start(stage adapter.StartStage) error {
+ return s.inbound.Start(stage)
+}
+
+func (s *ServerEndpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if network != N.NetworkTCP {
+ return nil, os.ErrInvalid
+ }
+ var sourceUUID *uuid.UUID
+ var ch chan net.Conn
+ if metadata := adapter.ContextFrom(ctx); metadata != nil {
+ if metadata.TunnelDestination != "" {
+ tunnelDestination, err := uuid.FromString(metadata.TunnelDestination)
+ if err != nil {
+ return nil, err
+ }
+ s.mtx.Lock()
+ var ok bool
+ ch, ok = s.conns[tunnelDestination]
+ if !ok {
+ return nil, E.New("user ", metadata.TunnelDestination, " not found")
+ }
+ s.mtx.Unlock()
+ }
+ if metadata.TunnelSource != "" {
+ tunnelSource, err := uuid.FromString(metadata.TunnelSource)
+ if err != nil {
+ return nil, err
+ }
+ sourceUUID = &tunnelSource
+ }
+ }
+ if ch == nil {
+ return nil, E.New("tunnel destination not set")
+ }
+ if sourceUUID == nil {
+ sourceUUID = &s.uuid
+ }
+ ctx, cancel := context.WithTimeout(ctx, s.timeout)
+ defer cancel()
+ for {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+ select {
+ case conn := <-ch:
+ err := WriteRequest(conn, &Request{UUID: *sourceUUID, Command: CommandTCP, Destination: destination})
+ if err != nil {
+ s.logger.ErrorContext(ctx, err)
+ continue
+ }
+ return conn, nil
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+ }
+}
+
+func (s *ServerEndpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ return nil, os.ErrInvalid
+}
+
+func (s *ServerEndpoint) Close() error {
+ return common.Close(s.inbound)
+}
+
+func (s *ServerEndpoint) connHandler(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
+ if metadata.Destination != Destination {
+ s.router.RouteConnectionEx(ctx, conn, metadata, onClose)
+ return nil
+ }
+ request, err := ReadRequest(conn)
+ if err != nil {
+ return err
+ }
+ if request.Command == CommandInbound {
+ s.mtx.Lock()
+ defer s.mtx.Unlock()
+ uuid, ok := s.users[request.UUID]
+ if !ok {
+ return E.New("key ", request.UUID.String(), " not found")
+ }
+ ch := s.conns[uuid]
+ select {
+ case ch <- conn:
+ default:
+ oldConn := <-ch
+ oldConn.Close()
+ ch <- conn
+ }
+ return nil
+ }
+ if request.Command == CommandTCP {
+ sourceUUID, ok := s.users[request.UUID]
+ if !ok {
+ return E.New("key ", request.UUID, " not found")
+ }
+ if sourceUUID == request.DestinationUUID {
+ return E.New("routing loop on ", sourceUUID)
+ }
+ s.mtx.Lock()
+ if request.DestinationUUID != s.uuid {
+ _, ok = s.keys[request.DestinationUUID]
+ if !ok {
+ return E.New("user ", sourceUUID, " not found")
+ }
+ }
+ s.mtx.Unlock()
+ metadata.Inbound = s.Tag()
+ metadata.InboundType = C.TypeTunnelServer
+ metadata.Destination = request.Destination
+ metadata.TunnelSource = sourceUUID.String()
+ metadata.TunnelDestination = request.DestinationUUID.String()
+ s.router.RouteConnectionEx(ctx, conn, metadata, onClose)
+ return nil
+ }
+ return E.New("command ", request.Command, " not found")
+}
diff --git a/protocol/vless/encryption/client.go b/protocol/vless/encryption/client.go
new file mode 100644
index 0000000000..947b279e33
--- /dev/null
+++ b/protocol/vless/encryption/client.go
@@ -0,0 +1,214 @@
+package encryption
+
+import (
+ "crypto/cipher"
+ "crypto/ecdh"
+ "crypto/mlkem"
+ "crypto/rand"
+ "io"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/cpuid"
+ E "github.com/sagernet/sing/common/exceptions"
+ "lukechampine.com/blake3"
+)
+
+type ClientInstance struct {
+ NfsPKeys []any
+ NfsPKeysBytes [][]byte
+ Hash32s [][32]byte
+ RelaysLength int
+ XorMode uint32
+ Seconds uint32
+ PaddingLens [][3]int
+ PaddingGaps [][3]int
+
+ RWLock sync.RWMutex
+ Expire time.Time
+ PfsKey []byte
+ Ticket []byte
+}
+
+func (i *ClientInstance) Init(nfsPKeysBytes [][]byte, xorMode, seconds uint32, padding string) (err error) {
+ if i.NfsPKeys != nil {
+ return E.New("already initialized")
+ }
+ l := len(nfsPKeysBytes)
+ if l == 0 {
+ return E.New("empty nfsPKeysBytes")
+ }
+ i.NfsPKeys = make([]any, l)
+ i.NfsPKeysBytes = nfsPKeysBytes
+ i.Hash32s = make([][32]byte, l)
+ for j, k := range nfsPKeysBytes {
+ if len(k) == 32 {
+ if i.NfsPKeys[j], err = ecdh.X25519().NewPublicKey(k); err != nil {
+ return
+ }
+ i.RelaysLength += 32 + 32
+ } else {
+ if i.NfsPKeys[j], err = mlkem.NewEncapsulationKey768(k); err != nil {
+ return
+ }
+ i.RelaysLength += 1088 + 32
+ }
+ i.Hash32s[j] = blake3.Sum256(k)
+ }
+ i.RelaysLength -= 32
+ i.XorMode = xorMode
+ i.Seconds = seconds
+ return ParsePadding(padding, &i.PaddingLens, &i.PaddingGaps)
+}
+
+func (i *ClientInstance) IsFullRandomXorMode() bool {
+ return i.XorMode == 2
+}
+
+func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) {
+ if i.NfsPKeys == nil {
+ return nil, E.New("uninitialized")
+ }
+ c := NewCommonConn(conn, cpuid.HasAESGCM)
+
+ ivAndRealysLength := 16 + i.RelaysLength
+ pfsKeyExchangeLength := 18 + 1184 + 32 + 16
+ paddingLength, paddingLens, paddingGaps := CreatePadding(i.PaddingLens, i.PaddingGaps)
+ clientHello := make([]byte, ivAndRealysLength+pfsKeyExchangeLength+paddingLength)
+
+ iv := clientHello[:16]
+ rand.Read(iv)
+ relays := clientHello[16:ivAndRealysLength]
+ var nfsKey []byte
+ var lastCTR cipher.Stream
+ for j, k := range i.NfsPKeys {
+ var index = 32
+ if k, ok := k.(*ecdh.PublicKey); ok {
+ privateKey, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ copy(relays, privateKey.PublicKey().Bytes())
+ var err error
+ nfsKey, err = privateKey.ECDH(k)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if k, ok := k.(*mlkem.EncapsulationKey768); ok {
+ var ciphertext []byte
+ nfsKey, ciphertext = k.Encapsulate()
+ copy(relays, ciphertext)
+ index = 1088
+ }
+ if i.XorMode > 0 { // this xor can (others can't) be recovered by client's config, revealing an X25519 public key / ML-KEM-768 ciphertext, that's why "native" values
+ NewCTR(i.NfsPKeysBytes[j], iv).XORKeyStream(relays, relays[:index]) // make X25519 public key / ML-KEM-768 ciphertext distinguishable from random bytes
+ }
+ if lastCTR != nil {
+ lastCTR.XORKeyStream(relays, relays[:32]) // make this relay irreplaceable
+ }
+ if j == len(i.NfsPKeys)-1 {
+ break
+ }
+ lastCTR = NewCTR(nfsKey, iv)
+ lastCTR.XORKeyStream(relays[index:], i.Hash32s[j+1][:])
+ relays = relays[index+32:]
+ }
+ nfsAEAD := NewAEAD(iv, nfsKey, c.UseAES)
+
+ if i.Seconds > 0 {
+ i.RWLock.RLock()
+ if time.Now().Before(i.Expire) {
+ c.Client = i
+ c.UnitedKey = append(i.PfsKey, nfsKey...) // different unitedKey for each connection
+ nfsAEAD.Seal(clientHello[:ivAndRealysLength], nil, EncodeLength(32), nil)
+ nfsAEAD.Seal(clientHello[:ivAndRealysLength+18], nil, i.Ticket, nil)
+ i.RWLock.RUnlock()
+ c.PreWrite = clientHello[:ivAndRealysLength+18+32]
+ c.AEAD = NewAEAD(clientHello[ivAndRealysLength+18:ivAndRealysLength+18+32], c.UnitedKey, c.UseAES)
+ if i.XorMode == 2 {
+ c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, iv), nil, len(c.PreWrite), 16)
+ }
+ return c, nil
+ }
+ i.RWLock.RUnlock()
+ }
+
+ pfsKeyExchange := clientHello[ivAndRealysLength : ivAndRealysLength+pfsKeyExchangeLength]
+ nfsAEAD.Seal(pfsKeyExchange[:0], nil, EncodeLength(pfsKeyExchangeLength-18), nil)
+ mlkem768DKey, _ := mlkem.GenerateKey768()
+ x25519SKey, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ pfsPublicKey := append(mlkem768DKey.EncapsulationKey().Bytes(), x25519SKey.PublicKey().Bytes()...)
+ nfsAEAD.Seal(pfsKeyExchange[:18], nil, pfsPublicKey, nil)
+
+ padding := clientHello[ivAndRealysLength+pfsKeyExchangeLength:]
+ nfsAEAD.Seal(padding[:0], nil, EncodeLength(paddingLength-18), nil)
+ nfsAEAD.Seal(padding[:18], nil, padding[18:paddingLength-16], nil)
+
+ paddingLens[0] = ivAndRealysLength + pfsKeyExchangeLength + paddingLens[0]
+ for i, l := range paddingLens { // sends padding in a fragmented way, to create variable traffic pattern, before inner VLESS flow takes control
+ if l > 0 {
+ if _, err := conn.Write(clientHello[:l]); err != nil {
+ return nil, err
+ }
+ clientHello = clientHello[l:]
+ }
+ if len(paddingGaps) > i {
+ time.Sleep(paddingGaps[i])
+ }
+ }
+
+ encryptedPfsPublicKey := make([]byte, 1088+32+16)
+ if _, err := io.ReadFull(conn, encryptedPfsPublicKey); err != nil {
+ return nil, err
+ }
+ nfsAEAD.Open(encryptedPfsPublicKey[:0], MaxNonce, encryptedPfsPublicKey, nil)
+ mlkem768Key, err := mlkem768DKey.Decapsulate(encryptedPfsPublicKey[:1088])
+ if err != nil {
+ return nil, err
+ }
+ peerX25519PKey, err := ecdh.X25519().NewPublicKey(encryptedPfsPublicKey[1088 : 1088+32])
+ if err != nil {
+ return nil, err
+ }
+ x25519Key, err := x25519SKey.ECDH(peerX25519PKey)
+ if err != nil {
+ return nil, err
+ }
+ pfsKey := make([]byte, 32+32) // no more capacity
+ copy(pfsKey, mlkem768Key)
+ copy(pfsKey[32:], x25519Key)
+ c.UnitedKey = append(pfsKey, nfsKey...)
+ c.AEAD = NewAEAD(pfsPublicKey, c.UnitedKey, c.UseAES)
+ c.PeerAEAD = NewAEAD(encryptedPfsPublicKey[:1088+32], c.UnitedKey, c.UseAES)
+
+ encryptedTicket := make([]byte, 32)
+ if _, err := io.ReadFull(conn, encryptedTicket); err != nil {
+ return nil, err
+ }
+ if _, err := c.PeerAEAD.Open(encryptedTicket[:0], nil, encryptedTicket, nil); err != nil {
+ return nil, err
+ }
+ seconds := DecodeLength(encryptedTicket)
+
+ if i.Seconds > 0 && seconds > 0 {
+ i.RWLock.Lock()
+ i.Expire = time.Now().Add(time.Duration(seconds) * time.Second)
+ i.PfsKey = pfsKey
+ i.Ticket = encryptedTicket[:16]
+ i.RWLock.Unlock()
+ }
+
+ encryptedLength := make([]byte, 18)
+ if _, err := io.ReadFull(conn, encryptedLength); err != nil {
+ return nil, err
+ }
+ if _, err := c.PeerAEAD.Open(encryptedLength[:0], nil, encryptedLength, nil); err != nil {
+ return nil, err
+ }
+ length := DecodeLength(encryptedLength[:2])
+ c.PeerPadding = make([]byte, length) // important: allows server sends padding slowly, eliminating 1-RTT's traffic pattern
+
+ if i.XorMode == 2 {
+ c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, iv), NewCTR(c.UnitedKey, encryptedTicket[:16]), 0, length)
+ }
+ return c, nil
+}
diff --git a/protocol/vless/encryption/common.go b/protocol/vless/encryption/common.go
new file mode 100644
index 0000000000..84e3818dbb
--- /dev/null
+++ b/protocol/vless/encryption/common.go
@@ -0,0 +1,297 @@
+package encryption
+
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/crypto"
+ E "github.com/sagernet/sing/common/exceptions"
+ "golang.org/x/crypto/chacha20poly1305"
+ "lukechampine.com/blake3"
+)
+
+var OutBytesPool = sync.Pool{
+ New: func() any {
+ return make([]byte, 5+8192+16)
+ },
+}
+
+type EncryptionConn interface {
+ net.Conn
+ IsEncryptionLayer() bool
+}
+
+type CommonConn struct {
+ net.Conn
+ UseAES bool
+ Client *ClientInstance
+ UnitedKey []byte
+ PreWrite []byte
+ AEAD *AEAD
+ PeerAEAD *AEAD
+ PeerPadding []byte
+ rawInput bytes.Buffer
+ input bytes.Reader
+}
+
+func NewCommonConn(conn net.Conn, useAES bool) *CommonConn {
+ return &CommonConn{
+ Conn: conn,
+ UseAES: useAES,
+ }
+}
+
+func (c *CommonConn) Write(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+ outBytes := OutBytesPool.Get().([]byte)
+ defer OutBytesPool.Put(outBytes)
+ for n := 0; n < len(b); {
+ b := b[n:]
+ if len(b) > 8192 {
+ b = b[:8192] // for avoiding another copy() in peer's Read()
+ }
+ n += len(b)
+ headerAndData := outBytes[:5+len(b)+16]
+ EncodeHeader(headerAndData, len(b)+16)
+ max := false
+ if bytes.Equal(c.AEAD.Nonce[:], MaxNonce) {
+ max = true
+ }
+ c.AEAD.Seal(headerAndData[:5], nil, b, headerAndData[:5])
+ if max {
+ c.AEAD = NewAEAD(headerAndData, c.UnitedKey, c.UseAES)
+ }
+ if c.PreWrite != nil {
+ headerAndData = append(c.PreWrite, headerAndData...)
+ c.PreWrite = nil
+ }
+ if _, err := c.Conn.Write(headerAndData); err != nil {
+ return 0, err
+ }
+ }
+ return len(b), nil
+}
+
+func (c *CommonConn) Read(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+ if c.PeerAEAD == nil { // client's 0-RTT
+ serverRandom := make([]byte, 16)
+ if _, err := io.ReadFull(c.Conn, serverRandom); err != nil {
+ return 0, err
+ }
+ c.PeerAEAD = NewAEAD(serverRandom, c.UnitedKey, c.UseAES)
+ if xorConn, ok := c.Conn.(*XorConn); ok {
+ xorConn.PeerCTR = NewCTR(c.UnitedKey, serverRandom)
+ }
+ }
+ if c.PeerPadding != nil { // client's 1-RTT
+ if _, err := io.ReadFull(c.Conn, c.PeerPadding); err != nil {
+ return 0, err
+ }
+ if _, err := c.PeerAEAD.Open(c.PeerPadding[:0], nil, c.PeerPadding, nil); err != nil {
+ return 0, err
+ }
+ c.PeerPadding = nil
+ }
+ if c.input.Len() > 0 {
+ return c.input.Read(b)
+ }
+ peerHeader := [5]byte{}
+ if _, err := io.ReadFull(c.Conn, peerHeader[:]); err != nil {
+ return 0, err
+ }
+ l, err := DecodeHeader(peerHeader[:]) // l: 17~17000
+ if err != nil {
+ if c.Client != nil && errors.Is(err, ErrInvalidHeader) { // client's 0-RTT
+ c.Client.RWLock.Lock()
+ if bytes.HasPrefix(c.UnitedKey, c.Client.PfsKey) {
+ c.Client.Expire = time.Now() // expired
+ }
+ c.Client.RWLock.Unlock()
+ return 0, E.New("new handshake needed")
+ }
+ return 0, err
+ }
+ c.Client = nil
+ if c.rawInput.Cap() < l {
+ c.rawInput.Grow(l) // no need to use sync.Pool, because we are always reading
+ }
+ peerData := c.rawInput.Bytes()[:l]
+ if _, err := io.ReadFull(c.Conn, peerData); err != nil {
+ return 0, err
+ }
+ dst := peerData[:l-16]
+ if len(dst) <= len(b) {
+ dst = b[:len(dst)] // avoids another copy()
+ }
+ var newAEAD *AEAD
+ if bytes.Equal(c.PeerAEAD.Nonce[:], MaxNonce) {
+ newAEAD = NewAEAD(append(peerHeader[:], peerData...), c.UnitedKey, c.UseAES)
+ }
+ _, err = c.PeerAEAD.Open(dst[:0], nil, peerData, peerHeader[:])
+ if newAEAD != nil {
+ c.PeerAEAD = newAEAD
+ }
+ if err != nil {
+ return 0, err
+ }
+ if len(dst) > len(b) {
+ c.input.Reset(dst[copy(b, dst):])
+ dst = b // for len(dst)
+ }
+ return len(dst), nil
+}
+
+// Upstream returns the underlying connection, allowing Vision to unwrap and access the TLS connection
+func (c *CommonConn) Upstream() any {
+ return c.Conn
+}
+
+func (c *CommonConn) IsEncryptionLayer() bool {
+ return true
+}
+
+type AEAD struct {
+ cipher.AEAD
+ Nonce [12]byte
+}
+
+func NewAEAD(ctx, key []byte, useAES bool) *AEAD {
+ k := make([]byte, 32)
+ blake3.DeriveKey(k, string(ctx), key)
+ var aead cipher.AEAD
+ if useAES {
+ block, _ := aes.NewCipher(k)
+ aead, _ = cipher.NewGCM(block)
+ } else {
+ aead, _ = chacha20poly1305.New(k)
+ }
+ return &AEAD{AEAD: aead}
+}
+
+func (a *AEAD) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
+ if nonce == nil {
+ nonce = IncreaseNonce(a.Nonce[:])
+ }
+ return a.AEAD.Seal(dst, nonce, plaintext, additionalData)
+}
+
+func (a *AEAD) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+ if nonce == nil {
+ nonce = IncreaseNonce(a.Nonce[:])
+ }
+ return a.AEAD.Open(dst, nonce, ciphertext, additionalData)
+}
+
+func IncreaseNonce(nonce []byte) []byte {
+ for i := range 12 {
+ nonce[11-i]++
+ if nonce[11-i] != 0 {
+ break
+ }
+ }
+ return nonce
+}
+
+var MaxNonce = bytes.Repeat([]byte{255}, 12)
+
+func EncodeLength(l int) []byte {
+ return []byte{byte(l >> 8), byte(l)}
+}
+
+func DecodeLength(b []byte) int {
+ return int(b[0])<<8 | int(b[1])
+}
+
+func EncodeHeader(h []byte, l int) {
+ h[0] = 23
+ h[1] = 3
+ h[2] = 3
+ h[3] = byte(l >> 8)
+ h[4] = byte(l)
+}
+
+var ErrInvalidHeader = errors.New("invalid header")
+
+func DecodeHeader(h []byte) (l int, err error) {
+ l = int(h[3])<<8 | int(h[4])
+ if h[0] != 23 || h[1] != 3 || h[2] != 3 {
+ l = 0
+ }
+ if l < 17 || l > 17000 { // TODO: TLSv1.3 max length
+ err = fmt.Errorf("%w: %v", ErrInvalidHeader, h[:5]) // DO NOT CHANGE: relied by client's Read()
+ }
+ return
+}
+
+func ParsePadding(padding string, paddingLens, paddingGaps *[][3]int) (err error) {
+ if padding == "" {
+ return
+ }
+ maxLen := 0
+ for i, s := range strings.Split(padding, ".") {
+ x := strings.Split(s, "-")
+ if len(x) < 3 || x[0] == "" || x[1] == "" || x[2] == "" {
+ return E.New("invalid padding lenth/gap parameter: " + s)
+ }
+ y := [3]int{}
+ if y[0], err = strconv.Atoi(x[0]); err != nil {
+ return
+ }
+ if y[1], err = strconv.Atoi(x[1]); err != nil {
+ return
+ }
+ if y[2], err = strconv.Atoi(x[2]); err != nil {
+ return
+ }
+ if i == 0 && (y[0] < 100 || y[1] < 18+17 || y[2] < 18+17) {
+ return E.New("first padding length must not be smaller than 35")
+ }
+ if i%2 == 0 {
+ *paddingLens = append(*paddingLens, y)
+ maxLen += max(y[1], y[2])
+ } else {
+ *paddingGaps = append(*paddingGaps, y)
+ }
+ }
+ if maxLen > 18+65535 {
+ return E.New("total padding length must not be larger than 65553")
+ }
+ return
+}
+
+func CreatePadding(paddingLens, paddingGaps [][3]int) (length int, lens []int, gaps []time.Duration) {
+ if len(paddingLens) == 0 {
+ paddingLens = [][3]int{{100, 111, 1111}, {50, 0, 3333}}
+ paddingGaps = [][3]int{{75, 0, 111}}
+ }
+ for _, y := range paddingLens {
+ l := 0
+ if y[0] >= int(crypto.RandBetween(0, 100)) {
+ l = int(crypto.RandBetween(int64(y[1]), int64(y[2])))
+ }
+ lens = append(lens, l)
+ length += l
+ }
+ for _, y := range paddingGaps {
+ g := 0
+ if y[0] >= int(crypto.RandBetween(0, 100)) {
+ g = int(crypto.RandBetween(int64(y[1]), int64(y[2])))
+ }
+ gaps = append(gaps, time.Duration(g)*time.Millisecond)
+ }
+ return
+}
diff --git a/protocol/vless/encryption/server.go b/protocol/vless/encryption/server.go
new file mode 100644
index 0000000000..6e25f166c1
--- /dev/null
+++ b/protocol/vless/encryption/server.go
@@ -0,0 +1,336 @@
+package encryption
+
+import (
+ "bytes"
+ "crypto/cipher"
+ "crypto/ecdh"
+ "crypto/mlkem"
+ "crypto/rand"
+ "fmt"
+ "io"
+ "net"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/crypto"
+ E "github.com/sagernet/sing/common/exceptions"
+ "lukechampine.com/blake3"
+)
+
+type ServerSession struct {
+ PfsKey []byte
+ NfsKeys sync.Map
+}
+
+type ServerInstance struct {
+ NfsSKeys []any
+ NfsPKeysBytes [][]byte
+ Hash32s [][32]byte
+ RelaysLength int
+ XorMode uint32
+ SecondsFrom int64
+ SecondsTo int64
+ PaddingLens [][3]int
+ PaddingGaps [][3]int
+
+ RWLock sync.RWMutex
+ Closed bool
+ Lasts map[int64][16]byte
+ Tickets [][16]byte
+ Sessions map[[16]byte]*ServerSession
+}
+
+func (i *ServerInstance) Init(nfsSKeysBytes [][]byte, xorMode uint32, secondsFrom, secondsTo int64, padding string) (err error) {
+ if i.NfsSKeys != nil {
+ return E.New("already initialized")
+ }
+ l := len(nfsSKeysBytes)
+ if l == 0 {
+ return E.New("empty nfsSKeysBytes")
+ }
+ i.NfsSKeys = make([]any, l)
+ i.NfsPKeysBytes = make([][]byte, l)
+ i.Hash32s = make([][32]byte, l)
+ for j, k := range nfsSKeysBytes {
+ if len(k) == 32 {
+ if i.NfsSKeys[j], err = ecdh.X25519().NewPrivateKey(k); err != nil {
+ return
+ }
+ i.NfsPKeysBytes[j] = i.NfsSKeys[j].(*ecdh.PrivateKey).PublicKey().Bytes()
+ i.RelaysLength += 32 + 32
+ } else {
+ if i.NfsSKeys[j], err = mlkem.NewDecapsulationKey768(k); err != nil {
+ return
+ }
+ i.NfsPKeysBytes[j] = i.NfsSKeys[j].(*mlkem.DecapsulationKey768).EncapsulationKey().Bytes()
+ i.RelaysLength += 1088 + 32
+ }
+ i.Hash32s[j] = blake3.Sum256(i.NfsPKeysBytes[j])
+ }
+ i.RelaysLength -= 32
+ i.XorMode = xorMode
+ i.SecondsFrom = secondsFrom
+ i.SecondsTo = secondsTo
+ err = ParsePadding(padding, &i.PaddingLens, &i.PaddingGaps)
+ if err != nil {
+ return
+ }
+ if i.SecondsFrom > 0 || i.SecondsTo > 0 {
+ i.Lasts = make(map[int64][16]byte)
+ i.Tickets = make([][16]byte, 0, 1024)
+ i.Sessions = make(map[[16]byte]*ServerSession)
+ go func() {
+ for {
+ time.Sleep(time.Minute)
+ i.RWLock.Lock()
+ if i.Closed {
+ i.RWLock.Unlock()
+ return
+ }
+ minute := time.Now().Unix() / 60
+ last := i.Lasts[minute]
+ delete(i.Lasts, minute)
+ delete(i.Lasts, minute-1) // for insurance
+ if last != [16]byte{} {
+ for j, ticket := range i.Tickets {
+ delete(i.Sessions, ticket)
+ if ticket == last {
+ i.Tickets = i.Tickets[j+1:]
+ break
+ }
+ }
+ }
+ i.RWLock.Unlock()
+ }
+ }()
+ }
+ return
+}
+
+func (i *ServerInstance) Close() (err error) {
+ i.RWLock.Lock()
+ i.Closed = true
+ i.RWLock.Unlock()
+ return
+}
+
+func (i *ServerInstance) IsXorMode() bool {
+ return i.XorMode > 0
+}
+
+func (i *ServerInstance) IsFullRandomXorMode() bool {
+ return i.XorMode == 2
+}
+
+func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn, error) {
+ if i.NfsSKeys == nil {
+ return nil, E.New("uninitialized")
+ }
+ c := NewCommonConn(conn, true)
+
+ ivAndRelays := make([]byte, 16+i.RelaysLength)
+ if _, err := io.ReadFull(conn, ivAndRelays); err != nil {
+ return nil, err
+ }
+ if fallback != nil {
+ *fallback = append(*fallback, ivAndRelays...)
+ }
+ iv := ivAndRelays[:16]
+ relays := ivAndRelays[16:]
+ var nfsKey []byte
+ var lastCTR cipher.Stream
+ for j, k := range i.NfsSKeys {
+ if lastCTR != nil {
+ lastCTR.XORKeyStream(relays, relays[:32]) // recover this relay
+ }
+ var index = 32
+ if _, ok := k.(*mlkem.DecapsulationKey768); ok {
+ index = 1088
+ }
+ if i.XorMode > 0 {
+ NewCTR(i.NfsPKeysBytes[j], iv).XORKeyStream(relays, relays[:index]) // we don't use buggy elligator2, because we have PSK :)
+ }
+ if k, ok := k.(*ecdh.PrivateKey); ok {
+ publicKey, err := ecdh.X25519().NewPublicKey(relays[:index])
+ if err != nil {
+ return nil, err
+ }
+ if publicKey.Bytes()[31] > 127 { // we just don't want the observer can change even one bit without breaking the connection, though it has nothing to do with security
+ return nil, E.New("the highest bit of the last byte of the peer-sent X25519 public key is not 0")
+ }
+ nfsKey, err = k.ECDH(publicKey)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if k, ok := k.(*mlkem.DecapsulationKey768); ok {
+ var err error
+ nfsKey, err = k.Decapsulate(relays[:index])
+ if err != nil {
+ return nil, err
+ }
+ }
+ if j == len(i.NfsSKeys)-1 {
+ break
+ }
+ relays = relays[index:]
+ lastCTR = NewCTR(nfsKey, iv)
+ lastCTR.XORKeyStream(relays, relays[:32])
+ if !bytes.Equal(relays[:32], i.Hash32s[j+1][:]) {
+ return nil, E.New("unexpected hash32: " + fmt.Sprintf("%v", relays[:32]))
+ }
+ relays = relays[32:]
+ }
+ nfsAEAD := NewAEAD(iv, nfsKey, c.UseAES)
+
+ encryptedLength := make([]byte, 18)
+ if _, err := io.ReadFull(conn, encryptedLength); err != nil {
+ return nil, err
+ }
+ if fallback != nil {
+ *fallback = append(*fallback, encryptedLength...)
+ }
+ decryptedLength := make([]byte, 2)
+ if _, err := nfsAEAD.Open(decryptedLength[:0], nil, encryptedLength, nil); err != nil {
+ c.UseAES = !c.UseAES
+ nfsAEAD = NewAEAD(iv, nfsKey, c.UseAES)
+ if _, err := nfsAEAD.Open(decryptedLength[:0], nil, encryptedLength, nil); err != nil {
+ return nil, err
+ }
+ }
+ if fallback != nil {
+ *fallback = nil
+ }
+ length := DecodeLength(decryptedLength)
+
+ if length == 32 {
+ if i.SecondsFrom == 0 && i.SecondsTo == 0 {
+ return nil, E.New("0-RTT is not allowed")
+ }
+ encryptedTicket := make([]byte, 32)
+ if _, err := io.ReadFull(conn, encryptedTicket); err != nil {
+ return nil, err
+ }
+ ticket, err := nfsAEAD.Open(nil, nil, encryptedTicket, nil)
+ if err != nil {
+ return nil, err
+ }
+ i.RWLock.RLock()
+ s := i.Sessions[[16]byte(ticket)]
+ i.RWLock.RUnlock()
+ if s == nil {
+ noises := make([]byte, crypto.RandBetween(1279, 2279)) // matches 1-RTT's server hello length for "random", though it is not important, just for example
+ var err error
+ for err == nil {
+ rand.Read(noises)
+ _, err = DecodeHeader(noises)
+ }
+ conn.Write(noises) // make client do new handshake
+ return nil, E.New("expired ticket")
+ }
+ if _, loaded := s.NfsKeys.LoadOrStore([32]byte(nfsKey), true); loaded { // prevents bad client also
+ return nil, E.New("replay detected")
+ }
+ c.UnitedKey = append(s.PfsKey, nfsKey...) // the same nfsKey links the upload & download (prevents server -> client's another request)
+ c.PreWrite = make([]byte, 16)
+ rand.Read(c.PreWrite) // always trust yourself, not the client (also prevents being parsed as TLS thus causing false interruption for "native" and "xorpub")
+ c.AEAD = NewAEAD(c.PreWrite, c.UnitedKey, c.UseAES)
+ c.PeerAEAD = NewAEAD(encryptedTicket, c.UnitedKey, c.UseAES) // unchangeable ctx (prevents server -> server), and different ctx length for upload / download (prevents client -> client)
+ if i.XorMode == 2 {
+ c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, c.PreWrite), NewCTR(c.UnitedKey, iv), 16, 0) // it doesn't matter if the attacker sends client's iv back to the client
+ }
+ return c, nil
+ }
+
+ if length < 1184+32+16 { // client may send more public keys in the future's version
+ return nil, E.New("too short length")
+ }
+ encryptedPfsPublicKey := make([]byte, length)
+ if _, err := io.ReadFull(conn, encryptedPfsPublicKey); err != nil {
+ return nil, err
+ }
+ if _, err := nfsAEAD.Open(encryptedPfsPublicKey[:0], nil, encryptedPfsPublicKey, nil); err != nil {
+ return nil, err
+ }
+ mlkem768EKey, err := mlkem.NewEncapsulationKey768(encryptedPfsPublicKey[:1184])
+ if err != nil {
+ return nil, err
+ }
+ mlkem768Key, encapsulatedPfsKey := mlkem768EKey.Encapsulate()
+ peerX25519PKey, err := ecdh.X25519().NewPublicKey(encryptedPfsPublicKey[1184 : 1184+32])
+ if err != nil {
+ return nil, err
+ }
+ x25519SKey, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ x25519Key, err := x25519SKey.ECDH(peerX25519PKey)
+ if err != nil {
+ return nil, err
+ }
+ pfsKey := make([]byte, 32+32) // no more capacity
+ copy(pfsKey, mlkem768Key)
+ copy(pfsKey[32:], x25519Key)
+ pfsPublicKey := append(encapsulatedPfsKey, x25519SKey.PublicKey().Bytes()...)
+ c.UnitedKey = append(pfsKey, nfsKey...)
+ c.AEAD = NewAEAD(pfsPublicKey, c.UnitedKey, c.UseAES)
+ c.PeerAEAD = NewAEAD(encryptedPfsPublicKey[:1184+32], c.UnitedKey, c.UseAES)
+
+ ticket := [16]byte{}
+ rand.Read(ticket[:])
+ var seconds int64
+ if i.SecondsTo == 0 {
+ seconds = i.SecondsFrom * crypto.RandBetween(50, 100) / 100
+ } else {
+ seconds = crypto.RandBetween(i.SecondsFrom, i.SecondsTo)
+ }
+ copy(ticket[:], EncodeLength(int(seconds)))
+ if seconds > 0 {
+ i.RWLock.Lock()
+ i.Lasts[(time.Now().Unix()+max(i.SecondsFrom, i.SecondsTo))/60+2] = ticket
+ i.Tickets = append(i.Tickets, ticket)
+ i.Sessions[ticket] = &ServerSession{PfsKey: pfsKey}
+ i.RWLock.Unlock()
+ }
+
+ pfsKeyExchangeLength := 1088 + 32 + 16
+ encryptedTicketLength := 32
+ paddingLength, paddingLens, paddingGaps := CreatePadding(i.PaddingLens, i.PaddingGaps)
+ serverHello := make([]byte, pfsKeyExchangeLength+encryptedTicketLength+paddingLength)
+ nfsAEAD.Seal(serverHello[:0], MaxNonce, pfsPublicKey, nil)
+ c.AEAD.Seal(serverHello[:pfsKeyExchangeLength], nil, ticket[:], nil)
+ padding := serverHello[pfsKeyExchangeLength+encryptedTicketLength:]
+ c.AEAD.Seal(padding[:0], nil, EncodeLength(paddingLength-18), nil)
+ c.AEAD.Seal(padding[:18], nil, padding[18:paddingLength-16], nil)
+
+ paddingLens[0] = pfsKeyExchangeLength + encryptedTicketLength + paddingLens[0]
+ for i, l := range paddingLens { // sends padding in a fragmented way, to create variable traffic pattern, before inner VLESS flow takes control
+ if l > 0 {
+ if _, err := conn.Write(serverHello[:l]); err != nil {
+ return nil, err
+ }
+ serverHello = serverHello[l:]
+ }
+ if len(paddingGaps) > i {
+ time.Sleep(paddingGaps[i])
+ }
+ }
+
+ // important: allows client sends padding slowly, eliminating 1-RTT's traffic pattern
+ if _, err := io.ReadFull(conn, encryptedLength); err != nil {
+ return nil, err
+ }
+ if _, err := nfsAEAD.Open(encryptedLength[:0], nil, encryptedLength, nil); err != nil {
+ return nil, err
+ }
+ encryptedPadding := make([]byte, DecodeLength(encryptedLength[:2]))
+ if _, err := io.ReadFull(conn, encryptedPadding); err != nil {
+ return nil, err
+ }
+ if _, err := nfsAEAD.Open(encryptedPadding[:0], nil, encryptedPadding, nil); err != nil {
+ return nil, err
+ }
+
+ if i.XorMode == 2 {
+ c.Conn = NewXorConn(conn, NewCTR(c.UnitedKey, ticket[:]), NewCTR(c.UnitedKey, iv), 0, 0)
+ }
+ return c, nil
+}
diff --git a/protocol/vless/encryption/xor.go b/protocol/vless/encryption/xor.go
new file mode 100644
index 0000000000..ac7bd58deb
--- /dev/null
+++ b/protocol/vless/encryption/xor.go
@@ -0,0 +1,101 @@
+package encryption
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "net"
+
+ "lukechampine.com/blake3"
+)
+
+func NewCTR(key, iv []byte) cipher.Stream {
+ k := make([]byte, 32)
+ blake3.DeriveKey(k, "VLESS", key) // avoids using key directly
+ block, _ := aes.NewCipher(k)
+ return cipher.NewCTR(block, iv)
+}
+
+type XorConn struct {
+ net.Conn
+ CTR cipher.Stream
+ PeerCTR cipher.Stream
+ OutSkip int
+ OutHeader []byte
+ InSkip int
+ InHeader []byte
+}
+
+func NewXorConn(conn net.Conn, ctr, peerCTR cipher.Stream, outSkip, inSkip int) *XorConn {
+ return &XorConn{
+ Conn: conn,
+ CTR: ctr,
+ PeerCTR: peerCTR,
+ OutSkip: outSkip,
+ OutHeader: make([]byte, 0, 5), // important
+ InSkip: inSkip,
+ InHeader: make([]byte, 0, 5), // important
+ }
+}
+
+func (c *XorConn) Write(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+ for p := b; ; {
+ if len(p) <= c.OutSkip {
+ c.OutSkip -= len(p)
+ break
+ }
+ p = p[c.OutSkip:]
+ c.OutSkip = 0
+ need := 5 - len(c.OutHeader)
+ if len(p) < need {
+ c.OutHeader = append(c.OutHeader, p...)
+ c.CTR.XORKeyStream(p, p)
+ break
+ }
+ c.OutSkip, _ = DecodeHeader(append(c.OutHeader, p[:need]...))
+ c.OutHeader = c.OutHeader[:0]
+ c.CTR.XORKeyStream(p[:need], p[:need])
+ p = p[need:]
+ }
+ if _, err := c.Conn.Write(b); err != nil {
+ return 0, err
+ }
+ return len(b), nil
+}
+
+func (c *XorConn) Read(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+ n, err := c.Conn.Read(b)
+ for p := b[:n]; ; {
+ if len(p) <= c.InSkip {
+ c.InSkip -= len(p)
+ break
+ }
+ p = p[c.InSkip:]
+ c.InSkip = 0
+ need := 5 - len(c.InHeader)
+ if len(p) < need {
+ c.PeerCTR.XORKeyStream(p, p)
+ c.InHeader = append(c.InHeader, p...)
+ break
+ }
+ c.PeerCTR.XORKeyStream(p[:need], p[:need])
+ c.InSkip, _ = DecodeHeader(append(c.InHeader, p[:need]...))
+ c.InHeader = c.InHeader[:0]
+ p = p[need:]
+ }
+ return n, err
+}
+
+// Upstream returns the underlying connection, allowing Vision to unwrap and access the TLS connection
+func (c *XorConn) Upstream() any {
+ return c.Conn
+}
+
+func (c *XorConn) IsEncryptionLayer() bool {
+ return true
+}
diff --git a/protocol/vless/inbound.go b/protocol/vless/inbound.go
index 75cd4124cd..62ae39840f 100644
--- a/protocol/vless/inbound.go
+++ b/protocol/vless/inbound.go
@@ -2,8 +2,11 @@ package vless
import (
"context"
+ "encoding/base64"
"net"
"os"
+ "strconv"
+ "strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/inbound"
@@ -14,6 +17,7 @@ import (
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/protocol/vless/encryption"
"github.com/sagernet/sing-box/transport/v2ray"
"github.com/sagernet/sing-vmess/packetaddr"
"github.com/sagernet/sing-vmess/vless"
@@ -35,14 +39,15 @@ var _ adapter.TCPInjectableInbound = (*Inbound)(nil)
type Inbound struct {
inbound.Adapter
- ctx context.Context
- router adapter.ConnectionRouterEx
- logger logger.ContextLogger
- listener *listener.Listener
- users []option.VLESSUser
- service *vless.Service[int]
- tlsConfig tls.ServerConfig
- transport adapter.V2RayServerTransport
+ ctx context.Context
+ router adapter.ConnectionRouterEx
+ logger logger.ContextLogger
+ listener *listener.Listener
+ users []option.VLESSUser
+ service *vless.Service[int]
+ tlsConfig tls.ServerConfig
+ transport adapter.V2RayServerTransport
+ decryption *encryption.ServerInstance
}
func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSInboundOptions) (adapter.Inbound, error) {
@@ -58,7 +63,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
if err != nil {
return nil, err
}
- service := vless.NewService[int](logger, adapter.NewUpstreamContextHandlerEx(inbound.newConnectionEx, inbound.newPacketConnectionEx))
+ service := vless.NewService[int](logger, adapter.NewUpstreamContextHandler(inbound.newConnectionEx, inbound.newPacketConnectionEx))
service.UpdateUsers(common.MapIndexed(inbound.users, func(index int, _ option.VLESSUser) int {
return index
}), common.Map(inbound.users, func(it option.VLESSUser) string {
@@ -68,16 +73,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
}))
inbound.service = service
if options.TLS != nil {
- inbound.tlsConfig, err = tls.NewServerWithOptions(tls.ServerOptions{
- Context: ctx,
- Logger: logger,
- Options: common.PtrValueOrDefault(options.TLS),
- KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" &&
- !common.PtrValueOrDefault(options.Multiplex).Enabled &&
- common.All(options.Users, func(it option.VLESSUser) bool {
- return it.Flow == ""
- }),
- })
+ inbound.tlsConfig, err = tls.NewServer(ctx, logger, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
@@ -88,6 +84,18 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
return nil, E.Cause(err, "create server transport: ", options.Transport.Type)
}
}
+ // Parse decryption configuration
+ if options.Decryption != "" && options.Decryption != "none" {
+ decryptionConfig, err := parseServerDecryption(options.Decryption)
+ if err != nil {
+ return nil, E.Cause(err, "parse decryption")
+ }
+ inbound.decryption = &encryption.ServerInstance{}
+ if err := inbound.decryption.Init(decryptionConfig.keys, decryptionConfig.xorMode, decryptionConfig.secondsFrom, decryptionConfig.secondsTo, decryptionConfig.padding); err != nil {
+ return nil, E.Cause(err, "initialize decryption")
+ }
+ logger.Debug("decryption initialized with ", len(decryptionConfig.keys), " keys xorMode=", decryptionConfig.xorMode, " secondsFrom=", decryptionConfig.secondsFrom, " secondsTo=", decryptionConfig.secondsTo, " padding=", decryptionConfig.padding)
+ }
inbound.listener = listener.New(listener.Options{
Context: ctx,
Logger: logger,
@@ -139,6 +147,9 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
}
func (h *Inbound) Close() error {
+ if h.decryption != nil {
+ h.decryption.Close()
+ }
return common.Close(
h.service,
h.listener,
@@ -147,7 +158,15 @@ func (h *Inbound) Close() error {
)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+ canSplice := h.transport == nil
+ if canSplice && h.decryption != nil && h.decryption.IsFullRandomXorMode() {
+ canSplice = false
+ }
+ h.newConnectionExInternal(ctx, conn, metadata, onClose, canSplice)
+}
+
+func (h *Inbound) newConnectionExInternal(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc, canSplice bool) {
if h.tlsConfig != nil && h.transport == nil {
tlsConn, err := tls.ServerHandshake(ctx, conn, h.tlsConfig)
if err != nil {
@@ -157,7 +176,17 @@ func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
}
conn = tlsConn
}
- err := h.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, metadata.Source, onClose)
+ // Apply decryption if configured
+ if h.decryption != nil {
+ encConn, err := h.decryption.Handshake(conn, nil)
+ if err != nil {
+ N.CloseOnHandshakeFailure(conn, onClose, err)
+ h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source, ": encryption handshake"))
+ return
+ }
+ conn = encConn
+ }
+ err := h.service.NewConnectionWithOptions(adapter.WithContext(ctx, &metadata), conn, metadata.Source, onClose, canSplice)
if err != nil {
N.CloseOnHandshakeFailure(conn, onClose, err)
h.logger.ErrorContext(ctx, E.Cause(err, "process connection from ", metadata.Source))
@@ -206,6 +235,90 @@ func (h *Inbound) newPacketConnectionEx(ctx context.Context, conn N.PacketConn,
h.router.RoutePacketConnectionEx(ctx, conn, metadata, onClose)
}
+type serverDecryptionConfig struct {
+ keys [][]byte
+ xorMode uint32
+ secondsFrom int64
+ secondsTo int64
+ padding string
+}
+
+func parseServerDecryption(raw string) (serverDecryptionConfig, error) {
+ var cfg serverDecryptionConfig
+ raw = strings.TrimSpace(raw)
+ if raw == "" {
+ return cfg, E.New("empty decryption string")
+ }
+ parts := strings.Split(raw, ".")
+ if len(parts) < 4 {
+ return cfg, E.New("invalid decryption string: missing components")
+ }
+ if parts[0] != "mlkem768x25519plus" {
+ return cfg, E.New("unsupported decryption prefix: ", parts[0])
+ }
+ switch parts[1] {
+ case "native":
+ cfg.xorMode = 0
+ case "xorpub":
+ cfg.xorMode = 1
+ case "random":
+ cfg.xorMode = 2
+ default:
+ return cfg, E.New("unknown decryption mode: ", parts[1])
+ }
+
+ secondsToken := strings.TrimSpace(parts[2])
+ if secondsToken == "" {
+ return cfg, E.New("invalid decryption seconds segment")
+ }
+ trimmed := strings.TrimSuffix(secondsToken, "s")
+ if trimmed == "" {
+ return cfg, E.New("invalid decryption seconds segment")
+ }
+ values := strings.SplitN(trimmed, "-", 2)
+ secondsFrom, err := strconv.ParseInt(values[0], 10, 64)
+ if err != nil {
+ return cfg, E.Cause(err, "parse decryption seconds_from")
+ }
+ cfg.secondsFrom = secondsFrom
+ if len(values) == 2 && values[1] != "" {
+ secondsTo, err := strconv.ParseInt(values[1], 10, 64)
+ if err != nil {
+ return cfg, E.Cause(err, "parse decryption seconds_to")
+ }
+ cfg.secondsTo = secondsTo
+ }
+
+ paddingPhase := true
+ var paddingParts []string
+ for _, segment := range parts[3:] {
+ segment = strings.TrimSpace(segment)
+ if segment == "" {
+ return cfg, E.New("invalid empty segment in decryption string")
+ }
+ if data, err := base64.RawURLEncoding.DecodeString(segment); err == nil {
+ if len(data) == 32 || len(data) == 64 {
+ cfg.keys = append(cfg.keys, data)
+ paddingPhase = false
+ continue
+ }
+ return cfg, E.New("invalid decryption key length: ", len(data))
+ }
+ if paddingPhase {
+ paddingParts = append(paddingParts, segment)
+ continue
+ }
+ return cfg, E.New("invalid decryption key: ", segment)
+ }
+ if len(cfg.keys) == 0 {
+ return cfg, E.New("no valid decryption keys found in decryption string")
+ }
+ if len(paddingParts) > 0 {
+ cfg.padding = strings.Join(paddingParts, ".")
+ }
+ return cfg, nil
+}
+
var _ adapter.V2RayServerTransportHandler = (*inboundTransportHandler)(nil)
type inboundTransportHandler Inbound
@@ -217,6 +330,7 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
//nolint:staticcheck
metadata.InboundDetour = h.listener.ListenOptions().Detour
//nolint:staticcheck
+ metadata.InboundOptions = h.listener.ListenOptions().InboundOptions
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
- (*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
+ (*Inbound)(h).newConnectionExInternal(ctx, conn, metadata, onClose, false)
}
diff --git a/protocol/vless/outbound.go b/protocol/vless/outbound.go
index d8132cf9d4..23656ca790 100644
--- a/protocol/vless/outbound.go
+++ b/protocol/vless/outbound.go
@@ -2,16 +2,23 @@ package vless
import (
"context"
+ stdtls "crypto/tls"
+ "encoding/base64"
"net"
+ "reflect"
+ "strings"
+ "sync"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/adapter/outbound"
"github.com/sagernet/sing-box/common/dialer"
"github.com/sagernet/sing-box/common/mux"
"github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/common/vision"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/protocol/vless/encryption"
"github.com/sagernet/sing-box/transport/v2ray"
"github.com/sagernet/sing-vmess/packetaddr"
"github.com/sagernet/sing-vmess/vless"
@@ -35,10 +42,11 @@ type Outbound struct {
serverAddr M.Socksaddr
multiplexDialer *mux.Client
tlsConfig tls.Config
- tlsDialer tls.Dialer
transport adapter.V2RayClientTransport
packetAddr bool
xudp bool
+ encryption *encryption.ClientInstance
+ vision bool
}
func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.VLESSOutboundOptions) (adapter.Outbound, error) {
@@ -51,21 +59,13 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
logger: logger,
dialer: outboundDialer,
serverAddr: options.ServerOptions.Build(),
+ vision: strings.HasPrefix(options.Flow, "xtls-rprx-vision"),
}
if options.TLS != nil {
- outbound.tlsConfig, err = tls.NewClientWithOptions(tls.ClientOptions{
- Context: ctx,
- Logger: logger,
- ServerAddress: options.Server,
- Options: common.PtrValueOrDefault(options.TLS),
- KTLSCompatible: common.PtrValueOrDefault(options.Transport).Type == "" &&
- !common.PtrValueOrDefault(options.Multiplex).Enabled &&
- options.Flow == "",
- })
+ outbound.tlsConfig, err = tls.NewClient(ctx, logger, options.Server, common.PtrValueOrDefault(options.TLS))
if err != nil {
return nil, err
}
- outbound.tlsDialer = tls.NewDialer(outboundDialer, outbound.tlsConfig)
}
if options.Transport != nil {
outbound.transport, err = v2ray.NewClientTransport(ctx, outbound.dialer, outbound.serverAddr, common.PtrValueOrDefault(options.Transport), outbound.tlsConfig)
@@ -86,11 +86,28 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
return nil, E.New("unknown packet encoding: ", options.PacketEncoding)
}
}
+ // Parse encryption configuration
+ if options.Encryption != "" && options.Encryption != "none" {
+ encryptionConfig, err := parseClientEncryption(options.Encryption)
+ if err != nil {
+ return nil, E.Cause(err, "parse encryption")
+ }
+ outbound.encryption = &encryption.ClientInstance{}
+ if err := outbound.encryption.Init(encryptionConfig.keys, encryptionConfig.xorMode, encryptionConfig.seconds, encryptionConfig.padding); err != nil {
+ return nil, E.Cause(err, "initialize encryption")
+ }
+ logger.Debug("encryption initialized: keys=", len(encryptionConfig.keys), " xorMode=", encryptionConfig.xorMode, " seconds=", encryptionConfig.seconds, " padding=", encryptionConfig.padding)
+ }
+
+ muxOpts := common.PtrValueOrDefault(options.Multiplex)
+ if muxOpts.Enabled {
+ options.Flow = ""
+ }
outbound.client, err = vless.NewClient(options.UUID, options.Flow, logger)
if err != nil {
return nil, err
}
- outbound.multiplexDialer, err = mux.NewClientWithOptions((*vlessDialer)(outbound), logger, common.PtrValueOrDefault(options.Multiplex))
+ outbound.multiplexDialer, err = mux.NewClientWithOptions((*vlessDialer)(outbound), logger, muxOpts)
if err != nil {
return nil, err
}
@@ -147,27 +164,99 @@ func (h *vlessDialer) DialContext(ctx context.Context, network string, destinati
metadata.Outbound = h.Tag()
metadata.Destination = destination
var conn net.Conn
+ var baseConn net.Conn
+ var hookOnce sync.Once
+ if h.vision {
+ ctx = vision.WithHook(ctx, func(tlsConn net.Conn) {
+ if tlsConn == nil || !isVisionTLSConn(tlsConn) {
+ return
+ }
+ hookOnce.Do(func() {
+ baseConn = tlsConn
+ })
+ })
+ }
var err error
if h.transport != nil {
conn, err = h.transport.DialContext(ctx)
- } else if h.tlsDialer != nil {
- conn, err = h.tlsDialer.DialTLSContext(ctx, h.serverAddr)
+ if err == nil && h.vision {
+ if baseConn == nil {
+ // Only set baseConn if the transport delivered a TLS-capable connection
+ if isVisionTLSConn(conn) {
+ h.logger.Warn("Vision enabled but hook was not called by transport, using fallback")
+ baseConn = conn
+ }
+ }
+ }
} else {
conn, err = h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err == nil && h.tlsConfig != nil {
+ conn, err = tls.ClientHandshake(ctx, conn, h.tlsConfig)
+ if err == nil && h.vision && baseConn == nil {
+ baseConn = conn
+ }
+ }
}
if err != nil {
return nil, err
}
+
+ // Apply encryption if configured
+ if h.encryption != nil {
+ conn, err = h.encryption.Handshake(conn)
+ if err != nil {
+ return nil, E.Cause(err, "encryption handshake")
+ }
+ }
+
+ // For Vision: wrap the connection to expose the TLS/encryption connection for vless client
+ var visionBaseConn net.Conn // The connection to pass to Vision (TLS or encryption layer)
+ var visionCanSplice bool
+ if h.vision {
+ isRAWTransport := h.transport == nil
+
+ if baseConn != nil && !isVisionTLSConn(baseConn) {
+ baseConn = nil
+ }
+ if baseConn != nil {
+ // Has TLS/Reality: use baseConn (TLS connection)
+ visionBaseConn = baseConn
+ visionCanSplice = isRAWTransport
+ conn = newVisionConnWrapper(conn, baseConn)
+ } else if h.encryption != nil {
+ // Only has encryption (no TLS/Reality): use encryption layer itself
+ encConn := findEncryptionLayer(conn)
+ if encConn != nil {
+ visionBaseConn = encConn
+ if h.encryption.IsFullRandomXorMode() {
+ visionCanSplice = false
+ } else {
+ visionCanSplice = isRAWTransport
+ }
+ conn = newVisionConnWrapper(conn, encConn)
+ } else {
+ return nil, E.New("Vision: failed to find encryption layer")
+ }
+ } else {
+ return nil, E.New("Vision requires either TLS/Reality or Encryption")
+ }
+ }
+
switch N.NetworkName(network) {
case N.NetworkTCP:
h.logger.InfoContext(ctx, "outbound connection to ", destination)
+ if h.vision && visionBaseConn != nil {
+ // For Vision, we need to pass the base connection (TLS or encryption layer)
+ // to prepareConn so it can properly initialize VisionConn
+ return h.client.DialEarlyConnWithOptions(conn, visionBaseConn, destination, visionCanSplice)
+ }
return h.client.DialEarlyConn(conn, destination)
case N.NetworkUDP:
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
if h.xudp {
return h.client.DialEarlyXUDPPacketConn(conn, destination)
} else if h.packetAddr {
- if destination.IsDomain() {
+ if destination.IsFqdn() {
return nil, E.New("packetaddr: domain destination is not supported")
}
packetConn, err := h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress})
@@ -192,19 +281,28 @@ func (h *vlessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr)
var err error
if h.transport != nil {
conn, err = h.transport.DialContext(ctx)
- } else if h.tlsDialer != nil {
- conn, err = h.tlsDialer.DialTLSContext(ctx, h.serverAddr)
} else {
conn, err = h.dialer.DialContext(ctx, N.NetworkTCP, h.serverAddr)
+ if err == nil && h.tlsConfig != nil {
+ conn, err = tls.ClientHandshake(ctx, conn, h.tlsConfig)
+ }
}
if err != nil {
common.Close(conn)
return nil, err
}
+ // Apply encryption if configured
+ if h.encryption != nil {
+ conn, err = h.encryption.Handshake(conn)
+ if err != nil {
+ common.Close(conn)
+ return nil, E.Cause(err, "encryption handshake")
+ }
+ }
if h.xudp {
return h.client.DialEarlyXUDPPacketConn(conn, destination)
} else if h.packetAddr {
- if destination.IsDomain() {
+ if destination.IsFqdn() {
return nil, E.New("packetaddr: domain destination is not supported")
}
conn, err := h.client.DialEarlyPacketConn(conn, M.Socksaddr{Fqdn: packetaddr.SeqPacketMagicAddress})
@@ -216,3 +314,152 @@ func (h *vlessDialer) ListenPacket(ctx context.Context, destination M.Socksaddr)
return h.client.DialEarlyPacketConn(conn, destination)
}
}
+
+type visionConnWrapper struct {
+ net.Conn
+ upstream net.Conn
+}
+
+var (
+ _ N.ReaderWithUpstream = (*visionConnWrapper)(nil)
+ _ N.WriterWithUpstream = (*visionConnWrapper)(nil)
+ _ common.WithUpstream = (*visionConnWrapper)(nil)
+)
+
+func newVisionConnWrapper(conn net.Conn, upstream net.Conn) net.Conn {
+ if upstream == nil || conn == nil || conn == upstream {
+ return conn
+ }
+ return &visionConnWrapper{
+ Conn: conn,
+ upstream: upstream,
+ }
+}
+
+func (c *visionConnWrapper) Upstream() any {
+ return c.upstream
+}
+
+func (c *visionConnWrapper) ReaderReplaceable() bool {
+ if replacer, ok := c.Conn.(N.ReaderWithUpstream); ok {
+ return replacer.ReaderReplaceable()
+ }
+ return true
+}
+
+func (c *visionConnWrapper) WriterReplaceable() bool {
+ if replacer, ok := c.Conn.(N.WriterWithUpstream); ok {
+ return replacer.WriterReplaceable()
+ }
+ return true
+}
+
+// isVisionTLSConn returns true when the provided connection exposes TLS semantics Vision expects.
+func isVisionTLSConn(conn net.Conn) bool {
+ if conn == nil {
+ return false
+ }
+ if _, ok := conn.(interface{ ConnectionState() stdtls.ConnectionState }); ok {
+ return true
+ }
+ if _, ok := conn.(interface{ Handshake() error }); ok {
+ return true
+ }
+ connType := reflect.TypeOf(conn)
+ if connType == nil {
+ return false
+ }
+ if connType.Kind() == reflect.Ptr {
+ pkgPath := connType.Elem().PkgPath()
+ if pkgPath == "crypto/tls" || strings.Contains(pkgPath, "utls") || strings.Contains(pkgPath, "shadowtls") {
+ return true
+ }
+ }
+ return false
+}
+
+func findEncryptionLayer(conn net.Conn) net.Conn {
+ for conn != nil {
+ if enc, ok := conn.(encryption.EncryptionConn); ok && enc.IsEncryptionLayer() {
+ return conn
+ }
+ if upstream, ok := conn.(common.WithUpstream); ok {
+ if next := upstream.Upstream(); next != nil {
+ if nextConn, ok := next.(net.Conn); ok {
+ conn = nextConn
+ continue
+ }
+ }
+ }
+ break
+ }
+ return nil
+}
+
+type clientEncryptionConfig struct {
+ keys [][]byte
+ xorMode uint32
+ seconds uint32
+ padding string
+}
+
+func parseClientEncryption(raw string) (clientEncryptionConfig, error) {
+ var cfg clientEncryptionConfig
+ raw = strings.TrimSpace(raw)
+ if raw == "" {
+ return cfg, E.New("empty encryption string")
+ }
+ parts := strings.Split(raw, ".")
+ if len(parts) < 4 {
+ return cfg, E.New("invalid encryption string: missing components")
+ }
+ if parts[0] != "mlkem768x25519plus" {
+ return cfg, E.New("unsupported encryption prefix: ", parts[0])
+ }
+ switch parts[1] {
+ case "native":
+ cfg.xorMode = 0
+ case "xorpub":
+ cfg.xorMode = 1
+ case "random":
+ cfg.xorMode = 2
+ default:
+ return cfg, E.New("unknown encryption mode: ", parts[1])
+ }
+ switch parts[2] {
+ case "0rtt":
+ cfg.seconds = 1
+ case "1rtt":
+ cfg.seconds = 0
+ default:
+ return cfg, E.New("unsupported encryption RTT value: ", parts[2])
+ }
+ paddingPhase := true
+ var paddingParts []string
+ for _, segment := range parts[3:] {
+ segment = strings.TrimSpace(segment)
+ if segment == "" {
+ return cfg, E.New("invalid empty segment in encryption string")
+ }
+ if data, err := base64.RawURLEncoding.DecodeString(segment); err == nil {
+ if len(data) == 32 || len(data) == 1184 {
+ cfg.keys = append(cfg.keys, data)
+ paddingPhase = false
+ continue
+ }
+ return cfg, E.New("invalid encryption key length: ", len(data))
+ }
+ if paddingPhase {
+ paddingParts = append(paddingParts, segment)
+ continue
+ }
+ return cfg, E.New("invalid encryption key: ", segment)
+ }
+ if len(cfg.keys) == 0 {
+ return cfg, E.New("no valid encryption keys found in encryption string")
+ }
+ if len(paddingParts) > 0 {
+ cfg.padding = strings.Join(paddingParts, ".")
+ }
+ return cfg, nil
+}
diff --git a/protocol/vmess/inbound.go b/protocol/vmess/inbound.go
index 4e9c763c93..8783d3e377 100644
--- a/protocol/vmess/inbound.go
+++ b/protocol/vmess/inbound.go
@@ -66,7 +66,7 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
if options.Transport != nil && options.Transport.Type != "" {
serviceOptions = append(serviceOptions, vmess.ServiceWithDisableHeaderProtection())
}
- service := vmess.NewService[int](adapter.NewUpstreamContextHandlerEx(inbound.newConnectionEx, inbound.newPacketConnectionEx), serviceOptions...)
+ service := vmess.NewService[int](adapter.NewUpstreamContextHandler(inbound.newConnectionEx, inbound.newPacketConnectionEx), serviceOptions...)
inbound.service = service
err = service.UpdateUsers(common.MapIndexed(options.Users, func(index int, it option.VMessUser) int {
return index
@@ -153,7 +153,7 @@ func (h *Inbound) Close() error {
)
}
-func (h *Inbound) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (h *Inbound) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
if h.tlsConfig != nil && h.transport == nil {
tlsConn, err := tls.ServerHandshake(ctx, conn, h.tlsConfig)
if err != nil {
@@ -224,5 +224,5 @@ func (h *inboundTransportHandler) NewConnectionEx(ctx context.Context, conn net.
metadata.InboundDetour = h.listener.ListenOptions().Detour
//nolint:staticcheck
h.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
- (*Inbound)(h).NewConnectionEx(ctx, conn, metadata, onClose)
+ (*Inbound)(h).NewConnection(ctx, conn, metadata, onClose)
}
diff --git a/protocol/warp/endpoint_warp.go b/protocol/warp/endpoint_warp.go
new file mode 100644
index 0000000000..6e9c375e16
--- /dev/null
+++ b/protocol/warp/endpoint_warp.go
@@ -0,0 +1,203 @@
+package warp
+
+import (
+ "context"
+ "encoding/json"
+ "math/rand"
+ "net"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/endpoint"
+ "github.com/sagernet/sing-box/common/cloudflare"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+func RegisterWARPEndpoint(registry *endpoint.Registry) {
+ endpoint.Register[option.WARPEndpointOptions](registry, C.TypeWARP, NewWARPEndpoint)
+}
+
+type WARPEndpoint struct {
+ endpoint.Adapter
+ endpoint adapter.Endpoint
+ startHandler func()
+
+ mtx sync.Mutex
+}
+
+func NewWARPEndpoint(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.WARPEndpointOptions) (adapter.Endpoint, error) {
+ var dependencies []string
+ if options.Detour != "" {
+ dependencies = append(dependencies, options.Detour)
+ }
+ if options.Profile.Detour != "" {
+ dependencies = append(dependencies, options.Profile.Detour)
+ }
+ warpEndpoint := &WARPEndpoint{
+ Adapter: endpoint.NewAdapter(C.TypeWARP, tag, []string{N.NetworkTCP, N.NetworkUDP}, dependencies),
+ }
+ uniqueId := options.UniqueIdentifier
+ if uniqueId == "" {
+ uniqueId = tag
+ }
+ warpEndpoint.mtx.Lock()
+ warpEndpoint.startHandler = func() {
+ defer warpEndpoint.mtx.Unlock()
+ cacheFile := service.FromContext[adapter.CacheFile](ctx)
+ var config *C.WARPConfig
+ var err error
+ if !options.Profile.Recreate && cacheFile != nil && cacheFile.StoreWARPConfig() {
+ savedProfile := cacheFile.LoadBinary(uniqueId)
+ if savedProfile != nil {
+ if err = json.Unmarshal(savedProfile.Content, &config); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ }
+ }
+ if config == nil && options.WARPConfig != nil {
+ config = options.WARPConfig
+ }
+ if config == nil || config.PrivateKey == "" {
+ profile, err := GetWarpProfile(ctx, &options.Profile)
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ config = &profile.Config
+
+ if cacheFile != nil && cacheFile.StoreWARPConfig() {
+ content, err := json.Marshal(config)
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ cacheFile.SaveBinary(uniqueId, &adapter.SavedBinary{
+ LastUpdated: time.Now(),
+ Content: content,
+ LastEtag: "",
+ })
+ }
+ }
+ peer := config.Peers[0]
+ hostParts := strings.Split(peer.Endpoint.Host, ":")
+ peerAddr := hostParts[0]
+ perrPort := uint16(peer.Endpoint.Ports[rand.Intn(len(peer.Endpoint.Ports))])
+ if options.ServerOptions.Server != "" {
+ peerAddr = options.ServerOptions.Server
+ }
+ if options.ServerOptions.ServerPort != 0 {
+ perrPort = options.ServerOptions.ServerPort
+ }
+ if options.AWG != nil && options.AWG.IsAvailble() {
+ warpEndpoint.endpoint, err = createWARPAwgEndpoint(ctx, router, logger, tag, options, config, peerAddr, perrPort, peer.PublicKey)
+ } else {
+ warpEndpoint.endpoint, err = createWARPWireGuardEndpoint(ctx, router, logger, tag, options, config, peerAddr, perrPort, peer.PublicKey)
+ }
+ if err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ if err = warpEndpoint.endpoint.Start(adapter.StartStateStart); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ if err = warpEndpoint.endpoint.Start(adapter.StartStatePostStart); err != nil {
+ logger.ErrorContext(ctx, err)
+ return
+ }
+ }
+ return warpEndpoint, nil
+}
+func GetWarpProfile(ctx context.Context, profile *option.WARPProfile) (*cloudflare.CloudflareProfile, error) {
+ var dialer N.Dialer
+ outmanager := service.FromContext[adapter.OutboundManager](ctx)
+ if profile.Detour != "" && outmanager != nil {
+ var ok bool
+ dialer, ok = outmanager.Outbound(profile.Detour)
+ if !ok {
+ return nil, E.New("outbound detour not found: ", profile.Detour)
+ }
+
+ }
+ cf, err := GetWarpProfileDialer(ctx, dialer, profile)
+ if err == nil || outmanager == nil {
+ return cf, nil
+ }
+
+ for _, dialer := range outmanager.Outbounds() {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
+ if cf, err := GetWarpProfileDialer(ctx, dialer, profile); err == nil {
+ return cf, nil
+ }
+ }
+ return nil, err
+
+}
+func GetWarpProfileDialer(ctx context.Context, dialer N.Dialer, profile *option.WARPProfile) (*cloudflare.CloudflareProfile, error) {
+ api := cloudflare.NewCloudflareApiDetour(dialer)
+ if profile.AuthToken != "" && profile.ID != "" {
+ return api.GetProfile(ctx, profile.AuthToken, profile.ID)
+
+ } else {
+ return api.CreateProfileLicense(ctx, profile.PrivateKey, profile.License)
+ }
+}
+func (w *WARPEndpoint) IsReady() bool {
+ if ok := w.isEndpointInitialized(); !ok {
+ return false
+ }
+ return w.endpoint.IsReady()
+}
+func (w *WARPEndpoint) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStatePostStart {
+ return nil
+ }
+ go w.startHandler()
+ return nil
+}
+
+func (w *WARPEndpoint) Close() error {
+ return common.Close(w.endpoint)
+}
+
+func (w *WARPEndpoint) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if ok := w.isEndpointInitialized(); !ok {
+ return nil, E.New("endpoint not initialized")
+ }
+ return w.endpoint.DialContext(ctx, network, destination)
+}
+
+func (w *WARPEndpoint) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ if ok := w.isEndpointInitialized(); !ok {
+ return nil, E.New("endpoint not initialized")
+ }
+ return w.endpoint.ListenPacket(ctx, destination)
+}
+
+func (w *WARPEndpoint) isEndpointInitialized() bool {
+ w.mtx.Lock()
+ defer w.mtx.Unlock()
+ return w.endpoint != nil
+}
+
+func (w *WARPEndpoint) DisplayType() string {
+ str := C.ProxyDisplayName(w.Type())
+ if !w.IsReady() {
+ str += " ⚠️ Connecting..."
+ }
+ return str
+}
diff --git a/protocol/warp/endpoint_warp_awg.go b/protocol/warp/endpoint_warp_awg.go
new file mode 100644
index 0000000000..27f5a21945
--- /dev/null
+++ b/protocol/warp/endpoint_warp_awg.go
@@ -0,0 +1,51 @@
+//go:build with_awg
+
+package warp
+
+import (
+ "context"
+ "net/netip"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/protocol/awg"
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+func createWARPAwgEndpoint(
+ ctx context.Context,
+ router adapter.Router,
+ logger log.ContextLogger,
+ tag string,
+ options option.WARPEndpointOptions,
+ config *C.WARPConfig,
+ peerAddr string,
+ peerPort uint16,
+ peerPublicKey string,
+) (adapter.Endpoint, error) {
+ return awg.NewEndpoint(ctx, router, logger, tag, option.AwgEndpointOptions{
+ UseIntegratedTun: options.System,
+ PrivateKey: config.PrivateKey,
+ Address: badoption.Listable[netip.Prefix]{
+ netip.MustParsePrefix(config.Interface.Addresses.V4 + "/32"),
+ netip.MustParsePrefix(config.Interface.Addresses.V6 + "/128"),
+ },
+ MTU: options.MTU,
+ ListenPort: options.ListenPort,
+ Awg: *options.AWG,
+ Peers: []option.AwgPeerOptions{
+ {
+ Address: peerAddr,
+ Port: peerPort,
+ PublicKey: peerPublicKey,
+ AllowedIPs: badoption.Listable[netip.Prefix]{
+ netip.MustParsePrefix("0.0.0.0/0"),
+ netip.MustParsePrefix("::/0"),
+ },
+ },
+ },
+ DialerOptions: options.DialerOptions,
+ })
+}
diff --git a/protocol/warp/endpoint_warp_awg_stub.go b/protocol/warp/endpoint_warp_awg_stub.go
new file mode 100644
index 0000000000..f8c134ae1c
--- /dev/null
+++ b/protocol/warp/endpoint_warp_awg_stub.go
@@ -0,0 +1,27 @@
+//go:build !with_awg
+
+package warp
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func createWARPAwgEndpoint(
+ ctx context.Context,
+ router adapter.Router,
+ logger log.ContextLogger,
+ tag string,
+ options option.WARPEndpointOptions,
+ config *C.WARPConfig,
+ peerAddr string,
+ peerPort uint16,
+ peerPublicKey string,
+) (adapter.Endpoint, error) {
+ return nil, E.New(`Awg is not included in this build, rebuild with -tags with_awg`)
+}
diff --git a/protocol/warp/endpoint_warp_wireguard.go b/protocol/warp/endpoint_warp_wireguard.go
new file mode 100644
index 0000000000..ab781cddfe
--- /dev/null
+++ b/protocol/warp/endpoint_warp_wireguard.go
@@ -0,0 +1,54 @@
+package warp
+
+import (
+ "context"
+ "net/netip"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ wg "github.com/sagernet/sing-box/protocol/wireguard"
+ "github.com/sagernet/sing/common/json/badoption"
+)
+
+func createWARPWireGuardEndpoint(
+ ctx context.Context,
+ router adapter.Router,
+ logger log.ContextLogger,
+ tag string,
+ options option.WARPEndpointOptions,
+ config *C.WARPConfig,
+ peerAddr string,
+ peerPort uint16,
+ peerPublicKey string,
+) (adapter.Endpoint, error) {
+ return wg.NewEndpoint(ctx, router, logger, tag, option.WireGuardEndpointOptions{
+ System: options.System,
+ Name: options.Name,
+ ListenPort: options.ListenPort,
+ UDPTimeout: options.UDPTimeout,
+ Workers: options.Workers,
+ PreallocatedBuffersPerPool: options.PreallocatedBuffersPerPool,
+ DisablePauses: options.DisablePauses,
+ Noise: options.Noise,
+ DialerOptions: options.DialerOptions,
+ Address: badoption.Listable[netip.Prefix]{
+ netip.MustParsePrefix(config.Interface.Addresses.V4 + "/32"),
+ netip.MustParsePrefix(config.Interface.Addresses.V6 + "/128"),
+ },
+ PrivateKey: config.PrivateKey,
+ Peers: []option.WireGuardPeer{
+ {
+ Address: peerAddr,
+ Port: peerPort,
+ PublicKey: peerPublicKey,
+ AllowedIPs: badoption.Listable[netip.Prefix]{
+ netip.MustParsePrefix("0.0.0.0/0"),
+ netip.MustParsePrefix("::/0"),
+ },
+ },
+ },
+ MTU: options.MTU,
+ })
+}
diff --git a/protocol/wireguard/outbound.go b/protocol/wireguard/outbound.go
new file mode 100644
index 0000000000..c1a0076b30
--- /dev/null
+++ b/protocol/wireguard/outbound.go
@@ -0,0 +1,175 @@
+package wireguard
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/outbound"
+ "github.com/sagernet/sing-box/common/dialer"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing-box/transport/wireguard"
+ tun "github.com/sagernet/sing-tun"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+var _ adapter.OutboundWithPreferredRoutes = (*Outbound)(nil)
+
+func RegisterOutbound(registry *outbound.Registry) {
+ outbound.Register[option.LegacyWireGuardOutboundOptions](registry, C.TypeWireGuard, NewOutbound)
+}
+
+type Outbound struct {
+ outbound.Adapter
+ ctx context.Context
+ dnsRouter adapter.DNSRouter
+ logger logger.ContextLogger
+ localAddresses []netip.Prefix
+ endpoint *wireguard.Endpoint
+}
+
+func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.LegacyWireGuardOutboundOptions) (adapter.Outbound, error) {
+ outbound := &Outbound{
+ Adapter: outbound.NewAdapterWithDialerOptions(C.TypeWireGuard, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, options.DialerOptions),
+ ctx: ctx,
+ dnsRouter: service.FromContext[adapter.DNSRouter](ctx),
+ logger: logger,
+ localAddresses: options.LocalAddress,
+ }
+ if options.Detour != "" && options.GSO {
+ return nil, E.New("gso is conflict with detour")
+ }
+ outboundDialer, err := dialer.NewWithOptions(dialer.Options{
+ Context: ctx,
+ Options: options.DialerOptions,
+ RemoteIsDomain: options.ServerIsDomain() || common.Any(options.Peers, func(it option.LegacyWireGuardPeer) bool {
+ return it.ServerIsDomain()
+ }),
+ ResolverOnDetour: true,
+ })
+ if err != nil {
+ return nil, err
+ }
+ peers := common.Map(options.Peers, func(it option.LegacyWireGuardPeer) wireguard.PeerOptions {
+ return wireguard.PeerOptions{
+ Endpoint: it.ServerOptions.Build(),
+ PublicKey: it.PublicKey,
+ PreSharedKey: it.PreSharedKey,
+ AllowedIPs: it.AllowedIPs,
+ // PersistentKeepaliveInterval: time.Duration(it.PersistentKeepaliveInterval),
+ Reserved: it.Reserved,
+ }
+ })
+ if len(peers) == 0 {
+ peers = []wireguard.PeerOptions{{
+ Endpoint: options.ServerOptions.Build(),
+ PublicKey: options.PeerPublicKey,
+ PreSharedKey: options.PreSharedKey,
+ AllowedIPs: []netip.Prefix{netip.PrefixFrom(netip.IPv4Unspecified(), 0), netip.PrefixFrom(netip.IPv6Unspecified(), 0)},
+ Reserved: options.Reserved,
+ }}
+ }
+
+ wgEndpoint, err := wireguard.NewEndpoint(wireguard.EndpointOptions{
+ Context: ctx,
+ Logger: logger,
+ System: options.SystemInterface,
+ Dialer: outboundDialer,
+ CreateDialer: func(interfaceName string) N.Dialer {
+ return common.Must1(dialer.NewDefault(ctx, option.DialerOptions{
+ BindInterface: interfaceName,
+ }))
+ },
+ Name: options.InterfaceName,
+ MTU: options.MTU,
+ Address: options.LocalAddress,
+ PrivateKey: options.PrivateKey,
+ ResolvePeer: func(domain string) (netip.Addr, error) {
+ endpointAddresses, lookupErr := outbound.dnsRouter.Lookup(ctx, domain, outboundDialer.(dialer.ResolveDialer).QueryOptions())
+ if lookupErr != nil {
+ return netip.Addr{}, lookupErr
+ }
+ return endpointAddresses[0], nil
+ },
+ Peers: peers,
+ Workers: options.Workers,
+ PreallocatedBuffersPerPool: options.PreallocatedBuffersPerPool,
+ DisablePauses: options.DisablePauses,
+ Noise: options.Noise,
+ })
+ if err != nil {
+ return nil, err
+ }
+ outbound.endpoint = wgEndpoint
+ return outbound, nil
+}
+
+func (o *Outbound) Start(stage adapter.StartStage) error {
+ switch stage {
+ case adapter.StartStateStart:
+ return o.endpoint.Start(false)
+ case adapter.StartStatePostStart:
+ return o.endpoint.Start(true)
+ }
+ return nil
+}
+
+func (o *Outbound) Close() error {
+ return o.endpoint.Close()
+}
+
+func (o *Outbound) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ switch network {
+ case N.NetworkTCP:
+ o.logger.InfoContext(ctx, "outbound connection to ", destination)
+ case N.NetworkUDP:
+ o.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ }
+ if destination.IsFqdn() {
+ destinationAddresses, err := o.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return N.DialSerial(ctx, o.endpoint, network, destination, destinationAddresses)
+ } else if !destination.Addr.IsValid() {
+ return nil, E.New("invalid destination: ", destination)
+ }
+ return o.endpoint.DialContext(ctx, network, destination)
+}
+
+func (o *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ o.logger.InfoContext(ctx, "outbound packet connection to ", destination)
+ if destination.IsFqdn() {
+ destinationAddresses, err := o.dnsRouter.Lookup(ctx, destination.Fqdn, adapter.DNSQueryOptions{})
+ if err != nil {
+ return nil, err
+ }
+ packetConn, _, err := N.ListenSerial(ctx, o.endpoint, destination, destinationAddresses)
+ if err != nil {
+ return nil, err
+ }
+ return packetConn, err
+ }
+ return o.endpoint.ListenPacket(ctx, destination)
+}
+
+func (o *Outbound) PreferredDomain(domain string) bool {
+ return false
+}
+
+func (o *Outbound) PreferredAddress(address netip.Addr) bool {
+ return o.endpoint.Lookup(address) != nil
+}
+
+func (o *Outbound) NewDirectRouteConnection(metadata adapter.InboundContext, routeContext tun.DirectRouteContext, timeout time.Duration) (tun.DirectRouteDestination, error) {
+ return o.endpoint.NewDirectRouteConnection(metadata, routeContext, timeout)
+}
diff --git a/release/DEFAULT_BUILD_TAGS b/release/DEFAULT_BUILD_TAGS
index 4374ea93b6..e06bc120e0 100644
--- a/release/DEFAULT_BUILD_TAGS
+++ b/release/DEFAULT_BUILD_TAGS
@@ -1 +1 @@
-with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_naive_outbound,badlinkname,tfogo_checklinkname0
\ No newline at end of file
+with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,with_naive_outbound,badlinkname,tfogo_checklinkname0
\ No newline at end of file
diff --git a/release/DEFAULT_BUILD_TAGS_OTHERS b/release/DEFAULT_BUILD_TAGS_OTHERS
index 814b53f063..a28e900e9d 100644
--- a/release/DEFAULT_BUILD_TAGS_OTHERS
+++ b/release/DEFAULT_BUILD_TAGS_OTHERS
@@ -1 +1 @@
-with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,badlinkname,tfogo_checklinkname0
\ No newline at end of file
+with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,badlinkname,tfogo_checklinkname0
\ No newline at end of file
diff --git a/release/DEFAULT_BUILD_TAGS_WINDOWS b/release/DEFAULT_BUILD_TAGS_WINDOWS
index 746827a736..af4fe41620 100644
--- a/release/DEFAULT_BUILD_TAGS_WINDOWS
+++ b/release/DEFAULT_BUILD_TAGS_WINDOWS
@@ -1 +1 @@
-with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0
\ No newline at end of file
+with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,with_naive_outbound,with_purego,badlinkname,tfogo_checklinkname0
\ No newline at end of file
diff --git a/replace/psiphon-quic-go b/replace/psiphon-quic-go
new file mode 160000
index 0000000000..47042a7c24
--- /dev/null
+++ b/replace/psiphon-quic-go
@@ -0,0 +1 @@
+Subproject commit 47042a7c2475c081b370b8c9da2c22525774b27b
diff --git a/replace/psiphon-tls b/replace/psiphon-tls
new file mode 160000
index 0000000000..4af85c2fb9
--- /dev/null
+++ b/replace/psiphon-tls
@@ -0,0 +1 @@
+Subproject commit 4af85c2fb9f25576c15ccdb71d8299581dcd47fd
diff --git a/replace/tailscale b/replace/tailscale
new file mode 160000
index 0000000000..788aa623ed
--- /dev/null
+++ b/replace/tailscale
@@ -0,0 +1 @@
+Subproject commit 788aa623edebf3e9918919cee4c590b177c61ec4
diff --git a/replace/wireguard-go b/replace/wireguard-go
new file mode 160000
index 0000000000..b120224503
--- /dev/null
+++ b/replace/wireguard-go
@@ -0,0 +1 @@
+Subproject commit b12022450359150cfb54790bc7316dee899e2336
diff --git a/route/conn.go b/route/conn.go
index 9fdc6cda8c..a7dd779598 100644
--- a/route/conn.go
+++ b/route/conn.go
@@ -13,7 +13,6 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
- "github.com/sagernet/sing-box/common/sniff"
"github.com/sagernet/sing-box/common/tlsfragment"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing/common"
@@ -112,6 +111,9 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
var dialerString string
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+ if outbound.Type() == C.TypeBalancer {
+ dialerString += "[" + metadata.GetRealOutbound() + "]"
+ }
}
err = E.Cause(err, "open connection to ", remoteString, dialerString)
N.CloseOnHandshakeFailure(conn, onClose, err)
@@ -129,12 +131,11 @@ func (m *ConnectionManager) NewConnection(ctx context.Context, this N.Dialer, co
if metadata.TLSFragment || metadata.TLSRecordFragment {
remoteConn = tf.NewConn(remoteConn, ctx, metadata.TLSFragment, metadata.TLSRecordFragment, metadata.TLSFragmentFallbackDelay)
}
- serverFirst := sniff.Skip(&metadata)
var done atomic.Bool
- if m.kickWriteHandshake(ctx, conn, remoteConn, serverFirst, false, &done, onClose) {
+ if m.kickWriteHandshake(ctx, conn, remoteConn, false, &done, onClose) {
return
}
- if m.kickWriteHandshake(ctx, remoteConn, conn, serverFirst, true, &done, onClose) {
+ if m.kickWriteHandshake(ctx, remoteConn, conn, true, &done, onClose) {
return
}
go m.connectionCopy(ctx, conn, remoteConn, false, &done, onClose)
@@ -176,6 +177,9 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
var dialerString string
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+ if outbound.Type() == C.TypeBalancer {
+ dialerString += "[" + metadata.GetRealOutbound() + "]"
+ }
}
err = E.Cause(err, "open packet connection to ", remoteString, dialerString)
N.CloseOnHandshakeFailure(conn, onClose, err)
@@ -199,6 +203,9 @@ func (m *ConnectionManager) NewPacketConnection(ctx context.Context, this N.Dial
var dialerString string
if outbound, isOutbound := this.(adapter.Outbound); isOutbound {
dialerString = " using outbound/" + outbound.Type() + "[" + outbound.Tag() + "]"
+ if outbound.Type() == C.TypeBalancer {
+ dialerString += "[" + metadata.GetRealOutbound() + "]"
+ }
}
err = E.Cause(err, "listen packet connection using ", dialerString)
N.CloseOnHandshakeFailure(conn, onClose, err)
@@ -279,7 +286,7 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source net.Conn,
if !direction {
if err == nil {
m.logger.DebugContext(ctx, "connection upload finished")
- } else if !E.IsClosedOrCanceled(err) {
+ } else if !E.IsClosedOrCanceled(err) && !strings.Contains(err.Error(), "NO_ERROR") {
m.logger.ErrorContext(ctx, "connection upload closed: ", err)
} else {
m.logger.TraceContext(ctx, "connection upload closed")
@@ -287,7 +294,7 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source net.Conn,
} else {
if err == nil {
m.logger.DebugContext(ctx, "connection download finished")
- } else if !E.IsClosedOrCanceled(err) {
+ } else if !E.IsClosedOrCanceled(err) && !strings.Contains(err.Error(), "NO_ERROR") && !strings.Contains(err.Error(), "response body closed") {
m.logger.ErrorContext(ctx, "connection download closed: ", err)
} else {
m.logger.TraceContext(ctx, "connection download closed")
@@ -295,43 +302,37 @@ func (m *ConnectionManager) connectionCopy(ctx context.Context, source net.Conn,
}
}
-func (m *ConnectionManager) kickWriteHandshake(ctx context.Context, source net.Conn, destination net.Conn, serverFirst bool, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) bool {
+func (m *ConnectionManager) kickWriteHandshake(ctx context.Context, source net.Conn, destination net.Conn, direction bool, done *atomic.Bool, onClose N.CloseHandlerFunc) bool {
if !N.NeedHandshakeForWrite(destination) {
return false
}
var (
- err error
+ cachedBuffer *buf.Buffer
wrotePayload bool
)
- if serverFirst {
- _ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
- _, err = destination.Write(nil)
- _ = destination.SetWriteDeadline(time.Time{})
- } else {
- var cachedBuffer *buf.Buffer
- sourceReader, readCounters := N.UnwrapCountReader(source, nil)
- destinationWriter, writeCounters := N.UnwrapCountWriter(destination, nil)
- if cachedReader, ok := sourceReader.(N.CachedReader); ok {
- cachedBuffer = cachedReader.ReadCached()
- }
- if cachedBuffer != nil {
- wrotePayload = true
- dataLen := cachedBuffer.Len()
- _, err = destinationWriter.Write(cachedBuffer.Bytes())
- cachedBuffer.Release()
- if err == nil {
- for _, counter := range readCounters {
- counter(int64(dataLen))
- }
- for _, counter := range writeCounters {
- counter(int64(dataLen))
- }
+ sourceReader, readCounters := N.UnwrapCountReader(source, nil)
+ destinationWriter, writeCounters := N.UnwrapCountWriter(destination, nil)
+ if cachedReader, ok := sourceReader.(N.CachedReader); ok {
+ cachedBuffer = cachedReader.ReadCached()
+ }
+ var err error
+ if cachedBuffer != nil {
+ wrotePayload = true
+ dataLen := cachedBuffer.Len()
+ _, err = destinationWriter.Write(cachedBuffer.Bytes())
+ cachedBuffer.Release()
+ if err == nil {
+ for _, counter := range readCounters {
+ counter(int64(dataLen))
+ }
+ for _, counter := range writeCounters {
+ counter(int64(dataLen))
}
- } else {
- _ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
- _, err = destinationWriter.Write(nil)
- _ = destination.SetWriteDeadline(time.Time{})
}
+ } else {
+ _ = destination.SetWriteDeadline(time.Now().Add(C.ReadPayloadTimeout))
+ _, err = destinationWriter.Write(nil)
+ _ = destination.SetWriteDeadline(time.Time{})
}
if err == nil {
return false
diff --git a/route/neighbor_resolver_darwin.go b/route/neighbor_resolver_darwin.go
new file mode 100644
index 0000000000..cc24ec73ec
--- /dev/null
+++ b/route/neighbor_resolver_darwin.go
@@ -0,0 +1,245 @@
+//go:build darwin
+
+package route
+
+import (
+ "net"
+ "net/netip"
+ "os"
+ "sync"
+ "time"
+
+ "github.com/sagernet/fswatch"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+
+ "golang.org/x/net/route"
+ "golang.org/x/sys/unix"
+)
+
+var defaultLeaseFiles = []string{
+ "/var/db/dhcpd_leases",
+ "/tmp/dhcp.leases",
+}
+
+type neighborResolver struct {
+ logger logger.ContextLogger
+ leaseFiles []string
+ access sync.RWMutex
+ neighborIPToMAC map[netip.Addr]net.HardwareAddr
+ leaseIPToMAC map[netip.Addr]net.HardwareAddr
+ ipToHostname map[netip.Addr]string
+ macToHostname map[string]string
+ watcher *fswatch.Watcher
+ done chan struct{}
+}
+
+func newNeighborResolver(resolverLogger logger.ContextLogger, leaseFiles []string) (adapter.NeighborResolver, error) {
+ if len(leaseFiles) == 0 {
+ for _, path := range defaultLeaseFiles {
+ info, err := os.Stat(path)
+ if err == nil && info.Size() > 0 {
+ leaseFiles = append(leaseFiles, path)
+ }
+ }
+ }
+ return &neighborResolver{
+ logger: resolverLogger,
+ leaseFiles: leaseFiles,
+ neighborIPToMAC: make(map[netip.Addr]net.HardwareAddr),
+ leaseIPToMAC: make(map[netip.Addr]net.HardwareAddr),
+ ipToHostname: make(map[netip.Addr]string),
+ macToHostname: make(map[string]string),
+ done: make(chan struct{}),
+ }, nil
+}
+
+func (r *neighborResolver) Start() error {
+ err := r.loadNeighborTable()
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "load neighbor table"))
+ }
+ r.doReloadLeaseFiles()
+ go r.subscribeNeighborUpdates()
+ if len(r.leaseFiles) > 0 {
+ watcher, err := fswatch.NewWatcher(fswatch.Options{
+ Path: r.leaseFiles,
+ Logger: r.logger,
+ Callback: func(_ string) {
+ r.doReloadLeaseFiles()
+ },
+ })
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "create lease file watcher"))
+ } else {
+ r.watcher = watcher
+ err = watcher.Start()
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "start lease file watcher"))
+ }
+ }
+ }
+ return nil
+}
+
+func (r *neighborResolver) Close() error {
+ close(r.done)
+ if r.watcher != nil {
+ return r.watcher.Close()
+ }
+ return nil
+}
+
+func (r *neighborResolver) LookupMAC(address netip.Addr) (net.HardwareAddr, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ mac, found := r.neighborIPToMAC[address]
+ if found {
+ return mac, true
+ }
+ mac, found = r.leaseIPToMAC[address]
+ if found {
+ return mac, true
+ }
+ mac, found = extractMACFromEUI64(address)
+ if found {
+ return mac, true
+ }
+ return nil, false
+}
+
+func (r *neighborResolver) LookupAddresses(hostname string) []netip.Addr {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ return lookupAddressesByHostname(hostname, r.ipToHostname, r.macToHostname, r.neighborIPToMAC, r.leaseIPToMAC)
+}
+
+func (r *neighborResolver) LookupHostname(address netip.Addr) (string, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ hostname, found := r.ipToHostname[address]
+ if found {
+ return hostname, true
+ }
+ mac, macFound := r.neighborIPToMAC[address]
+ if !macFound {
+ mac, macFound = r.leaseIPToMAC[address]
+ }
+ if !macFound {
+ mac, macFound = extractMACFromEUI64(address)
+ }
+ if macFound {
+ hostname, found = r.macToHostname[mac.String()]
+ if found {
+ return hostname, true
+ }
+ }
+ return "", false
+}
+
+func (r *neighborResolver) loadNeighborTable() error {
+ entries, err := ReadNeighborEntries()
+ if err != nil {
+ return err
+ }
+ r.access.Lock()
+ defer r.access.Unlock()
+ for _, entry := range entries {
+ r.neighborIPToMAC[entry.Address] = entry.MACAddress
+ }
+ return nil
+}
+
+func (r *neighborResolver) subscribeNeighborUpdates() {
+ routeSocket, err := unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, 0)
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "subscribe neighbor updates"))
+ return
+ }
+ err = unix.SetNonblock(routeSocket, true)
+ if err != nil {
+ unix.Close(routeSocket)
+ r.logger.Warn(E.Cause(err, "set route socket nonblock"))
+ return
+ }
+ routeSocketFile := os.NewFile(uintptr(routeSocket), "route")
+ defer routeSocketFile.Close()
+ buffer := buf.NewPacket()
+ defer buffer.Release()
+ for {
+ select {
+ case <-r.done:
+ return
+ default:
+ }
+ err = setReadDeadline(routeSocketFile, 3*time.Second)
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "set route socket read deadline"))
+ return
+ }
+ n, err := routeSocketFile.Read(buffer.FreeBytes())
+ if err != nil {
+ if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
+ continue
+ }
+ select {
+ case <-r.done:
+ return
+ default:
+ }
+ r.logger.Warn(E.Cause(err, "receive neighbor update"))
+ continue
+ }
+ messages, err := route.ParseRIB(route.RIBTypeRoute, buffer.FreeBytes()[:n])
+ if err != nil {
+ continue
+ }
+ for _, message := range messages {
+ routeMessage, isRouteMessage := message.(*route.RouteMessage)
+ if !isRouteMessage {
+ continue
+ }
+ if routeMessage.Flags&unix.RTF_LLINFO == 0 {
+ continue
+ }
+ address, mac, isDelete, ok := ParseRouteNeighborMessage(routeMessage)
+ if !ok {
+ continue
+ }
+ r.access.Lock()
+ if isDelete {
+ delete(r.neighborIPToMAC, address)
+ } else {
+ r.neighborIPToMAC[address] = mac
+ }
+ r.access.Unlock()
+ }
+ }
+}
+
+func (r *neighborResolver) doReloadLeaseFiles() {
+ leaseIPToMAC, ipToHostname, macToHostname := ReloadLeaseFiles(r.leaseFiles)
+ r.access.Lock()
+ r.leaseIPToMAC = leaseIPToMAC
+ r.ipToHostname = ipToHostname
+ r.macToHostname = macToHostname
+ r.access.Unlock()
+}
+
+func setReadDeadline(file *os.File, timeout time.Duration) error {
+ rawConn, err := file.SyscallConn()
+ if err != nil {
+ return err
+ }
+ var controlErr error
+ err = rawConn.Control(func(fd uintptr) {
+ tv := unix.NsecToTimeval(int64(timeout))
+ controlErr = unix.SetsockoptTimeval(int(fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, &tv)
+ })
+ if err != nil {
+ return err
+ }
+ return controlErr
+}
diff --git a/route/neighbor_resolver_hostname.go b/route/neighbor_resolver_hostname.go
new file mode 100644
index 0000000000..d030bd1cd3
--- /dev/null
+++ b/route/neighbor_resolver_hostname.go
@@ -0,0 +1,56 @@
+package route
+
+import (
+ "net"
+ "net/netip"
+ "strings"
+
+ "github.com/sagernet/sing-box/dns"
+)
+
+func lookupAddressesByHostname(
+ hostname string,
+ ipToHostname map[netip.Addr]string,
+ macToHostname map[string]string,
+ ipToMACTables ...map[netip.Addr]net.HardwareAddr,
+) []netip.Addr {
+ hostname = dns.FqdnToDomain(hostname)
+ if hostname == "" {
+ return nil
+ }
+ resultSet := make(map[netip.Addr]struct{})
+ var result []netip.Addr
+ addAddress := func(address netip.Addr) {
+ if isScopedIPv6Address(address) {
+ return
+ }
+ if _, exists := resultSet[address]; exists {
+ return
+ }
+ resultSet[address] = struct{}{}
+ result = append(result, address)
+ }
+ for address, entryHostname := range ipToHostname {
+ if strings.EqualFold(entryHostname, hostname) {
+ addAddress(address)
+ }
+ }
+ for mac, entryHostname := range macToHostname {
+ if !strings.EqualFold(entryHostname, hostname) {
+ continue
+ }
+ for _, table := range ipToMACTables {
+ for address, entryMAC := range table {
+ if entryMAC.String() == mac {
+ addAddress(address)
+ }
+ }
+ }
+ }
+ return result
+}
+
+func isScopedIPv6Address(address netip.Addr) bool {
+ // DNS AAAA records cannot carry an interface zone.
+ return address.Is6() && (address.IsLinkLocalUnicast() || address.Zone() != "")
+}
diff --git a/route/neighbor_resolver_lease.go b/route/neighbor_resolver_lease.go
new file mode 100644
index 0000000000..e3f9c0b464
--- /dev/null
+++ b/route/neighbor_resolver_lease.go
@@ -0,0 +1,386 @@
+package route
+
+import (
+ "bufio"
+ "encoding/hex"
+ "net"
+ "net/netip"
+ "os"
+ "strconv"
+ "strings"
+ "time"
+)
+
+func parseLeaseFile(path string, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ file, err := os.Open(path)
+ if err != nil {
+ return
+ }
+ defer file.Close()
+ if strings.HasSuffix(path, "dhcpd_leases") {
+ parseBootpdLeases(file, ipToMAC, ipToHostname, macToHostname)
+ return
+ }
+ if strings.HasSuffix(path, "kea-leases4.csv") {
+ parseKeaCSV4(file, ipToMAC, ipToHostname, macToHostname)
+ return
+ }
+ if strings.HasSuffix(path, "kea-leases6.csv") {
+ parseKeaCSV6(file, ipToMAC, ipToHostname, macToHostname)
+ return
+ }
+ if strings.HasSuffix(path, "dhcpd.leases") {
+ parseISCDhcpd(file, ipToMAC, ipToHostname, macToHostname)
+ return
+ }
+ parseDnsmasqOdhcpd(file, ipToMAC, ipToHostname, macToHostname)
+}
+
+func ReloadLeaseFiles(leaseFiles []string) (leaseIPToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ leaseIPToMAC = make(map[netip.Addr]net.HardwareAddr)
+ ipToHostname = make(map[netip.Addr]string)
+ macToHostname = make(map[string]string)
+ for _, path := range leaseFiles {
+ parseLeaseFile(path, leaseIPToMAC, ipToHostname, macToHostname)
+ }
+ return
+}
+
+func parseDnsmasqOdhcpd(file *os.File, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ now := time.Now().Unix()
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if strings.HasPrefix(line, "duid ") {
+ continue
+ }
+ if strings.HasPrefix(line, "# ") {
+ parseOdhcpdLine(line[2:], ipToMAC, ipToHostname, macToHostname)
+ continue
+ }
+ fields := strings.Fields(line)
+ if len(fields) < 4 {
+ continue
+ }
+ expiry, err := strconv.ParseInt(fields[0], 10, 64)
+ if err != nil {
+ continue
+ }
+ if expiry != 0 && expiry < now {
+ continue
+ }
+ if strings.Contains(fields[1], ":") {
+ mac, macErr := net.ParseMAC(fields[1])
+ if macErr != nil {
+ continue
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(fields[2]))
+ if !addrOK {
+ continue
+ }
+ address = address.Unmap()
+ ipToMAC[address] = mac
+ hostname := fields[3]
+ if hostname != "*" {
+ ipToHostname[address] = hostname
+ macToHostname[mac.String()] = hostname
+ }
+ } else {
+ var mac net.HardwareAddr
+ if len(fields) >= 5 {
+ duid, duidErr := parseDUID(fields[4])
+ if duidErr == nil {
+ mac, _ = extractMACFromDUID(duid)
+ }
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(fields[2]))
+ if !addrOK {
+ continue
+ }
+ address = address.Unmap()
+ if mac != nil {
+ ipToMAC[address] = mac
+ }
+ hostname := fields[3]
+ if hostname != "*" {
+ ipToHostname[address] = hostname
+ if mac != nil {
+ macToHostname[mac.String()] = hostname
+ }
+ }
+ }
+ }
+}
+
+func parseOdhcpdLine(line string, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ fields := strings.Fields(line)
+ if len(fields) < 5 {
+ return
+ }
+ validTime, err := strconv.ParseInt(fields[4], 10, 64)
+ if err != nil {
+ return
+ }
+ if validTime == 0 {
+ return
+ }
+ if validTime > 0 && validTime < time.Now().Unix() {
+ return
+ }
+ hostname := fields[3]
+ if hostname == "-" || strings.HasPrefix(hostname, `broken\x20`) {
+ hostname = ""
+ }
+ if len(fields) >= 8 && fields[2] == "ipv4" {
+ mac, macErr := net.ParseMAC(fields[1])
+ if macErr != nil {
+ return
+ }
+ addressField := fields[7]
+ slashIndex := strings.IndexByte(addressField, '/')
+ if slashIndex >= 0 {
+ addressField = addressField[:slashIndex]
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(addressField))
+ if !addrOK {
+ return
+ }
+ address = address.Unmap()
+ ipToMAC[address] = mac
+ if hostname != "" {
+ ipToHostname[address] = hostname
+ macToHostname[mac.String()] = hostname
+ }
+ return
+ }
+ var mac net.HardwareAddr
+ duidHex := fields[1]
+ duidBytes, hexErr := hex.DecodeString(duidHex)
+ if hexErr == nil {
+ mac, _ = extractMACFromDUID(duidBytes)
+ }
+ for i := 7; i < len(fields); i++ {
+ addressField := fields[i]
+ slashIndex := strings.IndexByte(addressField, '/')
+ if slashIndex >= 0 {
+ addressField = addressField[:slashIndex]
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(addressField))
+ if !addrOK {
+ continue
+ }
+ address = address.Unmap()
+ if mac != nil {
+ ipToMAC[address] = mac
+ }
+ if hostname != "" {
+ ipToHostname[address] = hostname
+ if mac != nil {
+ macToHostname[mac.String()] = hostname
+ }
+ }
+ }
+}
+
+func parseISCDhcpd(file *os.File, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ scanner := bufio.NewScanner(file)
+ var currentIP netip.Addr
+ var currentMAC net.HardwareAddr
+ var currentHostname string
+ var currentActive bool
+ var inLease bool
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if strings.HasPrefix(line, "lease ") && strings.HasSuffix(line, "{") {
+ ipString := strings.TrimSuffix(strings.TrimPrefix(line, "lease "), " {")
+ parsed, addrOK := netip.AddrFromSlice(net.ParseIP(ipString))
+ if addrOK {
+ currentIP = parsed.Unmap()
+ inLease = true
+ currentMAC = nil
+ currentHostname = ""
+ currentActive = false
+ }
+ continue
+ }
+ if line == "}" && inLease {
+ if currentActive && currentMAC != nil {
+ ipToMAC[currentIP] = currentMAC
+ if currentHostname != "" {
+ ipToHostname[currentIP] = currentHostname
+ macToHostname[currentMAC.String()] = currentHostname
+ }
+ } else {
+ delete(ipToMAC, currentIP)
+ delete(ipToHostname, currentIP)
+ }
+ inLease = false
+ continue
+ }
+ if !inLease {
+ continue
+ }
+ if strings.HasPrefix(line, "hardware ethernet ") {
+ macString := strings.TrimSuffix(strings.TrimPrefix(line, "hardware ethernet "), ";")
+ parsed, macErr := net.ParseMAC(macString)
+ if macErr == nil {
+ currentMAC = parsed
+ }
+ } else if strings.HasPrefix(line, "client-hostname ") {
+ hostname := strings.TrimSuffix(strings.TrimPrefix(line, "client-hostname "), ";")
+ hostname = strings.Trim(hostname, "\"")
+ if hostname != "" {
+ currentHostname = hostname
+ }
+ } else if strings.HasPrefix(line, "binding state ") {
+ state := strings.TrimSuffix(strings.TrimPrefix(line, "binding state "), ";")
+ currentActive = state == "active"
+ }
+ }
+}
+
+func parseKeaCSV4(file *os.File, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ scanner := bufio.NewScanner(file)
+ firstLine := true
+ for scanner.Scan() {
+ if firstLine {
+ firstLine = false
+ continue
+ }
+ fields := strings.Split(scanner.Text(), ",")
+ if len(fields) < 10 {
+ continue
+ }
+ if fields[9] != "0" {
+ continue
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(fields[0]))
+ if !addrOK {
+ continue
+ }
+ address = address.Unmap()
+ mac, macErr := net.ParseMAC(fields[1])
+ if macErr != nil {
+ continue
+ }
+ ipToMAC[address] = mac
+ hostname := ""
+ if len(fields) > 8 {
+ hostname = fields[8]
+ }
+ if hostname != "" {
+ ipToHostname[address] = hostname
+ macToHostname[mac.String()] = hostname
+ }
+ }
+}
+
+func parseKeaCSV6(file *os.File, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ scanner := bufio.NewScanner(file)
+ firstLine := true
+ for scanner.Scan() {
+ if firstLine {
+ firstLine = false
+ continue
+ }
+ fields := strings.Split(scanner.Text(), ",")
+ if len(fields) < 14 {
+ continue
+ }
+ if fields[13] != "0" {
+ continue
+ }
+ address, addrOK := netip.AddrFromSlice(net.ParseIP(fields[0]))
+ if !addrOK {
+ continue
+ }
+ address = address.Unmap()
+ var mac net.HardwareAddr
+ if fields[12] != "" {
+ mac, _ = net.ParseMAC(fields[12])
+ }
+ if mac == nil {
+ duid, duidErr := hex.DecodeString(strings.ReplaceAll(fields[1], ":", ""))
+ if duidErr == nil {
+ mac, _ = extractMACFromDUID(duid)
+ }
+ }
+ hostname := ""
+ if len(fields) > 11 {
+ hostname = fields[11]
+ }
+ if mac != nil {
+ ipToMAC[address] = mac
+ }
+ if hostname != "" {
+ ipToHostname[address] = hostname
+ if mac != nil {
+ macToHostname[mac.String()] = hostname
+ }
+ }
+ }
+}
+
+func parseBootpdLeases(file *os.File, ipToMAC map[netip.Addr]net.HardwareAddr, ipToHostname map[netip.Addr]string, macToHostname map[string]string) {
+ now := time.Now().Unix()
+ scanner := bufio.NewScanner(file)
+ var currentName string
+ var currentIP netip.Addr
+ var currentMAC net.HardwareAddr
+ var currentLease int64
+ var inBlock bool
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if line == "{" {
+ inBlock = true
+ currentName = ""
+ currentIP = netip.Addr{}
+ currentMAC = nil
+ currentLease = 0
+ continue
+ }
+ if line == "}" && inBlock {
+ if currentMAC != nil && currentIP.IsValid() {
+ if currentLease == 0 || currentLease >= now {
+ ipToMAC[currentIP] = currentMAC
+ if currentName != "" {
+ ipToHostname[currentIP] = currentName
+ macToHostname[currentMAC.String()] = currentName
+ }
+ }
+ }
+ inBlock = false
+ continue
+ }
+ if !inBlock {
+ continue
+ }
+ key, value, found := strings.Cut(line, "=")
+ if !found {
+ continue
+ }
+ switch key {
+ case "name":
+ currentName = value
+ case "ip_address":
+ parsed, addrOK := netip.AddrFromSlice(net.ParseIP(value))
+ if addrOK {
+ currentIP = parsed.Unmap()
+ }
+ case "hw_address":
+ typeAndMAC, hasSep := strings.CutPrefix(value, "1,")
+ if hasSep {
+ mac, macErr := net.ParseMAC(typeAndMAC)
+ if macErr == nil {
+ currentMAC = mac
+ }
+ }
+ case "lease":
+ leaseHex := strings.TrimPrefix(value, "0x")
+ parsed, parseErr := strconv.ParseInt(leaseHex, 16, 64)
+ if parseErr == nil {
+ currentLease = parsed
+ }
+ }
+ }
+}
diff --git a/route/neighbor_resolver_linux.go b/route/neighbor_resolver_linux.go
new file mode 100644
index 0000000000..5c6cdcb722
--- /dev/null
+++ b/route/neighbor_resolver_linux.go
@@ -0,0 +1,230 @@
+//go:build linux
+
+package route
+
+import (
+ "net"
+ "net/netip"
+ "os"
+ "slices"
+ "sync"
+ "time"
+
+ "github.com/sagernet/fswatch"
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+
+ "github.com/jsimonetti/rtnetlink"
+ "github.com/mdlayher/netlink"
+ "golang.org/x/sys/unix"
+)
+
+var defaultLeaseFiles = []string{
+ "/tmp/dhcp.leases",
+ "/var/lib/dhcp/dhcpd.leases",
+ "/var/lib/dhcpd/dhcpd.leases",
+ "/var/lib/kea/kea-leases4.csv",
+ "/var/lib/kea/kea-leases6.csv",
+}
+
+type neighborResolver struct {
+ logger logger.ContextLogger
+ leaseFiles []string
+ access sync.RWMutex
+ neighborIPToMAC map[netip.Addr]net.HardwareAddr
+ leaseIPToMAC map[netip.Addr]net.HardwareAddr
+ ipToHostname map[netip.Addr]string
+ macToHostname map[string]string
+ watcher *fswatch.Watcher
+ done chan struct{}
+}
+
+func newNeighborResolver(resolverLogger logger.ContextLogger, leaseFiles []string) (adapter.NeighborResolver, error) {
+ if len(leaseFiles) == 0 {
+ for _, path := range defaultLeaseFiles {
+ info, err := os.Stat(path)
+ if err == nil && info.Size() > 0 {
+ leaseFiles = append(leaseFiles, path)
+ }
+ }
+ }
+ return &neighborResolver{
+ logger: resolverLogger,
+ leaseFiles: leaseFiles,
+ neighborIPToMAC: make(map[netip.Addr]net.HardwareAddr),
+ leaseIPToMAC: make(map[netip.Addr]net.HardwareAddr),
+ ipToHostname: make(map[netip.Addr]string),
+ macToHostname: make(map[string]string),
+ done: make(chan struct{}),
+ }, nil
+}
+
+func (r *neighborResolver) Start() error {
+ err := r.loadNeighborTable()
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "load neighbor table"))
+ }
+ r.doReloadLeaseFiles()
+ go r.subscribeNeighborUpdates()
+ if len(r.leaseFiles) > 0 {
+ watcher, err := fswatch.NewWatcher(fswatch.Options{
+ Path: r.leaseFiles,
+ Logger: r.logger,
+ Callback: func(_ string) {
+ r.doReloadLeaseFiles()
+ },
+ })
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "create lease file watcher"))
+ } else {
+ r.watcher = watcher
+ err = watcher.Start()
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "start lease file watcher"))
+ }
+ }
+ }
+ return nil
+}
+
+func (r *neighborResolver) Close() error {
+ close(r.done)
+ if r.watcher != nil {
+ return r.watcher.Close()
+ }
+ return nil
+}
+
+func (r *neighborResolver) LookupMAC(address netip.Addr) (net.HardwareAddr, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ mac, found := r.neighborIPToMAC[address]
+ if found {
+ return mac, true
+ }
+ mac, found = r.leaseIPToMAC[address]
+ if found {
+ return mac, true
+ }
+ mac, found = extractMACFromEUI64(address)
+ if found {
+ return mac, true
+ }
+ return nil, false
+}
+
+func (r *neighborResolver) LookupAddresses(hostname string) []netip.Addr {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ return lookupAddressesByHostname(hostname, r.ipToHostname, r.macToHostname, r.neighborIPToMAC, r.leaseIPToMAC)
+}
+
+func (r *neighborResolver) LookupHostname(address netip.Addr) (string, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ hostname, found := r.ipToHostname[address]
+ if found {
+ return hostname, true
+ }
+ mac, macFound := r.neighborIPToMAC[address]
+ if !macFound {
+ mac, macFound = r.leaseIPToMAC[address]
+ }
+ if !macFound {
+ mac, macFound = extractMACFromEUI64(address)
+ }
+ if macFound {
+ hostname, found = r.macToHostname[mac.String()]
+ if found {
+ return hostname, true
+ }
+ }
+ return "", false
+}
+
+func (r *neighborResolver) loadNeighborTable() error {
+ connection, err := rtnetlink.Dial(nil)
+ if err != nil {
+ return E.Cause(err, "dial rtnetlink")
+ }
+ defer connection.Close()
+ neighbors, err := connection.Neigh.List()
+ if err != nil {
+ return E.Cause(err, "list neighbors")
+ }
+ r.access.Lock()
+ defer r.access.Unlock()
+ for _, neigh := range neighbors {
+ if neigh.Attributes == nil {
+ continue
+ }
+ if neigh.Attributes.LLAddress == nil || len(neigh.Attributes.Address) == 0 {
+ continue
+ }
+ address, ok := netip.AddrFromSlice(neigh.Attributes.Address)
+ if !ok {
+ continue
+ }
+ r.neighborIPToMAC[address] = slices.Clone(neigh.Attributes.LLAddress)
+ }
+ return nil
+}
+
+func (r *neighborResolver) subscribeNeighborUpdates() {
+ connection, err := netlink.Dial(unix.NETLINK_ROUTE, &netlink.Config{
+ Groups: 1 << (unix.RTNLGRP_NEIGH - 1),
+ })
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "subscribe neighbor updates"))
+ return
+ }
+ defer connection.Close()
+ for {
+ select {
+ case <-r.done:
+ return
+ default:
+ }
+ err = connection.SetReadDeadline(time.Now().Add(3 * time.Second))
+ if err != nil {
+ r.logger.Warn(E.Cause(err, "set netlink read deadline"))
+ return
+ }
+ messages, err := connection.Receive()
+ if err != nil {
+ if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
+ continue
+ }
+ select {
+ case <-r.done:
+ return
+ default:
+ }
+ r.logger.Warn(E.Cause(err, "receive neighbor update"))
+ continue
+ }
+ for _, message := range messages {
+ address, mac, isDelete, ok := ParseNeighborMessage(message)
+ if !ok {
+ continue
+ }
+ r.access.Lock()
+ if isDelete {
+ delete(r.neighborIPToMAC, address)
+ } else {
+ r.neighborIPToMAC[address] = mac
+ }
+ r.access.Unlock()
+ }
+ }
+}
+
+func (r *neighborResolver) doReloadLeaseFiles() {
+ leaseIPToMAC, ipToHostname, macToHostname := ReloadLeaseFiles(r.leaseFiles)
+ r.access.Lock()
+ r.leaseIPToMAC = leaseIPToMAC
+ r.ipToHostname = ipToHostname
+ r.macToHostname = macToHostname
+ r.access.Unlock()
+}
diff --git a/route/neighbor_resolver_parse.go b/route/neighbor_resolver_parse.go
new file mode 100644
index 0000000000..1979b7eabc
--- /dev/null
+++ b/route/neighbor_resolver_parse.go
@@ -0,0 +1,50 @@
+package route
+
+import (
+ "encoding/binary"
+ "encoding/hex"
+ "net"
+ "net/netip"
+ "slices"
+ "strings"
+)
+
+func extractMACFromDUID(duid []byte) (net.HardwareAddr, bool) {
+ if len(duid) < 4 {
+ return nil, false
+ }
+ duidType := binary.BigEndian.Uint16(duid[0:2])
+ hwType := binary.BigEndian.Uint16(duid[2:4])
+ if hwType != 1 {
+ return nil, false
+ }
+ switch duidType {
+ case 1:
+ if len(duid) < 14 {
+ return nil, false
+ }
+ return net.HardwareAddr(slices.Clone(duid[8:14])), true
+ case 3:
+ if len(duid) < 10 {
+ return nil, false
+ }
+ return net.HardwareAddr(slices.Clone(duid[4:10])), true
+ }
+ return nil, false
+}
+
+func extractMACFromEUI64(address netip.Addr) (net.HardwareAddr, bool) {
+ if !address.Is6() {
+ return nil, false
+ }
+ b := address.As16()
+ if b[11] != 0xff || b[12] != 0xfe {
+ return nil, false
+ }
+ return net.HardwareAddr{b[8] ^ 0x02, b[9], b[10], b[13], b[14], b[15]}, true
+}
+
+func parseDUID(s string) ([]byte, error) {
+ cleaned := strings.ReplaceAll(s, ":", "")
+ return hex.DecodeString(cleaned)
+}
diff --git a/route/neighbor_resolver_platform.go b/route/neighbor_resolver_platform.go
new file mode 100644
index 0000000000..a9930c0e43
--- /dev/null
+++ b/route/neighbor_resolver_platform.go
@@ -0,0 +1,90 @@
+package route
+
+import (
+ "net"
+ "net/netip"
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/logger"
+)
+
+type platformNeighborResolver struct {
+ logger logger.ContextLogger
+ platform adapter.PlatformInterface
+ access sync.RWMutex
+ ipToMAC map[netip.Addr]net.HardwareAddr
+ ipToHostname map[netip.Addr]string
+ macToHostname map[string]string
+}
+
+func newPlatformNeighborResolver(resolverLogger logger.ContextLogger, platform adapter.PlatformInterface) adapter.NeighborResolver {
+ return &platformNeighborResolver{
+ logger: resolverLogger,
+ platform: platform,
+ ipToMAC: make(map[netip.Addr]net.HardwareAddr),
+ ipToHostname: make(map[netip.Addr]string),
+ macToHostname: make(map[string]string),
+ }
+}
+
+func (r *platformNeighborResolver) Start() error {
+ return r.platform.StartNeighborMonitor(r)
+}
+
+func (r *platformNeighborResolver) Close() error {
+ return r.platform.CloseNeighborMonitor(r)
+}
+
+func (r *platformNeighborResolver) LookupMAC(address netip.Addr) (net.HardwareAddr, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ mac, found := r.ipToMAC[address]
+ if found {
+ return mac, true
+ }
+ return extractMACFromEUI64(address)
+}
+
+func (r *platformNeighborResolver) LookupAddresses(hostname string) []netip.Addr {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ return lookupAddressesByHostname(hostname, r.ipToHostname, r.macToHostname, r.ipToMAC)
+}
+
+func (r *platformNeighborResolver) LookupHostname(address netip.Addr) (string, bool) {
+ r.access.RLock()
+ defer r.access.RUnlock()
+ hostname, found := r.ipToHostname[address]
+ if found {
+ return hostname, true
+ }
+ mac, found := r.ipToMAC[address]
+ if !found {
+ mac, found = extractMACFromEUI64(address)
+ }
+ if !found {
+ return "", false
+ }
+ hostname, found = r.macToHostname[mac.String()]
+ return hostname, found
+}
+
+func (r *platformNeighborResolver) UpdateNeighborTable(entries []adapter.NeighborEntry) {
+ ipToMAC := make(map[netip.Addr]net.HardwareAddr)
+ ipToHostname := make(map[netip.Addr]string)
+ macToHostname := make(map[string]string)
+ for _, entry := range entries {
+ ipToMAC[entry.Address] = entry.MACAddress
+ if entry.Hostname != "" {
+ ipToHostname[entry.Address] = entry.Hostname
+ macToHostname[entry.MACAddress.String()] = entry.Hostname
+ }
+ }
+ r.access.Lock()
+ r.ipToMAC = ipToMAC
+ r.ipToHostname = ipToHostname
+ r.macToHostname = macToHostname
+ r.access.Unlock()
+ r.logger.Info("updated neighbor table: ", len(entries), " entries")
+}
diff --git a/route/neighbor_resolver_stub.go b/route/neighbor_resolver_stub.go
new file mode 100644
index 0000000000..177a1fccbc
--- /dev/null
+++ b/route/neighbor_resolver_stub.go
@@ -0,0 +1,14 @@
+//go:build !linux && !darwin
+
+package route
+
+import (
+ "os"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/logger"
+)
+
+func newNeighborResolver(_ logger.ContextLogger, _ []string) (adapter.NeighborResolver, error) {
+ return nil, os.ErrInvalid
+}
diff --git a/route/neighbor_table_darwin.go b/route/neighbor_table_darwin.go
new file mode 100644
index 0000000000..8ca2d0f0b7
--- /dev/null
+++ b/route/neighbor_table_darwin.go
@@ -0,0 +1,104 @@
+//go:build darwin
+
+package route
+
+import (
+ "net"
+ "net/netip"
+ "syscall"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "golang.org/x/net/route"
+ "golang.org/x/sys/unix"
+)
+
+func ReadNeighborEntries() ([]adapter.NeighborEntry, error) {
+ var entries []adapter.NeighborEntry
+ ipv4Entries, err := readNeighborEntriesAF(syscall.AF_INET)
+ if err != nil {
+ return nil, E.Cause(err, "read IPv4 neighbors")
+ }
+ entries = append(entries, ipv4Entries...)
+ ipv6Entries, err := readNeighborEntriesAF(syscall.AF_INET6)
+ if err != nil {
+ return nil, E.Cause(err, "read IPv6 neighbors")
+ }
+ entries = append(entries, ipv6Entries...)
+ return entries, nil
+}
+
+func readNeighborEntriesAF(addressFamily int) ([]adapter.NeighborEntry, error) {
+ rib, err := route.FetchRIB(addressFamily, route.RIBType(syscall.NET_RT_FLAGS), syscall.RTF_LLINFO)
+ if err != nil {
+ return nil, err
+ }
+ messages, err := route.ParseRIB(route.RIBType(syscall.NET_RT_FLAGS), rib)
+ if err != nil {
+ return nil, err
+ }
+ var entries []adapter.NeighborEntry
+ for _, message := range messages {
+ routeMessage, isRouteMessage := message.(*route.RouteMessage)
+ if !isRouteMessage {
+ continue
+ }
+ address, macAddress, ok := parseRouteNeighborEntry(routeMessage)
+ if !ok {
+ continue
+ }
+ entries = append(entries, adapter.NeighborEntry{
+ Address: address,
+ MACAddress: macAddress,
+ })
+ }
+ return entries, nil
+}
+
+func parseRouteNeighborEntry(message *route.RouteMessage) (address netip.Addr, macAddress net.HardwareAddr, ok bool) {
+ if len(message.Addrs) <= unix.RTAX_GATEWAY {
+ return
+ }
+ gateway, isLinkAddr := message.Addrs[unix.RTAX_GATEWAY].(*route.LinkAddr)
+ if !isLinkAddr || len(gateway.Addr) < 6 {
+ return
+ }
+ switch destination := message.Addrs[unix.RTAX_DST].(type) {
+ case *route.Inet4Addr:
+ address = netip.AddrFrom4(destination.IP)
+ case *route.Inet6Addr:
+ address = netip.AddrFrom16(destination.IP)
+ default:
+ return
+ }
+ macAddress = net.HardwareAddr(make([]byte, len(gateway.Addr)))
+ copy(macAddress, gateway.Addr)
+ ok = true
+ return
+}
+
+func ParseRouteNeighborMessage(message *route.RouteMessage) (address netip.Addr, macAddress net.HardwareAddr, isDelete bool, ok bool) {
+ isDelete = message.Type == unix.RTM_DELETE
+ if len(message.Addrs) <= unix.RTAX_GATEWAY {
+ return
+ }
+ switch destination := message.Addrs[unix.RTAX_DST].(type) {
+ case *route.Inet4Addr:
+ address = netip.AddrFrom4(destination.IP)
+ case *route.Inet6Addr:
+ address = netip.AddrFrom16(destination.IP)
+ default:
+ return
+ }
+ if !isDelete {
+ gateway, isLinkAddr := message.Addrs[unix.RTAX_GATEWAY].(*route.LinkAddr)
+ if !isLinkAddr || len(gateway.Addr) < 6 {
+ return
+ }
+ macAddress = net.HardwareAddr(make([]byte, len(gateway.Addr)))
+ copy(macAddress, gateway.Addr)
+ }
+ ok = true
+ return
+}
diff --git a/route/neighbor_table_linux.go b/route/neighbor_table_linux.go
new file mode 100644
index 0000000000..61a214fd3a
--- /dev/null
+++ b/route/neighbor_table_linux.go
@@ -0,0 +1,68 @@
+//go:build linux
+
+package route
+
+import (
+ "net"
+ "net/netip"
+ "slices"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ "github.com/jsimonetti/rtnetlink"
+ "github.com/mdlayher/netlink"
+ "golang.org/x/sys/unix"
+)
+
+func ReadNeighborEntries() ([]adapter.NeighborEntry, error) {
+ connection, err := rtnetlink.Dial(nil)
+ if err != nil {
+ return nil, E.Cause(err, "dial rtnetlink")
+ }
+ defer connection.Close()
+ neighbors, err := connection.Neigh.List()
+ if err != nil {
+ return nil, E.Cause(err, "list neighbors")
+ }
+ var entries []adapter.NeighborEntry
+ for _, neighbor := range neighbors {
+ if neighbor.Attributes == nil {
+ continue
+ }
+ if neighbor.Attributes.LLAddress == nil || len(neighbor.Attributes.Address) == 0 {
+ continue
+ }
+ address, ok := netip.AddrFromSlice(neighbor.Attributes.Address)
+ if !ok {
+ continue
+ }
+ entries = append(entries, adapter.NeighborEntry{
+ Address: address,
+ MACAddress: slices.Clone(neighbor.Attributes.LLAddress),
+ })
+ }
+ return entries, nil
+}
+
+func ParseNeighborMessage(message netlink.Message) (address netip.Addr, macAddress net.HardwareAddr, isDelete bool, ok bool) {
+ var neighMessage rtnetlink.NeighMessage
+ err := neighMessage.UnmarshalBinary(message.Data)
+ if err != nil {
+ return
+ }
+ if neighMessage.Attributes == nil || len(neighMessage.Attributes.Address) == 0 {
+ return
+ }
+ address, ok = netip.AddrFromSlice(neighMessage.Attributes.Address)
+ if !ok {
+ return
+ }
+ isDelete = message.Header.Type == unix.RTM_DELNEIGH
+ if !isDelete && neighMessage.Attributes.LLAddress == nil {
+ ok = false
+ return
+ }
+ macAddress = slices.Clone(neighMessage.Attributes.LLAddress)
+ return
+}
diff --git a/route/network.go b/route/network.go
index 03e94879bf..1393ca90a0 100644
--- a/route/network.go
+++ b/route/network.go
@@ -78,10 +78,11 @@ func NewNetworkManager(ctx context.Context, logger logger.ContextLogger, options
RoutingMark: uint32(options.DefaultMark),
DomainResolver: defaultDomainResolver.Server,
DomainResolveOptions: adapter.DNSQueryOptions{
- Strategy: C.DomainStrategy(defaultDomainResolver.Strategy),
- DisableCache: defaultDomainResolver.DisableCache,
- RewriteTTL: defaultDomainResolver.RewriteTTL,
- ClientSubnet: defaultDomainResolver.ClientSubnet.Build(netip.Prefix{}),
+ Strategy: C.DomainStrategy(defaultDomainResolver.Strategy),
+ DisableCache: defaultDomainResolver.DisableCache,
+ DisableOptimisticCache: defaultDomainResolver.DisableOptimisticCache,
+ RewriteTTL: defaultDomainResolver.RewriteTTL,
+ ClientSubnet: defaultDomainResolver.ClientSubnet.Build(netip.Prefix{}),
},
NetworkStrategy: (*C.NetworkStrategy)(options.DefaultNetworkStrategy),
NetworkType: common.Map(options.DefaultNetworkType, option.InterfaceType.Build),
@@ -424,7 +425,6 @@ func (r *NetworkManager) WIFIState() adapter.WIFIState {
}
func (r *NetworkManager) onWIFIStateChanged(state adapter.WIFIState) {
- state.BSSID = adapter.NormalizeWIFIBSSID(state.BSSID)
r.wifiStateMutex.Lock()
if state != r.wifiState {
r.wifiState = state
diff --git a/route/process_cache.go b/route/process_cache.go
index f99cebadb0..691a4e8e9d 100644
--- a/route/process_cache.go
+++ b/route/process_cache.go
@@ -3,8 +3,6 @@ package route
import (
"context"
"net/netip"
- "slices"
- "strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/process"
@@ -34,61 +32,3 @@ func (r *Router) findProcessInfoCached(ctx context.Context, network string, sour
r.processCache.Add(key, processCacheEntry{result: result, err: err})
return result, err
}
-
-func (r *Router) searchProcessInfo(ctx context.Context, metadata *adapter.InboundContext) {
- if r.processSearcher == nil || metadata.ProcessInfo != nil || !r.isLocalSource(metadata.Source.Addr) {
- return
- }
- var originDestination netip.AddrPort
- if metadata.OriginDestination.IsValid() {
- originDestination = metadata.OriginDestination.AddrPort()
- } else if metadata.Destination.IsIP() {
- originDestination = metadata.Destination.AddrPort()
- }
- processInfo, err := r.findProcessInfoCached(ctx, metadata.Network, metadata.Source.AddrPort(), originDestination)
- if err != nil {
- r.logger.InfoContext(ctx, "failed to search process: ", err)
- return
- }
- metadata.ProcessInfo = processInfo
- if processInfo.ProcessPath != "" {
- if processInfo.UserName != "" {
- r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath, ", user: ", processInfo.UserName)
- } else if processInfo.UserId != -1 {
- r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath, ", user id: ", processInfo.UserId)
- } else {
- r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath)
- }
- return
- }
- if len(processInfo.AndroidPackageNames) > 0 {
- r.logger.InfoContext(ctx, "found package name: ", strings.Join(processInfo.AndroidPackageNames, ", "))
- return
- }
- if processInfo.UserId != -1 {
- if processInfo.UserName != "" {
- r.logger.InfoContext(ctx, "found user: ", processInfo.UserName)
- } else {
- r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId)
- }
- }
-}
-
-func (r *Router) isLocalSource(source netip.Addr) bool {
- if source.IsLoopback() {
- return true
- }
- if r.platformInterface != nil {
- if slices.Contains(r.platformInterface.MyInterfaceAddress(), source) {
- return true
- }
- }
- for _, netInterface := range r.network.InterfaceFinder().Interfaces() {
- for _, prefix := range netInterface.Addresses {
- if prefix.Addr() == source {
- return true
- }
- }
- }
- return false
-}
diff --git a/route/route.go b/route/route.go
index aec5281c6c..339c00f69c 100644
--- a/route/route.go
+++ b/route/route.go
@@ -31,7 +31,7 @@ import (
// Deprecated: use RouteConnectionEx instead.
func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
- done := make(chan any)
+ done := make(chan interface{})
err := r.routeConnection(ctx, conn, metadata, N.OnceClose(func(it error) {
close(done)
}))
@@ -74,7 +74,7 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
metadata.LastInbound = metadata.Inbound
metadata.Inbound = metadata.InboundDetour
metadata.InboundDetour = ""
- injectable.NewConnectionEx(ctx, conn, metadata, onClose)
+ injectable.NewConnection(ctx, conn, metadata, onClose)
return nil
}
metadata.Network = N.NetworkTCP
@@ -152,8 +152,8 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
for _, tracker := range r.trackers {
conn = tracker.RoutedConnection(ctx, conn, metadata, selectedRule, selectedOutbound)
}
- if outboundHandler, isHandler := selectedOutbound.(adapter.ConnectionHandlerEx); isHandler {
- outboundHandler.NewConnectionEx(ctx, conn, metadata, onClose)
+ if outboundHandler, isHandler := selectedOutbound.(adapter.ConnectionHandler); isHandler {
+ outboundHandler.NewConnection(ctx, conn, metadata, onClose)
} else {
r.connection.NewConnection(ctx, selectedOutbound, conn, metadata, onClose)
}
@@ -161,7 +161,7 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
}
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
- done := make(chan any)
+ done := make(chan interface{})
err := r.routePacketConnection(ctx, conn, metadata, N.OnceClose(func(it error) {
close(done)
}))
@@ -209,7 +209,7 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
metadata.LastInbound = metadata.Inbound
metadata.Inbound = metadata.InboundDetour
metadata.InboundDetour = ""
- injectable.NewPacketConnectionEx(ctx, conn, metadata, onClose)
+ injectable.NewPacketConnection(ctx, conn, metadata, onClose)
return nil
}
// TODO: move to UoT
@@ -281,8 +281,8 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
if metadata.FakeIP {
conn = bufio.NewNATPacketConn(bufio.NewNetPacketConn(conn), metadata.OriginDestination, metadata.Destination)
}
- if outboundHandler, isHandler := selectedOutbound.(adapter.PacketConnectionHandlerEx); isHandler {
- outboundHandler.NewPacketConnectionEx(ctx, conn, metadata, onClose)
+ if outboundHandler, isHandler := selectedOutbound.(adapter.PacketConnectionHandler); isHandler {
+ outboundHandler.NewPacketConnection(ctx, conn, metadata, onClose)
} else {
r.connection.NewPacketConnection(ctx, selectedOutbound, conn, metadata, onClose)
}
@@ -407,7 +407,54 @@ func (r *Router) matchRule(
selectedRule adapter.Rule, selectedRuleIndex int,
buffers []*buf.Buffer, packetBuffers []*N.PacketBuffer, fatalErr error,
) {
- r.searchProcessInfo(ctx, metadata)
+ if r.processSearcher != nil && metadata.ProcessInfo == nil {
+ var originDestination netip.AddrPort
+ if metadata.OriginDestination.IsValid() {
+ originDestination = metadata.OriginDestination.AddrPort()
+ } else if metadata.Destination.IsIP() {
+ originDestination = metadata.Destination.AddrPort()
+ }
+ processInfo, fErr := r.findProcessInfoCached(ctx, metadata.Network, metadata.Source.AddrPort(), originDestination)
+ if fErr != nil {
+ r.logger.InfoContext(ctx, "failed to search process: ", fErr)
+ } else {
+ if processInfo.ProcessPath != "" {
+ if processInfo.UserName != "" {
+ r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath, ", user: ", processInfo.UserName)
+ } else if processInfo.UserId != -1 {
+ r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath, ", user id: ", processInfo.UserId)
+ } else {
+ r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath)
+ }
+ } else if len(processInfo.AndroidPackageNames) > 0 {
+ r.logger.InfoContext(ctx, "found package name: ", strings.Join(processInfo.AndroidPackageNames, ", "))
+ } else if processInfo.UserId != -1 {
+ if processInfo.UserName != "" {
+ r.logger.InfoContext(ctx, "found user: ", processInfo.UserName)
+ } else {
+ r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId)
+ }
+ }
+ metadata.ProcessInfo = processInfo
+ }
+ }
+ if r.neighborResolver != nil && metadata.SourceMACAddress == nil && metadata.Source.Addr.IsValid() {
+ mac, macFound := r.neighborResolver.LookupMAC(metadata.Source.Addr)
+ if macFound {
+ metadata.SourceMACAddress = mac
+ }
+ hostname, hostnameFound := r.neighborResolver.LookupHostname(metadata.Source.Addr)
+ if hostnameFound {
+ metadata.SourceHostname = hostname
+ if macFound {
+ r.logger.InfoContext(ctx, "found neighbor: ", mac, ", hostname: ", hostname)
+ } else {
+ r.logger.InfoContext(ctx, "found neighbor hostname: ", hostname)
+ }
+ } else if macFound {
+ r.logger.InfoContext(ctx, "found neighbor: ", mac)
+ }
+ }
if metadata.Destination.Addr.IsValid() && r.dnsTransport.FakeIP() != nil && r.dnsTransport.FakeIP().Store().Contains(metadata.Destination.Addr) {
domain, loaded := r.dnsTransport.FakeIP().Store().Lookup(metadata.Destination.Addr)
if !loaded {
@@ -487,6 +534,9 @@ match:
Fqdn: metadata.Destination.Fqdn,
}
}
+ if routeOptions.OverrideTunnelDestination != "" {
+ metadata.TunnelDestination = routeOptions.OverrideTunnelDestination
+ }
if routeOptions.NetworkStrategy != nil {
metadata.NetworkStrategy = routeOptions.NetworkStrategy
}
@@ -769,11 +819,12 @@ func (r *Router) actionResolve(ctx context.Context, metadata *adapter.InboundCon
}
}
addresses, err := r.dns.Lookup(adapter.WithContext(ctx, metadata), metadata.Destination.Fqdn, adapter.DNSQueryOptions{
- Transport: transport,
- Strategy: action.Strategy,
- DisableCache: action.DisableCache,
- RewriteTTL: action.RewriteTTL,
- ClientSubnet: action.ClientSubnet,
+ Transport: transport,
+ Strategy: action.Strategy,
+ DisableCache: action.DisableCache,
+ DisableOptimisticCache: action.DisableOptimisticCache,
+ RewriteTTL: action.RewriteTTL,
+ ClientSubnet: action.ClientSubnet,
})
if err != nil {
return err
diff --git a/route/router.go b/route/router.go
index bc19b5d38f..72f549c382 100644
--- a/route/router.go
+++ b/route/router.go
@@ -33,12 +33,16 @@ type Router struct {
dnsTransport adapter.DNSTransportManager
connection adapter.ConnectionManager
network adapter.NetworkManager
+ httpClientManager adapter.HTTPClientManager
rules []adapter.Rule
needFindProcess bool
+ needFindNeighbor bool
+ leaseFiles []string
ruleSets []adapter.RuleSet
ruleSetMap map[string]adapter.RuleSet
processSearcher process.Searcher
processCache freelru.Cache[processCacheKey, processCacheEntry]
+ neighborResolver adapter.NeighborResolver
pauseManager pause.Manager
trackers []adapter.ConnectionTracker
platformInterface adapter.PlatformInterface
@@ -55,9 +59,12 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
dnsTransport: service.FromContext[adapter.DNSTransportManager](ctx),
connection: service.FromContext[adapter.ConnectionManager](ctx),
network: service.FromContext[adapter.NetworkManager](ctx),
+ httpClientManager: service.FromContext[adapter.HTTPClientManager](ctx),
rules: make([]adapter.Rule, 0, len(options.Rules)),
ruleSetMap: make(map[string]adapter.RuleSet),
needFindProcess: hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess,
+ needFindNeighbor: hasRule(options.Rules, isNeighborRule) || hasDNSRule(dnsOptions.Rules, isNeighborDNSRule) || options.FindNeighbor,
+ leaseFiles: options.DHCPLeaseFiles,
pauseManager: service.FromContext[pause.Manager](ctx),
platformInterface: service.FromContext[adapter.PlatformInterface](ctx),
}
@@ -65,6 +72,10 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
func (r *Router) Initialize(rules []option.Rule, ruleSets []option.RuleSet) error {
for i, options := range rules {
+ err := R.ValidateNoNestedRuleActions(options)
+ if err != nil {
+ return E.Cause(err, "parse rule[", i, "]")
+ }
rule, err := R.NewRule(r.ctx, r.logger, options, false)
if err != nil {
return E.Cause(err, "parse rule[", i, "]")
@@ -89,15 +100,15 @@ func (r *Router) Start(stage adapter.StartStage) error {
monitor := taskmonitor.New(r.logger, C.StartTimeout)
switch stage {
case adapter.StartStateStart:
- var cacheContext *adapter.HTTPStartContext
+ var startContext *adapter.HTTPStartContext
if len(r.ruleSets) > 0 {
monitor.Start("initialize rule-set")
- cacheContext = adapter.NewHTTPStartContext(r.ctx)
+ startContext = adapter.NewHTTPStartContext()
var ruleSetStartGroup task.Group
for i, ruleSet := range r.ruleSets {
ruleSetInPlace := ruleSet
ruleSetStartGroup.Append0(func(ctx context.Context) error {
- err := ruleSetInPlace.StartContext(ctx, cacheContext)
+ err := ruleSetInPlace.StartContext(ctx, startContext)
if err != nil {
return E.Cause(err, "initialize rule-set[", i, "]")
}
@@ -112,11 +123,12 @@ func (r *Router) Start(stage adapter.StartStage) error {
return err
}
}
- if cacheContext != nil {
- cacheContext.Close()
+ if startContext != nil {
+ startContext.Close()
}
r.network.Initialize(r.ruleSets)
needFindProcess := r.needFindProcess
+ needFindNeighbor := r.needFindNeighbor
for _, ruleSet := range r.ruleSets {
metadata := ruleSet.Metadata()
if metadata.ContainsProcessRule {
@@ -151,6 +163,36 @@ func (r *Router) Start(stage adapter.StartStage) error {
processCache.SetLifetime(200 * time.Millisecond)
r.processCache = processCache
}
+ r.needFindNeighbor = needFindNeighbor
+ if needFindNeighbor {
+ if r.platformInterface != nil && r.platformInterface.UsePlatformNeighborResolver() {
+ monitor.Start("initialize neighbor resolver")
+ resolver := newPlatformNeighborResolver(r.logger, r.platformInterface)
+ err := resolver.Start()
+ monitor.Finish()
+ if err != nil {
+ r.logger.Error(E.Cause(err, "start neighbor resolver"))
+ } else {
+ r.neighborResolver = resolver
+ }
+ } else {
+ monitor.Start("initialize neighbor resolver")
+ resolver, err := newNeighborResolver(r.logger, r.leaseFiles)
+ monitor.Finish()
+ if err != nil {
+ if err != os.ErrInvalid {
+ r.logger.Error(E.Cause(err, "create neighbor resolver"))
+ }
+ } else {
+ err = resolver.Start()
+ if err != nil {
+ r.logger.Error(E.Cause(err, "start neighbor resolver"))
+ } else {
+ r.neighborResolver = resolver
+ }
+ }
+ }
+ }
case adapter.StartStatePostStart:
for i, rule := range r.rules {
monitor.Start("initialize rule[", i, "]")
@@ -182,6 +224,13 @@ func (r *Router) Start(stage adapter.StartStage) error {
func (r *Router) Close() error {
monitor := taskmonitor.New(r.logger, C.StopTimeout)
var err error
+ if r.neighborResolver != nil {
+ monitor.Start("close neighbor resolver")
+ err = E.Append(err, r.neighborResolver.Close(), func(closeErr error) error {
+ return E.Cause(closeErr, "close neighbor resolver")
+ })
+ monitor.Finish()
+ }
for i, rule := range r.rules {
monitor.Start("close rule[", i, "]")
err = E.Append(err, rule.Close(), func(err error) error {
@@ -223,7 +272,16 @@ func (r *Router) NeedFindProcess() bool {
return r.needFindProcess
}
+func (r *Router) NeedFindNeighbor() bool {
+ return r.needFindNeighbor
+}
+
+func (r *Router) NeighborResolver() adapter.NeighborResolver {
+ return r.neighborResolver
+}
+
func (r *Router) ResetNetwork() {
r.network.ResetNetwork()
+ r.httpClientManager.ResetNetwork()
r.dns.ResetNetwork()
}
diff --git a/route/rule/match_state.go b/route/rule/match_state.go
index 0d2e4b0b47..feac8418a2 100644
--- a/route/rule/match_state.go
+++ b/route/rule/match_state.go
@@ -42,11 +42,11 @@ func (s ruleMatchStateSet) combine(other ruleMatchStateSet) ruleMatchStateSet {
return 0
}
var combined ruleMatchStateSet
- for left := range ruleMatchState(16) {
+ for left := ruleMatchState(0); left < 16; left++ {
if !s.contains(left) {
continue
}
- for right := range ruleMatchState(16) {
+ for right := ruleMatchState(0); right < 16; right++ {
if !other.contains(right) {
continue
}
@@ -61,7 +61,7 @@ func (s ruleMatchStateSet) withBase(base ruleMatchState) ruleMatchStateSet {
return 0
}
var withBase ruleMatchStateSet
- for state := range ruleMatchState(16) {
+ for state := ruleMatchState(0); state < 16; state++ {
if !s.contains(state) {
continue
}
@@ -72,7 +72,7 @@ func (s ruleMatchStateSet) withBase(base ruleMatchState) ruleMatchStateSet {
func (s ruleMatchStateSet) filter(allowed func(ruleMatchState) bool) ruleMatchStateSet {
var filtered ruleMatchStateSet
- for state := range ruleMatchState(16) {
+ for state := ruleMatchState(0); state < 16; state++ {
if !s.contains(state) {
continue
}
@@ -91,6 +91,10 @@ type ruleStateMatcherWithBase interface {
matchStatesWithBase(metadata *adapter.InboundContext, base ruleMatchState) ruleMatchStateSet
}
+func matchHeadlessRuleStates(rule adapter.HeadlessRule, metadata *adapter.InboundContext) ruleMatchStateSet {
+ return matchHeadlessRuleStatesWithBase(rule, metadata, 0)
+}
+
func matchHeadlessRuleStatesWithBase(rule adapter.HeadlessRule, metadata *adapter.InboundContext, base ruleMatchState) ruleMatchStateSet {
if matcher, isStateMatcher := rule.(ruleStateMatcherWithBase); isStateMatcher {
return matcher.matchStatesWithBase(metadata, base)
@@ -104,6 +108,10 @@ func matchHeadlessRuleStatesWithBase(rule adapter.HeadlessRule, metadata *adapte
return 0
}
+func matchRuleItemStates(item RuleItem, metadata *adapter.InboundContext) ruleMatchStateSet {
+ return matchRuleItemStatesWithBase(item, metadata, 0)
+}
+
func matchRuleItemStatesWithBase(item RuleItem, metadata *adapter.InboundContext, base ruleMatchState) ruleMatchStateSet {
if matcher, isStateMatcher := item.(ruleStateMatcherWithBase); isStateMatcher {
return matcher.matchStatesWithBase(metadata, base)
diff --git a/route/rule/rule_abstract.go b/route/rule/rule_abstract.go
index 8a95fa6d2a..d7b844adbb 100644
--- a/route/rule/rule_abstract.go
+++ b/route/rule/rule_abstract.go
@@ -156,7 +156,6 @@ func (r *abstractDefaultRule) matchStatesWithBase(metadata *adapter.InboundConte
return r.invertedFailure(inheritedBase)
}
if r.invert {
- // DNS pre-lookup defers destination address-limit checks until the response phase.
if metadata.IgnoreDestinationIPCIDRMatch && stateSet == emptyRuleMatchState() && !metadata.DidMatch && len(r.destinationIPCIDRItems) > 0 {
return emptyRuleMatchState().withBase(inheritedBase)
}
diff --git a/route/rule/rule_abstract_test.go b/route/rule/rule_abstract_test.go
index a5bbc35379..ace3dec6ef 100644
--- a/route/rule/rule_abstract_test.go
+++ b/route/rule/rule_abstract_test.go
@@ -141,6 +141,7 @@ func TestAbstractLogicalRule_And_WithRuleSetInvert(t *testing.T) {
},
}
for _, testCase := range testCases {
+ testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
logicalRule := &abstractLogicalRule{
diff --git a/route/rule/rule_action.go b/route/rule/rule_action.go
index cac814e765..7cb4ff6973 100644
--- a/route/rule/rule_action.go
+++ b/route/rule/rule_action.go
@@ -13,7 +13,7 @@ import (
"github.com/sagernet/sing-box/common/sniff"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing-tun"
+ tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
@@ -34,6 +34,7 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
RuleActionRouteOptions: RuleActionRouteOptions{
OverrideAddress: M.ParseSocksaddrHostPort(action.RouteOptions.OverrideAddress, 0),
OverridePort: action.RouteOptions.OverridePort,
+ OverrideTunnelDestination: action.RouteOptions.OverrideTunnelDestination,
NetworkStrategy: (*C.NetworkStrategy)(action.RouteOptions.NetworkStrategy),
FallbackDelay: time.Duration(action.RouteOptions.FallbackDelay),
UDPDisableDomainUnmapping: action.RouteOptions.UDPDisableDomainUnmapping,
@@ -107,11 +108,12 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
return sniffAction, sniffAction.build()
case C.RuleActionTypeResolve:
return &RuleActionResolve{
- Server: action.ResolveOptions.Server,
- Strategy: C.DomainStrategy(action.ResolveOptions.Strategy),
- DisableCache: action.ResolveOptions.DisableCache,
- RewriteTTL: action.ResolveOptions.RewriteTTL,
- ClientSubnet: action.ResolveOptions.ClientSubnet.Build(netip.Prefix{}),
+ Server: action.ResolveOptions.Server,
+ Strategy: C.DomainStrategy(action.ResolveOptions.Strategy),
+ DisableCache: action.ResolveOptions.DisableCache,
+ DisableOptimisticCache: action.ResolveOptions.DisableOptimisticCache,
+ RewriteTTL: action.ResolveOptions.RewriteTTL,
+ ClientSubnet: action.ResolveOptions.ClientSubnet.Build(netip.Prefix{}),
}, nil
default:
panic(F.ToString("unknown rule action: ", action.Action))
@@ -126,18 +128,34 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
return &RuleActionDNSRoute{
Server: action.RouteOptions.Server,
RuleActionDNSRouteOptions: RuleActionDNSRouteOptions{
- Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
- DisableCache: action.RouteOptions.DisableCache,
- RewriteTTL: action.RouteOptions.RewriteTTL,
- ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
+ Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
+ DisableCache: action.RouteOptions.DisableCache,
+ DisableOptimisticCache: action.RouteOptions.DisableOptimisticCache,
+ RewriteTTL: action.RouteOptions.RewriteTTL,
+ ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
+ BypassIfFailed: action.RouteOptions.BypassIfFailed,
},
}
+ case C.RuleActionTypeEvaluate:
+ return &RuleActionEvaluate{
+ Server: action.RouteOptions.Server,
+ RuleActionDNSRouteOptions: RuleActionDNSRouteOptions{
+ Strategy: C.DomainStrategy(action.RouteOptions.Strategy),
+ DisableCache: action.RouteOptions.DisableCache,
+ DisableOptimisticCache: action.RouteOptions.DisableOptimisticCache,
+ RewriteTTL: action.RouteOptions.RewriteTTL,
+ ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptions.ClientSubnet)),
+ },
+ }
+ case C.RuleActionTypeRespond:
+ return &RuleActionRespond{}
case C.RuleActionTypeRouteOptions:
return &RuleActionDNSRouteOptions{
- Strategy: C.DomainStrategy(action.RouteOptionsOptions.Strategy),
- DisableCache: action.RouteOptionsOptions.DisableCache,
- RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
- ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
+ Strategy: C.DomainStrategy(action.RouteOptionsOptions.Strategy),
+ DisableCache: action.RouteOptionsOptions.DisableCache,
+ DisableOptimisticCache: action.RouteOptionsOptions.DisableOptimisticCache,
+ RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
+ ClientSubnet: netip.Prefix(common.PtrValueOrDefault(action.RouteOptionsOptions.ClientSubnet)),
}
case C.RuleActionTypeReject:
return &RuleActionReject{
@@ -195,6 +213,7 @@ func (r *RuleActionBypass) String() string {
type RuleActionRouteOptions struct {
OverrideAddress M.Socksaddr
OverridePort uint16
+ OverrideTunnelDestination string
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
@@ -205,6 +224,7 @@ type RuleActionRouteOptions struct {
TLSFragment bool
TLSFragmentFallbackDelay time.Duration
TLSRecordFragment bool
+ BypassIfFailed bool
}
func (r *RuleActionRouteOptions) Type() string {
@@ -223,6 +243,9 @@ func (r *RuleActionRouteOptions) Descriptions() []string {
if r.OverridePort > 0 {
descriptions = append(descriptions, F.ToString("override-port=", r.OverridePort))
}
+ if r.OverrideTunnelDestination != "" {
+ descriptions = append(descriptions, F.ToString("override-tunnel-destination=", r.OverrideTunnelDestination))
+ }
if r.NetworkStrategy != nil {
descriptions = append(descriptions, F.ToString("network-strategy=", r.NetworkStrategy))
}
@@ -230,7 +253,7 @@ func (r *RuleActionRouteOptions) Descriptions() []string {
descriptions = append(descriptions, F.ToString("network-type=", strings.Join(common.Map(r.NetworkType, C.InterfaceType.String), ",")))
}
if r.FallbackNetworkType != nil {
- descriptions = append(descriptions, F.ToString("fallback-network-type="+strings.Join(common.Map(r.NetworkType, C.InterfaceType.String), ",")))
+ descriptions = append(descriptions, F.ToString("fallback-network-type=", strings.Join(common.Map(r.FallbackNetworkType, C.InterfaceType.String), ",")))
}
if r.FallbackDelay > 0 {
descriptions = append(descriptions, F.ToString("fallback-delay=", r.FallbackDelay.String()))
@@ -266,25 +289,57 @@ func (r *RuleActionDNSRoute) Type() string {
}
func (r *RuleActionDNSRoute) String() string {
+ return formatDNSRouteAction("route", r.Server, r.RuleActionDNSRouteOptions)
+}
+
+type RuleActionEvaluate struct {
+ Server string
+ RuleActionDNSRouteOptions
+}
+
+func (r *RuleActionEvaluate) Type() string {
+ return C.RuleActionTypeEvaluate
+}
+
+func (r *RuleActionEvaluate) String() string {
+ return formatDNSRouteAction("evaluate", r.Server, r.RuleActionDNSRouteOptions)
+}
+
+type RuleActionRespond struct{}
+
+func (r *RuleActionRespond) Type() string {
+ return C.RuleActionTypeRespond
+}
+
+func (r *RuleActionRespond) String() string {
+ return "respond"
+}
+
+func formatDNSRouteAction(action string, server string, options RuleActionDNSRouteOptions) string {
var descriptions []string
- descriptions = append(descriptions, r.Server)
- if r.DisableCache {
+ descriptions = append(descriptions, server)
+ if options.DisableCache {
descriptions = append(descriptions, "disable-cache")
}
- if r.RewriteTTL != nil {
- descriptions = append(descriptions, F.ToString("rewrite-ttl=", *r.RewriteTTL))
+ if options.DisableOptimisticCache {
+ descriptions = append(descriptions, "disable-optimistic-cache")
}
- if r.ClientSubnet.IsValid() {
- descriptions = append(descriptions, F.ToString("client-subnet=", r.ClientSubnet))
+ if options.RewriteTTL != nil {
+ descriptions = append(descriptions, F.ToString("rewrite-ttl=", *options.RewriteTTL))
}
- return F.ToString("route(", strings.Join(descriptions, ","), ")")
+ if options.ClientSubnet.IsValid() {
+ descriptions = append(descriptions, F.ToString("client-subnet=", options.ClientSubnet))
+ }
+ return F.ToString(action, "(", strings.Join(descriptions, ","), ")")
}
type RuleActionDNSRouteOptions struct {
- Strategy C.DomainStrategy
- DisableCache bool
- RewriteTTL *uint32
- ClientSubnet netip.Prefix
+ Strategy C.DomainStrategy
+ DisableCache bool
+ DisableOptimisticCache bool
+ RewriteTTL *uint32
+ ClientSubnet netip.Prefix
+ BypassIfFailed bool
}
func (r *RuleActionDNSRouteOptions) Type() string {
@@ -296,6 +351,9 @@ func (r *RuleActionDNSRouteOptions) String() string {
if r.DisableCache {
descriptions = append(descriptions, "disable-cache")
}
+ if r.DisableOptimisticCache {
+ descriptions = append(descriptions, "disable-optimistic-cache")
+ }
if r.RewriteTTL != nil {
descriptions = append(descriptions, F.ToString("rewrite-ttl=", *r.RewriteTTL))
}
@@ -471,11 +529,12 @@ func (r *RuleActionSniff) String() string {
}
type RuleActionResolve struct {
- Server string
- Strategy C.DomainStrategy
- DisableCache bool
- RewriteTTL *uint32
- ClientSubnet netip.Prefix
+ Server string
+ Strategy C.DomainStrategy
+ DisableCache bool
+ DisableOptimisticCache bool
+ RewriteTTL *uint32
+ ClientSubnet netip.Prefix
}
func (r *RuleActionResolve) Type() string {
@@ -493,6 +552,9 @@ func (r *RuleActionResolve) String() string {
if r.DisableCache {
options = append(options, "disable_cache")
}
+ if r.DisableOptimisticCache {
+ options = append(options, "disable_optimistic_cache")
+ }
if r.RewriteTTL != nil {
options = append(options, F.ToString("rewrite_ttl=", *r.RewriteTTL))
}
diff --git a/route/rule/rule_default.go b/route/rule/rule_default.go
index b921c8b286..02409c335a 100644
--- a/route/rule/rule_default.go
+++ b/route/rule/rule_default.go
@@ -186,6 +186,16 @@ func NewDefaultRule(ctx context.Context, logger log.ContextLogger, options optio
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.TunnelSource) > 0 {
+ item := NewTunnelSourceItem(options.TunnelSource)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.TunnelDestination) > 0 {
+ item := NewTunnelDestinationItem(options.TunnelDestination)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)
@@ -209,6 +219,14 @@ func NewDefaultRule(ctx context.Context, logger log.ContextLogger, options optio
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.PackageNameRegex) > 0 {
+ item, err := NewPackageNameRegexItem(options.PackageNameRegex)
+ if err != nil {
+ return nil, E.Cause(err, "package_name_regex")
+ }
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.User) > 0 {
item := NewUserItem(options.User)
rule.items = append(rule.items, item)
@@ -264,6 +282,16 @@ func NewDefaultRule(ctx context.Context, logger log.ContextLogger, options optio
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.SourceMACAddress) > 0 {
+ item := NewSourceMACAddressItem(options.SourceMACAddress)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.SourceHostname) > 0 {
+ item := NewSourceHostnameItem(options.SourceHostname)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.PreferredBy) > 0 {
item := NewPreferredByItem(ctx, options.PreferredBy)
rule.items = append(rule.items, item)
@@ -316,6 +344,10 @@ func NewLogicalRule(ctx context.Context, logger log.ContextLogger, options optio
return nil, E.New("unknown logical mode: ", options.Mode)
}
for i, subOptions := range options.Rules {
+ err = validateNoNestedRuleActions(subOptions, true)
+ if err != nil {
+ return nil, E.Cause(err, "sub rule[", i, "]")
+ }
subRule, err := NewRule(ctx, logger, subOptions, false)
if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]")
diff --git a/route/rule/rule_dns.go b/route/rule/rule_dns.go
index 04f0f236b2..438c6fbdaf 100644
--- a/route/rule/rule_dns.go
+++ b/route/rule/rule_dns.go
@@ -5,58 +5,84 @@ import (
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/service"
+
+ "github.com/miekg/dns"
)
-func NewDNSRule(ctx context.Context, logger log.ContextLogger, options option.DNSRule, checkServer bool) (adapter.DNSRule, error) {
+func NewDNSRule(ctx context.Context, logger log.ContextLogger, options option.DNSRule, checkServer bool, legacyDNSMode bool) (adapter.DNSRule, error) {
switch options.Type {
case "", C.RuleTypeDefault:
if !options.DefaultOptions.IsValid() {
return nil, E.New("missing conditions")
}
+ if !checkServer && options.DefaultOptions.Action == C.RuleActionTypeEvaluate {
+ return nil, E.New(options.DefaultOptions.Action, " is only allowed on top-level DNS rules")
+ }
+ err := validateDNSRuleAction(options.DefaultOptions.DNSRuleAction)
+ if err != nil {
+ return nil, err
+ }
switch options.DefaultOptions.Action {
- case "", C.RuleActionTypeRoute:
+ case "", C.RuleActionTypeRoute, C.RuleActionTypeEvaluate:
if options.DefaultOptions.RouteOptions.Server == "" && checkServer {
return nil, E.New("missing server field")
}
}
- return NewDefaultDNSRule(ctx, logger, options.DefaultOptions)
+ return NewDefaultDNSRule(ctx, logger, options.DefaultOptions, legacyDNSMode)
case C.RuleTypeLogical:
if !options.LogicalOptions.IsValid() {
return nil, E.New("missing conditions")
}
+ if !checkServer && options.LogicalOptions.Action == C.RuleActionTypeEvaluate {
+ return nil, E.New(options.LogicalOptions.Action, " is only allowed on top-level DNS rules")
+ }
+ err := validateDNSRuleAction(options.LogicalOptions.DNSRuleAction)
+ if err != nil {
+ return nil, err
+ }
switch options.LogicalOptions.Action {
- case "", C.RuleActionTypeRoute:
+ case "", C.RuleActionTypeRoute, C.RuleActionTypeEvaluate:
if options.LogicalOptions.RouteOptions.Server == "" && checkServer {
return nil, E.New("missing server field")
}
}
- return NewLogicalDNSRule(ctx, logger, options.LogicalOptions)
+ return NewLogicalDNSRule(ctx, logger, options.LogicalOptions, legacyDNSMode)
default:
return nil, E.New("unknown rule type: ", options.Type)
}
}
+func validateDNSRuleAction(action option.DNSRuleAction) error {
+ if action.Action == C.RuleActionTypeReject && action.RejectOptions.Method == C.RuleActionRejectMethodReply {
+ return E.New("reject method `reply` is not supported for DNS rules")
+ }
+ return nil
+}
+
var _ adapter.DNSRule = (*DefaultDNSRule)(nil)
type DefaultDNSRule struct {
abstractDefaultRule
+ matchResponse bool
}
func (r *DefaultDNSRule) matchStates(metadata *adapter.InboundContext) ruleMatchStateSet {
return r.abstractDefaultRule.matchStates(metadata)
}
-func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options option.DefaultDNSRule) (*DefaultDNSRule, error) {
+func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options option.DefaultDNSRule, legacyDNSMode bool) (*DefaultDNSRule, error) {
rule := &DefaultDNSRule{
abstractDefaultRule: abstractDefaultRule{
invert: options.Invert,
action: NewDNSRuleAction(logger, options.DNSRuleAction),
},
+ matchResponse: options.MatchResponse,
}
if len(options.Inbound) > 0 {
item := NewInboundRule(options.Inbound)
@@ -116,7 +142,7 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.destinationAddressItems = append(rule.destinationAddressItems, item)
rule.allItems = append(rule.allItems, item)
}
- if len(options.Geosite) > 0 {
+ if len(options.Geosite) > 0 { //nolint:staticcheck
return nil, E.New("geosite database is deprecated in sing-box 1.8.0 and removed in sing-box 1.12.0")
}
if len(options.SourceGeoIP) > 0 {
@@ -156,6 +182,26 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.destinationIPCIDRItems = append(rule.destinationIPCIDRItems, item)
rule.allItems = append(rule.allItems, item)
}
+ if options.ResponseRcode != nil {
+ item := NewDNSResponseRCodeItem(int(*options.ResponseRcode))
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.ResponseAnswer) > 0 {
+ item := NewDNSResponseRecordItem("response_answer", options.ResponseAnswer, dnsResponseAnswers)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.ResponseNs) > 0 {
+ item := NewDNSResponseRecordItem("response_ns", options.ResponseNs, dnsResponseNS)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.ResponseExtra) > 0 {
+ item := NewDNSResponseRecordItem("response_extra", options.ResponseExtra, dnsResponseExtra)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.SourcePort) > 0 {
item := NewPortItem(true, options.SourcePort)
rule.sourcePortItems = append(rule.sourcePortItems, item)
@@ -182,6 +228,16 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.TunnelSource) > 0 {
+ item := NewTunnelSourceItem(options.TunnelSource)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.TunnelDestination) > 0 {
+ item := NewTunnelDestinationItem(options.TunnelDestination)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)
@@ -205,6 +261,14 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.PackageNameRegex) > 0 {
+ item, err := NewPackageNameRegexItem(options.PackageNameRegex)
+ if err != nil {
+ return nil, E.Cause(err, "package_name_regex")
+ }
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.User) > 0 {
item := NewUserItem(options.User)
rule.items = append(rule.items, item)
@@ -265,6 +329,23 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.SourceMACAddress) > 0 {
+ item := NewSourceMACAddressItem(options.SourceMACAddress)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.SourceHostname) > 0 {
+ item := NewSourceHostnameItem(options.SourceHostname)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if options.RuleSetIPCIDRAcceptEmpty { //nolint:staticcheck
+ if legacyDNSMode {
+ deprecated.Report(ctx, deprecated.OptionRuleSetIPCIDRAcceptEmpty)
+ } else {
+ return nil, E.New(deprecated.OptionRuleSetIPCIDRAcceptEmpty.MessageWithLink())
+ }
+ }
if len(options.RuleSet) > 0 {
//nolint:staticcheck
if options.Deprecated_RulesetIPCIDRMatchSource {
@@ -274,7 +355,7 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
if options.RuleSetIPCIDRMatchSource {
matchSource = true
}
- item := NewRuleSetItem(router, options.RuleSet, matchSource, options.RuleSetIPCIDRAcceptEmpty)
+ item := NewRuleSetItem(router, options.RuleSet, matchSource, options.RuleSetIPCIDRAcceptEmpty) //nolint:staticcheck
rule.ruleSetItem = item
rule.allItems = append(rule.allItems, item)
}
@@ -299,15 +380,35 @@ func (r *DefaultDNSRule) WithAddressLimit() bool {
}
func (r *DefaultDNSRule) Match(metadata *adapter.InboundContext) bool {
+ return !r.matchStatesForMatch(metadata).isEmpty()
+}
+
+func (r *DefaultDNSRule) LegacyPreMatch(metadata *adapter.InboundContext) bool {
+ if r.matchResponse {
+ return false
+ }
metadata.IgnoreDestinationIPCIDRMatch = true
- defer func() {
- metadata.IgnoreDestinationIPCIDRMatch = false
- }()
- return !r.matchStates(metadata).isEmpty()
+ defer func() { metadata.IgnoreDestinationIPCIDRMatch = false }()
+ return !r.abstractDefaultRule.matchStates(metadata).isEmpty()
}
-func (r *DefaultDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
- return !r.matchStates(metadata).isEmpty()
+func (r *DefaultDNSRule) matchStatesForMatch(metadata *adapter.InboundContext) ruleMatchStateSet {
+ if r.matchResponse {
+ if metadata.DNSResponse == nil {
+ return r.abstractDefaultRule.invertedFailure(0)
+ }
+ matchMetadata := *metadata
+ matchMetadata.DestinationAddressMatchFromResponse = true
+ return r.abstractDefaultRule.matchStates(&matchMetadata)
+ }
+ return r.abstractDefaultRule.matchStates(metadata)
+}
+
+func (r *DefaultDNSRule) MatchAddressLimit(metadata *adapter.InboundContext, response *dns.Msg) bool {
+ matchMetadata := *metadata
+ matchMetadata.DNSResponse = response
+ matchMetadata.DestinationAddressMatchFromResponse = true
+ return !r.abstractDefaultRule.matchStates(&matchMetadata).isEmpty()
}
var _ adapter.DNSRule = (*LogicalDNSRule)(nil)
@@ -320,7 +421,53 @@ func (r *LogicalDNSRule) matchStates(metadata *adapter.InboundContext) ruleMatch
return r.abstractLogicalRule.matchStates(metadata)
}
-func NewLogicalDNSRule(ctx context.Context, logger log.ContextLogger, options option.LogicalDNSRule) (*LogicalDNSRule, error) {
+func matchDNSHeadlessRuleStatesForMatch(rule adapter.HeadlessRule, metadata *adapter.InboundContext) ruleMatchStateSet {
+ switch typedRule := rule.(type) {
+ case *DefaultDNSRule:
+ return typedRule.matchStatesForMatch(metadata)
+ case *LogicalDNSRule:
+ return typedRule.matchStatesForMatch(metadata)
+ default:
+ return matchHeadlessRuleStates(typedRule, metadata)
+ }
+}
+
+func (r *LogicalDNSRule) matchStatesForMatch(metadata *adapter.InboundContext) ruleMatchStateSet {
+ var stateSet ruleMatchStateSet
+ if r.mode == C.LogicalTypeAnd {
+ stateSet = emptyRuleMatchState()
+ for _, rule := range r.rules {
+ nestedMetadata := *metadata
+ nestedMetadata.ResetRuleCache()
+ nestedStateSet := matchDNSHeadlessRuleStatesForMatch(rule, &nestedMetadata)
+ if nestedStateSet.isEmpty() {
+ if r.invert {
+ return emptyRuleMatchState()
+ }
+ return 0
+ }
+ stateSet = stateSet.combine(nestedStateSet)
+ }
+ } else {
+ for _, rule := range r.rules {
+ nestedMetadata := *metadata
+ nestedMetadata.ResetRuleCache()
+ stateSet = stateSet.merge(matchDNSHeadlessRuleStatesForMatch(rule, &nestedMetadata))
+ }
+ if stateSet.isEmpty() {
+ if r.invert {
+ return emptyRuleMatchState()
+ }
+ return 0
+ }
+ }
+ if r.invert {
+ return 0
+ }
+ return stateSet
+}
+
+func NewLogicalDNSRule(ctx context.Context, logger log.ContextLogger, options option.LogicalDNSRule, legacyDNSMode bool) (*LogicalDNSRule, error) {
r := &LogicalDNSRule{
abstractLogicalRule: abstractLogicalRule{
rules: make([]adapter.HeadlessRule, len(options.Rules)),
@@ -337,7 +484,11 @@ func NewLogicalDNSRule(ctx context.Context, logger log.ContextLogger, options op
return nil, E.New("unknown logical mode: ", options.Mode)
}
for i, subRule := range options.Rules {
- rule, err := NewDNSRule(ctx, logger, subRule, false)
+ err := validateNoNestedDNSRuleActions(subRule, true)
+ if err != nil {
+ return nil, E.Cause(err, "sub rule[", i, "]")
+ }
+ rule, err := NewDNSRule(ctx, logger, subRule, false, legacyDNSMode)
if err != nil {
return nil, E.Cause(err, "sub rule[", i, "]")
}
@@ -367,13 +518,32 @@ func (r *LogicalDNSRule) WithAddressLimit() bool {
}
func (r *LogicalDNSRule) Match(metadata *adapter.InboundContext) bool {
+ return !r.matchStatesForMatch(metadata).isEmpty()
+}
+
+func (r *LogicalDNSRule) LegacyPreMatch(metadata *adapter.InboundContext) bool {
metadata.IgnoreDestinationIPCIDRMatch = true
- defer func() {
- metadata.IgnoreDestinationIPCIDRMatch = false
- }()
- return !r.matchStates(metadata).isEmpty()
+ defer func() { metadata.IgnoreDestinationIPCIDRMatch = false }()
+ return !r.abstractLogicalRule.matchStates(metadata).isEmpty()
+}
+
+func (r *LogicalDNSRule) MatchAddressLimit(metadata *adapter.InboundContext, response *dns.Msg) bool {
+ matchMetadata := *metadata
+ matchMetadata.DNSResponse = response
+ matchMetadata.DestinationAddressMatchFromResponse = true
+ return !r.abstractLogicalRule.matchStates(&matchMetadata).isEmpty()
}
+func (r *LogicalDNSRule) BypassIfFailed() bool {
-func (r *LogicalDNSRule) MatchAddressLimit(metadata *adapter.InboundContext) bool {
- return !r.matchStates(metadata).isEmpty()
+ if act, ok := r.action.(*RuleActionDNSRoute); ok && act != nil {
+ return act.RuleActionDNSRouteOptions.BypassIfFailed
+ }
+ return false
+}
+
+func (r *DefaultDNSRule) BypassIfFailed() bool {
+ if act, ok := r.action.(*RuleActionDNSRoute); ok && act != nil {
+ return act.RuleActionDNSRouteOptions.BypassIfFailed
+ }
+ return false
}
diff --git a/route/rule/rule_headless.go b/route/rule/rule_headless.go
index c5146318b4..bef30d46c1 100644
--- a/route/rule/rule_headless.go
+++ b/route/rule/rule_headless.go
@@ -130,6 +130,16 @@ func NewDefaultHeadlessRule(ctx context.Context, options option.DefaultHeadlessR
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.TunnelSource) > 0 {
+ item := NewTunnelSourceItem(options.TunnelSource)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
+ if len(options.TunnelDestination) > 0 {
+ item := NewTunnelDestinationItem(options.TunnelDestination)
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)
@@ -153,6 +163,14 @@ func NewDefaultHeadlessRule(ctx context.Context, options option.DefaultHeadlessR
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
+ if len(options.PackageNameRegex) > 0 {
+ item, err := NewPackageNameRegexItem(options.PackageNameRegex)
+ if err != nil {
+ return nil, E.Cause(err, "package_name_regex")
+ }
+ rule.items = append(rule.items, item)
+ rule.allItems = append(rule.allItems, item)
+ }
if networkManager != nil {
if len(options.NetworkType) > 0 {
item := NewNetworkTypeItem(networkManager, common.Map(options.NetworkType, option.InterfaceType.Build))
diff --git a/route/rule/rule_item_cidr.go b/route/rule/rule_item_cidr.go
index 1b0105ea91..28f74161f1 100644
--- a/route/rule/rule_item_cidr.go
+++ b/route/rule/rule_item_cidr.go
@@ -2,7 +2,6 @@ package rule
import (
"net/netip"
- "slices"
"strings"
"github.com/sagernet/sing-box/adapter"
@@ -77,11 +76,31 @@ func (r *IPCIDRItem) Match(metadata *adapter.InboundContext) bool {
if r.isSource || metadata.IPCIDRMatchSource {
return r.ipSet.Contains(metadata.Source.Addr)
}
+ if metadata.DestinationAddressMatchFromResponse {
+ addresses := metadata.DNSResponseAddressesForMatch()
+ if len(addresses) == 0 {
+ // Legacy rule_set_ip_cidr_accept_empty only applies when the DNS response
+ // does not expose any address answers for matching.
+ return metadata.IPCIDRAcceptEmpty
+ }
+ for _, address := range addresses {
+ if r.ipSet.Contains(address) {
+ return true
+ }
+ }
+ return false
+ }
if metadata.Destination.IsIP() {
return r.ipSet.Contains(metadata.Destination.Addr)
}
- if len(metadata.DestinationAddresses) > 0 {
- return slices.ContainsFunc(metadata.DestinationAddresses, r.ipSet.Contains)
+ addresses := metadata.DestinationAddresses
+ if len(addresses) > 0 {
+ for _, address := range addresses {
+ if r.ipSet.Contains(address) {
+ return true
+ }
+ }
+ return false
}
return metadata.IPCIDRAcceptEmpty
}
diff --git a/route/rule/rule_item_domain.go b/route/rule/rule_item_domain.go
index 7e6484ea81..af790aa385 100644
--- a/route/rule/rule_item_domain.go
+++ b/route/rule/rule_item_domain.go
@@ -1,7 +1,6 @@
package rule
import (
- "slices"
"strings"
"github.com/sagernet/sing-box/adapter"
@@ -17,11 +16,15 @@ type DomainItem struct {
}
func NewDomainItem(domains []string, domainSuffixes []string) (*DomainItem, error) {
- if slices.Contains(domains, "") {
- return nil, E.New("domain: empty item is not allowed")
+ for _, domainItem := range domains {
+ if domainItem == "" {
+ return nil, E.New("domain: empty item is not allowed")
+ }
}
- if slices.Contains(domainSuffixes, "") {
- return nil, E.New("domain_suffix: empty item is not allowed")
+ for _, domainSuffixItem := range domainSuffixes {
+ if domainSuffixItem == "" {
+ return nil, E.New("domain_suffix: empty item is not allowed")
+ }
}
var description string
if dLen := len(domains); dLen > 0 {
diff --git a/route/rule/rule_item_ip_accept_any.go b/route/rule/rule_item_ip_accept_any.go
index 1ca7125735..fceebc1860 100644
--- a/route/rule/rule_item_ip_accept_any.go
+++ b/route/rule/rule_item_ip_accept_any.go
@@ -13,6 +13,9 @@ func NewIPAcceptAnyItem() *IPAcceptAnyItem {
}
func (r *IPAcceptAnyItem) Match(metadata *adapter.InboundContext) bool {
+ if metadata.DestinationAddressMatchFromResponse {
+ return len(metadata.DNSResponseAddressesForMatch()) > 0
+ }
return len(metadata.DestinationAddresses) > 0
}
diff --git a/route/rule/rule_item_ip_is_private.go b/route/rule/rule_item_ip_is_private.go
index e185db1db4..c968877395 100644
--- a/route/rule/rule_item_ip_is_private.go
+++ b/route/rule/rule_item_ip_is_private.go
@@ -1,8 +1,6 @@
package rule
import (
- "net/netip"
-
"github.com/sagernet/sing-box/adapter"
N "github.com/sagernet/sing/common/network"
)
@@ -18,21 +16,24 @@ func NewIPIsPrivateItem(isSource bool) *IPIsPrivateItem {
}
func (r *IPIsPrivateItem) Match(metadata *adapter.InboundContext) bool {
- var destination netip.Addr
if r.isSource {
- destination = metadata.Source.Addr
- } else {
- destination = metadata.Destination.Addr
- }
- if destination.IsValid() {
- return !N.IsPublicAddr(destination)
+ return !N.IsPublicAddr(metadata.Source.Addr)
}
- if !r.isSource {
- for _, destinationAddress := range metadata.DestinationAddresses {
+ if metadata.DestinationAddressMatchFromResponse {
+ for _, destinationAddress := range metadata.DNSResponseAddressesForMatch() {
if !N.IsPublicAddr(destinationAddress) {
return true
}
}
+ return false
+ }
+ if metadata.Destination.Addr.IsValid() {
+ return !N.IsPublicAddr(metadata.Destination.Addr)
+ }
+ for _, destinationAddress := range metadata.DestinationAddresses {
+ if !N.IsPublicAddr(destinationAddress) {
+ return true
+ }
}
return false
}
diff --git a/route/rule/rule_item_package_name_regex.go b/route/rule/rule_item_package_name_regex.go
new file mode 100644
index 0000000000..9db4504acf
--- /dev/null
+++ b/route/rule/rule_item_package_name_regex.go
@@ -0,0 +1,56 @@
+package rule
+
+import (
+ "regexp"
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+ F "github.com/sagernet/sing/common/format"
+)
+
+var _ RuleItem = (*PackageNameRegexItem)(nil)
+
+type PackageNameRegexItem struct {
+ matchers []*regexp.Regexp
+ description string
+}
+
+func NewPackageNameRegexItem(expressions []string) (*PackageNameRegexItem, error) {
+ matchers := make([]*regexp.Regexp, 0, len(expressions))
+ for i, regex := range expressions {
+ matcher, err := regexp.Compile(regex)
+ if err != nil {
+ return nil, E.Cause(err, "parse expression ", i)
+ }
+ matchers = append(matchers, matcher)
+ }
+ description := "package_name_regex="
+ eLen := len(expressions)
+ if eLen == 1 {
+ description += expressions[0]
+ } else if eLen > 3 {
+ description += F.ToString("[", strings.Join(expressions[:3], " "), "]")
+ } else {
+ description += F.ToString("[", strings.Join(expressions, " "), "]")
+ }
+ return &PackageNameRegexItem{matchers, description}, nil
+}
+
+func (r *PackageNameRegexItem) Match(metadata *adapter.InboundContext) bool {
+ if metadata.ProcessInfo == nil || len(metadata.ProcessInfo.AndroidPackageNames) == 0 {
+ return false
+ }
+ for _, matcher := range r.matchers {
+ for _, packageName := range metadata.ProcessInfo.AndroidPackageNames {
+ if matcher.MatchString(packageName) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (r *PackageNameRegexItem) String() string {
+ return r.description
+}
diff --git a/route/rule/rule_item_preferred_by_dns.go b/route/rule/rule_item_preferred_by_dns.go
new file mode 100644
index 0000000000..d00d780c62
--- /dev/null
+++ b/route/rule/rule_item_preferred_by_dns.go
@@ -0,0 +1,74 @@
+package rule
+
+import (
+ "context"
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+ E "github.com/sagernet/sing/common/exceptions"
+ F "github.com/sagernet/sing/common/format"
+ "github.com/sagernet/sing/service"
+
+ mDNS "github.com/miekg/dns"
+)
+
+var _ RuleItem = (*PreferredByDNSItem)(nil)
+
+type PreferredByDNSItem struct {
+ ctx context.Context
+ transportTags []string
+ transports []adapter.DNSTransportWithPreferredDomain
+}
+
+func NewPreferredByDNSItem(ctx context.Context, transportTags []string) *PreferredByDNSItem {
+ return &PreferredByDNSItem{
+ ctx: ctx,
+ transportTags: transportTags,
+ }
+}
+
+func (r *PreferredByDNSItem) Start() error {
+ transportManager := service.FromContext[adapter.DNSTransportManager](r.ctx)
+ for _, transportTag := range r.transportTags {
+ rawTransport, loaded := transportManager.Transport(transportTag)
+ if !loaded {
+ return E.New("DNS server not found: ", transportTag)
+ }
+ transportWithPreferredDomain, withPreferredDomain := rawTransport.(adapter.DNSTransportWithPreferredDomain)
+ if !withPreferredDomain {
+ return E.New("DNS server type does not support preferred_by: ", rawTransport.Type())
+ }
+ r.transports = append(r.transports, transportWithPreferredDomain)
+ }
+ return nil
+}
+
+func (r *PreferredByDNSItem) Match(metadata *adapter.InboundContext) bool {
+ var domainHost string
+ if metadata.Domain != "" {
+ domainHost = metadata.Domain
+ } else {
+ domainHost = metadata.Destination.Fqdn
+ }
+ if domainHost == "" {
+ return false
+ }
+ canonical := mDNS.CanonicalName(domainHost)
+ for _, transport := range r.transports {
+ if transport.PreferredDomain(canonical) {
+ return true
+ }
+ }
+ return false
+}
+
+func (r *PreferredByDNSItem) String() string {
+ description := "preferred_by="
+ pLen := len(r.transportTags)
+ if pLen == 1 {
+ description += F.ToString(r.transportTags[0])
+ } else {
+ description += "[" + strings.Join(F.MapToString(r.transportTags), " ") + "]"
+ }
+ return description
+}
diff --git a/route/rule/rule_item_response_rcode.go b/route/rule/rule_item_response_rcode.go
new file mode 100644
index 0000000000..cac75e8034
--- /dev/null
+++ b/route/rule/rule_item_response_rcode.go
@@ -0,0 +1,26 @@
+package rule
+
+import (
+ "github.com/sagernet/sing-box/adapter"
+ F "github.com/sagernet/sing/common/format"
+
+ "github.com/miekg/dns"
+)
+
+var _ RuleItem = (*DNSResponseRCodeItem)(nil)
+
+type DNSResponseRCodeItem struct {
+ rcode int
+}
+
+func NewDNSResponseRCodeItem(rcode int) *DNSResponseRCodeItem {
+ return &DNSResponseRCodeItem{rcode: rcode}
+}
+
+func (r *DNSResponseRCodeItem) Match(metadata *adapter.InboundContext) bool {
+ return metadata.DNSResponse != nil && metadata.DNSResponse.Rcode == r.rcode
+}
+
+func (r *DNSResponseRCodeItem) String() string {
+ return F.ToString("response_rcode=", dns.RcodeToString[r.rcode])
+}
diff --git a/route/rule/rule_item_response_record.go b/route/rule/rule_item_response_record.go
new file mode 100644
index 0000000000..3a2c889beb
--- /dev/null
+++ b/route/rule/rule_item_response_record.go
@@ -0,0 +1,63 @@
+package rule
+
+import (
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/option"
+
+ "github.com/miekg/dns"
+)
+
+var _ RuleItem = (*DNSResponseRecordItem)(nil)
+
+type DNSResponseRecordItem struct {
+ field string
+ records []option.DNSRecordOptions
+ selector func(*dns.Msg) []dns.RR
+}
+
+func NewDNSResponseRecordItem(field string, records []option.DNSRecordOptions, selector func(*dns.Msg) []dns.RR) *DNSResponseRecordItem {
+ return &DNSResponseRecordItem{
+ field: field,
+ records: records,
+ selector: selector,
+ }
+}
+
+func (r *DNSResponseRecordItem) Match(metadata *adapter.InboundContext) bool {
+ if metadata.DNSResponse == nil {
+ return false
+ }
+ records := r.selector(metadata.DNSResponse)
+ for _, expected := range r.records {
+ for _, record := range records {
+ if expected.Match(record) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (r *DNSResponseRecordItem) String() string {
+ descriptions := make([]string, 0, len(r.records))
+ for _, record := range r.records {
+ if record.RR != nil {
+ descriptions = append(descriptions, record.RR.String())
+ }
+ }
+ return r.field + "=[" + strings.Join(descriptions, " ") + "]"
+}
+
+func dnsResponseAnswers(message *dns.Msg) []dns.RR {
+ return message.Answer
+}
+
+func dnsResponseNS(message *dns.Msg) []dns.RR {
+ return message.Ns
+}
+
+func dnsResponseExtra(message *dns.Msg) []dns.RR {
+ return message.Extra
+}
diff --git a/route/rule/rule_item_rule_set.go b/route/rule/rule_item_rule_set.go
index 3467843ba1..0136494353 100644
--- a/route/rule/rule_item_rule_set.go
+++ b/route/rule/rule_item_rule_set.go
@@ -29,9 +29,11 @@ func NewRuleSetItem(router adapter.Router, tagList []string, ipCIDRMatchSource b
}
func (r *RuleSetItem) Start() error {
+ _ = r.Close()
for _, tag := range r.tagList {
ruleSet, loaded := r.router.RuleSet(tag)
if !loaded {
+ _ = r.Close()
return E.New("rule-set not found: ", tag)
}
ruleSet.IncRef()
@@ -40,6 +42,15 @@ func (r *RuleSetItem) Start() error {
return nil
}
+func (r *RuleSetItem) Close() error {
+ for _, ruleSet := range r.setList {
+ ruleSet.DecRef()
+ }
+ clear(r.setList)
+ r.setList = nil
+ return nil
+}
+
func (r *RuleSetItem) Match(metadata *adapter.InboundContext) bool {
return !r.matchStates(metadata).isEmpty()
}
diff --git a/route/rule/rule_item_rule_set_test.go b/route/rule/rule_item_rule_set_test.go
new file mode 100644
index 0000000000..21d2070d9b
--- /dev/null
+++ b/route/rule/rule_item_rule_set_test.go
@@ -0,0 +1,138 @@
+package rule
+
+import (
+ "context"
+ "net"
+ "sync/atomic"
+ "testing"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-tun"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/x/list"
+
+ "github.com/stretchr/testify/require"
+ "go4.org/netipx"
+)
+
+type ruleSetItemTestRouter struct {
+ ruleSets map[string]adapter.RuleSet
+}
+
+func (r *ruleSetItemTestRouter) Start(adapter.StartStage) error { return nil }
+func (r *ruleSetItemTestRouter) Close() error { return nil }
+func (r *ruleSetItemTestRouter) PreMatch(adapter.InboundContext, tun.DirectRouteContext, time.Duration, bool) (tun.DirectRouteDestination, error) {
+ return nil, nil
+}
+
+func (r *ruleSetItemTestRouter) RouteConnection(context.Context, net.Conn, adapter.InboundContext) error {
+ return nil
+}
+
+func (r *ruleSetItemTestRouter) RoutePacketConnection(context.Context, N.PacketConn, adapter.InboundContext) error {
+ return nil
+}
+
+func (r *ruleSetItemTestRouter) RouteConnectionEx(context.Context, net.Conn, adapter.InboundContext, N.CloseHandlerFunc) {
+}
+
+func (r *ruleSetItemTestRouter) RoutePacketConnectionEx(context.Context, N.PacketConn, adapter.InboundContext, N.CloseHandlerFunc) {
+}
+
+func (r *ruleSetItemTestRouter) RuleSet(tag string) (adapter.RuleSet, bool) {
+ ruleSet, loaded := r.ruleSets[tag]
+ return ruleSet, loaded
+}
+func (r *ruleSetItemTestRouter) Rules() []adapter.Rule { return nil }
+func (r *ruleSetItemTestRouter) NeedFindProcess() bool { return false }
+func (r *ruleSetItemTestRouter) NeedFindNeighbor() bool { return false }
+func (r *ruleSetItemTestRouter) NeighborResolver() adapter.NeighborResolver { return nil }
+func (r *ruleSetItemTestRouter) AppendTracker(adapter.ConnectionTracker) {}
+func (r *ruleSetItemTestRouter) ResetNetwork() {}
+
+type countingRuleSet struct {
+ name string
+ refs atomic.Int32
+}
+
+func (s *countingRuleSet) Name() string { return s.name }
+func (s *countingRuleSet) StartContext(context.Context, *adapter.HTTPStartContext) error { return nil }
+func (s *countingRuleSet) PostStart() error { return nil }
+func (s *countingRuleSet) Metadata() adapter.RuleSetMetadata { return adapter.RuleSetMetadata{} }
+func (s *countingRuleSet) ExtractIPSet() []*netipx.IPSet { return nil }
+func (s *countingRuleSet) IncRef() { s.refs.Add(1) }
+func (s *countingRuleSet) DecRef() {
+ if s.refs.Add(-1) < 0 {
+ panic("rule-set: negative refs")
+ }
+}
+func (s *countingRuleSet) Cleanup() {}
+func (s *countingRuleSet) RegisterCallback(adapter.RuleSetUpdateCallback) *list.Element[adapter.RuleSetUpdateCallback] {
+ return nil
+}
+func (s *countingRuleSet) UnregisterCallback(*list.Element[adapter.RuleSetUpdateCallback]) {}
+func (s *countingRuleSet) Close() error { return nil }
+func (s *countingRuleSet) Match(*adapter.InboundContext) bool { return true }
+func (s *countingRuleSet) String() string { return s.name }
+func (s *countingRuleSet) RefCount() int32 { return s.refs.Load() }
+
+func TestRuleSetItemCloseReleasesRefs(t *testing.T) {
+ t.Parallel()
+
+ firstSet := &countingRuleSet{name: "first"}
+ secondSet := &countingRuleSet{name: "second"}
+ item := NewRuleSetItem(&ruleSetItemTestRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "first": firstSet,
+ "second": secondSet,
+ },
+ }, []string{"first", "second"}, false, false)
+
+ require.NoError(t, item.Start())
+ require.EqualValues(t, 1, firstSet.RefCount())
+ require.EqualValues(t, 1, secondSet.RefCount())
+
+ require.NoError(t, item.Close())
+ require.Zero(t, firstSet.RefCount())
+ require.Zero(t, secondSet.RefCount())
+
+ require.NoError(t, item.Close())
+ require.Zero(t, firstSet.RefCount())
+ require.Zero(t, secondSet.RefCount())
+}
+
+func TestRuleSetItemStartRollbackOnFailure(t *testing.T) {
+ t.Parallel()
+
+ firstSet := &countingRuleSet{name: "first"}
+ item := NewRuleSetItem(&ruleSetItemTestRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "first": firstSet,
+ },
+ }, []string{"first", "missing"}, false, false)
+
+ err := item.Start()
+ require.ErrorContains(t, err, "rule-set not found: missing")
+ require.Zero(t, firstSet.RefCount())
+}
+
+func TestRuleSetItemRestartKeepsBalancedRefs(t *testing.T) {
+ t.Parallel()
+
+ firstSet := &countingRuleSet{name: "first"}
+ item := NewRuleSetItem(&ruleSetItemTestRouter{
+ ruleSets: map[string]adapter.RuleSet{
+ "first": firstSet,
+ },
+ }, []string{"first"}, false, false)
+
+ require.NoError(t, item.Start())
+ require.EqualValues(t, 1, firstSet.RefCount())
+
+ require.NoError(t, item.Start())
+ require.EqualValues(t, 1, firstSet.RefCount())
+
+ require.NoError(t, item.Close())
+ require.Zero(t, firstSet.RefCount())
+}
diff --git a/route/rule/rule_item_source_hostname.go b/route/rule/rule_item_source_hostname.go
new file mode 100644
index 0000000000..0df11c8c8a
--- /dev/null
+++ b/route/rule/rule_item_source_hostname.go
@@ -0,0 +1,42 @@
+package rule
+
+import (
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+)
+
+var _ RuleItem = (*SourceHostnameItem)(nil)
+
+type SourceHostnameItem struct {
+ hostnames []string
+ hostnameMap map[string]bool
+}
+
+func NewSourceHostnameItem(hostnameList []string) *SourceHostnameItem {
+ rule := &SourceHostnameItem{
+ hostnames: hostnameList,
+ hostnameMap: make(map[string]bool),
+ }
+ for _, hostname := range hostnameList {
+ rule.hostnameMap[hostname] = true
+ }
+ return rule
+}
+
+func (r *SourceHostnameItem) Match(metadata *adapter.InboundContext) bool {
+ if metadata.SourceHostname == "" {
+ return false
+ }
+ return r.hostnameMap[metadata.SourceHostname]
+}
+
+func (r *SourceHostnameItem) String() string {
+ var description string
+ if len(r.hostnames) == 1 {
+ description = "source_hostname=" + r.hostnames[0]
+ } else {
+ description = "source_hostname=[" + strings.Join(r.hostnames, " ") + "]"
+ }
+ return description
+}
diff --git a/route/rule/rule_item_source_mac_address.go b/route/rule/rule_item_source_mac_address.go
new file mode 100644
index 0000000000..feeadb1dbf
--- /dev/null
+++ b/route/rule/rule_item_source_mac_address.go
@@ -0,0 +1,48 @@
+package rule
+
+import (
+ "net"
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+)
+
+var _ RuleItem = (*SourceMACAddressItem)(nil)
+
+type SourceMACAddressItem struct {
+ addresses []string
+ addressMap map[string]bool
+}
+
+func NewSourceMACAddressItem(addressList []string) *SourceMACAddressItem {
+ rule := &SourceMACAddressItem{
+ addresses: addressList,
+ addressMap: make(map[string]bool),
+ }
+ for _, address := range addressList {
+ parsed, err := net.ParseMAC(address)
+ if err == nil {
+ rule.addressMap[parsed.String()] = true
+ } else {
+ rule.addressMap[address] = true
+ }
+ }
+ return rule
+}
+
+func (r *SourceMACAddressItem) Match(metadata *adapter.InboundContext) bool {
+ if metadata.SourceMACAddress == nil {
+ return false
+ }
+ return r.addressMap[metadata.SourceMACAddress.String()]
+}
+
+func (r *SourceMACAddressItem) String() string {
+ var description string
+ if len(r.addresses) == 1 {
+ description = "source_mac_address=" + r.addresses[0]
+ } else {
+ description = "source_mac_address=[" + strings.Join(r.addresses, " ") + "]"
+ }
+ return description
+}
diff --git a/route/rule/rule_item_tunnel_destination.go b/route/rule/rule_item_tunnel_destination.go
new file mode 100644
index 0000000000..34f711d6eb
--- /dev/null
+++ b/route/rule/rule_item_tunnel_destination.go
@@ -0,0 +1,35 @@
+package rule
+
+import (
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+ F "github.com/sagernet/sing/common/format"
+)
+
+var _ RuleItem = (*TunnelDestinationItem)(nil)
+
+type TunnelDestinationItem struct {
+ destinations []string
+ destinationMap map[string]bool
+}
+
+func NewTunnelDestinationItem(destinations []string) *TunnelDestinationItem {
+ rule := &TunnelDestinationItem{destinations, make(map[string]bool)}
+ for _, destination := range destinations {
+ rule.destinationMap[destination] = true
+ }
+ return rule
+}
+
+func (r *TunnelDestinationItem) Match(metadata *adapter.InboundContext) bool {
+ return r.destinationMap[metadata.TunnelDestination]
+}
+
+func (r *TunnelDestinationItem) String() string {
+ if len(r.destinations) == 1 {
+ return F.ToString("tunnel_destination=", r.destinations[0])
+ } else {
+ return F.ToString("tunnel_destination=[", strings.Join(r.destinations, " "), "]")
+ }
+}
diff --git a/route/rule/rule_item_tunnel_source.go b/route/rule/rule_item_tunnel_source.go
new file mode 100644
index 0000000000..6a2f01cb2f
--- /dev/null
+++ b/route/rule/rule_item_tunnel_source.go
@@ -0,0 +1,35 @@
+package rule
+
+import (
+ "strings"
+
+ "github.com/sagernet/sing-box/adapter"
+ F "github.com/sagernet/sing/common/format"
+)
+
+var _ RuleItem = (*TunnelSourceItem)(nil)
+
+type TunnelSourceItem struct {
+ sources []string
+ sourceMap map[string]bool
+}
+
+func NewTunnelSourceItem(sources []string) *TunnelSourceItem {
+ rule := &TunnelSourceItem{sources, make(map[string]bool)}
+ for _, source := range sources {
+ rule.sourceMap[source] = true
+ }
+ return rule
+}
+
+func (r *TunnelSourceItem) Match(metadata *adapter.InboundContext) bool {
+ return r.sourceMap[metadata.TunnelSource]
+}
+
+func (r *TunnelSourceItem) String() string {
+ if len(r.sources) == 1 {
+ return F.ToString("tunnel_source=", r.sources[0])
+ } else {
+ return F.ToString("tunnel_source=[", strings.Join(r.sources, " "), "]")
+ }
+}
diff --git a/route/rule/rule_item_wifi_bssid.go b/route/rule/rule_item_wifi_bssid.go
index 703562ba79..8f887322e5 100644
--- a/route/rule/rule_item_wifi_bssid.go
+++ b/route/rule/rule_item_wifi_bssid.go
@@ -18,7 +18,7 @@ type WIFIBSSIDItem struct {
func NewWIFIBSSIDItem(networkManager adapter.NetworkManager, bssidList []string) *WIFIBSSIDItem {
bssidMap := make(map[string]bool)
for _, bssid := range bssidList {
- bssidMap[adapter.NormalizeWIFIBSSID(bssid)] = true
+ bssidMap[bssid] = true
}
return &WIFIBSSIDItem{
bssidList,
diff --git a/route/rule/rule_nested_action.go b/route/rule/rule_nested_action.go
new file mode 100644
index 0000000000..44e58839b5
--- /dev/null
+++ b/route/rule/rule_nested_action.go
@@ -0,0 +1,71 @@
+package rule
+
+import (
+ "reflect"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+func ValidateNoNestedRuleActions(rule option.Rule) error {
+ return validateNoNestedRuleActions(rule, false)
+}
+
+func ValidateNoNestedDNSRuleActions(rule option.DNSRule) error {
+ return validateNoNestedDNSRuleActions(rule, false)
+}
+
+func validateNoNestedRuleActions(rule option.Rule, nested bool) error {
+ if nested && ruleHasConfiguredAction(rule) {
+ return E.New(option.RouteRuleActionNestedUnsupportedMessage)
+ }
+ if rule.Type != C.RuleTypeLogical {
+ return nil
+ }
+ for i, subRule := range rule.LogicalOptions.Rules {
+ err := validateNoNestedRuleActions(subRule, true)
+ if err != nil {
+ return E.Cause(err, "sub rule[", i, "]")
+ }
+ }
+ return nil
+}
+
+func validateNoNestedDNSRuleActions(rule option.DNSRule, nested bool) error {
+ if nested && dnsRuleHasConfiguredAction(rule) {
+ return E.New(option.DNSRuleActionNestedUnsupportedMessage)
+ }
+ if rule.Type != C.RuleTypeLogical {
+ return nil
+ }
+ for i, subRule := range rule.LogicalOptions.Rules {
+ err := validateNoNestedDNSRuleActions(subRule, true)
+ if err != nil {
+ return E.Cause(err, "sub rule[", i, "]")
+ }
+ }
+ return nil
+}
+
+func ruleHasConfiguredAction(rule option.Rule) bool {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ return !reflect.DeepEqual(rule.DefaultOptions.RuleAction, option.RuleAction{})
+ case C.RuleTypeLogical:
+ return !reflect.DeepEqual(rule.LogicalOptions.RuleAction, option.RuleAction{})
+ default:
+ return false
+ }
+}
+
+func dnsRuleHasConfiguredAction(rule option.DNSRule) bool {
+ switch rule.Type {
+ case "", C.RuleTypeDefault:
+ return !reflect.DeepEqual(rule.DefaultOptions.DNSRuleAction, option.DNSRuleAction{})
+ case C.RuleTypeLogical:
+ return !reflect.DeepEqual(rule.LogicalOptions.DNSRuleAction, option.DNSRuleAction{})
+ default:
+ return false
+ }
+}
diff --git a/route/rule/rule_nested_action_test.go b/route/rule/rule_nested_action_test.go
new file mode 100644
index 0000000000..f895b89282
--- /dev/null
+++ b/route/rule/rule_nested_action_test.go
@@ -0,0 +1,88 @@
+package rule
+
+import (
+ "context"
+ "testing"
+
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestNewRuleRejectsNestedRuleAction(t *testing.T) {
+ t.Parallel()
+
+ _, err := NewRule(context.Background(), log.NewNOPFactory().NewLogger("router"), option.Rule{
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalRule{
+ RawLogicalRule: option.RawLogicalRule{
+ Mode: C.LogicalTypeAnd,
+ Rules: []option.Rule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultRule{
+ RuleAction: option.RuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.RouteActionOptions{
+ Outbound: "direct",
+ },
+ },
+ },
+ }},
+ },
+ },
+ }, false)
+ require.ErrorContains(t, err, option.RouteRuleActionNestedUnsupportedMessage)
+}
+
+func TestNewDNSRuleRejectsNestedRuleAction(t *testing.T) {
+ t.Parallel()
+
+ _, err := NewDNSRule(context.Background(), log.NewNOPFactory().NewLogger("dns"), option.DNSRule{
+ Type: C.RuleTypeLogical,
+ LogicalOptions: option.LogicalDNSRule{
+ RawLogicalDNSRule: option.RawLogicalDNSRule{
+ Mode: C.LogicalTypeAnd,
+ Rules: []option.DNSRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{
+ Server: "default",
+ },
+ },
+ },
+ }},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeRoute,
+ RouteOptions: option.DNSRouteActionOptions{
+ Server: "default",
+ },
+ },
+ },
+ }, true, false)
+ require.ErrorContains(t, err, option.DNSRuleActionNestedUnsupportedMessage)
+}
+
+func TestNewDNSRuleRejectsReplyRejectMethod(t *testing.T) {
+ t.Parallel()
+
+ _, err := NewDNSRule(context.Background(), log.NewNOPFactory().NewLogger("dns"), option.DNSRule{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultDNSRule{
+ RawDefaultDNSRule: option.RawDefaultDNSRule{
+ Domain: []string{"example.com"},
+ },
+ DNSRuleAction: option.DNSRuleAction{
+ Action: C.RuleActionTypeReject,
+ RejectOptions: option.RejectActionOptions{
+ Method: C.RuleActionRejectMethodReply,
+ },
+ },
+ },
+ }, false, false)
+ require.ErrorContains(t, err, "reject method `reply` is not supported for DNS rules")
+}
diff --git a/route/rule/rule_network_interface_address.go b/route/rule/rule_network_interface_address.go
index 135a703e98..c699c593fa 100644
--- a/route/rule/rule_network_interface_address.go
+++ b/route/rule/rule_network_interface_address.go
@@ -40,13 +40,9 @@ func NewNetworkInterfaceAddressItem(networkManager adapter.NetworkManager, inter
func (r *NetworkInterfaceAddressItem) Match(metadata *adapter.InboundContext) bool {
interfaces := r.networkManager.NetworkInterfaces()
- myInterface := r.networkManager.InterfaceMonitor().MyInterface()
match:
for ifType, addresses := range r.interfaceAddresses {
for _, networkInterface := range interfaces {
- if networkInterface.Name == myInterface {
- continue
- }
if networkInterface.Type != ifType {
continue
}
diff --git a/route/rule/rule_set.go b/route/rule/rule_set.go
index 39068dbf35..6720e788b7 100644
--- a/route/rule/rule_set.go
+++ b/route/rule/rule_set.go
@@ -2,6 +2,7 @@ package rule
import (
"context"
+ "reflect"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
@@ -9,6 +10,7 @@ import (
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
+ "github.com/sagernet/sing/service"
"go4.org/netipx"
)
@@ -18,7 +20,7 @@ func NewRuleSet(ctx context.Context, logger logger.ContextLogger, options option
case C.RuleSetTypeInline, C.RuleSetTypeLocal, "":
return NewLocalRuleSet(ctx, logger, options)
case C.RuleSetTypeRemote:
- return NewRemoteRuleSet(ctx, logger, options), nil
+ return NewRemoteRuleSet(ctx, logger, options)
default:
return nil, E.New("unknown rule-set type: ", options.Type)
}
@@ -59,7 +61,7 @@ func HasHeadlessRule(rules []option.HeadlessRule, cond func(rule option.DefaultH
}
func isProcessHeadlessRule(rule option.DefaultHeadlessRule) bool {
- return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0
+ return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.PackageNameRegex) > 0
}
func isWIFIHeadlessRule(rule option.DefaultHeadlessRule) bool {
@@ -69,3 +71,34 @@ func isWIFIHeadlessRule(rule option.DefaultHeadlessRule) bool {
func isIPCIDRHeadlessRule(rule option.DefaultHeadlessRule) bool {
return len(rule.IPCIDR) > 0 || rule.IPSet != nil
}
+
+func isDNSQueryTypeHeadlessRule(rule option.DefaultHeadlessRule) bool {
+ return len(rule.QueryType) > 0
+}
+
+func isNonIPCIDRHeadlessRule(rule option.DefaultHeadlessRule) bool {
+ ipOnly := option.DefaultHeadlessRule{
+ IPCIDR: rule.IPCIDR,
+ IPSet: rule.IPSet,
+ Invert: rule.Invert,
+ }
+ return !reflect.DeepEqual(rule, ipOnly)
+}
+
+func buildRuleSetMetadata(headlessRules []option.HeadlessRule) adapter.RuleSetMetadata {
+ return adapter.RuleSetMetadata{
+ ContainsProcessRule: HasHeadlessRule(headlessRules, isProcessHeadlessRule),
+ ContainsWIFIRule: HasHeadlessRule(headlessRules, isWIFIHeadlessRule),
+ ContainsIPCIDRRule: HasHeadlessRule(headlessRules, isIPCIDRHeadlessRule),
+ ContainsDNSQueryTypeRule: HasHeadlessRule(headlessRules, isDNSQueryTypeHeadlessRule),
+ ContainsNonIPCIDRRule: HasHeadlessRule(headlessRules, isNonIPCIDRHeadlessRule),
+ }
+}
+
+func validateRuleSetMetadataUpdate(ctx context.Context, tag string, metadata adapter.RuleSetMetadata) error {
+ validator := service.FromContext[adapter.DNSRuleSetUpdateValidator](ctx)
+ if validator == nil {
+ return nil
+ }
+ return validator.ValidateRuleSetMetadataUpdate(tag, metadata)
+}
diff --git a/route/rule/rule_set_local.go b/route/rule/rule_set_local.go
index ed873d7069..5408615fc0 100644
--- a/route/rule/rule_set_local.go
+++ b/route/rule/rule_set_local.go
@@ -137,10 +137,11 @@ func (s *LocalRuleSet) reloadRules(headlessRules []option.HeadlessRule) error {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}
}
- var metadata adapter.RuleSetMetadata
- metadata.ContainsProcessRule = HasHeadlessRule(headlessRules, isProcessHeadlessRule)
- metadata.ContainsWIFIRule = HasHeadlessRule(headlessRules, isWIFIHeadlessRule)
- metadata.ContainsIPCIDRRule = HasHeadlessRule(headlessRules, isIPCIDRHeadlessRule)
+ metadata := buildRuleSetMetadata(headlessRules)
+ err = validateRuleSetMetadataUpdate(s.ctx, s.tag, metadata)
+ if err != nil {
+ return err
+ }
s.access.Lock()
s.rules = rules
s.metadata = metadata
diff --git a/route/rule/rule_set_remote.go b/route/rule/rule_set_remote.go
index bda6e23f1e..3802482cda 100644
--- a/route/rule/rule_set_remote.go
+++ b/route/rule/rule_set_remote.go
@@ -3,9 +3,7 @@ package rule
import (
"bytes"
"context"
- "crypto/tls"
"io"
- "net"
"net/http"
"runtime"
"strings"
@@ -16,15 +14,13 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/srs"
C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/experimental/deprecated"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/json"
"github.com/sagernet/sing/common/logger"
- M "github.com/sagernet/sing/common/metadata"
- N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/common/ntp"
"github.com/sagernet/sing/common/x/list"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/pause"
@@ -41,20 +37,21 @@ type RemoteRuleSet struct {
outbound adapter.OutboundManager
options option.RuleSet
updateInterval time.Duration
- dialer N.Dialer
+ httpClient *http.Client
access sync.RWMutex
rules []adapter.HeadlessRule
metadata adapter.RuleSetMetadata
lastUpdated time.Time
lastEtag string
updateTicker *time.Ticker
+ startupTicker *time.Ticker //H
cacheFile adapter.CacheFile
pauseManager pause.Manager
callbacks list.List[adapter.RuleSetUpdateCallback]
refs atomic.Int32
}
-func NewRemoteRuleSet(ctx context.Context, logger logger.ContextLogger, options option.RuleSet) *RemoteRuleSet {
+func NewRemoteRuleSet(ctx context.Context, logger logger.ContextLogger, options option.RuleSet) (*RemoteRuleSet, error) {
ctx, cancel := context.WithCancel(ctx)
var updateInterval time.Duration
if options.RemoteOptions.UpdateInterval > 0 {
@@ -70,7 +67,7 @@ func NewRemoteRuleSet(ctx context.Context, logger logger.ContextLogger, options
options: options,
updateInterval: updateInterval,
pauseManager: service.FromContext[pause.Manager](ctx),
- }
+ }, nil
}
func (s *RemoteRuleSet) Name() string {
@@ -83,20 +80,15 @@ func (s *RemoteRuleSet) String() string {
func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter.HTTPStartContext) error {
s.cacheFile = service.FromContext[adapter.CacheFile](s.ctx)
- var dialer N.Dialer
- if s.options.RemoteOptions.DownloadDetour != "" {
- outbound, loaded := s.outbound.Outbound(s.options.RemoteOptions.DownloadDetour)
- if !loaded {
- return E.New("download detour not found: ", s.options.RemoteOptions.DownloadDetour)
- }
- dialer = outbound
- } else {
- dialer = s.outbound.Default()
+ transport, err := s.resolveTransport()
+ if err != nil {
+ return E.Cause(err, "create rule-set http client")
}
- s.dialer = dialer
+ startContext.Register(transport)
+ s.httpClient = &http.Client{Transport: transport}
if s.cacheFile != nil {
if savedSet := s.cacheFile.LoadRuleSet(s.options.Tag); savedSet != nil {
- err := s.loadBytes(savedSet.Content)
+ err = s.loadBytes(savedSet.Content)
if err != nil {
return E.Cause(err, "restore cached rule-set")
}
@@ -105,9 +97,9 @@ func (s *RemoteRuleSet) StartContext(ctx context.Context, startContext *adapter.
}
}
if s.lastUpdated.IsZero() {
- err := s.fetch(ctx, startContext)
+ err = s.fetch(ctx, true)
if err != nil {
- return E.Cause(err, "initial rule-set: ", s.options.Tag)
+ s.logger.Error(E.Cause(err, "initial rule-set: ", s.options.Tag))
}
}
s.updateTicker = time.NewTicker(s.updateInterval)
@@ -189,10 +181,13 @@ func (s *RemoteRuleSet) loadBytes(content []byte) error {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}
}
+ metadata := buildRuleSetMetadata(plainRuleSet.Rules)
+ err = validateRuleSetMetadataUpdate(s.ctx, s.options.Tag, metadata)
+ if err != nil {
+ return err
+ }
s.access.Lock()
- s.metadata.ContainsProcessRule = HasHeadlessRule(plainRuleSet.Rules, isProcessHeadlessRule)
- s.metadata.ContainsWIFIRule = HasHeadlessRule(plainRuleSet.Rules, isWIFIHeadlessRule)
- s.metadata.ContainsIPCIDRRule = HasHeadlessRule(plainRuleSet.Rules, isIPCIDRHeadlessRule)
+ s.metadata = metadata
s.rules = rules
callbacks := s.callbacks.Array()
s.access.Unlock()
@@ -204,13 +199,18 @@ func (s *RemoteRuleSet) loadBytes(content []byte) error {
func (s *RemoteRuleSet) loopUpdate() {
if time.Since(s.lastUpdated) > s.updateInterval {
- err := s.fetch(s.ctx, nil)
- if err != nil {
- s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err)
- } else if s.refs.Load() == 0 {
- s.rules = nil
+ s.updateOnce()
+ }
+ for s.lastUpdated.IsZero() {
+ select {
+ case <-s.ctx.Done():
+ return
+ case <-s.startupTicker.C:
+ s.updateOnce()
}
+
}
+
for {
runtime.GC()
select {
@@ -223,7 +223,7 @@ func (s *RemoteRuleSet) loopUpdate() {
}
func (s *RemoteRuleSet) updateOnce() {
- err := s.fetch(s.ctx, nil)
+ err := s.fetch(s.ctx, false)
if err != nil {
s.logger.Error("fetch rule-set ", s.options.Tag, ": ", err)
} else if s.refs.Load() == 0 {
@@ -231,26 +231,8 @@ func (s *RemoteRuleSet) updateOnce() {
}
}
-func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPStartContext) error {
+func (s *RemoteRuleSet) fetch(ctx context.Context, isStart bool) error {
s.logger.Debug("updating rule-set ", s.options.Tag, " from URL: ", s.options.RemoteOptions.URL)
- var httpClient *http.Client
- if startContext != nil {
- httpClient = startContext.HTTPClient(s.options.RemoteOptions.DownloadDetour, s.dialer)
- } else {
- httpClient = &http.Client{
- Transport: &http.Transport{
- ForceAttemptHTTP2: true,
- TLSHandshakeTimeout: C.TCPTimeout,
- DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
- return s.dialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
- },
- TLSClientConfig: &tls.Config{
- Time: ntp.TimeFuncFromContext(s.ctx),
- RootCAs: adapter.RootPoolFromContext(s.ctx),
- },
- },
- }
- }
request, err := http.NewRequest("GET", s.options.RemoteOptions.URL, nil)
if err != nil {
return err
@@ -258,10 +240,14 @@ func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPSta
if s.lastEtag != "" {
request.Header.Set("If-None-Match", s.lastEtag)
}
- response, err := httpClient.Do(request.WithContext(ctx))
+ if !isStart {
+ defer s.httpClient.CloseIdleConnections()
+ }
+ response, err := s.httpClient.Do(request.WithContext(ctx))
if err != nil {
return err
}
+ defer response.Body.Close()
switch response.StatusCode {
case http.StatusOK:
case http.StatusNotModified:
@@ -284,15 +270,12 @@ func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPSta
}
content, err := io.ReadAll(response.Body)
if err != nil {
- response.Body.Close()
return err
}
err = s.loadBytes(content)
if err != nil {
- response.Body.Close()
return err
}
- response.Body.Close()
eTagHeader := response.Header.Get("Etag")
if eTagHeader != "" {
s.lastEtag = eTagHeader
@@ -312,9 +295,36 @@ func (s *RemoteRuleSet) fetch(ctx context.Context, startContext *adapter.HTTPSta
return nil
}
+func (s *RemoteRuleSet) resolveTransport() (adapter.HTTPTransport, error) {
+ httpClientManager := service.FromContext[adapter.HTTPClientManager](s.ctx)
+ if s.options.RemoteOptions.HTTPClient != nil && !s.options.RemoteOptions.HTTPClient.IsEmpty() {
+ if s.options.RemoteOptions.DownloadDetour != "" { //nolint:staticcheck
+ return nil, E.New("http_client is conflict with deprecated download_detour field")
+ }
+ return httpClientManager.ResolveTransport(s.ctx, s.logger, *s.options.RemoteOptions.HTTPClient)
+ }
+ if s.options.RemoteOptions.DownloadDetour != "" { //nolint:staticcheck
+ deprecated.Report(s.ctx, deprecated.OptionLegacyRuleSetDownloadDetour)
+ return httpClientManager.ResolveTransport(s.ctx, s.logger, option.HTTPClientOptions{
+ DialerOptions: option.DialerOptions{
+ Detour: s.options.RemoteOptions.DownloadDetour, //nolint:staticcheck
+ },
+ DisableEmptyDirectCheck: true,
+ })
+ }
+ defaultTransport := httpClientManager.DefaultTransport()
+ if defaultTransport == nil {
+ return nil, E.New("default http client transport is not initialized")
+ }
+ return defaultTransport, nil
+}
+
func (s *RemoteRuleSet) Close() error {
s.rules = nil
s.cancel()
+ if s.startupTicker != nil {
+ s.startupTicker.Stop()
+ }
if s.updateTicker != nil {
s.updateTicker.Stop()
}
diff --git a/route/rule/rule_set_semantics_test.go b/route/rule/rule_set_semantics_test.go
index f198501524..2fc559d204 100644
--- a/route/rule/rule_set_semantics_test.go
+++ b/route/rule/rule_set_semantics_test.go
@@ -2,6 +2,7 @@ package rule
import (
"context"
+ "net"
"net/netip"
"strings"
"testing"
@@ -14,6 +15,7 @@ import (
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ mDNS "github.com/miekg/dns"
"github.com/stretchr/testify/require"
)
@@ -57,6 +59,7 @@ func TestRouteRuleSetMergeDestinationAddressGroup(t *testing.T) {
},
}
for _, testCase := range testCases {
+ testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
ruleSet := newLocalRuleSetForTest("merge-destination", testCase.inner)
@@ -222,6 +225,7 @@ func TestRouteRuleSetOuterGroupedStateMergesIntoSameGroup(t *testing.T) {
},
}
for _, testCase := range testCases {
+ testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
ruleSet := newLocalRuleSetForTest("outer-merge-"+testCase.name, headlessDefaultRule(t, func(rule *abstractDefaultRule) {
@@ -579,7 +583,7 @@ func TestDNSRuleSetSemantics(t *testing.T) {
addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
})
- require.True(t, rule.MatchAddressLimit(&metadata))
+ require.True(t, rule.MatchAddressLimit(&metadata, dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))))
})
t.Run("dns keeps ruleset or semantics", func(t *testing.T) {
t.Parallel()
@@ -594,7 +598,7 @@ func TestDNSRuleSetSemantics(t *testing.T) {
addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{emptyStateSet, destinationStateSet}})
addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
})
- require.True(t, rule.MatchAddressLimit(&metadata))
+ require.True(t, rule.MatchAddressLimit(&metadata, dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))))
})
t.Run("ruleset ip cidr flags stay scoped", func(t *testing.T) {
t.Parallel()
@@ -608,10 +612,384 @@ func TestDNSRuleSetSemantics(t *testing.T) {
ipCidrAcceptEmpty: true,
})
})
- require.True(t, rule.MatchAddressLimit(&metadata))
+ require.True(t, rule.MatchAddressLimit(&metadata, dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))))
+ require.False(t, rule.MatchAddressLimit(&metadata, dnsResponseForTest(netip.MustParseAddr("8.8.8.8"))))
+ require.True(t, rule.MatchAddressLimit(&metadata, dnsResponseForTest()))
require.False(t, metadata.IPCIDRMatchSource)
require.False(t, metadata.IPCIDRAcceptEmpty)
})
+ t.Run("pre lookup ruleset only deferred fields fail closed", func(t *testing.T) {
+ t.Parallel()
+ metadata := testMetadata("lookup.example")
+ ruleSet := newLocalRuleSetForTest("dns-prelookup-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }))
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+ // This is accepted without match_response so mixed rule_set deployments keep
+ // working; the destination-IP-only branch simply cannot match before a DNS
+ // response is available.
+ require.False(t, rule.Match(&metadata))
+ })
+ t.Run("pre lookup ruleset destination cidr does not fall back to other predicates", func(t *testing.T) {
+ t.Parallel()
+ metadata := testMetadata("lookup.example")
+ ruleSet := newLocalRuleSetForTest("dns-prelookup-network-and-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addOtherItem(rule, NewNetworkItem([]string{N.NetworkTCP}))
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }))
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+ require.False(t, rule.Match(&metadata))
+ })
+ t.Run("pre lookup mixed ruleset still matches non response branch", func(t *testing.T) {
+ t.Parallel()
+ metadata := testMetadata("www.example.com")
+ ruleSet := newLocalRuleSetForTest(
+ "dns-prelookup-mixed",
+ headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addOtherItem(rule, NewNetworkItem([]string{N.NetworkTCP}))
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }),
+ headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addDestinationAddressItem(t, rule, nil, []string{"example.com"})
+ }),
+ )
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+ // Destination-IP predicates inside rule_set fail closed before the DNS response,
+ // but they must not force validation errors or suppress sibling non-response
+ // branches.
+ require.True(t, rule.Match(&metadata))
+ })
+}
+
+func TestDNSMatchResponseRuleSetDestinationCIDRUsesDNSResponse(t *testing.T) {
+ t.Parallel()
+
+ ruleSet := newLocalRuleSetForTest("dns-response-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }))
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+ rule.matchResponse = true
+
+ matchedMetadata := testMetadata("lookup.example")
+ matchedMetadata.DNSResponse = dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))
+ require.True(t, rule.Match(&matchedMetadata))
+ require.Empty(t, matchedMetadata.DestinationAddresses)
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ unmatchedMetadata.DNSResponse = dnsResponseForTest(netip.MustParseAddr("8.8.8.8"))
+ require.False(t, rule.Match(&unmatchedMetadata))
+}
+
+func TestDNSMatchResponseMissingResponseUsesBooleanSemantics(t *testing.T) {
+ t.Parallel()
+
+ t.Run("plain rule remains false", func(t *testing.T) {
+ t.Parallel()
+
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {})
+ rule.matchResponse = true
+
+ metadata := testMetadata("lookup.example")
+ require.False(t, rule.Match(&metadata))
+ })
+
+ t.Run("invert rule becomes true", func(t *testing.T) {
+ t.Parallel()
+
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ rule.invert = true
+ })
+ rule.matchResponse = true
+
+ metadata := testMetadata("lookup.example")
+ require.True(t, rule.Match(&metadata))
+ })
+
+ t.Run("logical wrapper respects inverted child", func(t *testing.T) {
+ t.Parallel()
+
+ nestedRule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ rule.invert = true
+ })
+ nestedRule.matchResponse = true
+
+ logicalRule := &LogicalDNSRule{
+ abstractLogicalRule: abstractLogicalRule{
+ rules: []adapter.HeadlessRule{nestedRule},
+ mode: C.LogicalTypeAnd,
+ },
+ }
+
+ metadata := testMetadata("lookup.example")
+ require.True(t, logicalRule.Match(&metadata))
+ })
+}
+
+func TestDNSAddressLimitIgnoresDestinationAddresses(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ build func(*testing.T, *abstractDefaultRule)
+ matchedResponse *mDNS.Msg
+ unmatchedResponse *mDNS.Msg
+ }{
+ {
+ name: "ip_cidr",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("203.0.113.1")),
+ unmatchedResponse: dnsResponseForTest(netip.MustParseAddr("8.8.8.8")),
+ },
+ {
+ name: "ip_is_private",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPIsPrivateItem(rule)
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("10.0.0.1")),
+ unmatchedResponse: dnsResponseForTest(netip.MustParseAddr("8.8.8.8")),
+ },
+ {
+ name: "ip_accept_any",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPAcceptAnyItem(rule)
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("203.0.113.1")),
+ unmatchedResponse: dnsResponseForTest(),
+ },
+ }
+ for _, testCase := range testCases {
+ testCase := testCase
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ testCase.build(t, rule)
+ })
+
+ mismatchMetadata := testMetadata("lookup.example")
+ mismatchMetadata.DestinationAddresses = []netip.Addr{netip.MustParseAddr("203.0.113.1")}
+ require.False(t, rule.MatchAddressLimit(&mismatchMetadata, testCase.unmatchedResponse))
+
+ matchMetadata := testMetadata("lookup.example")
+ matchMetadata.DestinationAddresses = []netip.Addr{netip.MustParseAddr("8.8.8.8")}
+ require.True(t, rule.MatchAddressLimit(&matchMetadata, testCase.matchedResponse))
+ })
+ }
+}
+
+func TestDNSLegacyAddressLimitPreLookupDefersDirectRules(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ build func(*testing.T, *abstractDefaultRule)
+ matchedResponse *mDNS.Msg
+ unmatchedResponse *mDNS.Msg
+ }{
+ {
+ name: "ip_cidr",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("203.0.113.1")),
+ unmatchedResponse: dnsResponseForTest(netip.MustParseAddr("8.8.8.8")),
+ },
+ {
+ name: "ip_is_private",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPIsPrivateItem(rule)
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("10.0.0.1")),
+ unmatchedResponse: dnsResponseForTest(netip.MustParseAddr("8.8.8.8")),
+ },
+ {
+ name: "ip_accept_any",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPAcceptAnyItem(rule)
+ },
+ matchedResponse: dnsResponseForTest(netip.MustParseAddr("203.0.113.1")),
+ unmatchedResponse: dnsResponseForTest(),
+ },
+ }
+ for _, testCase := range testCases {
+ testCase := testCase
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ testCase.build(t, rule)
+ })
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, rule.LegacyPreMatch(&preLookupMetadata))
+
+ matchedMetadata := testMetadata("lookup.example")
+ require.True(t, rule.MatchAddressLimit(&matchedMetadata, testCase.matchedResponse))
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ require.False(t, rule.MatchAddressLimit(&unmatchedMetadata, testCase.unmatchedResponse))
+ })
+ }
+}
+
+func TestDNSLegacyAddressLimitPreLookupDefersRuleSetDestinationCIDR(t *testing.T) {
+ t.Parallel()
+
+ ruleSet := newLocalRuleSetForTest("dns-legacy-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }))
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, rule.LegacyPreMatch(&preLookupMetadata))
+
+ matchedMetadata := testMetadata("lookup.example")
+ require.True(t, rule.MatchAddressLimit(&matchedMetadata, dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))))
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ require.False(t, rule.MatchAddressLimit(&unmatchedMetadata, dnsResponseForTest(netip.MustParseAddr("8.8.8.8"))))
+}
+
+func TestDNSLegacyLogicalAddressLimitPreLookupDefersNestedRules(t *testing.T) {
+ t.Parallel()
+
+ nestedRule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addDestinationIPIsPrivateItem(rule)
+ })
+ logicalRule := &LogicalDNSRule{
+ abstractLogicalRule: abstractLogicalRule{
+ rules: []adapter.HeadlessRule{nestedRule},
+ mode: C.LogicalTypeAnd,
+ },
+ }
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, logicalRule.LegacyPreMatch(&preLookupMetadata))
+
+ matchedMetadata := testMetadata("lookup.example")
+ require.True(t, logicalRule.MatchAddressLimit(&matchedMetadata, dnsResponseForTest(netip.MustParseAddr("10.0.0.1"))))
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ require.False(t, logicalRule.MatchAddressLimit(&unmatchedMetadata, dnsResponseForTest(netip.MustParseAddr("8.8.8.8"))))
+}
+
+func TestDNSLegacyInvertAddressLimitPreLookupRegression(t *testing.T) {
+ t.Parallel()
+
+ testCases := []struct {
+ name string
+ build func(*testing.T, *abstractDefaultRule)
+ matchedAddrs []netip.Addr
+ unmatchedAddrs []netip.Addr
+ }{
+ {
+ name: "ip_cidr",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ },
+ matchedAddrs: []netip.Addr{netip.MustParseAddr("203.0.113.1")},
+ unmatchedAddrs: []netip.Addr{netip.MustParseAddr("8.8.8.8")},
+ },
+ {
+ name: "ip_is_private",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPIsPrivateItem(rule)
+ },
+ matchedAddrs: []netip.Addr{netip.MustParseAddr("10.0.0.1")},
+ unmatchedAddrs: []netip.Addr{netip.MustParseAddr("8.8.8.8")},
+ },
+ {
+ name: "ip_accept_any",
+ build: func(t *testing.T, rule *abstractDefaultRule) {
+ t.Helper()
+ addDestinationIPAcceptAnyItem(rule)
+ },
+ matchedAddrs: []netip.Addr{netip.MustParseAddr("203.0.113.1")},
+ },
+ }
+ for _, testCase := range testCases {
+ testCase := testCase
+ t.Run(testCase.name, func(t *testing.T) {
+ t.Parallel()
+
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ rule.invert = true
+ testCase.build(t, rule)
+ })
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, rule.LegacyPreMatch(&preLookupMetadata))
+
+ matchedMetadata := testMetadata("lookup.example")
+ require.False(t, rule.MatchAddressLimit(&matchedMetadata, dnsResponseForTest(testCase.matchedAddrs...)))
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ require.True(t, rule.MatchAddressLimit(&unmatchedMetadata, dnsResponseForTest(testCase.unmatchedAddrs...)))
+ })
+ }
+}
+
+func TestDNSLegacyInvertLogicalAddressLimitPreLookupRegression(t *testing.T) {
+ t.Parallel()
+
+ t.Run("inverted deferred child does not suppress branch", func(t *testing.T) {
+ t.Parallel()
+
+ logicalRule := &LogicalDNSRule{
+ abstractLogicalRule: abstractLogicalRule{
+ rules: []adapter.HeadlessRule{
+ dnsRuleForTest(func(rule *abstractDefaultRule) {
+ rule.invert = true
+ addDestinationIPIsPrivateItem(rule)
+ }),
+ },
+ mode: C.LogicalTypeAnd,
+ },
+ }
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, logicalRule.LegacyPreMatch(&preLookupMetadata))
+ })
+}
+
+func TestDNSLegacyInvertRuleSetAddressLimitPreLookupRegression(t *testing.T) {
+ t.Parallel()
+
+ ruleSet := newLocalRuleSetForTest("dns-legacy-invert-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
+ rule.invert = true
+ addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
+ }))
+ rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
+ addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
+ })
+
+ preLookupMetadata := testMetadata("lookup.example")
+ require.True(t, rule.LegacyPreMatch(&preLookupMetadata))
+
+ matchedMetadata := testMetadata("lookup.example")
+ require.False(t, rule.MatchAddressLimit(&matchedMetadata, dnsResponseForTest(netip.MustParseAddr("203.0.113.1"))))
+
+ unmatchedMetadata := testMetadata("lookup.example")
+ require.True(t, rule.MatchAddressLimit(&unmatchedMetadata, dnsResponseForTest(netip.MustParseAddr("8.8.8.8"))))
}
func TestDNSInvertAddressLimitPreLookupRegression(t *testing.T) {
@@ -650,6 +1028,7 @@ func TestDNSInvertAddressLimitPreLookupRegression(t *testing.T) {
},
}
for _, testCase := range testCases {
+ testCase := testCase
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()
rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
@@ -662,14 +1041,14 @@ func TestDNSInvertAddressLimitPreLookupRegression(t *testing.T) {
matchedMetadata := testMetadata("lookup.example")
matchedMetadata.DestinationAddresses = testCase.matchedAddrs
- require.False(t, rule.MatchAddressLimit(&matchedMetadata))
+ require.False(t, rule.MatchAddressLimit(&matchedMetadata, dnsResponseForTest(testCase.matchedAddrs...)))
unmatchedMetadata := testMetadata("lookup.example")
unmatchedMetadata.DestinationAddresses = testCase.unmatchedAddrs
- require.True(t, rule.MatchAddressLimit(&unmatchedMetadata))
+ require.True(t, rule.MatchAddressLimit(&unmatchedMetadata, dnsResponseForTest(testCase.unmatchedAddrs...)))
})
}
- t.Run("mixed resolved and deferred fields keep old pre lookup false", func(t *testing.T) {
+ t.Run("mixed resolved and deferred fields invert matches pre lookup", func(t *testing.T) {
t.Parallel()
metadata := testMetadata("lookup.example")
rule := dnsRuleForTest(func(rule *abstractDefaultRule) {
@@ -677,9 +1056,9 @@ func TestDNSInvertAddressLimitPreLookupRegression(t *testing.T) {
addOtherItem(rule, NewNetworkItem([]string{N.NetworkTCP}))
addDestinationIPCIDRItem(t, rule, []string{"203.0.113.0/24"})
})
- require.False(t, rule.Match(&metadata))
+ require.True(t, rule.Match(&metadata))
})
- t.Run("ruleset only deferred fields keep old pre lookup false", func(t *testing.T) {
+ t.Run("ruleset only deferred fields invert matches pre lookup", func(t *testing.T) {
t.Parallel()
metadata := testMetadata("lookup.example")
ruleSet := newLocalRuleSetForTest("dns-ruleset-ipcidr", headlessDefaultRule(t, func(rule *abstractDefaultRule) {
@@ -689,7 +1068,7 @@ func TestDNSInvertAddressLimitPreLookupRegression(t *testing.T) {
rule.invert = true
addRuleSetItem(rule, &RuleSetItem{setList: []adapter.RuleSet{ruleSet}})
})
- require.False(t, rule.Match(&metadata))
+ require.True(t, rule.Match(&metadata))
})
}
@@ -760,6 +1139,39 @@ func testMetadata(domain string) adapter.InboundContext {
}
}
+func dnsResponseForTest(addresses ...netip.Addr) *mDNS.Msg {
+ response := &mDNS.Msg{
+ MsgHdr: mDNS.MsgHdr{
+ Response: true,
+ Rcode: mDNS.RcodeSuccess,
+ },
+ }
+ for _, address := range addresses {
+ if address.Is4() {
+ response.Answer = append(response.Answer, &mDNS.A{
+ Hdr: mDNS.RR_Header{
+ Name: mDNS.Fqdn("lookup.example"),
+ Rrtype: mDNS.TypeA,
+ Class: mDNS.ClassINET,
+ Ttl: 60,
+ },
+ A: net.IP(append([]byte(nil), address.AsSlice()...)),
+ })
+ } else {
+ response.Answer = append(response.Answer, &mDNS.AAAA{
+ Hdr: mDNS.RR_Header{
+ Name: mDNS.Fqdn("lookup.example"),
+ Rrtype: mDNS.TypeAAAA,
+ Class: mDNS.ClassINET,
+ Ttl: 60,
+ },
+ AAAA: net.IP(append([]byte(nil), address.AsSlice()...)),
+ })
+ }
+ }
+ return response
+}
+
func addRuleSetItem(rule *abstractDefaultRule, item *RuleSetItem) {
rule.ruleSetItem = item
rule.allItems = append(rule.allItems, item)
diff --git a/route/rule/rule_set_update_validation_test.go b/route/rule/rule_set_update_validation_test.go
new file mode 100644
index 0000000000..0583d7bb62
--- /dev/null
+++ b/route/rule/rule_set_update_validation_test.go
@@ -0,0 +1,111 @@
+package rule
+
+import (
+ "context"
+ "sync/atomic"
+ "testing"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/json/badoption"
+ "github.com/sagernet/sing/common/x/list"
+ "github.com/sagernet/sing/service"
+
+ "github.com/stretchr/testify/require"
+)
+
+type fakeDNSRuleSetUpdateValidator struct {
+ validate func(tag string, metadata adapter.RuleSetMetadata) error
+}
+
+func (v *fakeDNSRuleSetUpdateValidator) ValidateRuleSetMetadataUpdate(tag string, metadata adapter.RuleSetMetadata) error {
+ if v.validate == nil {
+ return nil
+ }
+ return v.validate(tag, metadata)
+}
+
+func TestLocalRuleSetReloadRulesRejectsInvalidUpdateBeforeCommit(t *testing.T) {
+ t.Parallel()
+
+ var callbackCount atomic.Int32
+ ctx := service.ContextWith[adapter.DNSRuleSetUpdateValidator](context.Background(), &fakeDNSRuleSetUpdateValidator{
+ validate: func(tag string, metadata adapter.RuleSetMetadata) error {
+ require.Equal(t, "dynamic-set", tag)
+ if metadata.ContainsDNSQueryTypeRule {
+ return E.New("dns conflict")
+ }
+ return nil
+ },
+ })
+ ruleSet := &LocalRuleSet{
+ ctx: ctx,
+ tag: "dynamic-set",
+ fileFormat: C.RuleSetFormatSource,
+ }
+ _ = ruleSet.callbacks.PushBack(func(adapter.RuleSet) {
+ callbackCount.Add(1)
+ })
+
+ err := ruleSet.reloadRules([]option.HeadlessRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultHeadlessRule{
+ Domain: badoption.Listable[string]{"example.com"},
+ },
+ }})
+ require.NoError(t, err)
+ require.Equal(t, int32(1), callbackCount.Load())
+ require.False(t, ruleSet.metadata.ContainsDNSQueryTypeRule)
+ require.True(t, ruleSet.Match(&adapter.InboundContext{Domain: "example.com"}))
+
+ err = ruleSet.reloadRules([]option.HeadlessRule{{
+ Type: C.RuleTypeDefault,
+ DefaultOptions: option.DefaultHeadlessRule{
+ QueryType: badoption.Listable[option.DNSQueryType]{option.DNSQueryType(1)},
+ },
+ }})
+ require.ErrorContains(t, err, "dns conflict")
+ require.Equal(t, int32(1), callbackCount.Load())
+ require.False(t, ruleSet.metadata.ContainsDNSQueryTypeRule)
+ require.True(t, ruleSet.Match(&adapter.InboundContext{Domain: "example.com"}))
+}
+
+func TestRemoteRuleSetLoadBytesRejectsInvalidUpdateBeforeCommit(t *testing.T) {
+ t.Parallel()
+
+ var callbackCount atomic.Int32
+ ctx := service.ContextWith[adapter.DNSRuleSetUpdateValidator](context.Background(), &fakeDNSRuleSetUpdateValidator{
+ validate: func(tag string, metadata adapter.RuleSetMetadata) error {
+ require.Equal(t, "dynamic-set", tag)
+ if metadata.ContainsDNSQueryTypeRule {
+ return E.New("dns conflict")
+ }
+ return nil
+ },
+ })
+ ruleSet := &RemoteRuleSet{
+ ctx: ctx,
+ options: option.RuleSet{
+ Tag: "dynamic-set",
+ Format: C.RuleSetFormatSource,
+ },
+ callbacks: list.List[adapter.RuleSetUpdateCallback]{},
+ }
+ _ = ruleSet.callbacks.PushBack(func(adapter.RuleSet) {
+ callbackCount.Add(1)
+ })
+
+ err := ruleSet.loadBytes([]byte(`{"version":4,"rules":[{"domain":["example.com"]}]}`))
+ require.NoError(t, err)
+ require.Equal(t, int32(1), callbackCount.Load())
+ require.False(t, ruleSet.metadata.ContainsDNSQueryTypeRule)
+ require.True(t, ruleSet.Match(&adapter.InboundContext{Domain: "example.com"}))
+
+ err = ruleSet.loadBytes([]byte(`{"version":4,"rules":[{"query_type":["A"]}]}`))
+ require.ErrorContains(t, err, "dns conflict")
+ require.Equal(t, int32(1), callbackCount.Load())
+ require.False(t, ruleSet.metadata.ContainsDNSQueryTypeRule)
+ require.True(t, ruleSet.Match(&adapter.InboundContext{Domain: "example.com"}))
+}
diff --git a/route/rule_conds.go b/route/rule_conds.go
index 55c4a058e2..2c62902949 100644
--- a/route/rule_conds.go
+++ b/route/rule_conds.go
@@ -38,11 +38,19 @@ func hasDNSRule(rules []option.DNSRule, cond func(rule option.DefaultDNSRule) bo
}
func isProcessRule(rule option.DefaultRule) bool {
- return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
+ return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.PackageNameRegex) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
}
func isProcessDNSRule(rule option.DefaultDNSRule) bool {
- return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
+ return len(rule.ProcessName) > 0 || len(rule.ProcessPath) > 0 || len(rule.ProcessPathRegex) > 0 || len(rule.PackageName) > 0 || len(rule.PackageNameRegex) > 0 || len(rule.User) > 0 || len(rule.UserID) > 0
+}
+
+func isNeighborRule(rule option.DefaultRule) bool {
+ return len(rule.SourceMACAddress) > 0 || len(rule.SourceHostname) > 0
+}
+
+func isNeighborDNSRule(rule option.DefaultDNSRule) bool {
+ return len(rule.SourceMACAddress) > 0 || len(rule.SourceHostname) > 0
}
func isWIFIRule(rule option.DefaultRule) bool {
diff --git a/service/acme/service.go b/service/acme/service.go
new file mode 100644
index 0000000000..1b96770997
--- /dev/null
+++ b/service/acme/service.go
@@ -0,0 +1,399 @@
+//go:build with_acme
+
+package acme
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "net/http"
+ "net/url"
+ "reflect"
+ "slices"
+ "strings"
+ "time"
+ "unsafe"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
+ boxtls "github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/service"
+
+ "github.com/caddyserver/certmagic"
+ "github.com/caddyserver/zerossl"
+ "github.com/libdns/alidns"
+ "github.com/libdns/cloudflare"
+ "github.com/libdns/libdns"
+ "github.com/mholt/acmez/v3/acme"
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+func RegisterCertificateProvider(registry *certificate.Registry) {
+ certificate.Register[option.ACMECertificateProviderOptions](registry, C.TypeACME, NewCertificateProvider)
+}
+
+var (
+ _ adapter.CertificateProviderService = (*Service)(nil)
+ _ adapter.ACMECertificateProvider = (*Service)(nil)
+)
+
+type Service struct {
+ certificate.Adapter
+ ctx context.Context
+ config *certmagic.Config
+ cache *certmagic.Cache
+ domain []string
+ nextProtos []string
+}
+
+func NewCertificateProvider(ctx context.Context, logger log.ContextLogger, tag string, options option.ACMECertificateProviderOptions) (adapter.CertificateProviderService, error) {
+ if len(options.Domain) == 0 {
+ return nil, E.New("missing domain")
+ }
+ var acmeServer string
+ switch options.Provider {
+ case "", "letsencrypt":
+ acmeServer = certmagic.LetsEncryptProductionCA
+ case "zerossl":
+ acmeServer = certmagic.ZeroSSLProductionCA
+ default:
+ if !strings.HasPrefix(options.Provider, "https://") {
+ return nil, E.New("unsupported ACME provider: ", options.Provider)
+ }
+ acmeServer = options.Provider
+ }
+ if acmeServer == certmagic.ZeroSSLProductionCA &&
+ (options.ExternalAccount == nil || options.ExternalAccount.KeyID == "") &&
+ strings.TrimSpace(options.Email) == "" &&
+ strings.TrimSpace(options.AccountKey) == "" {
+ return nil, E.New("email is required to use the ZeroSSL ACME endpoint without external_account or account_key")
+ }
+
+ var storage certmagic.Storage
+ if options.DataDirectory != "" {
+ storage = &certmagic.FileStorage{Path: options.DataDirectory}
+ } else {
+ storage = certmagic.Default.Storage
+ }
+
+ zapLogger := zap.New(zapcore.NewCore(
+ zapcore.NewConsoleEncoder(boxtls.ACMEEncoderConfig()),
+ &boxtls.ACMELogWriter{Logger: logger},
+ zap.DebugLevel,
+ ))
+
+ config := &certmagic.Config{
+ DefaultServerName: options.DefaultServerName,
+ Storage: storage,
+ Logger: zapLogger,
+ }
+ if options.KeyType != "" {
+ var keyType certmagic.KeyType
+ switch options.KeyType {
+ case option.ACMEKeyTypeED25519:
+ keyType = certmagic.ED25519
+ case option.ACMEKeyTypeP256:
+ keyType = certmagic.P256
+ case option.ACMEKeyTypeP384:
+ keyType = certmagic.P384
+ case option.ACMEKeyTypeRSA2048:
+ keyType = certmagic.RSA2048
+ case option.ACMEKeyTypeRSA4096:
+ keyType = certmagic.RSA4096
+ default:
+ return nil, E.New("unsupported ACME key type: ", options.KeyType)
+ }
+ config.KeySource = certmagic.StandardKeyGenerator{KeyType: keyType}
+ }
+
+ profile := options.Profile
+ if profile == "" && acmeServer == certmagic.LetsEncryptProductionCA && slices.ContainsFunc(options.Domain, certmagic.SubjectIsIP) {
+ profile = "shortlived"
+ }
+
+ acmeIssuer := certmagic.ACMEIssuer{
+ CA: acmeServer,
+ Email: options.Email,
+ AccountKeyPEM: options.AccountKey,
+ Agreed: true,
+ Profile: profile,
+ DisableHTTPChallenge: options.DisableHTTPChallenge,
+ DisableTLSALPNChallenge: options.DisableTLSALPNChallenge,
+ AltHTTPPort: int(options.AlternativeHTTPPort),
+ AltTLSALPNPort: int(options.AlternativeTLSPort),
+ Logger: zapLogger,
+ }
+ acmeHTTPClient, err := newACMEHTTPClient(ctx, logger, options)
+ if err != nil {
+ return nil, err
+ }
+ dnsSolver, err := newDNSSolver(options.DNS01Challenge, zapLogger, acmeHTTPClient)
+ if err != nil {
+ return nil, err
+ }
+ if dnsSolver != nil {
+ acmeIssuer.DNS01Solver = dnsSolver
+ }
+ if options.ExternalAccount != nil && options.ExternalAccount.KeyID != "" {
+ acmeIssuer.ExternalAccount = (*acme.EAB)(options.ExternalAccount)
+ }
+ if acmeServer == certmagic.ZeroSSLProductionCA {
+ acmeIssuer.NewAccountFunc = func(ctx context.Context, acmeIssuer *certmagic.ACMEIssuer, account acme.Account) (acme.Account, error) {
+ if acmeIssuer.ExternalAccount != nil {
+ return account, nil
+ }
+ var err error
+ acmeIssuer.ExternalAccount, account, err = createZeroSSLExternalAccountBinding(ctx, acmeIssuer, account, acmeHTTPClient)
+ return account, err
+ }
+ }
+
+ certmagicIssuer := certmagic.NewACMEIssuer(config, acmeIssuer)
+ httpClientField := reflect.ValueOf(certmagicIssuer).Elem().FieldByName("httpClient")
+ if !httpClientField.IsValid() || !httpClientField.CanAddr() {
+ return nil, E.New("certmagic ACME issuer HTTP client field is unavailable")
+ }
+ reflect.NewAt(httpClientField.Type(), unsafe.Pointer(httpClientField.UnsafeAddr())).Elem().Set(reflect.ValueOf(acmeHTTPClient))
+ config.Issuers = []certmagic.Issuer{certmagicIssuer}
+ cache := certmagic.NewCache(certmagic.CacheOptions{
+ GetConfigForCert: func(certificate certmagic.Certificate) (*certmagic.Config, error) {
+ return config, nil
+ },
+ Logger: zapLogger,
+ })
+ config = certmagic.New(cache, *config)
+
+ var nextProtos []string
+ if !acmeIssuer.DisableTLSALPNChallenge && acmeIssuer.DNS01Solver == nil {
+ nextProtos = []string{C.ACMETLS1Protocol}
+ }
+ return &Service{
+ Adapter: certificate.NewAdapter(C.TypeACME, tag),
+ ctx: ctx,
+ config: config,
+ cache: cache,
+ domain: options.Domain,
+ nextProtos: nextProtos,
+ }, nil
+}
+
+func (s *Service) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ return s.config.ManageAsync(s.ctx, s.domain)
+}
+
+func (s *Service) Close() error {
+ if s.cache != nil {
+ s.cache.Stop()
+ }
+ return nil
+}
+
+func (s *Service) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ return s.config.GetCertificate(hello)
+}
+
+func (s *Service) GetACMENextProtos() []string {
+ return s.nextProtos
+}
+
+func newDNSSolver(dnsOptions *option.ACMEProviderDNS01ChallengeOptions, logger *zap.Logger, httpClient *http.Client) (*certmagic.DNS01Solver, error) {
+ if dnsOptions == nil || dnsOptions.Provider == "" {
+ return nil, nil
+ }
+ if dnsOptions.TTL < 0 {
+ return nil, E.New("invalid ACME DNS01 ttl: ", dnsOptions.TTL)
+ }
+ if dnsOptions.PropagationDelay < 0 {
+ return nil, E.New("invalid ACME DNS01 propagation_delay: ", dnsOptions.PropagationDelay)
+ }
+ if dnsOptions.PropagationTimeout < -1 {
+ return nil, E.New("invalid ACME DNS01 propagation_timeout: ", dnsOptions.PropagationTimeout)
+ }
+ solver := &certmagic.DNS01Solver{
+ DNSManager: certmagic.DNSManager{
+ TTL: time.Duration(dnsOptions.TTL),
+ PropagationDelay: time.Duration(dnsOptions.PropagationDelay),
+ PropagationTimeout: time.Duration(dnsOptions.PropagationTimeout),
+ Resolvers: dnsOptions.Resolvers,
+ OverrideDomain: dnsOptions.OverrideDomain,
+ Logger: logger.Named("dns_manager"),
+ },
+ }
+ switch dnsOptions.Provider {
+ case C.DNSProviderAliDNS:
+ solver.DNSProvider = &alidns.Provider{
+ CredentialInfo: alidns.CredentialInfo{
+ AccessKeyID: dnsOptions.AliDNSOptions.AccessKeyID,
+ AccessKeySecret: dnsOptions.AliDNSOptions.AccessKeySecret,
+ RegionID: dnsOptions.AliDNSOptions.RegionID,
+ SecurityToken: dnsOptions.AliDNSOptions.SecurityToken,
+ },
+ }
+ case C.DNSProviderCloudflare:
+ solver.DNSProvider = &cloudflare.Provider{
+ APIToken: dnsOptions.CloudflareOptions.APIToken,
+ ZoneToken: dnsOptions.CloudflareOptions.ZoneToken,
+ HTTPClient: httpClient,
+ }
+ case C.DNSProviderACMEDNS:
+ solver.DNSProvider = &acmeDNSProvider{
+ username: dnsOptions.ACMEDNSOptions.Username,
+ password: dnsOptions.ACMEDNSOptions.Password,
+ subdomain: dnsOptions.ACMEDNSOptions.Subdomain,
+ serverURL: dnsOptions.ACMEDNSOptions.ServerURL,
+ httpClient: httpClient,
+ }
+ default:
+ return nil, E.New("unsupported ACME DNS01 provider type: ", dnsOptions.Provider)
+ }
+ return solver, nil
+}
+
+func createZeroSSLExternalAccountBinding(ctx context.Context, acmeIssuer *certmagic.ACMEIssuer, account acme.Account, httpClient *http.Client) (*acme.EAB, acme.Account, error) {
+ email := strings.TrimSpace(acmeIssuer.Email)
+ if email == "" {
+ return nil, acme.Account{}, E.New("email is required to use the ZeroSSL ACME endpoint without external_account")
+ }
+ if len(account.Contact) == 0 {
+ account.Contact = []string{"mailto:" + email}
+ }
+ if acmeIssuer.CertObtainTimeout > 0 {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, acmeIssuer.CertObtainTimeout)
+ defer cancel()
+ }
+
+ form := url.Values{"email": []string{email}}
+ request, err := http.NewRequestWithContext(ctx, http.MethodPost, zerossl.BaseURL+"/acme/eab-credentials-email", strings.NewReader(form.Encode()))
+ if err != nil {
+ return nil, account, E.Cause(err, "create ZeroSSL EAB request")
+ }
+ request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ request.Header.Set("User-Agent", certmagic.UserAgent)
+
+ response, err := httpClient.Do(request)
+ if err != nil {
+ return nil, account, E.Cause(err, "request ZeroSSL EAB")
+ }
+ defer response.Body.Close()
+
+ var result struct {
+ Success bool `json:"success"`
+ Error struct {
+ Code int `json:"code"`
+ Type string `json:"type"`
+ } `json:"error"`
+ EABKID string `json:"eab_kid"`
+ EABHMACKey string `json:"eab_hmac_key"`
+ }
+ err = json.NewDecoder(response.Body).Decode(&result)
+ if err != nil {
+ return nil, account, E.Cause(err, "decode ZeroSSL EAB response")
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, account, E.New("failed getting ZeroSSL EAB credentials: HTTP ", response.StatusCode)
+ }
+ if result.Error.Code != 0 {
+ return nil, account, E.New("failed getting ZeroSSL EAB credentials: ", result.Error.Type, " (code ", result.Error.Code, ")")
+ }
+
+ acmeIssuer.Logger.Info("generated ZeroSSL EAB credentials", zap.String("key_id", result.EABKID))
+
+ return &acme.EAB{
+ KeyID: result.EABKID,
+ MACKey: result.EABHMACKey,
+ }, account, nil
+}
+
+func newACMEHTTPClient(ctx context.Context, logger log.ContextLogger, options option.ACMECertificateProviderOptions) (*http.Client, error) {
+ httpClientOptions := common.PtrValueOrDefault(options.HTTPClient)
+ httpClientManager := service.FromContext[adapter.HTTPClientManager](ctx)
+ transport, err := httpClientManager.ResolveTransport(ctx, logger, httpClientOptions)
+ if err != nil {
+ return nil, E.Cause(err, "create ACME provider http client")
+ }
+ return &http.Client{
+ Transport: transport,
+ Timeout: certmagic.HTTPTimeout,
+ }, nil
+}
+
+type acmeDNSProvider struct {
+ username string
+ password string
+ subdomain string
+ serverURL string
+ httpClient *http.Client
+}
+
+type acmeDNSRecord struct {
+ resourceRecord libdns.RR
+}
+
+func (r acmeDNSRecord) RR() libdns.RR {
+ return r.resourceRecord
+}
+
+func (p *acmeDNSProvider) AppendRecords(ctx context.Context, _ string, records []libdns.Record) ([]libdns.Record, error) {
+ if p.username == "" {
+ return nil, E.New("ACME-DNS username cannot be empty")
+ }
+ if p.password == "" {
+ return nil, E.New("ACME-DNS password cannot be empty")
+ }
+ if p.subdomain == "" {
+ return nil, E.New("ACME-DNS subdomain cannot be empty")
+ }
+ if p.serverURL == "" {
+ return nil, E.New("ACME-DNS server_url cannot be empty")
+ }
+ appendedRecords := make([]libdns.Record, 0, len(records))
+ for _, record := range records {
+ resourceRecord := record.RR()
+ if resourceRecord.Type != "TXT" {
+ return appendedRecords, E.New("ACME-DNS only supports adding TXT records")
+ }
+ requestBody, err := json.Marshal(map[string]string{
+ "subdomain": p.subdomain,
+ "txt": resourceRecord.Data,
+ })
+ if err != nil {
+ return appendedRecords, E.Cause(err, "marshal ACME-DNS update request")
+ }
+ request, err := http.NewRequestWithContext(ctx, http.MethodPost, p.serverURL+"/update", bytes.NewReader(requestBody))
+ if err != nil {
+ return appendedRecords, E.Cause(err, "create ACME-DNS update request")
+ }
+ request.Header.Set("X-Api-User", p.username)
+ request.Header.Set("X-Api-Key", p.password)
+ request.Header.Set("Content-Type", "application/json")
+ response, err := p.httpClient.Do(request)
+ if err != nil {
+ return appendedRecords, E.Cause(err, "update ACME-DNS record")
+ }
+ _ = response.Body.Close()
+ if response.StatusCode != http.StatusOK {
+ return appendedRecords, E.New("update ACME-DNS record: HTTP ", response.StatusCode)
+ }
+ appendedRecords = append(appendedRecords, acmeDNSRecord{resourceRecord: libdns.RR{
+ Type: "TXT",
+ Name: resourceRecord.Name,
+ Data: resourceRecord.Data,
+ }})
+ }
+ return appendedRecords, nil
+}
+
+func (p *acmeDNSProvider) DeleteRecords(context.Context, string, []libdns.Record) ([]libdns.Record, error) {
+ return nil, nil
+}
diff --git a/service/acme/stub.go b/service/acme/stub.go
new file mode 100644
index 0000000000..43a58d6449
--- /dev/null
+++ b/service/acme/stub.go
@@ -0,0 +1,3 @@
+//go:build !with_acme
+
+package acme
diff --git a/service/derp/service.go b/service/derp/service.go
index 02dac60bfa..ee91e3a166 100644
--- a/service/derp/service.go
+++ b/service/derp/service.go
@@ -5,7 +5,6 @@ package derp
import (
"bufio"
"context"
- stdTLS "crypto/tls"
"encoding/json"
"fmt"
"io"
@@ -34,7 +33,6 @@ import (
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
- "github.com/sagernet/sing/common/ntp"
aTLS "github.com/sagernet/sing/common/tls"
"github.com/sagernet/sing/service"
"github.com/sagernet/sing/service/filemanager"
@@ -151,29 +149,14 @@ func (d *Service) Start(stage adapter.StartStage) error {
if len(d.verifyClientURL) > 0 {
var httpClients []*http.Client
var urls []string
- for index, options := range d.verifyClientURL {
- verifyDialer, createErr := dialer.NewWithOptions(dialer.Options{
- Context: d.ctx,
- Options: options.DialerOptions,
- RemoteIsDomain: options.ServerIsDomain(),
- NewDialer: true,
- })
+ httpClientManager := service.FromContext[adapter.HTTPClientManager](d.ctx)
+ for index, verifyOptions := range d.verifyClientURL {
+ transport, createErr := httpClientManager.ResolveTransport(d.ctx, d.logger, verifyOptions.HTTPClientOptions)
if createErr != nil {
return E.Cause(createErr, "verify_client_url[", index, "]")
}
- httpClients = append(httpClients, &http.Client{
- Transport: &http.Transport{
- ForceAttemptHTTP2: true,
- TLSClientConfig: &stdTLS.Config{
- RootCAs: adapter.RootPoolFromContext(d.ctx),
- Time: ntp.TimeFuncFromContext(d.ctx),
- },
- DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
- return verifyDialer.DialContext(ctx, network, M.ParseSocksaddr(addr))
- },
- },
- })
- urls = append(urls, options.URL)
+ httpClients = append(httpClients, &http.Client{Transport: transport})
+ urls = append(urls, verifyOptions.URL)
}
server.SetVerifyClientHTTPClient(httpClients)
server.SetVerifyClientURL(urls)
@@ -310,7 +293,7 @@ func (d *Service) startMeshWithHost(derpServer *derpserver.Server, server *optio
}
var stdConfig *tls.STDConfig
if server.TLS != nil && server.TLS.Enabled {
- tlsConfig, err := tls.NewClient(d.ctx, d.logger, hostname, common.PtrValueOrDefault(server.TLS))
+ tlsConfig, err := tls.NewClient(d.ctx, d.logger, hostname, *server.TLS)
if err != nil {
return err
}
@@ -352,10 +335,11 @@ func (d *Service) startMeshWithHost(derpServer *derpserver.Server, server *optio
}
func (d *Service) Close() error {
- return common.Close(
+ err := common.Close(
common.PtrOrNil(d.listener),
d.tlsConfig,
)
+ return err
}
var homePage = `
diff --git a/service/oomkiller/badcleanup.go b/service/oomkiller/badcleanup.go
new file mode 100644
index 0000000000..4ba4b0cef8
--- /dev/null
+++ b/service/oomkiller/badcleanup.go
@@ -0,0 +1,19 @@
+//go:build badlinkname
+
+package oomkiller
+
+import (
+ "sync"
+ _ "unsafe"
+)
+
+//go:linkname jsonFieldCache json.fieldCache
+var jsonFieldCache sync.Map
+
+//go:linkname contextJSONFieldCache github.com/sagernet/sing/common/json/internal/contextjson.fieldCache
+var contextJSONFieldCache sync.Map
+
+func badCleanup() {
+ jsonFieldCache.Clear()
+ contextJSONFieldCache.Clear()
+}
diff --git a/service/oomkiller/badcleanup_stub.go b/service/oomkiller/badcleanup_stub.go
new file mode 100644
index 0000000000..d734eb9f16
--- /dev/null
+++ b/service/oomkiller/badcleanup_stub.go
@@ -0,0 +1,6 @@
+//go:build !badlinkname
+
+package oomkiller
+
+func badCleanup() {
+}
diff --git a/service/oomkiller/config.go b/service/oomkiller/config.go
deleted file mode 100644
index 693ced995b..0000000000
--- a/service/oomkiller/config.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package oomkiller
-
-import (
- "time"
-
- "github.com/sagernet/sing-box/option"
- E "github.com/sagernet/sing/common/exceptions"
-)
-
-func buildTimerConfig(options option.OOMKillerServiceOptions, memoryLimit uint64, useAvailable bool) (timerConfig, error) {
- safetyMargin := uint64(defaultSafetyMargin)
- if options.SafetyMargin != nil && options.SafetyMargin.Value() > 0 {
- safetyMargin = options.SafetyMargin.Value()
- }
-
- minInterval := defaultMinInterval
- if options.MinInterval != 0 {
- minInterval = time.Duration(options.MinInterval.Build())
- if minInterval <= 0 {
- return timerConfig{}, E.New("min_interval must be greater than 0")
- }
- }
-
- maxInterval := defaultMaxInterval
- if options.MaxInterval != 0 {
- maxInterval = time.Duration(options.MaxInterval.Build())
- if maxInterval <= 0 {
- return timerConfig{}, E.New("max_interval must be greater than 0")
- }
- }
- if maxInterval < minInterval {
- return timerConfig{}, E.New("max_interval must be greater than or equal to min_interval")
- }
-
- checksBeforeLimit := defaultChecksBeforeLimit
- if options.ChecksBeforeLimit != 0 {
- checksBeforeLimit = options.ChecksBeforeLimit
- if checksBeforeLimit <= 0 {
- return timerConfig{}, E.New("checks_before_limit must be greater than 0")
- }
- }
-
- return timerConfig{
- memoryLimit: memoryLimit,
- safetyMargin: safetyMargin,
- minInterval: minInterval,
- maxInterval: maxInterval,
- checksBeforeLimit: checksBeforeLimit,
- useAvailable: useAvailable,
- }, nil
-}
diff --git a/service/oomkiller/policy.go b/service/oomkiller/policy.go
new file mode 100644
index 0000000000..aa74430157
--- /dev/null
+++ b/service/oomkiller/policy.go
@@ -0,0 +1,46 @@
+package oomkiller
+
+import (
+ "context"
+
+ "github.com/sagernet/sing-box/adapter"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/memory"
+ "github.com/sagernet/sing/service"
+)
+
+const DefaultAppleNetworkExtensionMemoryLimit = 50 * 1024 * 1024
+
+type policyMode uint8
+
+const (
+ policyModeNone policyMode = iota
+ policyModeMemoryLimit
+ policyModeAvailable
+ policyModeNetworkExtension
+)
+
+func (m policyMode) hasTimerMode() bool {
+ return m != policyModeNone
+}
+
+func resolvePolicyMode(ctx context.Context, options option.OOMKillerServiceOptions) (uint64, policyMode) {
+ platformInterface := service.FromContext[adapter.PlatformInterface](ctx)
+ if C.IsIos && platformInterface != nil && platformInterface.UnderNetworkExtension() {
+ return DefaultAppleNetworkExtensionMemoryLimit, policyModeNetworkExtension
+ }
+ if options.MemoryLimitOverride > 0 {
+ return options.MemoryLimitOverride, policyModeMemoryLimit
+ }
+ if options.MemoryLimit != nil {
+ memoryLimit := options.MemoryLimit.Value()
+ if memoryLimit > 0 {
+ return memoryLimit, policyModeMemoryLimit
+ }
+ }
+ if memory.AvailableAvailable() {
+ return 0, policyModeAvailable
+ }
+ return 0, policyModeNone
+}
diff --git a/service/oomkiller/service.go b/service/oomkiller/service.go
index ff90f6e435..bbf032d0fa 100644
--- a/service/oomkiller/service.go
+++ b/service/oomkiller/service.go
@@ -1,193 +1,87 @@
-//go:build darwin && cgo
-
package oomkiller
-/*
-#include
-
-static dispatch_source_t memoryPressureSource;
-
-extern void goMemoryPressureCallback(unsigned long status);
-
-static void startMemoryPressureMonitor() {
- memoryPressureSource = dispatch_source_create(
- DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
- 0,
- DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_CRITICAL,
- dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)
- );
- dispatch_source_set_event_handler(memoryPressureSource, ^{
- unsigned long status = dispatch_source_get_data(memoryPressureSource);
- goMemoryPressureCallback(status);
- });
- dispatch_activate(memoryPressureSource);
-}
-
-static void stopMemoryPressureMonitor() {
- if (memoryPressureSource) {
- dispatch_source_cancel(memoryPressureSource);
- memoryPressureSource = NULL;
- }
-}
-*/
-import "C"
-
import (
"context"
- runtimeDebug "runtime/debug"
- "sync"
+ "sync/atomic"
+ "time"
"github.com/sagernet/sing-box/adapter"
boxService "github.com/sagernet/sing-box/adapter/service"
boxConstant "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
- "github.com/sagernet/sing/common/memory"
"github.com/sagernet/sing/service"
)
+type OOMReporter interface {
+ WriteReport(memoryUsage uint64) error
+ WriteDraft(memoryUsage uint64) error
+ DiscardDraft() error
+}
+
func RegisterService(registry *boxService.Registry) {
boxService.Register[option.OOMKillerServiceOptions](registry, boxConstant.TypeOOMKiller, NewService)
}
-var (
- globalAccess sync.Mutex
- globalServices []*Service
-)
-
type Service struct {
boxService.Adapter
- logger log.ContextLogger
- router adapter.Router
- memoryLimit uint64
- hasTimerMode bool
- useAvailable bool
- timerConfig timerConfig
- adaptiveTimer *adaptiveTimer
+ ctx context.Context
+ logger log.ContextLogger
+ network adapter.NetworkManager
+ timerConfig timerConfig
+ adaptiveTimer *adaptiveTimer
+ lastReportTime atomic.Int64
+ //nolint:unused // touched only on darwin && cgo via writeOOMDraft/discardOOMDraft.
+ draftCancelled atomic.Bool
}
func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.OOMKillerServiceOptions) (adapter.Service, error) {
- s := &Service{
- Adapter: boxService.NewAdapter(boxConstant.TypeOOMKiller, tag),
- logger: logger,
- router: service.FromContext[adapter.Router](ctx),
- }
-
- if options.MemoryLimit != nil {
- s.memoryLimit = options.MemoryLimit.Value()
- if s.memoryLimit > 0 {
- s.hasTimerMode = true
- }
- }
-
- config, err := buildTimerConfig(options, s.memoryLimit, s.useAvailable)
+ memoryLimit, mode := resolvePolicyMode(ctx, options)
+ config, err := buildTimerConfig(options, memoryLimit, mode, options.KillerDisabled)
if err != nil {
return nil, err
}
- s.timerConfig = config
-
- return s, nil
+ return &Service{
+ Adapter: boxService.NewAdapter(boxConstant.TypeOOMKiller, tag),
+ ctx: ctx,
+ logger: logger,
+ network: service.FromContext[adapter.NetworkManager](ctx),
+ timerConfig: config,
+ }, nil
}
-func (s *Service) Start(stage adapter.StartStage) error {
- if stage != adapter.StartStateStart {
- return nil
- }
-
- if s.hasTimerMode {
- s.adaptiveTimer = newAdaptiveTimer(s.logger, s.router, s.timerConfig)
- s.adaptiveTimer.start(false)
- if s.memoryLimit > 0 {
- s.logger.Info("started memory monitor with limit: ", s.memoryLimit/(1024*1024), " MiB")
- } else {
- s.logger.Info("started memory monitor with available memory detection")
- }
- } else {
- s.logger.Info("started memory pressure monitor")
- }
-
- globalAccess.Lock()
- isFirst := len(globalServices) == 0
- globalServices = append(globalServices, s)
- globalAccess.Unlock()
+func (s *Service) createTimer() {
+ s.adaptiveTimer = newAdaptiveTimer(s.logger, s.network, s.timerConfig, s.writeOOMReport)
+}
- if isFirst {
- C.startMemoryPressureMonitor()
- }
- return nil
+func (s *Service) startTimer() {
+ s.createTimer()
+ s.adaptiveTimer.start()
}
-func (s *Service) Close() error {
+func (s *Service) stopTimer() {
if s.adaptiveTimer != nil {
s.adaptiveTimer.stop()
}
- globalAccess.Lock()
- for i, svc := range globalServices {
- if svc == s {
- globalServices = append(globalServices[:i], globalServices[i+1:]...)
- break
- }
- }
- isLast := len(globalServices) == 0
- globalAccess.Unlock()
- if isLast {
- C.stopMemoryPressureMonitor()
- }
- return nil
}
-//export goMemoryPressureCallback
-func goMemoryPressureCallback(status C.ulong) {
- globalAccess.Lock()
- services := make([]*Service, len(globalServices))
- copy(services, globalServices)
- globalAccess.Unlock()
- if len(services) == 0 {
+func (s *Service) writeOOMReport(memoryUsage uint64) {
+ now := time.Now().Unix()
+ lastReport := s.lastReportTime.Load()
+ if now-lastReport < 3600 {
return
}
- criticalFlag := C.ulong(C.DISPATCH_MEMORYPRESSURE_CRITICAL)
- warnFlag := C.ulong(C.DISPATCH_MEMORYPRESSURE_WARN)
- isCritical := status&criticalFlag != 0
- isWarning := status&warnFlag != 0
- var level string
- switch {
- case isCritical:
- level = "critical"
- case isWarning:
- level = "warning"
- default:
- level = "normal"
+ if !s.lastReportTime.CompareAndSwap(lastReport, now) {
+ return
}
- var freeOSMemory bool
- for _, s := range services {
- usage := memory.Total()
- if s.hasTimerMode {
- if isCritical {
- s.logger.Warn("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB")
- if s.adaptiveTimer != nil {
- s.adaptiveTimer.start(true)
- }
- } else if isWarning {
- s.logger.Warn("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB")
- } else {
- s.logger.Debug("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB")
- if s.adaptiveTimer != nil {
- s.adaptiveTimer.stop()
- }
- }
- } else {
- if isCritical {
- s.logger.Error("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB, resetting network")
- s.router.ResetNetwork()
- freeOSMemory = true
- } else if isWarning {
- s.logger.Warn("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB")
- } else {
- s.logger.Debug("memory pressure: ", level, ", usage: ", usage/(1024*1024), " MiB")
- }
- }
+ reporter := service.FromContext[OOMReporter](s.ctx)
+ if reporter == nil {
+ return
}
- if freeOSMemory {
- runtimeDebug.FreeOSMemory()
+ err := reporter.WriteReport(memoryUsage)
+ if err != nil {
+ s.logger.Warn("failed to write OOM report: ", err)
+ } else {
+ s.logger.Info("OOM report saved")
}
}
diff --git a/service/oomkiller/service_darwin.go b/service/oomkiller/service_darwin.go
new file mode 100644
index 0000000000..f1d228369a
--- /dev/null
+++ b/service/oomkiller/service_darwin.go
@@ -0,0 +1,138 @@
+//go:build darwin && cgo
+
+package oomkiller
+
+/*
+#include
+
+static dispatch_source_t memoryPressureSource;
+
+extern void goMemoryPressureCallback(unsigned long status);
+
+static void startMemoryPressureMonitor() {
+ memoryPressureSource = dispatch_source_create(
+ DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
+ 0,
+ DISPATCH_MEMORYPRESSURE_CRITICAL,
+ dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)
+ );
+ dispatch_source_set_event_handler(memoryPressureSource, ^{
+ unsigned long status = dispatch_source_get_data(memoryPressureSource);
+ goMemoryPressureCallback(status);
+ });
+ dispatch_activate(memoryPressureSource);
+}
+
+static void stopMemoryPressureMonitor() {
+ if (memoryPressureSource) {
+ dispatch_source_cancel(memoryPressureSource);
+ memoryPressureSource = NULL;
+ }
+}
+*/
+import "C"
+
+import (
+ "sync"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/byteformats"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/service"
+)
+
+var (
+ globalAccess sync.Mutex
+ globalServices []*Service
+)
+
+func (s *Service) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ if s.timerConfig.policyMode == policyModeNetworkExtension {
+ s.createTimer()
+ globalAccess.Lock()
+ isFirst := len(globalServices) == 0
+ globalServices = append(globalServices, s)
+ globalAccess.Unlock()
+ if isFirst {
+ C.startMemoryPressureMonitor()
+ }
+ return nil
+ }
+ if !s.timerConfig.policyMode.hasTimerMode() {
+ return E.New("memory pressure monitoring is not available on this platform without memory_limit")
+ }
+ s.startTimer()
+ return nil
+}
+
+func (s *Service) Close() error {
+ s.stopTimer()
+ if s.timerConfig.policyMode == policyModeNetworkExtension {
+ globalAccess.Lock()
+ for i, svc := range globalServices {
+ if svc == s {
+ globalServices = append(globalServices[:i], globalServices[i+1:]...)
+ break
+ }
+ }
+ isLast := len(globalServices) == 0
+ globalAccess.Unlock()
+ if isLast {
+ C.stopMemoryPressureMonitor()
+ }
+ s.discardOOMDraft()
+ }
+ return nil
+}
+
+//export goMemoryPressureCallback
+func goMemoryPressureCallback(status C.ulong) {
+ globalAccess.Lock()
+ services := make([]*Service, len(globalServices))
+ copy(services, globalServices)
+ globalAccess.Unlock()
+ if len(services) == 0 {
+ return
+ }
+ sample := readMemorySample(policyModeNetworkExtension)
+ for _, s := range services {
+ s.logger.Warn("memory pressure: critical, usage: ", byteformats.FormatMemoryBytes(sample.usage))
+ s.writeOOMDraft(sample.usage)
+ s.adaptiveTimer.notifyPressure()
+ }
+}
+
+func (s *Service) writeOOMDraft(memoryUsage uint64) {
+ if s.draftCancelled.Load() {
+ return
+ }
+ reporter := service.FromContext[OOMReporter](s.ctx)
+ if reporter == nil {
+ return
+ }
+ err := reporter.WriteDraft(memoryUsage)
+ if s.draftCancelled.Load() {
+ reporter.DiscardDraft()
+ return
+ }
+ if err != nil {
+ s.logger.Error("failed to write OOM draft: ", err)
+ } else {
+ s.logger.Warn("OOM draft saved")
+ }
+}
+
+func (s *Service) discardOOMDraft() {
+ s.draftCancelled.Store(true)
+ reporter := service.FromContext[OOMReporter](s.ctx)
+ if reporter == nil {
+ return
+ }
+ err := reporter.DiscardDraft()
+ if err != nil {
+ s.logger.Error("failed to discard OOM draft: ", err)
+ }
+}
diff --git a/service/oomkiller/service_stub.go b/service/oomkiller/service_stub.go
index 7c1b84e895..5eaf82046a 100644
--- a/service/oomkiller/service_stub.go
+++ b/service/oomkiller/service_stub.go
@@ -3,79 +3,22 @@
package oomkiller
import (
- "context"
-
"github.com/sagernet/sing-box/adapter"
- boxService "github.com/sagernet/sing-box/adapter/service"
- boxConstant "github.com/sagernet/sing-box/constant"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/memory"
- "github.com/sagernet/sing/service"
)
-func RegisterService(registry *boxService.Registry) {
- boxService.Register[option.OOMKillerServiceOptions](registry, boxConstant.TypeOOMKiller, NewService)
-}
-
-type Service struct {
- boxService.Adapter
- logger log.ContextLogger
- router adapter.Router
- adaptiveTimer *adaptiveTimer
- timerConfig timerConfig
- hasTimerMode bool
- useAvailable bool
- memoryLimit uint64
-}
-
-func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.OOMKillerServiceOptions) (adapter.Service, error) {
- s := &Service{
- Adapter: boxService.NewAdapter(boxConstant.TypeOOMKiller, tag),
- logger: logger,
- router: service.FromContext[adapter.Router](ctx),
- }
-
- if options.MemoryLimit != nil {
- s.memoryLimit = options.MemoryLimit.Value()
- }
- if s.memoryLimit > 0 {
- s.hasTimerMode = true
- } else if memory.AvailableSupported() {
- s.useAvailable = true
- s.hasTimerMode = true
- }
-
- config, err := buildTimerConfig(options, s.memoryLimit, s.useAvailable)
- if err != nil {
- return nil, err
- }
- s.timerConfig = config
-
- return s, nil
-}
-
func (s *Service) Start(stage adapter.StartStage) error {
if stage != adapter.StartStateStart {
return nil
}
- if !s.hasTimerMode {
+ if !s.timerConfig.policyMode.hasTimerMode() {
return E.New("memory pressure monitoring is not available on this platform without memory_limit")
}
- s.adaptiveTimer = newAdaptiveTimer(s.logger, s.router, s.timerConfig)
- s.adaptiveTimer.start(false)
- if s.useAvailable {
- s.logger.Info("started memory monitor with available memory detection")
- } else {
- s.logger.Info("started memory monitor with limit: ", s.memoryLimit/(1024*1024), " MiB")
- }
+ s.startTimer()
return nil
}
func (s *Service) Close() error {
- if s.adaptiveTimer != nil {
- s.adaptiveTimer.stop()
- }
+ s.stopTimer()
return nil
}
diff --git a/service/oomkiller/service_timer.go b/service/oomkiller/service_timer.go
deleted file mode 100644
index 9f6a06c7d9..0000000000
--- a/service/oomkiller/service_timer.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package oomkiller
-
-import (
- runtimeDebug "runtime/debug"
- "sync"
- "time"
-
- "github.com/sagernet/sing-box/adapter"
- "github.com/sagernet/sing-box/log"
- "github.com/sagernet/sing/common/memory"
-)
-
-const (
- defaultChecksBeforeLimit = 4
- defaultMinInterval = 500 * time.Millisecond
- defaultMaxInterval = 10 * time.Second
- defaultSafetyMargin = 5 * 1024 * 1024
-)
-
-type adaptiveTimer struct {
- logger log.ContextLogger
- router adapter.Router
- memoryLimit uint64
- safetyMargin uint64
- minInterval time.Duration
- maxInterval time.Duration
- checksBeforeLimit int
- useAvailable bool
-
- access sync.Mutex
- timer *time.Timer
- previousUsage uint64
- lastInterval time.Duration
-}
-
-type timerConfig struct {
- memoryLimit uint64
- safetyMargin uint64
- minInterval time.Duration
- maxInterval time.Duration
- checksBeforeLimit int
- useAvailable bool
-}
-
-func newAdaptiveTimer(logger log.ContextLogger, router adapter.Router, config timerConfig) *adaptiveTimer {
- return &adaptiveTimer{
- logger: logger,
- router: router,
- memoryLimit: config.memoryLimit,
- safetyMargin: config.safetyMargin,
- minInterval: config.minInterval,
- maxInterval: config.maxInterval,
- checksBeforeLimit: config.checksBeforeLimit,
- useAvailable: config.useAvailable,
- }
-}
-
-func (t *adaptiveTimer) start(immediate bool) {
- t.access.Lock()
- t.startLocked()
- t.access.Unlock()
- if immediate {
- t.poll()
- }
-}
-
-func (t *adaptiveTimer) startLocked() {
- if t.timer != nil {
- return
- }
- t.previousUsage = memory.Total()
- t.lastInterval = t.minInterval
- t.timer = time.AfterFunc(t.minInterval, t.poll)
-}
-
-func (t *adaptiveTimer) stop() {
- t.access.Lock()
- defer t.access.Unlock()
- t.stopLocked()
-}
-
-func (t *adaptiveTimer) stopLocked() {
- if t.timer != nil {
- t.timer.Stop()
- t.timer = nil
- }
-}
-
-func (t *adaptiveTimer) poll() {
- t.access.Lock()
- defer t.access.Unlock()
- if t.timer == nil {
- return
- }
-
- usage := memory.Total()
- delta := int64(usage) - int64(t.previousUsage)
- t.previousUsage = usage
-
- var remaining uint64
- var triggered bool
-
- if t.memoryLimit > 0 {
- if usage >= t.memoryLimit {
- remaining = 0
- triggered = true
- } else {
- remaining = t.memoryLimit - usage
- }
- } else if t.useAvailable {
- available := memory.Available()
- if available <= t.safetyMargin {
- remaining = 0
- triggered = true
- } else {
- remaining = available - t.safetyMargin
- }
- } else {
- remaining = 0
- }
-
- if triggered {
- t.logger.Error("memory threshold reached, usage: ", usage/(1024*1024), " MiB, resetting network")
- t.router.ResetNetwork()
- runtimeDebug.FreeOSMemory()
- }
-
- var interval time.Duration
- if triggered {
- interval = t.maxInterval
- } else if delta <= 0 {
- interval = t.maxInterval
- } else if t.checksBeforeLimit <= 0 {
- interval = t.maxInterval
- } else {
- timeToLimit := time.Duration(float64(remaining) / float64(delta) * float64(t.lastInterval))
- interval = max(timeToLimit/time.Duration(t.checksBeforeLimit), t.minInterval)
- interval = min(interval, t.maxInterval)
- }
-
- t.lastInterval = interval
- t.timer.Reset(interval)
-}
diff --git a/service/oomkiller/timer.go b/service/oomkiller/timer.go
new file mode 100644
index 0000000000..6e9db4c1d8
--- /dev/null
+++ b/service/oomkiller/timer.go
@@ -0,0 +1,333 @@
+package oomkiller
+
+import (
+ runtimeDebug "runtime/debug"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/byteformats"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/memory"
+)
+
+const (
+ defaultMinInterval = 100 * time.Millisecond
+ defaultArmedInterval = time.Second
+ defaultMaxInterval = 10 * time.Second
+ defaultSafetyMargin = 5 * 1024 * 1024
+ defaultAvailableTriggerMarginMin = 32 * 1024 * 1024
+ defaultAvailableTriggerMarginMax = 128 * 1024 * 1024
+)
+
+type pressureState uint8
+
+const (
+ pressureStateNormal pressureState = iota
+ pressureStateArmed
+ pressureStateTriggered
+)
+
+type memorySample struct {
+ usage uint64
+ available uint64
+ availableKnown bool
+}
+
+type pressureThresholds struct {
+ trigger uint64
+ armed uint64
+ resume uint64
+}
+
+type timerConfig struct {
+ memoryLimit uint64
+ safetyMargin uint64
+ hasSafetyMargin bool
+ minInterval time.Duration
+ armedInterval time.Duration
+ maxInterval time.Duration
+ policyMode policyMode
+ killerDisabled bool
+}
+
+func buildTimerConfig(options option.OOMKillerServiceOptions, memoryLimit uint64, policyMode policyMode, killerDisabled bool) (timerConfig, error) {
+ minInterval := defaultMinInterval
+ if options.MinInterval != 0 {
+ minInterval = time.Duration(options.MinInterval.Build())
+ if minInterval <= 0 {
+ return timerConfig{}, E.New("min_interval must be greater than 0")
+ }
+ }
+
+ maxInterval := defaultMaxInterval
+ if options.MaxInterval != 0 {
+ maxInterval = time.Duration(options.MaxInterval.Build())
+ if maxInterval <= 0 {
+ return timerConfig{}, E.New("max_interval must be greater than 0")
+ }
+ }
+ if maxInterval < minInterval {
+ return timerConfig{}, E.New("max_interval must be greater than or equal to min_interval")
+ }
+
+ var (
+ safetyMargin uint64
+ hasSafetyMargin bool
+ )
+ if options.SafetyMargin != nil && options.SafetyMargin.Value() > 0 {
+ safetyMargin = options.SafetyMargin.Value()
+ hasSafetyMargin = true
+ } else if memoryLimit > 0 {
+ safetyMargin = defaultSafetyMargin
+ hasSafetyMargin = true
+ }
+
+ return timerConfig{
+ memoryLimit: memoryLimit,
+ safetyMargin: safetyMargin,
+ hasSafetyMargin: hasSafetyMargin,
+ minInterval: minInterval,
+ armedInterval: max(min(defaultArmedInterval, maxInterval), minInterval),
+ maxInterval: maxInterval,
+ policyMode: policyMode,
+ killerDisabled: killerDisabled,
+ }, nil
+}
+
+type adaptiveTimer struct {
+ timerConfig
+ logger log.ContextLogger
+ network adapter.NetworkManager
+ onTriggered func(uint64)
+ limitThresholds pressureThresholds
+
+ access sync.Mutex
+ cleanupTriggered bool
+ timer *time.Timer
+ state pressureState
+ currentInterval time.Duration
+ forceMinInterval bool
+ pendingPressureBaseline bool
+ pressureBaseline memorySample
+ pressureBaselineTime time.Time
+}
+
+func newAdaptiveTimer(logger log.ContextLogger, network adapter.NetworkManager, config timerConfig, onTriggered func(uint64)) *adaptiveTimer {
+ t := &adaptiveTimer{
+ timerConfig: config,
+ logger: logger,
+ network: network,
+ onTriggered: onTriggered,
+ }
+ if config.policyMode == policyModeMemoryLimit || config.policyMode == policyModeNetworkExtension {
+ t.limitThresholds = computeLimitThresholds(config.memoryLimit, config.safetyMargin)
+ }
+ return t
+}
+
+func (t *adaptiveTimer) start() {
+ t.access.Lock()
+ defer t.access.Unlock()
+ t.startLocked()
+}
+
+func (t *adaptiveTimer) startLocked() {
+ if t.timer != nil {
+ return
+ }
+ t.state = pressureStateNormal
+ t.forceMinInterval = false
+ t.timer = time.AfterFunc(t.minInterval, t.poll)
+}
+
+func (t *adaptiveTimer) stop() {
+ t.access.Lock()
+ defer t.access.Unlock()
+ if t.timer != nil {
+ t.timer.Stop()
+ t.timer = nil
+ }
+}
+
+func (t *adaptiveTimer) poll() {
+ var triggered bool
+ var rateTriggered bool
+ sample := readMemorySample(t.policyMode)
+
+ t.access.Lock()
+ if t.timer == nil {
+ t.access.Unlock()
+ return
+ }
+ if t.timerConfig.policyMode == policyModeNetworkExtension {
+ if t.cleanupTriggered {
+ runtimeDebug.FreeOSMemory()
+ t.cleanupTriggered = true
+ }
+ }
+ if t.pendingPressureBaseline {
+ t.pressureBaseline = sample
+ t.pressureBaselineTime = time.Now()
+ t.pendingPressureBaseline = false
+ }
+ previousState := t.state
+ t.state = t.nextState(sample)
+ if t.state == pressureStateNormal {
+ t.forceMinInterval = false
+ if !t.pressureBaselineTime.IsZero() && time.Since(t.pressureBaselineTime) > t.maxInterval {
+ t.pressureBaselineTime = time.Time{}
+ }
+ }
+ t.timer.Reset(t.intervalForState())
+ triggered = previousState != pressureStateTriggered && t.state == pressureStateTriggered
+ if !triggered && !t.pressureBaselineTime.IsZero() && t.memoryLimit > 0 &&
+ sample.usage > t.pressureBaseline.usage && sample.usage < t.memoryLimit {
+ elapsed := time.Since(t.pressureBaselineTime)
+ if elapsed >= t.minInterval/2 {
+ growth := sample.usage - t.pressureBaseline.usage
+ ratePerSecond := float64(growth) / elapsed.Seconds()
+ headroom := t.memoryLimit - sample.usage
+ timeToLimit := time.Duration(float64(headroom)/ratePerSecond) * time.Second
+ if timeToLimit < t.minInterval {
+ triggered = true
+ rateTriggered = true
+ t.state = pressureStateTriggered
+ }
+ }
+ }
+ t.access.Unlock()
+ if !triggered {
+ return
+ }
+ t.cleanupTriggered = false
+ t.onTriggered(sample.usage)
+ if rateTriggered {
+ if t.killerDisabled {
+ t.logger.Warn("memory growth rate critical (report only), usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample))
+ } else {
+ t.logger.Error("memory growth rate critical, usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample), ", resetting network")
+ t.network.ResetNetwork()
+ }
+ } else {
+ if t.killerDisabled {
+ t.logger.Warn("memory threshold reached (report only), usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample))
+ } else {
+ t.logger.Error("memory threshold reached, usage: ", byteformats.FormatMemoryBytes(sample.usage), t.logDetails(sample), ", resetting network")
+ t.network.ResetNetwork()
+ }
+ }
+ badCleanup()
+ runtimeDebug.FreeOSMemory()
+}
+
+func (t *adaptiveTimer) nextState(sample memorySample) pressureState {
+ switch t.policyMode {
+ case policyModeMemoryLimit, policyModeNetworkExtension:
+ return nextPressureState(t.state,
+ sample.usage >= t.limitThresholds.trigger,
+ sample.usage >= t.limitThresholds.armed,
+ sample.usage >= t.limitThresholds.resume,
+ )
+ case policyModeAvailable:
+ if !sample.availableKnown {
+ return pressureStateNormal
+ }
+ thresholds := t.availableThresholds(sample)
+ return nextPressureState(t.state,
+ sample.available <= thresholds.trigger,
+ sample.available <= thresholds.armed,
+ sample.available <= thresholds.resume,
+ )
+ default:
+ return pressureStateNormal
+ }
+}
+
+func computeLimitThresholds(memoryLimit uint64, safetyMargin uint64) pressureThresholds {
+ triggerMargin := min(safetyMargin, memoryLimit)
+ armedMargin := min(triggerMargin*2, memoryLimit)
+ resumeMargin := min(triggerMargin*4, memoryLimit)
+ return pressureThresholds{
+ trigger: memoryLimit - triggerMargin,
+ armed: memoryLimit - armedMargin,
+ resume: memoryLimit - resumeMargin,
+ }
+}
+
+func (t *adaptiveTimer) availableThresholds(sample memorySample) pressureThresholds {
+ var triggerMargin uint64
+ if t.hasSafetyMargin {
+ triggerMargin = t.safetyMargin
+ } else if sample.usage == 0 {
+ triggerMargin = defaultAvailableTriggerMarginMin
+ } else {
+ triggerMargin = max(defaultAvailableTriggerMarginMin, min(sample.usage/4, defaultAvailableTriggerMarginMax))
+ }
+ return pressureThresholds{
+ trigger: triggerMargin,
+ armed: triggerMargin * 2,
+ resume: triggerMargin * 4,
+ }
+}
+
+func (t *adaptiveTimer) intervalForState() time.Duration {
+ switch {
+ case t.forceMinInterval || t.state == pressureStateTriggered:
+ t.currentInterval = t.minInterval
+ case t.state == pressureStateArmed:
+ t.currentInterval = t.armedInterval
+ default:
+ if t.currentInterval == 0 {
+ t.currentInterval = t.maxInterval
+ } else {
+ t.currentInterval = min(t.currentInterval*2, t.maxInterval)
+ }
+ }
+ return t.currentInterval
+}
+
+func (t *adaptiveTimer) logDetails(sample memorySample) string {
+ switch t.policyMode {
+ case policyModeMemoryLimit, policyModeNetworkExtension:
+ headroom := uint64(0)
+ if sample.usage < t.memoryLimit {
+ headroom = t.memoryLimit - sample.usage
+ }
+ return ", limit: " + byteformats.FormatMemoryBytes(t.memoryLimit) + ", headroom: " + byteformats.FormatMemoryBytes(headroom)
+ case policyModeAvailable:
+ if sample.availableKnown {
+ return ", available: " + byteformats.FormatMemoryBytes(sample.available)
+ }
+ }
+ return ""
+}
+
+func nextPressureState(current pressureState, shouldTrigger, shouldArm, shouldStayTriggered bool) pressureState {
+ if current == pressureStateTriggered {
+ if shouldStayTriggered {
+ return pressureStateTriggered
+ }
+ return pressureStateNormal
+ }
+ if shouldTrigger {
+ return pressureStateTriggered
+ }
+ if shouldArm {
+ return pressureStateArmed
+ }
+ return pressureStateNormal
+}
+
+func readMemorySample(mode policyMode) memorySample {
+ sample := memorySample{
+ usage: memory.Total(),
+ }
+ if mode == policyModeAvailable {
+ sample.availableKnown = true
+ sample.available = memory.Available()
+ }
+ return sample
+}
diff --git a/service/oomkiller/timer_darwin.go b/service/oomkiller/timer_darwin.go
new file mode 100644
index 0000000000..6c4f7efab4
--- /dev/null
+++ b/service/oomkiller/timer_darwin.go
@@ -0,0 +1,12 @@
+//go:build darwin && cgo
+
+package oomkiller
+
+func (t *adaptiveTimer) notifyPressure() {
+ t.access.Lock()
+ t.startLocked()
+ t.forceMinInterval = true
+ t.pendingPressureBaseline = true
+ t.access.Unlock()
+ t.poll()
+}
diff --git a/service/origin_ca/service.go b/service/origin_ca/service.go
new file mode 100644
index 0000000000..e9fca42c60
--- /dev/null
+++ b/service/origin_ca/service.go
@@ -0,0 +1,608 @@
+package originca
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/tls"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/json"
+ "encoding/pem"
+ "errors"
+ "io"
+ "io/fs"
+ "net"
+ "net/http"
+ "slices"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/adapter/certificate"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/ntp"
+ "github.com/sagernet/sing/service"
+
+ "github.com/caddyserver/certmagic"
+)
+
+const (
+ cloudflareOriginCAEndpoint = "https://api.cloudflare.com/client/v4/certificates"
+ defaultRequestedValidity = option.CloudflareOriginCARequestValidity5475
+ // min of 30 days and certmagic's 1/3 lifetime ratio (maintain.go)
+ defaultRenewBefore = 30 * 24 * time.Hour
+ // from certmagic retry backoff range (async.go)
+ minimumRenewRetryDelay = time.Minute
+ maximumRenewRetryDelay = time.Hour
+ storageLockPrefix = "cloudflare-origin-ca"
+)
+
+func RegisterCertificateProvider(registry *certificate.Registry) {
+ certificate.Register[option.CloudflareOriginCACertificateProviderOptions](registry, C.TypeCloudflareOriginCA, NewCertificateProvider)
+}
+
+var _ adapter.CertificateProviderService = (*Service)(nil)
+
+type Service struct {
+ certificate.Adapter
+ logger log.ContextLogger
+ ctx context.Context
+ cancel context.CancelFunc
+ done chan struct{}
+ timeFunc func() time.Time
+ httpClient *http.Client
+ storage certmagic.Storage
+ storageIssuerKey string
+ storageNamesKey string
+ storageLockKey string
+ apiToken string
+ originCAKey string
+ domain []string
+ requestType option.CloudflareOriginCARequestType
+ requestedValidity option.CloudflareOriginCARequestValidity
+
+ access sync.RWMutex
+ currentCertificate *tls.Certificate
+ currentLeaf *x509.Certificate
+}
+
+func NewCertificateProvider(ctx context.Context, logger log.ContextLogger, tag string, options option.CloudflareOriginCACertificateProviderOptions) (adapter.CertificateProviderService, error) {
+ domain, err := normalizeHostnames(options.Domain)
+ if err != nil {
+ return nil, err
+ }
+ if len(domain) == 0 {
+ return nil, E.New("missing domain")
+ }
+ apiToken := strings.TrimSpace(options.APIToken)
+ originCAKey := strings.TrimSpace(options.OriginCAKey)
+ switch {
+ case apiToken == "" && originCAKey == "":
+ return nil, E.New("api_token or origin_ca_key is required")
+ case apiToken != "" && originCAKey != "":
+ return nil, E.New("api_token and origin_ca_key are mutually exclusive")
+ }
+ requestType := options.RequestType
+ if requestType == "" {
+ requestType = option.CloudflareOriginCARequestTypeOriginRSA
+ }
+ requestedValidity := options.RequestedValidity
+ if requestedValidity == 0 {
+ requestedValidity = defaultRequestedValidity
+ }
+ ctx, cancel := context.WithCancel(ctx)
+ httpClient, err := originCAHTTPClient(ctx, logger, options)
+ if err != nil {
+ cancel()
+ return nil, err
+ }
+ var storage certmagic.Storage
+ if options.DataDirectory != "" {
+ storage = &certmagic.FileStorage{Path: options.DataDirectory}
+ } else {
+ storage = certmagic.Default.Storage
+ }
+ timeFunc := ntp.TimeFuncFromContext(ctx)
+ if timeFunc == nil {
+ timeFunc = time.Now
+ }
+ storageIssuerKey := C.TypeCloudflareOriginCA + "-" + string(requestType)
+ storageNamesKey := (&certmagic.CertificateResource{SANs: slices.Clone(domain)}).NamesKey()
+ storageLockKey := strings.Join([]string{
+ storageLockPrefix,
+ certmagic.StorageKeys.Safe(storageIssuerKey),
+ certmagic.StorageKeys.Safe(storageNamesKey),
+ }, "/")
+ return &Service{
+ Adapter: certificate.NewAdapter(C.TypeCloudflareOriginCA, tag),
+ logger: logger,
+ ctx: ctx,
+ cancel: cancel,
+ timeFunc: timeFunc,
+ httpClient: httpClient,
+ storage: storage,
+ storageIssuerKey: storageIssuerKey,
+ storageNamesKey: storageNamesKey,
+ storageLockKey: storageLockKey,
+ apiToken: apiToken,
+ originCAKey: originCAKey,
+ domain: domain,
+ requestType: requestType,
+ requestedValidity: requestedValidity,
+ }, nil
+}
+
+func originCAHTTPClient(ctx context.Context, logger log.ContextLogger, options option.CloudflareOriginCACertificateProviderOptions) (*http.Client, error) {
+ httpClientOptions := common.PtrValueOrDefault(options.HTTPClient)
+ httpClientManager := service.FromContext[adapter.HTTPClientManager](ctx)
+ transport, err := httpClientManager.ResolveTransport(ctx, logger, httpClientOptions)
+ if err != nil {
+ return nil, E.Cause(err, "create Cloudflare Origin CA http client")
+ }
+ return &http.Client{Transport: transport}, nil
+}
+
+func (s *Service) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+ cachedCertificate, cachedLeaf, err := s.loadCachedCertificate()
+ if err != nil {
+ s.logger.Warn(E.Cause(err, "load cached Cloudflare Origin CA certificate"))
+ } else if cachedCertificate != nil {
+ s.setCurrentCertificate(cachedCertificate, cachedLeaf)
+ }
+ if cachedCertificate == nil {
+ err = s.issueAndStoreCertificate()
+ if err != nil {
+ return err
+ }
+ } else if s.shouldRenew(cachedLeaf, s.timeFunc()) {
+ err = s.issueAndStoreCertificate()
+ if err != nil {
+ s.logger.Warn(E.Cause(err, "renew cached Cloudflare Origin CA certificate"))
+ }
+ }
+ s.done = make(chan struct{})
+ go s.refreshLoop()
+ return nil
+}
+
+func (s *Service) Close() error {
+ s.cancel()
+ if done := s.done; done != nil {
+ <-done
+ }
+ return nil
+}
+
+func (s *Service) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
+ s.access.RLock()
+ certificate := s.currentCertificate
+ s.access.RUnlock()
+ if certificate == nil {
+ return nil, E.New("Cloudflare Origin CA certificate is unavailable")
+ }
+ return certificate, nil
+}
+
+func (s *Service) refreshLoop() {
+ defer close(s.done)
+ var retryDelay time.Duration
+ for {
+ waitDuration := retryDelay
+ if waitDuration == 0 {
+ s.access.RLock()
+ leaf := s.currentLeaf
+ s.access.RUnlock()
+ if leaf == nil {
+ waitDuration = minimumRenewRetryDelay
+ } else {
+ refreshAt := leaf.NotAfter.Add(-s.effectiveRenewBefore(leaf))
+ waitDuration = max(refreshAt.Sub(s.timeFunc()), minimumRenewRetryDelay)
+ }
+ }
+ timer := time.NewTimer(waitDuration)
+ select {
+ case <-s.ctx.Done():
+ if !timer.Stop() {
+ select {
+ case <-timer.C:
+ default:
+ }
+ }
+ return
+ case <-timer.C:
+ }
+ err := s.issueAndStoreCertificate()
+ if err != nil {
+ s.logger.Error(E.Cause(err, "renew Cloudflare Origin CA certificate"))
+ s.access.RLock()
+ leaf := s.currentLeaf
+ s.access.RUnlock()
+ if leaf == nil {
+ retryDelay = minimumRenewRetryDelay
+ } else {
+ remaining := leaf.NotAfter.Sub(s.timeFunc())
+ switch {
+ case remaining <= minimumRenewRetryDelay:
+ retryDelay = minimumRenewRetryDelay
+ case remaining < maximumRenewRetryDelay:
+ retryDelay = max(remaining/2, minimumRenewRetryDelay)
+ default:
+ retryDelay = maximumRenewRetryDelay
+ }
+ }
+ continue
+ }
+ retryDelay = 0
+ }
+}
+
+func (s *Service) shouldRenew(leaf *x509.Certificate, now time.Time) bool {
+ return !now.Before(leaf.NotAfter.Add(-s.effectiveRenewBefore(leaf)))
+}
+
+func (s *Service) effectiveRenewBefore(leaf *x509.Certificate) time.Duration {
+ lifetime := leaf.NotAfter.Sub(leaf.NotBefore)
+ if lifetime <= 0 {
+ return 0
+ }
+ return min(lifetime/3, defaultRenewBefore)
+}
+
+func (s *Service) issueAndStoreCertificate() error {
+ err := s.storage.Lock(s.ctx, s.storageLockKey)
+ if err != nil {
+ return E.Cause(err, "lock Cloudflare Origin CA certificate storage")
+ }
+ defer func() {
+ err = s.storage.Unlock(context.WithoutCancel(s.ctx), s.storageLockKey)
+ if err != nil {
+ s.logger.Warn(E.Cause(err, "unlock Cloudflare Origin CA certificate storage"))
+ }
+ }()
+ cachedCertificate, cachedLeaf, err := s.loadCachedCertificate()
+ if err != nil {
+ s.logger.Warn(E.Cause(err, "load cached Cloudflare Origin CA certificate"))
+ } else if cachedCertificate != nil && !s.shouldRenew(cachedLeaf, s.timeFunc()) {
+ s.setCurrentCertificate(cachedCertificate, cachedLeaf)
+ return nil
+ }
+ certificatePEM, privateKeyPEM, tlsCertificate, leaf, err := s.requestCertificate(s.ctx)
+ if err != nil {
+ return err
+ }
+ issuerData, err := json.Marshal(originCAIssuerData{
+ RequestType: s.requestType,
+ RequestedValidity: s.requestedValidity,
+ })
+ if err != nil {
+ return E.Cause(err, "encode Cloudflare Origin CA certificate metadata")
+ }
+ err = storeCertificateResource(s.ctx, s.storage, s.storageIssuerKey, certmagic.CertificateResource{
+ SANs: slices.Clone(s.domain),
+ CertificatePEM: certificatePEM,
+ PrivateKeyPEM: privateKeyPEM,
+ IssuerData: issuerData,
+ })
+ if err != nil {
+ return E.Cause(err, "store Cloudflare Origin CA certificate")
+ }
+ s.setCurrentCertificate(tlsCertificate, leaf)
+ s.logger.Info("updated Cloudflare Origin CA certificate, expires at ", leaf.NotAfter.Format(time.RFC3339))
+ return nil
+}
+
+func (s *Service) requestCertificate(ctx context.Context) ([]byte, []byte, *tls.Certificate, *x509.Certificate, error) {
+ var privateKey crypto.Signer
+ switch s.requestType {
+ case option.CloudflareOriginCARequestTypeOriginRSA:
+ rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
+ if err != nil {
+ return nil, nil, nil, nil, err
+ }
+ privateKey = rsaKey
+ case option.CloudflareOriginCARequestTypeOriginECC:
+ ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ if err != nil {
+ return nil, nil, nil, nil, err
+ }
+ privateKey = ecKey
+ default:
+ return nil, nil, nil, nil, E.New("unsupported Cloudflare Origin CA request type: ", s.requestType)
+ }
+ privateKeyDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "encode private key")
+ }
+ privateKeyPEM := pem.EncodeToMemory(&pem.Block{
+ Type: "PRIVATE KEY",
+ Bytes: privateKeyDER,
+ })
+ certificateRequestDER, err := x509.CreateCertificateRequest(rand.Reader, &x509.CertificateRequest{
+ Subject: pkix.Name{CommonName: s.domain[0]},
+ DNSNames: s.domain,
+ }, privateKey)
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "create certificate request")
+ }
+ certificateRequestPEM := pem.EncodeToMemory(&pem.Block{
+ Type: "CERTIFICATE REQUEST",
+ Bytes: certificateRequestDER,
+ })
+ requestBody, err := json.Marshal(originCARequest{
+ CSR: string(certificateRequestPEM),
+ Hostnames: s.domain,
+ RequestType: string(s.requestType),
+ RequestedValidity: uint16(s.requestedValidity),
+ })
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "marshal request")
+ }
+ request, err := http.NewRequestWithContext(ctx, http.MethodPost, cloudflareOriginCAEndpoint, bytes.NewReader(requestBody))
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "create request")
+ }
+ request.Header.Set("Accept", "application/json")
+ request.Header.Set("Content-Type", "application/json")
+ request.Header.Set("User-Agent", "sing-box/"+C.Version)
+ if s.apiToken != "" {
+ request.Header.Set("Authorization", "Bearer "+s.apiToken)
+ } else {
+ request.Header.Set("X-Auth-User-Service-Key", s.originCAKey)
+ }
+ defer s.httpClient.CloseIdleConnections()
+ response, err := s.httpClient.Do(request)
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "request certificate from Cloudflare")
+ }
+ defer response.Body.Close()
+ responseBody, err := io.ReadAll(response.Body)
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "read Cloudflare response")
+ }
+ var responseEnvelope originCAResponse
+ err = json.Unmarshal(responseBody, &responseEnvelope)
+ if err != nil && response.StatusCode >= http.StatusOK && response.StatusCode < http.StatusMultipleChoices {
+ return nil, nil, nil, nil, E.Cause(err, "decode Cloudflare response")
+ }
+ if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices {
+ return nil, nil, nil, nil, buildOriginCAError(response.StatusCode, responseEnvelope.Errors, responseBody)
+ }
+ if !responseEnvelope.Success {
+ return nil, nil, nil, nil, buildOriginCAError(response.StatusCode, responseEnvelope.Errors, responseBody)
+ }
+ if responseEnvelope.Result.Certificate == "" {
+ return nil, nil, nil, nil, E.New("Cloudflare Origin CA response is missing certificate data")
+ }
+ certificatePEM := []byte(responseEnvelope.Result.Certificate)
+ tlsCertificate, leaf, err := parseKeyPair(certificatePEM, privateKeyPEM)
+ if err != nil {
+ return nil, nil, nil, nil, E.Cause(err, "parse issued certificate")
+ }
+ if !s.matchesCertificate(leaf) {
+ return nil, nil, nil, nil, E.New("issued Cloudflare Origin CA certificate does not match requested hostnames or key type")
+ }
+ return certificatePEM, privateKeyPEM, tlsCertificate, leaf, nil
+}
+
+func (s *Service) loadCachedCertificate() (*tls.Certificate, *x509.Certificate, error) {
+ certificateResource, err := loadCertificateResource(s.ctx, s.storage, s.storageIssuerKey, s.storageNamesKey)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ return nil, nil, nil
+ }
+ return nil, nil, err
+ }
+ tlsCertificate, leaf, err := parseKeyPair(certificateResource.CertificatePEM, certificateResource.PrivateKeyPEM)
+ if err != nil {
+ return nil, nil, E.Cause(err, "parse cached key pair")
+ }
+ if s.timeFunc().After(leaf.NotAfter) {
+ return nil, nil, nil
+ }
+ if !s.matchesCertificate(leaf) {
+ return nil, nil, nil
+ }
+ return tlsCertificate, leaf, nil
+}
+
+func (s *Service) matchesCertificate(leaf *x509.Certificate) bool {
+ if leaf == nil {
+ return false
+ }
+ leafHostnames := leaf.DNSNames
+ if len(leafHostnames) == 0 && leaf.Subject.CommonName != "" {
+ leafHostnames = []string{leaf.Subject.CommonName}
+ }
+ normalizedLeafHostnames, err := normalizeHostnames(leafHostnames)
+ if err != nil {
+ return false
+ }
+ if !slices.Equal(normalizedLeafHostnames, s.domain) {
+ return false
+ }
+ switch s.requestType {
+ case option.CloudflareOriginCARequestTypeOriginRSA:
+ return leaf.PublicKeyAlgorithm == x509.RSA
+ case option.CloudflareOriginCARequestTypeOriginECC:
+ return leaf.PublicKeyAlgorithm == x509.ECDSA
+ default:
+ return false
+ }
+}
+
+func (s *Service) setCurrentCertificate(certificate *tls.Certificate, leaf *x509.Certificate) {
+ s.access.Lock()
+ s.currentCertificate = certificate
+ s.currentLeaf = leaf
+ s.access.Unlock()
+}
+
+func normalizeHostnames(hostnames []string) ([]string, error) {
+ normalizedHostnames := make([]string, 0, len(hostnames))
+ seen := make(map[string]struct{}, len(hostnames))
+ for _, hostname := range hostnames {
+ normalizedHostname := strings.ToLower(strings.TrimSpace(strings.TrimSuffix(hostname, ".")))
+ if normalizedHostname == "" {
+ return nil, E.New("hostname is empty")
+ }
+ if net.ParseIP(normalizedHostname) != nil {
+ return nil, E.New("hostname cannot be an IP address: ", normalizedHostname)
+ }
+ if strings.Contains(normalizedHostname, "*") {
+ if !strings.HasPrefix(normalizedHostname, "*.") || strings.Count(normalizedHostname, "*") != 1 {
+ return nil, E.New("invalid wildcard hostname: ", normalizedHostname)
+ }
+ suffix := strings.TrimPrefix(normalizedHostname, "*.")
+ if strings.Count(suffix, ".") == 0 {
+ return nil, E.New("wildcard hostname must cover a multi-label domain: ", normalizedHostname)
+ }
+ normalizedHostname = "*." + suffix
+ }
+ if _, loaded := seen[normalizedHostname]; loaded {
+ continue
+ }
+ seen[normalizedHostname] = struct{}{}
+ normalizedHostnames = append(normalizedHostnames, normalizedHostname)
+ }
+ slices.Sort(normalizedHostnames)
+ return normalizedHostnames, nil
+}
+
+func parseKeyPair(certificatePEM []byte, privateKeyPEM []byte) (*tls.Certificate, *x509.Certificate, error) {
+ keyPair, err := tls.X509KeyPair(certificatePEM, privateKeyPEM)
+ if err != nil {
+ return nil, nil, err
+ }
+ if len(keyPair.Certificate) == 0 {
+ return nil, nil, E.New("certificate chain is empty")
+ }
+ leaf, err := x509.ParseCertificate(keyPair.Certificate[0])
+ if err != nil {
+ return nil, nil, err
+ }
+ keyPair.Leaf = leaf
+ return &keyPair, leaf, nil
+}
+
+func storeCertificateResource(ctx context.Context, storage certmagic.Storage, issuerKey string, certificateResource certmagic.CertificateResource) error {
+ metaBytes, err := json.MarshalIndent(certificateResource, "", "\t")
+ if err != nil {
+ return err
+ }
+ namesKey := certificateResource.NamesKey()
+ keyValueList := []struct {
+ key string
+ value []byte
+ }{
+ {
+ key: certmagic.StorageKeys.SitePrivateKey(issuerKey, namesKey),
+ value: certificateResource.PrivateKeyPEM,
+ },
+ {
+ key: certmagic.StorageKeys.SiteCert(issuerKey, namesKey),
+ value: certificateResource.CertificatePEM,
+ },
+ {
+ key: certmagic.StorageKeys.SiteMeta(issuerKey, namesKey),
+ value: metaBytes,
+ },
+ }
+ for i, item := range keyValueList {
+ err = storage.Store(ctx, item.key, item.value)
+ if err != nil {
+ for j := i - 1; j >= 0; j-- {
+ storage.Delete(ctx, keyValueList[j].key)
+ }
+ return err
+ }
+ }
+ return nil
+}
+
+func loadCertificateResource(ctx context.Context, storage certmagic.Storage, issuerKey string, namesKey string) (certmagic.CertificateResource, error) {
+ privateKeyPEM, err := storage.Load(ctx, certmagic.StorageKeys.SitePrivateKey(issuerKey, namesKey))
+ if err != nil {
+ return certmagic.CertificateResource{}, err
+ }
+ certificatePEM, err := storage.Load(ctx, certmagic.StorageKeys.SiteCert(issuerKey, namesKey))
+ if err != nil {
+ return certmagic.CertificateResource{}, err
+ }
+ metaBytes, err := storage.Load(ctx, certmagic.StorageKeys.SiteMeta(issuerKey, namesKey))
+ if err != nil {
+ return certmagic.CertificateResource{}, err
+ }
+ var certificateResource certmagic.CertificateResource
+ err = json.Unmarshal(metaBytes, &certificateResource)
+ if err != nil {
+ return certmagic.CertificateResource{}, E.Cause(err, "decode Cloudflare Origin CA certificate metadata")
+ }
+ certificateResource.PrivateKeyPEM = privateKeyPEM
+ certificateResource.CertificatePEM = certificatePEM
+ return certificateResource, nil
+}
+
+func buildOriginCAError(statusCode int, responseErrors []originCAResponseError, responseBody []byte) error {
+ if len(responseErrors) > 0 {
+ messageList := make([]string, 0, len(responseErrors))
+ for _, responseError := range responseErrors {
+ if responseError.Message == "" {
+ continue
+ }
+ if responseError.Code != 0 {
+ messageList = append(messageList, responseError.Message+" (code "+strconv.Itoa(responseError.Code)+")")
+ } else {
+ messageList = append(messageList, responseError.Message)
+ }
+ }
+ if len(messageList) > 0 {
+ return E.New("Cloudflare Origin CA request failed: HTTP ", statusCode, " ", strings.Join(messageList, ", "))
+ }
+ }
+ responseText := strings.TrimSpace(string(responseBody))
+ if responseText == "" {
+ return E.New("Cloudflare Origin CA request failed: HTTP ", statusCode)
+ }
+ return E.New("Cloudflare Origin CA request failed: HTTP ", statusCode, " ", responseText)
+}
+
+type originCARequest struct {
+ CSR string `json:"csr"`
+ Hostnames []string `json:"hostnames"`
+ RequestType string `json:"request_type"`
+ RequestedValidity uint16 `json:"requested_validity"`
+}
+
+type originCAResponse struct {
+ Success bool `json:"success"`
+ Errors []originCAResponseError `json:"errors"`
+ Result originCAResponseResult `json:"result"`
+}
+
+type originCAResponseError struct {
+ Code int `json:"code"`
+ Message string `json:"message"`
+}
+
+type originCAResponseResult struct {
+ Certificate string `json:"certificate"`
+}
+
+type originCAIssuerData struct {
+ RequestType option.CloudflareOriginCARequestType `json:"request_type,omitempty"`
+ RequestedValidity option.CloudflareOriginCARequestValidity `json:"requested_validity,omitempty"`
+}
diff --git a/service/resolved/service.go b/service/resolved/service.go
index eaedc09d43..8f9740a06d 100644
--- a/service/resolved/service.go
+++ b/service/resolved/service.go
@@ -132,7 +132,7 @@ func (i *Service) Close() error {
return i.listener.Close()
}
-func (i *Service) NewConnectionEx(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
+func (i *Service) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
metadata.Inbound = i.Tag()
metadata.InboundType = i.Type()
metadata.Destination = M.Socksaddr{}
@@ -146,7 +146,7 @@ func (i *Service) NewConnectionEx(ctx context.Context, conn net.Conn, metadata a
}
}
-func (i *Service) NewPacketEx(buffer *buf.Buffer, oob []byte, source M.Socksaddr) {
+func (i *Service) NewPacket(buffer *buf.Buffer, oob []byte, source M.Socksaddr) {
go i.exchangePacket(buffer, oob, source)
}
diff --git a/service/resolved/transport.go b/service/resolved/transport.go
index bdc3555110..df062a79c7 100644
--- a/service/resolved/transport.go
+++ b/service/resolved/transport.go
@@ -32,7 +32,10 @@ func RegisterTransport(registry *dns.TransportRegistry) {
dns.RegisterTransport[option.ResolvedDNSServerOptions](registry, C.TypeResolved, NewTransport)
}
-var _ adapter.DNSTransport = (*Transport)(nil)
+var (
+ _ adapter.DNSTransport = (*Transport)(nil)
+ _ adapter.DNSTransportWithPreferredDomain = (*Transport)(nil)
+)
type Transport struct {
dns.TransportAdapter
@@ -191,6 +194,22 @@ func (t *Transport) deleteTransport(link *TransportLink) {
delete(t.linkServers, link)
}
+func (t *Transport) PreferredDomain(domain string) bool {
+ t.service.linkAccess.RLock()
+ defer t.service.linkAccess.RUnlock()
+ for _, link := range t.service.links {
+ for _, linkDomain := range link.domain {
+ if linkDomain.Domain == "." {
+ continue
+ }
+ if strings.HasSuffix(domain, linkDomain.Domain) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
question := message.Question[0]
var selectedLink *TransportLink
diff --git a/service/smart_dns_pool/service.go b/service/smart_dns_pool/service.go
new file mode 100644
index 0000000000..d04375ceab
--- /dev/null
+++ b/service/smart_dns_pool/service.go
@@ -0,0 +1,210 @@
+// Package smart_dns_pool provides a sing-box service that runs a local DNS
+// server fronting many recursive upstream resolvers, using
+// github.com/hiddify/hmrd_multi_resolver_dns under the hood.
+//
+// Why: dnstt's tunnel sends DNS queries to a single recursive resolver
+// (e.g. `8.8.8.8`). When that resolver gets rate-limited or blocked the
+// tunnel stalls. Configure this service with the recursive resolvers you
+// want to distribute load across, then point dnstt's `resolvers` at the
+// service's listen address (e.g. `udp://127.0.0.1:19876`). dnstt sees a
+// normal local resolver; the service transparently fans queries out to
+// many real upstreams with deadline-aware failover, AIMD rate-limit
+// throttling, and recovery probing.
+package smart_dns_pool
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/netip"
+ "strconv"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ boxService "github.com/sagernet/sing-box/adapter/service"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ E "github.com/sagernet/sing/common/exceptions"
+
+ multidns "github.com/hiddify/hmrd_multi_resolver_dns"
+)
+
+// RegisterService hooks the smart_dns_pool service type into the registry.
+func RegisterService(registry *boxService.Registry) {
+ boxService.Register[option.SmartDNSPoolServiceOptions](registry, C.TypeSmartDNSPool, NewService)
+}
+
+var _ adapter.Service = (*Service)(nil)
+
+type Service struct {
+ boxService.Adapter
+ logger log.ContextLogger
+ opts option.SmartDNSPoolServiceOptions
+
+ listenAddr string
+
+ mu sync.Mutex
+ mgr *multidns.Manager
+ server *multidns.Server
+ serverOnce sync.Once
+ serveErr chan error
+}
+
+// NewService constructs a smart_dns_pool service. It validates the options
+// up-front so config errors surface at parse time, but defers any network
+// activity (binding the listener, building upstream transports) to Start.
+func NewService(ctx context.Context, logger log.ContextLogger, tag string, opts option.SmartDNSPoolServiceOptions) (adapter.Service, error) {
+ if len(opts.Upstreams) == 0 {
+ return nil, E.New("smart_dns_pool: at least one upstream is required")
+ }
+
+ host := "127.0.0.1"
+ if opts.Listen != nil {
+ host = opts.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})).String()
+ }
+ port := opts.ListenPort
+ if port == 0 {
+ return nil, E.New("smart_dns_pool: listen_port is required (e.g. 19876)")
+ }
+
+ for i, up := range opts.Upstreams {
+ if up.Address == "" {
+ return nil, E.New("smart_dns_pool: upstream #", i, " missing address")
+ }
+ if _, err := protocolFromString(up.Type); err != nil {
+ return nil, E.Cause(err, "smart_dns_pool: upstream #", i)
+ }
+ }
+
+ return &Service{
+ Adapter: boxService.NewAdapter(C.TypeSmartDNSPool, tag),
+ logger: logger,
+ opts: opts,
+ listenAddr: net.JoinHostPort(host, strconv.Itoa(int(port))),
+ }, nil
+}
+
+// Start brings up the smart pool and binds the local DNS listener. It runs
+// at the StartStart stage so dnstt outbounds (which start later) find a
+// listener already accepting queries on their first request.
+func (s *Service) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ mgr := multidns.New(multidns.Options{
+ DefaultDeadline: time.Duration(s.opts.Deadline),
+ DefaultResolverTimeout: time.Duration(s.opts.PerAttempt),
+ ProbeInterval: time.Duration(s.opts.ProbeInterval),
+ DownAfterFailures: s.opts.DownAfter,
+ LoadBalance: lbFromString(s.opts.LoadBalance),
+ Logger: newLoggerAdapter(s.logger, s.Tag()),
+ })
+
+ for i, up := range s.opts.Upstreams {
+ proto, _ := protocolFromString(up.Type) // already validated in NewService
+ cfg := multidns.ResolverConfig{
+ Name: up.Name,
+ Protocol: proto,
+ Address: up.Address,
+ Weight: up.Weight,
+ }
+ if _, err := mgr.AddResolver(cfg); err != nil {
+ _ = mgr.Close()
+ return E.Cause(err, "smart_dns_pool: register upstream #", i, " (", up.Type, " ", up.Address, ")")
+ }
+ }
+
+ srv := mgr.NewServer(s.listenAddr) // UDP+TCP by default
+ s.serveErr = make(chan error, 1)
+ go func() {
+ if err := srv.ListenAndServe(); err != nil {
+ s.serveErr <- err
+ s.logger.Error("smart_dns_pool: listener exited: ", err)
+ }
+ }()
+
+ s.mgr = mgr
+ s.server = srv
+ s.logger.Info("smart_dns_pool: listening on ", s.listenAddr, " (udp+tcp), ", len(s.opts.Upstreams), " upstream(s)")
+ return nil
+}
+
+func (s *Service) Close() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+
+ var firstErr error
+ if s.server != nil {
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ if err := s.server.Shutdown(ctx); err != nil {
+ firstErr = err
+ }
+ cancel()
+ s.server = nil
+ }
+ if s.mgr != nil {
+ if err := s.mgr.Close(); err != nil && firstErr == nil {
+ firstErr = err
+ }
+ s.mgr = nil
+ }
+ return firstErr
+}
+
+func protocolFromString(s string) (multidns.Protocol, error) {
+ switch s {
+ case "udp", "":
+ return multidns.ProtoUDP, nil
+ case "tcp":
+ return multidns.ProtoTCP, nil
+ case "tls", "dot":
+ return multidns.ProtoDoT, nil
+ case "https", "doh":
+ return multidns.ProtoDoH, nil
+ default:
+ return "", fmt.Errorf("unsupported upstream type %q (want udp|tcp|tls|https)", s)
+ }
+}
+
+func lbFromString(s string) multidns.LBStrategy {
+ switch s {
+ case "weighted":
+ return multidns.LBWeighted
+ case "lowest_latency":
+ return multidns.LBLowestLatency
+ default:
+ return multidns.LBRoundRobin
+ }
+}
+
+// loggerAdapter bridges sing-box's ContextLogger to multidns.Logger
+// (printf-style). The tag prefix lets operators tell which service
+// instance produced a line when multiple smart_dns_pool services are
+// configured.
+type loggerAdapter struct {
+ logger log.ContextLogger
+ tag string
+}
+
+func newLoggerAdapter(logger log.ContextLogger, tag string) *loggerAdapter {
+ return &loggerAdapter{logger: logger, tag: tag}
+}
+
+func (l *loggerAdapter) Debugf(format string, args ...any) {
+ l.logger.Debug(l.tag, ": ", fmt.Sprintf(format, args...))
+}
+func (l *loggerAdapter) Infof(format string, args ...any) {
+ l.logger.Info(l.tag, ": ", fmt.Sprintf(format, args...))
+}
+func (l *loggerAdapter) Warnf(format string, args ...any) {
+ l.logger.Warn(l.tag, ": ", fmt.Sprintf(format, args...))
+}
+func (l *loggerAdapter) Errorf(format string, args ...any) {
+ l.logger.Error(l.tag, ": ", fmt.Sprintf(format, args...))
+}
diff --git a/service/smart_dns_pool/service_test.go b/service/smart_dns_pool/service_test.go
new file mode 100644
index 0000000000..e1055296f0
--- /dev/null
+++ b/service/smart_dns_pool/service_test.go
@@ -0,0 +1,259 @@
+package smart_dns_pool
+
+import (
+ "context"
+ "net"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ "github.com/sagernet/sing/common/json/badoption"
+
+ "github.com/miekg/dns"
+)
+
+// startUDPUpstream spins up a tiny in-process miekg/dns UDP server that
+// answers any A query with answerIP, simulating a recursive resolver.
+func startUDPUpstream(t *testing.T, answerIP string) (string, func()) {
+ t.Helper()
+ pc, err := net.ListenPacket("udp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatalf("listen udp: %v", err)
+ }
+ srv := &dns.Server{
+ PacketConn: pc,
+ Handler: dns.HandlerFunc(func(w dns.ResponseWriter, q *dns.Msg) {
+ r := new(dns.Msg)
+ r.SetReply(q)
+ r.Rcode = dns.RcodeSuccess
+ if len(q.Question) > 0 && q.Question[0].Qtype == dns.TypeA {
+ r.Answer = append(r.Answer, &dns.A{
+ Hdr: dns.RR_Header{
+ Name: q.Question[0].Name, Rrtype: dns.TypeA,
+ Class: dns.ClassINET, Ttl: 30,
+ },
+ A: net.ParseIP(answerIP).To4(),
+ })
+ }
+ _ = w.WriteMsg(r)
+ }),
+ }
+ go func() { _ = srv.ActivateAndServe() }()
+ return pc.LocalAddr().String(), func() { _ = srv.Shutdown() }
+}
+
+// freePort returns a port number guaranteed to be free at the moment of
+// the call (the listener is closed before returning, so technically there's
+// a TOCTOU window, but it's fine for tests).
+func freePort(t *testing.T) uint16 {
+ t.Helper()
+ l, err := net.ListenPacket("udp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatalf("freePort: %v", err)
+ }
+ port := l.LocalAddr().(*net.UDPAddr).Port
+ l.Close()
+ return uint16(port)
+}
+
+// digOnce sends a single A query for `name` to addr (host:port) over UDP and
+// returns the resolved IP string, or fatals.
+func digOnce(t *testing.T, addr, name string) string {
+ t.Helper()
+ c := &dns.Client{Net: "udp", Timeout: 1500 * time.Millisecond}
+ q := new(dns.Msg)
+ q.SetQuestion(dns.Fqdn(name), dns.TypeA)
+ resp, _, err := c.Exchange(q, addr)
+ if err != nil {
+ t.Fatalf("exchange: %v", err)
+ }
+ if resp == nil || resp.Rcode != dns.RcodeSuccess || len(resp.Answer) != 1 {
+ t.Fatalf("unexpected resp: %#v", resp)
+ }
+ a, ok := resp.Answer[0].(*dns.A)
+ if !ok || a.A == nil {
+ t.Fatalf("not an A record: %#v", resp.Answer[0])
+ }
+ return a.A.String()
+}
+
+// TestSmartDNSPool_EndToEnd builds the service from a real
+// SmartDNSPoolServiceOptions, starts it, sends an A query to its bound
+// address, and verifies the answer routed through one of the configured
+// upstreams. This is the integration shape dnstt would use: resolver
+// address = 127.0.0.1: instead of 8.8.8.8:53.
+func TestSmartDNSPool_EndToEnd(t *testing.T) {
+ upA, stopA := startUDPUpstream(t, "192.0.2.51")
+ defer stopA()
+ upB, stopB := startUDPUpstream(t, "192.0.2.52")
+ defer stopB()
+
+ port := freePort(t)
+ listenAddr := badoption.Addr{}
+ if err := listenAddr.UnmarshalJSON([]byte(`"127.0.0.1"`)); err != nil {
+ t.Fatalf("parse listen addr: %v", err)
+ }
+
+ opts := option.SmartDNSPoolServiceOptions{
+ ListenOptions: option.ListenOptions{
+ Listen: &listenAddr,
+ ListenPort: port,
+ },
+ Upstreams: []option.SmartDNSPoolUpstreamOptions{
+ {Type: "udp", Address: upA},
+ {Type: "udp", Address: upB},
+ },
+ LoadBalance: "roundrobin",
+ }
+
+ svc, err := NewService(context.Background(), log.NewNOPFactory().NewLogger("smart-dns-pool-test"), "smart-dns-pool", opts)
+ if err != nil {
+ t.Fatalf("NewService: %v", err)
+ }
+ if err := svc.Start(adapter.StartStateStart); err != nil {
+ t.Fatalf("Start: %v", err)
+ }
+ defer svc.Close()
+
+ addr := "127.0.0.1:" + strconv.Itoa(int(port))
+
+ // Wait for the listener to bind.
+ deadline := time.Now().Add(time.Second)
+ for time.Now().Before(deadline) {
+ c := &dns.Client{Net: "udp", Timeout: 100 * time.Millisecond}
+ q := new(dns.Msg)
+ q.SetQuestion("ready.test.", dns.TypeA)
+ if _, _, err := c.Exchange(q, addr); err == nil {
+ break
+ }
+ time.Sleep(20 * time.Millisecond)
+ }
+
+ // Run several queries — round-robin should distribute across both upstreams.
+ answers := map[string]int{}
+ for i := 0; i < 10; i++ {
+ ip := digOnce(t, addr, "smart.test.")
+ answers[ip]++
+ }
+ if answers["192.0.2.51"] == 0 || answers["192.0.2.52"] == 0 {
+ t.Fatalf("round-robin didn't reach both upstreams: %#v", answers)
+ }
+}
+
+// TestSmartDNSPool_FailoverWithinDeadline configures one dropping upstream
+// and one healthy one, and verifies queries through the local listener
+// still get answered (the smart pool's failover keeps the tunnel alive
+// even when one resolver is dead — the headline use case for dnstt).
+func TestSmartDNSPool_FailoverWithinDeadline(t *testing.T) {
+ // Dropping upstream: a UDP socket that just drops packets.
+ pc, err := net.ListenPacket("udp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatalf("listen drop: %v", err)
+ }
+ defer pc.Close()
+ dropAddr := pc.LocalAddr().String()
+
+ good, stopGood := startUDPUpstream(t, "192.0.2.60")
+ defer stopGood()
+
+ port := freePort(t)
+ listenAddr := badoption.Addr{}
+ if err := listenAddr.UnmarshalJSON([]byte(`"127.0.0.1"`)); err != nil {
+ t.Fatalf("parse listen addr: %v", err)
+ }
+
+ opts := option.SmartDNSPoolServiceOptions{
+ ListenOptions: option.ListenOptions{Listen: &listenAddr, ListenPort: port},
+ Upstreams: []option.SmartDNSPoolUpstreamOptions{
+ {Type: "udp", Address: dropAddr},
+ {Type: "udp", Address: good},
+ },
+ Deadline: badoption.Duration(2 * time.Second),
+ PerAttempt: badoption.Duration(150 * time.Millisecond),
+ }
+
+ svc, err := NewService(context.Background(), log.NewNOPFactory().NewLogger("smart-dns-pool-test"), "smart-dns-pool", opts)
+ if err != nil {
+ t.Fatalf("NewService: %v", err)
+ }
+ if err := svc.Start(adapter.StartStateStart); err != nil {
+ t.Fatalf("Start: %v", err)
+ }
+ defer svc.Close()
+
+ addr := "127.0.0.1:" + strconv.Itoa(int(port))
+ // Warmup until the listener accepts.
+ deadline := time.Now().Add(time.Second)
+ for time.Now().Before(deadline) {
+ c := &dns.Client{Net: "udp", Timeout: 100 * time.Millisecond}
+ q := new(dns.Msg)
+ q.SetQuestion("ready.test.", dns.TypeA)
+ if _, _, err := c.Exchange(q, addr); err == nil {
+ break
+ }
+ time.Sleep(20 * time.Millisecond)
+ }
+
+ saw := false
+ for i := 0; i < 6; i++ {
+ ip := digOnce(t, addr, "fail.test.")
+ if ip == "192.0.2.60" {
+ saw = true
+ }
+ }
+ if !saw {
+ t.Fatalf("no successful answers — failover broken")
+ }
+}
+
+// TestSmartDNSPool_RejectsBadConfig verifies validation at NewService time.
+func TestSmartDNSPool_RejectsBadConfig(t *testing.T) {
+ cases := []struct {
+ name string
+ opts option.SmartDNSPoolServiceOptions
+ wantErr string
+ wantOK bool
+ }{
+ {
+ name: "no upstreams",
+ opts: option.SmartDNSPoolServiceOptions{
+ ListenOptions: option.ListenOptions{ListenPort: 19000},
+ },
+ wantErr: "at least one upstream is required",
+ },
+ {
+ name: "missing port",
+ opts: option.SmartDNSPoolServiceOptions{
+ Upstreams: []option.SmartDNSPoolUpstreamOptions{
+ {Type: "udp", Address: "1.1.1.1:53"},
+ },
+ },
+ wantErr: "listen_port is required",
+ },
+ {
+ name: "unsupported type",
+ opts: option.SmartDNSPoolServiceOptions{
+ ListenOptions: option.ListenOptions{ListenPort: 19000},
+ Upstreams: []option.SmartDNSPoolUpstreamOptions{
+ {Type: "h3", Address: "1.1.1.1:443"},
+ },
+ },
+ wantErr: "unsupported upstream type",
+ },
+ }
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ _, err := NewService(context.Background(), log.NewNOPFactory().NewLogger("test"), "t", tc.opts)
+ if err == nil {
+ t.Fatalf("expected error containing %q, got nil", tc.wantErr)
+ }
+ if !strings.Contains(err.Error(), tc.wantErr) {
+ t.Fatalf("expected error containing %q, got: %v", tc.wantErr, err)
+ }
+ })
+ }
+}
diff --git a/test/go.mod b/test/go.mod
index 7d6d9edcff..41c73441ac 100644
--- a/test/go.mod
+++ b/test/go.mod
@@ -6,132 +6,223 @@ require github.com/sagernet/sing-box v0.0.0
replace github.com/sagernet/sing-box => ../
+replace github.com/sagernet/sing-dns => github.com/shtorm-7/sing-dns v0.4.6-extended-1.0.0
+
+replace github.com/ameshkov/dnscrypt/v2 => github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0
+
+replace github.com/sagernet/wireguard-go => ../replace/wireguard-go
+
+replace github.com/sagernet/tailscale => ../replace/tailscale
+
+replace github.com/Psiphon-Labs/quic-go => ../replace/psiphon-quic-go
+
+replace github.com/Psiphon-Labs/psiphon-tls => ../replace/psiphon-tls
+
+replace github.com/net2share/vaydns => github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9
+
require (
github.com/docker/docker v27.3.1+incompatible
github.com/docker/go-connections v0.5.0
github.com/gofrs/uuid/v5 v5.4.0
- github.com/sagernet/quic-go v0.59.0-sing-box-mod.2
- github.com/sagernet/sing v0.8.0-beta.16
- github.com/sagernet/sing-quic v0.6.0-beta.11
+ github.com/sagernet/quic-go v0.59.0-sing-box-mod.4
+ github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386
+ github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6
github.com/sagernet/sing-shadowsocks v0.2.8
github.com/sagernet/sing-shadowsocks2 v0.2.1
github.com/spyzhov/ajson v0.9.4
github.com/stretchr/testify v1.11.1
go.uber.org/goleak v1.3.0
- golang.org/x/net v0.48.0
+ golang.org/x/net v0.50.0
)
require (
+ filippo.io/bigmod v0.0.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
+ filippo.io/keygen v0.0.0-20230306160926-5201437acf8e // indirect
+ github.com/AdguardTeam/golibs v0.32.7 // indirect
+ github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
+ github.com/Jigsaw-Code/outline-sdk v0.0.16 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
+ github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7 // indirect
+ github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737 // indirect
+ github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464 // indirect
+ github.com/Psiphon-Labs/psiphon-tls v0.0.0-20250318183125-2a2fae2db378 // indirect
+ github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760 // indirect
+ github.com/Psiphon-Labs/quic-go v0.0.0-20250527153145-79fe45fb83b1 // indirect
+ github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/akutz/memconn v0.1.0 // indirect
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect
- github.com/andybalholm/brotli v1.1.0 // indirect
- github.com/anthropics/anthropic-sdk-go v1.19.0 // indirect
+ github.com/ameshkov/dnscrypt/v2 v2.4.0 // indirect
+ github.com/ameshkov/dnsstamps v1.0.3 // indirect
+ github.com/amnezia-vpn/amneziawg-go v0.2.16 // indirect
+ github.com/andybalholm/brotli v1.2.0 // indirect
+ github.com/anthropics/anthropic-sdk-go v1.26.0 // indirect
github.com/anytls/sing-anytls v0.0.11 // indirect
- github.com/caddyserver/certmagic v0.25.0 // indirect
- github.com/caddyserver/zerossl v0.1.3 // indirect
+ github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f // indirect
+ github.com/axiomhq/hyperloglog v0.2.6 // indirect
+ github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61 // indirect
+ github.com/biter777/countries v1.7.5 // indirect
+ github.com/bits-and-blooms/bitset v1.10.0 // indirect
+ github.com/bits-and-blooms/bloom/v3 v3.6.0 // indirect
+ github.com/caddyserver/certmagic v0.25.2 // indirect
+ github.com/caddyserver/zerossl v0.1.5 // indirect
+ github.com/cespare/xxhash v1.1.0 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 // indirect
+ github.com/cloudflare/circl v1.6.1 // indirect
github.com/coder/websocket v1.8.14 // indirect
+ github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // indirect
+ github.com/coreos/go-oidc/v3 v3.17.0 // indirect
github.com/cretz/bine v0.2.0 // indirect
github.com/database64128/netx-go v0.1.1 // indirect
- github.com/database64128/tfo-go/v2 v2.3.1 // indirect
+ github.com/database64128/tfo-go/v2 v2.3.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect
+ github.com/dchest/siphash v1.2.3 // indirect
+ github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273 // indirect
+ github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
+ github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/ebitengine/purego v0.9.1 // indirect
+ github.com/enfein/mieru/v3 v3.27.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/florianl/go-nfqueue/v2 v2.0.2 // indirect
+ github.com/flynn/noise v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gaissmai/bart v0.18.0 // indirect
- github.com/go-chi/chi/v5 v5.2.3 // indirect
+ github.com/go-chi/chi/v5 v5.2.5 // indirect
github.com/go-chi/render v1.0.3 // indirect
+ github.com/go-jose/go-jose/v4 v4.1.3 // indirect
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
- github.com/godbus/dbus/v5 v5.2.1 // indirect
+ github.com/godbus/dbus/v5 v5.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 // indirect
github.com/google/uuid v1.6.0 // indirect
+ github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
- github.com/insomniacslk/dhcp v0.0.0-20251020182700-175e84fbb167 // indirect
+ github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91 // indirect
+ github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 // indirect
github.com/jsimonetti/rtnetlink v1.4.0 // indirect
+ github.com/kamstrup/intmap v0.5.2 // indirect
github.com/keybase/go-keychain v0.0.1 // indirect
- github.com/klauspost/compress v1.18.0 // indirect
+ github.com/klauspost/compress v1.18.3 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
+ github.com/klauspost/reedsolomon v1.13.0 // indirect
github.com/libdns/acmedns v0.5.0 // indirect
- github.com/libdns/alidns v1.0.6-beta.3 // indirect
+ github.com/libdns/alidns v1.0.6 // indirect
github.com/libdns/cloudflare v0.2.2 // indirect
github.com/libdns/libdns v1.1.1 // indirect
+ github.com/libp2p/go-reuseport v0.4.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
- github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect
+ github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a // indirect
+ github.com/mdlayher/netlink v1.9.0 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/metacubex/utls v1.8.4 // indirect
- github.com/mholt/acmez/v3 v3.1.4 // indirect
- github.com/miekg/dns v1.1.69 // indirect
+ github.com/mholt/acmez/v3 v3.1.6 // indirect
+ github.com/miekg/dns v1.1.72 // indirect
github.com/mitchellh/go-ps v1.0.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
- github.com/openai/openai-go/v3 v3.15.0 // indirect
+ github.com/mroth/weightedrand v1.0.0 // indirect
+ github.com/net2share/vaydns v0.2.6 // indirect
+ github.com/openai/openai-go/v3 v3.26.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
+ github.com/pion/datachannel v1.5.5 // indirect
+ github.com/pion/dtls/v2 v2.2.7 // indirect
+ github.com/pion/ice/v2 v2.3.24 // indirect
+ github.com/pion/interceptor v0.1.25 // indirect
+ github.com/pion/logging v0.2.2 // indirect
+ github.com/pion/mdns v0.0.12 // indirect
+ github.com/pion/randutil v0.1.0 // indirect
+ github.com/pion/rtcp v1.2.12 // indirect
+ github.com/pion/rtp v1.8.5 // indirect
+ github.com/pion/sctp v1.8.16 // indirect
+ github.com/pion/sdp/v3 v3.0.9 // indirect
+ github.com/pion/srtp/v2 v2.0.18 // indirect
+ github.com/pion/stun v0.6.1 // indirect
+ github.com/pion/transport/v2 v2.2.4 // indirect
+ github.com/pion/turn/v2 v2.1.3 // indirect
+ github.com/pion/webrtc/v3 v3.2.40 // indirect
github.com/pires/go-proxyproto v0.8.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus-community/pro-bing v0.4.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
+ github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2 // indirect
+ github.com/refraction-networking/ed25519 v0.1.2 // indirect
+ github.com/refraction-networking/gotapdance v1.7.10 // indirect
+ github.com/refraction-networking/obfs4 v0.1.2 // indirect
+ github.com/refraction-networking/utls v1.8.2 // indirect
github.com/safchain/ethtool v0.3.0 // indirect
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect
github.com/sagernet/cors v1.2.1 // indirect
- github.com/sagernet/cronet-go v0.0.0-20260117110918-dc1cda1fe287 // indirect
- github.com/sagernet/cronet-go/all v0.0.0-20260117110918-dc1cda1fe287 // indirect
- github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260117110516-f21660bef13f // indirect
- github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260117110516-f21660bef13f // indirect
+ github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa // indirect
+ github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa // indirect
+ github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b // indirect
+ github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b // indirect
github.com/sagernet/fswatch v0.1.1 // indirect
github.com/sagernet/gvisor v0.0.0-20250822052253-5558536cf237 // indirect
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
+ github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9 // indirect
github.com/sagernet/sing-mux v0.3.4 // indirect
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 // indirect
- github.com/sagernet/sing-tun v0.8.0-beta.17 // indirect
+ github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695 // indirect
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 // indirect
github.com/sagernet/smux v1.5.50-sing-box-mod.1 // indirect
- github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6 // indirect
- github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20250917110311-16510ac47288 // indirect
+ github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.7 // indirect
+ github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20260224074747-506b7631853c // indirect
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect
+ github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 // indirect
+ github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect
+ github.com/sirupsen/logrus v1.9.4 // indirect
+ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e // indirect
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 // indirect
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect
@@ -143,37 +234,48 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
+ github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
+ github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 // indirect
+ github.com/wlynxg/anet v0.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
+ github.com/xtaci/kcp-go/v5 v5.6.70 // indirect
+ github.com/xtaci/smux v1.5.50 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect
+ gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
- go.opentelemetry.io/otel v1.38.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect
- go.opentelemetry.io/otel/metric v1.38.0 // indirect
- go.opentelemetry.io/otel/trace v1.38.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
+ go.opentelemetry.io/otel v1.39.0 // indirect
+ go.opentelemetry.io/otel/metric v1.39.0 // indirect
+ go.opentelemetry.io/otel/trace v1.39.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.1 // indirect
go.uber.org/zap/exp v0.3.0 // indirect
go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
- golang.org/x/crypto v0.46.0 // indirect
+ golang.org/x/crypto v0.48.0 // indirect
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
- golang.org/x/mod v0.31.0 // indirect
- golang.org/x/oauth2 v0.32.0 // indirect
+ golang.org/x/mod v0.33.0 // indirect
+ golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sync v0.19.0 // indirect
- golang.org/x/sys v0.39.0 // indirect
- golang.org/x/term v0.38.0 // indirect
- golang.org/x/text v0.32.0 // indirect
- golang.org/x/time v0.11.0 // indirect
- golang.org/x/tools v0.40.0 // indirect
+ golang.org/x/sys v0.41.0 // indirect
+ golang.org/x/term v0.40.0 // indirect
+ golang.org/x/text v0.34.0 // indirect
+ golang.org/x/time v0.14.0 // indirect
+ golang.org/x/tools v0.42.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
+ golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
+ golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
- google.golang.org/grpc v1.77.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
+ google.golang.org/grpc v1.79.1 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
- lukechampine.com/blake3 v1.3.0 // indirect
+ gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect
+ lukechampine.com/blake3 v1.4.1 // indirect
+ tailscale.com v1.58.2 // indirect
+ zombiezen.com/go/capnproto2 v2.18.2+incompatible // indirect
)
diff --git a/test/go.sum b/test/go.sum
index 34f8d99704..097fc845e7 100644
--- a/test/go.sum
+++ b/test/go.sum
@@ -1,48 +1,129 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+code.pfad.fr/check v1.1.0 h1:GWvjdzhSEgHvEHe2uJujDcpmZoySKuHQNrZMfzfO0bE=
+code.pfad.fr/check v1.1.0/go.mod h1:NiUH13DtYsb7xp5wll0U4SXx7KhXQVCtRgdC96IPfoM=
+filippo.io/bigmod v0.0.1 h1:OaEqDr3gEbofpnHbGqZweSL/bLMhy1pb54puiCDeuOA=
+filippo.io/bigmod v0.0.1/go.mod h1:KyzqAbH7bRH6MOuOF1TPfUjvLoi0mRF2bIyD2ouRNQI=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
+filippo.io/keygen v0.0.0-20230306160926-5201437acf8e h1:+xwUCyMiCWKWsI0RowhzB4sngpUdMHgU6lLuWJCX5Dg=
+filippo.io/keygen v0.0.0-20230306160926-5201437acf8e/go.mod h1:ZGSiF/b2hd6MRghF/cid0vXw8pXykRTmIu+JSPw/NCQ=
+github.com/AdguardTeam/golibs v0.32.7 h1:3dmGlAVgmvquCCwHsvEl58KKcRAK3z1UnjMnwSIeDH4=
+github.com/AdguardTeam/golibs v0.32.7/go.mod h1:bE8KV1zqTzgZjmjFyBJ9f9O5DEKO717r7e57j1HclJA=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
+github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c h1:pxW6RcqyfI9/kWtOwnv/G+AzdKuy2ZrqINhenH4HyNs=
+github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/Jigsaw-Code/outline-sdk v0.0.16 h1:WbHmv80FKDIpzEmR3GehTbq5CibYTLvcxIIpMMILiEs=
+github.com/Jigsaw-Code/outline-sdk v0.0.16/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8=
+github.com/Jigsaw-Code/outline-ss-server v1.8.0 h1:6h7CZsyl1vQLz3nvxmL9FbhDug4QxJ1YTxm534eye1E=
+github.com/Jigsaw-Code/outline-ss-server v1.8.0/go.mod h1:slnHH3OZsQmZx/DRKhxvvaGE/8+n3Lkd6363h1ev71E=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
+github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/Psiphon-Inc/rotate-safe-writer v0.0.0-20210303140923-464a7a37606e h1:NPfqIbzmijrl0VclX2t8eO5EPBhqe47LLGKpRrcVjXk=
+github.com/Psiphon-Inc/rotate-safe-writer v0.0.0-20210303140923-464a7a37606e/go.mod h1:ZdY5pBfat/WVzw3eXbIf7N1nZN0XD5H5+X8ZMDWbCs4=
+github.com/Psiphon-Inc/uds-ipc v1.0.1 h1:K3Z0cS1XfzDdhxWTIwh/hiLrkRR83ZxUo2bqgBOGuZE=
+github.com/Psiphon-Inc/uds-ipc v1.0.1/go.mod h1:R8TGG+OXumorJdpAcSFE4SVTT2frMFEGY43Zc/44sNk=
+github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7 h1:Hx/NCZTnvoKZuIBwSmxE58KKoNLXIGG6hBJYN7pj9Ag=
+github.com/Psiphon-Labs/bolt v0.0.0-20200624191537-23cedaef7ad7/go.mod h1:alTtZBo3j4AWFvUrAH6F5ZaHcTj4G5Y01nHz8dkU6vU=
+github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737 h1:QTMy7Uc2Xc7fz6O/Khy1xi0VBND13GqzLUE2mHw6HUU=
+github.com/Psiphon-Labs/consistent v0.0.0-20240322131436-20aaa4e05737/go.mod h1:Enj/Gszv2zCbuRbHbabmNvfO9EM+5kmaGj8CyjwNPlY=
+github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464 h1:VmnMMMheFXwLV0noxYhbJbLmkV4iaVW3xNnj6xcCNHo=
+github.com/Psiphon-Labs/goptlib v0.0.0-20200406165125-c0e32a7a3464/go.mod h1:Pe5BqN2DdIdChorAXl6bDaQd/wghpCleJfid2NoSli0=
+github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760 h1:R4O6UNd88eb1s/txuBTg99U/BZrDOGQgJ4pSL2MRBEs=
+github.com/Psiphon-Labs/psiphon-tunnel-core v1.0.11-0.20260126173038-c86a1497a760/go.mod h1:FcBjozoGjC2I7ZID0lXFlVQcy/jx6irCzlPxapGebEY=
+github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d h1:PlKwrArEuQOVqEmThSs9KsXMiBduP8MSu9rlWmQ4jgE=
+github.com/Psiphon-Labs/utls v0.0.0-20260129182755-24497d415a8d/go.mod h1:1vv0gVAzq9e2XYkW8HAKrmtuuZrBdDixQFx5H22KAjI=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A=
github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
-github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
-github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
-github.com/anthropics/anthropic-sdk-go v1.19.0 h1:mO6E+ffSzLRvR/YUH9KJC0uGw0uV8GjISIuzem//3KE=
-github.com/anthropics/anthropic-sdk-go v1.19.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE=
+github.com/ameshkov/dnsstamps v1.0.3 h1:Srzik+J9mivH1alRACTbys2xOxs0lRH9qnTA7Y1OYVo=
+github.com/ameshkov/dnsstamps v1.0.3/go.mod h1:Ii3eUu73dx4Vw5O4wjzmT5+lkCwovjzaEZZ4gKyIH5A=
+github.com/amnezia-vpn/amneziawg-go v0.2.16 h1:XY6HOq/xtqH8ZXMncRWkjFs85EKdN10NLNnw23kTpE0=
+github.com/amnezia-vpn/amneziawg-go v0.2.16/go.mod h1:nRkPpIzjCxMW8pZKXTRkpqAQVlmFJdVOGkeQSC7wbms=
+github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
+github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
+github.com/anthropics/anthropic-sdk-go v1.26.0 h1:oUTzFaUpAevfuELAP1sjL6CQJ9HHAfT7CoSYSac11PY=
+github.com/anthropics/anthropic-sdk-go v1.26.0/go.mod h1:qUKmaW+uuPB64iy1l+4kOSvaLqPXnHTTBKH6RVZ7q5Q=
github.com/anytls/sing-anytls v0.0.11 h1:w8e9Uj1oP3m4zxkyZDewPk0EcQbvVxb7Nn+rapEx4fc=
github.com/anytls/sing-anytls v0.0.11/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8=
-github.com/caddyserver/certmagic v0.25.0 h1:VMleO/XA48gEWes5l+Fh6tRWo9bHkhwAEhx63i+F5ic=
-github.com/caddyserver/certmagic v0.25.0/go.mod h1:m9yB7Mud24OQbPHOiipAoyKPn9pKHhpSJxXR1jydBxA=
-github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
-github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
+github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f h1:SaJ6yqg936TshyeFZqQE+N+9hYkIeL9AMr7S4voCl10=
+github.com/armon/go-proxyproto v0.0.0-20180202201750-5b7edb60ff5f/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
+github.com/axiomhq/hyperloglog v0.2.6 h1:sRhvvF3RIXWQgAXaTphLp4yJiX4S0IN3MWTaAgZoRJw=
+github.com/axiomhq/hyperloglog v0.2.6/go.mod h1:YjX/dQqCR/7QYX0g8mu8UZAjpIenz1FKM71UEsjFoTo=
+github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61 h1:BU+NxuoaYPIvvp8NNkNlLr8aA0utGyuunf4Q3LJ0bh0=
+github.com/bifurcation/mint v0.0.0-20180306135233-198357931e61/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
+github.com/biter777/countries v1.7.5 h1:MJ+n3+rSxWQdqVJU8eBy9RqcdH6ePPn4PJHocVWUa+Q=
+github.com/biter777/countries v1.7.5/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E=
+github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
+github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
+github.com/bits-and-blooms/bloom/v3 v3.6.0 h1:dTU0OVLJSoOhz9m68FTXMFfA39nR8U/nTCs1zb26mOI=
+github.com/bits-and-blooms/bloom/v3 v3.6.0/go.mod h1:VKlUSvp0lFIYqxJjzdnSsZEw4iHb1kOL2tfHTgyJBHg=
+github.com/caddyserver/certmagic v0.25.2 h1:D7xcS7ggX/WEY54x0czj7ioTkmDWKIgxtIi2OcQclUc=
+github.com/caddyserver/certmagic v0.25.2/go.mod h1:llW/CvsNmza8S6hmsuggsZeiX+uS27dkqY27wDIuBWg=
+github.com/caddyserver/zerossl v0.1.5 h1:dkvOjBAEEtY6LIGAHei7sw2UgqSD6TrWweXpV7lvEvE=
+github.com/caddyserver/zerossl v0.1.5/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
+github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9 h1:a1zrFsLFac2xoM6zG1u72DWJwZG3ayttYLfmLbxVETk=
+github.com/cheekybits/genny v0.0.0-20170328200008-9127e812e1e9/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/cilium/ebpf v0.15.0 h1:7NxJhNiBT3NG8pZJ3c+yfrVdHY8ScgKD27sScgjLMMk=
github.com/cilium/ebpf v0.15.0/go.mod h1:DHp1WyrLeiBh19Cf/tfiSMhqheEiK8fXFZ4No0P1Hso=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
+github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
+github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea h1:9C2rdYRp8Vzwhm3sbFX0yYfB+70zKFRjn7cnPCucHSw=
+github.com/cognusion/go-cache-lru v0.0.0-20170419142635-f73e2280ecea/go.mod h1:MdyNkAe06D7xmJsf+MsLvbZKYNXuOHLKJrvw+x4LlcQ=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6AYUslN6c6iuZWTKsKxUFDlpnmilO6R2n0=
github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
+github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc=
+github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
github.com/database64128/netx-go v0.1.1 h1:dT5LG7Gs7zFZBthFBbzWE6K8wAHjSNAaK7wCYZT7NzM=
github.com/database64128/netx-go v0.1.1/go.mod h1:LNlYVipaYkQArRFDNNJ02VkNV+My9A5XR/IGS7sIBQc=
-github.com/database64128/tfo-go/v2 v2.3.1 h1:EGE+ELd5/AQ0X6YBlQ9RgKs8+kciNhgN3d8lRvfEJQw=
-github.com/database64128/tfo-go/v2 v2.3.1/go.mod h1:k9wcpg/8i5zenspBkc9jUEYehpZZccBnCElzOJB++bU=
+github.com/database64128/tfo-go/v2 v2.3.2 h1:UhZMKiMq3swZGUiETkLBDzQnZBPSAeBMClpJGlnJ5Fw=
+github.com/database64128/tfo-go/v2 v2.3.2/go.mod h1:GC3uB5oa4beGpCUbRb2ZOWP73bJJFmMyAVgQSO7r724=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa h1:h8TfIT1xc8FWbwwpmHn1J5i43Y0uZP97GqasGCzSRJk=
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa/go.mod h1:Nx87SkVqTKd8UtT+xu7sM/l+LgXs6c0aHrlKusR+2EQ=
+github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
+github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
+github.com/deckarep/golang-set v0.0.0-20171013212420-1d4478f51bed h1:njG8LmGD6JCWJu4bwIKmkOHvch70UOEIqczl5vp7Gok=
+github.com/deckarep/golang-set v0.0.0-20171013212420-1d4478f51bed/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
+github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273 h1:45qZ7jowabqhyi3l9Ervox4dhQvLGB5BJPdC8w0a77k=
+github.com/dgraph-io/badger v1.5.4-0.20180815194500-3a87f6d9c273/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
+github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
+github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 h1:ucRHb6/lvW/+mTEIGbvhcYU3S8+uSNkuMjx/qZFfhtM=
+github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
@@ -51,10 +132,25 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A=
github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
+github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d h1:rtM8HsT3NG37YPjz8sYSbUSdElP9lUsQENYzJDZDUBE=
+github.com/elazarl/goproxy v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d h1:st1tmvy+4duoRj+RaeeJoECWCWM015fBtf/4aR+hhqk=
+github.com/elazarl/goproxy/ext v0.0.0-20200809112317-0581fc3aee2d/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
+github.com/enfein/mieru/v3 v3.27.0 h1:+E/1TF7OfimS2h582atEXQxPtJMyvqUTFBJUgzn1rxg=
+github.com/enfein/mieru/v3 v3.27.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/florianl/go-nfqueue v1.1.1-0.20200829120558-a2f196e98ab0 h1:7ZJyJV4KiWBijCCzUPvVaqxsDxO36+KD0XKBdEN3I+8=
+github.com/florianl/go-nfqueue v1.1.1-0.20200829120558-a2f196e98ab0/go.mod h1:2z3Tfqwv2ueuK6h563xUHRcCh1mv38wS9EjiWiesk84=
github.com/florianl/go-nfqueue/v2 v2.0.2 h1:FL5lQTeetgpCvac1TRwSfgaXUn0YSO7WzGvWNIp3JPE=
github.com/florianl/go-nfqueue/v2 v2.0.2/go.mod h1:VA09+iPOT43OMoCKNfXHyzujQUty2xmzyCRkBOlmabc=
+github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg=
+github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
+github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
+github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
@@ -63,10 +159,12 @@ github.com/gaissmai/bart v0.18.0 h1:jQLBT/RduJu0pv/tLwXE+xKPgtWJejbxuXAR+wLJafo=
github.com/gaissmai/bart v0.18.0/go.mod h1:JJzMAhNF5Rjo4SF4jWBrANuJfqY+FvsFhW7t1UZJ+XY=
github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I=
github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo=
-github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE=
-github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
+github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
+github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
+github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
+github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced h1:Q311OHjMh/u5E2TITc++WlTP5We0xNseRMkHDyvhW7I=
github.com/go-json-experiment/json v0.0.0-20250813024750-ebf49471dced/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -76,70 +174,124 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
+github.com/gobwas/glob v0.2.4-0.20180402141543-f00a7392b439 h1:T6zlOdzrYuHf6HUKujm9bzkzbZ5Iv/xf6rs8BHZDpoI=
+github.com/gobwas/glob v0.2.4-0.20180402141543-f00a7392b439/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
-github.com/godbus/dbus/v5 v5.2.1 h1:I4wwMdWSkmI57ewd+elNGwLRf2/dtSaFz1DujfWYvOk=
-github.com/godbus/dbus/v5 v5.2.1/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
+github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
+github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0=
github.com/gofrs/uuid/v5 v5.4.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
+github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806 h1:wG8RYIyctLhdFk6Vl1yPGtSRtwGpVkWyZww1OCil2MI=
github.com/google/nftables v0.2.1-0.20240414091927-5e242ec57806/go.mod h1:Beg6V6zZ3oEn0JuiUQ4wqwuyqqzasOltcoXPtgLbFp4=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
+github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
+github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
+github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427 h1:xh96CCAZTX8LJPFoOVRgTwZbn2DvJl8fyCyivohhSIg=
+github.com/grafov/m3u8 v0.0.0-20171211212457-6ab8f28ed427/go.mod h1:PdjzaU/pJUo4jTIn2rcgMFs+HqBGl/sPJLr8BI0Xq/I=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
+github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
+github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU=
github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo=
-github.com/insomniacslk/dhcp v0.0.0-20251020182700-175e84fbb167 h1:MEufgJohwIjFi2n3eJv4c/8UdRLQVUwPwSWQPoER+eU=
-github.com/insomniacslk/dhcp v0.0.0-20251020182700-175e84fbb167/go.mod h1:qfvBmyDNp+/liLEYWRvqny/PEz9hGe2Dz833eXILSmo=
+github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9 h1:KXnaABX8hHmkcL0jbL769hEIGI5+z/DajCrlO+Bkzcc=
+github.com/hiddify/vaydns v0.0.0-20260401180616-890dc987a6a9/go.mod h1:+8kEfQsZJn7/4aIppVekrSuqhrKjGBIgnacTJkdAlS8=
+github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91 h1:u9i04mGE3iliBh0EFuWaKsmcwrLacqGmq1G3XoaM7gY=
+github.com/insomniacslk/dhcp v0.0.0-20260220084031-5adc3eb26f91/go.mod h1:qfvBmyDNp+/liLEYWRvqny/PEz9hGe2Dz833eXILSmo=
+github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86 h1:elKwZS1OcdQ0WwEDBeqxKwb7WB62QX8bvZ/FJnVXIfk=
+github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86/go.mod h1:aFAMtuldEgx/4q7iSGazk22+IcgvtiC+HIimFO9XlS8=
github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I=
github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E=
+github.com/kamstrup/intmap v0.5.2 h1:qnwBm1mh4XAnW9W9Ue9tZtTff8pS6+s6iKF6JRIV2Dk=
+github.com/kamstrup/intmap v0.5.2/go.mod h1:gWUVWHKzWj8xpJVFf5GC0O26bWmv3GqdnIX/LMT6Aq4=
github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU=
github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
-github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw=
+github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
+github.com/klauspost/reedsolomon v1.13.0 h1:E0Cmgf2kMuhZTj6eefnvpKC4/Q4jhCi9YIjcZjK4arc=
+github.com/klauspost/reedsolomon v1.13.0/go.mod h1:ggJT9lc71Vu+cSOPBlxGvBN6TfAS77qB4fp8vJ05NSA=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/letsencrypt/challtestsrv v1.4.2 h1:0ON3ldMhZyWlfVNYYpFuWRTmZNnyfiL9Hh5YzC3JVwU=
+github.com/letsencrypt/challtestsrv v1.4.2/go.mod h1:GhqMqcSoeGpYd5zX5TgwA6er/1MbWzx/o7yuuVya+Wk=
+github.com/letsencrypt/pebble/v2 v2.10.0 h1:Wq6gYXlsY6ubqI3hhxsTzdyotvfdjFBxuwYqCLCnj/U=
+github.com/letsencrypt/pebble/v2 v2.10.0/go.mod h1:Sk8cmUIPcIdv2nINo+9PB4L+ZBhzY+F9A1a/h/xmWiQ=
github.com/libdns/acmedns v0.5.0 h1:5pRtmUj4Lb/QkNJSl1xgOGBUJTWW7RjpNaIhjpDXjPE=
github.com/libdns/acmedns v0.5.0/go.mod h1:X7UAFP1Ep9NpTwWpVlrZzJLR7epynAy0wrIxSPFgKjQ=
-github.com/libdns/alidns v1.0.6-beta.3 h1:KAmb7FQ1tRzKsaAUGa7ZpGKAMRANwg7+1c7tUbSELq8=
-github.com/libdns/alidns v1.0.6-beta.3/go.mod h1:RECwyQ88e9VqQVtSrvX76o1ux3gQUKGzMgxICi+u7Ec=
+github.com/libdns/alidns v1.0.6 h1:/Ii428ty6WHFJmE24rZxq2taq++gh7rf9jhgLfp8PmM=
+github.com/libdns/alidns v1.0.6/go.mod h1:RECwyQ88e9VqQVtSrvX76o1ux3gQUKGzMgxICi+u7Ec=
github.com/libdns/cloudflare v0.2.2 h1:XWHv+C1dDcApqazlh08Q6pjytYLgR2a+Y3xrXFu0vsI=
github.com/libdns/cloudflare v0.2.2/go.mod h1:w9uTmRCDlAoafAsTPnn2nJ0XHK/eaUMh86DUk8BWi60=
github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U=
github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
+github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
+github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 h1:A1Cq6Ysb0GM0tpKMbdCXCIfBclan4oHk1Jb+Hrejirg=
-github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42/go.mod h1:BB4YCPDOzfy7FniQ/lxuYQ3dgmM2cZumHbK8RpTjN2o=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
+github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
+github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a h1:6SRny9FLB1eWasPyDUqBQnMi9NhXU01XIlB0ao89YoI=
+github.com/marusama/semaphore v0.0.0-20171214154724-565ffd8e868a/go.mod h1:TmeOqAKoDinfPfSohs14CO3VcEf7o+Bem6JiNe05yrQ=
+github.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco=
+github.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/metacubex/utls v1.8.4 h1:HmL9nUApDdWSkgUyodfwF6hSjtiwCGGdyhaSpEejKpg=
github.com/metacubex/utls v1.8.4/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
-github.com/mholt/acmez/v3 v3.1.4 h1:DyzZe/RnAzT3rpZj/2Ii5xZpiEvvYk3cQEN/RmqxwFQ=
-github.com/mholt/acmez/v3 v3.1.4/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
-github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc=
-github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g=
+github.com/mholt/acmez/v3 v3.1.6 h1:eGVQNObP0pBN4sxqrXeg7MYqTOWyoiYpQqITVWlrevk=
+github.com/mholt/acmez/v3 v3.1.6/go.mod h1:5nTPosTGosLxF3+LU4ygbgMRFDhbAVpqMI4+a4aHLBY=
+github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
+github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
@@ -148,16 +300,79 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/mroth/weightedrand v1.0.0 h1:V8JeHChvl2MP1sAoXq4brElOcza+jxLkRuwvtQu8L3E=
+github.com/mroth/weightedrand v1.0.0/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
-github.com/openai/openai-go/v3 v3.15.0 h1:hk99rM7YPz+M99/5B/zOQcVwFRLLMdprVGx1vaZ8XMo=
-github.com/openai/openai-go/v3 v3.15.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
+github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
+github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
+github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
+github.com/openai/openai-go/v3 v3.26.0 h1:bRt6H/ozMNt/dDkN4gobnLqaEGrRGBzmbVs0xxJEnQE=
+github.com/openai/openai-go/v3 v3.26.0/go.mod h1:cdufnVK14cWcT9qA1rRtrXx4FTRsgbDPW7Ia7SS5cZo=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
+github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrzN7IgKZc=
+github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y=
+github.com/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
+github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pebbe/zmq4 v1.2.10 h1:wQkqRZ3CZeABIeidr3e8uQZMMH5YAykA/WN0L5zkd1c=
+github.com/pebbe/zmq4 v1.2.10/go.mod h1:nqnPueOapVhE2wItZ0uOErngczsJdLOGkebMxaO8r48=
+github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
+github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
+github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
+github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
+github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
+github.com/pion/ice/v2 v2.3.24 h1:RYgzhH/u5lH0XO+ABatVKCtRd+4U1GEaCXSMjNr13tI=
+github.com/pion/ice/v2 v2.3.24/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw=
+github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc=
+github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y=
+github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
+github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
+github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8=
+github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk=
+github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
+github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
+github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
+github.com/pion/rtcp v1.2.12 h1:bKWiX93XKgDZENEXCijvHRU/wRifm6JV5DGcH6twtSM=
+github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4=
+github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/rtp v1.8.5 h1:uYzINfaK+9yWs7r537z/Rc1SvT8ILjBcmDOpJcTB+OU=
+github.com/pion/rtp v1.8.5/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
+github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
+github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY=
+github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE=
+github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY=
+github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M=
+github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo=
+github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA=
+github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
+github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
+github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
+github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
+github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
+github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
+github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
+github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo=
+github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
+github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
+github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4=
+github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0=
+github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA=
+github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
+github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU=
+github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY=
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -165,66 +380,97 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
+github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
+github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2 h1:m2ZH6WV69otVmBpWbk8et3MypHFsjcYXTNrknQKS/PY=
+github.com/refraction-networking/conjure v0.7.11-0.20240130155008-c8df96195ab2/go.mod h1:7KuAtYfSL0K0WpCScjN9YKiOZ4AQ/8IzSjUtVwWbSv8=
+github.com/refraction-networking/ed25519 v0.1.2 h1:08kJZUkAlY7a7cZGosl1teGytV+QEoNxPO7NnRvAB+g=
+github.com/refraction-networking/ed25519 v0.1.2/go.mod h1:nxYLUAYt/hmNpAh64PNSQ/tQ9gTIB89wCaGKJlRtZ9I=
+github.com/refraction-networking/gotapdance v1.7.10 h1:vPtvuihP95SqrnnpX//KI1PTqrXCvNnOQslrG4gxsRY=
+github.com/refraction-networking/gotapdance v1.7.10/go.mod h1:N7Xmt+/bLv+1VctiBHtsaL6YBknW2ox5LRLzPTISMzY=
+github.com/refraction-networking/obfs4 v0.1.2 h1:J842O4fGSkd2W8ogYj0KN6gqVVY+Cpqodw9qFGL7wVU=
+github.com/refraction-networking/obfs4 v0.1.2/go.mod h1:wAl/+gWiLsrcykJA3nKJHx89f5/gXGM8UKvty7+mvbM=
+github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo=
+github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
+github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
+github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0=
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ=
github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI=
-github.com/sagernet/cronet-go v0.0.0-20260117110918-dc1cda1fe287 h1:0BYNmr0ptjsII948U0oBFmrbo4qEaCFcrE2JPRg3Zlk=
-github.com/sagernet/cronet-go v0.0.0-20260117110918-dc1cda1fe287/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw=
-github.com/sagernet/cronet-go/all v0.0.0-20260117110918-dc1cda1fe287 h1:ghxhYSBQpzkakqWqJDvXr/Zmxe0WjTjKuALEGbjGiGY=
-github.com/sagernet/cronet-go/all v0.0.0-20260117110918-dc1cda1fe287/go.mod h1:M+4ZjPhLJXIvoxcQsbDofmc19Wrig59hZ+hLvj6S3To=
-github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260117110516-f21660bef13f h1:8jZbZ4KBTdcXDFLwUBNQt5Xci6ZuAKh255S8TwuBCaM=
-github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260117110516-f21660bef13f/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
-github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260117110516-f21660bef13f h1:tG0hCx+0u5zca7qQ7AMkcv4DCrBG/DKW1ggs/P+BRRI=
-github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
-github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260117110516-f21660bef13f h1:ZXp5hKJIA7iJ52ZShJCKMQEPLpp/7dDIVZmPGV9Il40=
-github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260117110516-f21660bef13f/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
-github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260117110516-f21660bef13f h1:gL7H8HS8s38adz4/HZtRHh79qMwsbLTRRPz4GQ9LcWI=
-github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
-github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260117110516-f21660bef13f h1:Dchgc0pAY5Jwb5lzUlE+1nhHIzqLx+YOurXLHgvWd/0=
-github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
-github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260117110516-f21660bef13f h1:+MOLSQoduuKDxF410i1LcSPaQGaiP0eZb0INvMlmjM4=
-github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
-github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260117110516-f21660bef13f h1:lIZna05Vn6n8k21p8OpSUnhwGm+E57PrMjiI4ZUfMSg=
-github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260117110516-f21660bef13f/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0=
-github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260117110516-f21660bef13f h1:B2aFQ5CRHI20t8YsEizvtguS5W2QfK7D5XV/NzTIxPE=
-github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
-github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260117110516-f21660bef13f h1:qpSwJ1rFGYCfJDenNCZoWYjoG7N+xEa6ke+E7/JO1i4=
-github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260117110516-f21660bef13f/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo=
-github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260117110516-f21660bef13f h1:cx7Ipg0tSvTDjS4maMEYz4vuzz93BMPAysmZ1YLrz80=
-github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260117110516-f21660bef13f/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
-github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260117110516-f21660bef13f h1:4jOHuUiBxD8pJEpBBVQfJqyLmxjpd3t4MLRzU7YLFyg=
-github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260117110516-f21660bef13f/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
-github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260117110516-f21660bef13f h1:OpXBa2WlRU+Mam9oRe9Nn4/zf7gQ+qiBTNK8A5RwbfQ=
-github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
-github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260117110516-f21660bef13f h1:nJpGFi+6hI85tl4zoyNFEnFEQ5+xEV5gyvsUoMvd8g0=
-github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260117110516-f21660bef13f/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
-github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260117110516-f21660bef13f h1:SEy2rpmgOJgrqcEryJI/RSnqUWIsEsp0cfYoA8y21jc=
-github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260117110516-f21660bef13f/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
-github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260117110516-f21660bef13f h1:EW2TuFMLm0iBGqRZtuGwIZdeYmDtDsDmRcRRJQOMxUo=
-github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
-github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260117110516-f21660bef13f h1:3U5woxrNCkzfv1+UX+mVoWh1228AE1qAiMG02F9oFbY=
-github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260117110516-f21660bef13f/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
-github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260117110516-f21660bef13f h1:YwFTfuWG3mmctroeDYtFZ6LHjGsedVO+5wInYbbUuUY=
-github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260117110516-f21660bef13f/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
-github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260117110516-f21660bef13f h1:r4V0ddPCRLgGu0VdgR3aUsO9NjpmyjAf+h+3oTD9D6E=
-github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260117110516-f21660bef13f/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4=
-github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260117110516-f21660bef13f h1:B8yf4gFvEYUnwWmtVK9sdwUsflYZ387MhYmlOP2ohFQ=
-github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc=
-github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260117110516-f21660bef13f h1:9YyaMg4rO1/jIgrxmNb0LKH+X7frSYWfX2pFgW5JUVM=
-github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260117110516-f21660bef13f/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc=
-github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260117110516-f21660bef13f h1:B0fnGu0sh9yT/9JDN5u/GqThGoOzNN/daOAuGWFLXEk=
-github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
-github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260117110516-f21660bef13f h1:lxPcIXKSSI5JDhc7rx/6yufISWM4vtBS2FY9PavWQTs=
-github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260117110516-f21660bef13f/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
+github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa h1:7SehNSF1UHbLZa5dk+1rW1aperffJzl5r6TCJIXtAaY=
+github.com/sagernet/cronet-go v0.0.0-20260413093659-e4926ba205fa/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw=
+github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa h1:ijk5v9N/akiMgqu734yMpv7Pk9F4Qmjh8Vfdcb4uJHE=
+github.com/sagernet/cronet-go/all v0.0.0-20260413093659-e4926ba205fa/go.mod h1:+FENo4+0AOvH9e3oY6/iO7yy7USNt61dgbnI5W0TDZ0=
+github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b h1:O+PkYT88ayVWESX5tqxeMeS9OnzC3ZTic8gYiPJNXT8=
+github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw=
+github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:o0MsgbsJwYkbqlbfaCvmAwb8/LAXeoSP8NE/aNvR/yY=
+github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM=
+github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b h1:JEQnc7cRMUahWJFtWY6n0hs1LE0KgyRv3pD0RWS8Yo8=
+github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc=
+github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:69+AKzuUW9hzw2nU79c2DWfuzrIZ3PJm1KAwXh+7xr0=
+github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ=
+github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:jp9FHUVTCJQ67Ecw3Inoct6/z1VTFXPtNYpXt47pa4E=
+github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs=
+github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WN3DZoECd2UbhmYQGpOA4jx4QBXiZuN1DvL/35NT61g=
+github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0=
+github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:H4RKicwrIa4PwTXZOmXOg85hiCrpeFja4daOlX180pE=
+github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0=
+github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:Rwi+Cu+Hgwj28F1lh837gGqSqn7oU8+r5i3UJyLPkKc=
+github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4=
+github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:v2wcnPX3gt0PngFYXjXYAiarFckwx3pVAP6ETSpbSWE=
+github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo=
+github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b h1:Bl0zZ3QZq6pPJMbQlYHDhhaGngVefRlFzxWc0p48eHo=
+github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ=
+github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b h1:vf+MbGv6RvvmXUNvganykBOnDIVXxy8XgtKOOqOcxtE=
+github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU=
+github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:2IAc1bVFYF+B6hof34ChQKVhw7LElBxEEx7S0n+7o78=
+github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI=
+github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b h1:NrJaiOS0VLmWTbUHhXDsLTqelmCW4y3xJqptPs4Sx0s=
+github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ=
+github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b h1:A+ubSkca1nl2cT8pYUqCo1O7M41suNrKpWhZKCM/aIQ=
+github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0=
+github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:WrhGH5FDXlCAoXwN6N44yCMvy6EbIurmTmptkz3mmms=
+github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s=
+github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b h1:kgwB5p5e0gdVX5iYRE7VbZS/On4qnb4UKonkGPwhkDI=
+github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ=
+github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b h1:Z3dOeFlRIOeQhSh+mCYDHui1yR3S/Uw8eupczzBvxqw=
+github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow=
+github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b h1:LPi6jz1k11Q67hm3Pw6aaPJ/Z6e3VtNhzrRjr5/5AQo=
+github.com/sagernet/cronet-go/lib/linux_loong64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:Wt5uFdU3tnmm8YzobYewwdF7Mt6SucRQg6xeTNWC3Tk=
+github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b h1:55sqihyfXWN7y7p7gOEgtUz9cm1mV3SDQ90/v6ROFaA=
+github.com/sagernet/cronet-go/lib/linux_loong64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lyIF6wKBLwWa5ZXaAKbAoewewl+yCHo2iYev39Mbj4E=
+github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b h1:OTA1cbv5YIDVsYA8AAXHC4NgEc7b6pDiY+edujLWfJU=
+github.com/sagernet/cronet-go/lib/linux_mips64le v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:H46PnSTTZNcZokLLiDeMDaHiS1l14PH3tzWi0eykjD8=
+github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b h1:B/rdD/1A+RgqUYUZcoGhLeMqijnBd1mUt8+5LhOH7j8=
+github.com/sagernet/cronet-go/lib/linux_mipsle v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:RBhSUDAKWq7fswtV4nQUQhuaTLcX3ettR7teA7/yf2w=
+github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b h1:QFRWi6FucrODS4xQ8e9GYIzGSeMFO/DAMtTCVeJiCvM=
+github.com/sagernet/cronet-go/lib/linux_mipsle_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:wRzoIOGG4xbpp3Gh3triLKwMwYriScXzFtunLYhY4w0=
+github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b h1:2WJjPKZHLNIB4D17c3o9S+SP9kb3Qh0D26oWlun1+pE=
+github.com/sagernet/cronet-go/lib/linux_riscv64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:LNiZXmWil1OPwKCheqQjtakZlJuKGFz+iv2eGF76Hhs=
+github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b h1:cUNTe4gNncRpYL28jzQf6qcJej40zzGQsH0o6CLUGws=
+github.com/sagernet/cronet-go/lib/linux_riscv64_musl v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:YFDGKTkpkJGc5+hnX/RYosZyTWg9h+68VB55fYRRLYc=
+github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:+sc1LJF0FjU2hVO5xBqqT+8qzoU08J2uHwxSle2m/Hw=
+github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4=
+github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:+D/uhFxllI/KTLpeNEl8dwF3omPGmUFbrqt5tJkAyp0=
+github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc=
+github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b h1:nSUzzTUAZdqjGGckayk64sz+F0TGJPHvauTiAn27UKk=
+github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc=
+github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b h1:PE/fYBiHzB52gnQMg0soBfQyJCzmWHti48kCe2TBt9w=
+github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8=
+github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b h1:hy/3lPV11pKAAojDFnb95l9NpwOym6kME7FxS9p8sXs=
+github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20260413092954-cd09eb3e271b/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw=
github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
github.com/sagernet/gvisor v0.0.0-20250822052253-5558536cf237 h1:SUPFNB+vSP4RBPrSEgNII+HkfqC8hKMpYLodom4o4EU=
@@ -233,40 +479,61 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
-github.com/sagernet/quic-go v0.59.0-sing-box-mod.2 h1:hJUL+HtxEOjxsa0CsucbBVqI/AMS4k52NwNU637zmdw=
-github.com/sagernet/quic-go v0.59.0-sing-box-mod.2/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4=
-github.com/sagernet/sing v0.8.0-beta.16 h1:Fe+6E9VHYky9Mx4cf0ugbZPWDcXRflpAu7JQ5bWXvaA=
-github.com/sagernet/sing v0.8.0-beta.16/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
+github.com/sagernet/quic-go v0.59.0-sing-box-mod.4 h1:6qvrUW79S+CrPwWz6cMePXohgjHoKxLo3c+MDhNwc3o=
+github.com/sagernet/quic-go v0.59.0-sing-box-mod.4/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4=
+github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386 h1:gNonzIaoKi4MiEmK/5iJI+RoGof1PtYqzSaNE/lmWLw=
+github.com/sagernet/sing v0.8.7-0.20260417135631-0d22698ed386/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
+github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9 h1:wWJexq4V7ope1c4XYSqT/hydqd9omdtbDRvSZIOhjfY=
+github.com/sagernet/sing-cloudflared v0.0.0-20260416083718-efa6ab16dba9/go.mod h1:bH2NKX+NpDTY1Zkxfboxw6MXB/ZywaNLmrDJYgKMJ2Y=
github.com/sagernet/sing-mux v0.3.4 h1:ZQplKl8MNXutjzbMVtWvWG31fohhgOfCuUZR4dVQ8+s=
github.com/sagernet/sing-mux v0.3.4/go.mod h1:QvlKMyNBNrQoyX4x+gq028uPbLM2XeRpWtDsWBJbFSk=
-github.com/sagernet/sing-quic v0.6.0-beta.11 h1:eUusxITKKRedhWC2ScUYFUvD96h/QfbKLaS3N6/7in4=
-github.com/sagernet/sing-quic v0.6.0-beta.11/go.mod h1:K5bWvITOm4vE10fwLfrWpw27bCoVJ+tfQ79tOWg+Ko8=
+github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6 h1:j3ISQRDyY5rs27NzUS/le+DHR0iOO0K0x+mWDLzu4Ok=
+github.com/sagernet/sing-quic v0.6.2-0.20260412143638-8f65b6be7cd6/go.mod h1:r5Adw0EMUyhGBCjPI2JEupDtC040DrrvreXtua7Ifdc=
github.com/sagernet/sing-shadowsocks v0.2.8 h1:PURj5PRoAkqeHh2ZW205RWzN9E9RtKCVCzByXruQWfE=
github.com/sagernet/sing-shadowsocks v0.2.8/go.mod h1:lo7TWEMDcN5/h5B8S0ew+r78ZODn6SwVaFhvB6H+PTI=
github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnqqs2gQ2/Qioo=
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
-github.com/sagernet/sing-tun v0.8.0-beta.17 h1:6DdbNXeTFYj8Tb4FCh8Mp2boA3rVY6VNqzTOObj7Xis=
-github.com/sagernet/sing-tun v0.8.0-beta.17/go.mod h1:+HAK/y9GZljdT0KYKMYDR8MjjqnqDDQZYp5ZZQoRzS8=
+github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695 h1:2maqN3XuorEo5faXHIyYZQZ1/ybim4hImfCEWZwdPbk=
+github.com/sagernet/sing-tun v0.8.8-0.20260410061515-018f5eaae695/go.mod h1:pLCo4o+LacXEzz0bhwhJkKBjLlKOGPBNOAZ97ZVZWzs=
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o=
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY=
github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478=
github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8=
-github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6 h1:eYz/OpMqWCvO2++iw3dEuzrlfC2xv78GdlGvprIM6O8=
-github.com/sagernet/tailscale v1.92.4-sing-box-1.13-mod.6/go.mod h1:m87GAn4UcesHQF3leaPFEINZETO5za1LGn1GJdNDgNc=
-github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20250917110311-16510ac47288 h1:E2tZFeg9mGYGQ7E7BbxMv1cU35HxwgRm6tPKI2Pp7DA=
-github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20250917110311-16510ac47288/go.mod h1:WUxgxUDZoCF2sxVmW+STSxatP02Qn3FcafTiI2BLtE0=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
-github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
-github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507 h1:ML7ZNtcln5UBo5Wv7RIv9Xg3Pr5VuRCWLFXEwda54Y4=
+github.com/sergeyfrolov/bsbuffer v0.0.0-20180903213811-94e85abb8507/go.mod h1:DbI1gxrXI2jRGw7XGEUZQOOMd6PsnKzRrCKabvvMrwM=
+github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28=
+github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM=
+github.com/shirou/gopsutil/v4 v4.24.5 h1:gGsArG5K6vmsh5hcFOHaPm87UD003CaDMkAOweSQjhM=
+github.com/shirou/gopsutil/v4 v4.24.5/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0 h1:e5s7RKBd2rIPR0StbvZ2vTVtJ5jDTsTk5wtIIapZTRg=
+github.com/shtorm-7/dnscrypt/v2 v2.4.0-extended-1.0.0/go.mod h1:WpEFV2uhebXb8Jhes/5/fSdpmhGV8TL22RDaeWwV6hI=
+github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
+github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spyzhov/ajson v0.9.4 h1:MVibcTCgO7DY4IlskdqIlCmDOsUOZ9P7oKj8ifdcf84=
github.com/spyzhov/ajson v0.9.4/go.mod h1:a6oSw0MMb7Z5aD2tPoPO+jq11ETKgXUr2XktHdT8Wt8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
+github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e h1:PtWT87weP5LWHEY//SWsYkSO3RWRZo4OSWagh3YD2vQ=
github.com/tailscale/certstore v0.1.1-0.20231202035212-d3fa0460f47e/go.mod h1:XrBNfAFN+pwoWuksbFS9Ccxnopa15zJGgXRFN90l3K4=
github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55 h1:Gzfnfk2TWrk8Jj4P4c1a3CtQyMaTVCznlkLZI++hok4=
@@ -293,43 +560,74 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
+github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=
+github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
+github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
+github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
+github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
+github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
+github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
+github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78 h1:9sreu9e9KOihf2Y0NbpyfWhd1XFDcL4GTkPYL4IvMrg=
+github.com/wader/filtertransport v0.0.0-20200316221534-bdd9e61eee78/go.mod h1:HazXTRLhXFyq80TQp7PUXi6BKE6mS+ydEdzEqNBKopQ=
+github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
+github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xtaci/kcp-go/v5 v5.6.70 h1:AYX0QZl6PqmNj2IdYGZGuBfZuDUkUfl+eHYNijCqaO0=
+github.com/xtaci/kcp-go/v5 v5.6.70/go.mod h1:9O3D8WR+cyyUjGiTILYfg17vn72otWuXK2AFfqIe6CM=
+github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
+github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
+github.com/xtaci/smux v1.5.50 h1:y/1DlWQC9bnMeZzsyk4oL2hbLK6uVk4BKTz5BeQqUEA=
+github.com/xtaci/smux v1.5.50/go.mod h1:IGQ9QYrBphmb/4aTnLEcJby0TNr3NV+OslIOMrX825Q=
+github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
+github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
+gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0 h1:rzdY78Ox2T+VlXcxGxELF+6VyUXlZBhmRqZu5etLm+c=
+gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/goptlib v1.5.0/go.mod h1:70bhd4JKW/+1HLfm+TMrgHJsUHG4coelMWwiVEJ2gAg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM=
-go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
-go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4=
-go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
-go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
-go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
-go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
-go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
-go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
-go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
-go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
-go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
-go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
+go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
+go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
+go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
+go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
+go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
+go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
+go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
+go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
+go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
+go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
+go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
+go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
+go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
@@ -343,87 +641,185 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/W
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
-golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
-golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
+golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
+golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w=
golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
-golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
+golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
-golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
-golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
-golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
+golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
+golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
+golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
-golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
+golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
-golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
+golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
+golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
-golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
-golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
-golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
+golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
-golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
+golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
+golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10 h1:3GDAcqdIg1ozBNLgPy4SLT84nfcBjr6rhGtXYtrkWLU=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20241231184526-a9ab2273dd10/go.mod h1:T97yPqesLiNrOYxkwmhMI0ZIlJDm+p0PMR8eRVeR5tQ=
golang.zx2c4.com/wireguard/windows v0.5.3 h1:On6j2Rpn3OEMXqBq00QEDC7bWSZrPIHKIus8eIuExIE=
golang.zx2c4.com/wireguard/windows v0.5.3/go.mod h1:9TEe8TJmtwyQebdFwAkEWOPr3prrtqm+REGFifP60hI=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
-google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4=
-google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
-google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
-google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
+google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
+google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
-lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
-lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
+gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 h1:ze1vwAdliUAr68RQ5NtufWaXaOg8WUO2OACzEV+TNdE=
+gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489/go.mod h1:10sU+Uh5KKNv1+2x2A0Gvzt8FjD3ASIhorV3YsauXhk=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg=
+lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo=
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
+tailscale.com v1.58.2 h1:5trkhh/fpUn7f6TUcGUQYJ0GokdNNfNrjh9ONJhoc5A=
+tailscale.com v1.58.2/go.mod h1:faWR8XaXemnSKCDjHC7SAQzaagkUjA5x4jlLWiwxtuk=
+zombiezen.com/go/capnproto2 v2.18.2+incompatible h1:v3BD1zbruvffn7zjJUU5Pn8nZAB11bhZSQC4W+YnnKo=
+zombiezen.com/go/capnproto2 v2.18.2+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=
diff --git a/transport/awg/bind.go b/transport/awg/bind.go
new file mode 100644
index 0000000000..8c8ae68ebf
--- /dev/null
+++ b/transport/awg/bind.go
@@ -0,0 +1,181 @@
+package awg
+
+import (
+ "context"
+ "errors"
+ "net"
+ "net/netip"
+ "sync"
+ "syscall"
+
+ "github.com/amnezia-vpn/amneziawg-go/conn"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+)
+
+var _ conn.Bind = (*bind_adapter)(nil)
+
+type bind_adapter struct {
+ conn4 net.PacketConn
+ conn6 net.PacketConn
+ dialer N.Dialer
+ ctx context.Context
+ mutex sync.Mutex
+}
+
+func newBind(ctx context.Context, dial N.Dialer) conn.Bind {
+ return &bind_adapter{
+ ctx: ctx,
+ dialer: dial,
+ }
+}
+
+func (b *bind_adapter) connect(addr netip.Addr, port uint16) (net.PacketConn, error) {
+ return b.dialer.ListenPacket(b.ctx, M.Socksaddr{Addr: addr, Port: port})
+}
+
+func (b *bind_adapter) receive(c net.PacketConn) conn.ReceiveFunc {
+ return func(packets [][]byte, sizes []int, eps []conn.Endpoint) (n int, err error) {
+ n, addr, err := c.ReadFrom(packets[0])
+ if err != nil {
+ return 0, E.Cause(err, "read data")
+ }
+
+ bindEp, err := b.ParseEndpoint(addr.String())
+ if err != nil {
+ return 0, E.Cause(err, "parse endpoint")
+ }
+
+ sizes[0] = n
+ eps[0] = bindEp
+ return 1, nil
+ }
+}
+
+func (b *bind_adapter) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+
+ if b.conn4 != nil || b.conn6 != nil {
+ return nil, 0, conn.ErrBindAlreadyOpen
+ }
+
+ conn4, err := b.connect(netip.IPv4Unspecified(), port)
+ if err != nil && !errors.Is(err, syscall.EAFNOSUPPORT) {
+ return nil, 0, E.Cause(err, "create ipv4 connection")
+ }
+ if conn4 != nil {
+ fns = append(fns, b.receive(conn4))
+ }
+
+ conn6, err := b.connect(netip.IPv6Unspecified(), port)
+ if err != nil && !errors.Is(err, syscall.EAFNOSUPPORT) {
+ return nil, 0, E.Cause(err, "create ipv6 connection")
+ }
+ if conn6 != nil {
+ fns = append(fns, b.receive(conn6))
+ }
+
+ b.conn4 = conn4
+ b.conn6 = conn6
+
+ return fns, port, nil
+}
+
+func (b *bind_adapter) Close() error {
+ b.mutex.Lock()
+ defer b.mutex.Unlock()
+
+ var err4, err6 error
+
+ if b.conn4 != nil {
+ err4 = b.conn4.Close()
+ b.conn4 = nil
+ }
+
+ if b.conn6 != nil {
+ err6 = b.conn6.Close()
+ b.conn6 = nil
+ }
+
+ return errors.Join(err4, err6)
+}
+
+func (b *bind_adapter) SetMark(mark uint32) error {
+ return nil
+}
+
+func (b *bind_adapter) Send(bufs [][]byte, ep conn.Endpoint) error {
+ var conn net.PacketConn
+ if ep.DstIP().Is6() {
+ conn = b.conn6
+ } else {
+ conn = b.conn4
+ }
+
+ if conn == nil {
+ return errors.ErrUnsupported
+ }
+
+ bindEp, ok := ep.(*bind_endpoint)
+ if !ok {
+ return errors.ErrUnsupported
+ }
+
+ udpAddr := &net.UDPAddr{
+ IP: bindEp.AddrPort.Addr().AsSlice(),
+ Port: int(bindEp.AddrPort.Port()),
+ }
+
+ for _, buf := range bufs {
+ if _, err := conn.WriteTo(buf, udpAddr); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (b *bind_adapter) ParseEndpoint(s string) (conn.Endpoint, error) {
+ ap, err := netip.ParseAddrPort(s)
+ if err != nil {
+ return nil, E.Cause(err, "parse addrport")
+ }
+
+ return &bind_endpoint{AddrPort: ap}, nil
+}
+
+func (b *bind_adapter) BatchSize() int {
+ return 1
+}
+
+var _ conn.Endpoint = (*bind_endpoint)(nil)
+
+type bind_endpoint struct {
+ AddrPort netip.AddrPort
+}
+
+func (e bind_endpoint) ClearSrc() {
+}
+
+func (e bind_endpoint) SrcToString() string {
+ return ""
+}
+
+func (e bind_endpoint) DstToString() string {
+ return e.AddrPort.String()
+}
+
+func (e bind_endpoint) DstToBytes() []byte {
+ b, _ := e.AddrPort.MarshalBinary()
+ return b
+}
+
+func (e bind_endpoint) DstIP() netip.Addr {
+ return e.AddrPort.Addr()
+}
+
+func (e bind_endpoint) SrcIP() netip.Addr {
+ return netip.Addr{}
+}
diff --git a/transport/awg/device.go b/transport/awg/device.go
new file mode 100644
index 0000000000..16101cdc0b
--- /dev/null
+++ b/transport/awg/device.go
@@ -0,0 +1,109 @@
+package awg
+
+import (
+ "context"
+ "fmt"
+ "net"
+ "net/netip"
+ "strings"
+
+ "github.com/amnezia-vpn/amneziawg-go/conn"
+ "github.com/amnezia-vpn/amneziawg-go/device"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/exceptions"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ "github.com/sagernet/sing/common/metadata"
+ "github.com/sagernet/sing/common/network"
+)
+
+type DeviceOpts struct {
+ UseIntegratedTun bool
+ Address []netip.Prefix
+ AllowedIps []netip.Prefix
+ ExcludedIps []netip.Prefix
+ MTU uint32
+}
+
+type Device struct {
+ awgDevice *device.Device
+ tun tunAdapter
+ bind conn.Bind
+ logger *device.Logger
+ ipcConfig string
+}
+
+func NewDevice(ctx context.Context, logger logger.ContextLogger, dial network.Dialer, ipcConfig string, opts DeviceOpts) (*Device, error) {
+ var (
+ tun tunAdapter
+ err error
+ )
+
+ if opts.UseIntegratedTun {
+ tun, err = newSystemTun(ctx, opts.Address, opts.AllowedIps, opts.ExcludedIps, opts.MTU, logger)
+ if err != nil {
+ return nil, exceptions.Cause(err, "create tunnel")
+ }
+ } else {
+ tun, err = newNetworkTun(opts.Address, opts.MTU)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ awgLogger := &device.Logger{
+ Verbosef: func(format string, args ...interface{}) {
+ logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
+ },
+ Errorf: func(format string, args ...interface{}) {
+ logger.Error(fmt.Sprintf(strings.ToLower(format), args...))
+ },
+ }
+
+ return &Device{
+ tun: tun,
+ bind: newBind(ctx, dial),
+ logger: awgLogger,
+ ipcConfig: ipcConfig,
+ }, nil
+}
+
+func (d *Device) Start(stage adapter.StartStage) error {
+ if stage != adapter.StartStateStart {
+ return nil
+ }
+
+ d.awgDevice = device.NewDevice(d.tun, d.bind, d.logger)
+ if err := d.awgDevice.IpcSet(d.ipcConfig); err != nil {
+ return E.Cause(err, "set ipc config")
+ }
+
+ if err := d.tun.Start(); err != nil {
+ return E.Cause(err, "tun start")
+ }
+
+ return d.awgDevice.Up()
+}
+
+func (d *Device) IsUnderLoad() bool {
+ if d.awgDevice == nil {
+ return false
+ }
+ return d.awgDevice.IsUnderLoad()
+}
+
+func (d *Device) Close() error {
+ if d.awgDevice != nil {
+ d.awgDevice.Close()
+ }
+ return nil
+}
+
+func (d *Device) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) {
+ return d.tun.DialContext(ctx, network, destination)
+}
+
+func (d *Device) ListenPacket(ctx context.Context, destination metadata.Socksaddr) (net.PacketConn, error) {
+ return d.tun.ListenPacket(ctx, destination)
+}
\ No newline at end of file
diff --git a/transport/awg/tun.go b/transport/awg/tun.go
new file mode 100644
index 0000000000..a03c8455d5
--- /dev/null
+++ b/transport/awg/tun.go
@@ -0,0 +1,13 @@
+package awg
+
+import (
+ awgTun "github.com/amnezia-vpn/amneziawg-go/tun"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing/common/network"
+)
+
+type tunAdapter interface {
+ network.Dialer
+ awgTun.Device
+ adapter.SimpleLifecycle
+}
diff --git a/transport/awg/tun_network.go b/transport/awg/tun_network.go
new file mode 100644
index 0000000000..e2cf85756e
--- /dev/null
+++ b/transport/awg/tun_network.go
@@ -0,0 +1,45 @@
+package awg
+
+import (
+ "context"
+ "net"
+ "net/netip"
+
+ "github.com/amnezia-vpn/amneziawg-go/tun"
+ "github.com/amnezia-vpn/amneziawg-go/tun/netstack"
+ "github.com/sagernet/sing/common/metadata"
+)
+
+type networkTun struct {
+ tun.Device
+ conn *netstack.Net
+}
+
+func newNetworkTun(address []netip.Prefix, mtu uint32) (tunAdapter, error) {
+ var localAddresses []netip.Addr
+ for _, prefix := range address {
+ localAddresses = append(localAddresses, prefix.Addr())
+ }
+
+ tun, conn, err := netstack.CreateNetTUN(localAddresses, []netip.Addr{}, int(mtu))
+ if err != nil {
+ return nil, err
+ }
+
+ return &networkTun{
+ Device: tun,
+ conn: conn,
+ }, nil
+}
+
+func (t *networkTun) Start() error {
+ return nil
+}
+
+func (t *networkTun) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) {
+ return t.conn.DialContext(ctx, network, destination.String())
+}
+
+func (t *networkTun) ListenPacket(ctx context.Context, destination metadata.Socksaddr) (net.PacketConn, error) {
+ return t.conn.DialUDPAddrPort(netip.AddrPort{}, destination.AddrPort())
+}
diff --git a/transport/awg/tun_system.go b/transport/awg/tun_system.go
new file mode 100644
index 0000000000..c924d91696
--- /dev/null
+++ b/transport/awg/tun_system.go
@@ -0,0 +1,143 @@
+package awg
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "os"
+
+ awgTun "github.com/amnezia-vpn/amneziawg-go/tun"
+
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/dialer"
+ "github.com/sagernet/sing-box/option"
+ tun "github.com/sagernet/sing-tun"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ "github.com/sagernet/sing/common/metadata"
+ "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/service"
+)
+
+type systemTun struct {
+ mtu uint32
+ singtun tun.Tun
+ events chan awgTun.Event
+ name string
+ dialer network.Dialer
+}
+
+func newSystemTun(ctx context.Context, address []netip.Prefix, allowedIps []netip.Prefix, excludedIps []netip.Prefix, mtu uint32, logger logger.Logger) (tunAdapter, error) {
+ networkManager := service.FromContext[adapter.NetworkManager](ctx)
+ name := tun.CalculateInterfaceName("")
+ events := make(chan awgTun.Event)
+
+ dial, err := dialer.NewDefault(ctx, option.DialerOptions{
+ BindInterface: name,
+ })
+ if err != nil {
+ return nil, exceptions.Cause(err, "get in-tunnel dialer")
+ }
+
+ singtun, err := tun.New(tun.Options{
+ Name: name,
+ GSO: true,
+ MTU: uint32(mtu),
+ Inet4Address: common.Filter(address, func(it netip.Prefix) bool {
+ return it.Addr().Is4()
+ }),
+ Inet6Address: common.Filter(address, func(it netip.Prefix) bool {
+ return it.Addr().Is6()
+ }),
+ InterfaceMonitor: networkManager.InterfaceMonitor(),
+ InterfaceFinder: networkManager.InterfaceFinder(),
+ Inet4RouteAddress: common.Filter(allowedIps, func(it netip.Prefix) bool {
+ return it.Addr().Is4()
+ }),
+ Inet6RouteAddress: common.Filter(allowedIps, func(it netip.Prefix) bool {
+ return it.Addr().Is6()
+ }),
+ Inet4RouteExcludeAddress: common.Filter(excludedIps, func(it netip.Prefix) bool {
+ return it.Addr().Is4()
+ }),
+ Inet6RouteExcludeAddress: common.Filter(excludedIps, func(it netip.Prefix) bool {
+ return it.Addr().Is6()
+ }),
+ Logger: logger,
+ })
+ if err != nil {
+ return nil, exceptions.Cause(err, "create tunnel")
+ }
+
+ return &systemTun{
+ mtu: mtu,
+ events: events,
+ singtun: singtun,
+ name: name,
+ dialer: dial,
+ }, nil
+}
+
+func (t *systemTun) Start() error {
+ if err := t.singtun.Start(); err != nil {
+ return exceptions.Cause(err, "start tunnel")
+ }
+
+ t.events <- awgTun.EventUp
+ return nil
+}
+
+func (t *systemTun) File() *os.File {
+ return nil
+}
+
+func (t *systemTun) Read(bufs [][]byte, sizes []int, offset int) (int, error) {
+ n, err := t.singtun.Read(bufs[0][offset-tun.PacketOffset:])
+ if err != nil {
+ return 0, err
+ }
+ sizes[0] = n
+ return 1, nil
+}
+
+func (t *systemTun) Write(bufs [][]byte, offset int) (int, error) {
+ for _, buf := range bufs {
+ common.ClearArray(buf[offset-tun.PacketOffset : offset])
+ tun.PacketFillHeader(buf[offset-tun.PacketOffset:], tun.PacketIPVersion(buf[offset:]))
+
+ if _, err := t.singtun.Write(buf[offset-tun.PacketOffset:]); err != nil {
+ return 0, err
+ }
+ }
+ return len(bufs), nil
+}
+
+func (t *systemTun) MTU() (int, error) {
+ return int(t.mtu), nil
+}
+
+func (t *systemTun) Name() (string, error) {
+ return t.name, nil
+}
+
+func (t *systemTun) Events() <-chan awgTun.Event {
+ return t.events
+}
+
+func (t *systemTun) Close() error {
+ close(t.events)
+ return nil
+}
+
+func (t *systemTun) BatchSize() int {
+ return 1
+}
+
+func (t *systemTun) DialContext(ctx context.Context, network string, destination metadata.Socksaddr) (net.Conn, error) {
+ return t.dialer.DialContext(ctx, network, destination)
+}
+
+func (t *systemTun) ListenPacket(ctx context.Context, destination metadata.Socksaddr) (net.PacketConn, error) {
+ return t.dialer.ListenPacket(ctx, destination)
+}
diff --git a/transport/masque/adapter.go b/transport/masque/adapter.go
new file mode 100644
index 0000000000..f72748f7e2
--- /dev/null
+++ b/transport/masque/adapter.go
@@ -0,0 +1,82 @@
+package masque
+
+import (
+ "sync"
+
+ "github.com/sagernet/wireguard-go/tun"
+ "github.com/songgao/water"
+)
+
+type NetstackAdapter struct {
+ dev tun.Device
+ tunnelBufPool sync.Pool
+ tunnelSizesPool sync.Pool
+}
+
+func (n *NetstackAdapter) ReadPacket(buf []byte) (int, error) {
+ packetBufsPtr := n.tunnelBufPool.Get().(*[][]byte)
+ sizesPtr := n.tunnelSizesPool.Get().(*[]int)
+
+ defer func() {
+ (*packetBufsPtr)[0] = nil
+ n.tunnelBufPool.Put(packetBufsPtr)
+ n.tunnelSizesPool.Put(sizesPtr)
+ }()
+
+ (*packetBufsPtr)[0] = buf
+ (*sizesPtr)[0] = 0
+
+ _, err := n.dev.Read(*packetBufsPtr, *sizesPtr, 0)
+ if err != nil {
+ return 0, err
+ }
+
+ return (*sizesPtr)[0], nil
+}
+
+func (n *NetstackAdapter) WritePacket(pkt []byte) error {
+ // Write expects a slice of packet buffers.
+ _, err := n.dev.Write([][]byte{pkt}, 0)
+ return err
+}
+
+// NewNetstackAdapter creates a new NetstackAdapter.
+func NewNetstackAdapter(dev tun.Device) TunnelDevice {
+ return &NetstackAdapter{
+ dev: dev,
+ tunnelBufPool: sync.Pool{
+ New: func() interface{} {
+ buf := make([][]byte, 1)
+ return &buf
+ },
+ },
+ tunnelSizesPool: sync.Pool{
+ New: func() interface{} {
+ sizes := make([]int, 1)
+ return &sizes
+ },
+ },
+ }
+}
+
+type WaterAdapter struct {
+ iface *water.Interface
+}
+
+func (w *WaterAdapter) ReadPacket(buf []byte) (int, error) {
+ n, err := w.iface.Read(buf)
+ if err != nil {
+ return 0, err
+ }
+
+ return n, nil
+}
+
+func (w *WaterAdapter) WritePacket(pkt []byte) error {
+ _, err := w.iface.Write(pkt)
+ return err
+}
+
+func NewWaterAdapter(iface *water.Interface) TunnelDevice {
+ return &WaterAdapter{iface: iface}
+}
diff --git a/transport/masque/device.go b/transport/masque/device.go
new file mode 100644
index 0000000000..d6f7159776
--- /dev/null
+++ b/transport/masque/device.go
@@ -0,0 +1,33 @@
+package masque
+
+import (
+ "context"
+ "net/netip"
+ "time"
+
+ "github.com/sagernet/sing-tun"
+ "github.com/sagernet/sing/common/logger"
+ N "github.com/sagernet/sing/common/network"
+ wgTun "github.com/sagernet/wireguard-go/tun"
+)
+
+type Device interface {
+ wgTun.Device
+ N.Dialer
+ Start() error
+}
+
+type DeviceOptions struct {
+ Context context.Context
+ Logger logger.ContextLogger
+ Handler tun.Handler
+ UDPTimeout time.Duration
+ CreateDialer func(interfaceName string) N.Dialer
+ Name string
+ MTU uint32
+ Address []netip.Prefix
+}
+
+func NewDevice(options DeviceOptions) (Device, error) {
+ return newStackDevice(options)
+}
diff --git a/transport/masque/device_stack.go b/transport/masque/device_stack.go
new file mode 100644
index 0000000000..0d926dcaac
--- /dev/null
+++ b/transport/masque/device_stack.go
@@ -0,0 +1,309 @@
+//go:build with_gvisor
+
+package masque
+
+import (
+ "context"
+ "net"
+ "net/netip"
+ "os"
+
+ "github.com/sagernet/gvisor/pkg/buffer"
+ "github.com/sagernet/gvisor/pkg/tcpip"
+ "github.com/sagernet/gvisor/pkg/tcpip/adapters/gonet"
+ "github.com/sagernet/gvisor/pkg/tcpip/header"
+ "github.com/sagernet/gvisor/pkg/tcpip/network/ipv4"
+ "github.com/sagernet/gvisor/pkg/tcpip/network/ipv6"
+ "github.com/sagernet/gvisor/pkg/tcpip/stack"
+ "github.com/sagernet/gvisor/pkg/tcpip/transport/icmp"
+ "github.com/sagernet/gvisor/pkg/tcpip/transport/tcp"
+ "github.com/sagernet/gvisor/pkg/tcpip/transport/udp"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/transport/wireguard"
+ "github.com/sagernet/sing-tun"
+ "github.com/sagernet/sing/common/buf"
+ E "github.com/sagernet/sing/common/exceptions"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ wgTun "github.com/sagernet/wireguard-go/tun"
+)
+
+type stackDevice struct {
+ ctx context.Context
+ logger log.ContextLogger
+ stack *stack.Stack
+ mtu uint32
+ events chan wgTun.Event
+ wgTun.Device
+ outbound chan *stack.PacketBuffer
+ packetOutbound chan *buf.Buffer
+ done chan struct{}
+ dispatcher stack.NetworkDispatcher
+ inet4Address netip.Addr
+ inet6Address netip.Addr
+}
+
+func newStackDevice(options DeviceOptions) (*stackDevice, error) {
+ tunDevice := &stackDevice{
+ ctx: options.Context,
+ logger: options.Logger,
+ mtu: options.MTU,
+ events: make(chan wgTun.Event, 1),
+ outbound: make(chan *stack.PacketBuffer, 256),
+ packetOutbound: make(chan *buf.Buffer, 256),
+ done: make(chan struct{}),
+ }
+ ipStack, err := tun.NewGVisorStackWithOptions((*wireEndpoint)(tunDevice), stack.NICOptions{}, true)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ inet4Address netip.Addr
+ inet6Address netip.Addr
+ )
+ for _, prefix := range options.Address {
+ addr := tun.AddressFromAddr(prefix.Addr())
+ protoAddr := tcpip.ProtocolAddress{
+ AddressWithPrefix: tcpip.AddressWithPrefix{
+ Address: addr,
+ PrefixLen: prefix.Bits(),
+ },
+ }
+ if prefix.Addr().Is4() {
+ inet4Address = prefix.Addr()
+ tunDevice.inet4Address = inet4Address
+ protoAddr.Protocol = ipv4.ProtocolNumber
+ } else {
+ inet6Address = prefix.Addr()
+ tunDevice.inet6Address = inet6Address
+ protoAddr.Protocol = ipv6.ProtocolNumber
+ }
+ gErr := ipStack.AddProtocolAddress(tun.DefaultNIC, protoAddr, stack.AddressProperties{})
+ if gErr != nil {
+ return nil, E.New("parse local address ", protoAddr.AddressWithPrefix, ": ", gErr.String())
+ }
+ }
+ tunDevice.stack = ipStack
+ if options.Handler != nil {
+ ipStack.SetTransportProtocolHandler(tcp.ProtocolNumber, tun.NewTCPForwarder(options.Context, ipStack, options.Handler).HandlePacket)
+ ipStack.SetTransportProtocolHandler(udp.ProtocolNumber, tun.NewUDPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout).HandlePacket)
+ icmpForwarder := tun.NewICMPForwarder(options.Context, ipStack, options.Handler, options.UDPTimeout)
+ ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber4, icmpForwarder.HandlePacket)
+ ipStack.SetTransportProtocolHandler(icmp.ProtocolNumber6, icmpForwarder.HandlePacket)
+ }
+ return tunDevice, nil
+}
+
+func (w *stackDevice) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ addr := tcpip.FullAddress{
+ NIC: tun.DefaultNIC,
+ Port: destination.Port,
+ Addr: tun.AddressFromAddr(destination.Addr),
+ }
+ bind := tcpip.FullAddress{
+ NIC: tun.DefaultNIC,
+ }
+ var networkProtocol tcpip.NetworkProtocolNumber
+ if destination.IsIPv4() {
+ if !w.inet4Address.IsValid() {
+ return nil, E.New("missing IPv4 local address")
+ }
+ networkProtocol = header.IPv4ProtocolNumber
+ bind.Addr = tun.AddressFromAddr(w.inet4Address)
+ } else {
+ if !w.inet6Address.IsValid() {
+ return nil, E.New("missing IPv6 local address")
+ }
+ networkProtocol = header.IPv6ProtocolNumber
+ bind.Addr = tun.AddressFromAddr(w.inet6Address)
+ }
+ switch N.NetworkName(network) {
+ case N.NetworkTCP:
+ tcpConn, err := wireguard.DialTCPWithBind(ctx, w.stack, bind, addr, networkProtocol)
+ if err != nil {
+ return nil, err
+ }
+ return tcpConn, nil
+ case N.NetworkUDP:
+ udpConn, err := gonet.DialUDP(w.stack, &bind, &addr, networkProtocol)
+ if err != nil {
+ return nil, err
+ }
+ return udpConn, nil
+ default:
+ return nil, E.Extend(N.ErrUnknownNetwork, network)
+ }
+}
+
+func (w *stackDevice) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ bind := tcpip.FullAddress{
+ NIC: tun.DefaultNIC,
+ }
+ var networkProtocol tcpip.NetworkProtocolNumber
+ if destination.IsIPv4() {
+ networkProtocol = header.IPv4ProtocolNumber
+ bind.Addr = tun.AddressFromAddr(w.inet4Address)
+ } else {
+ networkProtocol = header.IPv6ProtocolNumber
+ bind.Addr = tun.AddressFromAddr(w.inet4Address)
+ }
+ udpConn, err := gonet.DialUDP(w.stack, &bind, nil, networkProtocol)
+ if err != nil {
+ return nil, err
+ }
+ return udpConn, nil
+}
+
+func (w *stackDevice) Start() error {
+ w.events <- wgTun.EventUp
+ return nil
+}
+
+func (w *stackDevice) File() *os.File {
+ return nil
+}
+
+func (w *stackDevice) Read(bufs [][]byte, sizes []int, offset int) (count int, err error) {
+ select {
+ case packet, ok := <-w.outbound:
+ if !ok {
+ return 0, os.ErrClosed
+ }
+ defer packet.DecRef()
+ var copyN int
+ /*rangeIterate(packet.Data().AsRange(), func(view *buffer.View) {
+ copyN += copy(bufs[0][offset+copyN:], view.AsSlice())
+ })*/
+ for _, view := range packet.AsSlices() {
+ copyN += copy(bufs[0][offset+copyN:], view)
+ }
+ sizes[0] = copyN
+ return 1, nil
+ case packet := <-w.packetOutbound:
+ defer packet.Release()
+ sizes[0] = copy(bufs[0][offset:], packet.Bytes())
+ return 1, nil
+ case <-w.done:
+ return 0, os.ErrClosed
+ }
+}
+
+func (w *stackDevice) Write(bufs [][]byte, offset int) (count int, err error) {
+ for _, b := range bufs {
+ b = b[offset:]
+ if len(b) == 0 {
+ continue
+ }
+ var networkProtocol tcpip.NetworkProtocolNumber
+ switch header.IPVersion(b) {
+ case header.IPv4Version:
+ networkProtocol = header.IPv4ProtocolNumber
+ case header.IPv6Version:
+ networkProtocol = header.IPv6ProtocolNumber
+ }
+ packetBuffer := stack.NewPacketBuffer(stack.PacketBufferOptions{
+ Payload: buffer.MakeWithData(b),
+ })
+ w.dispatcher.DeliverNetworkPacket(networkProtocol, packetBuffer)
+ packetBuffer.DecRef()
+ count++
+ }
+ return
+}
+
+func (w *stackDevice) Flush() error {
+ return nil
+}
+
+func (w *stackDevice) MTU() (int, error) {
+ return int(w.mtu), nil
+}
+
+func (w *stackDevice) Name() (string, error) {
+ return "sing-box", nil
+}
+
+func (w *stackDevice) Events() <-chan wgTun.Event {
+ return w.events
+}
+
+func (w *stackDevice) Close() error {
+ close(w.done)
+ close(w.events)
+ w.stack.Close()
+ for _, endpoint := range w.stack.CleanupEndpoints() {
+ endpoint.Abort()
+ }
+ w.stack.Wait()
+ return nil
+}
+
+func (w *stackDevice) BatchSize() int {
+ return 1
+}
+
+var _ stack.LinkEndpoint = (*wireEndpoint)(nil)
+
+type wireEndpoint stackDevice
+
+func (ep *wireEndpoint) MTU() uint32 {
+ return ep.mtu
+}
+
+func (ep *wireEndpoint) SetMTU(mtu uint32) {
+}
+
+func (ep *wireEndpoint) MaxHeaderLength() uint16 {
+ return 0
+}
+
+func (ep *wireEndpoint) LinkAddress() tcpip.LinkAddress {
+ return ""
+}
+
+func (ep *wireEndpoint) SetLinkAddress(addr tcpip.LinkAddress) {
+}
+
+func (ep *wireEndpoint) Capabilities() stack.LinkEndpointCapabilities {
+ return stack.CapabilityRXChecksumOffload
+}
+
+func (ep *wireEndpoint) Attach(dispatcher stack.NetworkDispatcher) {
+ ep.dispatcher = dispatcher
+}
+
+func (ep *wireEndpoint) IsAttached() bool {
+ return ep.dispatcher != nil
+}
+
+func (ep *wireEndpoint) Wait() {
+}
+
+func (ep *wireEndpoint) ARPHardwareType() header.ARPHardwareType {
+ return header.ARPHardwareNone
+}
+
+func (ep *wireEndpoint) AddHeader(buffer *stack.PacketBuffer) {
+}
+
+func (ep *wireEndpoint) ParseHeader(ptr *stack.PacketBuffer) bool {
+ return true
+}
+
+func (ep *wireEndpoint) WritePackets(list stack.PacketBufferList) (int, tcpip.Error) {
+ for _, packetBuffer := range list.AsSlice() {
+ packetBuffer.IncRef()
+ select {
+ case <-ep.done:
+ return 0, &tcpip.ErrClosedForSend{}
+ case ep.outbound <- packetBuffer:
+ }
+ }
+ return list.Len(), nil
+}
+
+func (ep *wireEndpoint) Close() {
+}
+
+func (ep *wireEndpoint) SetOnCloseAction(f func()) {
+}
diff --git a/transport/masque/device_stack_stub.go b/transport/masque/device_stack_stub.go
new file mode 100644
index 0000000000..476a1f58d3
--- /dev/null
+++ b/transport/masque/device_stack_stub.go
@@ -0,0 +1,13 @@
+//go:build !with_gvisor
+
+package masque
+
+import "github.com/sagernet/sing-tun"
+
+func newStackDevice(options DeviceOptions) (Device, error) {
+ return nil, tun.ErrGVisorNotIncluded
+}
+
+func newSystemStackDevice(options DeviceOptions) (Device, error) {
+ return nil, tun.ErrGVisorNotIncluded
+}
diff --git a/transport/masque/masque.go b/transport/masque/masque.go
new file mode 100644
index 0000000000..477eb9d4a8
--- /dev/null
+++ b/transport/masque/masque.go
@@ -0,0 +1,142 @@
+package masque
+
+import (
+ "context"
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "net"
+ "net/http"
+ "net/netip"
+ "strings"
+
+ connectip "github.com/Diniboy1123/connect-ip-go"
+ "github.com/sagernet/quic-go"
+ "github.com/sagernet/quic-go/http3"
+ qtls "github.com/sagernet/sing-quic"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ aTLS "github.com/sagernet/sing/common/tls"
+ "github.com/yosida95/uritemplate/v3"
+ "golang.org/x/net/http2"
+)
+
+type (
+ DialContext func(ctx context.Context, network, address string) (net.Conn, error)
+ ListenPacket func(network string, address string) (net.PacketConn, error)
+)
+
+func ConnectTunnel(ctx context.Context, dialer N.Dialer, tlsConfig aTLS.Config, quicConfig *quic.Config, connectUri string, endpoint net.Addr, useHTTP2 bool) (net.PacketConn, *http3.Transport, *connectip.Conn, *http.Response, error) {
+ template := uritemplate.MustNew(connectUri)
+ additionalHeaders := http.Header{
+ "User-Agent": []string{""},
+ }
+ if useHTTP2 {
+ h2Endpoint, ok := endpoint.(*net.TCPAddr)
+ if !ok || h2Endpoint == nil {
+ return nil, nil, nil, nil, errors.New("missing HTTP/2 TCP endpoint")
+ }
+ h2Headers := additionalHeaders.Clone()
+ h2Headers.Set("cf-connect-proto", "cf-connect-ip")
+ h2Headers.Set("pq-enabled", "false")
+ h2Client, err := newHTTP2Client(dialer, tlsConfig, h2Endpoint, connectUri)
+ if err != nil {
+ return nil, nil, nil, nil, fmt.Errorf("failed to create HTTP/2 client: %w", err)
+ }
+ ipConn, rsp, err := connectip.DialH2(ctx, h2Client, template, h2Headers)
+ if err != nil {
+ if strings.Contains(err.Error(), "tls: access denied") {
+ return nil, nil, nil, nil, errors.New("login failed! Please double-check if your tls key and cert is enrolled in the Cloudflare Access service")
+ }
+ return nil, nil, nil, nil, fmt.Errorf("failed to dial connect-ip over HTTP/2: %w", err)
+ }
+ return nil, nil, ipConn, rsp, nil
+ }
+ quicEndpoint, ok := endpoint.(*net.UDPAddr)
+ if !ok || quicEndpoint == nil {
+ return nil, nil, nil, nil, errors.New("missing HTTP/3 UDP endpoint")
+ }
+ udpConn, err := dialer.ListenPacket(ctx, M.SocksaddrFromNetIP(quicEndpoint.AddrPort()))
+ if err != nil {
+ return nil, nil, nil, nil, err
+ }
+ conn, err := qtls.Dial(
+ ctx,
+ udpConn,
+ quicEndpoint,
+ tlsConfig,
+ quicConfig,
+ )
+ if err != nil {
+ return nil, nil, nil, nil, err
+ }
+ tr := &http3.Transport{
+ EnableDatagrams: true,
+ AdditionalSettings: map[uint64]uint64{
+ // official client still sends this out as well, even though
+ // it's deprecated, see https://datatracker.ietf.org/doc/draft-ietf-masque-h3-datagram/00/
+ // SETTINGS_H3_DATAGRAM_00 = 0x0000000000000276
+ // https://github.com/cloudflare/quiche/blob/7c66757dbc55b8d0c3653d4b345c6785a181f0b7/quiche/src/h3/frame.rs#L46
+ 0x276: 1,
+ },
+ DisableCompression: true,
+ }
+ hconn := tr.NewClientConn(conn)
+ ipConn, rsp, err := connectip.Dial(ctx, hconn, template, "cf-connect-ip", additionalHeaders, true)
+ if err != nil {
+ _ = tr.Close()
+ _ = conn.CloseWithError(0, "connect-ip dial failed")
+ if strings.Contains(err.Error(), "tls: access denied") {
+ return udpConn, nil, nil, nil, errors.New("login failed! Please double-check if your tls key and cert is enrolled in the Cloudflare Access service")
+ }
+ return udpConn, nil, nil, nil, fmt.Errorf("failed to dial connect-ip: %w", err)
+ }
+ err = ipConn.AdvertiseRoute(ctx, []connectip.IPRoute{
+ {
+ IPProtocol: 0,
+ StartIP: netip.AddrFrom4([4]byte{}),
+ EndIP: netip.AddrFrom4([4]byte{255, 255, 255, 255}),
+ },
+ {
+ IPProtocol: 0,
+ StartIP: netip.AddrFrom16([16]byte{}),
+ EndIP: netip.AddrFrom16([16]byte{
+ 255, 255, 255, 255,
+ 255, 255, 255, 255,
+ 255, 255, 255, 255,
+ 255, 255, 255, 255,
+ }),
+ },
+ })
+ if err != nil {
+ return udpConn, nil, nil, nil, err
+ }
+ return udpConn, tr, ipConn, rsp, nil
+}
+
+func newHTTP2Client(dialer N.Dialer, baseTLSConfig aTLS.Config, endpoint *net.TCPAddr, connectURI string) (*http.Client, error) {
+ if endpoint == nil {
+ return nil, errors.New("missing HTTP/2 endpoint")
+ }
+ tlsConfig := baseTLSConfig.Clone()
+ tlsConfig.SetNextProtos([]string{"h2"})
+ return &http.Client{
+ Transport: &http2.Transport{
+ DialTLSContext: func(ctx context.Context, network, _ string, _ *tls.Config) (net.Conn, error) {
+ conn, err := dialer.DialContext(ctx, network, M.SocksaddrFromNetIP(endpoint.AddrPort()))
+ if err != nil {
+ return nil, err
+ }
+ tlsConn, err := tlsConfig.Client(conn)
+ if err != nil {
+ return nil, err
+ }
+ if err := tlsConn.HandshakeContext(ctx); err != nil {
+ _ = conn.Close()
+ return nil, err
+ }
+ return tlsConn, nil
+ },
+ },
+ }, nil
+}
diff --git a/transport/masque/options.go b/transport/masque/options.go
new file mode 100644
index 0000000000..b272243615
--- /dev/null
+++ b/transport/masque/options.go
@@ -0,0 +1,24 @@
+package masque
+
+import (
+ "net"
+ "net/netip"
+ "time"
+
+ tun "github.com/sagernet/sing-tun"
+ N "github.com/sagernet/sing/common/network"
+ "github.com/sagernet/sing/common/tls"
+)
+
+type TunnelOptions struct {
+ Handler tun.Handler
+ Dialer N.Dialer
+ Address []netip.Prefix
+ Endpoint net.Addr
+ TLSConfig tls.Config
+ UseHTTP2 bool
+ UDPTimeout time.Duration
+ UDPKeepalivePeriod time.Duration
+ UDPInitialPacketSize uint16
+ ReconnectDelay time.Duration
+}
diff --git a/transport/masque/tunnel.go b/transport/masque/tunnel.go
new file mode 100644
index 0000000000..f76e459971
--- /dev/null
+++ b/transport/masque/tunnel.go
@@ -0,0 +1,235 @@
+package masque
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "sync"
+ "time"
+
+ connectip "github.com/Diniboy1123/connect-ip-go"
+ "github.com/sagernet/quic-go/http3"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+)
+
+type TunnelDevice interface {
+ ReadPacket(buf []byte) (int, error)
+ WritePacket(pkt []byte) error
+}
+
+type Tunnel struct {
+ ctx context.Context
+ logger logger.ContextLogger
+ options TunnelOptions
+ tunDevice Device
+ tunnelDevice TunnelDevice
+
+ udpConn net.PacketConn
+ tr *http3.Transport
+ ipConn *connectip.Conn
+
+ mtx sync.Mutex
+}
+
+func NewTunnel(ctx context.Context, logger logger.ContextLogger, options TunnelOptions) (*Tunnel, error) {
+ deviceOptions := DeviceOptions{
+ Context: ctx,
+ Logger: logger,
+ Handler: options.Handler,
+ UDPTimeout: options.UDPTimeout,
+ MTU: 1280,
+ Address: options.Address,
+ }
+ tunDevice, err := NewDevice(deviceOptions)
+ if err != nil {
+ return nil, E.Cause(err, "create MASQUE device")
+ }
+ return &Tunnel{
+ ctx: ctx,
+ logger: logger,
+ options: options,
+ tunDevice: tunDevice,
+ tunnelDevice: NewNetstackAdapter(tunDevice),
+ }, nil
+}
+
+func (e *Tunnel) Start(resolve bool) error {
+ if resolve {
+ err := e.tunDevice.Start()
+ if err != nil {
+ return err
+ }
+ go e.maintainTunnel()
+ }
+ return nil
+}
+
+func (e *Tunnel) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
+ if !destination.Addr.IsValid() {
+ return nil, E.Cause(os.ErrInvalid, "invalid non-IP destination")
+ }
+ return e.tunDevice.DialContext(ctx, network, destination)
+}
+
+func (e *Tunnel) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
+ if !destination.Addr.IsValid() {
+ return nil, E.Cause(os.ErrInvalid, "invalid non-IP destination")
+ }
+ return e.tunDevice.ListenPacket(ctx, destination)
+}
+
+func (e *Tunnel) Close() error {
+ e.mtx.Lock()
+ defer e.mtx.Unlock()
+ if e.ipConn != nil {
+ e.ipConn.Close()
+ if e.udpConn != nil {
+ e.udpConn.Close()
+ }
+ if e.tr != nil {
+ e.tr.Close()
+ }
+ e.ipConn = nil
+ }
+ return e.tunDevice.Close()
+}
+
+func (e *Tunnel) maintainTunnel() {
+ go func() {
+ buf := make([]byte, 1280)
+ for e.ctx.Err() == nil {
+ n, err := e.tunnelDevice.ReadPacket(buf)
+ if err != nil {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("failed to read from TUN device: %v", err))
+ continue
+ }
+ ipConn, err := e.getIpConn()
+ if err != nil {
+ return
+ }
+ icmp, err := ipConn.WritePacket(buf[:n])
+ if err != nil {
+ if errors.As(err, new(*connectip.CloseError)) {
+ if ok := e.closeIpConn(ipConn); ok {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("connection closed while writing to IP connection: %w", err))
+ }
+ continue
+ }
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("Error writing to IP connection: %v, continuing...", err))
+ continue
+ }
+ if len(icmp) > 0 {
+ if err := e.tunnelDevice.WritePacket(icmp); err != nil {
+ if errors.As(err, new(*connectip.CloseError)) {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("connection closed while writing ICMP to TUN device: %v", err))
+ continue
+ }
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("Error writing ICMP to TUN device: %v, continuing...", err))
+ }
+ }
+ }
+ }()
+ go func() {
+ buf := make([]byte, 1280)
+ for e.ctx.Err() == nil {
+ ipConn, err := e.getIpConn()
+ if err != nil {
+ return
+ }
+ n, err := ipConn.ReadPacket(buf, true)
+ if err != nil {
+ if e.options.UseHTTP2 || errors.As(err, new(*connectip.CloseError)) {
+ if ok := e.closeIpConn(ipConn); ok {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("connection closed while reading from IP connection: %v", err))
+ }
+ continue
+ }
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("Error reading from IP connection: %v, continuine...", err))
+ continue
+ }
+ if err := e.tunnelDevice.WritePacket(buf[:n]); err != nil {
+ continue
+ }
+ }
+ }()
+ <-e.ctx.Done()
+}
+
+func (e *Tunnel) getIpConn() (*connectip.Conn, error) {
+ e.mtx.Lock()
+ defer e.mtx.Unlock()
+ if e.ctx.Err() != nil {
+ return nil, e.ctx.Err()
+ }
+ if e.ipConn != nil {
+ return e.ipConn, nil
+ }
+ e.logger.InfoContext(e.ctx, "Establishing MASQUE connection to ", e.options.Endpoint)
+ timer := time.NewTimer(0)
+ defer timer.Stop()
+ for {
+ e.logger.InfoContext(e.ctx, fmt.Errorf("Establishing MASQUE connection to %s", e.options.Endpoint))
+ udpConn, tr, ipConn, rsp, err := ConnectTunnel(
+ e.ctx,
+ e.options.Dialer,
+ e.options.TLSConfig,
+ DefaultQuicConfig(e.options.UDPKeepalivePeriod, e.options.UDPInitialPacketSize),
+ "https://cloudflareaccess.com",
+ e.options.Endpoint,
+ e.options.UseHTTP2,
+ )
+ if err != nil {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("Failed to connect tunnel: %v", err))
+ timer.Reset(e.options.ReconnectDelay)
+ select {
+ case <-e.ctx.Done():
+ return nil, err
+ case <-timer.C:
+ }
+ continue
+ }
+ if rsp.StatusCode != 200 {
+ e.logger.ErrorContext(e.ctx, fmt.Errorf("Tunnel connection failed: %s", rsp.Status))
+ ipConn.Close()
+ if udpConn != nil {
+ udpConn.Close()
+ }
+ if tr != nil {
+ tr.Close()
+ }
+ timer.Reset(e.options.ReconnectDelay)
+ select {
+ case <-e.ctx.Done():
+ return nil, err
+ case <-timer.C:
+ }
+ continue
+ }
+ e.udpConn = udpConn
+ e.tr = tr
+ e.ipConn = ipConn
+ e.logger.InfoContext(e.ctx, "Connected to MASQUE server", e.options.Endpoint)
+ return ipConn, nil
+ }
+}
+
+func (e *Tunnel) closeIpConn(ipConn *connectip.Conn) bool {
+ e.mtx.Lock()
+ defer e.mtx.Unlock()
+ if ipConn == e.ipConn {
+ e.ipConn.Close()
+ if e.udpConn != nil {
+ e.udpConn.Close()
+ }
+ if e.tr != nil {
+ e.tr.Close()
+ }
+ e.ipConn = nil
+ return true
+ }
+ return false
+}
diff --git a/transport/masque/utils.go b/transport/masque/utils.go
new file mode 100644
index 0000000000..b99b445985
--- /dev/null
+++ b/transport/masque/utils.go
@@ -0,0 +1,326 @@
+package masque
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/x509"
+ "encoding/base64"
+ "encoding/hex"
+ "errors"
+ "log"
+ "math/big"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/sagernet/quic-go"
+)
+
+// PortMapping represents a network port forwarding rule.
+type PortMapping struct {
+ BindAddress string // The address to bind the local port.
+ LocalPort int // The local port number.
+ RemoteIP string // The remote destination IP address.
+ RemotePort int // The remote destination port number.
+}
+
+// GenerateRandomAndroidSerial generates a random 8-byte Android-like device identifier
+// and returns it as a hexadecimal string.
+//
+// Returns:
+// - string: A randomly generated 16-character hexadecimal serial number.
+// - error: An error if random data generation fails.
+func GenerateRandomAndroidSerial() (string, error) {
+ serial := make([]byte, 8)
+ if _, err := rand.Read(serial); err != nil {
+ return "", err
+ }
+ return hex.EncodeToString(serial), nil
+}
+
+// GenerateRandomWgPubkey generates a random 32-byte WireGuard like public key
+// and returns it as a base64-encoded string.
+//
+// Returns:
+// - string: A randomly generated WireGuard like public key in base64 format.
+// - error: An error if random data generation fails.
+func GenerateRandomWgPubkey() (string, error) {
+ publicKey := make([]byte, 32)
+ if _, err := rand.Read(publicKey); err != nil {
+ return "", err
+ }
+ return base64.StdEncoding.EncodeToString(publicKey), nil
+}
+
+// TimeAsCfString formats a given time.Time into a Cloudflare-compatible string format.
+//
+// The format follows the standard: "YYYY-MM-DDTHH:MM:SS.sss-07:00".
+//
+// Parameters:
+// - t: time.Time to format.
+//
+// Returns:
+// - string: The formatted time string.
+func TimeAsCfString(t time.Time) string {
+ return t.Format("2006-01-02T15:04:05.000-07:00")
+}
+
+// GenerateEcKeyPair generates a new ECDSA key pair using the P-256 curve.
+//
+// Returns:
+// - []byte: The marshalled private key in ASN.1 DER format.
+// - []byte: The marshalled public key in PKIX format.
+// - error: An error if key generation or marshalling fails.
+func GenerateEcKeyPair() ([]byte, []byte, error) {
+ privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ marshalledPrivKey, err := x509.MarshalECPrivateKey(privKey)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ marshalledPubKey, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return marshalledPrivKey, marshalledPubKey, nil
+}
+
+// GenerateCert creates a self-signed certificate using the provided ECDSA private and public keys.
+//
+// The certificate is valid for 24 hours.
+//
+// Parameters:
+// - privKey: *ecdsa.PrivateKey - The private key to sign the certificate.
+// - pubKey: *ecdsa.PublicKey - The public key to include in the certificate.
+//
+// Returns:
+// - [][]byte: A slice containing the certificate in DER format.
+// - error: An error if certificate generation fails.
+func GenerateCert(privKey *ecdsa.PrivateKey, pubKey *ecdsa.PublicKey) ([][]byte, error) {
+ cert, err := x509.CreateCertificate(rand.Reader, &x509.Certificate{
+ SerialNumber: big.NewInt(0),
+ NotBefore: time.Now(),
+ NotAfter: time.Now().Add(1 * 24 * time.Hour),
+ }, &x509.Certificate{}, &privKey.PublicKey, privKey)
+ if err != nil {
+ return nil, err
+ }
+
+ return [][]byte{cert}, nil
+}
+
+// DefaultQuicConfig returns a MASQUE-compatible default QUIC configuration.
+//
+// When initialPacketSize is 0, Path MTU Discovery remains enabled.
+//
+// Parameters:
+// - keepalivePeriod: time.Duration - The duration for sending QUIC keep-alive packets.
+// - initialPacketSize: uint16 - The custom initial size of QUIC packets (0 = auto with PMTU discovery).
+//
+// Returns:
+// - *quic.Config: A pointer to a configured QUIC configuration object.
+func DefaultQuicConfig(keepalivePeriod time.Duration, initialPacketSize uint16) *quic.Config {
+ cfg := &quic.Config{
+ EnableDatagrams: true,
+ KeepAlivePeriod: keepalivePeriod,
+ }
+
+ if initialPacketSize > 0 {
+ cfg.InitialPacketSize = initialPacketSize
+ cfg.DisablePathMTUDiscovery = true
+ }
+
+ return cfg
+}
+
+// parsePortMapping is an internal helper function that parses a port mapping string into its components.
+//
+// It handles IPv6 addresses enclosed in brackets and various format edge cases.
+//
+// Parameters:
+// - port: string - The port mapping string.
+//
+// Returns:
+// - string: The bind address.
+// - int: The local port.
+// - string: The remote hostname/IP.
+// - int: The remote port.
+// - error: An error if parsing fails.
+func parsePortMapping(port string) (bindAddress string, localPort int, remoteHost string, remotePort int, err error) {
+ parts := strings.Split(port, ":")
+
+ // Handle IPv6 addresses (which are enclosed in brackets)
+ if len(parts) >= 4 && strings.HasPrefix(parts[0], "[") && strings.Contains(parts[0], "]") {
+ bindAddress = parts[0]
+ parts = parts[1:] // Shift parts forward
+ } else if len(parts) == 3 {
+ bindAddress = "localhost" // Default to localhost
+ } else if len(parts) == 4 {
+ bindAddress = parts[0]
+ parts = parts[1:] // Shift forward
+ } else {
+ return "", 0, "", 0, errors.New("invalid port mapping format (expected format: [bind_address:]local_port:remote_host:remote_port)")
+ }
+
+ // Parse local port
+ localPort, err = strconv.Atoi(parts[0])
+ if err != nil || localPort <= 0 || localPort > 65535 {
+ return "", 0, "", 0, errors.New("invalid local port")
+ }
+
+ // Validate remote host (allow both hostnames and IPs)
+ remoteHost = parts[1]
+ if net.ParseIP(remoteHost) == nil && !isValidHostname(remoteHost) {
+ return "", 0, "", 0, errors.New("invalid remote hostname/IP")
+ }
+
+ // Parse remote port
+ remotePort, err = strconv.Atoi(parts[2])
+ if err != nil || remotePort <= 0 || remotePort > 65535 {
+ return "", 0, "", 0, errors.New("invalid remote port")
+ }
+
+ // If bindAddress is an IPv6 address, remove brackets for proper binding
+ if strings.HasPrefix(bindAddress, "[") && strings.HasSuffix(bindAddress, "]") {
+ bindAddress = strings.Trim(bindAddress, "[]")
+ }
+
+ // Convert "localhost" or hostnames to actual addresses
+ if bindAddress == "*" {
+ bindAddress = "0.0.0.0" // Allow all interfaces
+ }
+
+ // Validate bind address (support both IPs and hostnames)
+ bindAddress, err = resolveBindAddress(bindAddress)
+ if err != nil {
+ return "", 0, "", 0, errors.New("invalid local address: " + err.Error())
+ }
+
+ remoteHost, err = resolveBindAddress(remoteHost)
+ if err != nil {
+ return "", 0, "", 0, errors.New("invalid remote address: " + err.Error())
+ }
+
+ return bindAddress, localPort, remoteHost, remotePort, nil
+}
+
+// ParsePortMapping parses a port mapping string into a structured PortMapping.
+//
+// The expected format is: `[bind_address:]local_port:remote_host:remote_port`.
+//
+// Parameters:
+// - port: string - The port mapping string.
+//
+// Returns:
+// - PortMapping: A structured representation of the parsed port mapping.
+// - error: An error if the parsing fails.
+func ParsePortMapping(port string) (PortMapping, error) {
+ bindAddress, localPort, remoteHost, remotePort, err := parsePortMapping(port)
+ if err != nil {
+ return PortMapping{}, err
+ }
+
+ return PortMapping{
+ BindAddress: bindAddress,
+ LocalPort: localPort,
+ RemoteIP: remoteHost,
+ RemotePort: remotePort,
+ }, nil
+}
+
+// resolveBindAddress resolves a hostname or IP to its string representation.
+//
+// Parameters:
+// - addr: string - The hostname or IP.
+//
+// Returns:
+// - string: The resolved IP address.
+// - error: An error if resolution fails.
+func resolveBindAddress(addr string) (string, error) {
+ tcpAddr, err := net.ResolveTCPAddr("tcp", addr+":0") // Resolve the address
+ if err != nil {
+ return "", err
+ }
+ return tcpAddr.IP.String(), nil // Return resolved IP
+}
+
+// isValidHostname checks if a given hostname is valid.
+// Pretty ugly for now, needs to be refactored.
+//
+// Parameters:
+// - hostname: string - The hostname to validate.
+//
+// Returns:
+// - bool: True if valid, false otherwise.
+func isValidHostname(hostname string) bool {
+ // Must contain at least one dot (.) unless it's "localhost"
+ if hostname == "localhost" {
+ return true
+ }
+ return strings.Contains(hostname, ".")
+}
+
+// LoginToBase64 encodes a username and password into a base64-encoded string in "username:password" format.
+// This is commonly used for HTTP Basic Authentication.
+//
+// Parameters:
+// - username: string - The username to encode.
+// - password: string - The password to encode.
+//
+// Returns:
+// - string: The base64-encoded "username:password" string.
+func LoginToBase64(username, password string) string {
+ return base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
+}
+
+// CheckIfname validates a network interface name according to the following rules:
+// - Must not be empty.
+// - Should not exceed 15 characters (warning if it does).
+// - Should not contain non-ASCII characters (warning if it does).
+// - Should not contain invalid characters: '/', whitespace, or control characters.
+//
+// Parameters:
+// - name: string - The interface name to validate.
+//
+// Returns:
+// - error: An error if the name is invalid, or nil if valid.
+func CheckIfname(name string) error {
+ if name == "" {
+ return errors.New("interface name cannot be empty")
+ }
+
+ if len(name) >= 16 {
+ log.Printf("Warning: interface name '%s' is longer than %d characters", name, 16-1)
+ }
+
+ var invalidChar bool
+ var hasWhitespace bool
+
+ for _, r := range name {
+ if r > 127 {
+ invalidChar = true
+ break
+ }
+ if r == '/' || r == ' ' || strings.ContainsRune("\t\n\v\f\r", r) {
+ hasWhitespace = true
+ break
+ }
+ }
+
+ if invalidChar {
+ log.Printf("Warning: interface name contains non-ASCII character")
+ }
+
+ if hasWhitespace {
+ return errors.New("interface name contains invalid character: '/' or whitespace")
+ }
+
+ return nil
+}
diff --git a/transport/simple-obfs/http_server.go b/transport/simple-obfs/http_server.go
new file mode 100644
index 0000000000..86f8ef04ef
--- /dev/null
+++ b/transport/simple-obfs/http_server.go
@@ -0,0 +1,104 @@
+package obfs
+
+import (
+ "bufio"
+ "crypto/rand"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "time"
+)
+
+// HTTPObfsServer is the server-side simple-obfs HTTP implementation.
+// It strips the client's HTTP upgrade request and replies with HTTP 101.
+type HTTPObfsServer struct {
+ net.Conn
+ buf []byte
+ bio *bufio.Reader
+ offset int
+ firstRequest bool
+ firstResponse bool
+}
+
+func (hos *HTTPObfsServer) Read(b []byte) (int, error) {
+ if hos.buf != nil {
+ n := copy(b, hos.buf[hos.offset:])
+ hos.offset += n
+ if hos.offset == len(hos.buf) {
+ hos.offset = 0
+ hos.buf = nil
+ }
+ return n, nil
+ }
+
+ if hos.firstRequest {
+ bio := bufio.NewReader(hos.Conn)
+ req, err := http.ReadRequest(bio)
+ if err != nil {
+ return 0, err
+ }
+ if req.Method != "GET" || req.Header.Get("Connection") != "Upgrade" {
+ return 0, io.EOF
+ }
+
+ body, err := io.ReadAll(req.Body)
+ req.Body.Close()
+ if err != nil {
+ return 0, err
+ }
+ n := copy(b, body)
+ if n < len(body) {
+ hos.buf = body
+ hos.offset = n
+ }
+ hos.bio = bio
+ hos.firstRequest = false
+ return n, nil
+ }
+
+ return hos.bio.Read(b)
+}
+
+const httpResponseTemplate = "HTTP/1.1 101 Switching Protocols\r\n" +
+ "Server: nginx/1.%d.%d\r\n" +
+ "Date: %s\r\n" +
+ "Upgrade: websocket\r\n" +
+ "Connection: Upgrade\r\n" +
+ "Sec-WebSocket-Accept: %s\r\n" +
+ "\r\n"
+
+func (hos *HTTPObfsServer) Write(b []byte) (int, error) {
+ if hos.firstResponse {
+ randBytes := make([]byte, 16)
+ rand.Read(randBytes)
+ date := time.Now().Format(time.RFC1123)
+ resp := fmt.Sprintf(httpResponseTemplate, randInt()%11, randInt()%12, date, base64.URLEncoding.EncodeToString(randBytes))
+ if _, err := hos.Conn.Write([]byte(resp)); err != nil {
+ return 0, err
+ }
+ hos.firstResponse = false
+ }
+ return hos.Conn.Write(b)
+}
+
+func (hos *HTTPObfsServer) Upstream() any {
+ return hos.Conn
+}
+
+// NewHTTPObfsServer wraps conn with server-side HTTP obfs.
+func NewHTTPObfsServer(conn net.Conn) net.Conn {
+ return &HTTPObfsServer{
+ Conn: conn,
+ firstRequest: true,
+ firstResponse: true,
+ }
+}
+
+// randInt returns a pseudo-random non-negative integer.
+func randInt() int {
+ b := make([]byte, 1)
+ rand.Read(b)
+ return int(b[0])
+}
diff --git a/transport/simple-obfs/tls_server.go b/transport/simple-obfs/tls_server.go
new file mode 100644
index 0000000000..9c30cf9682
--- /dev/null
+++ b/transport/simple-obfs/tls_server.go
@@ -0,0 +1,166 @@
+package obfs
+
+import (
+ "bytes"
+ "crypto/rand"
+ "encoding/binary"
+ "io"
+ "net"
+ "time"
+
+ B "github.com/sagernet/sing/common/buf"
+)
+
+// TLSObfsServer is the server-side simple-obfs TLS implementation.
+// It reads the client's fake ClientHello and writes a fake ServerHello.
+type TLSObfsServer struct {
+ net.Conn
+ remain int
+ firstRequest bool
+ sessionTicketDone bool
+ firstResponse bool
+}
+
+func (tos *TLSObfsServer) read(b []byte, discardN int) (int, error) {
+ discard := B.Get(discardN)
+ _, err := io.ReadFull(tos.Conn, discard)
+ B.Put(discard)
+ if err != nil {
+ return 0, err
+ }
+
+ sizeBuf := make([]byte, 2)
+ _, err = io.ReadFull(tos.Conn, sizeBuf)
+ if err != nil {
+ return 0, nil
+ }
+
+ length := int(binary.BigEndian.Uint16(sizeBuf))
+ if length > len(b) {
+ n, err := tos.Conn.Read(b)
+ if err != nil {
+ return n, err
+ }
+ tos.remain = length - n
+ return n, nil
+ }
+
+ return io.ReadFull(tos.Conn, b[:length])
+}
+
+// skipOtherExts discards SNI and other TLS extensions after session ticket.
+func (tos *TLSObfsServer) skipOtherExts() error {
+ buf := make([]byte, 256)
+ _, err := tos.read(buf, 7)
+ if err != nil {
+ return err
+ }
+ _, err = io.ReadFull(tos.Conn, buf[:4*16+2])
+ return err
+}
+
+func (tos *TLSObfsServer) Read(b []byte) (int, error) {
+ if tos.remain > 0 {
+ length := tos.remain
+ if length > len(b) {
+ length = len(b)
+ }
+ n, err := io.ReadFull(tos.Conn, b[:length])
+ tos.remain -= n
+ return n, err
+ }
+
+ if tos.firstRequest {
+ tos.firstRequest = false
+ // Skip: record header(5) + handshake header(4) + TLS version(2) + timestamp(4) + random(28) + sid_len(1) + sid(32) + cipher_suites_len(2) + ciphers(56) + compress(2) = 9*16-4 = 140 bytes
+ return tos.read(b, 9*16-4)
+ }
+
+ if !tos.sessionTicketDone {
+ tos.sessionTicketDone = true
+ if err := tos.skipOtherExts(); err != nil {
+ return 0, err
+ }
+ }
+
+ return tos.read(b, 3)
+}
+
+func (tos *TLSObfsServer) Write(b []byte) (int, error) {
+ length := len(b)
+ for i := 0; i < length; i += chunkSize {
+ end := i + chunkSize
+ if end > length {
+ end = length
+ }
+ if _, err := tos.write(b[i:end]); err != nil {
+ return i, err
+ }
+ }
+ return length, nil
+}
+
+func (tos *TLSObfsServer) write(b []byte) (int, error) {
+ if tos.firstResponse {
+ serverHello := makeTLSServerHello(b)
+ _, err := tos.Conn.Write(serverHello)
+ tos.firstResponse = false
+ return len(b), err
+ }
+
+ buf := B.NewSize(5 + len(b))
+ defer buf.Release()
+ buf.Write([]byte{0x17, 0x03, 0x03})
+ binary.Write(buf, binary.BigEndian, uint16(len(b)))
+ buf.Write(b)
+ _, err := tos.Conn.Write(buf.Bytes())
+ return len(b), err
+}
+
+func (tos *TLSObfsServer) Upstream() any {
+ return tos.Conn
+}
+
+// NewTLSObfsServer wraps conn with server-side TLS obfs.
+func NewTLSObfsServer(conn net.Conn) net.Conn {
+ return &TLSObfsServer{
+ Conn: conn,
+ firstRequest: true,
+ firstResponse: true,
+ }
+}
+
+func makeTLSServerHello(data []byte) []byte {
+ randBytes := make([]byte, 28)
+ sessionID := make([]byte, 32)
+ rand.Read(randBytes)
+ rand.Read(sessionID)
+
+ buf := &bytes.Buffer{}
+
+ // ServerHello record
+ buf.WriteByte(0x16)
+ binary.Write(buf, binary.BigEndian, uint16(0x0301))
+ binary.Write(buf, binary.BigEndian, uint16(91))
+ buf.Write([]byte{2, 0, 0, 87, 0x03, 0x03})
+ binary.Write(buf, binary.BigEndian, uint32(time.Now().Unix()))
+ buf.Write(randBytes)
+ buf.WriteByte(32)
+ buf.Write(sessionID)
+ buf.Write([]byte{0xcc, 0xa8})
+ buf.WriteByte(0)
+ buf.Write([]byte{0x00, 0x00})
+ buf.Write([]byte{0xff, 0x01, 0x00, 0x01, 0x00})
+ buf.Write([]byte{0x00, 0x17, 0x00, 0x00})
+ buf.Write([]byte{0x00, 0x0b, 0x00, 0x02, 0x01, 0x00})
+
+ // ChangeCipherSpec
+ buf.Write([]byte{0x14, 0x03, 0x03, 0x00, 0x01, 0x01})
+
+ // Finished (carrying the first payload)
+ buf.Write([]byte{0x16, 0x03, 0x03})
+ binary.Write(buf, binary.BigEndian, uint16(len(data)))
+ buf.Write(data)
+
+ return buf.Bytes()
+}
diff --git a/transport/v2ray/transport.go b/transport/v2ray/transport.go
index ab52f55e8e..0a9438cbe2 100644
--- a/transport/v2ray/transport.go
+++ b/transport/v2ray/transport.go
@@ -10,6 +10,7 @@ import (
"github.com/sagernet/sing-box/transport/v2rayhttp"
"github.com/sagernet/sing-box/transport/v2rayhttpupgrade"
"github.com/sagernet/sing-box/transport/v2raywebsocket"
+ xhttp "github.com/sagernet/sing-box/transport/v2rayxhttp"
E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
@@ -39,6 +40,8 @@ func NewServerTransport(ctx context.Context, logger logger.ContextLogger, option
return NewGRPCServer(ctx, logger, options.GRPCOptions, tlsConfig, handler)
case C.V2RayTransportTypeHTTPUpgrade:
return v2rayhttpupgrade.NewServer(ctx, logger, options.HTTPUpgradeOptions, tlsConfig, handler)
+ case C.V2RayTransportTypeXHTTP:
+ return xhttp.NewServer(ctx, logger, options.XHTTPOptions, tlsConfig, handler)
default:
return nil, E.New("unknown transport type: " + options.Type)
}
@@ -49,6 +52,7 @@ func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socks
return nil, nil
}
switch options.Type {
+
case C.V2RayTransportTypeHTTP:
return v2rayhttp.NewClient(ctx, dialer, serverAddr, options.HTTPOptions, tlsConfig)
case C.V2RayTransportTypeGRPC:
@@ -62,7 +66,9 @@ func NewClientTransport(ctx context.Context, dialer N.Dialer, serverAddr M.Socks
return NewQUICClient(ctx, dialer, serverAddr, options.QUICOptions, tlsConfig)
case C.V2RayTransportTypeHTTPUpgrade:
return v2rayhttpupgrade.NewClient(ctx, dialer, serverAddr, options.HTTPUpgradeOptions, tlsConfig)
+ case C.V2RayTransportTypeXHTTP:
+ return xhttp.NewClient(ctx, dialer, serverAddr, options.XHTTPOptions, tlsConfig)
default:
- return nil, E.New("unknown transport type: " + options.Type)
+ return nil, E.New("unknown client transport type: " + options.Type)
}
}
diff --git a/transport/v2rayhttp/client.go b/transport/v2rayhttp/client.go
index 6c327cd65f..20cf41f50b 100644
--- a/transport/v2rayhttp/client.go
+++ b/transport/v2rayhttp/client.go
@@ -12,12 +12,12 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
sHTTP "github.com/sagernet/sing/protocol/http"
-
"golang.org/x/net/http2"
)
@@ -74,6 +74,15 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
if !strings.HasPrefix(requestURL.Path, "/") {
requestURL.Path = "/" + requestURL.Path
}
+ headers := options.Headers.Build()
+
+ if host := headers.Get("Host"); host != "" { //H
+ headers.Del("Host") //H
+ requestURL.Host = host //H
+ }
+ if headers.Get("User-Agent") == "" { //H
+ headers.Set("User-Agent", C.DefaultBrowserAgent) //H
+ } //H
return &Client{
ctx: ctx,
dialer: dialer,
@@ -81,7 +90,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
requestURL: requestURL,
host: options.Host,
method: options.Method,
- headers: options.Headers.Build(),
+ headers: headers, //H
transport: transport,
http2: tlsConfig != nil,
}, nil
diff --git a/transport/v2rayhttpupgrade/client.go b/transport/v2rayhttpupgrade/client.go
index f282d3f697..8577b0a9db 100644
--- a/transport/v2rayhttpupgrade/client.go
+++ b/transport/v2rayhttpupgrade/client.go
@@ -10,6 +10,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/tls"
+ C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
@@ -63,6 +64,9 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
for key, value := range options.Headers {
headers[key] = value
}
+ if headers.Get("User-Agent") == "" { //H
+ headers.Set("User-Agent", C.DefaultBrowserAgent) //H
+ } //H
return &Client{
dialer: dialer,
serverAddr: serverAddr,
diff --git a/transport/v2raywebsocket/client.go b/transport/v2raywebsocket/client.go
index e56301093e..bb20e177c8 100644
--- a/transport/v2raywebsocket/client.go
+++ b/transport/v2raywebsocket/client.go
@@ -61,7 +61,7 @@ func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, opt
requestURL.Host = host
}
if headers.Get("User-Agent") == "" {
- headers.Set("User-Agent", "Go-http-client/1.1")
+ headers.Set("User-Agent", C.DefaultBrowserAgent) //H
}
return &Client{
dialer,
diff --git a/transport/v2rayxhttp/client.go b/transport/v2rayxhttp/client.go
new file mode 100644
index 0000000000..c11466b323
--- /dev/null
+++ b/transport/v2rayxhttp/client.go
@@ -0,0 +1,368 @@
+package xhttp
+
+import (
+ "context"
+ gotls "crypto/tls"
+ "io"
+ "net/http"
+ "net/http/httptrace"
+ "net/url"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/quic-go"
+ "github.com/sagernet/quic-go/http3"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/common/xray/buf"
+ "github.com/sagernet/sing-box/common/xray/net"
+ "github.com/sagernet/sing-box/common/xray/pipe"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+ "github.com/sagernet/sing-box/common/xray/uuid"
+ "github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/bufio"
+ E "github.com/sagernet/sing/common/exceptions"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ sHTTP "github.com/sagernet/sing/protocol/http"
+ "github.com/sagernet/sing/service"
+ "golang.org/x/net/http2"
+)
+
+type Client struct {
+ ctx context.Context
+ options *option.V2RayXHTTPOptions
+ baseRequestURL url.URL
+ baseRequestURL2 url.URL
+ getHTTPClient func() (DialerClient, *XmuxClient)
+ getHTTPClient2 func() (DialerClient, *XmuxClient)
+}
+
+func NewClient(ctx context.Context, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayXHTTPOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
+ if options.Mode == "" {
+ return nil, E.New("mode is not set")
+ }
+ dest := serverAddr
+ baseRequestURL, err := getBaseRequestURL(&options.V2RayXHTTPBaseOptions, dest, tlsConfig)
+ if err != nil {
+ return nil, err
+ }
+ var xmuxOptions option.V2RayXHTTPXmuxOptions
+ if options.Xmux != nil {
+ xmuxOptions = *options.Xmux
+ }
+ xmuxManager := NewXmuxManager(xmuxOptions, func() XmuxConn {
+ return createHTTPClient(dest, dialer, &options.V2RayXHTTPBaseOptions, tlsConfig)
+ })
+ getHTTPClient := func() (DialerClient, *XmuxClient) {
+ xmuxClient := xmuxManager.GetXmuxClient(ctx)
+ return xmuxClient.XmuxConn.(DialerClient), xmuxClient
+ }
+ baseRequestURL2 := baseRequestURL
+ getHTTPClient2 := getHTTPClient
+ if options.Download != nil {
+ options2 := options.Download
+ dialer2 := dialer
+ if options2.Detour != "" {
+ var ok bool
+ dialer2, ok = service.FromContext[adapter.OutboundManager](ctx).Outbound(options2.Detour)
+ if !ok {
+ return nil, E.New("outbound detour not found: ", options2.Detour)
+ }
+ }
+ dest2 := options2.ServerOptions.Build()
+ var tlsConfig2 tls.Config
+ if options2.TLS != nil {
+ tlsConfig2, err = tls.NewClient(ctx, logger.NOP(), options2.Server, common.PtrValueOrDefault(options2.TLS))
+ if err != nil {
+ return nil, err
+ }
+ }
+ baseRequestURL2, err = getBaseRequestURL(&options2.V2RayXHTTPBaseOptions, dest2, tlsConfig2)
+ if err != nil {
+ return nil, err
+ }
+ var xmuxOptions2 option.V2RayXHTTPXmuxOptions
+ if options2.Xmux != nil {
+ xmuxOptions2 = *options2.Xmux
+ }
+ xmuxManager2 := NewXmuxManager(xmuxOptions2, func() XmuxConn {
+ return createHTTPClient(dest2, dialer2, &options2.V2RayXHTTPBaseOptions, tlsConfig2)
+ })
+ getHTTPClient2 = func() (DialerClient, *XmuxClient) {
+ xmuxClient2 := xmuxManager2.GetXmuxClient(ctx)
+ return xmuxClient2.XmuxConn.(DialerClient), xmuxClient2
+ }
+ }
+ return &Client{
+ ctx: ctx,
+ options: &options,
+ getHTTPClient: getHTTPClient,
+ getHTTPClient2: getHTTPClient2,
+ baseRequestURL: baseRequestURL,
+ baseRequestURL2: baseRequestURL2,
+ }, nil
+}
+
+func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
+ options := c.options
+ mode := c.options.Mode
+ sessionId := ""
+ if c.options.Mode != "stream-one" {
+ sessionIdUuid := uuid.New()
+ sessionId = sessionIdUuid.String()
+ }
+ requestURL := c.baseRequestURL
+ requestURL2 := c.baseRequestURL2
+ httpClient, xmuxClient := c.getHTTPClient()
+ httpClient2, xmuxClient2 := c.getHTTPClient2()
+ if xmuxClient != nil {
+ xmuxClient.OpenUsage.Add(1)
+ }
+ if xmuxClient2 != nil && xmuxClient2 != xmuxClient {
+ xmuxClient2.OpenUsage.Add(1)
+ }
+ var closed atomic.Int32
+ reader, writer := io.Pipe()
+ conn := splitConn{
+ writer: writer,
+ onClose: func() {
+ if closed.Add(1) > 1 {
+ return
+ }
+ if xmuxClient != nil {
+ xmuxClient.OpenUsage.Add(-1)
+ }
+ if xmuxClient2 != nil && xmuxClient2 != xmuxClient {
+ xmuxClient2.OpenUsage.Add(-1)
+ }
+ },
+ }
+ var err error
+ if mode == "stream-one" {
+ requestURL.Path = options.GetNormalizedPath()
+ if xmuxClient != nil {
+ xmuxClient.LeftRequests.Add(-1)
+ }
+ conn.reader, conn.remoteAddr, conn.localAddr, err = httpClient.OpenStream(ctx, requestURL.String(), sessionId, reader, false)
+ if err != nil { // browser dialer only
+ return nil, err
+ }
+ return &conn, nil
+ } else { // stream-down
+ if xmuxClient2 != nil {
+ xmuxClient2.LeftRequests.Add(-1)
+ }
+ conn.reader, conn.remoteAddr, conn.localAddr, err = httpClient2.OpenStream(ctx, requestURL2.String(), sessionId, nil, false)
+ if err != nil { // browser dialer only
+ return nil, err
+ }
+ }
+ if mode == "stream-up" {
+ if xmuxClient != nil {
+ xmuxClient.LeftRequests.Add(-1)
+ }
+ _, _, _, err = httpClient.OpenStream(ctx, requestURL.String(), sessionId, reader, true)
+ if err != nil { // browser dialer only
+ return nil, err
+ }
+ return &conn, nil
+ }
+ scMaxEachPostBytes := options.GetNormalizedScMaxEachPostBytes()
+ scMinPostsIntervalMs := options.GetNormalizedScMinPostsIntervalMs()
+ if scMaxEachPostBytes.From <= buf.Size {
+ panic("`scMaxEachPostBytes` should be bigger than " + strconv.Itoa(buf.Size))
+ }
+ maxUploadSize := scMaxEachPostBytes.Rand()
+ // WithSizeLimit(0) will still allow single bytes to pass, and a lot of
+ // code relies on this behavior. Subtract 1 so that together with
+ // uploadWriter wrapper, exact size limits can be enforced
+ // uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - 1))
+ uploadPipeReader, uploadPipeWriter := pipe.New(pipe.WithSizeLimit(maxUploadSize - buf.Size))
+ conn.writer = uploadWriter{
+ uploadPipeWriter,
+ maxUploadSize,
+ }
+ go func() {
+ var seq int64
+ var lastWrite time.Time
+ for {
+ wroteRequest := done.New()
+ ctx := httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
+ WroteRequest: func(httptrace.WroteRequestInfo) {
+ wroteRequest.Close()
+ },
+ })
+ // this intentionally makes a shallow-copy of the struct so we
+ // can reassign Path (potentially concurrently)
+ url := requestURL
+ seqStr := strconv.FormatInt(seq, 10)
+ seq += 1
+ if scMinPostsIntervalMs.From > 0 {
+ time.Sleep(time.Duration(scMinPostsIntervalMs.Rand())*time.Millisecond - time.Since(lastWrite))
+ }
+ // by offloading the uploads into a buffered pipe, multiple conn.Write
+ // calls get automatically batched together into larger POST requests.
+ // without batching, bandwidth is extremely limited.
+ chunk, err := uploadPipeReader.ReadMultiBuffer()
+ if err != nil {
+ break
+ }
+ lastWrite = time.Now()
+ if xmuxClient != nil && (xmuxClient.LeftRequests.Add(-1) <= 0 ||
+ (xmuxClient.UnreusableAt != time.Time{} && lastWrite.After(xmuxClient.UnreusableAt))) {
+ httpClient, xmuxClient = c.getHTTPClient()
+ }
+ go func() {
+ err := httpClient.PostPacket(
+ ctx,
+ url.String(),
+ sessionId,
+ seqStr,
+ &buf.MultiBufferContainer{MultiBuffer: chunk},
+ int64(chunk.Len()),
+ )
+ wroteRequest.Close()
+ if err != nil {
+ uploadPipeReader.Interrupt()
+ }
+ }()
+ if _, ok := httpClient.(*DefaultDialerClient); ok {
+ select {
+ case <-ctx.Done():
+ case <-wroteRequest.Wait():
+ }
+
+ }
+ }
+ }()
+ return &conn, nil
+}
+
+func (c *Client) Close() error {
+ return nil
+}
+
+func decideHTTPVersion(tlsConfig tls.Config) string {
+ if tlsConfig == nil || len(tlsConfig.NextProtos()) == 0 || tlsConfig.NextProtos()[0] == "http/1.1" {
+ return "1.1"
+ }
+ if tlsConfig.NextProtos()[0] == "h3" {
+ return "3"
+ }
+ return "2"
+}
+
+func getBaseRequestURL(options *option.V2RayXHTTPBaseOptions, dest M.Socksaddr, tlsConfig tls.Config) (url.URL, error) {
+ var requestURL url.URL
+ if tlsConfig == nil {
+ requestURL.Scheme = "http"
+ } else {
+ requestURL.Scheme = "https"
+ }
+ requestURL.Host = options.Host
+ if requestURL.Host == "" && tlsConfig != nil {
+ requestURL.Host = tlsConfig.ServerName()
+ }
+ if requestURL.Host == "" {
+ requestURL.Host = dest.AddrString()
+ }
+ requestURL.Path = options.Path
+ if err := sHTTP.URLSetPath(&requestURL, options.Path); err != nil {
+ return requestURL, E.New(err, "parse path")
+ }
+ if !strings.HasPrefix(requestURL.Path, "/") {
+ requestURL.Path = "/" + requestURL.Path
+ }
+ requestURL.Path = options.GetNormalizedPath()
+ requestURL.RawQuery = options.GetNormalizedQuery()
+ return requestURL, nil
+}
+
+func createHTTPClient(dest M.Socksaddr, dialer N.Dialer, options *option.V2RayXHTTPBaseOptions, tlsConfig tls.Config) DialerClient {
+ httpVersion := decideHTTPVersion(tlsConfig)
+ dialContext := func(ctxInner context.Context) (net.Conn, error) {
+ conn, err := dialer.DialContext(ctxInner, "tcp", dest)
+ if err != nil {
+ return nil, err
+ }
+ if httpVersion != "3" && tlsConfig != nil {
+ return tls.ClientHandshake(ctxInner, conn, tlsConfig)
+ }
+ return conn, nil
+ }
+ var keepAlivePeriod time.Duration
+ if options.Xmux != nil {
+ keepAlivePeriod = time.Duration(options.Xmux.HKeepAlivePeriod) * time.Second
+ }
+ var transport http.RoundTripper
+ switch httpVersion {
+ case "3":
+ if keepAlivePeriod == 0 {
+ keepAlivePeriod = net.QuicgoH3KeepAlivePeriod
+ }
+ if keepAlivePeriod < 0 {
+ keepAlivePeriod = 0
+ }
+ quicConfig := &quic.Config{
+ MaxIdleTimeout: net.ConnIdleTimeout,
+ // these two are defaults of quic-go/http3. the default of quic-go (no
+ // http3) is different, so it is hardcoded here for clarity.
+ // https://github.com/quic-go/quic-go/blob/b8ea5c798155950fb5bbfdd06cad1939c9355878/http3/client.go#L36-L39
+ MaxIncomingStreams: -1,
+ KeepAlivePeriod: keepAlivePeriod,
+ }
+ transport = &http3.Transport{
+ QUICConfig: quicConfig,
+ Dial: func(ctx context.Context, addr string, tlsCfg *gotls.Config, cfg *quic.Config) (*quic.Conn, error) {
+ udpConn, dErr := dialer.DialContext(ctx, N.NetworkUDP, dest)
+ if dErr != nil {
+ return nil, dErr
+ }
+ return qtls.DialEarly(ctx, bufio.NewUnbindPacketConn(udpConn), udpConn.RemoteAddr(), tlsConfig, cfg)
+ },
+ }
+ case "2":
+ if keepAlivePeriod == 0 {
+ keepAlivePeriod = net.ChromeH2KeepAlivePeriod
+ }
+ if keepAlivePeriod < 0 {
+ keepAlivePeriod = 0
+ }
+ transport = &http2.Transport{
+ DialTLSContext: func(ctxInner context.Context, network string, addr string, cfg *gotls.Config) (net.Conn, error) {
+ return dialContext(ctxInner)
+ },
+ IdleConnTimeout: net.ConnIdleTimeout,
+ ReadIdleTimeout: keepAlivePeriod,
+ }
+ default:
+ httpDialContext := func(ctxInner context.Context, network string, addr string) (net.Conn, error) {
+ return dialContext(ctxInner)
+ }
+ transport = &http.Transport{
+ DialTLSContext: httpDialContext,
+ DialContext: httpDialContext,
+ IdleConnTimeout: net.ConnIdleTimeout,
+ // chunked transfer download with KeepAlives is buggy with
+ // http.Client and our custom dial context.
+ DisableKeepAlives: true,
+ }
+ }
+ client := &DefaultDialerClient{
+ options: options,
+ client: &http.Client{
+ Transport: transport,
+ },
+ httpVersion: httpVersion,
+ uploadRawPool: &sync.Pool{},
+ dialUploadConn: dialContext,
+ }
+ return client
+}
diff --git a/transport/v2rayxhttp/conn.go b/transport/v2rayxhttp/conn.go
new file mode 100644
index 0000000000..7da8e916c1
--- /dev/null
+++ b/transport/v2rayxhttp/conn.go
@@ -0,0 +1,108 @@
+package xhttp
+
+import (
+ "bufio"
+ "io"
+ "net"
+ "net/http"
+ "sync"
+ "time"
+
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+)
+
+type splitConn struct {
+ writer io.WriteCloser
+ reader io.ReadCloser
+ remoteAddr net.Addr
+ localAddr net.Addr
+ onClose func()
+}
+
+func (c *splitConn) Write(b []byte) (int, error) {
+ return c.writer.Write(b)
+}
+
+func (c *splitConn) Read(b []byte) (int, error) {
+ return c.reader.Read(b)
+}
+
+func (c *splitConn) Close() error {
+ if c.onClose != nil {
+ c.onClose()
+ }
+
+ err := c.writer.Close()
+ err2 := c.reader.Close()
+ if err != nil {
+ return err
+ }
+
+ if err2 != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (c *splitConn) LocalAddr() net.Addr {
+ return c.localAddr
+}
+
+func (c *splitConn) RemoteAddr() net.Addr {
+ return c.remoteAddr
+}
+
+func (c *splitConn) SetDeadline(t time.Time) error {
+ // TODO cannot do anything useful
+ return nil
+}
+
+func (c *splitConn) SetReadDeadline(t time.Time) error {
+ // TODO cannot do anything useful
+ return nil
+}
+
+func (c *splitConn) SetWriteDeadline(t time.Time) error {
+ // TODO cannot do anything useful
+ return nil
+}
+
+type H1Conn struct {
+ UnreadedResponsesCount int
+ RespBufReader *bufio.Reader
+ net.Conn
+}
+
+func NewH1Conn(conn net.Conn) *H1Conn {
+ return &H1Conn{
+ RespBufReader: bufio.NewReader(conn),
+ Conn: conn,
+ }
+}
+
+type httpServerConn struct {
+ sync.Mutex
+ *done.Instance
+ io.Reader // no need to Close request.Body
+ http.ResponseWriter
+}
+
+func (c *httpServerConn) Write(b []byte) (int, error) {
+ c.Lock()
+ defer c.Unlock()
+ if c.Done() {
+ return 0, io.ErrClosedPipe
+ }
+ n, err := c.ResponseWriter.Write(b)
+ if err == nil {
+ c.ResponseWriter.(http.Flusher).Flush()
+ }
+ return n, err
+}
+
+func (c *httpServerConn) Close() error {
+ c.Lock()
+ defer c.Unlock()
+ return c.Instance.Close()
+}
diff --git a/transport/v2rayxhttp/dialer.go b/transport/v2rayxhttp/dialer.go
new file mode 100644
index 0000000000..9c17baf463
--- /dev/null
+++ b/transport/v2rayxhttp/dialer.go
@@ -0,0 +1,333 @@
+package xhttp
+
+import (
+ "bytes"
+ "context"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "net/http/httptrace"
+ "strings"
+ "sync"
+
+ common "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+ "github.com/sagernet/sing-box/option"
+)
+
+// interface to abstract between use of browser dialer, vs net/http
+type DialerClient interface {
+ IsClosed() bool
+
+ // ctx, url, sessionId, body, uploadOnly
+ OpenStream(context.Context, string, string, io.Reader, bool) (io.ReadCloser, net.Addr, net.Addr, error)
+
+ // ctx, url, sessionId, seqStr, body, contentLength
+ PostPacket(context.Context, string, string, string, io.Reader, int64) error
+}
+
+// implements xhttp.DialerClient in terms of direct network connections
+type DefaultDialerClient struct {
+ options *option.V2RayXHTTPBaseOptions
+ client *http.Client
+ closed bool
+ httpVersion string
+ // pool of net.Conn, created using dialUploadConn
+ uploadRawPool *sync.Pool
+ dialUploadConn func(ctxInner context.Context) (net.Conn, error)
+}
+
+func (c *DefaultDialerClient) IsClosed() bool {
+ return c.closed
+}
+
+func (c *DefaultDialerClient) OpenStream(ctx context.Context, url string, sessionId string, body io.Reader, uploadOnly bool) (wrc io.ReadCloser, remoteAddr, localAddr net.Addr, err error) {
+ // this is done when the TCP/UDP connection to the server was established,
+ // and we can unblock the Dial function and print correct net addresses in
+ // logs
+ gotConn := done.New()
+ ctx = httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
+ GotConn: func(connInfo httptrace.GotConnInfo) {
+ remoteAddr = connInfo.Conn.RemoteAddr()
+ localAddr = connInfo.Conn.LocalAddr()
+ gotConn.Close()
+ },
+ })
+ method := "GET" // stream-down
+ if body != nil {
+ method = c.options.GetNormalizedUplinkHTTPMethod() // stream-up/one
+ }
+ req, _ := http.NewRequestWithContext(context.WithoutCancel(ctx), method, url, body)
+ req.Header = c.options.GetRequestHeader()
+ length := int(c.options.GetNormalizedXPaddingBytes().Rand())
+ config := XPaddingConfig{Length: length}
+ if c.options.XPaddingObfsMode {
+ config.Placement = XPaddingPlacement{
+ Placement: c.options.XPaddingPlacement,
+ Key: c.options.XPaddingKey,
+ Header: c.options.XPaddingHeader,
+ RawURL: url,
+ }
+ config.Method = PaddingMethod(c.options.XPaddingMethod)
+ } else {
+ config.Placement = XPaddingPlacement{
+ Placement: option.PlacementQueryInHeader,
+ Key: "x_padding",
+ Header: "Referer",
+ RawURL: url,
+ }
+ }
+ ApplyXPaddingToRequest(req, config)
+ ApplyMetaToRequest(c.options, req, sessionId, "")
+ if method == c.options.GetNormalizedUplinkHTTPMethod() && !c.options.NoGRPCHeader {
+ req.Header.Set("Content-Type", "application/grpc")
+ }
+ wrc = &WaitReadCloser{ctx: ctx, Wait: make(chan struct{})}
+ go func() {
+ resp, err := c.client.Do(req)
+ if err != nil {
+ if !uploadOnly { // stream-down is enough
+ c.closed = true
+ }
+ gotConn.Close()
+ wrc.Close()
+ return
+ }
+ if resp.StatusCode != 200 || uploadOnly { // stream-up
+ io.Copy(io.Discard, resp.Body)
+ resp.Body.Close() // if it is called immediately, the upload will be interrupted also
+ wrc.Close()
+ return
+ }
+ wrc.(*WaitReadCloser).Set(resp.Body)
+ }()
+ select {
+ case <-gotConn.Wait():
+ case <-ctx.Done():
+ }
+ return
+}
+
+func (c *DefaultDialerClient) PostPacket(ctx context.Context, url string, sessionId string, seqStr string, body io.Reader, contentLength int64) error {
+ var encodedData string
+ dataPlacement := c.options.GetNormalizedUplinkDataPlacement()
+ if dataPlacement != option.PlacementBody {
+ data, err := io.ReadAll(body)
+ if err != nil {
+ return err
+ }
+ encodedData = base64.RawURLEncoding.EncodeToString(data)
+ body = nil
+ contentLength = 0
+ }
+ method := c.options.GetNormalizedUplinkHTTPMethod()
+ req, err := http.NewRequestWithContext(context.WithoutCancel(ctx), method, url, body)
+ if err != nil {
+ return err
+ }
+ req.ContentLength = contentLength
+ req.Header = c.options.GetRequestHeader()
+ if dataPlacement != option.PlacementBody {
+ key := c.options.UplinkDataKey
+ chunkSize := int(c.options.UplinkChunkSize)
+ switch dataPlacement {
+ case option.PlacementHeader:
+ for i := 0; i < len(encodedData); i += chunkSize {
+ end := i + chunkSize
+ if end > len(encodedData) {
+ end = len(encodedData)
+ }
+ chunk := encodedData[i:end]
+ headerKey := fmt.Sprintf("%s-%d", key, i/chunkSize)
+ req.Header.Set(headerKey, chunk)
+ }
+
+ req.Header.Set(key+"-Length", fmt.Sprintf("%d", len(encodedData)))
+ req.Header.Set(key+"-Upstream", "1")
+ case option.PlacementCookie:
+ for i := 0; i < len(encodedData); i += chunkSize {
+ end := i + chunkSize
+ if end > len(encodedData) {
+ end = len(encodedData)
+ }
+ chunk := encodedData[i:end]
+ cookieName := fmt.Sprintf("%s_%d", key, i/chunkSize)
+ req.AddCookie(&http.Cookie{Name: cookieName, Value: chunk})
+ }
+
+ req.AddCookie(&http.Cookie{Name: key + "_upstream", Value: "1"})
+ }
+ }
+ length := int(c.options.GetNormalizedXPaddingBytes().Rand())
+ config := XPaddingConfig{Length: length}
+ if c.options.XPaddingObfsMode {
+ config.Placement = XPaddingPlacement{
+ Placement: c.options.XPaddingPlacement,
+ Key: c.options.XPaddingKey,
+ Header: c.options.XPaddingHeader,
+ RawURL: url,
+ }
+ config.Method = PaddingMethod(c.options.XPaddingMethod)
+ } else {
+ config.Placement = XPaddingPlacement{
+ Placement: option.PlacementQueryInHeader,
+ Key: "x_padding",
+ Header: "Referer",
+ RawURL: url,
+ }
+ }
+ ApplyXPaddingToRequest(req, config)
+ ApplyMetaToRequest(c.options, req, sessionId, seqStr)
+ if c.httpVersion != "1.1" {
+ resp, err := c.client.Do(req)
+ if err != nil {
+ c.closed = true
+ return err
+ }
+ io.Copy(io.Discard, resp.Body)
+ defer resp.Body.Close()
+ } else {
+ // stringify the entire HTTP/1.1 request so it can be
+ // safely retried. if instead req.Write is called multiple
+ // times, the body is already drained after the first
+ // request
+ requestBuff := new(bytes.Buffer)
+ common.Must(req.Write(requestBuff))
+ var uploadConn any
+ var h1UploadConn *H1Conn
+ for {
+ uploadConn = c.uploadRawPool.Get()
+ newConnection := uploadConn == nil
+ if newConnection {
+ newConn, err := c.dialUploadConn(context.WithoutCancel(ctx))
+ if err != nil {
+ return err
+ }
+ h1UploadConn = NewH1Conn(newConn)
+ uploadConn = h1UploadConn
+ } else {
+ h1UploadConn = uploadConn.(*H1Conn)
+
+ // TODO: Replace 0 here with a config value later
+ // Or add some other condition for optimization purposes
+ if h1UploadConn.UnreadedResponsesCount > 0 {
+ resp, err := http.ReadResponse(h1UploadConn.RespBufReader, req)
+ if err != nil {
+ c.closed = true
+ return fmt.Errorf("error while reading response: %s", err.Error())
+ }
+ io.Copy(io.Discard, resp.Body)
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ return fmt.Errorf("got non-200 error response code: %d", resp.StatusCode)
+ }
+ }
+ }
+ _, err := h1UploadConn.Write(requestBuff.Bytes())
+ // if the write failed, we try another connection from
+ // the pool, until the write on a new connection fails.
+ // failed writes to a pooled connection are normal when
+ // the connection has been closed in the meantime.
+ if err == nil {
+ break
+ } else if newConnection {
+ return err
+ }
+ }
+ c.uploadRawPool.Put(uploadConn)
+ }
+ return nil
+}
+
+type WaitReadCloser struct {
+ ctx context.Context
+ Wait chan struct{}
+ io.ReadCloser
+}
+
+func (w *WaitReadCloser) Set(rc io.ReadCloser) {
+ w.ReadCloser = rc
+ defer func() {
+ if recover() != nil {
+ rc.Close()
+ }
+ }()
+ close(w.Wait)
+}
+
+func (w *WaitReadCloser) Read(b []byte) (int, error) {
+ select {
+ case <-w.ctx.Done():
+ return 0, w.ctx.Err()
+ default:
+ }
+
+ if w.ReadCloser == nil {
+ select {
+ case <-w.ctx.Done():
+ return 0, w.ctx.Err()
+ case <-w.Wait:
+ }
+ if w.ReadCloser == nil {
+ return 0, io.ErrClosedPipe
+ }
+ }
+ return w.ReadCloser.Read(b)
+}
+
+func (w *WaitReadCloser) Close() error {
+ if w.ReadCloser != nil {
+ return w.ReadCloser.Close()
+ }
+ defer func() {
+ if recover() != nil && w.ReadCloser != nil {
+ w.ReadCloser.Close()
+ }
+ }()
+ close(w.Wait)
+ return nil
+}
+
+func ApplyMetaToRequest(options *option.V2RayXHTTPBaseOptions, req *http.Request, sessionId string, seqStr string) {
+ sessionPlacement := options.GetNormalizedSessionPlacement()
+ seqPlacement := options.GetNormalizedSeqPlacement()
+ sessionKey := options.GetNormalizedSessionKey()
+ seqKey := options.GetNormalizedSeqKey()
+ if sessionId != "" {
+ switch sessionPlacement {
+ case option.PlacementPath:
+ req.URL.Path = appendToPath(req.URL.Path, sessionId)
+ case option.PlacementQuery:
+ q := req.URL.Query()
+ q.Set(sessionKey, sessionId)
+ req.URL.RawQuery = q.Encode()
+ case option.PlacementHeader:
+ req.Header.Set(sessionKey, sessionId)
+ case option.PlacementCookie:
+ req.AddCookie(&http.Cookie{Name: sessionKey, Value: sessionId})
+ }
+ }
+ if seqStr != "" {
+ switch seqPlacement {
+ case option.PlacementPath:
+ req.URL.Path = appendToPath(req.URL.Path, seqStr)
+ case option.PlacementQuery:
+ q := req.URL.Query()
+ q.Set(seqKey, seqStr)
+ req.URL.RawQuery = q.Encode()
+ case option.PlacementHeader:
+ req.Header.Set(seqKey, seqStr)
+ case option.PlacementCookie:
+ req.AddCookie(&http.Cookie{Name: seqKey, Value: seqStr})
+ }
+ }
+}
+
+func appendToPath(path, value string) string {
+ if strings.HasSuffix(path, "/") {
+ return path + value
+ }
+ return path + "/" + value
+}
diff --git a/transport/v2rayxhttp/http.go b/transport/v2rayxhttp/http.go
new file mode 100644
index 0000000000..03a47da71c
--- /dev/null
+++ b/transport/v2rayxhttp/http.go
@@ -0,0 +1,41 @@
+package xhttp
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/sagernet/sing-box/common/xray/net"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+)
+
+type httpSession struct {
+ uploadQueue *uploadQueue
+ // for as long as the GET request is not opened by the client, this will be
+ // open ("undone"), and the session may be expired within a certain TTL.
+ // after the client connects, this becomes "done" and the session lives as
+ // long as the GET request.
+ isFullyConnected *done.Instance
+}
+
+func parseXForwardedFor(header http.Header) []net.Address {
+ xff := header.Get("X-Forwarded-For")
+ if xff == "" {
+ return nil
+ }
+ list := strings.Split(xff, ",")
+ addrs := make([]net.Address, 0, len(list))
+ for _, proxy := range list {
+ addrs = append(addrs, net.ParseAddress(proxy))
+ }
+ return addrs
+}
+
+func isValidHTTPHost(request string, config string) bool {
+ r := strings.ToLower(request)
+ c := strings.ToLower(config)
+ if strings.Contains(r, ":") {
+ h, _, _ := net.SplitHostPort(r)
+ return h == c
+ }
+ return r == c
+}
diff --git a/transport/v2rayxhttp/mux.go b/transport/v2rayxhttp/mux.go
new file mode 100644
index 0000000000..f753aed5ef
--- /dev/null
+++ b/transport/v2rayxhttp/mux.go
@@ -0,0 +1,104 @@
+package xhttp
+
+import (
+ "context"
+ "crypto/rand"
+ "math"
+ "math/big"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "github.com/sagernet/sing-box/option"
+)
+
+type XmuxConn interface {
+ IsClosed() bool
+}
+
+type XmuxClient struct {
+ XmuxConn XmuxConn
+ OpenUsage atomic.Int32
+ leftUsage int32
+ LeftRequests atomic.Int32
+ UnreusableAt time.Time
+}
+
+type XmuxManager struct {
+ options option.V2RayXHTTPXmuxOptions
+ concurrency int32
+ connections int32
+ newConnFunc func() XmuxConn
+ xmuxClients []*XmuxClient
+ mtx sync.Mutex
+}
+
+func NewXmuxManager(options option.V2RayXHTTPXmuxOptions, newConnFunc func() XmuxConn) *XmuxManager {
+ return &XmuxManager{
+ options: options,
+ concurrency: options.GetNormalizedMaxConcurrency().Rand(),
+ connections: options.GetNormalizedMaxConnections().Rand(),
+ newConnFunc: newConnFunc,
+ xmuxClients: make([]*XmuxClient, 0),
+ }
+}
+
+func (m *XmuxManager) newXmuxClient() *XmuxClient {
+ xmuxClient := &XmuxClient{
+ XmuxConn: m.newConnFunc(),
+ leftUsage: -1,
+ }
+ if x := m.options.GetNormalizedCMaxReuseTimes().Rand(); x > 0 {
+ xmuxClient.leftUsage = x - 1
+ }
+ xmuxClient.LeftRequests.Store(math.MaxInt32)
+ if x := m.options.GetNormalizedHMaxRequestTimes().Rand(); x > 0 {
+ xmuxClient.LeftRequests.Store(x)
+ }
+ if x := m.options.GetNormalizedHMaxReusableSecs().Rand(); x > 0 {
+ xmuxClient.UnreusableAt = time.Now().Add(time.Duration(x) * time.Second)
+ }
+ m.xmuxClients = append(m.xmuxClients, xmuxClient)
+ return xmuxClient
+}
+
+func (m *XmuxManager) GetXmuxClient(ctx context.Context) *XmuxClient {
+ m.mtx.Lock()
+ defer m.mtx.Unlock()
+ for i := 0; i < len(m.xmuxClients); {
+ xmuxClient := m.xmuxClients[i]
+ if xmuxClient.XmuxConn.IsClosed() ||
+ xmuxClient.leftUsage == 0 ||
+ xmuxClient.LeftRequests.Load() <= 0 ||
+ (xmuxClient.UnreusableAt != time.Time{} && time.Now().After(xmuxClient.UnreusableAt)) {
+ m.xmuxClients = append(m.xmuxClients[:i], m.xmuxClients[i+1:]...)
+ } else {
+ i++
+ }
+ }
+ if len(m.xmuxClients) == 0 {
+ return m.newXmuxClient()
+ }
+ if m.connections > 0 && len(m.xmuxClients) < int(m.connections) {
+ return m.newXmuxClient()
+ }
+ xmuxClients := make([]*XmuxClient, 0)
+ if m.concurrency > 0 {
+ for _, xmuxClient := range m.xmuxClients {
+ if xmuxClient.OpenUsage.Load() < m.concurrency {
+ xmuxClients = append(xmuxClients, xmuxClient)
+ }
+ }
+ } else {
+ xmuxClients = m.xmuxClients
+ }
+ if len(xmuxClients) == 0 {
+ return m.newXmuxClient()
+ }
+ i, _ := rand.Int(rand.Reader, big.NewInt(int64(len(xmuxClients))))
+ xmuxClient := xmuxClients[i.Int64()]
+ if xmuxClient.leftUsage > 0 {
+ xmuxClient.leftUsage -= 1
+ }
+ return xmuxClient
+}
diff --git a/transport/v2rayxhttp/server.go b/transport/v2rayxhttp/server.go
new file mode 100644
index 0000000000..e4c54dbd8b
--- /dev/null
+++ b/transport/v2rayxhttp/server.go
@@ -0,0 +1,466 @@
+package xhttp
+
+import (
+ "bytes"
+ "context"
+ "encoding/base64"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "net/url"
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/sagernet/quic-go"
+ "github.com/sagernet/quic-go/http3"
+ "github.com/sagernet/sing-box/adapter"
+ "github.com/sagernet/sing-box/common/tls"
+ "github.com/sagernet/sing-box/common/xray/signal/done"
+ C "github.com/sagernet/sing-box/constant"
+ "github.com/sagernet/sing-box/log"
+ "github.com/sagernet/sing-box/option"
+ qtls "github.com/sagernet/sing-quic"
+ "github.com/sagernet/sing/common"
+ "github.com/sagernet/sing/common/logger"
+ M "github.com/sagernet/sing/common/metadata"
+ N "github.com/sagernet/sing/common/network"
+ aTLS "github.com/sagernet/sing/common/tls"
+ sHttp "github.com/sagernet/sing/protocol/http"
+)
+
+var _ adapter.V2RayServerTransport = (*Server)(nil)
+
+type Server struct {
+ ctx context.Context
+ logger logger.ContextLogger
+ tlsConfig tls.ServerConfig
+ quicConfig *quic.Config
+ handler adapter.V2RayServerTransportHandler
+ httpServer *http.Server
+ http3Server *http3.Server
+ localAddr net.Addr
+ options *option.V2RayXHTTPOptions
+ host string
+ path string
+ sessionMu sync.Mutex
+ sessions sync.Map
+}
+
+func NewServer(ctx context.Context, logger logger.ContextLogger, options option.V2RayXHTTPOptions, tlsConfig tls.ServerConfig, handler adapter.V2RayServerTransportHandler) (*Server, error) {
+ server := &Server{
+ ctx: ctx,
+ logger: logger,
+ tlsConfig: tlsConfig,
+ handler: handler,
+ options: &options,
+ host: options.Host,
+ path: options.GetNormalizedPath(),
+ }
+ if server.network() == N.NetworkTCP {
+ protocols := new(http.Protocols)
+ protocols.SetHTTP1(true)
+ protocols.SetUnencryptedHTTP2(true)
+ server.httpServer = &http.Server{
+ Handler: server,
+ ReadHeaderTimeout: time.Second * 4,
+ MaxHeaderBytes: 8192,
+ Protocols: protocols,
+ BaseContext: func(net.Listener) context.Context {
+ return ctx
+ },
+ ConnContext: func(ctx context.Context, c net.Conn) context.Context {
+ return log.ContextWithNewID(ctx)
+ },
+ }
+ } else {
+ server.quicConfig = &quic.Config{
+ DisablePathMTUDiscovery: !C.IsLinux && !C.IsWindows,
+ }
+ server.http3Server = &http3.Server{
+ Handler: server,
+ }
+ }
+ return server, nil
+}
+
+func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
+ if len(s.host) > 0 && !isValidHTTPHost(request.Host, s.host) {
+ s.logger.ErrorContext(request.Context(), "failed to validate host, request:", request.Host, ", config:", s.host)
+ writer.WriteHeader(http.StatusNotFound)
+ return
+ }
+ if !strings.HasPrefix(request.URL.Path, s.path) {
+ s.logger.ErrorContext(request.Context(), "failed to validate path, request:", request.URL.Path, ", config:", s.path)
+ writer.WriteHeader(http.StatusNotFound)
+ return
+ }
+ writer.Header().Set("Access-Control-Allow-Origin", "*")
+ writer.Header().Set("Access-Control-Allow-Methods", "*")
+ length := int(s.options.GetNormalizedXPaddingBytes().Rand())
+ config := XPaddingConfig{Length: length}
+ if s.options.XPaddingObfsMode {
+ config.Placement = XPaddingPlacement{
+ Placement: s.options.XPaddingPlacement,
+ Key: s.options.XPaddingKey,
+ Header: s.options.XPaddingHeader,
+ }
+ config.Method = PaddingMethod(s.options.XPaddingMethod)
+ } else {
+ config.Placement = XPaddingPlacement{
+ Placement: option.PlacementHeader,
+ Header: "X-Padding",
+ }
+ }
+ ApplyXPaddingToHeader(writer.Header(), config)
+ validRange := s.options.GetNormalizedXPaddingBytes()
+ paddingLength := 0
+ referrer := request.Header.Get("Referer")
+ if referrer != "" {
+ if referrerURL, err := url.Parse(referrer); err == nil {
+ // Browser dialer cannot control the host part of referrer header, so only check the query
+ paddingLength = len(referrerURL.Query().Get("x_padding"))
+ }
+ } else {
+ paddingLength = len(request.URL.Query().Get("x_padding"))
+ }
+ if int32(paddingLength) < validRange.From || int32(paddingLength) > validRange.To {
+ s.logger.ErrorContext(request.Context(), "invalid x_padding length:", int32(paddingLength))
+ writer.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ sessionId, seqStr := ExtractMetaFromRequest(s.options, request, s.path)
+ if sessionId == "" && s.options.Mode != "" && s.options.Mode != "auto" && s.options.Mode != "stream-one" && s.options.Mode != "stream-up" {
+ s.logger.ErrorContext(request.Context(), "stream-one mode is not allowed")
+ writer.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ forwardedAddrs := parseXForwardedFor(request.Header)
+ var remoteAddr net.Addr
+ var err error
+ remoteAddr, err = net.ResolveTCPAddr("tcp", request.RemoteAddr)
+ if err != nil {
+ remoteAddr = &net.TCPAddr{
+ IP: []byte{0, 0, 0, 0},
+ Port: 0,
+ }
+ }
+ if request.ProtoMajor == 3 {
+ remoteAddr = &net.UDPAddr{
+ IP: remoteAddr.(*net.TCPAddr).IP,
+ Port: remoteAddr.(*net.TCPAddr).Port,
+ }
+ }
+ if len(forwardedAddrs) > 0 && forwardedAddrs[0].Family().IsIP() {
+ remoteAddr = &net.TCPAddr{
+ IP: forwardedAddrs[0].IP(),
+ Port: 0,
+ }
+ }
+ var currentSession *httpSession
+ if sessionId != "" {
+ currentSession = s.upsertSession(sessionId)
+ }
+ scMaxEachPostBytes := int(s.options.GetNormalizedScMaxEachPostBytes().To)
+ uplinkHTTPMethod := s.options.GetNormalizedUplinkHTTPMethod()
+ isUplinkRequest := false
+ if uplinkHTTPMethod != "GET" && request.Method == uplinkHTTPMethod {
+ isUplinkRequest = true
+ }
+ uplinkDataPlacement := s.options.GetNormalizedUplinkDataPlacement()
+ uplinkDataKey := s.options.UplinkDataKey
+ switch uplinkDataPlacement {
+ case option.PlacementHeader:
+ if request.Header.Get(uplinkDataKey+"-Upstream") == "1" {
+ isUplinkRequest = true
+ }
+ case option.PlacementCookie:
+ if c, _ := request.Cookie(uplinkDataKey + "_upstream"); c != nil && c.Value == "1" {
+ isUplinkRequest = true
+ }
+ }
+ if isUplinkRequest && sessionId != "" { // stream-up, packet-up
+ if seqStr == "" {
+ if s.options.Mode != "" && s.options.Mode != "auto" && s.options.Mode != "stream-up" {
+ s.logger.ErrorContext(request.Context(), "stream-up mode is not allowed")
+ writer.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ httpSC := &httpServerConn{
+ Instance: done.New(),
+ Reader: request.Body,
+ ResponseWriter: writer,
+ }
+ err = currentSession.uploadQueue.Push(Packet{
+ Reader: httpSC,
+ })
+ if err != nil {
+ s.logger.InfoContext(request.Context(), err, "failed to upload (PushReader)")
+ writer.WriteHeader(http.StatusConflict)
+ } else {
+ writer.Header().Set("X-Accel-Buffering", "no")
+ writer.Header().Set("Cache-Control", "no-store")
+ writer.WriteHeader(http.StatusOK)
+ scStreamUpServerSecs := s.options.GetNormalizedScStreamUpServerSecs()
+ referrer := request.Header.Get("Referer")
+ if referrer != "" && scStreamUpServerSecs.To > 0 {
+ go func() {
+ for {
+ _, err := httpSC.Write(bytes.Repeat([]byte{'X'}, int(s.options.GetNormalizedXPaddingBytes().Rand())))
+ if err != nil {
+ break
+ }
+ time.Sleep(time.Duration(scStreamUpServerSecs.Rand()) * time.Second)
+ }
+ }()
+ }
+ select {
+ case <-request.Context().Done():
+ case <-httpSC.Wait():
+ }
+ }
+ httpSC.Close()
+ return
+ }
+ if s.options.Mode != "" && s.options.Mode != "auto" && s.options.Mode != "packet-up" {
+ s.logger.ErrorContext(request.Context(), "packet-up mode is not allowed")
+ writer.WriteHeader(http.StatusBadRequest)
+ return
+ }
+ var payload []byte
+ if uplinkDataPlacement != option.PlacementBody {
+ var encodedStr string
+ switch uplinkDataPlacement {
+ case option.PlacementHeader:
+ dataLenStr := request.Header.Get(uplinkDataKey + "-Length")
+ if dataLenStr != "" {
+ dataLen, _ := strconv.Atoi(dataLenStr)
+ var chunks []string
+ i := 0
+ for {
+ chunk := request.Header.Get(fmt.Sprintf("%s-%d", uplinkDataKey, i))
+ if chunk == "" {
+ break
+ }
+ chunks = append(chunks, chunk)
+ i++
+ }
+ encodedStr = strings.Join(chunks, "")
+ if len(encodedStr) != dataLen {
+ encodedStr = ""
+ }
+ }
+ case option.PlacementCookie:
+ var chunks []string
+ i := 0
+ for {
+ cookieName := fmt.Sprintf("%s_%d", uplinkDataKey, i)
+ if c, _ := request.Cookie(cookieName); c != nil {
+ chunks = append(chunks, c.Value)
+ i++
+ } else {
+ break
+ }
+ }
+ if len(chunks) > 0 {
+ encodedStr = strings.Join(chunks, "")
+ }
+ }
+ if encodedStr != "" {
+ payload, err = base64.RawURLEncoding.DecodeString(encodedStr)
+ } else {
+ s.logger.ErrorContext(request.Context(), err, "failed to extract data from key "+uplinkDataKey+" placed in "+uplinkDataPlacement)
+ writer.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ } else {
+ payload, err = io.ReadAll(io.LimitReader(request.Body, int64(scMaxEachPostBytes)+1))
+ }
+ if len(payload) > scMaxEachPostBytes {
+ s.logger.ErrorContext(request.Context(), "Too large upload. scMaxEachPostBytes is set to ", scMaxEachPostBytes, "but request size exceed it. Adjust scMaxEachPostBytes on the server to be at least as large as client.")
+ writer.WriteHeader(http.StatusRequestEntityTooLarge)
+ return
+ }
+ if err != nil {
+ s.logger.InfoContext(request.Context(), err, "failed to upload (ReadAll)")
+ writer.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ seq, err := strconv.ParseUint(seqStr, 10, 64)
+ if err != nil {
+ s.logger.InfoContext(request.Context(), err, "failed to upload (ParseUint)")
+ writer.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ err = currentSession.uploadQueue.Push(Packet{
+ Payload: payload,
+ Seq: seq,
+ })
+ if err != nil {
+ s.logger.InfoContext(request.Context(), err, "failed to upload (PushPayload)")
+ writer.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ writer.WriteHeader(http.StatusOK)
+ } else if request.Method == "GET" || sessionId == "" { // stream-down, stream-one
+ if sessionId != "" {
+ // after GET is done, the connection is finished. disable automatic
+ // session reaping, and handle it in defer
+ currentSession.isFullyConnected.Close()
+ defer s.sessions.Delete(sessionId)
+ }
+ // magic header instructs nginx + apache to not buffer response body
+ writer.Header().Set("X-Accel-Buffering", "no")
+ // A web-compliant header telling all middleboxes to disable caching.
+ // Should be able to prevent overloading the cache, or stop CDNs from
+ // teeing the response stream into their cache, causing slowdowns.
+ writer.Header().Set("Cache-Control", "no-store")
+ if !s.options.NoSSEHeader {
+ // magic header to make the HTTP middle box consider this as SSE to disable buffer
+ writer.Header().Set("Content-Type", "text/event-stream")
+ }
+ writer.WriteHeader(http.StatusOK)
+ writer.(http.Flusher).Flush()
+ httpSC := &httpServerConn{
+ Instance: done.New(),
+ Reader: request.Body,
+ ResponseWriter: writer,
+ }
+ conn := splitConn{
+ writer: httpSC,
+ reader: httpSC,
+ remoteAddr: remoteAddr,
+ localAddr: s.localAddr,
+ }
+ if sessionId != "" { // if not stream-one
+ conn.reader = currentSession.uploadQueue
+ }
+ s.handler.NewConnectionEx(request.Context(), &conn, sHttp.SourceAddress(request), M.Socksaddr{}, func(it error) {})
+ // "A ResponseWriter may not be used after [Handler.ServeHTTP] has returned."
+ select {
+ case <-request.Context().Done():
+ case <-httpSC.Wait():
+ }
+ conn.Close()
+ } else {
+ s.logger.ErrorContext(request.Context(), "unsupported method: ", request.Method)
+ writer.WriteHeader(http.StatusMethodNotAllowed)
+ }
+}
+
+func (s *Server) Network() []string {
+ return []string{s.network()}
+}
+
+func (s *Server) Serve(listener net.Listener) error {
+ if s.network() == N.NetworkTCP {
+ if s.tlsConfig != nil {
+ listener = aTLS.NewListener(listener, s.tlsConfig)
+ }
+ s.localAddr = listener.Addr()
+ return s.httpServer.Serve(listener)
+ }
+ return os.ErrInvalid
+}
+
+func (s *Server) ServePacket(listener net.PacketConn) error {
+ if s.network() == N.NetworkUDP {
+ quicListener, err := qtls.ListenEarly(listener, s.tlsConfig, s.quicConfig)
+ if err != nil {
+ return err
+ }
+ s.localAddr = quicListener.Addr()
+ return s.http3Server.ServeListener(quicListener)
+ }
+ return os.ErrInvalid
+}
+
+func (s *Server) Close() error {
+ if s.network() == N.NetworkTCP {
+ return common.Close(s.httpServer)
+ }
+ return common.Close(s.http3Server)
+}
+
+func (s *Server) network() string {
+ if s.tlsConfig != nil && len(s.tlsConfig.NextProtos()) == 1 && s.tlsConfig.NextProtos()[0] == "h3" {
+ return N.NetworkUDP
+ }
+ return N.NetworkTCP
+}
+
+func (s *Server) upsertSession(sessionId string) *httpSession {
+ // fast path
+ currentSessionAny, ok := s.sessions.Load(sessionId)
+ if ok {
+ return currentSessionAny.(*httpSession)
+ }
+ // slow path
+ s.sessionMu.Lock()
+ defer s.sessionMu.Unlock()
+ currentSessionAny, ok = s.sessions.Load(sessionId)
+ if ok {
+ return currentSessionAny.(*httpSession)
+ }
+ session := &httpSession{
+ uploadQueue: NewUploadQueue(s.options.GetNormalizedScMaxBufferedPosts()),
+ isFullyConnected: done.New(),
+ }
+ s.sessions.Store(sessionId, session)
+ shouldReap := done.New()
+ go func() {
+ time.Sleep(30 * time.Second)
+ shouldReap.Close()
+ }()
+ go func() {
+ select {
+ case <-shouldReap.Wait():
+ s.sessions.Delete(sessionId)
+ session.uploadQueue.Close()
+ case <-session.isFullyConnected.Wait():
+ case <-s.ctx.Done():
+ }
+ }()
+ return session
+}
+
+func ExtractMetaFromRequest(options *option.V2RayXHTTPOptions, req *http.Request, path string) (sessionId string, seqStr string) {
+ sessionPlacement := options.GetNormalizedSessionPlacement()
+ seqPlacement := options.GetNormalizedSeqPlacement()
+ sessionKey := options.GetNormalizedSessionKey()
+ seqKey := options.GetNormalizedSeqKey()
+ if sessionPlacement == option.PlacementPath && seqPlacement == option.PlacementPath {
+ subpath := strings.Split(req.URL.Path[len(path):], "/")
+ if len(subpath) > 0 {
+ sessionId = subpath[0]
+ }
+ if len(subpath) > 1 {
+ seqStr = subpath[1]
+ }
+ return sessionId, seqStr
+ }
+ switch sessionPlacement {
+ case option.PlacementQuery:
+ sessionId = req.URL.Query().Get(sessionKey)
+ case option.PlacementHeader:
+ sessionId = req.Header.Get(sessionKey)
+ case option.PlacementCookie:
+ if cookie, e := req.Cookie(sessionKey); e == nil {
+ sessionId = cookie.Value
+ }
+ }
+ switch seqPlacement {
+ case option.PlacementQuery:
+ seqStr = req.URL.Query().Get(seqKey)
+ case option.PlacementHeader:
+ seqStr = req.Header.Get(seqKey)
+ case option.PlacementCookie:
+ if cookie, e := req.Cookie(seqKey); e == nil {
+ seqStr = cookie.Value
+ }
+ }
+ return sessionId, seqStr
+}
diff --git a/transport/v2rayxhttp/upload_queue.go b/transport/v2rayxhttp/upload_queue.go
new file mode 100644
index 0000000000..32259a73be
--- /dev/null
+++ b/transport/v2rayxhttp/upload_queue.go
@@ -0,0 +1,157 @@
+package xhttp
+
+// upload_queue is a specialized priorityqueue + channel to reorder generic
+// packets by a sequence number
+
+import (
+ "container/heap"
+ "io"
+ "runtime"
+ "sync"
+
+ E "github.com/sagernet/sing/common/exceptions"
+)
+
+type Packet struct {
+ Reader io.ReadCloser
+ Payload []byte
+ Seq uint64
+}
+
+type uploadQueue struct {
+ reader io.ReadCloser
+ nomore bool
+ pushedPackets chan Packet
+ writeCloseMutex sync.Mutex
+ heap uploadHeap
+ nextSeq uint64
+ closed bool
+ maxPackets int
+}
+
+func NewUploadQueue(maxPackets int) *uploadQueue {
+ return &uploadQueue{
+ pushedPackets: make(chan Packet, maxPackets),
+ heap: uploadHeap{},
+ nextSeq: 0,
+ closed: false,
+ maxPackets: maxPackets,
+ }
+}
+
+func (h *uploadQueue) Push(p Packet) error {
+ h.writeCloseMutex.Lock()
+ defer h.writeCloseMutex.Unlock()
+ if h.closed {
+ return E.New("packet queue closed")
+ }
+ if h.nomore {
+ return E.New("h.reader already exists")
+ }
+ if p.Reader != nil {
+ h.nomore = true
+ }
+ h.pushedPackets <- p
+ return nil
+}
+
+func (h *uploadQueue) Close() error {
+ h.writeCloseMutex.Lock()
+ defer h.writeCloseMutex.Unlock()
+ if !h.closed {
+ h.closed = true
+ runtime.Gosched() // hope Read() gets the packet
+ f:
+ for {
+ select {
+ case p := <-h.pushedPackets:
+ if p.Reader != nil {
+ h.reader = p.Reader
+ }
+ default:
+ break f
+ }
+ }
+ close(h.pushedPackets)
+ }
+ if h.reader != nil {
+ return h.reader.Close()
+ }
+ return nil
+}
+
+func (h *uploadQueue) Read(b []byte) (int, error) {
+ if h.reader != nil {
+ return h.reader.Read(b)
+ }
+ if h.closed {
+ return 0, io.EOF
+ }
+ if len(h.heap) == 0 {
+ packet, more := <-h.pushedPackets
+ if !more {
+ return 0, io.EOF
+ }
+ if packet.Reader != nil {
+ h.reader = packet.Reader
+ return h.reader.Read(b)
+ }
+ heap.Push(&h.heap, packet)
+ }
+ for len(h.heap) > 0 {
+ packet := heap.Pop(&h.heap).(Packet)
+ n := 0
+
+ if packet.Seq == h.nextSeq {
+ copy(b, packet.Payload)
+ n = min(len(b), len(packet.Payload))
+
+ if n < len(packet.Payload) {
+ // partial read
+ packet.Payload = packet.Payload[n:]
+ heap.Push(&h.heap, packet)
+ } else {
+ h.nextSeq = packet.Seq + 1
+ }
+
+ return n, nil
+ }
+ // misordered packet
+ if packet.Seq > h.nextSeq {
+ if len(h.heap) > h.maxPackets {
+ // the "reassembly buffer" is too large, and we want to
+ // constrain memory usage somehow. let's tear down the
+ // connection, and hope the application retries.
+ return 0, E.New("packet queue is too large")
+ }
+ heap.Push(&h.heap, packet)
+ packet2, more := <-h.pushedPackets
+ if !more {
+ return 0, io.EOF
+ }
+ heap.Push(&h.heap, packet2)
+ }
+ }
+ return 0, nil
+}
+
+// heap code directly taken from https://pkg.go.dev/container/heap
+type uploadHeap []Packet
+
+func (h uploadHeap) Len() int { return len(h) }
+func (h uploadHeap) Less(i, j int) bool { return h[i].Seq < h[j].Seq }
+func (h uploadHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+
+func (h *uploadHeap) Push(x any) {
+ // Push and Pop use pointer receivers because they modify the slice's length,
+ // not just its contents.
+ *h = append(*h, x.(Packet))
+}
+
+func (h *uploadHeap) Pop() any {
+ old := *h
+ n := len(old)
+ x := old[n-1]
+ *h = old[0 : n-1]
+ return x
+}
diff --git a/transport/v2rayxhttp/writer.go b/transport/v2rayxhttp/writer.go
new file mode 100644
index 0000000000..3c11e3b3ee
--- /dev/null
+++ b/transport/v2rayxhttp/writer.go
@@ -0,0 +1,41 @@
+package xhttp
+
+import (
+ common "github.com/sagernet/sing-box/common/xray"
+ "github.com/sagernet/sing-box/common/xray/buf"
+ "github.com/sagernet/sing-box/common/xray/pipe"
+)
+
+// A wrapper around pipe that ensures the size limit is exactly honored.
+//
+// The MultiBuffer pipe accepts any single WriteMultiBuffer call even if that
+// single MultiBuffer exceeds the size limit, and then starts blocking on the
+// next WriteMultiBuffer call. This means that ReadMultiBuffer can return more
+// bytes than the size limit. We work around this by splitting a potentially
+// too large write up into multiple.
+type uploadWriter struct {
+ *pipe.Writer
+ maxLen int32
+}
+
+func (w uploadWriter) Write(b []byte) (int, error) {
+ /*
+ capacity := int(w.maxLen - w.Len())
+ if capacity > 0 && capacity < len(b) {
+ b = b[:capacity]
+ }
+ */
+
+ buffer := buf.MultiBufferContainer{}
+ common.Must2(buffer.Write(b))
+
+ var writed int
+ for _, buff := range buffer.MultiBuffer {
+ err := w.WriteMultiBuffer(buf.MultiBuffer{buff})
+ if err != nil {
+ return writed, err
+ }
+ writed += int(buff.Len())
+ }
+ return writed, nil
+}
diff --git a/transport/v2rayxhttp/xpadding.go b/transport/v2rayxhttp/xpadding.go
new file mode 100644
index 0000000000..f9dbf86831
--- /dev/null
+++ b/transport/v2rayxhttp/xpadding.go
@@ -0,0 +1,268 @@
+package xhttp
+
+import (
+ "crypto/rand"
+ "math"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/sagernet/sing-box/option"
+ "golang.org/x/net/http2/hpack"
+)
+
+type PaddingMethod string
+
+const (
+ PaddingMethodRepeatX PaddingMethod = "repeat-x"
+ PaddingMethodTokenish PaddingMethod = "tokenish"
+)
+
+const charsetBase62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+
+// Huffman encoding gives ~20% size reduction for base62 sequences
+const avgHuffmanBytesPerCharBase62 = 0.8
+
+const validationTolerance = 2
+
+type XPaddingPlacement struct {
+ Placement string
+ Key string
+ Header string
+ RawURL string
+}
+
+type XPaddingConfig struct {
+ Length int
+ Placement XPaddingPlacement
+ Method PaddingMethod
+}
+
+func randStringFromCharset(n int, charset string) (string, bool) {
+ if n <= 0 || len(charset) == 0 {
+ return "", false
+ }
+ m := len(charset)
+ limit := byte(256 - (256 % m))
+ result := make([]byte, n)
+ i := 0
+ buf := make([]byte, 256)
+ for i < n {
+ if _, err := rand.Read(buf); err != nil {
+ return "", false
+ }
+ for _, rb := range buf {
+ if rb >= limit {
+ continue
+ }
+ result[i] = charset[int(rb)%m]
+ i++
+ if i == n {
+ break
+ }
+ }
+ }
+ return string(result), true
+}
+
+func absInt(x int) int {
+ if x < 0 {
+ return -x
+ }
+ return x
+}
+
+func GenerateTokenishPaddingBase62(targetHuffmanBytes int) string {
+ n := int(math.Ceil(float64(targetHuffmanBytes) / avgHuffmanBytesPerCharBase62))
+ if n < 1 {
+ n = 1
+ }
+ randBase62Str, ok := randStringFromCharset(n, charsetBase62)
+ if !ok {
+ return ""
+ }
+ const maxIter = 150
+ adjustChar := byte('X')
+ // Adjust until close enough
+ for iter := 0; iter < maxIter; iter++ {
+ currentLength := int(hpack.HuffmanEncodeLength(randBase62Str))
+ diff := currentLength - targetHuffmanBytes
+
+ if absInt(diff) <= validationTolerance {
+ return randBase62Str
+ }
+ if diff < 0 {
+ // Too small -> append padding char(s)
+ randBase62Str += string(adjustChar)
+ // Avoid a long run of identical chars
+ if adjustChar == 'X' {
+ adjustChar = 'Z'
+ } else {
+ adjustChar = 'X'
+ }
+ } else {
+ // Too big -> remove from the end
+ if len(randBase62Str) <= 1 {
+ return randBase62Str
+ }
+ randBase62Str = randBase62Str[:len(randBase62Str)-1]
+ }
+ }
+ return randBase62Str
+}
+
+func GeneratePadding(method PaddingMethod, length int) string {
+ if length <= 0 {
+ return ""
+ }
+ // https://www.rfc-editor.org/rfc/rfc7541.html#appendix-B
+ // h2's HPACK Header Compression feature employs a huffman encoding using a static table.
+ // 'X' and 'Z' are assigned an 8 bit code, so HPACK compression won't change actual padding length on the wire.
+ // https://www.rfc-editor.org/rfc/rfc9204.html#section-4.1.2-2
+ // h3's similar QPACK feature uses the same huffman table.
+ switch method {
+ case PaddingMethodRepeatX:
+ return strings.Repeat("X", length)
+ case PaddingMethodTokenish:
+ paddingValue := GenerateTokenishPaddingBase62(length)
+ if paddingValue == "" {
+ return strings.Repeat("X", length)
+ }
+ return paddingValue
+ default:
+ return strings.Repeat("X", length)
+ }
+}
+
+func ApplyPaddingToCookie(req *http.Request, name, value string) {
+ if req == nil || name == "" || value == "" {
+ return
+ }
+ req.AddCookie(&http.Cookie{
+ Name: name,
+ Value: value,
+ Path: "/",
+ })
+}
+
+func ApplyPaddingToQuery(u *url.URL, key, value string) {
+ if u == nil || key == "" || value == "" {
+ return
+ }
+ q := u.Query()
+ q.Set(key, value)
+ u.RawQuery = q.Encode()
+}
+
+func ApplyXPaddingToHeader(h http.Header, config XPaddingConfig) {
+ if h == nil {
+ return
+ }
+ paddingValue := GeneratePadding(config.Method, config.Length)
+ switch p := config.Placement; p.Placement {
+ case option.PlacementHeader:
+ h.Set(p.Header, paddingValue)
+ case option.PlacementQueryInHeader:
+ u, err := url.Parse(p.RawURL)
+ if err != nil || u == nil {
+ return
+ }
+ u.RawQuery = p.Key + "=" + paddingValue
+ h.Set(p.Header, u.String())
+ }
+}
+
+func ApplyXPaddingToRequest(req *http.Request, config XPaddingConfig) {
+ if req == nil {
+ return
+ }
+ if req.Header == nil {
+ req.Header = make(http.Header)
+ }
+ placement := config.Placement.Placement
+ if placement == option.PlacementHeader || placement == option.PlacementQueryInHeader {
+ ApplyXPaddingToHeader(req.Header, config)
+ return
+ }
+ paddingValue := GeneratePadding(config.Method, config.Length)
+ switch placement {
+ case option.PlacementCookie:
+ ApplyPaddingToCookie(req, config.Placement.Key, paddingValue)
+ case option.PlacementQuery:
+ ApplyPaddingToQuery(req.URL, config.Placement.Key, paddingValue)
+ }
+}
+
+func ExtractXPaddingFromRequest(options *option.V2RayXHTTPBaseOptions, req *http.Request, obfsMode bool) (string, string) {
+ if req == nil {
+ return "", ""
+ }
+ if !obfsMode {
+ referrer := req.Header.Get("Referer")
+ if referrer != "" {
+ if referrerURL, err := url.Parse(referrer); err == nil {
+ paddingValue := referrerURL.Query().Get("x_padding")
+ paddingPlacement := option.PlacementQueryInHeader + "=Referer, key=x_padding"
+ return paddingValue, paddingPlacement
+ }
+ } else {
+ paddingValue := req.URL.Query().Get("x_padding")
+ return paddingValue, option.PlacementQuery + ", key=x_padding"
+ }
+ }
+ key := options.XPaddingKey
+ header := options.XPaddingHeader
+ if cookie, err := req.Cookie(key); err == nil {
+ if cookie != nil && cookie.Value != "" {
+ paddingValue := cookie.Value
+ paddingPlacement := option.PlacementCookie + ", key=" + key
+ return paddingValue, paddingPlacement
+ }
+ }
+ headerValue := req.Header.Get(header)
+ if headerValue != "" {
+ if options.XPaddingPlacement == option.PlacementHeader {
+ paddingPlacement := option.PlacementHeader + "=" + header
+ return headerValue, paddingPlacement
+ }
+
+ if parsedURL, err := url.Parse(headerValue); err == nil {
+ paddingPlacement := option.PlacementQueryInHeader + "=" + header + ", key=" + key
+
+ return parsedURL.Query().Get(key), paddingPlacement
+ }
+ }
+ queryValue := req.URL.Query().Get(key)
+ if queryValue != "" {
+ paddingPlacement := option.PlacementQuery + ", key=" + key
+ return queryValue, paddingPlacement
+ }
+ return "", ""
+}
+
+func IsPaddingValid(options *option.V2RayXHTTPBaseOptions, paddingValue string, from, to int32, method PaddingMethod) bool {
+ if paddingValue == "" {
+ return false
+ }
+ if to <= 0 {
+ r := options.GetNormalizedXPaddingBytes()
+ from, to = r.From, r.To
+ }
+ switch method {
+ case PaddingMethodRepeatX:
+ n := int32(len(paddingValue))
+ return n >= from && n <= to
+ case PaddingMethodTokenish:
+ const tolerance = int32(validationTolerance)
+ n := int32(hpack.HuffmanEncodeLength(paddingValue))
+ f := from - tolerance
+ t := to + tolerance
+ if f < 0 {
+ f = 0
+ }
+ return n >= f && n <= t
+ default:
+ n := int32(len(paddingValue))
+ return n >= from && n <= to
+ }
+}
diff --git a/transport/wireguard/client_bind.go b/transport/wireguard/client_bind.go
index e0e8b645a3..9c59e34618 100644
--- a/transport/wireguard/client_bind.go
+++ b/transport/wireguard/client_bind.go
@@ -100,6 +100,8 @@ func (c *ClientBind) connect() (*wireConn, error) {
func (c *ClientBind) Open(port uint16) (fns []conn.ReceiveFunc, actualPort uint16, err error) {
select {
+ case <-c.ctx.Done():
+ return nil, 0, c.ctx.Err()
case <-c.done:
c.done = make(chan struct{})
default:
@@ -162,6 +164,33 @@ func (c *ClientBind) SetMark(mark uint32) error {
return nil
}
+func (c *ClientBind) SendWithoutModify(bufs [][]byte, ep conn.Endpoint, offset int) error {
+ udpConn, err := c.connect()
+ if err != nil {
+ c.pauseManager.WaitActive()
+ time.Sleep(time.Second)
+ return err
+ }
+ destination := netip.AddrPort(ep.(remoteEndpoint))
+ for _, buf := range bufs {
+ if offset > 0 {
+ buf = buf[offset:]
+ }
+ if false && len(buf) > 3 { //do not modify to reserved
+ reserved, loaded := c.reservedForEndpoint[destination]
+ if !loaded {
+ reserved = c.reserved
+ }
+ copy(buf[1:4], reserved[:])
+ }
+ _, err = udpConn.WriteToUDPAddrPort(buf, destination)
+ if err != nil {
+ udpConn.Close()
+ return err
+ }
+ }
+ return nil
+}
func (c *ClientBind) Send(bufs [][]byte, ep conn.Endpoint, offset int) error {
udpConn, err := c.connect()
if err != nil {
diff --git a/transport/wireguard/endpoint.go b/transport/wireguard/endpoint.go
index 84d9fe7290..8b45928757 100644
--- a/transport/wireguard/endpoint.go
+++ b/transport/wireguard/endpoint.go
@@ -15,7 +15,7 @@ import (
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/dialer"
- "github.com/sagernet/sing-tun"
+ tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
@@ -293,3 +293,10 @@ func (c peerConfig) GenerateIpcLines() string {
}
return ipcLines.String()
}
+
+func (e *Endpoint) IsReady() bool {
+ if e.device == nil {
+ return false
+ }
+ return e.device.IsUnderLoad()
+}
diff --git a/transport/wireguard/endpoint_options.go b/transport/wireguard/endpoint_options.go
index bb9a46e69f..1a95cdbd3d 100644
--- a/transport/wireguard/endpoint_options.go
+++ b/transport/wireguard/endpoint_options.go
@@ -5,28 +5,32 @@ import (
"net/netip"
"time"
- "github.com/sagernet/sing-tun"
+ tun "github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/logger"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
+ hiddify "github.com/sagernet/wireguard-go/hiddify"
)
type EndpointOptions struct {
- Context context.Context
- Logger logger.ContextLogger
- System bool
- Handler tun.Handler
- UDPTimeout time.Duration
- Dialer N.Dialer
- CreateDialer func(interfaceName string) N.Dialer
- Name string
- MTU uint32
- Address []netip.Prefix
- PrivateKey string
- ListenPort uint16
- ResolvePeer func(domain string) (netip.Addr, error)
- Peers []PeerOptions
- Workers int
+ Context context.Context
+ Logger logger.ContextLogger
+ System bool
+ Handler tun.Handler
+ UDPTimeout time.Duration
+ Dialer N.Dialer
+ CreateDialer func(interfaceName string) N.Dialer
+ Name string
+ MTU uint32
+ Address []netip.Prefix
+ PrivateKey string
+ ListenPort uint16
+ ResolvePeer func(domain string) (netip.Addr, error)
+ Peers []PeerOptions
+ Workers int
+ PreallocatedBuffersPerPool uint32
+ DisablePauses bool
+ Noise hiddify.NoiseOptions
}
type PeerOptions struct {