1
0
mirror of https://github.com/DNSCrypt/dnscrypt-proxy.git synced 2024-12-26 00:02:34 +01:00

Implement an actual estimator for the response size

Scale back the minimum question size when relevant.

Did I mention that this is yet another thing that was never properly
implemented in dnscrypt-proxy 1.x?
This commit is contained in:
Frank Denis 2018-01-10 09:46:27 +01:00
parent f4346691bc
commit efd0477c2b
2 changed files with 24 additions and 2 deletions

View File

@ -1,14 +1,23 @@
package main package main
import "sync" import (
"sync"
"github.com/VividCortex/ewma"
)
const (
EwmaDecay = 100.0
)
type QuestionSizeEstimator struct { type QuestionSizeEstimator struct {
sync.RWMutex sync.RWMutex
minQuestionSize int minQuestionSize int
ewma ewma.MovingAverage
} }
func NewQuestionSizeEstimator() QuestionSizeEstimator { func NewQuestionSizeEstimator() QuestionSizeEstimator {
return QuestionSizeEstimator{minQuestionSize: InitialMinQuestionSize} return QuestionSizeEstimator{minQuestionSize: InitialMinQuestionSize, ewma: ewma.NewMovingAverage(EwmaDecay)}
} }
func (questionSizeEstimator *QuestionSizeEstimator) MinQuestionSize() int { func (questionSizeEstimator *QuestionSizeEstimator) MinQuestionSize() int {
@ -25,5 +34,16 @@ func (questionSizeEstimator *QuestionSizeEstimator) blindAdjust() {
} else { } else {
questionSizeEstimator.minQuestionSize *= 2 questionSizeEstimator.minQuestionSize *= 2
} }
questionSizeEstimator.ewma.Set(float64(questionSizeEstimator.minQuestionSize))
questionSizeEstimator.Unlock()
}
func (questionSizeEstimator *QuestionSizeEstimator) adjust(packetSize int) {
questionSizeEstimator.Lock()
questionSizeEstimator.ewma.Add(float64(packetSize))
ma, minQuestionSize := int(questionSizeEstimator.ewma.Value()), questionSizeEstimator.minQuestionSize
if ma > InitialMinQuestionSize && ma < minQuestionSize/2 {
questionSizeEstimator.minQuestionSize = Max(InitialMinQuestionSize, minQuestionSize/2)
}
questionSizeEstimator.Unlock() questionSizeEstimator.Unlock()
} }

View File

@ -163,6 +163,8 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, serverProto str
clientPc.(net.PacketConn).WriteTo(response, *clientAddr) clientPc.(net.PacketConn).WriteTo(response, *clientAddr)
if HasTCFlag(response) { if HasTCFlag(response) {
proxy.questionSizeEstimator.blindAdjust() proxy.questionSizeEstimator.blindAdjust()
} else {
proxy.questionSizeEstimator.adjust(len(response))
} }
} else { } else {
response, err = PrefixWithSize(response) response, err = PrefixWithSize(response)