/
tunnel.go
108 lines (93 loc) · 2.02 KB
/
tunnel.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
96
97
98
99
100
101
102
103
104
105
106
107
108
package internal
import (
"encoding/binary"
"github.com/go-well/spider/silk"
"io"
)
//TODO 封装成Tunnel类
func receiveTunnel(c *Client, conn io.ReadWriteCloser, id uint16) {
buf := make([]byte, 512)
binary.BigEndian.PutUint16(buf, id)
for {
n, e := conn.Read(buf[2:])
if e != nil {
_ = c.Send(&silk.Package{
Type: silk.TunnelError,
})
break
}
data := buf[:2+n]
pack := &silk.Package{
Type: silk.TunnelData,
Data: data,
}
_ = c.Send(pack)
}
_ = c.Send(&silk.Package{
Type: silk.TunnelDataEnd,
Data: buf[:2],
})
c.tunnels.Delete(id)
}
func (c *Client) TunnelBind(conn io.ReadWriteCloser) error {
p, err := c.Ask(&silk.Package{Type: silk.TunnelCreate})
if err != nil {
return err
}
id := binary.BigEndian.Uint16(p.Data)
c.tunnels.Store(id, conn)
go receiveTunnel(c, conn, id)
return nil
}
func init() {
RegisterHandler(silk.TunnelClose, func(c *Client, p *silk.Package) {
p.Type = silk.TunnelCloseAck
id := binary.BigEndian.Uint16(p.Data)
f, ok := c.tunnels.LoadAndDelete(id)
if !ok {
p.SetError("tunnel not exists")
_ = c.Send(p)
return
}
conn := f.(io.ReadWriteCloser)
err := conn.Close()
if err != nil {
p.SetError(err.Error())
}
_ = c.Send(p)
})
RegisterHandler(silk.TunnelData, func(c *Client, p *silk.Package) {
p.Type = silk.TunnelDataAck
id := binary.BigEndian.Uint16(p.Data)
f, ok := c.tunnels.Load(id)
if !ok {
p.SetError("tunnel not exists")
_ = c.Send(p)
return
}
conn := f.(io.ReadWriteCloser)
_, err := conn.Write(p.Data[2:])
if err != nil {
p.SetError(err.Error())
_ = c.Send(p)
}
//正常不回复
})
RegisterHandler(silk.TunnelDataEnd, func(c *Client, p *silk.Package) {
p.Type = silk.TunnelDataEndAck
id := binary.BigEndian.Uint16(p.Data)
f, ok := c.tunnels.LoadAndDelete(id)
if !ok {
p.SetError("tunnel not exists")
_ = c.Send(p)
return
}
conn := f.(io.ReadWriteCloser)
err := conn.Close()
if err != nil {
p.SetError(err.Error())
_ = c.Send(p)
}
//正常不回复
})
}