diff --git a/.github/update.log b/.github/update.log index db7a8c1d68..85d57fe50e 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1206,3 +1206,4 @@ Update On Fri Dec 5 19:41:34 CET 2025 Update On Sat Dec 6 19:36:39 CET 2025 Update On Sun Dec 7 19:36:46 CET 2025 Update On Mon Dec 8 19:42:31 CET 2025 +Update On Tue Dec 9 19:39:21 CET 2025 diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 166cd8379c..fd6956beaf 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,10 +2,10 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.17", - "mihomo_alpha": "alpha-6b40072", + "mihomo_alpha": "alpha-17b8eb8", "clash_rs": "v0.9.2", "clash_premium": "2023-09-05-gdcc8d87", - "clash_rs_alpha": "0.9.2-alpha+sha.53b277f" + "clash_rs_alpha": "0.9.2-alpha+sha.c9fe9e2" }, "arch_template": { "mihomo": { @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-12-06T22:21:16.955Z" + "updated_at": "2025-12-08T22:21:34.201Z" } diff --git a/lede/target/linux/rockchip/image/Makefile b/lede/target/linux/rockchip/image/Makefile index d3ecf21bcb..86b1848423 100644 --- a/lede/target/linux/rockchip/image/Makefile +++ b/lede/target/linux/rockchip/image/Makefile @@ -70,13 +70,10 @@ define Device/Default PROFILES := Default KERNEL := kernel-bin IMAGES := sysupgrade.img.gz - DEVICE_DTS = rockchip/$$(SOC)-$(lastword $(subst _, ,$(1))) + DEVICE_DTS_DIR = $$(DTS_DIR)/rockchip + DEVICE_DTS = $$(SOC)-$(lastword $(subst _, ,$(1))) endef -ifndef CONFIG_LINUX_5_15 - DTS_CPPFLAGS += -DDTS_NO_LEGACY -endif - include $(SUBTARGET).mk $(eval $(call BuildImage)) diff --git a/lede/target/linux/rockchip/image/armv8.mk b/lede/target/linux/rockchip/image/armv8.mk index e7bcd0abf8..318e66badc 100644 --- a/lede/target/linux/rockchip/image/armv8.mk +++ b/lede/target/linux/rockchip/image/armv8.mk @@ -18,7 +18,7 @@ define Device/ariaboard_photonicat SOC := rk3568 UBOOT_DEVICE_NAME := photonicat-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script vop | pine64-img | gzip | append-metadata - DEVICE_PACKAGES := kmod-drm-rockchip kmod-ath10k kmod-ath10k-sdio pcat-firmware pcat-manager wpad + DEVICE_PACKAGES := kmod-ath10k kmod-ath10k-sdio pcat-firmware pcat-manager wpad-openssl endef TARGET_DEVICES += ariaboard_photonicat @@ -26,9 +26,9 @@ define Device/ariaboard_photonicat2 DEVICE_VENDOR := Ariaboard DEVICE_MODEL := Photonicat 2 SOC := rk3576 - DEVICE_DTS := rockchip/rk3576-photonicat2 + DEVICE_DTS := rk3576-photonicat2 UBOOT_DEVICE_NAME := generic-rk3576 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3576 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-aic8800u wpad-openssl endef TARGET_DEVICES += ariaboard_photonicat2 @@ -36,9 +36,9 @@ TARGET_DEVICES += ariaboard_photonicat2 define Device/armsom_sige1 DEVICE_VENDOR := ArmSoM DEVICE_MODEL := Sige1 - DEVICE_DTS := rockchip/rk3528-armsom-sige1 + DEVICE_DTS := rk3528-armsom-sige1 UBOOT_DEVICE_NAME := generic-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := brcmfmac-firmware-43752-sdio kmod-brcmfmac kmod-r8125 wpad -urngd endef TARGET_DEVICES += armsom_sige1 @@ -47,7 +47,7 @@ define Device/armsom_sige3 DEVICE_VENDOR := ArmSoM DEVICE_MODEL := Sige3 SOC := rk3568 - DEVICE_DTS := rockchip/rk3568-armsom-sige3 + DEVICE_DTS := rk3568-armsom-sige3 UBOOT_DEVICE_NAME := generic-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := brcmfmac-firmware-43752-sdio kmod-brcmfmac kmod-r8125-rss wpad @@ -58,9 +58,9 @@ define Device/armsom_sige5 DEVICE_VENDOR := ArmSoM DEVICE_MODEL := Sige5 SOC := rk3576 - DEVICE_DTS := rockchip/rk3576-armsom-sige5 + DEVICE_DTS := rk3576-armsom-sige5 UBOOT_DEVICE_NAME := sige5-rk3576 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3576 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata endef TARGET_DEVICES += armsom_sige5 @@ -68,10 +68,10 @@ define Device/armsom_sige7 DEVICE_VENDOR := ArmSoM DEVICE_MODEL := Sige7 SOC := rk3588 - DEVICE_DTS := rockchip/rk3588-armsom-sige7 + DEVICE_DTS := rk3588-armsom-sige7 UBOOT_DEVICE_NAME := sige7-rk3588 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata - DEVICE_PACKAGES := kmod-brcmfmac kmod-r8125-rss wpad brcmfmac-firmware-43752-pcie brcmfmac-nvram-43752-pcie + DEVICE_PACKAGES := kmod-brcmfmac kmod-r8125-rss wpad endef TARGET_DEVICES += armsom_sige7 @@ -160,10 +160,10 @@ define Device/friendlyarm_nanopi-m5 DEVICE_VENDOR := FriendlyARM DEVICE_MODEL := NanoPi M5 SOC := rk3576 - DEVICE_DTS := rockchip/rk3576-nanopi-m5 + DEVICE_DTS := rk3576-nanopi-m5 UBOOT_DEVICE_NAME := generic-rk3576 DEVICE_PACKAGES := kmod-gpio-button-hotplug - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3576 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata endef TARGET_DEVICES += friendlyarm_nanopi-m5 @@ -290,17 +290,17 @@ define Device/friendlyarm_nanopi-r76s DEVICE_VENDOR := FriendlyARM DEVICE_MODEL := NanoPi R76S SOC := rk3576 - DEVICE_DTS := rockchip/rk3576-nanopi-r76s + DEVICE_DTS := rk3576-nanopi-r76s UBOOT_DEVICE_NAME := generic-rk3576 DEVICE_PACKAGES := kmod-gpio-button-hotplug kmod-r8125 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3576 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata endef TARGET_DEVICES += friendlyarm_nanopi-r76s define Device/firefly_station-p2 DEVICE_VENDOR := Firefly DEVICE_MODEL := Station P2 - DEVICE_DTS := rockchip/rk3568-roc-pc + DEVICE_DTS := rk3568-roc-pc UBOOT_DEVICE_NAME := station-p2-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-brcmfmac kmod-ikconfig wpad-openssl @@ -311,7 +311,7 @@ define Device/hinlink_common DEVICE_VENDOR := HINLINK UBOOT_DEVICE_NAME := generic-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script vop | pine64-img | gzip | append-metadata - DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-drm-rockchip kmod-hwmon-pwmfan kmod-mt7921e kmod-r8125-rss wpad-openssl + DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-drm-rockchip kmod-mt7921e kmod-r8125-rss wpad-openssl endef define Device/hinlink_opc-h28k @@ -319,7 +319,7 @@ define Device/hinlink_opc-h28k DEVICE_MODEL := OPC-H28K SOC := rk3528 UBOOT_DEVICE_NAME := generic-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-r8168 -urngd endef TARGET_DEVICES += hinlink_opc-h28k @@ -329,7 +329,7 @@ define Device/hinlink_opc-h29k DEVICE_MODEL := OPC-H29K SOC := rk3528 UBOOT_DEVICE_NAME := generic-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-aic8800s kmod-fb-tft-st7789v wpad-openssl -urngd endef TARGET_DEVICES += hinlink_opc-h29k @@ -352,7 +352,7 @@ define Device/hinlink_opc-h69k $(call Device/hinlink_common) DEVICE_MODEL := OPC-H69K SOC := rk3568 - DEVICE_PACKAGES += kmod-mt7916-firmware kmod-usb-serial-option uqmi + DEVICE_PACKAGES += kmod-hwmon-pwmfan kmod-mt7916-firmware kmod-usb-serial-option endef TARGET_DEVICES += hinlink_opc-h69k @@ -361,7 +361,7 @@ define Device/hinlink_opc-ht2 DEVICE_MODEL := OPC-HT2 SOC := rk3528 UBOOT_DEVICE_NAME := generic-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-aic8800s wpad-openssl -urngd endef TARGET_DEVICES += hinlink_opc-ht2 @@ -372,7 +372,7 @@ define Device/lyt_t68m SOC := rk3568 UBOOT_DEVICE_NAME := generic-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script vop | pine64-img | gzip | append-metadata - DEVICE_PACKAGES := kmod-drm-rockchip kmod-gpio-button-hotplug kmod-r8125-rss uboot-envtools + DEVICE_PACKAGES := kmod-drm-rockchip kmod-gpio-button-hotplug kmod-r8125-rss endef TARGET_DEVICES += lyt_t68m @@ -380,7 +380,7 @@ define Device/mmbox_anas3035 DEVICE_VENDOR := MMBOX DEVICE_MODEL := ANAS3035 SOC := rk3568 - DEVICE_DTS := rockchip/rk3568-mmbox-anas3035 + DEVICE_DTS := rk3568-mmbox-anas3035 UBOOT_DEVICE_NAME := mmbox-anas3035-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-hwmon-drivetemp kmod-hwmon-pwmfan kmod-r8125-rss @@ -400,7 +400,7 @@ TARGET_DEVICES += nlnet_xiguapi-v3 define Device/panther_x2 DEVICE_VENDOR := Panther DEVICE_MODEL := X2 - DEVICE_DTS := rockchip/rk3566-panther-x2 + DEVICE_DTS := rk3566-panther-x2 UBOOT_DEVICE_NAME := panther-x2-rk3566 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-brcmfmac kmod-ikconfig brcmfmac-nvram-43430-sdio wpad-openssl @@ -419,9 +419,9 @@ TARGET_DEVICES += pine64_rockpro64 define Device/radxa_e20c DEVICE_VENDOR := Radxa DEVICE_MODEL := E20C - DEVICE_DTS := rockchip/rk3528-radxa-e20c + DEVICE_DTS := rk3528-radxa-e20c UBOOT_DEVICE_NAME := radxa-e20c-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-gpio-button-hotplug kmod-r8168 -urngd endef TARGET_DEVICES += radxa_e20c @@ -429,9 +429,9 @@ TARGET_DEVICES += radxa_e20c define Device/radxa_e24c DEVICE_VENDOR := Radxa DEVICE_MODEL := E24C - DEVICE_DTS := rockchip/rk3528-radxa-e24c + DEVICE_DTS := rk3528-radxa-e24c UBOOT_DEVICE_NAME := radxa-e20c-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-gpio-button-hotplug kmod-dsa-rtl8365mb -urngd endef TARGET_DEVICES += radxa_e24c @@ -439,7 +439,7 @@ TARGET_DEVICES += radxa_e24c define Device/radxa_e25 DEVICE_VENDOR := Radxa DEVICE_MODEL := E25 - DEVICE_DTS := rockchip/rk3568-radxa-e25 + DEVICE_DTS := rk3568-radxa-e25 UBOOT_DEVICE_NAME := radxa-e25-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-r8125-rss @@ -449,7 +449,7 @@ TARGET_DEVICES += radxa_e25 define Device/radxa_e52c DEVICE_VENDOR := Radxa DEVICE_MODEL := E52C - DEVICE_DTS := rockchip/rk3582-radxa-e52c + DEVICE_DTS := rk3582-radxa-e52c UBOOT_DEVICE_NAME := generic-rk3588 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-gpio-button-hotplug kmod-r8125-rss @@ -459,7 +459,7 @@ TARGET_DEVICES += radxa_e52c define Device/radxa_e54c DEVICE_VENDOR := Radxa DEVICE_MODEL := E54C - DEVICE_DTS := rockchip/rk3582-radxa-e54c + DEVICE_DTS := rk3582-radxa-e54c UBOOT_DEVICE_NAME := generic-rk3588 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-gpio-button-hotplug kmod-dsa-rtl8365mb @@ -471,7 +471,7 @@ define Device/radxa_rock-2a DEVICE_MODEL := ROCK 2A SOC := rk3528 UBOOT_DEVICE_NAME := radxa-e20c-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata endef TARGET_DEVICES += radxa_rock-2a @@ -480,7 +480,7 @@ define Device/radxa_rock-2f DEVICE_MODEL := ROCK 2F SOC := rk3528 UBOOT_DEVICE_NAME := radxa-e20c-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata endef TARGET_DEVICES += radxa_rock-2f @@ -554,7 +554,7 @@ TARGET_DEVICES += radxa_rock-5c define Device/radxa_zero-3e DEVICE_VENDOR := Radxa DEVICE_MODEL := ZERO 3E - DEVICE_DTS := rockchip/rk3566-radxa-zero-3e + DEVICE_DTS := rk3566-radxa-zero-3e UBOOT_DEVICE_NAME := radxa-zero-3-rk3566 endef TARGET_DEVICES += radxa_zero-3e @@ -562,7 +562,7 @@ TARGET_DEVICES += radxa_zero-3e define Device/radxa_zero-3w DEVICE_VENDOR := Radxa DEVICE_MODEL := ZERO 3W - DEVICE_DTS := rockchip/rk3566-radxa-zero-3w + DEVICE_DTS := rk3566-radxa-zero-3w DEVICE_PACKAGES := kmod-aic8800s wpad-openssl UBOOT_DEVICE_NAME := radxa-zero-3-rk3566 endef @@ -630,10 +630,10 @@ TARGET_DEVICES += seewo_srcm3588-sw define Device/seewo_sv21 DEVICE_VENDOR := Seewo DEVICE_MODEL := SV21 - DEVICE_DTS := rockchip/rk3568-seewo-sv21 + DEVICE_DTS := rk3568-seewo-sv21 UBOOT_DEVICE_NAME := generic-rk3568 IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata - DEVICE_PACKAGES := kmod-usb-net-rtl8152 kmod-ata-ahci-dwc + DEVICE_PACKAGES := kmod-ata-ahci-dwc kmod-usb-net-rtl8152 endef TARGET_DEVICES += seewo_sv21 @@ -721,7 +721,7 @@ define Device/widora_mangopi-m28 DEVICE_VENDOR := Widora SOC := rk3528 UBOOT_DEVICE_NAME := generic-rk3528 - IMAGE/sysupgrade.img.gz := boot-common | boot-script rk3528 | pine64-img | gzip | append-metadata + IMAGE/sysupgrade.img.gz := boot-common | boot-script | pine64-img | gzip | append-metadata DEVICE_PACKAGES := kmod-aic8800s wpad-openssl -urngd endef diff --git a/lede/target/linux/rockchip/image/mmc.bootscript b/lede/target/linux/rockchip/image/mmc.bootscript index 7c3ac3d4bf..0d2304e456 100644 --- a/lede/target/linux/rockchip/image/mmc.bootscript +++ b/lede/target/linux/rockchip/image/mmc.bootscript @@ -1,14 +1,20 @@ part uuid mmc ${devnum}:2 uuid -if test $stdout = 'serial@fe660000' ; -then serial_addr=',0xfe660000'; +if test $stdout = 'serial@2ad40000' ; +then serial_addr=',0x2ad40000'; serial_port='ttyS0'; +elif test $stdout = 'serial@fe660000' ; +then serial_addr=',0xfe660000'; serial_port='ttyS2'; +elif test $stdout = 'serial@feb50000' ; +then serial_addr=',0xfeb50000'; serial_port='ttyS2'; elif test $stdout = 'serial@ff130000' ; -then serial_addr=',0xff130000'; +then serial_addr=',0xff130000'; serial_port='ttyS2'; elif test $stdout = 'serial@ff1a0000' ; -then serial_addr=',0xff1a0000'; +then serial_addr=',0xff1a0000'; serial_port='ttyS2'; +elif test $stdout = 'serial@ff9f0000' ; +then serial_addr=',0xff9f0000'; serial_port='ttyS0'; fi; -setenv bootargs "console=ttyS2,1500000 earlycon=uart8250,mmio32${serial_addr} root=PARTUUID=${uuid} rw rootwait"; +setenv bootargs "console=${serial_port},1500000 earlycon=uart8250,mmio32${serial_addr} root=PARTUUID=${uuid} rw rootwait"; load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb load mmc ${devnum}:1 ${kernel_addr_r} kernel.img diff --git a/lede/target/linux/rockchip/image/rk3528.bootscript b/lede/target/linux/rockchip/image/rk3528.bootscript deleted file mode 100644 index 3ebc48eb30..0000000000 --- a/lede/target/linux/rockchip/image/rk3528.bootscript +++ /dev/null @@ -1,8 +0,0 @@ -part uuid mmc ${devnum}:2 uuid - -setenv bootargs "console=ttyS0,1500000 earlycon=uart8250,mmio32,0xff9f0000 root=PARTUUID=${uuid} rw rootwait" - -load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb -load mmc ${devnum}:1 ${kernel_addr_r} kernel.img - -booti ${kernel_addr_r} - ${fdt_addr_r} diff --git a/lede/target/linux/rockchip/image/rk3576.bootscript b/lede/target/linux/rockchip/image/rk3576.bootscript deleted file mode 100644 index 9826f33a8b..0000000000 --- a/lede/target/linux/rockchip/image/rk3576.bootscript +++ /dev/null @@ -1,8 +0,0 @@ -part uuid mmc ${devnum}:2 uuid - -setenv bootargs "console=ttyS0,1500000 earlycon=uart8250,mmio32,0x2ad40000 root=PARTUUID=${uuid} rw rootwait" - -load mmc ${devnum}:1 ${fdt_addr_r} rockchip.dtb -load mmc ${devnum}:1 ${kernel_addr_r} kernel.img - -booti ${kernel_addr_r} - ${fdt_addr_r} diff --git a/mieru/.github/workflows/mihomo.yaml b/mieru/.github/workflows/mihomo.yaml index 76a4bd85ff..8b7b69a168 100644 --- a/mieru/.github/workflows/mihomo.yaml +++ b/mieru/.github/workflows/mihomo.yaml @@ -34,11 +34,11 @@ jobs: - name: Build mihomo working-directory: mihomo run: make linux-amd64-v1 - - name: Copy mihomo binary - run: cp mihomo/bin/mihomo-linux-amd64-v1 mieru/mihomo - name: Build mieru test binaries working-directory: mieru run: make test-binary + - name: Copy mihomo binary + run: cp mihomo/bin/mihomo-linux-amd64-v1 mieru/bin/mihomo - name: Build mieru test docker image working-directory: mieru run: docker build -t mihomo:latest -f test/deploy/mihomo/Dockerfile . diff --git a/mieru/.github/workflows/sing-box.yaml b/mieru/.github/workflows/sing-box.yaml index 0b865ade22..f2aa804c38 100644 --- a/mieru/.github/workflows/sing-box.yaml +++ b/mieru/.github/workflows/sing-box.yaml @@ -41,11 +41,11 @@ jobs: - name: Build sing-box working-directory: sing-box run: make build - - name: Copy sing-box binary - run: cp sing-box/sing-box mieru/sing-box - name: Build mieru test binaries working-directory: mieru run: make test-binary + - name: Copy sing-box binary + run: cp sing-box/sing-box mieru/bin/sing-box - name: Build mieru test docker image working-directory: mieru run: docker build -t singbox:latest -f test/deploy/singbox/Dockerfile . diff --git a/mieru/.gitignore b/mieru/.gitignore index 82ad8826e6..93df59e642 100644 --- a/mieru/.gitignore +++ b/mieru/.gitignore @@ -2,6 +2,7 @@ /vendor # binaries +/bin /release *.exe *.dll diff --git a/mieru/Makefile b/mieru/Makefile index 4a43920e37..5932ccf7eb 100644 --- a/mieru/Makefile +++ b/mieru/Makefile @@ -361,16 +361,17 @@ rpm-server-arm64: server-linux-arm64 # Build binaries used in integration tests. .PHONY: test-binary test-binary: - CGO_ENABLED=0 go build -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=C'" -o mieru cmd/mieru/mieru.go - CGO_ENABLED=0 go build -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=S'" -o mita cmd/mita/mita.go - CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=C2'" -o mieru2 cmd/mieru/mieru.go - CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=S2'" -o mita2 cmd/mita/mita.go - CGO_ENABLED=0 go build test/cmd/exampleapiclient/exampleapiclient.go - CGO_ENABLED=0 go build test/cmd/exampleapiserver/exampleapiserver.go - CGO_ENABLED=0 go build test/cmd/httpserver/httpserver.go - CGO_ENABLED=0 go build test/cmd/sockshttpclient/sockshttpclient.go - CGO_ENABLED=0 go build test/cmd/socksudpclient/socksudpclient.go - CGO_ENABLED=0 go build test/cmd/udpserver/udpserver.go + mkdir -p bin + CGO_ENABLED=0 go build -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=C'" -o bin/mieru cmd/mieru/mieru.go + CGO_ENABLED=0 go build -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=S'" -o bin/mita cmd/mita/mita.go + CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=C2'" -o bin/mieru2 cmd/mieru/mieru.go + CGO_ENABLED=1 go build -race -ldflags="-X 'github.com/enfein/mieru/v3/pkg/log.LogPrefix=S2'" -o bin/mita2 cmd/mita/mita.go + CGO_ENABLED=0 go build -o bin/exampleapiclient test/cmd/exampleapiclient/exampleapiclient.go + CGO_ENABLED=0 go build -o bin/exampleapiserver test/cmd/exampleapiserver/exampleapiserver.go + CGO_ENABLED=0 go build -o bin/httpserver test/cmd/httpserver/httpserver.go + CGO_ENABLED=0 go build -o bin/sockshttpclient test/cmd/sockshttpclient/sockshttpclient.go + CGO_ENABLED=0 go build -o bin/socksudpclient test/cmd/socksudpclient/socksudpclient.go + CGO_ENABLED=0 go build -o bin/udpserver test/cmd/udpserver/udpserver.go # Build docker images to run integration tests. .PHONY: test-container-image @@ -379,7 +380,6 @@ test-container-image: test-binary docker build -t mieru_apiclient:${SHORT_SHA} -f test/deploy/apiclient/Dockerfile . docker build -t mieru_apiserver:${SHORT_SHA} -f test/deploy/apiserver/Dockerfile . docker build -t mieru_proxychain:${SHORT_SHA} -f test/deploy/proxychain/Dockerfile . - rm -f exampleapiclient exampleapiserver mieru mieru2 mita mita2 httpserver sockshttpclient socksudpclient udpserver # Run docker integration tests. .PHONY: run-container-test diff --git a/mieru/test/deploy/apiclient/Dockerfile b/mieru/test/deploy/apiclient/Dockerfile index e9d969bd82..c0b2d7b788 100644 --- a/mieru/test/deploy/apiclient/Dockerfile +++ b/mieru/test/deploy/apiclient/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY exampleapiclient mita httpserver sockshttpclient socksudpclient udpserver \ +COPY bin/exampleapiclient bin/mita bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \ test/deploy/apiclient/server_mix.json \ test/deploy/apiclient/test.sh /test/ diff --git a/mieru/test/deploy/apiserver/Dockerfile b/mieru/test/deploy/apiserver/Dockerfile index 256596c865..67499cd6f5 100644 --- a/mieru/test/deploy/apiserver/Dockerfile +++ b/mieru/test/deploy/apiserver/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY exampleapiserver mieru httpserver sockshttpclient socksudpclient udpserver \ +COPY bin/exampleapiserver bin/mieru bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \ test/deploy/apiserver/client_tcp_no_wait.json \ test/deploy/apiserver/client_tcp.json \ test/deploy/apiserver/client_udp_no_wait.json \ diff --git a/mieru/test/deploy/basic/Dockerfile b/mieru/test/deploy/basic/Dockerfile index b2dfc4015d..2bcd69279b 100644 --- a/mieru/test/deploy/basic/Dockerfile +++ b/mieru/test/deploy/basic/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY exampleapiclient mieru mita httpserver sockshttpclient socksudpclient udpserver \ +COPY bin/exampleapiclient bin/mieru bin/mita bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \ test/deploy/basic/client_mix.json test/deploy/basic/server_mix.json \ test/deploy/basic/client_tcp.json test/deploy/basic/client_tcp_no_wait.json test/deploy/basic/server_tcp.json \ test/deploy/basic/client_udp.json test/deploy/basic/client_udp_no_wait.json test/deploy/basic/server_udp.json \ diff --git a/mieru/test/deploy/mihomo/Dockerfile b/mieru/test/deploy/mihomo/Dockerfile index c245f82fa2..588f56f70d 100644 --- a/mieru/test/deploy/mihomo/Dockerfile +++ b/mieru/test/deploy/mihomo/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY mihomo mieru mita httpserver sockshttpclient socksudpclient udpserver \ +COPY bin/mihomo bin/mieru bin/mita bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \ test/deploy/mihomo/mihomo-client-tcp.yaml \ test/deploy/mihomo/mihomo-client-tcp-no-wait.yaml \ test/deploy/mihomo/mihomo-client-udp.yaml \ diff --git a/mieru/test/deploy/proxychain/Dockerfile b/mieru/test/deploy/proxychain/Dockerfile index d91cca56ea..a81f43f38d 100644 --- a/mieru/test/deploy/proxychain/Dockerfile +++ b/mieru/test/deploy/proxychain/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY mieru mieru2 mita mita2 httpserver sockshttpclient \ +COPY bin/mieru bin/mieru2 bin/mita bin/mita2 bin/httpserver bin/sockshttpclient \ test/deploy/proxychain/client1.json test/deploy/proxychain/client2.json \ test/deploy/proxychain/server1.json test/deploy/proxychain/server2.json \ test/deploy/proxychain/test.sh /test/ diff --git a/mieru/test/deploy/singbox/Dockerfile b/mieru/test/deploy/singbox/Dockerfile index fb823702a0..1b672c2109 100644 --- a/mieru/test/deploy/singbox/Dockerfile +++ b/mieru/test/deploy/singbox/Dockerfile @@ -20,7 +20,7 @@ FROM ubuntu:24.04 WORKDIR /test # Copy binaries, data and test script into the container. -COPY sing-box mita httpserver sockshttpclient socksudpclient udpserver \ +COPY bin/sing-box bin/mita bin/httpserver bin/sockshttpclient bin/socksudpclient bin/udpserver \ test/deploy/singbox/singbox-config-tcp.json \ test/deploy/singbox/singbox-config-udp.json \ test/deploy/singbox/server_tcp.json \ diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index 864b46489e..647566c970 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -820,7 +820,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -927,7 +927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1469,7 +1469,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.5.10", "system-configuration", "tokio", "tower-service", @@ -2116,7 +2116,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2441,7 +2441,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.1", + "socket2 0.5.10", "thiserror", "tokio", "tracing", @@ -2478,9 +2478,9 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.5.10", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -2593,9 +2593,9 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.24" +version = "0.12.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" dependencies = [ "base64", "bytes", @@ -2747,7 +2747,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3432,7 +3432,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3637,9 +3637,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.10.0", "bytes", @@ -4060,7 +4060,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/sing-box/.github/setup_musl_cross.sh b/sing-box/.github/setup_musl_cross.sh new file mode 100755 index 0000000000..b56cf4bfa9 --- /dev/null +++ b/sing-box/.github/setup_musl_cross.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -xeuo pipefail + +TARGET="$1" + +# Download musl-cross toolchain from musl.cc +cd "$HOME" +wget -q "https://musl.cc/${TARGET}-cross.tgz" +mkdir -p musl-cross +tar -xf "${TARGET}-cross.tgz" -C musl-cross --strip-components=1 +rm "${TARGET}-cross.tgz" diff --git a/sing-box/.github/update_cronet.sh b/sing-box/.github/update_cronet.sh new file mode 100755 index 0000000000..87310ffc2b --- /dev/null +++ b/sing-box/.github/update_cronet.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +PROJECTS=$(dirname "$0")/../.. +git -C $PROJECTS/cronet-go fetch origin go +go get -x github.com/sagernet/cronet-go/all@$(git -C $PROJECTS/cronet-go rev-parse origin/go) + +go mod tidy diff --git a/sing-box/.github/workflows/build.yml b/sing-box/.github/workflows/build.yml index b5a86c87c3..3f6d410b22 100644 --- a/sing-box/.github/workflows/build.yml +++ b/sing-box/.github/workflows/build.yml @@ -143,6 +143,9 @@ jobs: run: | set -xeuo pipefail TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,badlinkname,tfogo_checklinkname0' + if [[ "${{ matrix.os }}" == "android" ]]; then + TAGS="${TAGS},with_naive_outbound" + fi echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}" - name: Build if: matrix.os != 'android' @@ -315,7 +318,7 @@ jobs: - name: Set build tags run: | set -xeuo pipefail - TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,badlinkname,tfogo_checklinkname0' + TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,badlinkname,tfogo_checklinkname0' echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}" - name: Build run: | @@ -352,6 +355,128 @@ jobs: with: name: binary-darwin_${{ matrix.arch }}${{ matrix.legacy_name && format('-legacy-{0}', matrix.legacy_name) }} path: "dist" + build_naive_linux: + name: Build Linux with naive outbound + if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Binary' + runs-on: ubuntu-latest + needs: + - calculate_version + strategy: + matrix: + include: + # Linux glibc (dynamic linking with Debian Bullseye sysroot) + - { arch: amd64, sysroot_arch: amd64, sysroot_sha: "36a164623d03f525e3dfb783a5e9b8a00e98e1ddd2b5cff4e449bd016dd27e50", cc_target: "x86_64-linux-gnu", suffix: "-naive" } + - { arch: arm64, sysroot_arch: arm64, sysroot_sha: "2f915d821eec27515c0c6d21b69898e23762908d8d7ccc1aa2a8f5f25e8b7e18", cc_target: "aarch64-linux-gnu", suffix: "-naive" } + - { arch: "386", sysroot_arch: i386, sysroot_sha: "63f0e5128b84f7b0421956a4a40affa472be8da0e58caf27e9acbc84072daee7", cc_target: "i686-linux-gnu", suffix: "-naive" } + - { arch: arm, goarm: "7", sysroot_arch: armhf, sysroot_sha: "47b3a0b161ca011b2b33d4fc1ef6ef269b8208a0b7e4c900700c345acdfd1814", cc_target: "arm-linux-gnueabihf", suffix: "-naive" } + # Linux musl (static linking) + - { arch: amd64, musl: true, cc_target: "x86_64-linux-musl", suffix: "-naive-musl" } + - { arch: arm64, musl: true, cc_target: "aarch64-linux-musl", suffix: "-naive-musl" } + - { arch: "386", musl: true, cc_target: "i686-linux-musl", suffix: "-naive-musl" } + - { arch: arm, goarm: "7", musl: true, cc_target: "arm-linux-musleabihf", suffix: "-naive-musl" } + 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" >> "$GITHUB_ENV" + git tag v${{ needs.calculate_version.outputs.version }} -f + - name: Download sysroot (glibc) + if: ${{ ! matrix.musl }} + run: | + set -xeuo pipefail + wget -q "https://commondatastorage.googleapis.com/chrome-linux-sysroot/${{ matrix.sysroot_sha }}" -O sysroot.tar.xz + mkdir -p /tmp/sysroot + tar -xf sysroot.tar.xz -C /tmp/sysroot + - name: Install cross compiler (glibc) + if: ${{ ! matrix.musl }} + run: | + set -xeuo pipefail + sudo apt-get update + sudo apt-get install -y clang lld + if [[ "${{ matrix.arch }}" == "arm64" ]]; then + sudo apt-get install -y libc6-dev-arm64-cross + elif [[ "${{ matrix.arch }}" == "386" ]]; then + sudo apt-get install -y libc6-dev-i386-cross + elif [[ "${{ matrix.arch }}" == "arm" ]]; then + sudo apt-get install -y libc6-dev-armhf-cross + fi + - name: Install musl cross compiler + if: matrix.musl + run: | + set -xeuo pipefail + .github/setup_musl_cross.sh "${{ matrix.cc_target }}" + echo "PATH=$HOME/musl-cross/bin:$PATH" >> $GITHUB_ENV + - name: Set build tags + run: | + set -xeuo pipefail + TAGS='with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_naive_outbound,badlinkname,tfogo_checklinkname0' + if [[ "${{ matrix.musl }}" == "true" ]]; then + TAGS="${TAGS},with_musl" + fi + echo "BUILD_TAGS=${TAGS}" >> "${GITHUB_ENV}" + - name: Build (glibc) + if: ${{ ! matrix.musl }} + 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 }} -checklinkname=0 -linkmode=external -extldflags "-fuse-ld=lld --sysroot=/tmp/sysroot"' \ + ./cmd/sing-box + env: + CGO_ENABLED: "1" + GOOS: linux + GOARCH: ${{ matrix.arch }} + GOARM: ${{ matrix.goarm }} + CC: "clang --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot" + CXX: "clang++ --target=${{ matrix.cc_target }} --sysroot=/tmp/sysroot" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Build (musl) + if: matrix.musl + 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 }} -checklinkname=0 -linkmode=external -extldflags "-static"' \ + ./cmd/sing-box + env: + CGO_ENABLED: "1" + GOOS: linux + GOARCH: ${{ matrix.arch }} + GOARM: ${{ matrix.goarm }} + CC: "${{ matrix.cc_target }}-gcc" + CXX: "${{ matrix.cc_target }}-g++" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Set name + run: |- + DIR_NAME="sing-box-${{ needs.calculate_version.outputs.version }}-linux-${{ matrix.arch }}" + if [[ -n "${{ matrix.goarm }}" ]]; then + DIR_NAME="${DIR_NAME}v${{ matrix.goarm }}" + fi + DIR_NAME="${DIR_NAME}${{ matrix.suffix }}" + 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-linux_${{ matrix.arch }}${{ matrix.goarm && format('v{0}', matrix.goarm) }}${{ matrix.suffix }} + path: "dist" build_android: name: Build Android if: github.event_name != 'workflow_dispatch' || inputs.build == 'All' || inputs.build == 'Android' @@ -687,6 +812,7 @@ jobs: - calculate_version - build - build_darwin + - build_naive_linux - build_android - build_apple steps: diff --git a/sing-box/go.mod b/sing-box/go.mod index ebbdf620e6..cc1e824e70 100644 --- a/sing-box/go.mod +++ b/sing-box/go.mod @@ -25,6 +25,8 @@ require ( 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-20251209163619-43499a42c286 + github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3 github.com/sagernet/fswatch v0.1.1 github.com/sagernet/gomobile v0.1.8 github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1 @@ -104,6 +106,24 @@ require ( github.com/prometheus-community/pro-bing v0.4.0 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/safchain/ethtool v0.3.0 // indirect + github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286 // indirect + github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286 // indirect github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect github.com/sagernet/nftables v0.3.0-beta.4 // indirect github.com/spf13/pflag v1.0.6 // indirect diff --git a/sing-box/go.sum b/sing-box/go.sum index 10f0568460..4fe8031544 100644 --- a/sing-box/go.sum +++ b/sing-box/go.sum @@ -150,6 +150,46 @@ 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-20251209163619-43499a42c286 h1:T3l7r/FRNyf6AS1ZZfvFMYtTCozKWgm/mNXjmg/HqOw= +github.com/sagernet/cronet-go v0.0.0-20251209163619-43499a42c286/go.mod h1:l5IZJLEWpDGJbrF0qBHgxAVBPsAxKOLa1BYDh6B2sdI= +github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3 h1:a6/HHQ2bBrX4humT9jSACAD9kj4ucgal5tYWjOpxsXA= +github.com/sagernet/cronet-go/all v0.0.0-20251209163943-9ad85d71d2e3/go.mod h1:bq4r/IRzbgNUWfcWxJTyex/jKzI6WCSPfrCK3ns4O3A= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286 h1:sZFASnzhbYtPJoz+7OAx7IC85161iROwEkmHVQcaHS0= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286 h1:XmPpSRMDde4Oi5XzYBuOqWAvzPQsNjmKQfft98OlvLg= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286 h1:EEn7N5sCLZwnmlZjYb63Ewt2SjfYKTQwlQqEaC0zyF8= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209163619-43499a42c286/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286 h1:UA4/kKm8qA694fO7Y9EAe9csHecdBgAoKyn5CzUdAig= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286 h1:Cz1iXs54Urg23BRtdkikDUzaifE72lNwq3D+DHZTVXE= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286 h1:9f7dGYztdhJHqnGxAfg6e3pwiQc7gCIFfbnpYUG8+l4= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286 h1:cVnXsYi+qvBGxtv5i5qzx05Ol0go4/ZVhEB/nwKdZxE= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286 h1:L/M8nypnkrbv+zSFBEzoU3E2WVYoL/+BiF7W/ZGOkcE= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286 h1:UcNkxALcHUpo49DBHr2epN00hTRRiijwh4qv1fdXgRQ= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286 h1:R68J9khidtJRKka3J2dNVKVGrBq0ieevNRS3P8vijMw= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286 h1:aDxXLIVS219vxa56UN1ak9Grju6UWKhX0ULw7RGDIgs= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286 h1:r4eaHyVT7KWguRhYTudhq+RHsd0pq7HHP/xLn3v/NuI= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209163619-43499a42c286/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286 h1:TYxTK8434FqUokQKzg5Qs8xpjU8ws2VVn7J4gfL0jY0= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209163619-43499a42c286/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286 h1:2dysrFpUGjR/BePrJYoGyl8UmqlEY67g8ySyI2p1cjA= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286 h1:edRSfV1xEloFgpdiordf0S653D5r0exHN4X85BT06nk= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209163619-43499a42c286/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= +github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286 h1:CUWmGJ8PslWMJHanzgxF9+CuN4fk4NigKwxw1tjpdRY= +github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209163619-43499a42c286/go.mod h1:rnS7D+ULJX2PrP0Cy+05GS0mRZ2PP6+gVSroZKt8fjk= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286 h1:2/fTHNBvTGgxWALqogKGpzKw1zLgc5lSidMRchLcoqk= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209163619-43499a42c286/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286 h1:J1nQYpbALQGlCOuErF0/lI3SnwPd0egy/iUxhgRK76g= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209163619-43499a42c286/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.8 h1:vXgoN0pjsMONAaYCTdsKBX2T1kxuS7sbT/mZ7PElGoo= diff --git a/sing-box/include/naive_outbound.go b/sing-box/include/naive_outbound.go new file mode 100644 index 0000000000..d15d0450c6 --- /dev/null +++ b/sing-box/include/naive_outbound.go @@ -0,0 +1,12 @@ +//go:build with_naive_outbound + +package include + +import ( + "github.com/sagernet/sing-box/adapter/outbound" + "github.com/sagernet/sing-box/protocol/naive" +) + +func registerNaiveOutbound(registry *outbound.Registry) { + naive.RegisterOutbound(registry) +} diff --git a/sing-box/include/naive_outbound_stub.go b/sing-box/include/naive_outbound_stub.go new file mode 100644 index 0000000000..cf892091d6 --- /dev/null +++ b/sing-box/include/naive_outbound_stub.go @@ -0,0 +1,20 @@ +//go:build !with_naive_outbound + +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 registerNaiveOutbound(registry *outbound.Registry) { + outbound.Register[option.NaiveOutboundOptions](registry, C.TypeNaive, func(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.NaiveOutboundOptions) (adapter.Outbound, error) { + return nil, E.New(`naive outbound is not included in this build, rebuild with -tags with_naive_outbound`) + }) +} diff --git a/sing-box/include/registry.go b/sing-box/include/registry.go index 9965bc5e1f..8f08189d40 100644 --- a/sing-box/include/registry.go +++ b/sing-box/include/registry.go @@ -86,6 +86,7 @@ func OutboundRegistry() *outbound.Registry { shadowsocks.RegisterOutbound(registry) vmess.RegisterOutbound(registry) trojan.RegisterOutbound(registry) + registerNaiveOutbound(registry) tor.RegisterOutbound(registry) ssh.RegisterOutbound(registry) shadowtls.RegisterOutbound(registry) diff --git a/sing-box/option/naive.go b/sing-box/option/naive.go index 0b19f26473..50f034541e 100644 --- a/sing-box/option/naive.go +++ b/sing-box/option/naive.go @@ -1,6 +1,9 @@ package option -import "github.com/sagernet/sing/common/auth" +import ( + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" +) type NaiveInboundOptions struct { ListenOptions @@ -8,3 +11,13 @@ type NaiveInboundOptions struct { Network NetworkList `json:"network,omitempty"` InboundTLSOptionsContainer } + +type NaiveOutboundOptions struct { + DialerOptions + ServerOptions + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + InsecureConcurrency int `json:"insecure_concurrency,omitempty"` + ExtraHeaders badoption.HTTPHeader `json:"extra_headers,omitempty"` + OutboundTLSOptionsContainer +} diff --git a/sing-box/protocol/naive/inbound.go b/sing-box/protocol/naive/inbound.go index 21371f49d7..6354f011c5 100644 --- a/sing-box/protocol/naive/inbound.go +++ b/sing-box/protocol/naive/inbound.go @@ -2,8 +2,8 @@ package naive import ( "context" + "errors" "io" - "math/rand" "net" "net/http" @@ -22,7 +22,11 @@ import ( "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" + + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" ) var ConfigureHTTP3ListenerFunc func(listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, logger logger.Logger) (io.Closer, error) @@ -82,16 +86,11 @@ func (n *Inbound) Start(stage adapter.StartStage) error { if stage != adapter.StartStateStart { return nil } - var tlsConfig *tls.STDConfig if n.tlsConfig != nil { err := n.tlsConfig.Start() if err != nil { return E.Cause(err, "create TLS config") } - tlsConfig, err = n.tlsConfig.STDConfig() - if err != nil { - return err - } } if common.Contains(n.network, N.NetworkTCP) { tcpListener, err := n.listener.ListenTCP() @@ -99,20 +98,23 @@ func (n *Inbound) Start(stage adapter.StartStage) error { return err } n.httpServer = &http.Server{ - Handler: n, - TLSConfig: tlsConfig, + Handler: h2c.NewHandler(n, &http2.Server{}), BaseContext: func(listener net.Listener) context.Context { return n.ctx }, } go func() { - var sErr error - if tlsConfig != nil { - sErr = n.httpServer.ServeTLS(tcpListener, "", "") - } else { - sErr = n.httpServer.Serve(tcpListener) + listener := net.Listener(tcpListener) + if n.tlsConfig != nil { + if len(n.tlsConfig.NextProtos()) == 0 { + n.tlsConfig.SetNextProtos([]string{http2.NextProtoTLS, "http/1.1"}) + } else if !common.Contains(n.tlsConfig.NextProtos(), http2.NextProtoTLS) { + n.tlsConfig.SetNextProtos(append([]string{http2.NextProtoTLS}, n.tlsConfig.NextProtos()...)) + } + listener = aTLS.NewListener(tcpListener, n.tlsConfig) } - if sErr != nil && !E.IsClosedOrCanceled(sErr) { + sErr := n.httpServer.Serve(listener) + if sErr != nil && !errors.Is(sErr, http.ErrServerClosed) { n.logger.Error("http server serve error: ", sErr) } }() @@ -161,13 +163,16 @@ func (n *Inbound) ServeHTTP(writer http.ResponseWriter, request *http.Request) { n.badRequest(ctx, request, E.New("authorization failed")) return } - writer.Header().Set("Padding", generateNaivePaddingHeader()) + writer.Header().Set("Padding", generatePaddingHeader()) writer.WriteHeader(http.StatusOK) writer.(http.Flusher).Flush() - hostPort := request.URL.Host + hostPort := request.Header.Get("-connect-authority") if hostPort == "" { - hostPort = request.Host + hostPort = request.URL.Host + if hostPort == "" { + hostPort = request.Host + } } source := sHttp.SourceAddress(request) destination := M.ParseSocksaddr(hostPort).Unwrap() @@ -178,9 +183,14 @@ func (n *Inbound) ServeHTTP(writer http.ResponseWriter, request *http.Request) { n.badRequest(ctx, request, E.New("hijack failed")) return } - n.newConnection(ctx, false, &naiveH1Conn{Conn: conn}, userName, source, destination) + n.newConnection(ctx, false, &naiveConn{Conn: conn}, userName, source, destination) } else { - n.newConnection(ctx, true, &naiveH2Conn{reader: request.Body, writer: writer, flusher: writer.(http.Flusher)}, userName, source, destination) + n.newConnection(ctx, true, &naiveH2Conn{ + reader: request.Body, + writer: writer, + flusher: writer.(http.Flusher), + remoteAddress: source, + }, userName, source, destination) } } @@ -236,18 +246,3 @@ func rejectHTTP(writer http.ResponseWriter, statusCode int) { } conn.Close() } - -func generateNaivePaddingHeader() string { - paddingLen := rand.Intn(32) + 30 - padding := make([]byte, paddingLen) - bits := rand.Uint64() - for i := 0; i < 16; i++ { - // Codes that won't be Huffman coded. - padding[i] = "!#$()+<>?@[]^`{}"[bits&15] - bits >>= 4 - } - for i := 16; i < paddingLen; i++ { - padding[i] = '~' - } - return string(padding) -} diff --git a/sing-box/protocol/naive/inbound_conn.go b/sing-box/protocol/naive/inbound_conn.go index 16944cbaff..1dbb2bd828 100644 --- a/sing-box/protocol/naive/inbound_conn.go +++ b/sing-box/protocol/naive/inbound_conn.go @@ -7,417 +7,242 @@ import ( "net" "net/http" "os" - "strings" "time" "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/baderror" "github.com/sagernet/sing/common/buf" M "github.com/sagernet/sing/common/metadata" "github.com/sagernet/sing/common/rw" ) -const kFirstPaddings = 8 +const paddingCount = 8 -type naiveH1Conn struct { - net.Conn +func generatePaddingHeader() string { + paddingLen := rand.Intn(32) + 30 + padding := make([]byte, paddingLen) + bits := rand.Uint64() + for i := 0; i < 16; i++ { + padding[i] = "!#$()+<>?@[]^`{}"[bits&15] + bits >>= 4 + } + for i := 16; i < paddingLen; i++ { + padding[i] = '~' + } + return string(padding) +} + +type paddingConn struct { readPadding int writePadding int readRemaining int paddingRemaining int } -func (c *naiveH1Conn) Read(p []byte) (n int, err error) { - n, err = c.read(p) - return n, wrapHttpError(err) -} - -func (c *naiveH1Conn) read(p []byte) (n int, err error) { - if c.readRemaining > 0 { - if len(p) > c.readRemaining { - p = p[:c.readRemaining] +func (p *paddingConn) readWithPadding(reader io.Reader, buffer []byte) (n int, err error) { + if p.readRemaining > 0 { + if len(buffer) > p.readRemaining { + buffer = buffer[:p.readRemaining] } - n, err = c.Conn.Read(p) + n, err = reader.Read(buffer) if err != nil { return } - c.readRemaining -= n + p.readRemaining -= n return } - if c.paddingRemaining > 0 { - err = rw.SkipN(c.Conn, c.paddingRemaining) + if p.paddingRemaining > 0 { + err = rw.SkipN(reader, p.paddingRemaining) if err != nil { return } - c.paddingRemaining = 0 + p.paddingRemaining = 0 } - if c.readPadding < kFirstPaddings { - var paddingHdr []byte - if len(p) >= 3 { - paddingHdr = p[:3] + if p.readPadding < paddingCount { + var paddingHeader []byte + if len(buffer) >= 3 { + paddingHeader = buffer[:3] } else { - paddingHdr = make([]byte, 3) + paddingHeader = make([]byte, 3) } - _, err = io.ReadFull(c.Conn, paddingHdr) + _, err = io.ReadFull(reader, paddingHeader) if err != nil { return } - originalDataSize := int(binary.BigEndian.Uint16(paddingHdr[:2])) - paddingSize := int(paddingHdr[2]) - if len(p) > originalDataSize { - p = p[:originalDataSize] + originalDataSize := int(binary.BigEndian.Uint16(paddingHeader[:2])) + paddingSize := int(paddingHeader[2]) + if len(buffer) > originalDataSize { + buffer = buffer[:originalDataSize] } - n, err = c.Conn.Read(p) + n, err = reader.Read(buffer) if err != nil { return } - c.readPadding++ - c.readRemaining = originalDataSize - n - c.paddingRemaining = paddingSize + p.readPadding++ + p.readRemaining = originalDataSize - n + p.paddingRemaining = paddingSize return } - return c.Conn.Read(p) + return reader.Read(buffer) } -func (c *naiveH1Conn) Write(p []byte) (n int, err error) { - for pLen := len(p); pLen > 0; { - var data []byte - if pLen > 65535 { - data = p[:65535] - p = p[65535:] - pLen -= 65535 - } else { - data = p - pLen = 0 - } - var writeN int - writeN, err = c.write(data) - n += writeN - if err != nil { - break - } - } - return n, wrapHttpError(err) -} - -func (c *naiveH1Conn) write(p []byte) (n int, err error) { - if c.writePadding < kFirstPaddings { +func (p *paddingConn) writeWithPadding(writer io.Writer, data []byte) (n int, err error) { + if p.writePadding < paddingCount { paddingSize := rand.Intn(256) - - buffer := buf.NewSize(3 + len(p) + paddingSize) + buffer := buf.NewSize(3 + len(data) + paddingSize) defer buffer.Release() header := buffer.Extend(3) - binary.BigEndian.PutUint16(header, uint16(len(p))) + binary.BigEndian.PutUint16(header, uint16(len(data))) header[2] = byte(paddingSize) - - common.Must1(buffer.Write(p)) - _, err = c.Conn.Write(buffer.Bytes()) + common.Must1(buffer.Write(data)) + _, err = writer.Write(buffer.Bytes()) if err == nil { - n = len(p) + n = len(data) } - c.writePadding++ + p.writePadding++ return } - return c.Conn.Write(p) + return writer.Write(data) } -func (c *naiveH1Conn) FrontHeadroom() int { - if c.writePadding < kFirstPaddings { - return 3 - } - return 0 -} - -func (c *naiveH1Conn) RearHeadroom() int { - if c.writePadding < kFirstPaddings { - return 255 - } - return 0 -} - -func (c *naiveH1Conn) WriterMTU() int { - if c.writePadding < kFirstPaddings { - return 65535 - } - return 0 -} - -func (c *naiveH1Conn) WriteBuffer(buffer *buf.Buffer) error { - defer buffer.Release() - if c.writePadding < kFirstPaddings { +func (p *paddingConn) writeBufferWithPadding(writer io.Writer, buffer *buf.Buffer) error { + if p.writePadding < paddingCount { bufferLen := buffer.Len() if bufferLen > 65535 { - return common.Error(c.Write(buffer.Bytes())) + _, err := p.writeChunked(writer, buffer.Bytes()) + return err } paddingSize := rand.Intn(256) header := buffer.ExtendHeader(3) binary.BigEndian.PutUint16(header, uint16(bufferLen)) header[2] = byte(paddingSize) buffer.Extend(paddingSize) - c.writePadding++ + p.writePadding++ } - return wrapHttpError(common.Error(c.Conn.Write(buffer.Bytes()))) + return common.Error(writer.Write(buffer.Bytes())) } -// FIXME -/*func (c *naiveH1Conn) WriteTo(w io.Writer) (n int64, err error) { - if c.readPadding < kFirstPaddings { - n, err = bufio.WriteToN(c, w, kFirstPaddings-c.readPadding) - } else { - n, err = bufio.Copy(w, c.Conn) - } - return n, wrapHttpError(err) -} - -func (c *naiveH1Conn) ReadFrom(r io.Reader) (n int64, err error) { - if c.writePadding < kFirstPaddings { - n, err = bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding) - } else { - n, err = bufio.Copy(c.Conn, r) - } - return n, wrapHttpError(err) -} -*/ - -func (c *naiveH1Conn) Upstream() any { - return c.Conn -} - -func (c *naiveH1Conn) ReaderReplaceable() bool { - return c.readPadding == kFirstPaddings -} - -func (c *naiveH1Conn) WriterReplaceable() bool { - return c.writePadding == kFirstPaddings -} - -type naiveH2Conn struct { - reader io.Reader - writer io.Writer - flusher http.Flusher - rAddr net.Addr - readPadding int - writePadding int - readRemaining int - paddingRemaining int -} - -func (c *naiveH2Conn) Read(p []byte) (n int, err error) { - n, err = c.read(p) - return n, wrapHttpError(err) -} - -func (c *naiveH2Conn) read(p []byte) (n int, err error) { - if c.readRemaining > 0 { - if len(p) > c.readRemaining { - p = p[:c.readRemaining] - } - n, err = c.reader.Read(p) - if err != nil { - return - } - c.readRemaining -= n - return - } - if c.paddingRemaining > 0 { - err = rw.SkipN(c.reader, c.paddingRemaining) - if err != nil { - return - } - c.paddingRemaining = 0 - } - if c.readPadding < kFirstPaddings { - var paddingHdr []byte - if len(p) >= 3 { - paddingHdr = p[:3] +func (p *paddingConn) writeChunked(writer io.Writer, data []byte) (n int, err error) { + for len(data) > 0 { + var chunk []byte + if len(data) > 65535 { + chunk = data[:65535] + data = data[65535:] } else { - paddingHdr = make([]byte, 3) + chunk = data + data = nil } - _, err = io.ReadFull(c.reader, paddingHdr) + var written int + written, err = p.writeWithPadding(writer, chunk) + n += written if err != nil { return } - originalDataSize := int(binary.BigEndian.Uint16(paddingHdr[:2])) - paddingSize := int(paddingHdr[2]) - if len(p) > originalDataSize { - p = p[:originalDataSize] - } - n, err = c.reader.Read(p) - if err != nil { - return - } - c.readPadding++ - c.readRemaining = originalDataSize - n - c.paddingRemaining = paddingSize - return } - return c.reader.Read(p) + return } -func (c *naiveH2Conn) Write(p []byte) (n int, err error) { - for pLen := len(p); pLen > 0; { - var data []byte - if pLen > 65535 { - data = p[:65535] - p = p[65535:] - pLen -= 65535 - } else { - data = p - pLen = 0 - } - var writeN int - writeN, err = c.write(data) - n += writeN - if err != nil { - break - } - } - if err == nil { - c.flusher.Flush() - } - return n, wrapHttpError(err) -} - -func (c *naiveH2Conn) write(p []byte) (n int, err error) { - if c.writePadding < kFirstPaddings { - paddingSize := rand.Intn(256) - - buffer := buf.NewSize(3 + len(p) + paddingSize) - defer buffer.Release() - header := buffer.Extend(3) - binary.BigEndian.PutUint16(header, uint16(len(p))) - header[2] = byte(paddingSize) - - common.Must1(buffer.Write(p)) - _, err = c.writer.Write(buffer.Bytes()) - if err == nil { - n = len(p) - } - c.writePadding++ - return - } - return c.writer.Write(p) -} - -func (c *naiveH2Conn) FrontHeadroom() int { - if c.writePadding < kFirstPaddings { +func (p *paddingConn) frontHeadroom() int { + if p.writePadding < paddingCount { return 3 } return 0 } -func (c *naiveH2Conn) RearHeadroom() int { - if c.writePadding < kFirstPaddings { +func (p *paddingConn) rearHeadroom() int { + if p.writePadding < paddingCount { return 255 } return 0 } -func (c *naiveH2Conn) WriterMTU() int { - if c.writePadding < kFirstPaddings { +func (p *paddingConn) writerMTU() int { + if p.writePadding < paddingCount { return 65535 } return 0 } +func (p *paddingConn) readerReplaceable() bool { + return p.readPadding == paddingCount +} + +func (p *paddingConn) writerReplaceable() bool { + return p.writePadding == paddingCount +} + +type naiveConn struct { + net.Conn + paddingConn +} + +func (c *naiveConn) Read(p []byte) (n int, err error) { + n, err = c.readWithPadding(c.Conn, p) + return n, baderror.WrapH2(err) +} + +func (c *naiveConn) Write(p []byte) (n int, err error) { + n, err = c.writeChunked(c.Conn, p) + return n, baderror.WrapH2(err) +} + +func (c *naiveConn) WriteBuffer(buffer *buf.Buffer) error { + defer buffer.Release() + err := c.writeBufferWithPadding(c.Conn, buffer) + return baderror.WrapH2(err) +} + +func (c *naiveConn) FrontHeadroom() int { return c.frontHeadroom() } +func (c *naiveConn) RearHeadroom() int { return c.rearHeadroom() } +func (c *naiveConn) WriterMTU() int { return c.writerMTU() } +func (c *naiveConn) Upstream() any { return c.Conn } +func (c *naiveConn) ReaderReplaceable() bool { return c.readerReplaceable() } +func (c *naiveConn) WriterReplaceable() bool { return c.writerReplaceable() } + +type naiveH2Conn struct { + reader io.Reader + writer io.Writer + flusher http.Flusher + remoteAddress net.Addr + paddingConn +} + +func (c *naiveH2Conn) Read(p []byte) (n int, err error) { + n, err = c.readWithPadding(c.reader, p) + return n, baderror.WrapH2(err) +} + +func (c *naiveH2Conn) Write(p []byte) (n int, err error) { + n, err = c.writeChunked(c.writer, p) + if err == nil { + c.flusher.Flush() + } + return n, baderror.WrapH2(err) +} + func (c *naiveH2Conn) WriteBuffer(buffer *buf.Buffer) error { defer buffer.Release() - if c.writePadding < kFirstPaddings { - bufferLen := buffer.Len() - if bufferLen > 65535 { - return common.Error(c.Write(buffer.Bytes())) - } - paddingSize := rand.Intn(256) - header := buffer.ExtendHeader(3) - binary.BigEndian.PutUint16(header, uint16(bufferLen)) - header[2] = byte(paddingSize) - buffer.Extend(paddingSize) - c.writePadding++ - } - err := common.Error(c.writer.Write(buffer.Bytes())) + err := c.writeBufferWithPadding(c.writer, buffer) if err == nil { c.flusher.Flush() } - return wrapHttpError(err) + return baderror.WrapH2(err) } -// FIXME -/*func (c *naiveH2Conn) WriteTo(w io.Writer) (n int64, err error) { - if c.readPadding < kFirstPaddings { - n, err = bufio.WriteToN(c, w, kFirstPaddings-c.readPadding) - } else { - n, err = bufio.Copy(w, c.reader) - } - return n, wrapHttpError(err) -} - -func (c *naiveH2Conn) ReadFrom(r io.Reader) (n int64, err error) { - if c.writePadding < kFirstPaddings { - n, err = bufio.ReadFromN(c, r, kFirstPaddings-c.writePadding) - } else { - n, err = bufio.Copy(c.writer, r) - } - return n, wrapHttpError(err) -}*/ - func (c *naiveH2Conn) Close() error { - return common.Close( - c.reader, - c.writer, - ) + return common.Close(c.reader, c.writer) } -func (c *naiveH2Conn) LocalAddr() net.Addr { - return M.Socksaddr{} -} - -func (c *naiveH2Conn) RemoteAddr() net.Addr { - return c.rAddr -} - -func (c *naiveH2Conn) SetDeadline(t time.Time) error { - return os.ErrInvalid -} - -func (c *naiveH2Conn) SetReadDeadline(t time.Time) error { - return os.ErrInvalid -} - -func (c *naiveH2Conn) SetWriteDeadline(t time.Time) error { - return os.ErrInvalid -} - -func (c *naiveH2Conn) NeedAdditionalReadDeadline() bool { - return true -} - -func (c *naiveH2Conn) UpstreamReader() any { - return c.reader -} - -func (c *naiveH2Conn) UpstreamWriter() any { - return c.writer -} - -func (c *naiveH2Conn) ReaderReplaceable() bool { - return c.readPadding == kFirstPaddings -} - -func (c *naiveH2Conn) WriterReplaceable() bool { - return c.writePadding == kFirstPaddings -} - -func wrapHttpError(err error) error { - if err == nil { - return err - } - if strings.Contains(err.Error(), "client disconnected") { - return net.ErrClosed - } - if strings.Contains(err.Error(), "body closed by handler") { - return net.ErrClosed - } - if strings.Contains(err.Error(), "canceled with error code 268") { - return io.EOF - } - return err -} +func (c *naiveH2Conn) LocalAddr() net.Addr { return M.Socksaddr{} } +func (c *naiveH2Conn) RemoteAddr() net.Addr { return c.remoteAddress } +func (c *naiveH2Conn) SetDeadline(t time.Time) error { return os.ErrInvalid } +func (c *naiveH2Conn) SetReadDeadline(t time.Time) error { return os.ErrInvalid } +func (c *naiveH2Conn) SetWriteDeadline(t time.Time) error { return os.ErrInvalid } +func (c *naiveH2Conn) NeedAdditionalReadDeadline() bool { return true } +func (c *naiveH2Conn) UpstreamReader() any { return c.reader } +func (c *naiveH2Conn) UpstreamWriter() any { return c.writer } +func (c *naiveH2Conn) FrontHeadroom() int { return c.frontHeadroom() } +func (c *naiveH2Conn) RearHeadroom() int { return c.rearHeadroom() } +func (c *naiveH2Conn) WriterMTU() int { return c.writerMTU() } +func (c *naiveH2Conn) ReaderReplaceable() bool { return c.readerReplaceable() } +func (c *naiveH2Conn) WriterReplaceable() bool { return c.writerReplaceable() } diff --git a/sing-box/protocol/naive/outbound.go b/sing-box/protocol/naive/outbound.go new file mode 100644 index 0000000000..48209ae856 --- /dev/null +++ b/sing-box/protocol/naive/outbound.go @@ -0,0 +1,179 @@ +//go:build with_naive_outbound + +package naive + +import ( + "context" + "net" + "os" + "strings" + + "github.com/sagernet/cronet-go" + _ "github.com/sagernet/cronet-go/all" + "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" +) + +func RegisterOutbound(registry *outbound.Registry) { + outbound.Register[option.NaiveOutboundOptions](registry, C.TypeNaive, NewOutbound) +} + +type Outbound struct { + outbound.Adapter + ctx context.Context + logger logger.ContextLogger + client *cronet.NaiveClient +} + +func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.NaiveOutboundOptions) (adapter.Outbound, error) { + if options.TLS == nil || !options.TLS.Enabled { + return nil, C.ErrTLSRequired + } + if options.TLS.DisableSNI { + return nil, E.New("disable_sni is not supported on naive outbound") + } + if options.TLS.Insecure { + return nil, E.New("insecure is not supported on naive outbound") + } + if len(options.TLS.ALPN) > 0 { + return nil, E.New("alpn is not supported on naive outbound") + } + if options.TLS.MinVersion != "" { + return nil, E.New("min_version is not supported on naive outbound") + } + if options.TLS.MaxVersion != "" { + return nil, E.New("max_version is not supported on naive outbound") + } + if len(options.TLS.CipherSuites) > 0 { + return nil, E.New("cipher_suites is not supported on naive outbound") + } + if len(options.TLS.CurvePreferences) > 0 { + return nil, E.New("curve_preferences is not supported on naive outbound") + } + if len(options.TLS.ClientCertificate) > 0 || options.TLS.ClientCertificatePath != "" { + return nil, E.New("client_certificate is not supported on naive outbound") + } + if len(options.TLS.ClientKey) > 0 || options.TLS.ClientKeyPath != "" { + return nil, E.New("client_key is not supported on naive outbound") + } + if options.TLS.Fragment || options.TLS.RecordFragment { + return nil, E.New("fragment is not supported on naive outbound") + } + if options.TLS.KernelTx || options.TLS.KernelRx { + return nil, E.New("kernel TLS is not supported on naive outbound") + } + if options.TLS.ECH != nil && options.TLS.ECH.Enabled { + return nil, E.New("ECH is not currently supported on naive outbound") + } + if options.TLS.UTLS != nil && options.TLS.UTLS.Enabled { + return nil, E.New("uTLS is not supported on naive outbound") + } + if options.TLS.Reality != nil && options.TLS.Reality.Enabled { + return nil, E.New("reality is not supported on naive outbound") + } + + serverAddress := options.ServerOptions.Build() + + var serverName string + if options.TLS.ServerName != "" { + serverName = options.TLS.ServerName + } else { + serverName = serverAddress.AddrString() + } + + outboundDialer, err := dialer.NewWithOptions(dialer.Options{ + Context: ctx, + Options: options.DialerOptions, + RemoteIsDomain: true, + ResolverOnDetour: true, + NewDialer: true, + }) + if err != nil { + return nil, err + } + + var trustedRootCertificates string + if len(options.TLS.Certificate) > 0 { + trustedRootCertificates = strings.Join(options.TLS.Certificate, "\n") + } else if options.TLS.CertificatePath != "" { + content, err := os.ReadFile(options.TLS.CertificatePath) + if err != nil { + return nil, E.Cause(err, "read certificate") + } + trustedRootCertificates = string(content) + } + + extraHeaders := make(map[string]string) + for key, values := range options.ExtraHeaders.Build() { + if len(values) > 0 { + extraHeaders[key] = values[0] + } + } + + client, err := cronet.NewNaiveClient(cronet.NaiveClientConfig{ + Context: ctx, + ServerAddress: serverAddress, + ServerName: serverName, + Username: options.Username, + Password: options.Password, + Concurrency: options.InsecureConcurrency, + ExtraHeaders: extraHeaders, + TrustedRootCertificates: trustedRootCertificates, + CertificatePublicKeySHA256: options.TLS.CertificatePublicKeySHA256, + Dialer: outboundDialer, + }) + if err != nil { + return nil, err + } + + return &Outbound{ + Adapter: outbound.NewAdapterWithDialerOptions(C.TypeNaive, tag, []string{N.NetworkTCP}, options.DialerOptions), + ctx: ctx, + logger: logger, + client: client, + }, nil +} + +func (o *Outbound) Start(stage adapter.StartStage) error { + if stage != adapter.StartStateStart { + return nil + } + err := o.client.Start() + if err != nil { + return err + } + o.logger.Info("NaiveProxy started, version: ", o.client.Engine().Version()) + return 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 + o.logger.InfoContext(ctx, "outbound connection to ", destination) + return o.client.DialContext(ctx, destination) +} + +func (o *Outbound) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { + return nil, os.ErrInvalid +} + +func (o *Outbound) Close() error { + return o.client.Close() +} + +func (o *Outbound) StartNetLogToFile(fileName string, logAll bool) bool { + return o.client.Engine().StartNetLogToFile(fileName, logAll) +} + +func (o *Outbound) StopNetLog() { + o.client.Engine().StopNetLog() +} diff --git a/sing-box/test/box_test.go b/sing-box/test/box_test.go index 152948d208..d7d9b9b047 100644 --- a/sing-box/test/box_test.go +++ b/sing-box/test/box_test.go @@ -88,7 +88,7 @@ func testSuit(t *testing.T, clientPort uint16, testPort uint16) { func testQUIC(t *testing.T, clientPort uint16) { dialer := socks.NewClient(N.SystemDialer, M.ParseSocksaddrHostPort("127.0.0.1", clientPort), socks.Version5, "", "") client := &http.Client{ - Transport: &http3.RoundTripper{ + Transport: &http3.Transport{ Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (*quic.Conn, error) { destination := M.ParseSocksaddr(addr) udpConn, err := dialer.DialContext(ctx, N.NetworkUDP, destination) diff --git a/sing-box/test/go.mod b/sing-box/test/go.mod index cca3009972..47b13ab57b 100644 --- a/sing-box/test/go.mod +++ b/sing-box/test/go.mod @@ -1,8 +1,6 @@ module test -go 1.23.1 - -toolchain go1.24.0 +go 1.24.7 require github.com/sagernet/sing-box v0.0.0 @@ -12,15 +10,15 @@ require ( github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 github.com/gofrs/uuid/v5 v5.3.2 - github.com/sagernet/quic-go v0.52.0-beta.1 - github.com/sagernet/sing v0.7.8-0.20250909124511-ab3827767cea - github.com/sagernet/sing-quic v0.5.2-0.20250909100920-da23407a63d5 + github.com/sagernet/quic-go v0.57.1-sing-box-mod.1 + github.com/sagernet/sing v0.8.0-beta.6.0.20251207063731-56fd482ce1c6 + github.com/sagernet/sing-quic v0.6.0-beta.5 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.10.0 + github.com/stretchr/testify v1.11.1 go.uber.org/goleak v1.3.0 - golang.org/x/net v0.43.0 + golang.org/x/net v0.44.0 ) require ( @@ -30,14 +28,16 @@ require ( 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/anytls/sing-anytls v0.0.8 // indirect - github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/anthropics/anthropic-sdk-go v1.14.0 // indirect + github.com/anytls/sing-anytls v0.0.11 // indirect github.com/caddyserver/certmagic v0.23.0 // indirect github.com/caddyserver/zerossl v0.1.3 // indirect github.com/coder/websocket v1.8.13 // indirect github.com/containerd/log v0.1.0 // indirect github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 // 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect github.com/digitalocean/go-smbios v0.0.0-20180907143718-390a4f403a8e // indirect @@ -46,10 +46,10 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/gaissmai/bart v0.11.1 // indirect + github.com/gaissmai/bart v0.18.0 // indirect github.com/go-chi/chi/v5 v5.2.2 // indirect github.com/go-chi/render v1.0.3 // indirect - github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -62,16 +62,14 @@ require ( 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/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 // indirect - github.com/gorilla/securecookie v1.1.2 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/hdevalence/ed25519consensus v0.2.0 // indirect - github.com/illarion/gonotify/v2 v2.0.3 // indirect + github.com/illarion/gonotify/v3 v3.0.2 // indirect github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f // indirect github.com/jsimonetti/rtnetlink v1.4.0 // indirect + github.com/keybase/go-keychain v0.0.1 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a // indirect github.com/libdns/alidns v1.0.5-libdns.v1.beta1 // indirect github.com/libdns/cloudflare v0.2.2-0.20250708034226-c574dccb31a6 // indirect github.com/libdns/libdns v1.1.0 // indirect @@ -80,8 +78,7 @@ require ( github.com/mdlayher/netlink v1.7.3-0.20250113171957-fbb4dce95f42 // indirect github.com/mdlayher/sdnotify v1.0.0 // indirect github.com/mdlayher/socket v0.5.1 // indirect - github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4 // indirect - github.com/metacubex/utls v1.8.0 // indirect + github.com/metacubex/utls v1.8.3 // indirect github.com/mholt/acmez/v3 v3.1.2 // indirect github.com/miekg/dns v1.1.67 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect @@ -94,30 +91,54 @@ require ( 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.5.1 // indirect + github.com/quic-go/qpack v0.6.0 // 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-20251209105322-5fda1568c42f // indirect + github.com/sagernet/cronet-go/all v0.0.0-20251209105322-5fda1568c42f // indirect + github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209104729-fbe170b6824a // indirect + github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209104729-fbe170b6824a // 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-mux v0.3.3 // indirect github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 // indirect - github.com/sagernet/sing-tun v0.8.0-beta.1.0.20250909100419-a8cb01e6df93 // indirect + github.com/sagernet/sing-tun v0.8.0-beta.11 // indirect github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 // indirect github.com/sagernet/smux v1.5.34-mod.2 // indirect - github.com/sagernet/tailscale v1.80.3-sing-box-1.13-mod.1 // indirect - github.com/sagernet/wireguard-go v0.0.1-beta.7 // indirect + github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4 // indirect + github.com/sagernet/wireguard-go v0.0.2-beta.1.0.20250917110311-16510ac47288 // indirect github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // 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/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 // indirect github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect 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/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da // 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/tidwall/sjson v1.2.5 // indirect github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect github.com/vishvananda/netns v0.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect @@ -133,15 +154,15 @@ require ( 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.41.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/mod v0.27.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/term v0.34.0 // indirect - golang.org/x/text v0.28.0 // indirect - golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.36.0 // indirect + golang.org/x/crypto v0.42.0 // indirect + golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect + golang.org/x/mod v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.11.0 // indirect + golang.org/x/tools v0.37.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect diff --git a/sing-box/test/go.sum b/sing-box/test/go.sum index 06bc779260..62dbe45e7c 100644 --- a/sing-box/test/go.sum +++ b/sing-box/test/go.sum @@ -12,10 +12,10 @@ github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7V 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/anytls/sing-anytls v0.0.8 h1:1u/fnH1HoeeMV5mX7/eUOjLBvPdkd1UJRmXiRi6Vymc= -github.com/anytls/sing-anytls v0.0.8/go.mod h1:7rjN6IukwysmdusYsrV51Fgu1uW6vsrdd6ctjnEAln8= -github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= -github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/anthropics/anthropic-sdk-go v1.14.0 h1:EzNQvnZlaDHe2UPkoUySDz3ixRgNbwKdH8KtFpv7pi4= +github.com/anthropics/anthropic-sdk-go v1.14.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE= +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.23.0 h1:CfpZ/50jMfG4+1J/u2LV6piJq4HOfO6ppOnOf7DkFEU= github.com/caddyserver/certmagic v0.23.0/go.mod h1:9mEZIWqqWoI+Gf+4Trh04MOVPD0tGSxtqsxg87hAIH4= github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= @@ -32,6 +32,10 @@ github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6 h1:8h5+bWd7R6 github.com/coreos/go-iptables v0.7.1-0.20240112124308-65c67c9f46e6/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= 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/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= @@ -54,16 +58,16 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos 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.11.1 h1:5Uv5XwsaFBRo4E5VBcb9TzY8B7zxFf+U7isDxqOrRfc= -github.com/gaissmai/bart v0.11.1/go.mod h1:KHeYECXQiBjTzQz/om2tqn3sZF1J7hw9m6z41ftj3fg= +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.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= 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-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288 h1:KbX3Z3CgiYlbaavUq3Cj9/MjpO+88S7/AGXzynVDv84= -github.com/go-json-experiment/json v0.0.0-20250103232110-6a9a0fde9288/go.mod h1:BWmvoE1Xia34f3l/ibJweyhrT+aROb/FQ6d+37F0e2s= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -89,36 +93,30 @@ 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.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30 h1:fiJdrgVBkjZ5B1HJ2WQwNOaXB+QyYcNXTA3t1XYLz0M= -github.com/gorilla/csrf v1.7.3-0.20250123201450-9dd6af1f6d30/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk= -github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= -github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= 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/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/illarion/gonotify/v2 v2.0.3 h1:B6+SKPo/0Sw8cRJh1aLzNEeNVFfzE3c6N+o+vyxM+9A= -github.com/illarion/gonotify/v2 v2.0.3/go.mod h1:38oIJTgFqupkEydkkClkbL6i5lXV/bxdH9do5TALPEE= +github.com/illarion/gonotify/v3 v3.0.2 h1:O7S6vcopHexutmpObkeWsnzMJt/r1hONIEogeVNmJMk= +github.com/illarion/gonotify/v3 v3.0.2/go.mod h1:HWGPdPe817GfvY3w7cx6zkbzNZfi3QjcBm/wgVvEL1U= github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f h1:dd33oobuIv9PcBVqvbEiCXEbNTomOHyj3WFuC5YiPRU= github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f/go.mod h1:zhFlBeJssZ1YBCMZ5Lzu1pX4vhftDvU10WUVb1uXKtM= github.com/jsimonetti/rtnetlink v1.4.0 h1:Z1BF0fRgcETPEa0Kt0MRk3yV5+kF1FWTni6KUFKrq2I= github.com/jsimonetti/rtnetlink v1.4.0/go.mod h1:5W1jDvWdnthFJ7fxYX1GMK07BUpI4oskfOqvPteYS6E= +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.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= -github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -140,10 +138,8 @@ github.com/mdlayher/sdnotify v1.0.0 h1:Ma9XeLVN/l0qpyx1tNeMSeTjCPH6NtuD6/N9XdTlQ github.com/mdlayher/sdnotify v1.0.0/go.mod h1:HQUmpM4XgYkhDLtd+Uad8ZFK1T9D5+pNxnXQjCeJlGE= 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/tfo-go v0.0.0-20250516165257-e29c16ae41d4 h1:j1VRTiC9JLR4nUbSikx9OGdu/3AgFDqgcLj4GoqyQkc= -github.com/metacubex/tfo-go v0.0.0-20250516165257-e29c16ae41d4/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= -github.com/metacubex/utls v1.8.0 h1:mSYi6FMnmc5riARl5UZDmWVy710z+P5b7xuGW0lV9ac= -github.com/metacubex/utls v1.8.0/go.mod h1:FdjYzVfCtgtna19hX0ER1Xsa5uJInwdQ4IcaaI98lEQ= +github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= +github.com/metacubex/utls v1.8.3/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= github.com/mholt/acmez/v3 v3.1.2 h1:auob8J/0FhmdClQicvJvuDavgd5ezwLBfKuYmynhYzc= github.com/mholt/acmez/v3 v3.1.2/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ= github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0= @@ -171,8 +167,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= -github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +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/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0= @@ -181,6 +177,46 @@ 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-20251209105322-5fda1568c42f h1:t21xtGXGuCNAFGVcFIqi+c+RANTe9J8nbWfdZUglKDo= +github.com/sagernet/cronet-go v0.0.0-20251209105322-5fda1568c42f/go.mod h1:l5IZJLEWpDGJbrF0qBHgxAVBPsAxKOLa1BYDh6B2sdI= +github.com/sagernet/cronet-go/all v0.0.0-20251209105322-5fda1568c42f h1:bvHw+A54OGC0FhLVPNfhVz76vPfC4MS+YZ89PbpkdSY= +github.com/sagernet/cronet-go/all v0.0.0-20251209105322-5fda1568c42f/go.mod h1:AgwG7INaHB65NL1Jti5pRUMyN3e/8q+CIfgYQzBogKg= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209104729-fbe170b6824a h1:vBsGqf9KbfW40So9W90o8gJjokOrBkGUYzqcwtkdUtY= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209104729-fbe170b6824a h1:KUmCNxHmQLqekUeGsiKU3uvd6KXpANb6SbLyMGkbSCo= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209104729-fbe170b6824a h1:kJi9gU3znoL82BV1ie5v25jbcNP3faPQjsVdsl3BlrY= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251209104729-fbe170b6824a/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209104729-fbe170b6824a h1:y0odF2cQviQFByRorA/XczaoxL60vISwX9si4oRiREw= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209104729-fbe170b6824a h1:Uft47JfHxyZGYBh4oZsOSk6ZGq0ShUfMegoRxfmnW8A= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209104729-fbe170b6824a h1:WyR+mvnGnGySZKCq4lFB4kA+eugr10Wm2oVa0A4eefk= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209104729-fbe170b6824a h1:M15EObCrQkGOYkCSa7xelNEl/rkzHp/ekoTW0J90naY= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209104729-fbe170b6824a h1:kYXvKGBGtWAV85UcL015M6t/vfLKWeqgQTtnSCyFoO0= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209104729-fbe170b6824a h1:5vzeO3jUzvYlSL9Ov4Zmm0+Rv0Wu+Yf2B6Q1aj7jKFE= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251209104729-fbe170b6824a/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209104729-fbe170b6824a h1:D7HZteO5APBtMd+YvmugvDoOR1scKPZCcmKW7GYY8iQ= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209104729-fbe170b6824a h1:mky6g8OXDa2jDe+7cYEFNaCY50SMfdJKkKRj8Xy1Zxo= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251209104729-fbe170b6824a/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209104729-fbe170b6824a h1:ps9wsaJdjg+i2HebFzH8zle7NRG/OukYpsyceEgAaR8= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251209104729-fbe170b6824a/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209104729-fbe170b6824a h1:zAg5miXnoT56/WcLp19pDsq+oigBf7WIGe6HZ6BVAuM= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209104729-fbe170b6824a h1:EWwQ9RQpHYwxb7GeBadFHoyPt3AL/cXd10fyXPpYk/w= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251209104729-fbe170b6824a/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209104729-fbe170b6824a h1:CxY/o/IjRFMjncGb3PA4hQRQ7xWcrPbqt7pAnBe7JCY= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251209104729-fbe170b6824a/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= +github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209104729-fbe170b6824a h1:a3cD0jh7Ute8fkxUxuSCqsXmixkl/iu6GhGn946NIgQ= +github.com/sagernet/cronet-go/lib/windows_386 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:rnS7D+ULJX2PrP0Cy+05GS0mRZ2PP6+gVSroZKt8fjk= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209104729-fbe170b6824a h1:yJiwftlutei2sQms2JLF6OaOUCvXLV2Uow0VHYHNtB0= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251209104729-fbe170b6824a/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209104729-fbe170b6824a h1:Wo0WzyvWUt4jnTKTFUW73SHRYsWrz7u3rX3f3oQIq68= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251209104729-fbe170b6824a/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= @@ -189,31 +225,31 @@ 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.52.0-beta.1 h1:hWkojLg64zjV+MJOvJU/kOeWndm3tiEfBLx5foisszs= -github.com/sagernet/quic-go v0.52.0-beta.1/go.mod h1:OV+V5kEBb8kJS7k29MzDu6oj9GyMc7HA07sE1tedxz4= +github.com/sagernet/quic-go v0.57.1-sing-box-mod.1 h1:6fhKbfA0b7L1CVekayV1g87uJFtMXFE0rFXR48SRrWI= +github.com/sagernet/quic-go v0.57.1-sing-box-mod.1/go.mod h1:OqILvS182CyOol5zNNo6bguvOGgXzV459+chpRaUC+4= github.com/sagernet/sing v0.6.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= -github.com/sagernet/sing v0.7.8-0.20250909124511-ab3827767cea h1:vkWFzPVlqnKq3FMpmh43ZVDbqHWapbv0Sh3vQc8oo7o= -github.com/sagernet/sing v0.7.8-0.20250909124511-ab3827767cea/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.8.0-beta.6.0.20251207063731-56fd482ce1c6 h1:EYaDzllFzNYnzQ9xH/ieSAXct4wQ8pD45kgNMo7RPZc= +github.com/sagernet/sing v0.8.0-beta.6.0.20251207063731-56fd482ce1c6/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/sagernet/sing-mux v0.3.3 h1:YFgt9plMWzH994BMZLmyKL37PdIVaIilwP0Jg+EcLfw= github.com/sagernet/sing-mux v0.3.3/go.mod h1:pht8iFY4c9Xltj7rhVd208npkNaeCxzyXCgulDPLUDA= -github.com/sagernet/sing-quic v0.5.2-0.20250909100920-da23407a63d5 h1:vnRNLE0bBnz5NNbBoFH7NA7mlvNSa2Z4w+1Eb8pyX48= -github.com/sagernet/sing-quic v0.5.2-0.20250909100920-da23407a63d5/go.mod h1:gi/sGED8gTWgTAp3GlzXo2D7mXYY+ERoxtGvSkNx3sI= +github.com/sagernet/sing-quic v0.6.0-beta.5 h1:kZfRLmsPxAgl0usZUgomDurLn7ZZ26lJWIpGow9ZWR4= +github.com/sagernet/sing-quic v0.6.0-beta.5/go.mod h1:9D9GANrK33NjWCe1VkU5L5+8MxU39WrduBSmHuHz8GA= 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.1.0.20250909100419-a8cb01e6df93 h1:jGkwe0Uk5litEUnvHO/c0nukm2FqvdwKHJio4kJIOxM= -github.com/sagernet/sing-tun v0.8.0-beta.1.0.20250909100419-a8cb01e6df93/go.mod h1:LokZYuEV3crByjQc/XRohLgfNvybtXdx5qe/I4W6S7k= +github.com/sagernet/sing-tun v0.8.0-beta.11 h1:xVi8VcVkvz2o+3v1PLv5MOkFpiVCwjLjucVlmigDi5c= +github.com/sagernet/sing-tun v0.8.0-beta.11/go.mod h1:eWETzl4AwaxGKiZTpDIDVJLTBz9cfIdoZwaZY1jlSjg= 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.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4= github.com/sagernet/smux v1.5.34-mod.2/go.mod h1:0KW0+R+ycvA2INW4gbsd7BNyg+HEfLIAxa5N02/28Zc= -github.com/sagernet/tailscale v1.80.3-sing-box-1.13-mod.1 h1:cWM1iPwqIE1t06ft80wpvFB4xbhOpIFI+TFnTw2gnbs= -github.com/sagernet/tailscale v1.80.3-sing-box-1.13-mod.1/go.mod h1:EBxXsWu4OH2ELbQLq32WoBeIubG8KgDrg4/Oaxjs6lI= -github.com/sagernet/wireguard-go v0.0.1-beta.7 h1:ltgBwYHfr+9Wz1eG59NiWnHrYEkDKHG7otNZvu85DXI= -github.com/sagernet/wireguard-go v0.0.1-beta.7/go.mod h1:jGXij2Gn2wbrWuYNUmmNhf1dwcZtvyAvQoe8Xd8MbUo= +github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4 h1:Ceg+9Ug+qAFgEchGodlHmMOY2h7KktQQDAyuoIsPbos= +github.com/sagernet/tailscale v1.86.5-sing-box-1.13-mod.4/go.mod h1:YdN/avjce8sqPFLT9E1uEh8gPewNSnC41U4ZhBJ+ACw= +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= @@ -229,14 +265,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.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/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= github.com/tailscale/go-winio v0.0.0-20231025203758-c4f33415bf55/go.mod h1:4k4QO+dQ3R5FofL+SanAUZe+/QfeK0+OIuwDIRu2vSg= -github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 h1:rXZGgEa+k2vJM8xT0PoSKfVXwFGPQ3z3CJfmnHJkZZw= -github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4/go.mod h1:ikbF+YT089eInTp9f2vmvy4+ZVnW5hzX1q2WknxSprQ= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 h1:4chzWmimtJPxRs2O36yuGRW3f9SYV+bMTTvMBI0EKio= github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05/go.mod h1:PdCqy9JzfWMJf1H5UJW2ip33/d4YkoKN0r67yKH1mG8= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= @@ -247,8 +281,20 @@ github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc h1:24heQPtnFR+y github.com/tailscale/peercred v0.0.0-20250107143737-35a0c7bd7edc/go.mod h1:f93CXfllFsO9ZQVq+Zocb1Gp4G5Fz0b0rXHLOzt/Djc= github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976 h1:UBPHPtv8+nEAy2PD8RyAhOYvau1ek0HDJqLS/Pysi14= github.com/tailscale/web-client-prebuilt v0.0.0-20250124233751-d4cd19a26976/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da h1:jVRUZPRs9sqyKlYHHzHjAqKN+6e/Vog6NpHYeNPJqOw= +github.com/tailscale/wireguard-go v0.0.0-20250716170648-1d0488a3d7da/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4= 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/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= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +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/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= @@ -300,30 +346,30 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= -golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= -golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +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/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.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= -golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= +golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= 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-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.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= 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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -335,24 +381,24 @@ golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= -golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= 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.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= -golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= 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= @@ -377,6 +423,8 @@ 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= +gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633 h1:2gap+Kh/3F47cO6hAu3idFvsJ0ue6TRcEi2IUkv/F8k= +gvisor.dev/gvisor v0.0.0-20250205023644-9414b50a5633/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= diff --git a/sing-box/test/naive_self_test.go b/sing-box/test/naive_self_test.go new file mode 100644 index 0000000000..6f9aa47f4d --- /dev/null +++ b/sing-box/test/naive_self_test.go @@ -0,0 +1,442 @@ +package main + +import ( + "crypto/sha256" + "crypto/x509" + "encoding/pem" + "net/netip" + "os" + "strings" + "testing" + + "github.com/sagernet/sing-box/common/tls" + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" + "github.com/sagernet/sing-box/protocol/naive" + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/json/badoption" + "github.com/sagernet/sing/common/network" + + "github.com/stretchr/testify/require" +) + +func TestNaiveSelf(t *testing.T) { + caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + caPemContent, err := os.ReadFile(caPem) + require.NoError(t, err) + startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeNaive, + Tag: "naive-in", + Options: &option.NaiveInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkTCP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + CertificatePath: certPem, + KeyPath: keyPem, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeNaive, + Tag: "naive-out", + Options: &option.NaiveOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + Certificate: []string{string(caPemContent)}, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "naive-out", + }, + }, + }, + }, + }, + }, + }) + testTCP(t, clientPort, testPort) +} + +func TestNaiveSelfPublicKeySHA256(t *testing.T) { + _, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + + // Read and parse the server certificate to get its public key SHA256 + certPemContent, err := os.ReadFile(certPem) + require.NoError(t, err) + block, _ := pem.Decode(certPemContent) + require.NotNil(t, block) + cert, err := x509.ParseCertificate(block.Bytes) + require.NoError(t, err) + + // Calculate SHA256 of SPKI (Subject Public Key Info) + spkiBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey) + require.NoError(t, err) + pinHash := sha256.Sum256(spkiBytes) + + startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeNaive, + Tag: "naive-in", + Options: &option.NaiveInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkTCP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + CertificatePath: certPem, + KeyPath: keyPem, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeNaive, + Tag: "naive-out", + Options: &option.NaiveOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + CertificatePublicKeySHA256: [][]byte{pinHash[:]}, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "naive-out", + }, + }, + }, + }, + }, + }, + }) + testTCP(t, clientPort, testPort) +} + +func TestNaiveSelfECH(t *testing.T) { + t.Skip("TODO: ECH is not currently supported on naive outbound") + caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + caPemContent, err := os.ReadFile(caPem) + require.NoError(t, err) + echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org")) + instance := startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeNaive, + Tag: "naive-in", + Options: &option.NaiveInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkTCP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + CertificatePath: certPem, + KeyPath: keyPem, + ECH: &option.InboundECHOptions{ + Enabled: true, + Key: []string{echKey}, + }, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeNaive, + Tag: "naive-out", + Options: &option.NaiveOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + Certificate: []string{string(caPemContent)}, + ECH: &option.OutboundECHOptions{ + Enabled: true, + Config: []string{echConfig}, + }, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "naive-out", + }, + }, + }, + }, + }, + }, + }) + + naiveOut, ok := instance.Outbound().Outbound("naive-out") + require.True(t, ok) + naiveOutbound := naiveOut.(*naive.Outbound) + + netLogPath := "/tmp/naive_ech_netlog.json" + require.True(t, naiveOutbound.StartNetLogToFile(netLogPath, true)) + defer naiveOutbound.StopNetLog() + + testTCP(t, clientPort, testPort) + + naiveOutbound.StopNetLog() + + logContent, err := os.ReadFile(netLogPath) + require.NoError(t, err) + logStr := string(logContent) + + require.True(t, strings.Contains(logStr, `"encrypted_client_hello":true`), + "ECH should be accepted in TLS handshake. NetLog saved to: %s", netLogPath) +} + +func TestNaiveSelfInsecureConcurrency(t *testing.T) { + caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org") + caPemContent, err := os.ReadFile(caPem) + require.NoError(t, err) + + instance := startInstance(t, option.Options{ + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + Options: &option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeNaive, + Tag: "naive-in", + Options: &option.NaiveInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())), + ListenPort: serverPort, + }, + Users: []auth.User{ + { + Username: "sekai", + Password: "password", + }, + }, + Network: network.NetworkTCP, + InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{ + TLS: &option.InboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + CertificatePath: certPem, + KeyPath: keyPem, + }, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeNaive, + Tag: "naive-out", + Options: &option.NaiveOutboundOptions{ + ServerOptions: option.ServerOptions{ + Server: "127.0.0.1", + ServerPort: serverPort, + }, + Username: "sekai", + Password: "password", + InsecureConcurrency: 3, + OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{ + TLS: &option.OutboundTLSOptions{ + Enabled: true, + ServerName: "example.org", + Certificate: []string{string(caPemContent)}, + }, + }, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + Type: C.RuleTypeDefault, + DefaultOptions: option.DefaultRule{ + RawDefaultRule: option.RawDefaultRule{ + Inbound: []string{"mixed-in"}, + }, + RuleAction: option.RuleAction{ + Action: C.RuleActionTypeRoute, + RouteOptions: option.RouteActionOptions{ + Outbound: "naive-out", + }, + }, + }, + }, + }, + }, + }) + + naiveOut, ok := instance.Outbound().Outbound("naive-out") + require.True(t, ok) + naiveOutbound := naiveOut.(*naive.Outbound) + + netLogPath := "/tmp/naive_concurrency_netlog.json" + require.True(t, naiveOutbound.StartNetLogToFile(netLogPath, true)) + defer naiveOutbound.StopNetLog() + + // Send multiple sequential connections to trigger round-robin + // With insecure_concurrency=3, connections will be distributed to 3 pools + for i := 0; i < 6; i++ { + testTCP(t, clientPort, testPort) + } + + naiveOutbound.StopNetLog() + + // Verify NetLog contains multiple independent HTTP/2 sessions + logContent, err := os.ReadFile(netLogPath) + require.NoError(t, err) + logStr := string(logContent) + + // Count HTTP2_SESSION_INITIALIZED events to verify connection pool isolation + // NetLog stores event types as numeric IDs, HTTP2_SESSION_INITIALIZED = 249 + sessionCount := strings.Count(logStr, `"type":249`) + require.GreaterOrEqual(t, sessionCount, 3, + "Expected at least 3 HTTP/2 sessions with insecure_concurrency=3. NetLog: %s", netLogPath) +} diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index 034e2339f5..91ae8749c0 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=6878dbacfb1fcb1ee022f63ed6934bcefc95a3c4ba10c88f1131fb88dbf7c337 endef -GEOSITE_VER:=20251208040409 +GEOSITE_VER:=20251209063354 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=cdc1a448e95ba9109974c606d79d04318452f7c8181084bcc3b143c148349922 + HASH:=1132da7e8906a97a5d94a0c3c9eb716386abdbec5e3742babe2409fcfd3810dc endef GEOSITE_IRAN_VER:=202512080042 diff --git a/small/xray-core/Makefile b/small/xray-core/Makefile index 4957050855..e89af3c4e6 100644 --- a/small/xray-core/Makefile +++ b/small/xray-core/Makefile @@ -1,12 +1,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=xray-core -PKG_VERSION:=25.12.2 +PKG_VERSION:=25.12.8 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=e39c40b85decddea0b59719dae33df26aa149ac6fc673e7db9266e731cc2b3ad +PKG_HASH:=d4519b2d9bb1871f4d7612aa7a8db1c451573b5a44ac824219bb44d63f404e61 PKG_MAINTAINER:=Tianling Shen PKG_LICENSE:=MPL-2.0 diff --git a/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs index fd3436dbd0..52de0cd313 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/ActionPrecheckManager.cs @@ -3,13 +3,11 @@ namespace ServiceLib.Manager; /// /// Centralized pre-checks before sensitive actions (set active profile, generate config, etc.). /// -public class ActionPrecheckManager(Config config) +public class ActionPrecheckManager { - private static readonly Lazy _instance = new(() => new ActionPrecheckManager(AppManager.Instance.Config)); + private static readonly Lazy _instance = new(); public static ActionPrecheckManager Instance => _instance.Value; - private readonly Config _config = config; - // sing-box supported transports for different protocol types private static readonly HashSet SingboxUnsupportedTransports = [nameof(ETransport.kcp), nameof(ETransport.xhttp)]; @@ -56,6 +54,7 @@ public class ActionPrecheckManager(Config config) { return []; } + var coreType = AppManager.Instance.GetCoreType(item, item.ConfigType); return await ValidateNodeAndCoreSupport(item, coreType); } @@ -71,115 +70,35 @@ public class ActionPrecheckManager(Config config) errors.Add(string.Format(ResUI.NotSupportProtocol, item.ConfigType.ToString())); return errors; } - - if (!item.IsComplex()) + else if (item.ConfigType.IsGroupType()) { - if (item.Address.IsNullOrEmpty()) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Address")); - return errors; - } - - if (item.Port is <= 0 or >= 65536) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Port")); - return errors; - } - - switch (item.ConfigType) - { - case EConfigType.VMess: - if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Id")); - } - - break; - - case EConfigType.VLESS: - if (item.Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(item.Id) && item.Id.Length > 30)) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Id")); - } - - if (!Global.Flows.Contains(item.Flow)) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Flow")); - } - - break; - - case EConfigType.Shadowsocks: - if (item.Id.IsNullOrEmpty()) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Id")); - } - - if (string.IsNullOrEmpty(item.Security) || !Global.SsSecuritiesInSingbox.Contains(item.Security)) - { - errors.Add(string.Format(ResUI.InvalidProperty, "Security")); - } - - break; - } - - if (item.ConfigType is EConfigType.VLESS or EConfigType.Trojan - && item.StreamSecurity == Global.StreamSecurityReality - && item.PublicKey.IsNullOrEmpty()) - { - errors.Add(string.Format(ResUI.InvalidProperty, "PublicKey")); - } - - if (errors.Count > 0) - { - return errors; - } + var groupErrors = await ValidateGroupNode(item, coreType); + errors.AddRange(groupErrors); + return errors; + } + else if (!item.IsComplex()) + { + var normalErrors = await ValidateNormalNode(item, coreType); + errors.AddRange(normalErrors); + return errors; } - if (item.ConfigType.IsGroupType()) + return errors; + } + + private async Task> ValidateNormalNode(ProfileItem item, ECoreType? coreType = null) + { + var errors = new List(); + + if (item.Address.IsNullOrEmpty()) { - ProfileGroupItemManager.Instance.TryGet(item.IndexId, out var group); - if (group is null || group.NotHasChild()) - { - errors.Add(string.Format(ResUI.GroupEmpty, item.Remarks)); - return errors; - } + errors.Add(string.Format(ResUI.InvalidProperty, "Address")); + return errors; + } - var hasCycle = ProfileGroupItemManager.HasCycle(item.IndexId); - if (hasCycle) - { - errors.Add(string.Format(ResUI.GroupSelfReference, item.Remarks)); - return errors; - } - - var childIds = Utils.String2List(group.ChildItems) ?? []; - var subItems = await ProfileGroupItemManager.GetSubChildProfileItems(group); - childIds.AddRange(subItems.Select(p => p.IndexId)); - - foreach (var child in childIds) - { - var childErrors = new List(); - if (child.IsNullOrEmpty()) - { - continue; - } - - var childItem = await AppManager.Instance.GetProfileItem(child); - if (childItem is null) - { - childErrors.Add(string.Format(ResUI.NodeTagNotExist, child)); - continue; - } - - if (childItem.ConfigType is EConfigType.Custom or EConfigType.ProxyChain) - { - childErrors.Add(string.Format(ResUI.InvalidProperty, childItem.Remarks)); - continue; - } - - childErrors.AddRange(await ValidateNodeAndCoreSupport(childItem, coreType)); - errors.AddRange(childErrors); - } + if (item.Port is <= 0 or > 65535) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Port")); return errors; } @@ -191,20 +110,151 @@ public class ActionPrecheckManager(Config config) if (transportError != null) { errors.Add(transportError); - return errors; + } + + if (!Global.SingboxSupportConfigType.Contains(item.ConfigType)) + { + errors.Add(string.Format(ResUI.CoreNotSupportProtocol, + nameof(ECoreType.sing_box), item.ConfigType.ToString())); } } else if (coreType is ECoreType.Xray) { // Xray core does not support these protocols - if (!Global.XraySupportConfigType.Contains(item.ConfigType) - && !item.IsComplex()) + if (!Global.XraySupportConfigType.Contains(item.ConfigType)) { - errors.Add(string.Format(ResUI.CoreNotSupportProtocol, nameof(ECoreType.Xray), item.ConfigType.ToString())); - return errors; + errors.Add(string.Format(ResUI.CoreNotSupportProtocol, + nameof(ECoreType.Xray), item.ConfigType.ToString())); } } + switch (item.ConfigType) + { + case EConfigType.VMess: + if (item.Id.IsNullOrEmpty() || !Utils.IsGuidByParse(item.Id)) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Id")); + } + + break; + + case EConfigType.VLESS: + if (item.Id.IsNullOrEmpty() || (!Utils.IsGuidByParse(item.Id) && item.Id.Length > 30)) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Id")); + } + + if (!Global.Flows.Contains(item.Flow)) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Flow")); + } + + break; + + case EConfigType.Shadowsocks: + if (item.Id.IsNullOrEmpty()) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Id")); + } + + if (string.IsNullOrEmpty(item.Security) || !Global.SsSecuritiesInSingbox.Contains(item.Security)) + { + errors.Add(string.Format(ResUI.InvalidProperty, "Security")); + } + + break; + } + + if (item.StreamSecurity == Global.StreamSecurity) + { + // check certificate validity + if ((!item.Cert.IsNullOrEmpty()) && (CertPemManager.ParsePemChain(item.Cert).Count == 0)) + { + errors.Add(string.Format(ResUI.InvalidProperty, "TLS Certificate")); + } + } + + if (item.StreamSecurity == Global.StreamSecurityReality) + { + if (item.PublicKey.IsNullOrEmpty()) + { + errors.Add(string.Format(ResUI.InvalidProperty, "PublicKey")); + } + } + + if (item.Network == nameof(ETransport.xhttp) + && !item.Extra.IsNullOrEmpty()) + { + // check xhttp extra json validity + var xhttpExtra = JsonUtils.ParseJson(item.Extra); + if (xhttpExtra is null) + { + errors.Add(string.Format(ResUI.InvalidProperty, "XHTTP Extra")); + } + } + + // ws with tls, tls alpn should contain "http/1.1" in xray core + // rfc6455 + // https://github.com/XTLS/Xray-core/blob/81f8f398c7b2b845853b1e85087c6122acc6db0b/transport/internet/tls/tls.go#L95-L116 + if (item.Network == nameof(ETransport.ws) + && item.StreamSecurity == Global.StreamSecurity) + { + var alpnList = Utils.String2List(item.Alpn) ?? []; + if (alpnList.Count > 0 && !alpnList.Contains("http/1.1")) + { + errors.Add(ResUI.AlpnMustContainHttp11ForWsTls); + } + } + + return errors; + } + + private async Task> ValidateGroupNode(ProfileItem item, ECoreType? coreType = null) + { + var errors = new List(); + + ProfileGroupItemManager.Instance.TryGet(item.IndexId, out var group); + if (group is null || group.NotHasChild()) + { + errors.Add(string.Format(ResUI.GroupEmpty, item.Remarks)); + return errors; + } + + var hasCycle = ProfileGroupItemManager.HasCycle(item.IndexId); + if (hasCycle) + { + errors.Add(string.Format(ResUI.GroupSelfReference, item.Remarks)); + return errors; + } + + var childIds = Utils.String2List(group.ChildItems) ?? []; + var subItems = await ProfileGroupItemManager.GetSubChildProfileItems(group); + childIds.AddRange(subItems.Select(p => p.IndexId)); + + foreach (var child in childIds) + { + var childErrors = new List(); + if (child.IsNullOrEmpty()) + { + continue; + } + + var childItem = await AppManager.Instance.GetProfileItem(child); + if (childItem is null) + { + childErrors.Add(string.Format(ResUI.NodeTagNotExist, child)); + continue; + } + + if (childItem.ConfigType is EConfigType.Custom or EConfigType.ProxyChain) + { + childErrors.Add(string.Format(ResUI.InvalidProperty, childItem.Remarks)); + continue; + } + + childErrors.AddRange(await ValidateNodeAndCoreSupport(childItem, coreType)); + errors.AddRange(childErrors.Select(s => s.Insert(0, $"{childItem.Remarks}: "))); + } return errors; } @@ -271,7 +321,7 @@ public class ActionPrecheckManager(Config config) if (node is not null) { var nodeErrors = await ValidateNodeAndCoreSupport(node, coreType); - errors.AddRange(nodeErrors.Select(s => ResUI.ProxyChainedPrefix + s)); + errors.AddRange(nodeErrors.Select(s => ResUI.ProxyChainedPrefix + $"{node.Remarks}: " + s)); } else if (tag.IsNotEmpty()) { @@ -289,7 +339,7 @@ public class ActionPrecheckManager(Config config) } var coreType = AppManager.Instance.GetCoreType(item, item.ConfigType); - var routing = await ConfigHandler.GetDefaultRouting(_config); + var routing = await ConfigHandler.GetDefaultRouting(AppManager.Instance.Config); if (routing == null) { return errors; @@ -317,7 +367,7 @@ public class ActionPrecheckManager(Config config) } var tagErrors = await ValidateNodeAndCoreSupport(tagItem, coreType); - errors.AddRange(tagErrors.Select(s => ResUI.RoutingRuleOutboundPrefix + s)); + errors.AddRange(tagErrors.Select(s => ResUI.RoutingRuleOutboundPrefix + $"{tagItem.Remarks}: " + s)); } return errors; diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 64ca0292f4..a3b75407a2 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -19,7 +19,7 @@ namespace ServiceLib.Resx { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class ResUI { @@ -78,6 +78,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 ALPN must contain 'http/1.1' when using WebSocket with TLS. 的本地化字符串。 + /// + public static string AlpnMustContainHttp11ForWsTls { + get { + return ResourceManager.GetString("AlpnMustContainHttp11ForWsTls", resourceCulture); + } + } + /// /// 查找类似 Export share link to clipboard successfully 的本地化字符串。 /// diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 4f5467b3cc..9571ecd998 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1641,4 +1641,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Configuration Item 2, Select and add from self-built + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx index a4fbf84bd5..e17f56b9b9 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1638,4 +1638,7 @@ Si un certificat auto-signé est utilisé ou si le système contient une CA non Configuration Item 2, Select and add from self-built + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx index 0841b1112d..c7f6d51cd5 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1641,4 +1641,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Configuration Item 2, Select and add from self-built + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx index ceb7c91e2a..ce09f3f655 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1641,4 +1641,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Configuration Item 2, Select and add from self-built + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 331027334a..d502ff35f7 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1641,4 +1641,7 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if Configuration Item 2, Select and add from self-built + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index e53c420396..a567343098 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1638,4 +1638,7 @@ 子配置项二,从自建中选择添加 + + 使用 WebSocket+TLS 时,ALPN 必须包含 'http/1.1'。 + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 92421199d8..1a4ec70c91 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1638,4 +1638,7 @@ 子配置項二,從自建中選擇新增 + + ALPN must contain 'http/1.1' when using WebSocket with TLS. + \ No newline at end of file diff --git a/v2rayng/AndroidLibXrayLite/go.mod b/v2rayng/AndroidLibXrayLite/go.mod index b2bbfd8506..1ec3c215a1 100644 --- a/v2rayng/AndroidLibXrayLite/go.mod +++ b/v2rayng/AndroidLibXrayLite/go.mod @@ -1,9 +1,9 @@ module github.com/2dust/AndroidLibXrayLite -go 1.25.5 +go 1.25 require ( - github.com/xtls/xray-core v1.251202.0 + github.com/xtls/xray-core v1.251208.0 golang.org/x/mobile v0.0.0-20251126181937-5c265dc024c4 ) @@ -34,21 +34,21 @@ require ( github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 // indirect go.uber.org/mock v0.6.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect google.golang.org/grpc v1.77.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gvisor.dev/gvisor v0.0.0-20251201192414-f717cbac4761 // indirect + gvisor.dev/gvisor v0.0.0-20251208201337-b42c83311c5b // indirect lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/v2rayng/AndroidLibXrayLite/go.sum b/v2rayng/AndroidLibXrayLite/go.sum index d6b18abe57..53446e8fe6 100644 --- a/v2rayng/AndroidLibXrayLite/go.sum +++ b/v2rayng/AndroidLibXrayLite/go.sum @@ -72,8 +72,8 @@ github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zd github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237 h1:UXjrmniKlY+ZbIqpN91lejB3pszQQQRVu1vqH/p/aGM= github.com/xtls/reality v0.0.0-20251116175510-cd53f7d50237/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ= -github.com/xtls/xray-core v1.251202.0 h1:VwoBnq9IRTbYWEBhR0CqEw2cNjTlXYH6WxzKbSjx+XE= -github.com/xtls/xray-core v1.251202.0/go.mod h1:kclzboEF0g6VBrp9/NXm8C0Aj64SDBt52OfthH1LSr4= +github.com/xtls/xray-core v1.251208.0 h1:9jIXi+9KXnfmT5esSYNf9VAQlQkaAP8bG413B0eyAes= +github.com/xtls/xray-core v1.251208.0/go.mod h1:kclzboEF0g6VBrp9/NXm8C0Aj64SDBt52OfthH1LSr4= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -92,26 +92,26 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= 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.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +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/mobile v0.0.0-20251126181937-5c265dc024c4 h1:lZKReZrCBTDNaVewUp31194cua6qf65/tYg3mq1KUU0= golang.org/x/mobile v0.0.0-20251126181937-5c265dc024c4/go.mod h1:Eq3Nh/5pFSWug2ohiudJ1iyU59SO78QFuh4qTTN++I0= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +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/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +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.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +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/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= 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.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= 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-20250521234502-f333402bd9cb h1:whnFRlWMcXI9d+ZbWg+4sHnLp52d5yiIPUxMBSt4X9A= diff --git a/v2rayng/V2rayNG/app/build.gradle.kts b/v2rayng/V2rayNG/app/build.gradle.kts index 89e2ca9bf2..33de2bf47c 100644 --- a/v2rayng/V2rayNG/app/build.gradle.kts +++ b/v2rayng/V2rayNG/app/build.gradle.kts @@ -12,8 +12,8 @@ android { applicationId = "com.v2ray.ang" minSdk = 21 targetSdk = 35 - versionCode = 682 - versionName = "1.10.30" + versionCode = 683 + versionName = "1.10.31" multiDexEnabled = true val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';')