/
conn.go
93 lines (78 loc) · 1.47 KB
/
conn.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
package crypto
import (
"crypto/rc4"
"io"
"net"
"sync"
"time"
)
// Conn is an encrypted connexion. It implements the net.Conn interface.
type Conn struct {
conn net.Conn
readmu sync.Mutex
dec *rc4.Cipher
writemu sync.Mutex
enc *rc4.Cipher
err error
}
func (c *Conn) Read(b []byte) (n int, err error) {
c.readmu.Lock()
defer c.readmu.Unlock()
n, err = c.conn.Read(b)
c.dec.XORKeyStream(b[:n], b[:n])
return
}
var pool sync.Pool = sync.Pool{
New: func() interface{} {
buf := make([]byte, 32*1024)
return buf
},
}
func (c *Conn) Write(b []byte) (n int, err error) {
ibuf := pool.Get()
buf := ibuf.([]byte)
c.writemu.Lock()
defer func() {
c.writemu.Unlock()
pool.Put(ibuf)
}()
if c.err != nil {
return 0, c.err
}
for n < len(b) {
m := len(b) - n
if m > len(buf) {
m = len(buf)
}
c.enc.XORKeyStream(buf[:m], b[n:n+m])
var l int
l, err = c.conn.Write(buf[:m])
n += l
if err == nil && l < m {
err = io.ErrShortWrite
}
if err != nil {
c.err = err
return
}
}
return
}
func (c *Conn) Close() error {
return c.conn.Close()
}
func (c *Conn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
func (c *Conn) SetDeadline(t time.Time) error {
return c.conn.SetDeadline(t)
}
func (c *Conn) SetReadDeadline(t time.Time) error {
return c.conn.SetReadDeadline(t)
}
func (c *Conn) SetWriteDeadline(t time.Time) error {
return c.conn.SetWriteDeadline(t)
}