github.com/chwjbn/xclash@v0.2.0/constant/metadata.go (about) 1 package constant 2 3 import ( 4 "encoding/json" 5 "net" 6 "strconv" 7 ) 8 9 // Socks addr type 10 const ( 11 AtypIPv4 = 1 12 AtypDomainName = 3 13 AtypIPv6 = 4 14 15 TCP NetWork = iota 16 UDP 17 18 HTTP Type = iota 19 HTTPCONNECT 20 SOCKS4 21 SOCKS5 22 REDIR 23 TPROXY 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 default: 56 return "Unknown" 57 } 58 } 59 60 func (t Type) MarshalJSON() ([]byte, error) { 61 return json.Marshal(t.String()) 62 } 63 64 // Metadata is used to store connection address 65 type Metadata struct { 66 NetWork NetWork `json:"network"` 67 Type Type `json:"type"` 68 SrcIP net.IP `json:"sourceIP"` 69 DstIP net.IP `json:"destinationIP"` 70 SrcPort string `json:"sourcePort"` 71 DstPort string `json:"destinationPort"` 72 AddrType int `json:"-"` 73 Host string `json:"host"` 74 DNSMode DNSMode `json:"dnsMode"` 75 } 76 77 func (m *Metadata) RemoteAddress() string { 78 return net.JoinHostPort(m.String(), m.DstPort) 79 } 80 81 func (m *Metadata) SourceAddress() string { 82 return net.JoinHostPort(m.SrcIP.String(), m.SrcPort) 83 } 84 85 func (m *Metadata) Resolved() bool { 86 return m.DstIP != nil 87 } 88 89 // Pure is used to solve unexpected behavior 90 // when dialing proxy connection in DNSMapping mode. 91 func (m *Metadata) Pure() *Metadata { 92 if m.DNSMode == DNSMapping && m.DstIP != nil { 93 copy := *m 94 copy.Host = "" 95 if copy.DstIP.To4() != nil { 96 copy.AddrType = AtypIPv4 97 } else { 98 copy.AddrType = AtypIPv6 99 } 100 return © 101 } 102 103 return m 104 } 105 106 func (m *Metadata) UDPAddr() *net.UDPAddr { 107 if m.NetWork != UDP || m.DstIP == nil { 108 return nil 109 } 110 port, _ := strconv.ParseUint(m.DstPort, 10, 16) 111 return &net.UDPAddr{ 112 IP: m.DstIP, 113 Port: int(port), 114 } 115 } 116 117 func (m *Metadata) String() string { 118 if m.Host != "" { 119 return m.Host 120 } else if m.DstIP != nil { 121 return m.DstIP.String() 122 } else { 123 return "<nil>" 124 } 125 } 126 127 func (m *Metadata) Valid() bool { 128 return m.Host != "" || m.DstIP != nil 129 }