<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Citrus · News</title><description>Citrus news: releases, protocol changes and plans.</description><link>https://getmikan.github.io/Citrus/en/news/</link><language>en</language><item><title>Second beta — faster upload and download, lower latency under load</title><link>https://getmikan.github.io/Citrus/en/news/beta-2/</link><guid isPermaLink="true">https://getmikan.github.io/Citrus/en/news/beta-2/</guid><description>v1.0.0-beta.2 — a comparison with Xray, sing-box and mihomo on one host, faster download, latency under load, tunnel memory, TUIC, smux and quota fixes.</description><pubDate>Sun, 18 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The second beta release, &lt;a href=&quot;https://github.com/getmikan/Citrus/releases/tag/v1.0.0-beta.2&quot;&gt;&lt;code&gt;v1.0.0-beta.2&lt;/code&gt;&lt;/a&gt;, is out. The full list of changes is in the &lt;a href=&quot;/Citrus/en/changelog/&quot;&gt;changelog&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;four-servers-compared-126&quot;&gt;Four servers compared (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/126&quot;&gt;#126&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;Citrus, Xray v26.10.17, sing-box v1.14.3 and mihomo v1.19.32 were measured as servers on one host, eight protocols, the same clients for all. The results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Citrus leads upload: REALITY with 32 streams is 52% faster than the best of the others, and single-stream upload on REALITY and SS2022 is 40–49% faster.&lt;/li&gt;
&lt;li&gt;Citrus uses the least memory per idle tunnel on most protocols.&lt;/li&gt;
&lt;li&gt;sing-box leads AnyTLS, TUIC new connections and SS2022 download.&lt;/li&gt;
&lt;li&gt;Xray leads Trojan and SS2022 upload with 32 streams.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These numbers were measured before the changes below. The method, the caveats and every table are in &lt;code&gt;test/bench/compare/results/2026-10-18-four-cores/RESULTS.md&lt;/code&gt; in the repository.&lt;/p&gt;
&lt;h2 id=&quot;merged-after-the-comparison&quot;&gt;Merged after the comparison&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Download&lt;/strong&gt; (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/124&quot;&gt;#124&lt;/a&gt;). 64 KiB reads, and TLS records go to the socket together (in the getmikan/tls and getmikan/utls forks). With 32 streams, as the bench reports them: REALITY 2802 → 4235 MB/s, Trojan 2737 → 3936, SS2022 3895 → 4392.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency under load&lt;/strong&gt; (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/131&quot;&gt;#131&lt;/a&gt;). An echo next to eight downloads: 55–63 → 20 ms. For comparison, Xray is at about 77 ms and sing-box on SS2022 at about 47.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Idle tunnel memory&lt;/strong&gt; (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/129&quot;&gt;#129&lt;/a&gt;). Trojan −36% (37.7 KiB, below sing-box’s 43.6), AnyTLS −18%, REALITY −12%.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;QUIC&lt;/strong&gt; (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/125&quot;&gt;#125&lt;/a&gt;). The gap to sing-box on new streams went from 10–12% down to 4–6%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upload write batching (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/119&quot;&gt;#119&lt;/a&gt;) and fewer allocations per new connection (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/118&quot;&gt;#118&lt;/a&gt;) were in &lt;code&gt;dev&lt;/code&gt; before the comparison; its numbers already include them.&lt;/p&gt;
&lt;h2 id=&quot;fixes&quot;&gt;Fixes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TUIC: a &lt;code&gt;CONNECT&lt;/code&gt; with a 255-byte domain no longer crashes the server before authentication (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/125&quot;&gt;#125&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;smux is replaced with the &lt;a href=&quot;https://github.com/getmikan/smux&quot;&gt;getmikan/smux&lt;/a&gt; fork: after an error a caller’s buffer is no longer sent (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/123&quot;&gt;#123&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Limits: a race when closing a user over quota no longer touches the user’s new connections (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/116&quot;&gt;#116&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ci&quot;&gt;CI&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;-race&lt;/code&gt; job for the packages without races (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/121&quot;&gt;#121&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;A nightly performance check against mihomo (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/127&quot;&gt;#127&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;known-issues&quot;&gt;Known issues&lt;/h2&gt;
&lt;p&gt;The TUIC server accepts at most 2048 streams per QUIC connection. A client that opens more without waiting for stream credit (the sing-box client does this) gets errors on the extra ones.&lt;/p&gt;
&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;
&lt;p&gt;The AnyTLS rework (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/130&quot;&gt;#130&lt;/a&gt;) is planned for the next beta. The rest is on the &lt;a href=&quot;/Citrus/en/roadmap/&quot;&gt;Roadmap&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Audit closed, cascades, events, unix sockets and DNSCrypt</title><link>https://getmikan.github.io/Citrus/en/news/audit-cascades-events/</link><guid isPermaLink="true">https://getmikan.github.io/Citrus/en/news/audit-cascades-events/</guid><description>The week in dev — the audit fixes, chain groups, the /events stream, listeners on a unix socket, DNSCrypt and tests with mihomo clients.</description><pubDate>Thu, 15 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Everything below is merged into &lt;code&gt;dev&lt;/code&gt; and not in a release yet. To try it, &lt;a href=&quot;/Citrus/en/start/getting-started/#build-from-source&quot;&gt;build the core from source&lt;/a&gt;. The full list is in the &lt;a href=&quot;/Citrus/en/changelog/&quot;&gt;changelog&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-audit-is-closed&quot;&gt;The audit is closed&lt;/h2&gt;
&lt;p&gt;The static audit of the core has been worked through: its findings were fixed in a series of PRs from &lt;a href=&quot;https://github.com/getmikan/Citrus/pull/75&quot;&gt;#75&lt;/a&gt; to &lt;a href=&quot;https://github.com/getmikan/Citrus/pull/97&quot;&gt;#97&lt;/a&gt;, each with a test that fails on the old code. What users will notice most:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a controller on a network address needs a &lt;code&gt;secret&lt;/code&gt;, and on loopback without a secret it refuses browser requests from other sites;&lt;/li&gt;
&lt;li&gt;the HTTP proxy authenticates every request, UDP through SOCKS5 is bound to its user and port, and a password change closes sessions;&lt;/li&gt;
&lt;li&gt;self-update checks the package against the release’s &lt;code&gt;checksums.txt&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;a public provider URL cannot redirect into a private network, and paths are checked with symlinks resolved;&lt;/li&gt;
&lt;li&gt;state a client creates before authentication is bounded in every protocol;&lt;/li&gt;
&lt;li&gt;GitHub Actions and images are pinned by digest.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of these need config changes: they are collected on the new &lt;a href=&quot;/Citrus/en/migration/&quot;&gt;Migrating from mihomo&lt;/a&gt; page. How to report a vulnerability and what has been done to harden the core is on the &lt;a href=&quot;/Citrus/en/security/&quot;&gt;Security&lt;/a&gt; page.&lt;/p&gt;
&lt;h2 id=&quot;cascades-73&quot;&gt;Cascades (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/73&quot;&gt;#73&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;The new &lt;code&gt;type: chain&lt;/code&gt; group builds a chain of proxies and groups: the first hop is the entry, the last one is the exit.&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;/Citrus/_astro/ec.eoueo.css&quot;&gt;&lt;script type=&quot;module&quot; src=&quot;/Citrus/_astro/ec.0vx5m.js&quot;&gt;&lt;/script&gt;&lt;figure class=&quot;frame not-content&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;proxy-groups&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;exits&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;url-test&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;proxies&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;exit-de&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;exit-nl&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;https://cp.cloudflare.com/generate_204&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;cascade&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;chain&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;proxies&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: [&lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;entry&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;exits&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;]   &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# entry → best exit&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;https://cp.cloudflare.com/generate_204&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79C0FF&quot;&gt;300&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Копировать&quot; data-copied=&quot;Скопировано!&quot; data-code=&quot;proxy-groups:  - name: exits    type: url-test    proxies: [exit-de, exit-nl]    url: https://cp.cloudflare.com/generate_204  - name: cascade    type: chain    proxies: [entry, exits]   # entry → best exit    url: https://cp.cloudflare.com/generate_204    interval: 300&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;When the chain fails, the health check finds the first broken hop and reports it in &lt;code&gt;/proxies&lt;/code&gt;, &lt;code&gt;/metrics&lt;/code&gt; and a &lt;code&gt;chain.health&lt;/code&gt; event. More on the &lt;a href=&quot;/Citrus/en/start/chains/&quot;&gt;Chains&lt;/a&gt; page.&lt;/p&gt;
&lt;h2 id=&quot;the-event-stream-70&quot;&gt;The event stream (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/70&quot;&gt;#70&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GET /events&lt;/code&gt; streams core events over WebSocket, SSE or NDJSON: authentication, limits that kick in, user changes, config reloads, provider updates, listener and chain state. A panel no longer has to poll &lt;code&gt;/traffic/users&lt;/code&gt; and &lt;code&gt;/limits/users&lt;/code&gt; to learn that a quota ran out. See &lt;a href=&quot;/Citrus/en/start/events/&quot;&gt;Events&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;unix-sockets-68&quot;&gt;Unix sockets (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/68&quot;&gt;#68&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;TCP listeners (VLESS, Trojan, TrustTunnel, HTTP, SOCKS and more) can listen on a unix socket: &lt;code&gt;listen: unix:/run/citrus/vless.sock&lt;/code&gt;. That makes it easy to put a node behind nginx or Caddy, with the real client address passed through &lt;code&gt;trusted-proxy-header&lt;/code&gt; and &lt;code&gt;trusted-proxies: [loopback]&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;dnscrypt-63&quot;&gt;DNSCrypt (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/63&quot;&gt;#63&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;DNSCrypt v2 servers are set as &lt;code&gt;sdns://&lt;/code&gt; stamps in &lt;code&gt;nameserver&lt;/code&gt;. Queries go through the same dialer as the other DNS clients, so &lt;code&gt;#proxy&lt;/code&gt; and the rules apply and nothing leaks under TUN. No third-party DNSCrypt library was needed.&lt;/p&gt;
&lt;h2 id=&quot;mihomo-clients-74&quot;&gt;mihomo clients (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/74&quot;&gt;#74&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;A new interop suite runs the official mihomo v1.19.31 and v1.19.32 releases as clients against a Citrus server, the way the apps of Mikan users work. All 31 cases pass: REALITY with post-quantum settings, XHTTP, WebSocket, gRPC, Trojan, Shadowsocks 2022, Hysteria2, TUIC v5, AnyTLS, TrustTunnel, Snell, Mieru, Sudoku, HTTP and SOCKS. No incompatibility was found. The table is on the &lt;a href=&quot;/Citrus/en/compatibility/&quot;&gt;Compatibility&lt;/a&gt; page.&lt;/p&gt;
&lt;h2 id=&quot;also&quot;&gt;Also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PUT /rules&lt;/code&gt; replaces the rules without a config reload (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/64&quot;&gt;#64&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;XHTTP over h2 uses half the CPU per gigabyte (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/53&quot;&gt;#53&lt;/a&gt;), and an idle connection takes 30 KB less memory (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/52&quot;&gt;#52&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;JSON logs for Loki and ELK: &lt;code&gt;log-format: json&lt;/code&gt; (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/65&quot;&gt;#65&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;The getmikan/tls and getmikan/utls forks carry the TLS security fixes from Go 1.26 (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/58&quot;&gt;#58&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What comes next, the first release and moving the Mikan panel to Citrus, is on the &lt;a href=&quot;/Citrus/en/roadmap/&quot;&gt;Roadmap&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Post-quantum REALITY, faster XHTTP through CDNs, and a protocol cleanup</title><link>https://getmikan.github.io/Citrus/en/news/post-quantum-reality/</link><guid isPermaLink="true">https://getmikan.github.io/Citrus/en/news/post-quantum-reality/</guid><description>Merged into dev — post-quantum REALITY on the client and server, faster packet-up through CDNs, legacy protocols removed, a rejected-auth hook and race fixes.</description><pubDate>Mon, 12 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Everything below is merged into the &lt;code&gt;dev&lt;/code&gt; branch but is not in a release or prerelease yet. &lt;code&gt;dev&lt;/code&gt; is no longer packaged as &lt;code&gt;Prerelease-dev&lt;/code&gt;, so for now the only way to try it is to &lt;a href=&quot;/Citrus/en/start/getting-started/#build-from-source&quot;&gt;build the core from source&lt;/a&gt; on the &lt;code&gt;dev&lt;/code&gt; branch.&lt;/p&gt;
&lt;h2 id=&quot;post-quantum-reality-8-10&quot;&gt;Post-quantum REALITY (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/8&quot;&gt;#8&lt;/a&gt;, &lt;a href=&quot;https://github.com/getmikan/Citrus/pull/10&quot;&gt;#10&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;Since Xray 26.9.8, a REALITY server silently drops any ClientHello without an X25519MLKEM768 key share placed before X25519, so earlier Citrus could not connect to current Xray servers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Client (&lt;code&gt;reality-opts&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;X25519MLKEM768 is on by default. &lt;code&gt;support-x25519mlkem768: false&lt;/code&gt; sends the classical hello for old servers. Fingerprints without ML-KEM (ios, edge, randomized and others) get the key share added.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client-version&lt;/code&gt;: the Xray version the client reports to the server. Defaults to &lt;code&gt;26.10.10&lt;/code&gt;, instead of the hard-coded &lt;code&gt;1.8.2&lt;/code&gt;, so servers with &lt;code&gt;minClientVer&lt;/code&gt; accept it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mldsa65-verify&lt;/code&gt;: checks the ML-DSA-65 signature in the temporary certificate, like Xray’s &lt;code&gt;mldsa65Verify&lt;/code&gt; (&lt;code&gt;pqv&lt;/code&gt; in share links).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client-fingerprint: firefox&lt;/code&gt; and &lt;code&gt;safari&lt;/code&gt; now send the real Firefox 148 and Safari 26.3 hellos from our &lt;a href=&quot;https://github.com/getmikan/utls&quot;&gt;getmikan/utls&lt;/a&gt; fork. Xray names such as &lt;code&gt;hellofirefox_148&lt;/code&gt;, &lt;code&gt;hellosafari_26_3&lt;/code&gt; and &lt;code&gt;hellochrome_131&lt;/code&gt; are accepted too.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;/Citrus/_astro/ec.eoueo.css&quot;&gt;&lt;script type=&quot;module&quot; src=&quot;/Citrus/_astro/ec.0vx5m.js&quot;&gt;&lt;/script&gt;&lt;figure class=&quot;frame not-content&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;proxies&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;vless-reality-vision&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;vless&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79C0FF&quot;&gt;443&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;uuid&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;uuid&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;network&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;tcp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;tls&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79C0FF&quot;&gt;true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;flow&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;xtls-rprx-vision&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;servername&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;www.microsoft.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;client-fingerprint&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;chrome&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;reality-opts&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;public-key&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;xxx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;short-id&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;xxx&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# support-x25519mlkem768: true  # default; false only for old servers&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# client-version: 26.10.10      # default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# mldsa65-verify: xxx           # ML-DSA-65 public key (pqv)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Копировать&quot; data-copied=&quot;Скопировано!&quot; data-code=&quot;proxies:  - name: vless-reality-vision    type: vless    server: server    port: 443    uuid: uuid    network: tcp    tls: true    flow: xtls-rprx-vision    servername: www.microsoft.com    client-fingerprint: chrome    reality-opts:      public-key: xxx      short-id: xxx      # support-x25519mlkem768: true  # default; false only for old servers      # client-version: 26.10.10      # default      # mldsa65-verify: xxx           # ML-DSA-65 public key (pqv)&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Server (&lt;code&gt;reality-config&lt;/code&gt; on inbounds)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mldsa65-seed&lt;/code&gt;: signs the temporary certificate with ML-DSA-65, like Xray’s &lt;code&gt;mldsa65Seed&lt;/code&gt;. The &lt;code&gt;dest&lt;/code&gt; certificate chain must be at least about 3.5 KB, or the signature does not fit and the handshake fails. Xray has the same limit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;require-x25519mlkem768&lt;/code&gt;: only accept clients with X25519MLKEM768; the rest fall back to &lt;code&gt;dest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;min-client-ver&lt;/code&gt; and &lt;code&gt;max-client-ver&lt;/code&gt;: the accepted range of client versions.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame not-content&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;listeners&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;vless-in&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;vless&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79C0FF&quot;&gt;443&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;users&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#79C0FF&quot;&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;uuid&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;uuid&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;flow&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;xtls-rprx-vision&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;reality-config&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;dest&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;test.com:443&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;private-key&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;xxx&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;   &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# citrus generate reality-keypair&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;short-id&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;0123456789abcdef&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#7EE787&quot;&gt;server-names&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E6EDF3&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;--0:#A5D6FF&quot;&gt;test.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# max-time-difference: 60000     # milliseconds&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# mldsa65-seed: xxx              # xray mldsa65&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# require-x25519mlkem768: true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# min-client-ver: 26.9.8&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#8B949E&quot;&gt;# max-client-ver: 26.10.10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Копировать&quot; data-copied=&quot;Скопировано!&quot; data-code=&quot;listeners:  - name: vless-in    type: vless    port: 443    users:      - username: 1        uuid: uuid        flow: xtls-rprx-vision    reality-config:      dest: test.com:443      private-key: xxx   # citrus generate reality-keypair      short-id:        - 0123456789abcdef      server-names:        - test.com      # max-time-difference: 60000     # milliseconds      # mldsa65-seed: xxx              # xray mldsa65      # require-x25519mlkem768: true      # min-client-ver: 26.9.8      # max-client-ver: 26.10.10&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Live-tested against Xray 26.10.10 (VLESS + Vision + REALITY) in both directions, a Citrus client to an Xray server and an Xray client to a Citrus server, with and without ML-DSA-65. A wrong key is rejected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Behaviour change.&lt;/strong&gt; &lt;code&gt;max-time-difference&lt;/code&gt; is now in milliseconds, like Xray’s &lt;code&gt;maxTimeDiff&lt;/code&gt;. It used to be read as microseconds, so a value copied from an Xray config allowed 1000 times less clock skew. If you tuned the value for the old unit, divide it by 1000.&lt;/p&gt;
&lt;p&gt;Every key is described in the &lt;a href=&quot;https://github.com/getmikan/Citrus/blob/dev/docs/config.yaml&quot;&gt;config reference&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;xhttp-through-cdns-9&quot;&gt;XHTTP through CDNs (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/9&quot;&gt;#9&lt;/a&gt;)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;packet-up&lt;/code&gt; mode the next POST no longer waits for the previous response, as in Xray. Through a CDN each POST used to cost a full client → CDN → origin round trip, so upload was bound by latency. In a live test against Xray 26.10.10 a packet-up request took 0.4 s instead of 5.4 s. Over HTTP/1.1 responses are still awaited.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x-padding-bytes: &quot;0-0&quot;&lt;/code&gt; now means Xray’s default padding (100–1000 bytes) instead of none.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;path&lt;/code&gt; with a query, such as &lt;code&gt;/xh?ed=2048&lt;/code&gt;, is sent as a path and a query, as in Xray, instead of an escaped &lt;code&gt;%3F&lt;/code&gt; inside the path.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;legacy-protocols-removed-7&quot;&gt;Legacy protocols removed (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/7&quot;&gt;#7&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;ShadowsocksR, Hysteria v1, TUIC v4, Shadowsocks stream ciphers (rc4-md5, aes-ctr/cfb, chacha20 and others) and v2ray-plugin are gone. Shadowsocks accepts only &lt;code&gt;none&lt;/code&gt;, AEAD and &lt;code&gt;2022-blake3-*&lt;/code&gt;. VMess stays for now.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In a proxy provider such a node is skipped with a warning, and the rest of the subscription loads.&lt;/li&gt;
&lt;li&gt;In the main config it is an error with a clear message, for example “TUIC v4 is no longer supported, use uuid/password (v5)”.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;rejected-auth-journal-5&quot;&gt;Rejected-auth journal (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/5&quot;&gt;#5&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;component/authevent&lt;/code&gt; package reports failed logins on TrustTunnel, REALITY, AnyTLS, VLESS, Trojan, TUIC v5, Hysteria2 and Sudoku inbounds: protocol, addresses and reason, never credentials. It is the core side of a journal of rejected requests in the panel. Events go through a queue and never slow down the handshake.&lt;/p&gt;
&lt;h2 id=&quot;data-races-in-vision-and-anytls-11&quot;&gt;Data races in Vision and AnyTLS (&lt;a href=&quot;https://github.com/getmikan/Citrus/pull/11&quot;&gt;#11&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;Fixed the data races &lt;code&gt;go test -race&lt;/code&gt; found in the XTLS Vision filter and reader and in the AnyTLS stream. After the first packets, the Vision hot path costs one atomic load.&lt;/p&gt;
</content:encoded></item><item><title>Citrus is live</title><link>https://getmikan.github.io/Citrus/en/news/citrus-is-live/</link><guid isPermaLink="true">https://getmikan.github.io/Citrus/en/news/citrus-is-live/</guid><description>The Mikan network core is now a project of its own, a mihomo fork with its own releases. What is there and what is planned.</description><pubDate>Sun, 11 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Citrus is the network core of &lt;a href=&quot;https://miroshka000.github.io/mikan/&quot;&gt;Mikan&lt;/a&gt;, a fork of &lt;a href=&quot;https://github.com/MetaCubeX/mihomo&quot;&gt;MetaCubeX/mihomo&lt;/a&gt;. The core now lives in its own repository, &lt;a href=&quot;https://github.com/getmikan/Citrus&quot;&gt;getmikan/Citrus&lt;/a&gt;, with the upstream history and authorship kept, and ships its own releases.&lt;/p&gt;
&lt;h2 id=&quot;how-development-works&quot;&gt;How development works&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Two branches: &lt;code&gt;dev&lt;/code&gt; and &lt;code&gt;main&lt;/code&gt;. Every pull request goes to &lt;code&gt;dev&lt;/code&gt;; &lt;code&gt;main&lt;/code&gt; only gets merges from &lt;code&gt;dev&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each branch builds its own prerelease: &lt;code&gt;Prerelease-dev&lt;/code&gt; and &lt;code&gt;Prerelease-main&lt;/code&gt;. Stable versions ship as tagged releases.&lt;/li&gt;
&lt;li&gt;Changes from mihomo come in as separate PRs to &lt;code&gt;dev&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a href=&quot;/Citrus/en/project/contributing/&quot;&gt;Contributing&lt;/a&gt; for details.&lt;/p&gt;
&lt;h2 id=&quot;what-is-planned&quot;&gt;What is planned&lt;/h2&gt;
&lt;p&gt;These are plans, not finished work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Drop legacy protocols&lt;/strong&gt;, starting with VMess.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xray interoperability&lt;/strong&gt;, including post-quantum REALITY: X25519MLKEM768 key exchange and ML-DSA-65 signatures.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;xhttp fixes.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We will post here as each step lands in a release.&lt;/p&gt;
</content:encoded></item></channel></rss>