@ -45,6 +45,11 @@ var (
errOffsetTooSmall = errors . New ( "offset smaller than PacketStartOffset" )
errOffsetTooSmall = errors . New ( "offset smaller than PacketStartOffset" )
)
)
// parsedPacketPool holds a pool of ParsedPacket structs for use in filtering.
// This is needed because escape analysis cannot see that parsed packets
// do not escape through {Pre,Post}Filter{In,Out}.
var parsedPacketPool = sync . Pool { New : func ( ) interface { } { return new ( packet . ParsedPacket ) } }
// FilterFunc is a packet-filtering function with access to the TUN device.
// FilterFunc is a packet-filtering function with access to the TUN device.
// It must not hold onto the packet struct, as its backing storage will be reused.
// It must not hold onto the packet struct, as its backing storage will be reused.
type FilterFunc func ( * packet . ParsedPacket , * TUN ) filter . Response
type FilterFunc func ( * packet . ParsedPacket , * TUN ) filter . Response
@ -66,10 +71,6 @@ type TUN struct {
buffer [ maxBufferSize ] byte
buffer [ maxBufferSize ] byte
// bufferConsumed synchronizes access to buffer (shared by Read and poll).
// bufferConsumed synchronizes access to buffer (shared by Read and poll).
bufferConsumed chan struct { }
bufferConsumed chan struct { }
// parsedPacketPool holds a pool of ParsedPacket structs for use in filtering.
// This is needed because escape analysis cannot see that parsed packets
// do not escape through {Pre,Post}Filter{In,Out}.
parsedPacketPool sync . Pool // of *packet.ParsedPacket
// closed signals poll (by closing) when the device is closed.
// closed signals poll (by closing) when the device is closed.
closed chan struct { }
closed chan struct { }
@ -121,10 +122,6 @@ func WrapTUN(logf logger.Logf, tdev tun.Device) *TUN {
filterFlags : filter . LogAccepts | filter . LogDrops ,
filterFlags : filter . LogAccepts | filter . LogDrops ,
}
}
tun . parsedPacketPool . New = func ( ) interface { } {
return new ( packet . ParsedPacket )
}
go tun . poll ( )
go tun . poll ( )
// The buffer starts out consumed.
// The buffer starts out consumed.
tun . bufferConsumed <- struct { } { }
tun . bufferConsumed <- struct { } { }
@ -208,8 +205,8 @@ func (t *TUN) poll() {
}
}
func ( t * TUN ) filterOut ( buf [ ] byte ) filter . Response {
func ( t * TUN ) filterOut ( buf [ ] byte ) filter . Response {
p := t. parsedPacketPool. Get ( ) . ( * packet . ParsedPacket )
p := parsedPacketPool. Get ( ) . ( * packet . ParsedPacket )
defer t. parsedPacketPool. Put ( p )
defer parsedPacketPool. Put ( p )
p . Decode ( buf )
p . Decode ( buf )
if t . PreFilterOut != nil {
if t . PreFilterOut != nil {
@ -287,8 +284,8 @@ func (t *TUN) Read(buf []byte, offset int) (int, error) {
}
}
func ( t * TUN ) filterIn ( buf [ ] byte ) filter . Response {
func ( t * TUN ) filterIn ( buf [ ] byte ) filter . Response {
p := t. parsedPacketPool. Get ( ) . ( * packet . ParsedPacket )
p := parsedPacketPool. Get ( ) . ( * packet . ParsedPacket )
defer t. parsedPacketPool. Put ( p )
defer parsedPacketPool. Put ( p )
p . Decode ( buf )
p . Decode ( buf )
if t . PreFilterIn != nil {
if t . PreFilterIn != nil {