-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathtcp.go
More file actions
148 lines (122 loc) · 2.61 KB
/
Copy pathtcp.go
File metadata and controls
148 lines (122 loc) · 2.61 KB
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"context"
"net"
"strconv"
"time"
)
// 监听本地
func tcpLocal(addr string, ctx context.Context) {
l, err := net.Listen("tcp", addr)
if err != nil {
return
}
defer l.Close()
//循环接受连接
for {
select {
case <-ctx.Done():
return
default:
c, err := l.Accept()
if err != nil {
continue
}
go tcpShakehands(c)
}
}
}
//tcp握手
func tcpShakehands(c net.Conn) {
defer c.Close()
c.(*net.TCPConn).SetKeepAlive(true)
//查找对应远程地址
localPort := c.RemoteAddr().(*net.TCPAddr).Port
//先找出这条连接对应的进程id 和目标信息
pInfo, ok := tcpmap.Get(localPort)
if ok != true {
return
}
tcpmap.Del(localPort)
//查找进程对应的代理信息
prs, ok := proxyMap.Load(pInfo.pid)
if !ok {
return
}
pProxy, ok := prs.(ProxyInfo)
if !ok {
return
}
server := pProxy.ip + ":" + strconv.Itoa(pProxy.port)
//连接代理
rc, err := net.DialTimeout("tcp", server, 5*time.Second)
if err != nil {
return
}
defer rc.Close()
rc.(*net.TCPConn).SetKeepAlive(true)
switch pProxy.ptype {
case AtypSocks5: //Socks5
if err := Socks5Tcp(rc, pProxy.user, pProxy.passw, pInfo.ip); err != nil {
return
}
case AtypShadowSocks: //Shadowsocks
rc = pProxy.ciph.StreamConn(rc)
//ss协议发送头信息
if _, Perr := rc.Write(pInfo.ip); Perr != nil {
return
}
default:
return
}
//拷贝数据流 完成tcp对接
_, _, err = relay(rc, c, pInfo.pid)
if err != nil {
if err, ok := err.(net.Error); ok && err.Timeout() {
return // ignore i/o timeout
}
}
}
// 转发数据
func relay(left, right net.Conn, pid uint64) (int64, int64, error) {
type res struct {
N int64
Err error
}
ch := make(chan res)
go func() { //recv
n, err := Copy(right, left, AtypRecv, pid)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
ch <- res{n, err}
}()
//send
n, err := Copy(left, right, AtypSend, pid)
right.SetDeadline(time.Now()) // wake up the other goroutine blocking on right
left.SetDeadline(time.Now()) // wake up the other goroutine blocking on left
rs := <-ch
if err == nil {
err = rs.Err
}
return n, rs.N, err
}
func Copy(dst, src net.Conn, sc int, pid uint64) (written int64, err error) {
buf := make([]byte, tcpBufSize)
for {
nr, er := src.Read(buf)
if er != nil {
err = er
break
}
if nr > 0 {
_, ew := dst.Write(buf[0:nr])
if ew != nil {
err = ew
break
}
}
//流量统计
mcc <- mccInfo{pid: pid, to: sc, bytebyte: int64(nr)}
}
return written, err
}