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. -[![Packaging status](https://repology.org/badge/vertical-allrepos/sing-box.svg)](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 {