/
socks5.go
92 lines (75 loc) · 1.72 KB
/
socks5.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package main
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"io"
"net"
)
var (
handShakeProtoVersion = 0
handShakeAnswer = []byte{0x05, 0x00}
reqAnswer = []byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43}
)
func handShake(c net.Conn) error {
hsr := make([]byte, 3)
_, err := io.ReadFull(c, hsr)
if err != nil {
return fmt.Errorf("HandShake error")
}
protoVersion := hsr[handShakeProtoVersion]
if protoVersion != 0x05 {
return fmt.Errorf("Protocol mismatch: %d", protoVersion)
}
_, err = c.Write(handShakeAnswer)
return err
}
// commandCode, addressType, address, port, err
func parseReq(c net.Conn) (byte, byte, []byte, uint16, error) {
r := bufio.NewReader(c)
protoVersion, err := r.ReadByte()
if err != nil {
return 0, 0, nil, 0, err
}
if protoVersion != 0x05 {
return 0, 0, nil, 0, fmt.Errorf("Protocol mismatch: %d", protoVersion)
}
commandCode, err := r.ReadByte()
if err != nil {
return 0, 0, nil, 0, err
}
_, err = r.ReadByte()
if err != nil {
return 0, 0, nil, 0, err
}
addressType, err := r.ReadByte()
if err != nil {
return 0, 0, nil, 0, err
}
address := new(bytes.Buffer)
switch addressType {
case 0x01:
for i := 0; i < 4; i++ {
c, _ := r.ReadByte()
address.WriteByte(c)
}
case 0x03:
length, _ := r.ReadByte()
for i := 0; i < int(length); i++ {
c, _ := r.ReadByte()
address.WriteByte(c)
}
case 0x04:
for i := 0; i < 16; i++ {
c, _ := r.ReadByte()
address.WriteByte(c)
}
default:
return 0, 0, nil, 0, fmt.Errorf("Address Type error")
}
var port uint16
err = binary.Read(r, binary.BigEndian, &port)
// commandCode, addressType, address, port, err
return commandCode, addressType, address.Bytes(), port, err
}