metadata.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. package constant
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "net/netip"
  7. "strconv"
  8. "github.com/metacubex/mihomo/transport/socks5"
  9. )
  10. // Socks addr type
  11. const (
  12. TCP NetWork = iota
  13. UDP
  14. ALLNet
  15. InvalidNet = 0xff
  16. )
  17. const (
  18. HTTP Type = iota
  19. HTTPS
  20. SOCKS4
  21. SOCKS5
  22. SHADOWSOCKS
  23. VMESS
  24. REDIR
  25. TPROXY
  26. TUNNEL
  27. TUN
  28. TUIC
  29. HYSTERIA2
  30. INNER
  31. )
  32. type NetWork int
  33. func (n NetWork) String() string {
  34. switch n {
  35. case TCP:
  36. return "tcp"
  37. case UDP:
  38. return "udp"
  39. case ALLNet:
  40. return "all"
  41. default:
  42. return "invalid"
  43. }
  44. }
  45. func (n NetWork) MarshalJSON() ([]byte, error) {
  46. return json.Marshal(n.String())
  47. }
  48. type Type int
  49. func (t Type) String() string {
  50. switch t {
  51. case HTTP:
  52. return "HTTP"
  53. case HTTPS:
  54. return "HTTPS"
  55. case SOCKS4:
  56. return "Socks4"
  57. case SOCKS5:
  58. return "Socks5"
  59. case SHADOWSOCKS:
  60. return "ShadowSocks"
  61. case VMESS:
  62. return "Vmess"
  63. case REDIR:
  64. return "Redir"
  65. case TPROXY:
  66. return "TProxy"
  67. case TUNNEL:
  68. return "Tunnel"
  69. case TUN:
  70. return "Tun"
  71. case TUIC:
  72. return "Tuic"
  73. case HYSTERIA2:
  74. return "Hysteria2"
  75. case INNER:
  76. return "Inner"
  77. default:
  78. return "Unknown"
  79. }
  80. }
  81. func ParseType(t string) (*Type, error) {
  82. var res Type
  83. switch t {
  84. case "HTTP":
  85. res = HTTP
  86. case "HTTPS":
  87. res = HTTPS
  88. case "SOCKS4":
  89. res = SOCKS4
  90. case "SOCKS5":
  91. res = SOCKS5
  92. case "SHADOWSOCKS":
  93. res = SHADOWSOCKS
  94. case "VMESS":
  95. res = VMESS
  96. case "REDIR":
  97. res = REDIR
  98. case "TPROXY":
  99. res = TPROXY
  100. case "TUNNEL":
  101. res = TUNNEL
  102. case "TUN":
  103. res = TUN
  104. case "TUIC":
  105. res = TUIC
  106. case "HYSTERIA2":
  107. res = HYSTERIA2
  108. case "INNER":
  109. res = INNER
  110. default:
  111. return nil, fmt.Errorf("unknown type: %s", t)
  112. }
  113. return &res, nil
  114. }
  115. func (t Type) MarshalJSON() ([]byte, error) {
  116. return json.Marshal(t.String())
  117. }
  118. // Metadata is used to store connection address
  119. type Metadata struct {
  120. NetWork NetWork `json:"network"`
  121. Type Type `json:"type"`
  122. SrcIP netip.Addr `json:"sourceIP"`
  123. DstIP netip.Addr `json:"destinationIP"`
  124. DstGeoIP []string `json:"destinationGeoIP"` // can be nil if never queried, empty slice if got no result
  125. DstIPASN string `json:"destinationIPASN"`
  126. SrcPort uint16 `json:"sourcePort,string"` // `,string` is used to compatible with old version json output
  127. DstPort uint16 `json:"destinationPort,string"` // `,string` is used to compatible with old version json output
  128. InIP netip.Addr `json:"inboundIP"`
  129. InPort uint16 `json:"inboundPort,string"` // `,string` is used to compatible with old version json output
  130. InName string `json:"inboundName"`
  131. InUser string `json:"inboundUser"`
  132. Host string `json:"host"`
  133. DNSMode DNSMode `json:"dnsMode"`
  134. Uid uint32 `json:"uid"`
  135. Process string `json:"process"`
  136. ProcessPath string `json:"processPath"`
  137. SpecialProxy string `json:"specialProxy"`
  138. SpecialRules string `json:"specialRules"`
  139. RemoteDst string `json:"remoteDestination"`
  140. DSCP uint8 `json:"dscp"`
  141. RawSrcAddr net.Addr `json:"-"`
  142. RawDstAddr net.Addr `json:"-"`
  143. // Only domain rule
  144. SniffHost string `json:"sniffHost"`
  145. }
  146. func (m *Metadata) RemoteAddress() string {
  147. return net.JoinHostPort(m.String(), strconv.FormatUint(uint64(m.DstPort), 10))
  148. }
  149. func (m *Metadata) SourceAddress() string {
  150. return net.JoinHostPort(m.SrcIP.String(), strconv.FormatUint(uint64(m.SrcPort), 10))
  151. }
  152. func (m *Metadata) SourceAddrPort() netip.AddrPort {
  153. return netip.AddrPortFrom(m.SrcIP.Unmap(), m.SrcPort)
  154. }
  155. func (m *Metadata) SourceDetail() string {
  156. if m.Type == INNER {
  157. return fmt.Sprintf("%s", MihomoName)
  158. }
  159. switch {
  160. case m.Process != "" && m.Uid != 0:
  161. return fmt.Sprintf("%s(%s, uid=%d)", m.SourceAddress(), m.Process, m.Uid)
  162. case m.Uid != 0:
  163. return fmt.Sprintf("%s(uid=%d)", m.SourceAddress(), m.Uid)
  164. case m.Process != "":
  165. return fmt.Sprintf("%s(%s)", m.SourceAddress(), m.Process)
  166. default:
  167. return fmt.Sprintf("%s", m.SourceAddress())
  168. }
  169. }
  170. func (m *Metadata) SourceValid() bool {
  171. return m.SrcPort != 0 && m.SrcIP.IsValid()
  172. }
  173. func (m *Metadata) AddrType() int {
  174. switch true {
  175. case m.Host != "" || !m.DstIP.IsValid():
  176. return socks5.AtypDomainName
  177. case m.DstIP.Is4():
  178. return socks5.AtypIPv4
  179. default:
  180. return socks5.AtypIPv6
  181. }
  182. }
  183. func (m *Metadata) Resolved() bool {
  184. return m.DstIP.IsValid()
  185. }
  186. func (m *Metadata) RuleHost() string {
  187. if len(m.SniffHost) == 0 {
  188. return m.Host
  189. } else {
  190. return m.SniffHost
  191. }
  192. }
  193. // Pure is used to solve unexpected behavior
  194. // when dialing proxy connection in DNSMapping mode.
  195. func (m *Metadata) Pure() *Metadata {
  196. if (m.DNSMode == DNSMapping || m.DNSMode == DNSHosts) && m.DstIP.IsValid() {
  197. copyM := *m
  198. copyM.Host = ""
  199. return &copyM
  200. }
  201. return m
  202. }
  203. func (m *Metadata) AddrPort() netip.AddrPort {
  204. return netip.AddrPortFrom(m.DstIP.Unmap(), m.DstPort)
  205. }
  206. func (m *Metadata) UDPAddr() *net.UDPAddr {
  207. if m.NetWork != UDP || !m.DstIP.IsValid() {
  208. return nil
  209. }
  210. return net.UDPAddrFromAddrPort(m.AddrPort())
  211. }
  212. func (m *Metadata) String() string {
  213. if m.Host != "" {
  214. return m.Host
  215. } else if m.DstIP.IsValid() {
  216. return m.DstIP.String()
  217. } else {
  218. return "<nil>"
  219. }
  220. }
  221. func (m *Metadata) Valid() bool {
  222. return m.Host != "" || m.DstIP.IsValid()
  223. }
  224. func (m *Metadata) SetRemoteAddr(addr net.Addr) error {
  225. if addr == nil {
  226. return nil
  227. }
  228. if rawAddr, ok := addr.(interface{ RawAddr() net.Addr }); ok {
  229. if rawAddr := rawAddr.RawAddr(); rawAddr != nil {
  230. if err := m.SetRemoteAddr(rawAddr); err == nil {
  231. return nil
  232. }
  233. }
  234. }
  235. if addr, ok := addr.(interface{ AddrPort() netip.AddrPort }); ok { // *net.TCPAddr, *net.UDPAddr, M.Socksaddr
  236. if addrPort := addr.AddrPort(); addrPort.Port() != 0 {
  237. m.DstPort = addrPort.Port()
  238. if addrPort.IsValid() { // sing's M.Socksaddr maybe return an invalid AddrPort if it's a DomainName
  239. m.DstIP = addrPort.Addr().Unmap()
  240. return nil
  241. } else {
  242. if addr, ok := addr.(interface{ AddrString() string }); ok { // must be sing's M.Socksaddr
  243. m.Host = addr.AddrString() // actually is M.Socksaddr.Fqdn
  244. return nil
  245. }
  246. }
  247. }
  248. }
  249. return m.SetRemoteAddress(addr.String())
  250. }
  251. func (m *Metadata) SetRemoteAddress(rawAddress string) error {
  252. host, port, err := net.SplitHostPort(rawAddress)
  253. if err != nil {
  254. return err
  255. }
  256. var uint16Port uint16
  257. if port, err := strconv.ParseUint(port, 10, 16); err == nil {
  258. uint16Port = uint16(port)
  259. }
  260. if ip, err := netip.ParseAddr(host); err != nil {
  261. m.Host = host
  262. m.DstIP = netip.Addr{}
  263. } else {
  264. m.Host = ""
  265. m.DstIP = ip.Unmap()
  266. }
  267. m.DstPort = uint16Port
  268. return nil
  269. }