github.com/igoogolx/clash@v1.19.8/constant/metadata.go (about) 1 package constant 2 3 import ( 4 "encoding/json" 5 "net" 6 "net/netip" 7 "strconv" 8 9 "github.com/igoogolx/clash/transport/socks5" 10 ) 11 12 // Socks addr type 13 const ( 14 TCP NetWork = iota 15 UDP 16 17 HTTP Type = iota 18 HTTPCONNECT 19 SOCKS4 20 SOCKS5 21 REDIR 22 TPROXY 23 TUNNEL 24 ) 25 26 type NetWork int 27 28 func (n NetWork) String() string { 29 if n == TCP { 30 return "tcp" 31 } 32 return "udp" 33 } 34 35 func (n NetWork) MarshalJSON() ([]byte, error) { 36 return json.Marshal(n.String()) 37 } 38 39 type Type int 40 41 func (t Type) String() string { 42 switch t { 43 case HTTP: 44 return "HTTP" 45 case HTTPCONNECT: 46 return "HTTP Connect" 47 case SOCKS4: 48 return "Socks4" 49 case SOCKS5: 50 return "Socks5" 51 case REDIR: 52 return "Redir" 53 case TPROXY: 54 return "TProxy" 55 case TUNNEL: 56 return "Tunnel" 57 default: 58 return "Unknown" 59 } 60 } 61 62 func (t Type) MarshalJSON() ([]byte, error) { 63 return json.Marshal(t.String()) 64 } 65 66 // Metadata is used to store connection address 67 type Metadata struct { 68 NetWork NetWork `json:"network"` 69 Type Type `json:"type"` 70 SrcIP net.IP `json:"sourceIP"` 71 DstIP net.IP `json:"destinationIP"` 72 SrcPort Port `json:"sourcePort"` 73 DstPort Port `json:"destinationPort"` 74 Host string `json:"host"` 75 DNSMode DNSMode `json:"dnsMode"` 76 ProcessPath string `json:"processPath"` 77 SpecialProxy string `json:"specialProxy"` 78 79 OriginDst netip.AddrPort `json:"-"` 80 } 81 82 func (m *Metadata) RemoteAddress() string { 83 return net.JoinHostPort(m.String(), m.DstPort.String()) 84 } 85 86 func (m *Metadata) SourceAddress() string { 87 return net.JoinHostPort(m.SrcIP.String(), m.SrcPort.String()) 88 } 89 90 func (m *Metadata) AddrType() int { 91 switch true { 92 case m.Host != "" || m.DstIP == nil: 93 return socks5.AtypDomainName 94 case m.DstIP.To4() != nil: 95 return socks5.AtypIPv4 96 default: 97 return socks5.AtypIPv6 98 } 99 } 100 101 func (m *Metadata) Resolved() bool { 102 return m.DstIP != nil 103 } 104 105 // Pure is used to solve unexpected behavior 106 // when dialing proxy connection in DNSMapping mode. 107 func (m *Metadata) Pure() *Metadata { 108 if m.DNSMode == DNSMapping && m.DstIP != nil { 109 copy := *m 110 copy.Host = "" 111 return © 112 } 113 114 return m 115 } 116 117 func (m *Metadata) UDPAddr() *net.UDPAddr { 118 if m.NetWork != UDP || m.DstIP == nil { 119 return nil 120 } 121 return &net.UDPAddr{ 122 IP: m.DstIP, 123 Port: int(m.DstPort), 124 } 125 } 126 127 func (m *Metadata) String() string { 128 if m.Host != "" { 129 return m.Host 130 } else if m.DstIP != nil { 131 return m.DstIP.String() 132 } else { 133 return "<nil>" 134 } 135 } 136 137 func (m *Metadata) Valid() bool { 138 return m.Host != "" || m.DstIP != nil 139 } 140 141 // Port is used to compatible with old version 142 type Port uint16 143 144 func (n Port) MarshalJSON() ([]byte, error) { 145 return json.Marshal(n.String()) 146 } 147 148 func (n Port) String() string { 149 return strconv.FormatUint(uint64(n), 10) 150 }