socks5/request.go

69 lines
1.2 KiB
Go
Raw Normal View History

2021-07-09 16:50:43 +00:00
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
}