@@ -97,7 +97,7 @@ type Impl struct {
97
97
98
98
ipstack * stack.Stack
99
99
epMu sync.RWMutex
100
- linkEP * channel. Endpoint
100
+ linkEP * protectedLinkEP
101
101
tundev * tstun.Wrapper
102
102
e wgengine.Engine
103
103
mc * magicsock.Conn
@@ -159,7 +159,7 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
159
159
if tcpipErr != nil {
160
160
return nil , fmt .Errorf ("could not enable TCP SACK: %v" , tcpipErr )
161
161
}
162
- linkEP := channel .New (512 , mtu , "" )
162
+ linkEP := & protectedLinkEP { Endpoint : channel .New (512 , mtu , "" )}
163
163
if tcpipProblem := ipstack .CreateNIC (nicID , linkEP ); tcpipProblem != nil {
164
164
return nil , fmt .Errorf ("could not create netstack NIC: %v" , tcpipProblem )
165
165
}
@@ -202,9 +202,7 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
202
202
func (ns * Impl ) Close () error {
203
203
ns .ctxCancel ()
204
204
ns .ipstack .Close ()
205
- ns .epMu .Lock ()
206
205
ns .ipstack .Wait ()
207
- ns .epMu .Unlock ()
208
206
return nil
209
207
}
210
208
@@ -689,13 +687,7 @@ func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper) filter.Respons
689
687
packetBuf := stack .NewPacketBuffer (stack.PacketBufferOptions {
690
688
Payload : bufferv2 .MakeWithData (bytes .Clone (p .Buffer ())),
691
689
})
692
-
693
- if ns .epMu .TryRLock () {
694
- if ns .linkEP .IsAttached () {
695
- ns .linkEP .InjectInbound (pn , packetBuf )
696
- }
697
- ns .epMu .RUnlock ()
698
- }
690
+ ns .linkEP .InjectInbound (pn , packetBuf )
699
691
packetBuf .DecRef ()
700
692
701
693
// We've now delivered this to netstack, so we're done.
@@ -1216,3 +1208,40 @@ func ipPortOfNetstackAddr(a tcpip.Address, port uint16) (ipp netip.AddrPort, ok
1216
1208
return ipp , false
1217
1209
}
1218
1210
}
1211
+
1212
+ // protectedLinkEP guards use of the dispatcher via mutex and forwards
1213
+ // everything except Attach/InjectInbound to the underlying *channel.Endpoint.
1214
+ type protectedLinkEP struct {
1215
+ mu sync.RWMutex
1216
+ dispatcher stack.NetworkDispatcher
1217
+ * channel.Endpoint
1218
+ }
1219
+
1220
+ // InjectInbound injects an inbound packet.
1221
+ func (e * protectedLinkEP ) InjectInbound (protocol tcpip.NetworkProtocolNumber , pkt stack.PacketBufferPtr ) {
1222
+ e .mu .RLock ()
1223
+ dispatcher := e .dispatcher
1224
+ e .mu .RUnlock ()
1225
+ if dispatcher != nil {
1226
+ dispatcher .DeliverNetworkPacket (protocol , pkt )
1227
+ }
1228
+ }
1229
+
1230
+ // Attach saves the stack network-layer dispatcher for use later when packets
1231
+ // are injected.
1232
+ func (e * protectedLinkEP ) Attach (dispatcher stack.NetworkDispatcher ) {
1233
+ e .mu .Lock ()
1234
+ defer e .mu .Unlock ()
1235
+ // No need to attach the underlying channel.Endpoint, since we hijack
1236
+ // InjectInbound.
1237
+ e .dispatcher = dispatcher
1238
+ }
1239
+
1240
+ // IsAttached implements stack.LinkEndpoint.IsAttached.
1241
+ func (e * protectedLinkEP ) IsAttached () bool {
1242
+ e .mu .RLock ()
1243
+ defer e .mu .RUnlock ()
1244
+ return e .dispatcher != nil
1245
+ }
1246
+
1247
+ var _ stack.LinkEndpoint = (* protectedLinkEP )(nil )
0 commit comments