-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathproxy.go
71 lines (59 loc) · 1.31 KB
/
proxy.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
package quictun
import (
"io"
"log"
"net"
"sync"
"sync/atomic"
"time"
)
type closeWriter interface {
CloseWrite() error
}
var linkIdSeed, linkCount int64
var bufPool = sync.Pool{
New: func() interface{} {
return make([]byte, 1024)
},
}
func Proxy(conn, targetConn net.Conn) {
defer conn.Close()
defer targetConn.Close()
defer atomic.AddInt64(&linkCount, -1)
atomic.AddInt64(&linkCount, 1)
linkId := atomic.AddInt64(&linkIdSeed, 1)
log.Printf("[%d] START link [%#x] %v <-> %v\n",
atomic.LoadInt64(&linkCount), linkId,
conn.RemoteAddr(), targetConn.RemoteAddr())
copyAndWait := func(dst, src net.Conn, c chan int64) {
buf := bufPool.Get().([]byte)
n, err := io.CopyBuffer(dst, src, buf)
bufPool.Put(buf)
if err != nil {
log.Printf("Copy: %s\n", err.Error())
}
if tcpConn, ok := dst.(closeWriter); ok {
tcpConn.CloseWrite()
} else {
dst.Close()
}
c <- n
}
start := time.Now()
stod := make(chan int64)
go copyAndWait(targetConn, conn, stod)
dtos := make(chan int64)
go copyAndWait(conn, targetConn, dtos)
var nstod, ndtos int64
for i := 0; i < 2; {
select {
case nstod = <-stod:
i++
case ndtos = <-dtos:
i++
}
}
d := BeautifyDuration(time.Since(start))
log.Printf("CLOSE link [%#x] after %s ->%s <-%s\n",
linkId, d, BeautifySize(nstod), BeautifySize(ndtos))
}