@@ -68,15 +68,15 @@ type SeamlessEndpoint interface {
6868}
6969
7070type 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
7676var _ stack.LinkEndpoint = (* magiclink )(nil )
7777var _ stack.NetworkDispatcher = (* magiclink )(nil )
7878var _ 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
8282func 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
117118func 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 .
156157func (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+
191217func (l * magiclink ) MTU () uint32 {
192218 if e := l .e .Load (); e != nil {
193219 return e .MTU ()
0 commit comments