types.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package tuic
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "slices"
  7. "strconv"
  8. "strings"
  9. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  10. )
  11. type TuicServerSettings struct {
  12. Certificate string `json:"certificate"`
  13. PrivateKey string `json:"private_key"`
  14. CongestionControl string `json:"congestion_control"`
  15. ALPN []string `json:"alpn"`
  16. UDPRelayMode string `json:"udp_relay_mode"`
  17. ZeroRTTHandshake bool `json:"zero_rtt_handshake"`
  18. LogLevel string `json:"log_level"`
  19. MaxIdleTime int `json:"max_idle_time"`
  20. AuthenticationTimeout int `json:"authentication_timeout"`
  21. MaxUdpRelayPacketSize int `json:"max_udp_relay_packet_size"`
  22. SNI string `json:"sni,omitempty"`
  23. }
  24. type TuicClientSettings struct {
  25. UUID string `json:"uuid"`
  26. Password string `json:"password"`
  27. Email string `json:"email"`
  28. }
  29. type Instance struct {
  30. Id int
  31. Tag string
  32. Listen string
  33. Port int
  34. Certificate string
  35. PrivateKey string
  36. CongestionControl string
  37. ALPN []string
  38. UDPRelayMode string
  39. ZeroRTTHandshake bool
  40. LogLevel string
  41. MaxIdleTime int
  42. AuthenticationTimeout int
  43. MaxUdpRelayPacketSize int
  44. SNI string
  45. Clients []TuicClientSettings
  46. }
  47. func (inst Instance) BindTo() string {
  48. listen := inst.Listen
  49. if listen == "" {
  50. listen = "0.0.0.0"
  51. }
  52. return net.JoinHostPort(listen, strconv.Itoa(inst.Port))
  53. }
  54. func (inst Instance) StructuralFingerprint() string {
  55. parts := []string{
  56. inst.BindTo(),
  57. inst.Certificate,
  58. inst.PrivateKey,
  59. inst.CongestionControl,
  60. strings.Join(inst.ALPN, ","),
  61. inst.UDPRelayMode,
  62. strconv.FormatBool(inst.ZeroRTTHandshake),
  63. inst.LogLevel,
  64. strconv.Itoa(inst.MaxIdleTime),
  65. strconv.Itoa(inst.AuthenticationTimeout),
  66. strconv.Itoa(inst.MaxUdpRelayPacketSize),
  67. inst.SNI,
  68. }
  69. return strings.Join(parts, "|")
  70. }
  71. func (inst Instance) UsersFingerprint() string {
  72. pairs := make([]string, 0, len(inst.Clients))
  73. for _, c := range inst.Clients {
  74. pairs = append(pairs, fmt.Sprintf("%s=%s:%s", c.Email, c.UUID, c.Password))
  75. }
  76. slices.Sort(pairs)
  77. return strings.Join(pairs, "|")
  78. }
  79. func (inst Instance) FullFingerprint() string {
  80. return inst.StructuralFingerprint() + "#" + inst.UsersFingerprint()
  81. }
  82. func InstanceFromInbound(ib *model.Inbound) (Instance, bool) {
  83. if ib == nil || ib.Protocol != model.TUIC {
  84. return Instance{}, false
  85. }
  86. var parsed struct {
  87. Certificate string `json:"certificate"`
  88. PrivateKey string `json:"private_key"`
  89. CongestionControl string `json:"congestion_control"`
  90. ALPN []string `json:"alpn"`
  91. UDPRelayMode string `json:"udp_relay_mode"`
  92. ZeroRTTHandshake *bool `json:"zero_rtt_handshake"`
  93. LogLevel string `json:"log_level"`
  94. MaxIdleTime int `json:"max_idle_time"`
  95. AuthenticationTimeout int `json:"authentication_timeout"`
  96. MaxUdpRelayPacketSize int `json:"max_udp_relay_packet_size"`
  97. SNI string `json:"sni"`
  98. Server *struct {
  99. Certificate string `json:"certificate"`
  100. PrivateKey string `json:"private_key"`
  101. CongestionControl string `json:"congestion_control"`
  102. ALPN []string `json:"alpn"`
  103. UDPRelayMode string `json:"udp_relay_mode"`
  104. ZeroRTTHandshake *bool `json:"zero_rtt_handshake"`
  105. LogLevel string `json:"log_level"`
  106. MaxIdleTime int `json:"max_idle_time"`
  107. AuthenticationTimeout int `json:"authentication_timeout"`
  108. MaxUdpRelayPacketSize int `json:"max_udp_relay_packet_size"`
  109. SNI string `json:"sni"`
  110. } `json:"server"`
  111. Clients []struct {
  112. UUID string `json:"uuid"`
  113. ID string `json:"id"`
  114. Password string `json:"password"`
  115. Email string `json:"email"`
  116. Enable *bool `json:"enable"`
  117. TotalGB int64 `json:"totalGB"`
  118. ExpiryTime int64 `json:"expiryTime"`
  119. } `json:"clients"`
  120. }
  121. if ib.Settings != "" {
  122. if err := json.Unmarshal([]byte(ib.Settings), &parsed); err != nil {
  123. return Instance{}, false
  124. }
  125. }
  126. cert := parsed.Certificate
  127. key := parsed.PrivateKey
  128. cc := parsed.CongestionControl
  129. alpn := parsed.ALPN
  130. udpRelayMode := parsed.UDPRelayMode
  131. zeroRtt := true
  132. if parsed.ZeroRTTHandshake != nil {
  133. zeroRtt = *parsed.ZeroRTTHandshake
  134. }
  135. logLevel := parsed.LogLevel
  136. maxIdle := parsed.MaxIdleTime
  137. authTimeout := parsed.AuthenticationTimeout
  138. maxPacketSize := parsed.MaxUdpRelayPacketSize
  139. sni := parsed.SNI
  140. if parsed.Server != nil {
  141. if parsed.Server.Certificate != "" {
  142. cert = parsed.Server.Certificate
  143. }
  144. if parsed.Server.PrivateKey != "" {
  145. key = parsed.Server.PrivateKey
  146. }
  147. if parsed.Server.CongestionControl != "" {
  148. cc = parsed.Server.CongestionControl
  149. }
  150. if len(parsed.Server.ALPN) > 0 {
  151. alpn = parsed.Server.ALPN
  152. }
  153. if parsed.Server.UDPRelayMode != "" {
  154. udpRelayMode = parsed.Server.UDPRelayMode
  155. }
  156. if parsed.Server.ZeroRTTHandshake != nil {
  157. zeroRtt = *parsed.Server.ZeroRTTHandshake
  158. }
  159. if parsed.Server.LogLevel != "" {
  160. logLevel = parsed.Server.LogLevel
  161. }
  162. if parsed.Server.MaxIdleTime > 0 {
  163. maxIdle = parsed.Server.MaxIdleTime
  164. }
  165. if parsed.Server.AuthenticationTimeout > 0 {
  166. authTimeout = parsed.Server.AuthenticationTimeout
  167. }
  168. if parsed.Server.MaxUdpRelayPacketSize > 0 {
  169. maxPacketSize = parsed.Server.MaxUdpRelayPacketSize
  170. }
  171. if parsed.Server.SNI != "" {
  172. sni = parsed.Server.SNI
  173. }
  174. }
  175. if cc == "" {
  176. cc = "bbr"
  177. }
  178. if len(alpn) == 0 {
  179. alpn = []string{"h3", "spdy/3.1"}
  180. }
  181. if udpRelayMode == "" {
  182. udpRelayMode = "native"
  183. }
  184. if logLevel == "" {
  185. logLevel = "info"
  186. }
  187. if maxIdle <= 0 {
  188. maxIdle = 15
  189. }
  190. if authTimeout <= 0 {
  191. authTimeout = 3
  192. }
  193. if maxPacketSize <= 0 {
  194. maxPacketSize = 1500
  195. }
  196. clients := make([]TuicClientSettings, 0, len(parsed.Clients))
  197. for _, c := range parsed.Clients {
  198. if c.Enable != nil && !*c.Enable {
  199. continue
  200. }
  201. uuidVal := strings.ToLower(strings.TrimSpace(c.UUID))
  202. if uuidVal == "" {
  203. uuidVal = strings.ToLower(strings.TrimSpace(c.ID))
  204. }
  205. if uuidVal == "" || c.Password == "" {
  206. continue
  207. }
  208. clients = append(clients, TuicClientSettings{
  209. UUID: uuidVal,
  210. Password: c.Password,
  211. Email: c.Email,
  212. })
  213. }
  214. return Instance{
  215. Id: ib.Id,
  216. Tag: ib.Tag,
  217. Listen: ib.Listen,
  218. Port: ib.Port,
  219. Certificate: cert,
  220. PrivateKey: key,
  221. CongestionControl: cc,
  222. ALPN: alpn,
  223. UDPRelayMode: udpRelayMode,
  224. ZeroRTTHandshake: zeroRtt,
  225. LogLevel: logLevel,
  226. MaxIdleTime: maxIdle,
  227. AuthenticationTimeout: authTimeout,
  228. MaxUdpRelayPacketSize: maxPacketSize,
  229. SNI: sni,
  230. Clients: clients,
  231. }, true
  232. }