mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Tue Nov 4 19:40:31 CET 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -1171,3 +1171,4 @@ Update On Fri Oct 31 19:38:32 CET 2025
|
||||
Update On Sat Nov 1 19:37:41 CET 2025
|
||||
Update On Sun Nov 2 19:34:13 CET 2025
|
||||
Update On Mon Nov 3 19:37:13 CET 2025
|
||||
Update On Tue Nov 4 19:40:23 CET 2025
|
||||
|
||||
@@ -24,6 +24,8 @@ var WriteBuffer = bufio.WriteBuffer
|
||||
type ReadWaitOptions = network.ReadWaitOptions
|
||||
|
||||
var NewReadWaitOptions = network.NewReadWaitOptions
|
||||
var CalculateFrontHeadroom = network.CalculateFrontHeadroom
|
||||
var CalculateRearHeadroom = network.CalculateRearHeadroom
|
||||
|
||||
type ReaderWithUpstream = network.ReaderWithUpstream
|
||||
type WithUpstreamReader = network.WithUpstreamReader
|
||||
|
||||
@@ -16,7 +16,7 @@ require (
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905
|
||||
github.com/klauspost/compress v1.17.9 // lastest version compatible with golang1.20
|
||||
github.com/mdlayher/netlink v1.7.2
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d
|
||||
github.com/metacubex/bart v0.26.0
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b
|
||||
github.com/metacubex/blake3 v0.1.0
|
||||
|
||||
@@ -90,8 +90,8 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281 h1:09EM0sOLb2kfL0KETGhHujsBLB5iy5U/2yHRHsxf/pI=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/ascon v0.1.0 h1:6ZWxmXYszT1XXtwkf6nxfFhc/OTtQ9R3Vyj1jN32lGM=
|
||||
github.com/metacubex/ascon v0.1.0/go.mod h1:eV5oim4cVPPdEL8/EYaTZ0iIKARH9pnhAK/fcT5Kacc=
|
||||
github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w=
|
||||
|
||||
@@ -242,14 +242,26 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
|
||||
}
|
||||
|
||||
func (vc *Conn) FrontHeadroom() int {
|
||||
fontHeadroom := PaddingHeaderLen - uuid.Size
|
||||
if vc.readFilterUUID || vc.writeOnceUserUUID != nil {
|
||||
return PaddingHeaderLen
|
||||
fontHeadroom = PaddingHeaderLen
|
||||
}
|
||||
return PaddingHeaderLen - uuid.Size
|
||||
if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn
|
||||
if abs := N.CalculateFrontHeadroom(vc.netConn) - N.CalculateFrontHeadroom(vc.Conn); abs > 0 {
|
||||
fontHeadroom += abs
|
||||
}
|
||||
}
|
||||
return fontHeadroom
|
||||
}
|
||||
|
||||
func (vc *Conn) RearHeadroom() int {
|
||||
return 500 + 900
|
||||
rearHeadroom := 500 + 900
|
||||
if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn
|
||||
if abs := N.CalculateRearHeadroom(vc.netConn) - N.CalculateRearHeadroom(vc.Conn); abs > 0 {
|
||||
rearHeadroom += abs
|
||||
}
|
||||
}
|
||||
return rearHeadroom
|
||||
}
|
||||
|
||||
func (vc *Conn) NeedHandshake() bool {
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
"@emotion/styled": "11.14.1",
|
||||
"@juggle/resize-observer": "3.4.0",
|
||||
"@material/material-color-utilities": "0.3.0",
|
||||
"@mui/icons-material": "7.3.4",
|
||||
"@mui/icons-material": "7.3.5",
|
||||
"@mui/lab": "7.0.0-beta.17",
|
||||
"@mui/material": "7.3.4",
|
||||
"@mui/material": "7.3.5",
|
||||
"@mui/x-date-pickers": "8.16.0",
|
||||
"@nyanpasu/interface": "workspace:^",
|
||||
"@nyanpasu/ui": "workspace:^",
|
||||
@@ -59,9 +59,9 @@
|
||||
"@iconify/json": "2.2.403",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.90.6",
|
||||
"@tanstack/react-router": "1.134.9",
|
||||
"@tanstack/react-router-devtools": "1.134.9",
|
||||
"@tanstack/router-plugin": "1.134.9",
|
||||
"@tanstack/react-router": "1.134.12",
|
||||
"@tanstack/react-router-devtools": "1.134.12",
|
||||
"@tanstack/router-plugin": "1.134.12",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.3.0",
|
||||
"@tauri-apps/plugin-dialog": "2.4.0",
|
||||
"@tauri-apps/plugin-fs": "2.4.2",
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@material/material-color-utilities": "0.3.0",
|
||||
"@mui/icons-material": "7.3.4",
|
||||
"@mui/icons-material": "7.3.5",
|
||||
"@mui/lab": "7.0.0-beta.17",
|
||||
"@mui/material": "7.3.4",
|
||||
"@mui/material": "7.3.5",
|
||||
"@radix-ui/react-portal": "1.1.9",
|
||||
"@radix-ui/react-scroll-area": "1.2.10",
|
||||
"@tauri-apps/api": "2.8.0",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.15",
|
||||
"mihomo_alpha": "alpha-6fb1f79",
|
||||
"mihomo_alpha": "alpha-fd39c2a",
|
||||
"clash_rs": "v0.9.1",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.9.1-alpha+sha.4479974"
|
||||
"clash_rs_alpha": "0.9.1-alpha+sha.cff16c6"
|
||||
},
|
||||
"arch_template": {
|
||||
"mihomo": {
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-11-02T22:20:46.358Z"
|
||||
"updated_at": "2025-11-03T22:21:13.590Z"
|
||||
}
|
||||
|
||||
@@ -67,13 +67,13 @@
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/node": "24.10.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.46.2",
|
||||
"@typescript-eslint/parser": "8.46.2",
|
||||
"@typescript-eslint/eslint-plugin": "8.46.3",
|
||||
"@typescript-eslint/parser": "8.46.3",
|
||||
"autoprefixer": "10.4.21",
|
||||
"conventional-changelog-conventionalcommits": "9.1.0",
|
||||
"cross-env": "10.1.0",
|
||||
"dedent": "1.7.0",
|
||||
"eslint": "9.39.0",
|
||||
"eslint": "9.39.1",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-import-resolver-alias": "1.1.2",
|
||||
"eslint-plugin-html": "8.1.3",
|
||||
@@ -85,7 +85,7 @@
|
||||
"eslint-plugin-react-compiler": "19.1.0-rc.2",
|
||||
"eslint-plugin-react-hooks": "7.0.1",
|
||||
"globals": "16.5.0",
|
||||
"knip": "5.67.0",
|
||||
"knip": "5.67.1",
|
||||
"lint-staged": "16.2.6",
|
||||
"neostandard": "0.12.2",
|
||||
"npm-run-all2": "8.0.4",
|
||||
@@ -108,7 +108,7 @@
|
||||
"tailwindcss": "4.1.16",
|
||||
"tsx": "4.20.6",
|
||||
"typescript": "5.9.3",
|
||||
"typescript-eslint": "8.46.2"
|
||||
"typescript-eslint": "8.46.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.20.0",
|
||||
"engines": {
|
||||
|
||||
619
clash-nyanpasu/pnpm-lock.yaml
generated
619
clash-nyanpasu/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,9 @@ CONFIG_BINFMT_MISC=y
|
||||
CONFIG_BLK_DEV_BSGLIB=y
|
||||
CONFIG_BLK_DEV_BSG_COMMON=y
|
||||
CONFIG_BLK_DEV_INTEGRITY=y
|
||||
CONFIG_BLK_DEV_INTEGRITY_T10=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_MQ_PCI=y
|
||||
CONFIG_BLK_MQ_VIRTIO=y
|
||||
CONFIG_BLK_PM=y
|
||||
@@ -532,6 +534,13 @@ CONFIG_SCHED_INFO=y
|
||||
CONFIG_SCHED_MC=y
|
||||
CONFIG_SCHED_SMT=y
|
||||
CONFIG_SCHED_THERMAL_PRESSURE=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_SCSI_COMMON=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_SCSI_SAS_ATTRS=y
|
||||
CONFIG_SCSI_SAS_HOST_SMP=y
|
||||
CONFIG_SCSI_SAS_LIBSAS=y
|
||||
CONFIG_SECURITY=y
|
||||
# CONFIG_SECURITY_NETWORK is not set
|
||||
CONFIG_SERIAL_8250_FSL=y
|
||||
|
||||
@@ -31,7 +31,7 @@ function delete_mieru_client_log() {
|
||||
}
|
||||
|
||||
function run_new_conn_test() {
|
||||
config="$1"
|
||||
local config="$1"
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections with API server - $config <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
@@ -45,7 +45,7 @@ function run_new_conn_test() {
|
||||
}
|
||||
|
||||
function run_udp_associate_test() {
|
||||
config="$1"
|
||||
local config="$1"
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - with API server - $config <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
|
||||
@@ -21,11 +21,11 @@ WORKDIR /test
|
||||
|
||||
# Copy binaries, data and test script into the container.
|
||||
COPY mihomo mita httpserver sockshttpclient socksudpclient udpserver \
|
||||
test/deploy/mihomo/mihomo-config.yaml \
|
||||
test/deploy/mihomo/mihomo-config-no-wait.yaml \
|
||||
test/deploy/mihomo/mihomo-client-tcp.yaml \
|
||||
test/deploy/mihomo/mihomo-client-tcp-no-wait.yaml \
|
||||
test/deploy/mihomo/server_tcp.json \
|
||||
test/deploy/mihomo/libtest.sh \
|
||||
test/deploy/mihomo/test_tcp.sh \
|
||||
test/deploy/mihomo/test_client_tcp.sh \
|
||||
test/deploy/mihomo/test.sh /test/
|
||||
|
||||
# Create mita user and server config directory.
|
||||
|
||||
@@ -37,7 +37,7 @@ sleep 1
|
||||
|
||||
# Run TCP test.
|
||||
echo "========== BEGIN OF TCP TEST =========="
|
||||
./test_tcp.sh
|
||||
./test_client_tcp.sh
|
||||
echo "========== END OF TCP TEST =========="
|
||||
|
||||
echo "Test is successful."
|
||||
|
||||
109
mieru/test/deploy/mihomo/test_client_tcp.sh
Executable file
109
mieru/test/deploy/mihomo/test_client_tcp.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (C) 2024 mieru authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Make sure this script has executable permission:
|
||||
# git update-index --chmod=+x <file>
|
||||
|
||||
# Load test library.
|
||||
source ./libtest.sh
|
||||
|
||||
# Update mieru server with TCP config.
|
||||
./mita apply config server_tcp.json
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita apply config server_tcp.json' failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "mieru server config:"
|
||||
./mita describe config
|
||||
|
||||
# Start mieru server proxy.
|
||||
./mita start
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita start' failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start mihomo.
|
||||
./mihomo -f mihomo-client-tcp.yaml &
|
||||
sleep 1
|
||||
./mihomo -f mihomo-client-tcp-no-wait.yaml &
|
||||
sleep 1
|
||||
|
||||
function run_tcp_tests() {
|
||||
local port="$1"
|
||||
local suffix="${2:-}"
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections - TCP ${suffix} <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=${port} \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 new_conn ${suffix} failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - TCP ${suffix} <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_http_host=127.0.0.1 -local_http_port=${port} \
|
||||
-test_case=new_conn -num_request=1000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test HTTP new_conn ${suffix} failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - reuse one connection - TCP ${suffix} <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=${port} \
|
||||
-test_case=reuse_conn -test_time_sec=30
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 reuse_conn ${suffix} failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - TCP ${suffix} <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=${port} \
|
||||
-interval_ms=10 -num_request=100 -num_conn=60
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 udp_associate ${suffix} failed."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Start testing.
|
||||
run_tcp_tests 1080
|
||||
run_tcp_tests 1081 "(handshake no wait)"
|
||||
|
||||
# Print metrics and memory statistics.
|
||||
print_mieru_server_metrics
|
||||
sleep 1
|
||||
|
||||
# Stop mieru server proxy.
|
||||
./mita stop
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita stop' failed"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
@@ -1,145 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (C) 2024 mieru authors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Make sure this script has executable permission:
|
||||
# git update-index --chmod=+x <file>
|
||||
|
||||
# Load test library.
|
||||
source ./libtest.sh
|
||||
|
||||
# Update mieru server with TCP config.
|
||||
./mita apply config server_tcp.json
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita apply config server_tcp.json' failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "mieru server config:"
|
||||
./mita describe config
|
||||
|
||||
# Start mieru server proxy.
|
||||
./mita start
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita start' failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start mihomo.
|
||||
./mihomo -f mihomo-config.yaml &
|
||||
sleep 1
|
||||
./mihomo -f mihomo-config-no-wait.yaml &
|
||||
sleep 1
|
||||
|
||||
# Start testing.
|
||||
sleep 2
|
||||
echo ">>> socks5 - new connections - TCP <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1080 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 new_conn failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - TCP <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_http_host=127.0.0.1 -local_http_port=1080 \
|
||||
-test_case=new_conn -num_request=1000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test HTTP new_conn failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - reuse one connection - TCP <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1080 \
|
||||
-test_case=reuse_conn -test_time_sec=30
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 reuse_conn failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - TCP <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1080 \
|
||||
-interval_ms=10 -num_request=100 -num_conn=60
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 udp_associate failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - new connections - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-test_case=new_conn -num_request=3000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 new_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> http - new connections - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -proxy_mode=http -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_http_host=127.0.0.1 -local_http_port=1081 \
|
||||
-test_case=new_conn -num_request=1000
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test HTTP new_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 - reuse one connection - TCP - handshake no wait <<<"
|
||||
./sockshttpclient -dst_host=127.0.0.1 -dst_port=8080 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-test_case=reuse_conn -test_time_sec=30
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 reuse_conn (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
echo ">>> socks5 UDP associate - TCP - handshake no wait <<<"
|
||||
./socksudpclient -dst_host=127.0.0.1 -dst_port=9090 \
|
||||
-local_proxy_host=127.0.0.1 -local_proxy_port=1081 \
|
||||
-interval_ms=10 -num_request=100 -num_conn=60
|
||||
if [ "$?" -ne "0" ]; then
|
||||
print_mieru_server_thread_dump
|
||||
echo "TCP - test socks5 udp_associate (handshake no wait) failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Print metrics and memory statistics.
|
||||
print_mieru_server_metrics
|
||||
sleep 1
|
||||
|
||||
# Stop mieru server proxy.
|
||||
./mita stop
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "command 'mita stop' failed"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
@@ -24,6 +24,8 @@ var WriteBuffer = bufio.WriteBuffer
|
||||
type ReadWaitOptions = network.ReadWaitOptions
|
||||
|
||||
var NewReadWaitOptions = network.NewReadWaitOptions
|
||||
var CalculateFrontHeadroom = network.CalculateFrontHeadroom
|
||||
var CalculateRearHeadroom = network.CalculateRearHeadroom
|
||||
|
||||
type ReaderWithUpstream = network.ReaderWithUpstream
|
||||
type WithUpstreamReader = network.WithUpstreamReader
|
||||
|
||||
@@ -16,7 +16,7 @@ require (
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905
|
||||
github.com/klauspost/compress v1.17.9 // lastest version compatible with golang1.20
|
||||
github.com/mdlayher/netlink v1.7.2
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d
|
||||
github.com/metacubex/bart v0.26.0
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b
|
||||
github.com/metacubex/blake3 v0.1.0
|
||||
|
||||
@@ -90,8 +90,8 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281 h1:09EM0sOLb2kfL0KETGhHujsBLB5iy5U/2yHRHsxf/pI=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/ascon v0.1.0 h1:6ZWxmXYszT1XXtwkf6nxfFhc/OTtQ9R3Vyj1jN32lGM=
|
||||
github.com/metacubex/ascon v0.1.0/go.mod h1:eV5oim4cVPPdEL8/EYaTZ0iIKARH9pnhAK/fcT5Kacc=
|
||||
github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w=
|
||||
|
||||
@@ -242,14 +242,26 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) {
|
||||
}
|
||||
|
||||
func (vc *Conn) FrontHeadroom() int {
|
||||
fontHeadroom := PaddingHeaderLen - uuid.Size
|
||||
if vc.readFilterUUID || vc.writeOnceUserUUID != nil {
|
||||
return PaddingHeaderLen
|
||||
fontHeadroom = PaddingHeaderLen
|
||||
}
|
||||
return PaddingHeaderLen - uuid.Size
|
||||
if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn
|
||||
if abs := N.CalculateFrontHeadroom(vc.netConn) - N.CalculateFrontHeadroom(vc.Conn); abs > 0 {
|
||||
fontHeadroom += abs
|
||||
}
|
||||
}
|
||||
return fontHeadroom
|
||||
}
|
||||
|
||||
func (vc *Conn) RearHeadroom() int {
|
||||
return 500 + 900
|
||||
rearHeadroom := 500 + 900
|
||||
if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn
|
||||
if abs := N.CalculateRearHeadroom(vc.netConn) - N.CalculateRearHeadroom(vc.Conn); abs > 0 {
|
||||
rearHeadroom += abs
|
||||
}
|
||||
}
|
||||
return rearHeadroom
|
||||
}
|
||||
|
||||
func (vc *Conn) NeedHandshake() bool {
|
||||
|
||||
@@ -49,6 +49,9 @@ func (s *Service) loadCache() error {
|
||||
os.RemoveAll(basePath)
|
||||
return err
|
||||
}
|
||||
s.cacheMutex.Lock()
|
||||
s.lastSavedCache = cacheBinary
|
||||
s.cacheMutex.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -56,16 +59,30 @@ func (s *Service) saveCache() error {
|
||||
if s.cachePath == "" {
|
||||
return nil
|
||||
}
|
||||
cacheBinary, err := s.encodeCache()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.cacheMutex.Lock()
|
||||
defer s.cacheMutex.Unlock()
|
||||
if bytes.Equal(s.lastSavedCache, cacheBinary) {
|
||||
return nil
|
||||
}
|
||||
return s.writeCache(cacheBinary)
|
||||
}
|
||||
|
||||
func (s *Service) writeCache(cacheBinary []byte) error {
|
||||
basePath := filemanager.BasePath(s.ctx, s.cachePath)
|
||||
err := os.MkdirAll(filepath.Dir(basePath), 0o777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheBinary, err := s.encodeCache()
|
||||
err = os.WriteFile(basePath, cacheBinary, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(s.cachePath, cacheBinary, 0o644)
|
||||
s.lastSavedCache = cacheBinary
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) decodeCache(cacheBinary []byte) error {
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
boxService "github.com/sagernet/sing-box/adapter/service"
|
||||
@@ -28,21 +30,27 @@ func RegisterService(registry *boxService.Registry) {
|
||||
|
||||
type Service struct {
|
||||
boxService.Adapter
|
||||
ctx context.Context
|
||||
logger log.ContextLogger
|
||||
listener *listener.Listener
|
||||
tlsConfig tls.ServerConfig
|
||||
httpServer *http.Server
|
||||
traffics map[string]*TrafficManager
|
||||
users map[string]*UserManager
|
||||
cachePath string
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
logger log.ContextLogger
|
||||
listener *listener.Listener
|
||||
tlsConfig tls.ServerConfig
|
||||
httpServer *http.Server
|
||||
traffics map[string]*TrafficManager
|
||||
users map[string]*UserManager
|
||||
cachePath string
|
||||
saveTicker *time.Ticker
|
||||
lastSavedCache []byte
|
||||
cacheMutex sync.Mutex
|
||||
}
|
||||
|
||||
func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.SSMAPIServiceOptions) (adapter.Service, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
chiRouter := chi.NewRouter()
|
||||
s := &Service{
|
||||
Adapter: boxService.NewAdapter(C.TypeSSMAPI, tag),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
logger: logger,
|
||||
listener: listener.New(listener.Options{
|
||||
Context: ctx,
|
||||
@@ -95,6 +103,8 @@ func (s *Service) Start(stage adapter.StartStage) error {
|
||||
if err != nil {
|
||||
s.logger.Error(E.Cause(err, "load cache"))
|
||||
}
|
||||
s.saveTicker = time.NewTicker(1 * time.Minute)
|
||||
go s.loopSaveCache()
|
||||
if s.tlsConfig != nil {
|
||||
err = s.tlsConfig.Start()
|
||||
if err != nil {
|
||||
@@ -120,7 +130,27 @@ func (s *Service) Start(stage adapter.StartStage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) loopSaveCache() {
|
||||
for {
|
||||
select {
|
||||
case <-s.ctx.Done():
|
||||
return
|
||||
case <-s.saveTicker.C:
|
||||
err := s.saveCache()
|
||||
if err != nil {
|
||||
s.logger.Error(E.Cause(err, "save cache"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) Close() error {
|
||||
if s.cancel != nil {
|
||||
s.cancel()
|
||||
}
|
||||
if s.saveTicker != nil {
|
||||
s.saveTicker.Stop()
|
||||
}
|
||||
err := s.saveCache()
|
||||
if err != nil {
|
||||
s.logger.Error(E.Cause(err, "save cache"))
|
||||
|
||||
@@ -1285,15 +1285,26 @@ o = s:option(ListValue, "tuic_alpn", translate("TUIC ALPN"))
|
||||
o.default = ""
|
||||
o:value("", translate("Default"))
|
||||
o:value("h3")
|
||||
o:value("h2")
|
||||
o:value("h3,h2")
|
||||
o:value("spdy/3.1")
|
||||
o:value("h3,spdy/3.1")
|
||||
o:depends("type", "tuic")
|
||||
|
||||
-- IP STACK PREFERENCE
|
||||
o = s:option(ListValue, "ipstack_prefer", translate("IP Stack Preference"))
|
||||
o.default = ""
|
||||
o:value("", translate("Default"))
|
||||
o:value("v4first")
|
||||
o:value("v6first")
|
||||
o:depends("tuic_dual_stack", true)
|
||||
|
||||
-- [[ allowInsecure ]]--
|
||||
o = s:option(Flag, "insecure", translate("allowInsecure"))
|
||||
o.rmempty = false
|
||||
o:depends("tls", true)
|
||||
o:depends("type", "hysteria2")
|
||||
o:depends("type", "tuic")
|
||||
o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.")
|
||||
|
||||
-- [[ Hysteria2 TLS pinSHA256 ]] --
|
||||
|
||||
@@ -862,12 +862,37 @@ function import_ssr_url(btn, urlname, sid) {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_uuid')[0].value = method;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_ip')[0].value = params.sni || "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_ip')[0].value = params.ip || "";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_passwd')[0].value = password;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.udp_relay_mode')[0].value = params.udp_relay_mode || "native";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.congestion_control')[0].value = params.congestion_control || "cubic";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_alpn')[0].value = params.alpn || "";
|
||||
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.heartbeat')[0].value = params.heartbeat || "3";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.timeout')[0].value = params.timeout || "8";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.gc_interval')[0].value = params.gc_interval || "3";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.gc_lifetime')[0].value = params.gc_lifetime || "15";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.send_window')[0].value = params.send_window || "20971520";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.receive_window')[0].value = params.receive_window || "10485760";
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_max_package_size')[0].value = params.max_packet_size || "1500";
|
||||
if (params["disable_sni"] === "1" || params["disable_sni"] === "true") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.disable_sni')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.disable_sni')[0].dispatchEvent(event);
|
||||
}
|
||||
if (params["zero_rtt_handshake"] === "1" || params["zero_rtt_handshake"] === "true") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.zero_rtt_handshake')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.zero_rtt_handshake')[0].dispatchEvent(event);
|
||||
}
|
||||
if (params["dual_stack"] === "1" || params["dual_stack"] === "true") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_dual_stack')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_dual_stack')[0].dispatchEvent(event);
|
||||
if (params.ipstack_prefer && params.ipstack_prefer.trim() !== "") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ipstack_prefer')[0].value = params.ipstack_prefer;
|
||||
}
|
||||
}
|
||||
if (params["allowInsecure"] === "1" || params["allowInsecure"] === "true") {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true;
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event);
|
||||
}
|
||||
if (param != undefined) {
|
||||
document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -331,8 +331,8 @@ end
|
||||
mux = (server.v2ray_protocol ~= "wireguard") and {
|
||||
-- mux
|
||||
enabled = (server.mux == "1"), -- Mux
|
||||
concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发
|
||||
xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发
|
||||
concurrency = (server.mux == "1" and (tonumber(server.concurrency) or -1)) or nil, -- TCP 最大并发连接数
|
||||
xudpConcurrency = (server.mux == "1" and (tonumber(server.xudpConcurrency) or 16)) or nil, -- UDP 最大并发连接数
|
||||
xudpProxyUDP443 = (server.mux == "1" and (server.xudpProxyUDP443 or "reject")) or nil -- 对被代理的 UDP/443 流量处理方式
|
||||
} or nil
|
||||
}
|
||||
@@ -631,6 +631,8 @@ local tuic = {
|
||||
return nil
|
||||
end
|
||||
end)() or nil,
|
||||
ipstack_prefer = (server.tuic_dual_stack == "1") and server.ipstack_prefer or nil,
|
||||
skip_cert_verify = (server.insecure == "1" or server.insecure == true or server.insecure == "true"),
|
||||
disable_sni = (server.disable_sni == "1") and true or false,
|
||||
zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false,
|
||||
send_window = tonumber(server.send_window),
|
||||
@@ -715,3 +717,4 @@ function config:handleIndex(index)
|
||||
end
|
||||
local f = config:new()
|
||||
f:handleIndex(server.type)
|
||||
|
||||
|
||||
@@ -877,7 +877,7 @@ local function processData(szType, content)
|
||||
|
||||
-- TLS / Reality 标志
|
||||
local security = params.security or ""
|
||||
result.tls = (params.security == "tls" or security == "xtls") and "1" or "0"
|
||||
result.tls = (security == "tls" or security == "xtls") and "1" or "0"
|
||||
result.reality = (security == "reality") and "1" or "0"
|
||||
|
||||
-- 统一 TLS / Reality 公共字段
|
||||
@@ -1012,9 +1012,16 @@ local function processData(szType, content)
|
||||
end
|
||||
|
||||
result.type = tuic_type
|
||||
result.tuic_ip = params.sni or ""
|
||||
result.tuic_ip = params.ip or ""
|
||||
result.udp_relay_mode = params.udp_relay_mode or "native"
|
||||
result.congestion_control = params.congestion_control or "cubic"
|
||||
result.heartbeat = params.heartbeat or "3"
|
||||
result.timeout = params.timeout or "8"
|
||||
result.gc_interval = params.gc_interval or "3"
|
||||
result.gc_lifetime = params.gc_lifetime or "15"
|
||||
result.send_window = params.send_window or "20971520"
|
||||
result.receive_window = params.receive_window or "10485760"
|
||||
result.tuic_max_package_size = params.max_packet_size or "1500"
|
||||
|
||||
-- alpn 支持逗号或分号分隔
|
||||
if params.alpn and params.alpn ~= "" then
|
||||
@@ -1024,6 +1031,46 @@ local function processData(szType, content)
|
||||
end
|
||||
result.tuic_alpn = alpn
|
||||
end
|
||||
|
||||
-- 处理 disable_sni 参数
|
||||
if params.disable_sni then
|
||||
if params.disable_sni == "1" or params.disable_sni == "0" then
|
||||
result.disable_sni = params.disable_sni
|
||||
else
|
||||
result.disable_sni = string.lower(params.disable_sni) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理 zero_rtt_handshake 参数
|
||||
if params.zero_rtt_handshake then
|
||||
if params.zero_rtt_handshake == "1" or params.zero_rtt_handshake == "0" then
|
||||
result.zero_rtt_handshake = params.zero_rtt_handshake
|
||||
else
|
||||
result.zero_rtt_handshake = string.lower(params.zero_rtt_handshake) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理 dual_stack 参数
|
||||
if params.dual_stack then
|
||||
if params.dual_stack == "1" or params.dual_stack == "0" then
|
||||
result.dual_stack = params.dual_stack
|
||||
else
|
||||
result.dual_stack = string.lower(params.dual_stack) == "true" and "1" or "0"
|
||||
end
|
||||
-- 处理 ipstack_prefer 参数
|
||||
if params.ipstack_prefer and params.ipstack_prefer ~= "" then
|
||||
result.ipstack_prefer = params.ipstack_prefer
|
||||
end
|
||||
end
|
||||
|
||||
-- 处理 insecure 参数
|
||||
if params.allowInsecure then
|
||||
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||
result.insecure = params.allowInsecure
|
||||
else
|
||||
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||
end
|
||||
end
|
||||
end
|
||||
if not result.alias then
|
||||
if result.server and result.server_port then
|
||||
|
||||
@@ -1840,7 +1840,7 @@ The following extractors use this feature:
|
||||
#### youtube
|
||||
* `lang`: Prefer translated metadata (`title`, `description` etc) of this language code (case-sensitive). By default, the video primary language metadata is preferred, with a fallback to `en` translated. See [youtube/_base.py](https://github.com/yt-dlp/yt-dlp/blob/415b4c9f955b1a0391204bd24a7132590e7b3bdb/yt_dlp/extractor/youtube/_base.py#L402-L409) for the list of supported content language codes
|
||||
* `skip`: One or more of `hls`, `dash` or `translated_subs` to skip extraction of the m3u8 manifests, dash manifests and [auto-translated subtitles](https://github.com/yt-dlp/yt-dlp/issues/4090#issuecomment-1158102032) respectively
|
||||
* `player_client`: Clients to extract video data from. The currently available clients are `web`, `web_safari`, `web_embedded`, `web_music`, `web_creator`, `mweb`, `ios`, `android`, `android_sdkless`, `android_vr`, `tv`, `tv_simply` and `tv_embedded`. By default, `tv,android_sdkless,web` is used. If no JavaScript runtime is available, then `android_sdkless,web_safari,web` is used. If logged-in cookies are passed to yt-dlp, then `tv,web_safari,web` is used for free accounts and `tv,web_creator,web` is used for premium accounts. The `web_music` client is added for `music.youtube.com` URLs when logged-in cookies are used. The `web_embedded` client is added for age-restricted videos but only works if the video is embeddable. The `tv_embedded` and `web_creator` clients are added for age-restricted videos if account age-verification is required. Some clients, such as `web` and `web_music`, require a `po_token` for their formats to be downloadable. Some clients, such as `web_creator`, will only work with authentication. Not all clients support authentication via cookies. You can use `default` for the default clients, or you can use `all` for all clients (not recommended). You can prefix a client with `-` to exclude it, e.g. `youtube:player_client=default,-ios`
|
||||
* `player_client`: Clients to extract video data from. The currently available clients are `web`, `web_safari`, `web_embedded`, `web_music`, `web_creator`, `mweb`, `ios`, `android`, `android_sdkless`, `android_vr`, `tv`, `tv_simply`, `tv_downgraded`, and `tv_embedded`. By default, `tv,android_sdkless,web` is used. If no JavaScript runtime is available, then `android_sdkless,web_safari,web` is used. If logged-in cookies are passed to yt-dlp, then `tv_downgraded,web_safari,web` is used for free accounts and `tv_downgraded,web_creator,web` is used for premium accounts. The `web_music` client is added for `music.youtube.com` URLs when logged-in cookies are used. The `web_embedded` client is added for age-restricted videos but only works if the video is embeddable. The `tv_embedded` and `web_creator` clients are added for age-restricted videos if account age-verification is required. Some clients, such as `web` and `web_music`, require a `po_token` for their formats to be downloadable. Some clients, such as `web_creator`, will only work with authentication. Not all clients support authentication via cookies. You can use `default` for the default clients, or you can use `all` for all clients (not recommended). You can prefix a client with `-` to exclude it, e.g. `youtube:player_client=default,-ios`
|
||||
* `player_skip`: Skip some network requests that are generally needed for robust extraction. One or more of `configs` (skip client configs), `webpage` (skip initial webpage), `js` (skip js player), `initial_data` (skip initial data/next ep request). While these options can help reduce the number of requests needed or avoid some rate-limiting, they could cause issues such as missing formats or metadata. See [#860](https://github.com/yt-dlp/yt-dlp/pull/860) and [#12826](https://github.com/yt-dlp/yt-dlp/issues/12826) for more details
|
||||
* `webpage_skip`: Skip extraction of embedded webpage data. One or both of `player_response`, `initial_data`. These options are for testing purposes and don't skip any network requests
|
||||
* `player_params`: YouTube player parameters to use for player requests. Will overwrite any default ones set by yt-dlp.
|
||||
|
||||
@@ -488,20 +488,6 @@ class FFmpegFD(ExternalFD):
|
||||
if not self.params.get('verbose'):
|
||||
args += ['-hide_banner']
|
||||
|
||||
args += traverse_obj(info_dict, ('downloader_options', 'ffmpeg_args', ...))
|
||||
|
||||
# These exists only for compatibility. Extractors should use
|
||||
# info_dict['downloader_options']['ffmpeg_args'] instead
|
||||
args += info_dict.get('_ffmpeg_args') or []
|
||||
seekable = info_dict.get('_seekable')
|
||||
if seekable is not None:
|
||||
# setting -seekable prevents ffmpeg from guessing if the server
|
||||
# supports seeking(by adding the header `Range: bytes=0-`), which
|
||||
# can cause problems in some cases
|
||||
# https://github.com/ytdl-org/youtube-dl/issues/11800#issuecomment-275037127
|
||||
# http://trac.ffmpeg.org/ticket/6125#comment:10
|
||||
args += ['-seekable', '1' if seekable else '0']
|
||||
|
||||
env = None
|
||||
proxy = self.params.get('proxy')
|
||||
if proxy:
|
||||
@@ -521,39 +507,10 @@ class FFmpegFD(ExternalFD):
|
||||
env['HTTP_PROXY'] = proxy
|
||||
env['http_proxy'] = proxy
|
||||
|
||||
protocol = info_dict.get('protocol')
|
||||
|
||||
if protocol == 'rtmp':
|
||||
player_url = info_dict.get('player_url')
|
||||
page_url = info_dict.get('page_url')
|
||||
app = info_dict.get('app')
|
||||
play_path = info_dict.get('play_path')
|
||||
tc_url = info_dict.get('tc_url')
|
||||
flash_version = info_dict.get('flash_version')
|
||||
live = info_dict.get('rtmp_live', False)
|
||||
conn = info_dict.get('rtmp_conn')
|
||||
if player_url is not None:
|
||||
args += ['-rtmp_swfverify', player_url]
|
||||
if page_url is not None:
|
||||
args += ['-rtmp_pageurl', page_url]
|
||||
if app is not None:
|
||||
args += ['-rtmp_app', app]
|
||||
if play_path is not None:
|
||||
args += ['-rtmp_playpath', play_path]
|
||||
if tc_url is not None:
|
||||
args += ['-rtmp_tcurl', tc_url]
|
||||
if flash_version is not None:
|
||||
args += ['-rtmp_flashver', flash_version]
|
||||
if live:
|
||||
args += ['-rtmp_live', 'live']
|
||||
if isinstance(conn, list):
|
||||
for entry in conn:
|
||||
args += ['-rtmp_conn', entry]
|
||||
elif isinstance(conn, str):
|
||||
args += ['-rtmp_conn', conn]
|
||||
|
||||
start_time, end_time = info_dict.get('section_start') or 0, info_dict.get('section_end')
|
||||
|
||||
fallback_input_args = traverse_obj(info_dict, ('downloader_options', 'ffmpeg_args', ...))
|
||||
|
||||
selected_formats = info_dict.get('requested_formats') or [info_dict]
|
||||
for i, fmt in enumerate(selected_formats):
|
||||
is_http = re.match(r'https?://', fmt['url'])
|
||||
@@ -572,6 +529,37 @@ class FFmpegFD(ExternalFD):
|
||||
if end_time:
|
||||
args += ['-t', str(end_time - start_time)]
|
||||
|
||||
protocol = fmt.get('protocol')
|
||||
|
||||
if protocol == 'rtmp':
|
||||
player_url = fmt.get('player_url')
|
||||
page_url = fmt.get('page_url')
|
||||
app = fmt.get('app')
|
||||
play_path = fmt.get('play_path')
|
||||
tc_url = fmt.get('tc_url')
|
||||
flash_version = fmt.get('flash_version')
|
||||
live = fmt.get('rtmp_live', False)
|
||||
conn = fmt.get('rtmp_conn')
|
||||
if player_url is not None:
|
||||
args += ['-rtmp_swfverify', player_url]
|
||||
if page_url is not None:
|
||||
args += ['-rtmp_pageurl', page_url]
|
||||
if app is not None:
|
||||
args += ['-rtmp_app', app]
|
||||
if play_path is not None:
|
||||
args += ['-rtmp_playpath', play_path]
|
||||
if tc_url is not None:
|
||||
args += ['-rtmp_tcurl', tc_url]
|
||||
if flash_version is not None:
|
||||
args += ['-rtmp_flashver', flash_version]
|
||||
if live:
|
||||
args += ['-rtmp_live', 'live']
|
||||
if isinstance(conn, list):
|
||||
for entry in conn:
|
||||
args += ['-rtmp_conn', entry]
|
||||
elif isinstance(conn, str):
|
||||
args += ['-rtmp_conn', conn]
|
||||
|
||||
url = fmt['url']
|
||||
if self.params.get('enable_file_urls') and url.startswith('file:'):
|
||||
# The default protocol_whitelist is 'file,crypto,data' when reading local m3u8 URLs,
|
||||
@@ -586,6 +574,7 @@ class FFmpegFD(ExternalFD):
|
||||
# https://trac.ffmpeg.org/ticket/2702
|
||||
url = re.sub(r'^file://(?:localhost)?/', 'file:' if os.name == 'nt' else 'file:/', url)
|
||||
|
||||
args += traverse_obj(fmt, ('downloader_options', 'ffmpeg_args', ...)) or fallback_input_args
|
||||
args += [*self._configuration_args((f'_i{i + 1}', '_i')), '-i', url]
|
||||
|
||||
if not (start_time or end_time) or not self.params.get('force_keyframes_at_cuts'):
|
||||
|
||||
@@ -327,6 +327,17 @@ INNERTUBE_CLIENTS = {
|
||||
# See: https://github.com/youtube/cobalt/blob/main/cobalt/browser/user_agent/user_agent_platform_info.cc#L506
|
||||
'AUTHENTICATED_USER_AGENT': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/25.lts.30.1034943-gold (unlike Gecko), Unknown_TV_Unknown_0/Unknown (Unknown, Unknown)',
|
||||
},
|
||||
'tv_downgraded': {
|
||||
'INNERTUBE_CONTEXT': {
|
||||
'client': {
|
||||
'clientName': 'TVHTML5',
|
||||
'clientVersion': '4',
|
||||
'userAgent': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version',
|
||||
},
|
||||
},
|
||||
'INNERTUBE_CONTEXT_CLIENT_NAME': 7,
|
||||
'SUPPORTS_COOKIES': True,
|
||||
},
|
||||
'tv_simply': {
|
||||
'INNERTUBE_CONTEXT': {
|
||||
'client': {
|
||||
|
||||
@@ -147,9 +147,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
||||
_SUBTITLE_FORMATS = ('json3', 'srv1', 'srv2', 'srv3', 'ttml', 'srt', 'vtt')
|
||||
_DEFAULT_CLIENTS = ('tv', 'android_sdkless', 'web')
|
||||
_DEFAULT_JSLESS_CLIENTS = ('android_sdkless', 'web_safari', 'web')
|
||||
_DEFAULT_AUTHED_CLIENTS = ('tv', 'web_safari', 'web')
|
||||
_DEFAULT_AUTHED_CLIENTS = ('tv_downgraded', 'web_safari', 'web')
|
||||
# Premium does not require POT (except for subtitles)
|
||||
_DEFAULT_PREMIUM_CLIENTS = ('tv', 'web_creator', 'web')
|
||||
_DEFAULT_PREMIUM_CLIENTS = ('tv_downgraded', 'web_creator', 'web')
|
||||
|
||||
_GEO_BYPASS = False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user