Add all project files, configs, scripts and results
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
459
benchmark_improvements.sh
Executable file
459
benchmark_improvements.sh
Executable file
@@ -0,0 +1,459 @@
|
||||
#!/usr/bin/env bash
|
||||
# benchmark_improvements.sh
|
||||
# Tests each DPI-resistance improvement independently against baseline.
|
||||
# Metrics: avg/P95 latency, jitter (std dev), download Mbps, upload Mbps.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
XRAY_BIN="/usr/local/x-ui/bin/xray-linux-amd64"
|
||||
SOCKS_PORT=11083
|
||||
REMOTE_IP="83.99.190.32"
|
||||
VENV="/home/alvis/ai-xray/venv"
|
||||
RESULTS_FILE="/home/alvis/ai-xray/improvement_results.md"
|
||||
LATENCY_SAMPLES=20
|
||||
|
||||
# Current config values
|
||||
PUBLIC_KEY="58Iqd6LuWXgvjAgo92-7KURhTp0Vj79yGF81l_iuvTw"
|
||||
PRIVATE_KEY="KJfhenZvJV1kXwv4kDC8NPBtMUY0RR8lFrxsxfXfFmY"
|
||||
UUID_B="6e422ab5-070a-43f6-8241-38cd56d23d24"
|
||||
SID_B="6036d37d12c443c4"
|
||||
XHTTP_PATH="/xt-6036d37d"
|
||||
DEST="www.delfi.lv:443"
|
||||
SNI="www.delfi.lv"
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
|
||||
hdr() { echo ""; echo -e "${BOLD}${CYAN}══ $1 ══${NC}"; }
|
||||
pass() { echo -e " ${GREEN}✓${NC} $1"; }
|
||||
fail() { echo -e " ${RED}✗${NC} $1"; }
|
||||
info() { echo -e " ${YELLOW}→${NC} $1"; }
|
||||
|
||||
XRAY_PID=""
|
||||
cleanup() {
|
||||
if [[ -n "$XRAY_PID" ]]; then
|
||||
kill "$XRAY_PID" 2>/dev/null || true
|
||||
wait "$XRAY_PID" 2>/dev/null || true
|
||||
XRAY_PID=""
|
||||
fi
|
||||
}
|
||||
trap 'cleanup; rm -f /tmp/bench-cfg.json' EXIT
|
||||
|
||||
# ── Remote inbound updater ─────────────────────────────────────────────────
|
||||
remote_update() {
|
||||
local stream_json="$1"
|
||||
local uuid="$2"
|
||||
source "$VENV/bin/activate"
|
||||
python3 << PYEOF
|
||||
import requests, json
|
||||
import urllib3; urllib3.disable_warnings()
|
||||
s = requests.Session(); s.verify = False
|
||||
BASE = "https://share.alogins.net:16627/gBdsRLtVZdgZ63wmVR"
|
||||
s.post(f"{BASE}/login", data={"username": "xrayadmin", "password": "Admin2026!"})
|
||||
stream = $stream_json
|
||||
client = {"id": "$uuid", "flow": "", "email": "bench",
|
||||
"limitIp": 0, "totalGB": 0, "expiryTime": 0,
|
||||
"enable": True, "tgId": "", "subId": "", "comment": ""}
|
||||
payload = {"id": 1, "tag": "inbound-443", "enable": True, "port": 443,
|
||||
"listen": "", "protocol": "vless",
|
||||
"settings": json.dumps({"clients": [client], "decryption": "none", "fallbacks": []}),
|
||||
"streamSettings": json.dumps(stream),
|
||||
"sniffing": json.dumps({"enabled": False}),
|
||||
"remark": "inbound-443", "expiryTime": 0}
|
||||
r = s.post(f"{BASE}/panel/api/inbounds/update/1", json=payload)
|
||||
ok = r.json().get("success")
|
||||
print(f" Remote updated: {ok}")
|
||||
PYEOF
|
||||
}
|
||||
|
||||
restore_remote() {
|
||||
remote_update '{
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False,
|
||||
"dest": "'"$DEST"'",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "'"$PRIVATE_KEY"'",
|
||||
"shortIds": ["'"$SID_B"'", "48b4c16249ad44ff", ""]
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "'"$XHTTP_PATH"'", "host": "",
|
||||
"mode": "auto",
|
||||
"extra": {"xPaddingBytes": "100-1000", "xmux": {
|
||||
"maxConcurrency": "16-32", "maxConnections": 0,
|
||||
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
|
||||
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}}
|
||||
}
|
||||
}' "$UUID_B"
|
||||
sleep 2
|
||||
}
|
||||
|
||||
# ── Core benchmark runner ──────────────────────────────────────────────────
|
||||
bench() {
|
||||
local label="$1"
|
||||
local cfg_file="$2"
|
||||
|
||||
# Validate
|
||||
if ! "$XRAY_BIN" -test -c "$cfg_file" &>/dev/null; then
|
||||
fail "Config invalid — skipping"
|
||||
echo "$label|INVALID|—|—|—|—|—" >> /tmp/bench.tsv
|
||||
return
|
||||
fi
|
||||
|
||||
# Start xray
|
||||
cleanup
|
||||
"$XRAY_BIN" -c "$cfg_file" >/tmp/bench-xray.log 2>&1 &
|
||||
XRAY_PID=$!
|
||||
sleep 2
|
||||
|
||||
if ! kill -0 "$XRAY_PID" 2>/dev/null; then
|
||||
fail "Xray failed to start"
|
||||
echo "$label|FAIL|—|—|—|—|—" >> /tmp/bench.tsv
|
||||
return
|
||||
fi
|
||||
|
||||
# Connectivity check
|
||||
local exit_ip
|
||||
exit_ip=$(curl -s --socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 15 \
|
||||
https://api.ipify.org 2>/dev/null || echo "FAIL")
|
||||
if [[ "$exit_ip" != "$REMOTE_IP" ]]; then
|
||||
fail "No connectivity (exit IP: $exit_ip)"
|
||||
cleanup
|
||||
echo "$label|NO-CONN|—|—|—|—|—" >> /tmp/bench.tsv
|
||||
return
|
||||
fi
|
||||
pass "Connected via $exit_ip"
|
||||
|
||||
# Latency — N samples
|
||||
info "Latency ($LATENCY_SAMPLES samples)..."
|
||||
local lats=()
|
||||
for i in $(seq 1 $LATENCY_SAMPLES); do
|
||||
local ms
|
||||
ms=$(curl -s -o /dev/null -w "%{time_total}" --socks5-hostname 127.0.0.1:$SOCKS_PORT \
|
||||
--max-time 8 https://www.gstatic.com/generate_204 2>/dev/null \
|
||||
| awk '{printf "%d", $1*1000}')
|
||||
if [[ -n "$ms" && "$ms" -gt 0 ]]; then
|
||||
lats+=("$ms")
|
||||
fi
|
||||
done
|
||||
|
||||
local n=${#lats[@]} avg=0 p95=0 jitter=0 min=0 max=0
|
||||
if [[ $n -gt 0 ]]; then
|
||||
local sorted=($(printf '%s\n' "${lats[@]}" | sort -n))
|
||||
min=${sorted[0]}; max=${sorted[-1]}
|
||||
local sum=0; for v in "${lats[@]}"; do sum=$((sum+v)); done
|
||||
avg=$((sum/n))
|
||||
local p95i=$((n*95/100)); [[ $p95i -ge $n ]] && p95i=$((n-1))
|
||||
p95=${sorted[$p95i]}
|
||||
# Jitter = std dev (via python for float math)
|
||||
local csv_lats
|
||||
csv_lats=$(printf '%s,' "${lats[@]}" | sed 's/,$//')
|
||||
jitter=$(python3 -c "
|
||||
import math
|
||||
d=[$csv_lats]
|
||||
m=sum(d)/len(d)
|
||||
print(int(math.sqrt(sum((x-m)**2 for x in d)/len(d))))
|
||||
")
|
||||
fi
|
||||
pass "Latency: avg=${avg}ms p95=${p95}ms jitter=${jitter}ms (n=$n)"
|
||||
|
||||
# Download 10MB
|
||||
info "Download 10MB..."
|
||||
local dl_out
|
||||
dl_out=$(curl -s -o /dev/null -w "%{size_download} %{time_total}" \
|
||||
--socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 30 \
|
||||
"https://speed.cloudflare.com/__down?bytes=10485760" 2>/dev/null || echo "0 1")
|
||||
local dl_bytes dl_time dl_mbps=0
|
||||
dl_bytes=$(echo "$dl_out" | awk '{print $1}')
|
||||
dl_time=$(echo "$dl_out" | awk '{print $2}')
|
||||
if [[ "${dl_bytes:-0}" -gt 1000000 ]]; then
|
||||
dl_mbps=$(echo "scale=1; $dl_bytes*8/$dl_time/1000000" | bc)
|
||||
pass "Download: ${dl_mbps} Mbps"
|
||||
else
|
||||
fail "Download failed"
|
||||
fi
|
||||
|
||||
# Upload 5MB
|
||||
info "Upload 5MB..."
|
||||
local ul_out
|
||||
ul_out=$(dd if=/dev/urandom bs=1M count=5 2>/dev/null | \
|
||||
curl -s -o /dev/null -w "%{size_upload} %{time_total}" \
|
||||
--socks5-hostname 127.0.0.1:$SOCKS_PORT --max-time 30 \
|
||||
-X POST --data-binary @- https://httpbin.org/post 2>/dev/null || echo "0 1")
|
||||
local ul_bytes ul_time ul_mbps=0
|
||||
ul_bytes=$(echo "$ul_out" | awk '{print $1}')
|
||||
ul_time=$(echo "$ul_out" | awk '{print $2}')
|
||||
if [[ "${ul_bytes:-0}" -gt 100000 ]]; then
|
||||
ul_mbps=$(echo "scale=1; $ul_bytes*8/$ul_time/1000000" | bc)
|
||||
pass "Upload: ${ul_mbps} Mbps"
|
||||
else
|
||||
fail "Upload failed"
|
||||
ul_mbps=0
|
||||
fi
|
||||
|
||||
echo "$label|OK|$avg|$p95|$jitter|$dl_mbps|$ul_mbps" >> /tmp/bench.tsv
|
||||
cleanup
|
||||
sleep 1
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
# CONFIGS
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
# Baseline config writer helper
|
||||
write_xhttp_cfg() {
|
||||
local fp="$1" use_frag="$2" host_hdr="$3" path="$4" sni_val="$5"
|
||||
local frag_sockopt=""
|
||||
[[ "$use_frag" == "yes" ]] && frag_sockopt='"sockopt": {"dialerProxy": "frag-chain1"},'
|
||||
|
||||
cat > /tmp/bench-cfg.json << EOF
|
||||
{
|
||||
"log": {"loglevel": "error"},
|
||||
"inbounds": [{"listen":"127.0.0.1","port":$SOCKS_PORT,"protocol":"socks","settings":{"auth":"noauth","udp":true}}],
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "proxy", "protocol": "vless",
|
||||
"settings": {"vnext": [{"address": "share.alogins.net", "port": 443,
|
||||
"users": [{"id": "$UUID_B", "flow": "", "encryption": "none"}]}]},
|
||||
"streamSettings": {
|
||||
$frag_sockopt
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"fingerprint": "$fp",
|
||||
"serverName": "$sni_val",
|
||||
"publicKey": "$PUBLIC_KEY",
|
||||
"shortId": "$SID_B",
|
||||
"spiderX": "/"
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "$path",
|
||||
"host": "$host_hdr",
|
||||
"mode": "auto",
|
||||
"extra": {
|
||||
"xPaddingBytes": "100-1000",
|
||||
"xmux": {"maxConcurrency": "16-32", "maxConnections": 0,
|
||||
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
|
||||
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "frag-chain1", "protocol": "freedom",
|
||||
"settings": {"fragment": {"packets": "tlshello", "length": "100-200", "interval": "10-20"}},
|
||||
"streamSettings": {"sockopt": {"dialerProxy": "frag-chain2"}}
|
||||
},
|
||||
{
|
||||
"tag": "frag-chain2", "protocol": "freedom",
|
||||
"settings": {"fragment": {"packets": "1-3", "length": "1-5", "interval": "1-2"}}
|
||||
},
|
||||
{"tag": "direct", "protocol": "freedom"}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
# MAIN
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
echo "label|status|avg_ms|p95_ms|jitter_ms|dl_mbps|ul_mbps" > /tmp/bench.tsv
|
||||
|
||||
# Ensure baseline remote config is active
|
||||
info "Ensuring baseline remote config..."
|
||||
restore_remote
|
||||
|
||||
# ── 0. BASELINE ────────────────────────────────────────────────────────────
|
||||
hdr "0. BASELINE (current config)"
|
||||
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "0-baseline" /tmp/bench-cfg.json
|
||||
|
||||
# ── 1. fingerprint=randomized ──────────────────────────────────────────────
|
||||
hdr "1. fingerprint: randomized"
|
||||
write_xhttp_cfg "randomized" "no" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "1-fp-randomized" /tmp/bench-cfg.json
|
||||
|
||||
# ── 2. fingerprint=firefox ────────────────────────────────────────────────
|
||||
hdr "2. fingerprint: firefox"
|
||||
write_xhttp_cfg "firefox" "no" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "2-fp-firefox" /tmp/bench-cfg.json
|
||||
|
||||
# ── 3. + TLS ClientHello fragment chain ───────────────────────────────────
|
||||
hdr "3. fragment chain on TLS ClientHello"
|
||||
write_xhttp_cfg "chrome" "yes" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "3-fragment-chain" /tmp/bench-cfg.json
|
||||
|
||||
# ── 4. + host header = SNI domain ─────────────────────────────────────────
|
||||
hdr "4. host header = www.delfi.lv"
|
||||
write_xhttp_cfg "chrome" "no" "www.delfi.lv" "$XHTTP_PATH" "$SNI"
|
||||
bench "4-host-header" /tmp/bench-cfg.json
|
||||
|
||||
# ── 5. realistic XHTTP path + host header (needs server update) ───────────
|
||||
hdr "5. realistic path /api/v2/stream + host header"
|
||||
info "Updating remote path to /api/v2/stream ..."
|
||||
remote_update '{
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": False,
|
||||
"dest": "'"$DEST"'",
|
||||
"serverNames": ["www.delfi.lv","www.lmt.lv","www.inbox.lv","e-klase.lv"],
|
||||
"privateKey": "'"$PRIVATE_KEY"'",
|
||||
"shortIds": ["'"$SID_B"'", ""]
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "/api/v2/stream", "host": "www.delfi.lv",
|
||||
"mode": "auto",
|
||||
"extra": {"xPaddingBytes": "100-1000", "xmux": {
|
||||
"maxConcurrency": "16-32", "maxConnections": 0,
|
||||
"cMaxReuseTimes": "64-128", "cMaxLifetimeMs": 0,
|
||||
"hMaxRequestTimes": "600-900", "hMaxReusableSecs": "1800-3000"}}
|
||||
}
|
||||
}' "$UUID_B"
|
||||
sleep 2
|
||||
write_xhttp_cfg "chrome" "no" "www.delfi.lv" "/api/v2/stream" "$SNI"
|
||||
bench "5-realistic-path" /tmp/bench-cfg.json
|
||||
restore_remote
|
||||
|
||||
# ── 6. SNI = e-klase.lv (highest throughput in SNI test) ──────────────────
|
||||
hdr "6. SNI = e-klase.lv (top SNI from previous benchmark)"
|
||||
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "e-klase.lv"
|
||||
bench "6-sni-eklase" /tmp/bench-cfg.json
|
||||
|
||||
# ── 7. SNI = www.lmt.lv ───────────────────────────────────────────────────
|
||||
hdr "7. SNI = www.lmt.lv"
|
||||
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "www.lmt.lv"
|
||||
bench "7-sni-lmt" /tmp/bench-cfg.json
|
||||
|
||||
# ── 8. BBR check + enable on remote ───────────────────────────────────────
|
||||
hdr "8. BBR congestion control on remote server"
|
||||
source "$VENV/bin/activate"
|
||||
BBR_STATUS=$(python3 << 'PYEOF'
|
||||
import paramiko
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect("83.99.190.32", username="juris", password="VitaIeva2A.")
|
||||
_, out, _ = ssh.exec_command("lxc exec xray -- sysctl net.ipv4.tcp_congestion_control 2>/dev/null")
|
||||
cc = out.read().decode().strip()
|
||||
_, out2, _ = ssh.exec_command("lxc exec xray -- sysctl net.core.default_qdisc 2>/dev/null")
|
||||
qd = out2.read().decode().strip()
|
||||
print(f"cc={cc} | qd={qd}")
|
||||
ssh.close()
|
||||
PYEOF
|
||||
)
|
||||
info "Current: $BBR_STATUS"
|
||||
|
||||
if echo "$BBR_STATUS" | grep -q "bbr"; then
|
||||
info "BBR already enabled — testing as-is"
|
||||
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "8-bbr-already-on" /tmp/bench-cfg.json
|
||||
else
|
||||
info "Enabling BBR on remote container..."
|
||||
python3 << 'PYEOF'
|
||||
import paramiko
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect("83.99.190.32", username="juris", password="VitaIeva2A.")
|
||||
for cmd in [
|
||||
"lxc exec xray -- sysctl -w net.core.default_qdisc=fq",
|
||||
"lxc exec xray -- sysctl -w net.ipv4.tcp_congestion_control=bbr",
|
||||
"lxc exec xray -- sysctl -w net.core.rmem_max=16777216",
|
||||
"lxc exec xray -- sysctl -w net.core.wmem_max=16777216",
|
||||
]:
|
||||
_, out, err = ssh.exec_command(cmd)
|
||||
print(f" {cmd.split('--')[1].strip()}: {(out.read()+err.read()).decode().strip()}")
|
||||
ssh.close()
|
||||
PYEOF
|
||||
sleep 1
|
||||
write_xhttp_cfg "chrome" "no" "" "$XHTTP_PATH" "$SNI"
|
||||
bench "8-bbr-enabled" /tmp/bench-cfg.json
|
||||
fi
|
||||
|
||||
# ── Restore remote to canonical state ─────────────────────────────────────
|
||||
hdr "Restoring remote to baseline"
|
||||
restore_remote
|
||||
pass "Remote restored"
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
# SUMMARY
|
||||
# ══════════════════════════════════════════════════════════════════════════
|
||||
hdr "RESULTS SUMMARY"
|
||||
echo ""
|
||||
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" "Test" "Avg ms" "P95 ms" "Jitter ms" "DL Mbps" "UL Mbps"
|
||||
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" "────────────────────────────────" "───────" "───────" "─────────" "───────" "───────"
|
||||
|
||||
BASELINE_AVG=0; BASELINE_P95=0; BASELINE_JIT=0; BASELINE_DL=0; BASELINE_UL=0
|
||||
while IFS='|' read -r label status avg p95 jit dl ul; do
|
||||
[[ "$label" == "label" ]] && continue
|
||||
if [[ "$status" == "OK" ]]; then
|
||||
if [[ "$label" == "0-baseline" ]]; then
|
||||
BASELINE_AVG=$avg; BASELINE_P95=$p95; BASELINE_JIT=$jit
|
||||
BASELINE_DL=$dl; BASELINE_UL=$ul
|
||||
printf "${BOLD}%-32s${NC} %-7s %-7s %-9s %-9s %-9s\n" \
|
||||
"$label" "${avg}ms" "${p95}ms" "${jit}ms" "${dl}" "${ul}"
|
||||
else
|
||||
# Delta indicators
|
||||
local_delta_avg="" local_delta_jit="" local_delta_dl=""
|
||||
[[ -n "$BASELINE_AVG" && "$BASELINE_AVG" -gt 0 ]] && {
|
||||
diff=$((avg - BASELINE_AVG))
|
||||
[[ $diff -lt 0 ]] && local_delta_avg="${GREEN}${diff}${NC}" || local_delta_avg="${RED}+${diff}${NC}"
|
||||
}
|
||||
printf "%-32s %-7s %-7s %-9s %-9s %-9s\n" \
|
||||
"$label" "${avg}ms" "${p95}ms" "${jit}ms" "${dl}" "${ul}"
|
||||
fi
|
||||
else
|
||||
printf "${RED}%-32s${NC} %s\n" "$label" "$status"
|
||||
fi
|
||||
done < /tmp/bench.tsv
|
||||
|
||||
# Write markdown
|
||||
{
|
||||
cat << MDEOF
|
||||
# DPI Resistance Improvement Benchmark
|
||||
|
||||
**Date**: $(date '+%Y-%m-%d %H:%M')
|
||||
**Baseline**: VLESS+XHTTP+Reality, fingerprint=chrome, SNI=www.delfi.lv, path=/xt-6036d37d
|
||||
**Latency samples per test**: $LATENCY_SAMPLES
|
||||
**Jitter**: standard deviation of latency samples
|
||||
|
||||
## Results
|
||||
|
||||
| Test | Avg ms | P95 ms | Jitter ms | DL Mbps | UL Mbps | Notes |
|
||||
|------|--------|--------|-----------|---------|---------|-------|
|
||||
MDEOF
|
||||
|
||||
while IFS='|' read -r label status avg p95 jit dl ul; do
|
||||
[[ "$label" == "label" ]] && continue
|
||||
notes=""
|
||||
case "$label" in
|
||||
0-baseline) notes="Current active config" ;;
|
||||
1-fp-randomized) notes="uTLS fingerprint rotated per connection" ;;
|
||||
2-fp-firefox) notes="Firefox uTLS profile" ;;
|
||||
3-fragment-chain) notes="TLS ClientHello split 100-200B + micro-frag 1-5B" ;;
|
||||
4-host-header) notes="HTTP Host header = www.delfi.lv" ;;
|
||||
5-realistic-path) notes="Path=/api/v2/stream + Host header" ;;
|
||||
6-sni-eklase) notes="SNI switched to e-klase.lv" ;;
|
||||
7-sni-lmt) notes="SNI switched to www.lmt.lv" ;;
|
||||
8-bbr*) notes="BBR congestion control on remote" ;;
|
||||
esac
|
||||
if [[ "$status" == "OK" ]]; then
|
||||
echo "| $label | ${avg}ms | ${p95}ms | ${jit}ms | ${dl} | ${ul} | $notes |"
|
||||
else
|
||||
echo "| $label | — | — | — | — | — | $status |"
|
||||
fi
|
||||
done < /tmp/bench.tsv
|
||||
|
||||
cat << 'MDEOF'
|
||||
|
||||
## What Each Test Changes
|
||||
- **fingerprint=randomized**: uTLS fingerprint rotated per connection — defeats fingerprint-based blocking
|
||||
- **fingerprint=firefox**: Firefox uTLS profile instead of Chrome
|
||||
- **fragment chain**: TLS ClientHello split into 100-200B chunks, then micro-fragmented 1-5B + noise — defeats handshake DPI
|
||||
- **host header**: Sets HTTP `Host:` header to match SNI — makes request look more legitimate
|
||||
- **realistic path**: Changes XHTTP path from synthetic to `/api/v2/stream` with matching host header
|
||||
- **SNI e-klase.lv / lmt.lv**: Alternative SNIs from previous benchmark (dest stays www.delfi.lv)
|
||||
- **BBR**: Linux BBR congestion control + larger TCP buffers on remote — improves throughput under loss
|
||||
MDEOF
|
||||
} > "$RESULTS_FILE"
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD}Results: $RESULTS_FILE${NC}"
|
||||
Reference in New Issue
Block a user