-
Notifications
You must be signed in to change notification settings - Fork 3
/
vtunneltracker.go
119 lines (99 loc) · 3.21 KB
/
vtunneltracker.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
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
108
109
110
111
112
113
114
115
116
117
118
119
/*
Copyright © 2023 SUSE LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package tracker implements a tracking mechanism to keep track
// of the ports during various container event types e.g start, stop
package tracker
import (
"errors"
"fmt"
"github.com/docker/go-connections/nat"
"github.com/rancher-sandbox/rancher-desktop-agent/pkg/forwarder"
"github.com/rancher-sandbox/rancher-desktop-agent/pkg/types"
)
var ErrRemoveAll = errors.New("failed to remove all portMappings")
// VTunnelTracker keeps track of port mappings and forwards
// them to the privileged service on the host over AF_VSOCK
// tunnel (vtunnel).
type VTunnelTracker struct {
portStorage *portStorage
vtunnelForwarder forwarder.Forwarder
wslAddrs []types.ConnectAddrs
*ListenerTracker
}
// NewVTunnelTracker creates a new Port Tracker.
func NewVTunnelTracker(vtunnelForwarder forwarder.Forwarder, wslAddrs []types.ConnectAddrs) *VTunnelTracker {
return &VTunnelTracker{
portStorage: newPortStorage(),
vtunnelForwarder: vtunnelForwarder,
wslAddrs: wslAddrs,
ListenerTracker: NewListenerTracker(),
}
}
// Add a container ID and port mapping to the tracker and calls the
// vtunnel forwarder to send the port mappings to privileged service.
func (p *VTunnelTracker) Add(containerID string, portMap nat.PortMap) error {
if len(portMap) == 0 {
return nil
}
err := p.vtunnelForwarder.Send(types.PortMapping{
Remove: false,
Ports: portMap,
ConnectAddrs: p.wslAddrs,
})
if err != nil {
return err
}
p.portStorage.add(containerID, portMap)
return nil
}
// Get gets a port mapping by container ID from the tracker.
func (p *VTunnelTracker) Get(containerID string) nat.PortMap {
return p.portStorage.get(containerID)
}
// Remove deletes a container ID and port mapping from the tracker and calls the
// vtunnel forwarder to send the port mappings to privileged service.
func (p *VTunnelTracker) Remove(containerID string) error {
portMap := p.portStorage.get(containerID)
if len(portMap) != 0 {
err := p.vtunnelForwarder.Send(types.PortMapping{
Remove: true,
Ports: portMap,
ConnectAddrs: p.wslAddrs,
})
if err != nil {
return err
}
p.portStorage.remove(containerID)
}
return nil
}
// RemoveAll removes all the port bindings from the tracker.
func (p *VTunnelTracker) RemoveAll() error {
defer p.portStorage.removeAll()
allPortMappings := p.portStorage.getAll()
var errs []error
for _, portMap := range allPortMappings {
err := p.vtunnelForwarder.Send(types.PortMapping{
Remove: true,
Ports: portMap,
ConnectAddrs: p.wslAddrs,
})
if err != nil {
errs = append(errs, err)
}
}
if len(errs) != 0 {
return fmt.Errorf("%w: %+v", ErrRemoveAll, errs)
}
return nil
}