👻 XHTTP и HTTP/2
Доработки XHTTP в Prizrak-Core. Регулятор потока и буфер отправки сделаны по идеям Medium1992 из mihomo-proxy-ros, параметры листенера повторяют Jolymmiles/Xray-core и Xray-core.
Регулятор потока HTTP/2 (h2-flow)
Заголовок раздела «Регулятор потока HTTP/2 (h2-flow)»Клиентская часть регулятора потока HTTP/2 для XHTTP в режиме h2. Сервер присылает данные с той скоростью, с какой клиент их читает. Без регулятора сервер заполняет большие окна HTTP/2 (в Go это 4 МиБ на поток), и в памяти копятся данные, которые никто не читает. Сервер настраивать не нужно: регулятор работает через стандартное управление потоком HTTP/2 и подходит для любого сервера.
Как он работает:
- Окно по потреблению. Регулятор показывает серверу окно 64 КиБ, ограничивает размер кадра 16 КиБ и раз в секунду измеряет RTT своим PING. Серверу возвращается кредит, только пока непрочитанных данных меньше, чем клиент успевает прочитать за пару кругов RTT.
- Быстрый разгон. Новый поток стартует с окном 256 КиБ или с тем, что недавно понадобилось соединению. До первого замера RTT окно открывается на каждый кредит.
- Модель канала по
min_rtt. На Linux и Android регулятор читает из ядра TCP_INFO (rtt,min_rtt,rttvar) и держит окно скачивания не больше1,25 × максимальная скорость чтения × min_rtt. На других системах используются замеры PING. - Совместимость с регулятором на сервере. Такой же регулятор есть на стороне сервера в Jolymmiles/Xray-core (параметр
h2Flow). Клиент с регулятором объявляет стандартное окно 65535, по нему сервер понимает, что на другой стороне тоже регулятор, и не ограничивает отправку. Поэтому включать регулятор можно на клиенте, на сервере или на обеих сторонах: скачивание не застопорится, скорость та же. Серверную часть умеет запускать и листенер Prizrak-Core, см. раздел Листенер ниже.
Выключен по умолчанию, включается в каждом прокси отдельно блоком h2-flow:
xhttp-opts: h2-flow: enabled: true max-stream-receive-window: 16777216 # окно приёма на поток, байт max-connection-receive-window: 33554432 # окно приёма на соединение, байтenabledвключает регулятор.- Окна приёма:
- необязательны, значения от 65535 байт до 1 ГиБ;
- если не заданы, действуют окна Go по умолчанию (4 МиБ на поток);
- с регулятором это потолок, а реальное окно следует за чтением;
- без регулятора это фиксированные окна.
h2-flow-control: trueтоже работает: это короткая записьh2-flow.enabled: true. Если заданы оба, решаетh2-flow.enabled.- Скачивание через
download-settingsиспользует тот же блокh2-flow.
Работает только в режиме h2. Для h3 и http/1.1 не действует.
Включить h2-flow для пользователей подписки Remnawave можно через маппер хоста Remnawave, см. раздел Регулятор потока XHTTP на странице интеграции с Remnawave.
Буфер отправки HTTP/2: 32 КиБ
Заголовок раздела «Буфер отправки HTTP/2: 32 КиБ»Долгоживущие HTTP/2-потоки держат буфер отправки открытым всё время соединения. Это XHTTP в режимах stream-one/stream-up и gRPC. Его размер снижен с 512 КиБ до 32 КиБ, через форк legiz-ru/prizrak-http поверх metacubex/http v0.1.8. При большом числе одновременных туннелей это заметно экономит память при той же скорости. Настраивать ничего не нужно.
Метод аплоада GET в режиме packet-up
Заголовок раздела «Метод аплоада GET в режиме packet-up»В режиме packet-up Prizrak-Core умеет отправлять аплоад-запросы методом GET, как Xray с "uplinkHTTPMethod": "GET". Данные при этом идут в теле запроса, в заголовке или в cookie, это задаёт uplink-data-placement. Листенер Prizrak-Core тоже принимает такие запросы от клиентов Xray.
xhttp-opts: path: /x mode: packet-up uplink-http-method: GET uplink-data-placement: header # body, header или cookieGETработает только в режимеpacket-up. Вstream-oneиstream-upконфиг не загрузится, ядро вернёт ошибку.- Регистр метода не важен:
getиGETравнозначны. uplink-data-keyпо умолчанию как в Xray:X-Dataдля header иx_dataдля cookie. Задавать его нужно, только если на сервере другое имя.- Для header и cookie размер одного аплоада без
sc-max-each-post-bytesравен 4 КиБ: сервер Xray принимает заголовки до 8 КиБ. В клиенте Xray значение по умолчанию 1 МБ, там его нужно уменьшать вручную.
Соответствие параметрам Xray:
Xray (xhttpSettings) | Prizrak-Core (xhttp-opts) |
|---|---|
"mode": "packet-up" | mode: packet-up |
"uplinkHTTPMethod": "GET" | uplink-http-method: GET |
"uplinkDataPlacement": "header" | uplink-data-placement: header |
"uplinkDataKey": "X-Data" | uplink-data-key: X-Data |
"scMaxEachPostBytes": "4000" | sc-max-each-post-bytes: 4000 |
Одно HTTP/2-соединение за раз
Заголовок раздела «Одно HTTP/2-соединение за раз»Клиент XHTTP в режиме h2 открывает к серверу одно HTTP/2-соединение за раз. Раньше запросы, начатые одновременно, например при открытии страницы, открывали каждый своё соединение: 16 запросов на свежем подключении давали 13 соединений, а пока висело TLS-рукопожатие (цензор режет поток после ClientHello), все 16. Пачка рукопожатий — заметный признак для DPI, и она обходила reuse-settings.max-connections. Теперь такие запросы ждут одного дозвона и делят его соединение, новое открывается, только когда исчерпан лимит потоков сервера. Настраивать ничего не нужно. Это то же исправление, что -tags http2legacy в сборках Xray (XTLS/Xray-core#6797).
В режиме packet-up аплоад теперь также переотправляется по новому соединению, если сервер или CDN закрыл старое кадром GOAWAY. Раньше аплоад падал и соединение рвалось (так делает и Xray после XTLS/Xray-core#6632).
Аплоад методом OPTIONS
Заголовок раздела «Аплоад методом OPTIONS»uplink-http-method: OPTIONS работает с листенером Prizrak-Core так же, как с Xray начиная с v26.10.31 (XTLS/Xray-core#7290): запрос OPTIONS с заголовком Access-Control-Request-Method — это CORS-preflight, без него — аплоад. Раньше листенер отвечал на любой OPTIONS как на preflight и терял данные. Клиент отправляет любой заданный метод, в том числе OPTIONS; сервер должен быть Xray v26.10.31 или новее либо Prizrak-Core после v1.19.33-r8.
Листенер: регулятор, настройки HTTP/2 и KeepAlive для Mux.Cool
Заголовок раздела «Листенер: регулятор, настройки HTTP/2 и KeepAlive для Mux.Cool»xhttp-config листенера VLESS принимает три серверных параметра, как в Jolymmiles/Xray-core и Xray-core:
listeners: - name: vless-xhttp type: vless # ... xhttp-config: path: /x mux-keep-alive-secs: "20-25" # будить простаивающее скачивание packet-up / stream-up mux-keep-alive-bytes: "100-500" h2-flow: enabled: true # max-stream-receive-window: 6291456 # max-connection-receive-window: 6291456 # max-connection-send-window: 4194304 # -1 — без ограничения # queue-cuts: true h2-params: max-concurrent-streams: 256 # max-read-frame-size: 16384 # send-ping-timeout: 30sh2-flow— серверная часть регулятора потока. Выключен по умолчанию, работает только для HTTP/2 (TLS, REALITY и h2c).- Окна аплоада
max-stream-receive-windowиmax-connection-receive-window: от 65535 байт до 1 ГиБ; если не заданы, 6 МиБ с регулятором и 1 МиБ Go без него. max-connection-send-windowограничивает, сколько данных сервера держит клиент одного соединения, непрочитанными или как открытое окно: 4 МиБ по умолчанию,-1снимает ограничение. Клиента со своим регулятором это не касается.queue-cuts(включено по умолчанию) держит скорость скачивания рядом с другим трафиком на том же канале;falseотключает эти срезы.
- Окна аплоада
h2-params— настройки HTTP/2 сервера, какh2Paramsв Xray (XTLS/Xray-core#7295):max-concurrent-streams,max-read-frame-size,max-receive-buffer-per-connection,max-receive-buffer-per-stream,max-decoder-header-table-size,max-encoder-header-table-size,send-ping-timeout,ping-timeout,write-byte-timeout(длительности вида30sили число секунд),strict-max-concurrent-requests,permit-prohibited-cipher-suites. Незаданные поля остаются как в Go. Окно, заданное вh2-flow, важнее заданного здесь. С включённымh2-flowmax-concurrent-streamsне больше 4096.mux-keep-alive-secsиmux-keep-alive-bytes. Если клиент идёт через XHTTP с mux.cool и его скачивание в packet-up или stream-up столько секунд ничего не несёт, сервер шлёт кадр KeepAlive со случайным паддингом такого размера (не больше 1024 байт). Клиенты его отбрасывают, а CDN и обратные прокси не обрывают скачивание как простаивающее. Выключено по умолчанию;stream-oneне трогается.- Неверное значение не даёт листенеру запуститься при загрузке конфига, до открытия порта.
Соответствие параметрам Xray:
Xray (xhttpSettings) | Prizrak-Core (xhttp-config) |
|---|---|
"h2Flow": {"enabled": true} | h2-flow: {enabled: true} |
"h2Flow": {"maxConnectionSendWindow": -1} | h2-flow: {max-connection-send-window: -1} |
"h2Flow": {"queueCuts": false} | h2-flow: {queue-cuts: false} |
"h2Params": {"MaxConcurrentStreams": 256} | h2-params: {max-concurrent-streams: 256} |
"muxKeepAliveSecs": "20-25" | mux-keep-alive-secs: "20-25" |
"muxKeepAliveBytes": "100-500" | mux-keep-alive-bytes: "100-500" |