forked from yinghuocho/gosocks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
95 lines (85 loc) · 2.06 KB
/
client.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
93
94
95
package gosocks
import (
"bufio"
"fmt"
"io"
"net"
"time"
)
type ClientAuthenticator interface {
ClientAuthenticate(conn *SocksConn) error
}
type SocksDialer struct {
Timeout time.Duration
Auth ClientAuthenticator
}
type AnonymousClientAuthenticator struct{}
func (a *AnonymousClientAuthenticator) ClientAuthenticate(conn *SocksConn) (err error) {
conn.SetWriteDeadline(time.Now().Add(conn.Timeout))
var req [3]byte
req[0] = SocksVersion
req[1] = 1
req[2] = SocksNoAuthentication
_, err = conn.Write(req[:])
if err != nil {
return
}
conn.SetReadDeadline(time.Now().Add(conn.Timeout))
var resp [2]byte
r := bufio.NewReader(conn)
_, err = io.ReadFull(r, resp[:2])
if err != nil {
return
}
if resp[0] != SocksVersion || resp[1] != SocksNoAuthentication {
err = fmt.Errorf("Fail to pass anonymous authentication: (0x%02x, 0x%02x)", resp[0], resp[1])
return
}
return
}
func (d *SocksDialer) Dial(address string) (conn *SocksConn, err error) {
c, err := net.DialTimeout("tcp", address, d.Timeout)
if err != nil {
return
}
conn = &SocksConn{c.(*net.TCPConn), d.Timeout}
err = d.Auth.ClientAuthenticate(conn)
if err != nil {
conn.Close()
return
}
return
}
func ClientAuthAnonymous(conn *SocksConn) (err error) {
conn.SetWriteDeadline(time.Now().Add(conn.Timeout))
var req [3]byte
req[0] = SocksVersion
req[1] = 1
req[2] = SocksNoAuthentication
_, err = conn.Write(req[:])
if err != nil {
return
}
conn.SetReadDeadline(time.Now().Add(conn.Timeout))
var resp [2]byte
r := bufio.NewReader(conn)
_, err = io.ReadFull(r, resp[:2])
if err != nil {
return
}
if resp[0] != SocksVersion || resp[1] != SocksNoAuthentication {
err = fmt.Errorf("Fail to pass anonymous authentication: (0x%02x, 0x%02x)", resp[0], resp[1])
return
}
return
}
func ClientRequest(conn *SocksConn, req *SocksRequest) (reply *SocksReply, err error) {
conn.SetWriteDeadline(time.Now().Add(conn.Timeout))
_, err = WriteSocksRequest(conn, req)
if err != nil {
return
}
conn.SetReadDeadline(time.Now().Add(conn.Timeout))
reply, err = ReadSocksReply(conn)
return
}