fix: stop forcing port 53 on DoH/DoQ DNS server entries (#5950)

Object-form DNS server entries always received port: 53, because
DnsServerObjectInnerSchema defaulted the port unconditionally and the
DnsServerModal wire adapter always wrote it. Per Xray-core, encrypted
schemes must not carry a port field; a non-standard port is embedded in
the URL instead.

Default the port to 53 only for non-encrypted addresses and omit it for
the encrypted DNS schemes Xray dispatches without a port - https,
https+local, h2c, h2c+local and quic+local - both in the Zod schema and
in the modal's valuesToWire adapter. Schemes are matched
case-insensitively to mirror Xray-core's EqualFold comparison. A shared
isEncryptedDnsAddress helper backs both paths.

Fixes #5920

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
This commit is contained in:
Matt Van Horn
2026-07-14 03:55:10 -07:00
committed by GitHub
parent 65b5074b60
commit ae0da4c51f
4 changed files with 55 additions and 4 deletions
+11 -2
View File
@@ -14,9 +14,13 @@ const DnsHostValueSchema = z.union([z.string(), z.array(z.string())]);
export const DnsHostsSchema = z.record(z.string(), DnsHostValueSchema);
export type DnsHosts = z.infer<typeof DnsHostsSchema>;
export function isEncryptedDnsAddress(address: string): boolean {
return /^(https|https\+local|h2c|h2c\+local|quic\+local):\/\//i.test(address);
}
export const DnsServerObjectInnerSchema = z.object({
address: z.string(),
port: PortSchema.default(53),
port: PortSchema.optional(),
domains: z.array(z.string()).optional(),
expectedIPs: z.array(z.string()).optional(),
unexpectedIPs: z.array(z.string()).optional(),
@@ -41,7 +45,12 @@ export const DnsServerObjectSchema = z.preprocess(
return val;
},
DnsServerObjectInnerSchema,
);
).transform((v) => {
if (v.port === undefined && !isEncryptedDnsAddress(v.address)) {
return { ...v, port: 53 };
}
return v;
});
export type DnsServerObject = z.infer<typeof DnsServerObjectSchema>;
export const DnsServerEntrySchema = z.union([z.string(), DnsServerObjectSchema]);