socks5/reply.go
2021-07-09 19:50:43 +03:00

69 lines
1.2 KiB
Go

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
}