-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathhvsock.go
More file actions
107 lines (94 loc) · 2.54 KB
/
hvsock.go
File metadata and controls
107 lines (94 loc) · 2.54 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
package main
import (
"log"
"net"
"strings"
"github.com/linuxkit/virtsock/pkg/hvsock"
"github.com/linuxkit/virtsock/pkg/vsock"
)
var (
svcid, _ = hvsock.GUIDFromString("3049197C-FACB-11E6-BD58-64006A7986D3")
useHVSock = false
)
type hvsockAddr struct {
hvAddr hvsock.Addr
vAddr vsock.Addr
}
func init() {
// Check which version (hvsock/vsock) we should use for Hyper-V sockets
useHVSock = hvsock.Supported()
}
// hvsockParseSockStr extracts the vmid and svcid from a string.
// The format is "VMID:Service", "VMID", or ":Service" as well as an
// empty string. For VMID we also support "parent" and assume
// "loopback" if the string can't be parsed.
func hvsockParseSockStr(vmStr, svcStr string) hvsockAddr {
hvAddr := hvsock.Addr{hvsock.GUIDZero, svcid}
port, _ := svcid.Port()
vAddr := vsock.Addr{vsock.CIDAny, port}
if svcStr != "" && svcStr[0] == '/' {
svcStr = svcStr[1:]
}
if vmStr == "" && svcStr == "" {
return hvsockAddr{hvAddr: hvAddr, vAddr: vAddr}
}
var err error
if vmStr != "" {
if strings.Contains(vmStr, "-") {
if !useHVSock {
log.Fatalf("Can't use VM GUIDs in vsock mode")
}
hvAddr.VMID, err = hvsock.GUIDFromString(vmStr)
if err != nil {
log.Fatalf("Error parsing VM '%s': %v", vmStr, err)
}
} else if vmStr == "parent" {
hvAddr.VMID = hvsock.GUIDParent
vAddr.CID = vsock.CIDHost
} else {
hvAddr.VMID = hvsock.GUIDLoopback
vAddr.CID = vsock.CIDHypervisor
}
}
if svcStr != "" {
if hvAddr.ServiceID, err = hvsock.GUIDFromString(svcStr); err != nil {
log.Fatalf("Error parsing SVC '%s': %v", svcStr, err)
}
if !useHVSock {
if vAddr.Port, err = hvAddr.ServiceID.Port(); err != nil {
log.Fatalf("Error parsing SVC '%s': %v", svcStr, err)
}
}
}
return hvsockAddr{hvAddr: hvAddr, vAddr: vAddr}
}
func (s hvsockAddr) String() string {
return s.hvAddr.String()
}
// Dial connects on a Hyper-V socket
func (s hvsockAddr) Dial(conid int) (Conn, error) {
if !useHVSock {
return vsock.Dial(s.vAddr.CID, s.vAddr.Port)
}
return hvsock.Dial(s.hvAddr)
}
// Listen returns a net.Listener for a given Hyper-V socket
func (s hvsockAddr) Listen() net.Listener {
if !useHVSock {
l, err := vsock.Listen(s.vAddr.CID, s.vAddr.Port)
if err != nil {
log.Fatalln("Listen():", err)
}
return l
}
l, err := hvsock.Listen(s.hvAddr)
if err != nil {
log.Fatalln("Listen():", err)
}
return l
}
// ListenPacket is not implemented for Hyper-V sockets
func (s hvsockAddr) ListenPacket() net.PacketConn {
log.Fatalln("ListenPacket(): not implemented for Hyper-V sockets")
return nil
}