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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package proxy
import (
"encoding/json"
"errors"
"io"
"net"
)
type KiwiProxyState int
const KiwiProxyStateClosed KiwiProxyState = 0
const KiwiProxyStateConnecting KiwiProxyState = 1
const KiwiProxyStateHandshaking KiwiProxyState = 2
const KiwiProxyStateConnected KiwiProxyState = 3
type ConnError struct {
Msg string
Type string
}
func (err *ConnError) Error() string {
return err.Msg
}
type KiwiProxyConnection struct {
Username string
ProxyInterface string
DestHost string
DestPort int
DestTLS bool
State KiwiProxyState
Conn *net.Conn
}
func MakeKiwiProxyConnection() *KiwiProxyConnection {
return &KiwiProxyConnection{
State: KiwiProxyStateClosed,
}
}
func (c *KiwiProxyConnection) Close() error {
if c.State == KiwiProxyStateClosed {
return errors.New("Connection already closed")
}
return (*c.Conn).Close()
}
func (c *KiwiProxyConnection) Dial(proxyServerAddr string) error {
if c.State != KiwiProxyStateClosed {
return errors.New("Connection in closed state")
}
c.State = KiwiProxyStateConnecting
conn, err := net.Dial("tcp", proxyServerAddr)
if err != nil {
return err
}
c.Conn = &conn
c.State = KiwiProxyStateHandshaking
meta, _ := json.Marshal(map[string]interface{}{
"username": c.Username,
"interface": c.ProxyInterface,
"host": c.DestHost,
"port": c.DestPort,
"ssl": c.DestTLS,
})
(*c.Conn).Write(append(meta, byte('\n')))
buf := make([]byte, 1024)
bufLen, readErr := (*c.Conn).Read(buf)
if readErr != nil {
(*c.Conn).Close()
c.State = KiwiProxyStateClosed
return readErr
}
response := string(buf)
if bufLen > 0 && response[0] == '1' {
c.State = KiwiProxyStateConnected
} else {
(*c.Conn).Close()
c.State = KiwiProxyStateClosed
if bufLen == 0 {
return errors.New("The proxy could not connect to the destination")
}
switch response[0] {
case '0':
return errors.New("The proxy could not connect to the destination")
case '2':
return &ConnError{Msg: "Connection reset", Type: "conn_reset"}
case '3':
return &ConnError{Msg: "Connection refused", Type: "conn_refused"}
case '4':
return &ConnError{Msg: "Host not found", Type: "not_found"}
case '5':
return &ConnError{Msg: "Connection timed out", Type: "conn_timeout"}
}
}
return nil
}
func (c *KiwiProxyConnection) Read(b []byte) (n int, err error) {
if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking {
return 0, nil
} else if c.State == KiwiProxyStateClosed {
return 0, io.EOF
} else {
return (*c.Conn).Read(b)
}
}
func (c *KiwiProxyConnection) Write(b []byte) (n int, err error) {
if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking {
return 0, nil
} else if c.State == KiwiProxyStateClosed {
return 0, io.EOF
} else {
return (*c.Conn).Write(b)
}
}
|