github.com/xxf098/lite-proxy@v0.15.1-0.20230422081941-12c69f323218/tunnel/metadata.go (about) 1 package tunnel 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 "log" 8 "net" 9 "strconv" 10 11 "github.com/xxf098/lite-proxy/common" 12 ) 13 14 type AddressType byte 15 16 const ( 17 IPv4 AddressType = 1 18 DomainName AddressType = 3 19 IPv6 AddressType = 4 20 ) 21 22 type Address struct { 23 DomainName string 24 Port int 25 NetworkType string 26 net.IP 27 AddressType 28 } 29 30 func (a *Address) String() string { 31 switch a.AddressType { 32 case IPv4: 33 return fmt.Sprintf("%s:%d", a.IP.String(), a.Port) 34 case IPv6: 35 return fmt.Sprintf("[%s]:%d", a.IP.String(), a.Port) 36 case DomainName: 37 return fmt.Sprintf("%s:%d", a.DomainName, a.Port) 38 default: 39 return "INVALID_ADDRESS_TYPE" 40 } 41 } 42 43 func (a *Address) Network() string { 44 return a.NetworkType 45 } 46 47 func (a *Address) ResolveIP() (net.IP, error) { 48 if a.AddressType == IPv4 || a.AddressType == IPv6 { 49 return a.IP, nil 50 } 51 if a.IP != nil { 52 return a.IP, nil 53 } 54 addr, err := net.ResolveIPAddr("ip", a.DomainName) 55 if err != nil { 56 return nil, err 57 } 58 a.IP = addr.IP 59 return addr.IP, nil 60 } 61 62 func (a *Address) ReadFrom(r io.Reader) error { 63 byteBuf := [1]byte{} 64 _, err := io.ReadFull(r, byteBuf[:]) 65 if err != nil { 66 return common.NewError("unable to read ATYP").Base(err) 67 } 68 a.AddressType = AddressType(byteBuf[0]) 69 switch a.AddressType { 70 case IPv4: 71 var buf [6]byte 72 _, err := io.ReadFull(r, buf[:]) 73 if err != nil { 74 return common.NewError("failed to read IPv4").Base(err) 75 } 76 a.IP = buf[0:4] 77 a.Port = int(binary.BigEndian.Uint16(buf[4:6])) 78 case IPv6: 79 var buf [18]byte 80 _, err := io.ReadFull(r, buf[:]) 81 if err != nil { 82 return common.NewError("failed to read IPv6").Base(err) 83 } 84 a.IP = buf[0:16] 85 a.Port = int(binary.BigEndian.Uint16(buf[16:18])) 86 case DomainName: 87 _, err := io.ReadFull(r, byteBuf[:]) 88 length := byteBuf[0] 89 if err != nil { 90 return common.NewError("failed to read domain name length") 91 } 92 buf := make([]byte, length+2) 93 _, err = io.ReadFull(r, buf) 94 if err != nil { 95 return common.NewError("failed to read domain name") 96 } 97 //the fucking browser uses IP as a domain name sometimes 98 host := buf[0:length] 99 if ip := net.ParseIP(string(host)); ip != nil { 100 a.IP = ip 101 if ip.To4() != nil { 102 a.AddressType = IPv4 103 } else { 104 a.AddressType = IPv6 105 } 106 } else { 107 a.DomainName = string(host) 108 } 109 a.Port = int(binary.BigEndian.Uint16(buf[length : length+2])) 110 default: 111 return common.NewError("invalid ATYP " + strconv.FormatInt(int64(a.AddressType), 10)) 112 } 113 return nil 114 } 115 116 func (a *Address) WriteTo(w io.Writer) error { 117 _, err := w.Write([]byte{byte(a.AddressType)}) 118 switch a.AddressType { 119 case DomainName: 120 w.Write([]byte{byte(len(a.DomainName))}) 121 _, err = w.Write([]byte(a.DomainName)) 122 case IPv4: 123 _, err = w.Write(a.IP.To4()) 124 case IPv6: 125 _, err = w.Write(a.IP.To16()) 126 default: 127 return common.NewError("invalid ATYP " + strconv.FormatInt(int64(a.AddressType), 10)) 128 } 129 if err != nil { 130 return err 131 } 132 port := [2]byte{} 133 binary.BigEndian.PutUint16(port[:], uint16(a.Port)) 134 _, err = w.Write(port[:]) 135 return err 136 } 137 138 func NewAddressFromAddr(network string, addr string) (*Address, error) { 139 host, portStr, err := net.SplitHostPort(addr) 140 if err != nil { 141 return nil, err 142 } 143 port, err := strconv.ParseInt(portStr, 10, 32) 144 if err != nil { 145 log.Fatalln(err) 146 } 147 return NewAddressFromHostPort(network, host, int(port)), nil 148 } 149 150 func NewAddressFromHostPort(network string, host string, port int) *Address { 151 if ip := net.ParseIP(host); ip != nil { 152 if ip.To4() != nil { 153 return &Address{ 154 IP: ip, 155 Port: int(port), 156 AddressType: IPv4, 157 NetworkType: network, 158 } 159 } 160 return &Address{ 161 IP: ip, 162 Port: int(port), 163 AddressType: IPv6, 164 NetworkType: network, 165 } 166 } 167 return &Address{ 168 DomainName: host, 169 Port: int(port), 170 AddressType: DomainName, 171 NetworkType: network, 172 } 173 } 174 175 type Command byte 176 177 type Metadata struct { 178 Command 179 *Address 180 }