github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/utils/socks/structs.go (about) 1 package socks 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "errors" 7 "fmt" 8 "io" 9 "net" 10 "strconv" 11 ) 12 13 type Request struct { 14 ver uint8 15 cmd uint8 16 reserve uint8 17 addressType uint8 18 dstAddr string 19 dstPort string 20 dstHost string 21 bytes []byte 22 rw io.ReadWriter 23 } 24 25 func NewRequest(rw io.ReadWriter, header ...[]byte) (req Request, err interface{}) { 26 var b = make([]byte, 1024) 27 var n int 28 req = Request{rw: rw} 29 if header != nil && len(header) == 1 && len(header[0]) > 1 { 30 b = header[0] 31 n = len(header[0]) 32 } else { 33 n, err = rw.Read(b[:]) 34 if err != nil { 35 err = fmt.Errorf("read req data fail,ERR: %s", err) 36 return 37 } 38 } 39 req.ver = uint8(b[0]) 40 req.cmd = uint8(b[1]) 41 req.reserve = uint8(b[2]) 42 req.addressType = uint8(b[3]) 43 if b[0] != 0x5 { 44 err = fmt.Errorf("sosck version supported") 45 req.TCPReply(REP_REQ_FAIL) 46 return 47 } 48 switch b[3] { 49 case 0x01: //IP V4 50 req.dstHost = net.IPv4(b[4], b[5], b[6], b[7]).String() 51 case 0x03: //域名 52 req.dstHost = string(b[5 : n-2]) //b[4]表示域名的长度 53 case 0x04: //IP V6 54 req.dstHost = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String() 55 } 56 req.dstPort = strconv.Itoa(int(b[n-2])<<8 | int(b[n-1])) 57 req.dstAddr = net.JoinHostPort(req.dstHost, req.dstPort) 58 req.bytes = b[:n] 59 return 60 } 61 func (s *Request) Bytes() []byte { 62 return s.bytes 63 } 64 func (s *Request) Addr() string { 65 return s.dstAddr 66 } 67 func (s *Request) Host() string { 68 return s.dstHost 69 } 70 func (s *Request) Port() string { 71 return s.dstPort 72 } 73 func (s *Request) AType() uint8 { 74 return s.addressType 75 } 76 func (s *Request) CMD() uint8 { 77 return s.cmd 78 } 79 80 func (s *Request) TCPReply(rep uint8) (err error) { 81 _, err = s.rw.Write(s.NewReply(rep, "0.0.0.0:0")) 82 return 83 } 84 func (s *Request) UDPReply(rep uint8, addr string) (err error) { 85 _, err = s.rw.Write(s.NewReply(rep, addr)) 86 return 87 } 88 func (s *Request) NewReply(rep uint8, addr string) []byte { 89 var response bytes.Buffer 90 host, port, _ := net.SplitHostPort(addr) 91 ip := net.ParseIP(host) 92 ipb := ip.To4() 93 atyp := ATYP_IPV4 94 ipv6 := ip.To16() 95 zeroiIPv6 := fmt.Sprintf("%d%d%d%d%d%d%d%d%d%d%d%d", 96 ipv6[0], ipv6[1], ipv6[2], ipv6[3], 97 ipv6[4], ipv6[5], ipv6[6], ipv6[7], 98 ipv6[8], ipv6[9], ipv6[10], ipv6[11], 99 ) 100 if ipb == nil && ipv6 != nil && "0000000000255255" != zeroiIPv6 { 101 atyp = ATYP_IPV6 102 ipb = ip.To16() 103 } 104 porti, _ := strconv.Atoi(port) 105 portb := make([]byte, 2) 106 binary.BigEndian.PutUint16(portb, uint16(porti)) 107 // log.Printf("atyp : %v", atyp) 108 // log.Printf("ip : %v", []byte(ip)) 109 response.WriteByte(VERSION_V5) 110 response.WriteByte(rep) 111 response.WriteByte(RSV) 112 response.WriteByte(atyp) 113 response.Write(ipb) 114 response.Write(portb) 115 return response.Bytes() 116 } 117 118 type MethodsRequest struct { 119 ver uint8 120 methodsCount uint8 121 methods []uint8 122 bytes []byte 123 rw *io.ReadWriter 124 } 125 126 func NewMethodsRequest(r io.ReadWriter, header ...[]byte) (s MethodsRequest, err interface{}) { 127 defer func() { 128 if err == nil { 129 err = recover() 130 } 131 }() 132 s = MethodsRequest{} 133 s.rw = &r 134 var buf = make([]byte, 300) 135 var n int 136 if header != nil && len(header) == 1 && len(header[0]) > 1 { 137 buf = header[0] 138 n = len(header[0]) 139 } else { 140 n, err = r.Read(buf) 141 if err != nil { 142 return 143 } 144 } 145 if buf[0] != 0x05 { 146 err = fmt.Errorf("socks version not supported") 147 return 148 } 149 if n != int(buf[1])+int(2) { 150 err = fmt.Errorf("socks methods data length error") 151 return 152 } 153 s.ver = buf[0] 154 s.methodsCount = buf[1] 155 s.methods = buf[2:n] 156 s.bytes = buf[:n] 157 return 158 } 159 func (s *MethodsRequest) Version() uint8 { 160 return s.ver 161 } 162 func (s *MethodsRequest) MethodsCount() uint8 { 163 return s.methodsCount 164 } 165 func (s *MethodsRequest) Methods() []uint8 { 166 return s.methods 167 } 168 func (s *MethodsRequest) Select(method uint8) bool { 169 for _, m := range s.methods { 170 if m == method { 171 return true 172 } 173 } 174 return false 175 } 176 func (s *MethodsRequest) Reply(method uint8) (err error) { 177 _, err = (*s.rw).Write([]byte{byte(VERSION_V5), byte(method)}) 178 return 179 } 180 func (s *MethodsRequest) Bytes() []byte { 181 return s.bytes 182 } 183 184 func ParseUDPPacket(b []byte) (p UDPPacket, err error) { 185 p = UDPPacket{} 186 p.frag = uint8(b[2]) 187 p.bytes = b 188 if p.frag != 0 { 189 err = fmt.Errorf("FRAG only support for 0 , %v ,%v", p.frag, b[:4]) 190 return 191 } 192 portIndex := 0 193 p.atype = b[3] 194 switch p.atype { 195 case ATYP_IPV4: //IP V4 196 p.dstHost = net.IPv4(b[4], b[5], b[6], b[7]).String() 197 portIndex = 8 198 case ATYP_DOMAIN: //域名 199 domainLen := uint8(b[4]) 200 p.dstHost = string(b[5 : 5+domainLen]) //b[4]表示域名的长度 201 portIndex = int(5 + domainLen) 202 case ATYP_IPV6: //IP V6 203 p.dstHost = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String() 204 portIndex = 20 205 } 206 p.dstPort = strconv.Itoa(int(b[portIndex])<<8 | int(b[portIndex+1])) 207 p.data = b[portIndex+2:] 208 p.header = b[:portIndex+2] 209 return 210 } 211 212 type UDPPacket struct { 213 rsv uint16 214 frag uint8 215 atype uint8 216 dstHost string 217 dstPort string 218 data []byte 219 header []byte 220 bytes []byte 221 } 222 223 func (s *UDPPacket) Header() []byte { 224 return s.header 225 } 226 func (s *UDPPacket) NewReply(data []byte) []byte { 227 var buf bytes.Buffer 228 buf.Write(s.header) 229 buf.Write(data) 230 return buf.Bytes() 231 } 232 func (s *UDPPacket) Host() string { 233 return s.dstHost 234 } 235 236 func (s *UDPPacket) Port() string { 237 return s.dstPort 238 } 239 func (s *UDPPacket) Data() []byte { 240 return s.data 241 } 242 243 type PacketUDP struct { 244 rsv uint16 245 frag uint8 246 atype uint8 247 dstHost string 248 dstPort string 249 data []byte 250 } 251 252 func NewPacketUDP() (p PacketUDP) { 253 return PacketUDP{} 254 } 255 func (p *PacketUDP) Build(destAddr string, data []byte) (err error) { 256 host, port, err := net.SplitHostPort(destAddr) 257 if err != nil { 258 return 259 } 260 p.rsv = 0 261 p.frag = 0 262 p.dstHost = host 263 p.dstPort = port 264 p.atype = ATYP_IPV4 265 if ip := net.ParseIP(host); ip != nil { 266 if ip4 := ip.To4(); ip4 != nil { 267 p.atype = ATYP_IPV4 268 ip = ip4 269 } else { 270 p.atype = ATYP_IPV6 271 } 272 } else { 273 if len(host) > 255 { 274 err = errors.New("proxy: destination host name too long: " + host) 275 return 276 } 277 p.atype = ATYP_DOMAIN 278 } 279 p.data = data 280 281 return 282 } 283 func (p *PacketUDP) Parse(b []byte) (err error) { 284 if len(b) < 9 { 285 return fmt.Errorf("too short packet") 286 } 287 p.frag = uint8(b[2]) 288 if p.frag != 0 { 289 err = fmt.Errorf("FRAG only support for 0 , %v ,%v", p.frag, b[:4]) 290 return 291 } 292 portIndex := 0 293 p.atype = b[3] 294 switch p.atype { 295 case ATYP_IPV4: //IP V4 296 if len(b) < 11 { 297 return fmt.Errorf("too short packet") 298 } 299 p.dstHost = net.IPv4(b[4], b[5], b[6], b[7]).String() 300 portIndex = 8 301 case ATYP_DOMAIN: //域名 302 domainLen := uint8(b[4]) 303 if len(b) < int(domainLen)+7 { 304 return fmt.Errorf("too short packet") 305 } 306 p.dstHost = string(b[5 : 5+domainLen]) //b[4]表示域名的长度 307 portIndex = int(5 + domainLen) 308 case ATYP_IPV6: //IP V6 309 if len(b) < 22 { 310 return fmt.Errorf("too short packet") 311 } 312 p.dstHost = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String() 313 portIndex = 20 314 } 315 p.dstPort = strconv.Itoa(int(b[portIndex])<<8 | int(b[portIndex+1])) 316 p.data = b[portIndex+2:] 317 return 318 } 319 func (p *PacketUDP) Header() []byte { 320 header := new(bytes.Buffer) 321 header.Write([]byte{0x00, 0x00, p.frag, p.atype}) 322 if p.atype == ATYP_IPV4 { 323 ip := net.ParseIP(p.dstHost) 324 header.Write(ip.To4()) 325 } else if p.atype == ATYP_IPV6 { 326 ip := net.ParseIP(p.dstHost) 327 header.Write(ip.To16()) 328 } else if p.atype == ATYP_DOMAIN { 329 hBytes := []byte(p.dstHost) 330 header.WriteByte(byte(len(hBytes))) 331 header.Write(hBytes) 332 } 333 port, _ := strconv.ParseUint(p.dstPort, 10, 64) 334 portBytes := new(bytes.Buffer) 335 binary.Write(portBytes, binary.BigEndian, port) 336 header.Write(portBytes.Bytes()[portBytes.Len()-2:]) 337 return header.Bytes() 338 } 339 func (p *PacketUDP) Bytes() []byte { 340 packBytes := new(bytes.Buffer) 341 packBytes.Write(p.Header()) 342 packBytes.Write(p.data) 343 return packBytes.Bytes() 344 } 345 func (p *PacketUDP) Host() string { 346 return p.dstHost 347 } 348 func (p *PacketUDP) Addr() string { 349 return net.JoinHostPort(p.dstHost, p.dstPort) 350 } 351 func (p *PacketUDP) Port() string { 352 return p.dstPort 353 } 354 func (p *PacketUDP) Data() []byte { 355 return p.data 356 }