/
tunnel.go
62 lines (54 loc) · 1.53 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
package main
import (
"crypto/tls"
"io"
"net"
log "github.com/liudanking/log4go"
"time"
)
func pipe(dst net.Conn, src net.Conn, copiedBytes chan int64) {
n, err := io.Copy(dst, src)
if err != nil {
log.Warn("copy [%s] to [%s] error:%v", src.RemoteAddr().String(), dst.RemoteAddr().String(), err)
}
err = src.Close()
if err != nil {
log.Warn("close [%s] error:%v", src.RemoteAddr().String(), err)
}
copiedBytes <- n
}
var TLS_SESSION_CACHE tls.ClientSessionCache = tls.NewLRUClientSessionCache(32)
var CLIENT_TLS_CONFIG tls.Config = tls.Config{
InsecureSkipVerify: DEBUG,
ClientSessionCache: TLS_SESSION_CACHE, // use sessoin ticket to speed up tls handshake
}
func dialTLS(addr string) (net.Conn, error) {
start := time.Now()
conn, err := tls.Dial("tcp", addr, &CLIENT_TLS_CONFIG)
if err != nil {
return nil, err
}
cs := conn.ConnectionState()
log.Info("dialTLS ConnectionState: resume:%v, ciphersuite:0x%02x, cost:%v",
cs.DidResume, cs.CipherSuite, time.Now().Sub(start))
return conn, nil
}
func readWritable(c net.Conn) (readable, writable bool) {
readable = true
writable = true
c.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
buf := make([]byte, 1)
_, err := c.Read(buf)
if err != nil && err == io.EOF {
readable = false
log.Debug("detect readable error:%v", err)
}
c.SetReadDeadline(time.Time{})
c.SetWriteDeadline(time.Now().Add(10 * time.Millisecond))
if _, err := c.Write(buf); err != nil {
writable = false
log.Debug("detect writable error:%v", err)
}
c.SetWriteDeadline(time.Time{})
return
}