sockopt.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { z } from 'zod';
  2. export const SockoptDomainStrategySchema = z.enum([
  3. 'AsIs',
  4. 'UseIP',
  5. 'UseIPv6v4',
  6. 'UseIPv6',
  7. 'UseIPv4v6',
  8. 'UseIPv4',
  9. 'ForceIP',
  10. 'ForceIPv6v4',
  11. 'ForceIPv6',
  12. 'ForceIPv4v6',
  13. 'ForceIPv4',
  14. ]);
  15. export type SockoptDomainStrategy = z.infer<typeof SockoptDomainStrategySchema>;
  16. export const TcpCongestionSchema = z.enum(['bbr', 'cubic', 'reno']);
  17. export type TcpCongestion = z.infer<typeof TcpCongestionSchema>;
  18. export const TproxyModeSchema = z.enum(['off', 'redirect', 'tproxy']);
  19. export type TproxyMode = z.infer<typeof TproxyModeSchema>;
  20. export const AddressPortStrategySchema = z.enum([
  21. 'none',
  22. 'SrvPortOnly',
  23. 'SrvAddressOnly',
  24. 'SrvPortAndAddress',
  25. 'TxtPortOnly',
  26. 'TxtAddressOnly',
  27. 'TxtPortAndAddress',
  28. ]);
  29. export type AddressPortStrategy = z.infer<typeof AddressPortStrategySchema>;
  30. export const HappyEyeballsSchema = z.object({
  31. tryDelayMs: z.number().int().min(0).default(250),
  32. prioritizeIPv6: z.boolean().default(false),
  33. interleave: z.number().int().min(1).default(1),
  34. maxConcurrentTry: z.number().int().min(0).default(4),
  35. });
  36. export type HappyEyeballs = z.infer<typeof HappyEyeballsSchema>;
  37. export const CustomSockoptSchema = z.object({
  38. system: z.enum(['linux', 'windows', 'darwin']).optional(),
  39. type: z.enum(['int', 'str']),
  40. level: z.string().default('6'),
  41. opt: z.string(),
  42. value: z.union([z.string(), z.number()]),
  43. });
  44. export type CustomSockopt = z.infer<typeof CustomSockoptSchema>;
  45. export const SockoptStreamSettingsSchema = z.object({
  46. acceptProxyProtocol: z.boolean().default(false),
  47. tcpFastOpen: z.union([z.boolean(), z.number().int()]).default(false),
  48. mark: z.number().int().default(0),
  49. tproxy: TproxyModeSchema.default('off'),
  50. tcpMptcp: z.boolean().default(false),
  51. penetrate: z.boolean().default(false),
  52. domainStrategy: SockoptDomainStrategySchema.default('AsIs'),
  53. // 0 = omit on the wire; xray-core skips sockopt fields <= 0 and uses OS defaults.
  54. // Non-zero defaults here previously came from the xray docs *example* (clamp 600,
  55. // maxSeg 1440, userTimeout 10000) and were written into every config when the
  56. // panel sockopt switch was enabled, throttling long-haul links.
  57. tcpMaxSeg: z.number().int().min(0).default(0),
  58. dialerProxy: z.string().default(''),
  59. tcpKeepAliveInterval: z.number().int().min(0).default(0),
  60. tcpKeepAliveIdle: z.number().int().min(0).default(0),
  61. tcpUserTimeout: z.number().int().min(0).default(0),
  62. tcpcongestion: TcpCongestionSchema.default('bbr'),
  63. V6Only: z.boolean().default(false),
  64. tcpWindowClamp: z.number().int().min(0).default(0),
  65. interface: z.string().default(''),
  66. trustedXForwardedFor: z.array(z.string()).default([]),
  67. addressPortStrategy: AddressPortStrategySchema.default('none'),
  68. happyEyeballs: HappyEyeballsSchema.optional(),
  69. customSockopt: z.array(CustomSockoptSchema).default([]),
  70. });
  71. export type SockoptStreamSettings = z.infer<typeof SockoptStreamSettingsSchema>;