filter: prevent escape of QDecode to the heap (#417)
Performance impact: name old time/op new time/op delta Filter/tcp_in-4 70.7ns ± 1% 30.9ns ± 1% -56.30% (p=0.008 n=5+5) Filter/tcp_out-4 58.6ns ± 0% 19.4ns ± 0% -66.87% (p=0.000 n=5+4) Filter/udp_in-4 96.8ns ± 2% 55.5ns ± 0% -42.64% (p=0.016 n=5+4) Filter/udp_out-4 120ns ± 1% 79ns ± 1% -33.87% (p=0.008 n=5+5) Signed-off-by: Dmytro Shynkevych <dmytro@tailscale.com>
This commit is contained in:
committed by
GitHub
parent
83b6b06cc4
commit
73c40c77b0
@@ -138,16 +138,26 @@ var acceptBucket = rate.NewLimiter(rate.Every(10*time.Second), 3)
|
||||
var dropBucket = rate.NewLimiter(rate.Every(5*time.Second), 10)
|
||||
|
||||
func (f *Filter) logRateLimit(runflags RunFlags, b []byte, q *packet.QDecode, r Response, why string) {
|
||||
var verdict string
|
||||
|
||||
if r == Drop && (runflags&LogDrops) != 0 && dropBucket.Allow() {
|
||||
verdict = "Drop"
|
||||
runflags &= HexdumpDrops
|
||||
} else if r == Accept && (runflags&LogAccepts) != 0 && acceptBucket.Allow() {
|
||||
verdict = "Accept"
|
||||
runflags &= HexdumpAccepts
|
||||
}
|
||||
|
||||
// Note: it is crucial that q.String() be called only if {accept,drop}Bucket.Allow() passes,
|
||||
// since it causes an allocation.
|
||||
if verdict != "" {
|
||||
var qs string
|
||||
if q == nil {
|
||||
qs = fmt.Sprintf("(%d bytes)", len(b))
|
||||
} else {
|
||||
qs = q.String()
|
||||
}
|
||||
f.logf("Drop: %v %v %s\n%s", qs, len(b), why, maybeHexdump(runflags&HexdumpDrops, b))
|
||||
} else if r == Accept && (runflags&LogAccepts) != 0 && acceptBucket.Allow() {
|
||||
f.logf("Accept: %v %v %s\n%s", q, len(b), why, maybeHexdump(runflags&HexdumpAccepts, b))
|
||||
f.logf("%s: %s %d %s\n%s", verdict, qs, len(b), why, maybeHexdump(runflags, b))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +264,7 @@ func (f *Filter) pre(b []byte, q *packet.QDecode, rf RunFlags) Response {
|
||||
|
||||
if q.IPProto == packet.Junk {
|
||||
// Junk packets are dangerous; always drop them.
|
||||
f.logRateLimit(rf, b, q, Drop, "junk!")
|
||||
f.logRateLimit(rf, b, q, Drop, "junk")
|
||||
return Drop
|
||||
} else if q.IPProto == packet.Fragment {
|
||||
// Fragments after the first always need to be passed through.
|
||||
|
||||
Reference in New Issue
Block a user