-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathpeer.go
More file actions
82 lines (66 loc) · 1.82 KB
/
peer.go
File metadata and controls
82 lines (66 loc) · 1.82 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
package vncproxy
import (
"net"
"time"
"github.com/evangwt/go-bufcopy"
"github.com/pkg/errors"
"golang.org/x/net/websocket"
)
const (
defaultDialTimeout = 5 * time.Second
)
var (
bcopy = bufcopy.New()
)
// peer represents a vnc proxy peer
// with a websocket connection and a vnc backend connection
type peer struct {
source *websocket.Conn
target net.Conn
}
func NewPeer(ws *websocket.Conn, addr string, dialTimeout time.Duration) (*peer, error) {
if ws == nil {
return nil, errors.New("websocket connection is nil")
}
if len(addr) == 0 {
return nil, errors.New("addr is empty")
}
if dialTimeout <= 0 {
dialTimeout = defaultDialTimeout
}
c, err := net.DialTimeout("tcp", addr, dialTimeout)
if err != nil {
return nil, errors.Wrap(err, "cannot connect to vnc backend")
}
err = c.(*net.TCPConn).SetKeepAlive(true)
if err != nil {
return nil, errors.Wrap(err, "enable vnc backend connection keepalive failed")
}
err = c.(*net.TCPConn).SetKeepAlivePeriod(30 * time.Second)
if err != nil {
return nil, errors.Wrap(err, "set vnc backend connection keepalive period failed")
}
return &peer{
source: ws,
target: c,
}, nil
}
// ReadSource copy source stream to target connection
func (p *peer) ReadSource() error {
if _, err := bcopy.Copy(p.target, p.source); err != nil {
return errors.Wrapf(err, "copy source(%v) => target(%v) failed", p.source.RemoteAddr(), p.target.RemoteAddr())
}
return nil
}
// ReadTarget copys target stream to source connection
func (p *peer) ReadTarget() error {
if _, err := bcopy.Copy(p.source, p.target); err != nil {
return errors.Wrapf(err, "copy target(%v) => source(%v) failed", p.target.RemoteAddr(), p.source.RemoteAddr())
}
return nil
}
// Close close the websocket connection and the vnc backend connection
func (p *peer) Close() {
p.source.Close()
p.target.Close()
}