-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathslave.go
121 lines (106 loc) · 2.35 KB
/
slave.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
109
110
111
112
113
114
115
116
117
118
119
120
121
package main
import (
"flag"
"fmt"
"net"
"os"
)
var err error
func main() {
fmt.Println("*** Reverse Tunnel Slave***")
tnAddr := flag.String("t", "", "tunnel address")
ctAddr := flag.String("c", "", "address to be connected")
flag.Parse()
if *tnAddr == "" || *ctAddr == "" {
fmt.Println("Address not specified, please see usage")
os.Exit(0)
}
rts := NewRTSlave(*ctAddr, *tnAddr)
rts.Start()
}
// RTSlave is the Slave side of reverse tunnel.
type RTSlave struct {
ctAddr *net.TCPAddr
tnAddr *net.TCPAddr
cliConns map[int]net.Conn
tnConn net.Conn
ch chan TunnelData
}
// NewRTSlave returns a RTSlave.
func NewRTSlave(lnAddr, tnAddr string) *RTSlave {
c, err := net.ResolveTCPAddr("tcp", lnAddr)
if err != nil {
fmt.Println("Invilid address")
}
t, err := net.ResolveTCPAddr("tcp", tnAddr)
if err != nil {
fmt.Println("Invilid address")
}
return &RTSlave{
ctAddr: c,
tnAddr: t,
cliConns: make(map[int]net.Conn),
ch: make(chan TunnelData),
}
}
// Start .
func (rts *RTSlave) Start() {
go func() {
var err error
rts.tnConn, err = net.DialTCP("tcp", nil, rts.tnAddr)
if err != nil {
fmt.Println(err)
os.Exit(0)
}
fmt.Println("[+] Tunnel established")
rts.handleTunnelConn()
}()
// new tunnel data comes
for td := range rts.ch {
// not existed before
if rts.cliConns[td.id] == nil {
rts.cliConns[td.id], err = net.DialTCP("tcp", nil, rts.ctAddr)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("[!] Client", td.id, "comes")
}
// forward
n, _ := rts.cliConns[td.id].Write(td.data[:td.size])
fmt.Println("[*] forward", n, "bytes from client", td.id)
// wait response and send back
go rts.handleCliConns(td.id)
}
}
// read from tunnel and forward
func (rts *RTSlave) handleTunnelConn() {
for {
var buf [bufSize]byte
_, err := rts.tnConn.Read(buf[0:])
if err != nil {
return
}
td := TunnelData{
id: int(buf[0]),
size: int(buf[1]),
data: buf[2:],
}
rts.ch <- td
}
}
// read response and send back to tunnel
func (rts *RTSlave) handleCliConns(id int) {
for {
// reserve place for id and size
var buf [bufSize - 2]byte
n, err := rts.cliConns[id].Read(buf[0:])
if err != nil {
return
}
tmp := []byte{byte(id), byte(n)}
tmp = append(tmp, buf[:]...)
rts.tnConn.Write(tmp)
fmt.Println("[*] send back", n, "bytes", "to client", id)
}
}