A Go library implementing the SOCKS Protocol Version 4 and the SOCKS 4A extension (domain name support).
go get github.com/go-gost/gosocks4import "github.com/go-gost/gosocks4"
func handleConnection(conn net.Conn) {
req, err := gosocks4.ReadRequest(conn)
if err != nil {
// handle error
}
if req.Cmd == gosocks4.CmdConnect {
// Dial the target
target, _ := net.Dial("tcp", req.Addr.String())
// Reply granted with the bound address
reply := gosocks4.NewReply(gosocks4.Granted, &gosocks4.Addr{
Type: gosocks4.AddrIPv4,
Host: "0.0.0.0",
Port: 0,
})
reply.Write(conn)
// Relay traffic
// ...
}
}req := gosocks4.NewRequest(gosocks4.CmdConnect, &gosocks4.Addr{
Type: gosocks4.AddrIPv4,
Host: "93.184.216.34",
Port: 80,
}, []byte("userid"))
err := req.Write(conn)req := gosocks4.NewRequest(gosocks4.CmdConnect, &gosocks4.Addr{
Type: gosocks4.AddrDomain,
Host: "example.com",
Port: 443,
}, []byte("userid"))
err := req.Write(conn)reply, err := gosocks4.ReadReply(conn)
switch reply.Code {
case gosocks4.Granted:
// Connection granted
case gosocks4.Failed, gosocks4.Rejected:
// Request rejected
case gosocks4.RejectedUserid:
// Auth failure
}SOCKS4 destination address.
type Addr struct {
Type int // AddrIPv4 or AddrDomain
Host string // IPv4 address or hostname
Port uint16 // Destination port
}Methods: Decode(b []byte) error, Encode(b []byte) error, String() string
SOCKS4 CONNECT/BIND request.
type Request struct {
Cmd uint8 // CmdConnect or CmdBind
Addr *Addr // Destination address
Userid []byte // User identifier
}Methods: ReadRequest(r io.Reader) (*Request, error), Write(w io.Writer) error, String() string
SOCKS4 server reply.
type Reply struct {
Code uint8 // Granted, Failed, Rejected, RejectedUserid
Addr *Addr // Bound address
}Methods: ReadReply(r io.Reader) (*Reply, error), Write(w io.Writer) error, String() string
| Constant | Value | Description |
|---|---|---|
Ver4 |
4 | Protocol version |
CmdConnect |
1 | CONNECT command |
CmdBind |
2 | BIND command |
AddrIPv4 |
0 | IPv4 address type |
AddrDomain |
1 | Domain name type (SOCKS 4A) |
Granted |
90 | Request granted |
Failed |
91 | Request rejected or failed |
Rejected |
92 | Request rejected (identd) |
RejectedUserid |
93 | Request rejected (userid mismatch) |
Request:
+----+----+----+----+----+----+----+----+----+----+....+----+
| VN | CD | DSTPORT | DSTIP | USERID |NULL|
+----+----+----+----+----+----+----+----+----+----+....+----+
1 1 2 4 variable 1
SOCKS 4A: if DSTIP is 0.0.0.x (x != 0), a null-terminated hostname
follows after the userid:
+----+----+----+----+----+----+----+----+----+....+----+
| HOSTNAME |NULL|
+----+----+----+----+----+----+----+----+----+....+----+
variable 1
Reply:
+----+----+----+----+----+----+----+----+
| VN | CD | DSTPORT | DSTIP |
+----+----+----+----+----+----+----+----+
1 1 2 4
| Error | Description |
|---|---|
ErrBadVersion |
Invalid protocol version byte |
ErrBadAddrType |
Unknown address type or malformed IP |
ErrShortDataLength |
Input buffer too short |
ErrBadCmd |
Unknown command byte |
ErrFieldTooLong |
Userid or hostname exceeds 255-byte limit |