-
Notifications
You must be signed in to change notification settings - Fork 14
/
hdl.go
133 lines (113 loc) · 3.08 KB
/
hdl.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) 2022 RethinkDNS and its authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package netstack
import (
"errors"
"net"
"net/netip"
"strings"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/stack"
)
type GConnHandler interface {
TCP() GTCPConnHandler // TCP returns the TCP handler.
UDP() GUDPConnHandler // UDP returns the UDP handler.
ICMP() GICMPHandler // ICMP returns the ICMP handler.
CloseConns(csv string) string // CloseConns closes the connections with the given IDs, or all if empty.
Close() error // Close closes TCP, UDP, ICMP handlers and its resources.
}
type gconnhandler struct {
tcp GTCPConnHandler
udp GUDPConnHandler
icmp GICMPHandler
}
const allconns = ""
var _ GConnHandler = (*gconnhandler)(nil)
func NewGConnHandler(tcp GTCPConnHandler, udp GUDPConnHandler, icmp GICMPHandler) GConnHandler {
return &gconnhandler{
tcp: tcp,
udp: udp,
icmp: icmp,
}
}
func (g *gconnhandler) TCP() GTCPConnHandler {
return g.tcp
}
func (g *gconnhandler) UDP() GUDPConnHandler {
return g.udp
}
func (g *gconnhandler) ICMP() GICMPHandler {
return g.icmp
}
func (g *gconnhandler) CloseConns(csv string) string {
var cids []string = nil // nil closes all conns
if len(csv) > 0 {
// split returns [""] (slice of length 1) if csv is empty
// and so, avoid splitting on empty csv, and let cids be nil
cids = strings.Split(csv, ",")
}
var t []string
var u []string
var i []string
if tcp := g.tcp; tcp != nil {
t = tcp.CloseConns(cids)
}
if udp := g.udp; udp != nil {
u = udp.CloseConns(cids)
}
if icmp := g.icmp; icmp != nil {
i = icmp.CloseConns(cids)
}
s := make([]string, 0, len(t)+len(u)+len(i))
s = append(s, t...)
s = append(s, u...)
s = append(s, i...)
return strings.Join(s, ",")
}
func (g *gconnhandler) Close() error {
var errs error
g.CloseConns(allconns)
if t := g.tcp; t != nil {
err := t.End()
errs = errors.Join(errs, err)
}
if u := g.udp; u != nil {
err := u.End()
errs = errors.Join(errs, err)
}
if i := g.icmp; i != nil {
err := i.End()
errs = errors.Join(errs, err)
}
return errs
}
// src/dst addrs are flipped
// fdbased.Attach -> ... -> nic.DeliverNetworkPacket -> ... -> nic.DeliverTransportPacket:
// github.com/google/gvisor/blob/be6ffa7/pkg/tcpip/stack/nic.go#L831-L837
func localAddrPort(id stack.TransportEndpointID) netip.AddrPort {
// todo: unmap?
return localUDPAddr(id).AddrPort()
}
func remoteAddrPort(id stack.TransportEndpointID) netip.AddrPort {
// todo: unmap?
return remoteUDPAddr(id).AddrPort()
}
func remoteUDPAddr(id stack.TransportEndpointID) *net.UDPAddr {
return &net.UDPAddr{
IP: nsaddr2ip(id.RemoteAddress),
Port: int(id.RemotePort),
}
}
func localUDPAddr(id stack.TransportEndpointID) *net.UDPAddr {
return &net.UDPAddr{
IP: nsaddr2ip(id.LocalAddress),
Port: int(id.LocalPort),
}
}
func nsaddr2ip(addr tcpip.Address) net.IP {
b := addr.AsSlice()
return net.IP(b)
}