mKCP and xdns: a kcp host
Prizrak-Core carries VLESS over mKCP 👻 the way an Xray-core kcp inbound expects it since finalmask, with UDP masks such as xdns under mKCP. A typical use is a DNS tunnel: mKCP packets travel as DNS queries for the server’s zone through public resolvers and get through where everything except DNS is blocked.
The mapper
Section titled “The mapper”The mapper builds the whole proxy from the host’s own settings: the network, mkcp-opts and the client mask from the host’s Final Mask field.
{ "xrayJson": [], "mihomo": [ { "op": "set", "to": "network", "value": "mkcp" }, { "op": "copy", "from": "$host.transportOptions.clientMtu", "to": "mkcp-opts.mtu" }, { "op": "copy", "from": "$host.transportOptions.clientTti", "to": "mkcp-opts.tti" }, { "op": "copy", "from": "$host.transportOptions.congestion", "to": "mkcp-opts.congestion" }, { "op": "copy", "from": "$host.streamOverrides.finalMask", "to": "finalmask" }, { "op": "unset", "to": "client-fingerprint" } ], "base64": []}- The four
copyoperations are required. Without the mask the client talks to the server directly and the tunnel does not work. set networkandunset client-fingerprintare for tidiness: Prizrak-Core also acceptsnetwork: kcpand ignoresclient-fingerprinton a proxy without TLS.- Final Mask of the host holds the client mask in Xray’s form; Prizrak-Core reads it as it is. An example with the compact spelling of the first xdns:
{"udp":[{"type":"xdns","settings":{"resolvers":["t.example.com:aaaa+udp://77.88.8.8:53","t.example.com:aaaa+udp://8.8.8.8:53"]}}]}The server’s kcp inbound must have the server side of the same finalmask (xdns with your zone).
What the client gets
Section titled “What the client gets”With the compact spelling of the first xdns (Xray servers v26.1.31–v26.9.9):
proxies: - name: 🇷🇺 DNS tunnel type: vless server: 77.88.8.8 port: 53 uuid: <uuid> udp: true packet-encoding: xudp network: mkcp mkcp-opts: mtu: 77 tti: 100 congestion: false finalmask: udp: - type: xdns settings: resolvers: - "t.example.com:aaaa+udp://77.88.8.8:53" - "t.example.com:aaaa+udp://8.8.8.8:53"With the full spelling (servers newer than v26.9.9), here with VLESS Encryption on the same host; the generator adds encryption by itself:
proxies: - name: 🇦🇶 Backup (text only) type: vless server: <server IP> port: 53 uuid: <uuid> encryption: mlkem768x25519plus.native.0rtt.<key> udp: true packet-encoding: xudp network: mkcp mkcp-opts: mtu: 77 tti: 100 congestion: false finalmask: udp: - type: xdns settings: domains: - names: ["<xdns zone>"] types: [28] # AAAA edns0: 1232 resolvers: - addrs: - udp://77.88.8.8:53 - udp://77.88.8.1:53 # ... further resolversBoth forms were checked with Prizrak-Core v1.19.33-r10: in the Xray JSON form, as a vless://…?type=kcp&mtu=77&tti=100&fm=… link and as the YAML the mapper builds. Pages load in about a second; the speed is tens of KB/s, enough for messengers in text mode. While data flows, the core holds UDP sockets to the resolvers only, nothing goes to the server directly.