func getHeader(c io.Reader) (*header, error) { // raw := make([]byte, 260) raw := leakyBuf.Get() defer leakyBuf.Put(raw) header := new(header) io.ReadFull(c, raw[:5]) // !!MUST record errors, and return first error after parse header. var errs []error // get version pos := 0 if header.Ver = raw[pos]; header.Ver != version { errs = append(errs, fmt.Errorf("error mika version %d", header.Ver)) } pos++ header.Cmd = raw[pos] switch header.Cmd { case dataForward: default: errs = append(errs, fmt.Errorf("error mika cmd %d", header.Cmd)) header.Cmd = dataForward } pos++ // header.Reverse = raw[pos : pos+2] pos += 2 var err error header.Protocol = raw[pos] switch header.Protocol { case tcpForward, httpForward: header.ProtocolRelated, header.Addr, err = utils.GetAddress(c) if err != nil { errs = append(errs, err) } // case httpForward: // header.ProtocolRelated = nil default: len := rand.Int() % 4096 io.ReadFull(c, raw[:len]) if err != nil { errs = append(errs, fmt.Errorf("error mika cmd %d", header.Cmd)) } } io.ReadFull(c, raw[:18]) header.ChunkID = binary.BigEndian.Uint64(raw[:8]) header.Hmac = raw[8:18] if len(errs) > 0 { return nil, errs[0] } return header, header.Check() }
func (s *UDPRelay) parseRequest() (rawAddr []byte, addr string, err error) { frag, err := s.getFrag() if err != nil { return } // An implementation that does not support fragmentation // MUST drop any datagram whose FRAG field is other than X’00’. if frag != 0x00 { return nil, "", fmt.Errorf("frag %d is not 0, drop it", frag) } return utils.GetAddress(s.conn) }
// parseRequest parses socks5 client request. func (s *TCPRelay) parseRequest() (cmd byte, rawAddr []byte, addr string, err error) { cmd, err = s.getCmd() if err != nil { return } // check cmd type switch cmd { case CONNECT: case BIND: case UDP_ASSOCIATE: default: err = fmt.Errorf("unknow cmd type") return } if rawAddr, addr, err = utils.GetAddress(s.conn); err != nil { return } return }