Skip to content

Commit afdb151

Browse files
committed
netstack/seamless: snoop on newly swapped fdbased endpoint
1 parent cf466a3 commit afdb151

2 files changed

Lines changed: 63 additions & 17 deletions

File tree

intra/netstack/seamless.go

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ type SeamlessEndpoint interface {
6868
}
6969

7070
type magiclink struct {
71-
e *core.Volatile[stack.LinkEndpoint]
71+
e *core.Volatile[SeamlessEndpoint]
7272
d *core.Volatile[stack.NetworkDispatcher]
73-
FdSwapper
73+
s io.WriteCloser
7474
}
7575

7676
var _ stack.LinkEndpoint = (*magiclink)(nil)
7777
var _ stack.NetworkDispatcher = (*magiclink)(nil)
7878
var _ stack.GSOEndpoint = (*magiclink)(nil)
79-
var _ FdSwapper = (*magiclink)(nil)
79+
var _ SeamlessEndpoint = (*magiclink)(nil)
8080

8181
// ref: github.com/google/gvisor/blob/91f58d2cc/pkg/tcpip/sample/tun_tcp_echo/main.go#L102
8282
func NewEndpoint(dev, mtu int, sink io.WriteCloser) (ep SeamlessEndpoint, err error) {
@@ -105,13 +105,14 @@ func snoop(ep SeamlessEndpoint, sink io.WriteCloser) (SeamlessEndpoint, error) {
105105
return ep, nil
106106
}
107107
// TODO: MTU instead of SnapLen? Must match pcapsink.begin()
108-
if link, err := NewSnoopyEndpoint(ep, sink); err != nil {
108+
link, err := newSnoopyEndpoint(ep, sink, true /*write header*/)
109+
if err != nil {
109110
return nil, err
110-
} else {
111-
v := core.NewVolatile[stack.LinkEndpoint](link)
112-
d := core.NewZeroVolatile[stack.NetworkDispatcher]()
113-
return &magiclink{v, d, ep}, nil
114111
}
112+
113+
v := core.NewVolatile[SeamlessEndpoint](link)
114+
d := core.NewZeroVolatile[stack.NetworkDispatcher]()
115+
return &magiclink{v, d, sink}, nil
115116
}
116117

117118
func Pcap2Stdout(y bool) (ok bool) {
@@ -152,13 +153,14 @@ func PcapModes() string {
152153
return strings.Join(modes, ",")
153154
}
154155

155-
// Swap implements FdSwapper.
156+
// Swap implements SeamlessEndpoint.
156157
func (l *magiclink) Swap(fd int) error {
157-
if l.FdSwapper == nil {
158+
e := l.e.Load()
159+
if e == nil {
158160
return errNoFdSwapper
159161
}
160162

161-
err := l.FdSwapper.Swap(fd)
163+
err := e.Swap(fd)
162164
if errors.Is(err, errNeedsNewEndpoint) {
163165
umtu := uint32(l.MTU())
164166
opt := Options{
@@ -172,7 +174,13 @@ func (l *magiclink) Swap(fd int) error {
172174
return err
173175
}
174176

175-
if old := l.e.Swap(ep); old != nil {
177+
link, err := newSnoopyEndpoint(ep, l.s, false /*write header*/)
178+
if err != nil {
179+
log.E("netstack: magic(%d); err %v", fd, err)
180+
return err
181+
}
182+
183+
if old := l.e.Swap(link); old != nil {
176184
core.Go("magic."+strconv.Itoa(fd), old.Close)
177185
}
178186

@@ -188,6 +196,24 @@ func (l *magiclink) Swap(fd int) error {
188196
return err
189197
}
190198

199+
// Dispose implements SeamlessEndpoint.
200+
func (l *magiclink) Dispose() error {
201+
if e := l.e.Load(); e != nil {
202+
l.e.Store(nil) // clear the endpoint
203+
return e.Dispose()
204+
}
205+
log.W("netstack: magic: dispose; no endpoint")
206+
return nil
207+
}
208+
209+
// Stat implements SeamlessEndpoint.
210+
func (l *magiclink) Stat() EpStat {
211+
if e := l.e.Load(); e != nil {
212+
return e.Stat()
213+
}
214+
return EpStat{}
215+
}
216+
191217
func (l *magiclink) MTU() uint32 {
192218
if e := l.e.Load(); e != nil {
193219
return e.MTU()

intra/netstack/snooper.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,28 @@ type SnoopyEndpoint struct {
5050
writer io.Writer
5151
maxPCAPLen uint32
5252
logPrefix string
53+
fdSwapper FdSwapper
54+
}
55+
56+
// Dispose implements SeamlessEndpoint.
57+
func (e *SnoopyEndpoint) Dispose() error {
58+
return e.fdSwapper.Dispose()
59+
}
60+
61+
// Stat implements SeamlessEndpoint.
62+
func (e *SnoopyEndpoint) Stat() EpStat {
63+
return e.fdSwapper.Stat()
64+
}
65+
66+
// Swap implements SeamlessEndpoint.
67+
func (e *SnoopyEndpoint) Swap(fd int) error {
68+
return e.fdSwapper.Swap(fd)
5369
}
5470

5571
var _ stack.GSOEndpoint = (*SnoopyEndpoint)(nil)
5672
var _ stack.LinkEndpoint = (*SnoopyEndpoint)(nil)
5773
var _ stack.NetworkDispatcher = (*SnoopyEndpoint)(nil)
74+
var _ SeamlessEndpoint = (*SnoopyEndpoint)(nil)
5875

5976
// A Direction indicates whether the packing is being sent or received.
6077
type Direction int
@@ -101,20 +118,23 @@ func WritePCAPHeader(w io.Writer) error {
101118
})
102119
}
103120

104-
// NewSnoopyEndpoint creates a new snoop link-layer endpoint. It wraps around
121+
// newSnoopyEndpoint creates a new snoop link-layer endpoint. It wraps around
105122
// another endpoint and logs packets as they traverse the endpoint.
106123
//
107124
// Each packet is written to writer in the pcap format in a single Write call
108125
// without synchronization. A snoop created with this function will not emit
109126
// packets using the standard log package.
110-
func NewSnoopyEndpoint(lower stack.LinkEndpoint, writer io.Writer) (*SnoopyEndpoint, error) {
111-
if err := WritePCAPHeader(writer); err != nil {
112-
return nil, err
127+
func newSnoopyEndpoint(lower SeamlessEndpoint, w io.Writer, writeheader bool) (*SnoopyEndpoint, error) {
128+
if writeheader {
129+
if err := WritePCAPHeader(w); err != nil {
130+
return nil, err
131+
}
113132
}
114133
s := &SnoopyEndpoint{
115-
writer: writer,
134+
writer: w,
116135
maxPCAPLen: SnapLen,
117136
logPrefix: "",
137+
fdSwapper: lower,
118138
}
119139
s.Endpoint.Init(lower, s)
120140
return s, nil

0 commit comments

Comments
 (0)