github.com/yaling888/clash@v1.53.0/constant/metadata.go (about) 1 package constant 2 3 import ( 4 "encoding/json" 5 "net" 6 "net/netip" 7 "strconv" 8 "strings" 9 10 "github.com/phuslu/log" 11 12 "github.com/yaling888/clash/transport/socks5" 13 ) 14 15 var MetadataTypeMapping = map[string]Type{ 16 strings.ToLower(HTTP.String()): HTTP, 17 strings.ToLower(HTTPCONNECT.String()): HTTPCONNECT, 18 strings.ToLower(SOCKS4.String()): SOCKS4, 19 strings.ToLower(SOCKS5.String()): SOCKS5, 20 strings.ToLower(REDIR.String()): REDIR, 21 strings.ToLower(TPROXY.String()): TPROXY, 22 strings.ToLower(TUN.String()): TUN, 23 strings.ToLower(MITM.String()): MITM, 24 strings.ToLower(TUNNEL.String()): TUNNEL, 25 } 26 27 // Socks addr type 28 const ( 29 TCP NetWork = iota 30 UDP 31 ALLNet 32 ) 33 34 const ( 35 HTTP Type = iota 36 HTTPCONNECT 37 SOCKS4 38 SOCKS5 39 REDIR 40 TPROXY 41 TUN 42 MITM 43 TUNNEL 44 ) 45 46 type NetWork int 47 48 func (n NetWork) String() string { 49 if n == TCP { 50 return "tcp" 51 } else if n == UDP { 52 return "udp" 53 } 54 return "all" 55 } 56 57 func (n NetWork) MarshalJSON() ([]byte, error) { 58 return json.Marshal(n.String()) 59 } 60 61 type Type int 62 63 func (t Type) String() string { 64 switch t { 65 case HTTP: 66 return "HTTP" 67 case HTTPCONNECT: 68 return "HTTP Connect" 69 case SOCKS4: 70 return "Socks4" 71 case SOCKS5: 72 return "Socks5" 73 case REDIR: 74 return "Redir" 75 case TPROXY: 76 return "TProxy" 77 case TUN: 78 return "TUN" 79 case MITM: 80 return "MITM" 81 case TUNNEL: 82 return "Tunnel" 83 default: 84 return "Unknown" 85 } 86 } 87 88 func (t Type) MarshalJSON() ([]byte, error) { 89 return json.Marshal(t.String()) 90 } 91 92 // Metadata is used to store connection address 93 type Metadata struct { 94 NetWork NetWork `json:"network"` 95 Type Type `json:"type"` 96 SrcIP netip.Addr `json:"sourceIP"` 97 DstIP netip.Addr `json:"destinationIP"` 98 SrcPort Port `json:"sourcePort"` 99 DstPort Port `json:"destinationPort"` 100 Host string `json:"host"` 101 DNSMode DNSMode `json:"dnsMode"` 102 Process string `json:"process"` 103 ProcessPath string `json:"processPath"` 104 UserAgent string `json:"userAgent"` 105 SpecialProxy string `json:"specialProxy"` 106 107 OriginDst netip.AddrPort `json:"-"` 108 } 109 110 func (m *Metadata) RemoteAddress() string { 111 return net.JoinHostPort(m.String(), m.DstPort.String()) 112 } 113 114 func (m *Metadata) SourceAddress() string { 115 return net.JoinHostPort(m.SrcIP.String(), m.SrcPort.String()) 116 } 117 118 func (m *Metadata) AddrType() int { 119 switch true { 120 case m.DstIP.Is4(): 121 return socks5.AtypIPv4 122 case m.DstIP.Is6(): 123 return socks5.AtypIPv6 124 default: 125 return socks5.AtypDomainName 126 } 127 } 128 129 func (m *Metadata) Resolved() bool { 130 return m.DstIP.IsValid() 131 } 132 133 func (m *Metadata) UDPAddr() *net.UDPAddr { 134 if m.NetWork != UDP || !m.DstIP.IsValid() { 135 return nil 136 } 137 return &net.UDPAddr{ 138 IP: m.DstIP.AsSlice(), 139 Port: int(m.DstPort), 140 } 141 } 142 143 func (m *Metadata) String() string { 144 if m.Host != "" { 145 return m.Host 146 } else if m.DstIP.IsValid() { 147 return m.DstIP.String() 148 } else { 149 return "<nil>" 150 } 151 } 152 153 func (m *Metadata) Valid() bool { 154 return m.Host != "" || m.DstIP.IsValid() 155 } 156 157 func (m *Metadata) TypeFromString(s string) { 158 if _type, ok := MetadataTypeMapping[strings.ToLower(s)]; ok { 159 m.Type = _type 160 } else { 161 m.Type = -1 162 } 163 } 164 165 func (m *Metadata) NetworkFromString(s string) { 166 switch strings.ToLower(s) { 167 case "tcp": 168 m.NetWork = TCP 169 case "udp": 170 m.NetWork = UDP 171 default: 172 m.NetWork = ALLNet 173 } 174 } 175 176 func (m *Metadata) MarshalObject(e *log.Entry) { 177 e.Str("lAddr", m.SourceAddress()).Str("rAddr", m.RemoteAddress()) 178 179 if m.Process != "" { 180 e.Str("process", m.Process) 181 } 182 183 if m.UserAgent != "" { 184 e.Str("userAgent", m.UserAgent) 185 } 186 } 187 188 // Port is used to compatible with old version 189 type Port uint16 190 191 func (n Port) MarshalJSON() ([]byte, error) { 192 return json.Marshal(n.String()) 193 } 194 195 func (n Port) String() string { 196 return strconv.FormatUint(uint64(n), 10) 197 } 198 199 type LogAddr struct { 200 M Metadata 201 Src bool 202 HostOnly bool 203 } 204 205 func (l LogAddr) String() string { 206 if l.HostOnly { 207 return l.M.String() 208 } 209 if !l.Src { 210 return l.M.RemoteAddress() 211 } 212 return l.M.SourceAddress() 213 }