69 lines
1.2 KiB
Go
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
|
||
|
}
|