1
2
3 package remotevm
4
5 import (
6 "context"
7 "net"
8 "os"
9
10 "github.com/Microsoft/go-winio/pkg/guid"
11 "github.com/Microsoft/hcsshim/internal/vm"
12 "github.com/Microsoft/hcsshim/internal/vmservice"
13 "github.com/pkg/errors"
14 )
15
16 func (uvm *utilityVM) VMSocketListen(ctx context.Context, listenType vm.VMSocketType, connID interface{}) (_ net.Listener, err error) {
17
18 f, err := os.CreateTemp("", "")
19 if err != nil {
20 return nil, errors.Wrap(err, "failed to create temp file for unix socket")
21 }
22
23 if err := f.Close(); err != nil {
24 return nil, errors.Wrap(err, "failed to close temp file")
25 }
26
27 if err := os.Remove(f.Name()); err != nil {
28 return nil, errors.Wrap(err, "failed to delete temp file to free up name")
29 }
30
31 l, err := net.Listen("unix", f.Name())
32 if err != nil {
33 return nil, errors.Wrapf(err, "failed to listen on unix socket %q", f.Name())
34 }
35
36 defer func() {
37 if err != nil {
38 _ = l.Close()
39 }
40 }()
41
42 switch listenType {
43 case vm.HvSocket:
44 serviceGUID, ok := connID.(guid.GUID)
45 if !ok {
46 return nil, errors.New("parameter passed to hvsocketlisten is not a GUID")
47 }
48 if err := uvm.hvSocketListen(ctx, serviceGUID.String(), f.Name()); err != nil {
49 return nil, errors.Wrap(err, "failed to setup relay to hvsocket listener")
50 }
51 case vm.VSock:
52 port, ok := connID.(uint32)
53 if !ok {
54 return nil, errors.New("parameter passed to vsocklisten is not the right type")
55 }
56 if err := uvm.vsockListen(ctx, port, f.Name()); err != nil {
57 return nil, errors.Wrap(err, "failed to setup relay to vsock listener")
58 }
59 default:
60 return nil, errors.New("unknown vmsocket type requested")
61 }
62
63 return l, nil
64 }
65
66 func (uvm *utilityVM) hvSocketListen(ctx context.Context, serviceID string, listenerPath string) error {
67 if _, err := uvm.client.VMSocket(ctx, &vmservice.VMSocketRequest{
68 Type: vmservice.ModifyType_ADD,
69 Config: &vmservice.VMSocketRequest_HvsocketList{
70 HvsocketList: &vmservice.HVSocketListen{
71 ServiceID: serviceID,
72 ListenerPath: listenerPath,
73 },
74 },
75 }); err != nil {
76 return err
77 }
78 return nil
79 }
80
81 func (uvm *utilityVM) vsockListen(ctx context.Context, port uint32, listenerPath string) error {
82 if _, err := uvm.client.VMSocket(ctx, &vmservice.VMSocketRequest{
83 Type: vmservice.ModifyType_ADD,
84 Config: &vmservice.VMSocketRequest_VsockListen{
85 VsockListen: &vmservice.VSockListen{
86 Port: port,
87 ListenerPath: listenerPath,
88 },
89 },
90 }); err != nil {
91 return err
92 }
93 return nil
94 }
95
View as plain text