package socks5 import ( "io" ) // Request is the request packet type Request struct { Command Command ATYP ATYP DstAddr []byte DstPort []byte } // NewRequest returns new request packet func NewRequest(command Command, atyp ATYP, host []byte, port []byte) *Request { return &Request{ Command: command, ATYP: atyp, DstAddr: host, DstPort: port, } } // NewRequestFrom reads request packet from client func NewRequestFrom(r io.Reader) (*Request, error) { buf := make([]byte, 4) if _, err := io.ReadFull(r, buf); err != nil { return nil, err } if buf[0] != Version { return nil, ErrVersion } addr, err := ReadAddress(r, ATYP(buf[3])) if err != nil { return nil, err } port := make([]byte, 2) if _, err := io.ReadFull(r, port); err != nil { return nil, err } req := &Request{ Command: Command(buf[1]), ATYP: ATYP(buf[3]), DstAddr: addr, DstPort: port, } return req, nil } // WriteTo writes request packet func (s *Request) WriteTo(w io.Writer) (int64, error) { buf := []byte{Version, byte(s.Command), Reserved, byte(s.ATYP)} buf = append(buf, s.DstAddr...) buf = append(buf, s.DstPort...) n, err := w.Write(buf) if err != nil { return int64(n), err } return int64(n), nil }