package socks5 import ( "io" ) // Reply is the reply packet type Reply struct { Status ReplyStatus ATYP ATYP BindAddr []byte BindPort []byte } // NewReply returns new reply packet func NewReply(status ReplyStatus, atyp ATYP, host []byte, port []byte) *Reply { return &Reply{ Status: status, ATYP: atyp, BindAddr: host, BindPort: port, } } // NewReplyFrom reads reply packet from reader func NewReplyFrom(r io.Reader) (*Reply, 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 } rep := &Reply{ Status: ReplyStatus(buf[1]), ATYP: ATYP(buf[3]), BindAddr: addr, BindPort: port, } return rep, nil } // WriteTo writes reply packet func (s *Reply) WriteTo(w io.Writer) (int64, error) { buf := []byte{Version, byte(s.Status), Reserved, byte(s.ATYP)} buf = append(buf, s.BindAddr...) buf = append(buf, s.BindPort...) n, err := w.Write(buf) if err != nil { return int64(n), err } return int64(n), nil }