func (s *TCPRelay) parseRequest() (cmd byte, rawAddr []byte, addr string, err error) {
	cmd, err = s.getCmd()
	if err != nil {
		return
	}
	switch cmd {
	case cmdConnect:
	case cmdBind:
	case cmdUDPAssociate:
	default:
		err = fmt.Errorf("unknow cmd type")
		return
	}
	if rawAddr, addr, err = utils.GetAddress(s.conn); err != nil {
		return
	}
	return
}
parseRequest parses socks5 client request.
package socks5
import (
	"fmt"
	"io"
	"github.com/sakeven/mika/protocols"
	"github.com/sakeven/mika/protocols/proxy"
	"github.com/sakeven/mika/utils"
)
const (
	socksv5 = 0x05
)
type TCPRelay struct {
	conn   protocols.Protocol
	closed bool
	dialer proxy.Dialer
}
func NewTCPRelay(conn protocols.Protocol, dialer proxy.Dialer) *TCPRelay {
	return &TCPRelay{
		conn:   conn,
		dialer: dialer,
	}
}
func (s *TCPRelay) Serve() (err error) {
	defer func() {
		if !s.closed {
			s.conn.Close()
		}
	}()
	s.handShake()
	cmd, rawAddr, addr, err := s.parseRequest()
	if err != nil {
		utils.Errorf("Parse request error %v\n", err)
		return
	}
	utils.Infof("Proxy connection to %s\n", string(addr))
	s.reply()
	switch cmd {
	case cmdConnect:
		err = s.connect(rawAddr)
	case cmdUDPAssociate:
		s.udpAssociate()
	case cmdBind:
	default:
		err = fmt.Errorf("unknow cmd type")
	}
	return
}
func (s *TCPRelay) handShake() (err error) {
	raw := make([]byte, 257)
	if _, err = io.ReadFull(s.conn, raw[:2]); err != nil {
		return
	}
	if ver := raw[0]; ver != socksv5 {
		return fmt.Errorf("error socks version %d", ver)
	}
	nmethods := raw[1]
	if _, err = io.ReadFull(s.conn, raw[2:2+nmethods]); err != nil {
		return
	}
	_, err = s.conn.Write([]byte{socksv5, 0x00})
	return
}
const (
	cmdConnect      = 0x01
	cmdBind         = 0x02
	cmdUDPAssociate = 0x03
)
func (s *TCPRelay) getCmd() (cmd byte, err error) {
	raw := make([]byte, 3)
	if _, err = io.ReadFull(s.conn, raw); err != nil {
		return
	}
	if ver := raw[0]; ver != socksv5 {
		return 0, fmt.Errorf("error socks version %d", ver)
	}
	cmd = raw[1]
	return
}