forked from ginuerzh/gost
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vsock.go
76 lines (65 loc) · 1.53 KB
/
vsock.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
package gost
import (
"net"
"strconv"
"github.com/mdlayher/vsock"
)
// vsockTransporter is a raw VSOCK transporter.
type vsockTransporter struct{}
// VSOCKTransporter creates a raw VSOCK client.
func VSOCKTransporter() Transporter {
return &vsockTransporter{}
}
func (tr *vsockTransporter) Dial(addr string, options ...DialOption) (net.Conn, error) {
opts := &DialOptions{}
for _, option := range options {
option(opts)
}
if opts.Chain == nil {
vAddr, err := parseAddr(addr)
if err != nil {
return nil, err
}
return vsock.Dial(vAddr.ContextID, vAddr.Port, nil)
}
return opts.Chain.Dial(addr)
}
func parseUint32(s string) (uint32, error ) {
n, err := strconv.ParseUint(s, 10, 32)
if err != nil {
return 0, err
}
return uint32(n), nil
}
func parseAddr(addr string) (*vsock.Addr, error) {
hostStr, portStr, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
host := uint32(0)
if hostStr != "" {
host, err = parseUint32(hostStr)
if err != nil {
return nil, err
}
}
port, err := parseUint32(portStr)
if err != nil {
return nil, err
}
return &vsock.Addr{ContextID: host, Port: port}, nil
}
func (tr *vsockTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
return conn, nil
}
func (tr *vsockTransporter) Multiplex() bool {
return false
}
// VSOCKListener creates a Listener for VSOCK proxy server.
func VSOCKListener(addr string) (Listener, error) {
vAddr, err := parseAddr(addr)
if err != nil {
return nil, err
}
return vsock.Listen(vAddr.Port, nil)
}