Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 59 additions & 50 deletions dnscrypt-proxy/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/jedisct1/dlog"
stamps "github.com/jedisct1/go-dnsstamps"
"github.com/miekg/dns"
)

Expand Down Expand Up @@ -273,58 +274,64 @@ func NewPluginsState(
func (pluginsState *PluginsState) ApplyQueryPlugins(
pluginsGlobals *PluginsGlobals,
packet []byte,
needsEDNS0Padding bool,
) ([]byte, error) {
getServerInfo func() *ServerInfo,
) ([]byte, *ServerInfo, error) {
msg := dns.Msg{}
if err := msg.Unpack(packet); err != nil {
return packet, err
return packet, nil, err
}
if len(msg.Question) != 1 {
return packet, errors.New("Unexpected number of questions")
return packet, nil, errors.New("Unexpected number of questions")
}
qName, err := NormalizeQName(msg.Question[0].Name)
if err != nil {
return packet, err
return packet, nil, err
}
dlog.Debugf("Handling query for [%v]", qName)
pluginsState.qName = qName
pluginsState.questionMsg = &msg
if len(*pluginsGlobals.queryPlugins) == 0 && len(*pluginsGlobals.loggingPlugins) == 0 {
return packet, nil
}
pluginsGlobals.RLock()
defer pluginsGlobals.RUnlock()
for _, plugin := range *pluginsGlobals.queryPlugins {
if err := plugin.Eval(pluginsState, &msg); err != nil {
pluginsState.action = PluginsActionDrop
return packet, err
}
if pluginsState.action == PluginsActionReject {
synth := RefusedResponseFromMessage(
&msg,
pluginsGlobals.refusedCodeInResponses,
pluginsGlobals.respondWithIPv4,
pluginsGlobals.respondWithIPv6,
pluginsState.rejectTTL,
)
pluginsState.synthResponse = synth
}
if pluginsState.action != PluginsActionContinue {
break
if len(*pluginsGlobals.queryPlugins) > 0 {
pluginsGlobals.RLock()
for _, plugin := range *pluginsGlobals.queryPlugins {
if err := plugin.Eval(pluginsState, &msg); err != nil {
pluginsState.action = PluginsActionDrop
return packet, nil, err
}
if pluginsState.action == PluginsActionReject {
synth := RefusedResponseFromMessage(
&msg,
pluginsGlobals.refusedCodeInResponses,
pluginsGlobals.respondWithIPv4,
pluginsGlobals.respondWithIPv6,
pluginsState.rejectTTL,
)
pluginsState.synthResponse = synth
}
if pluginsState.action != PluginsActionContinue {
break
}
}
pluginsGlobals.RUnlock()
}
needsEDNS0Padding := false
var serverInfo *ServerInfo
if pluginsState.action == PluginsActionContinue {
serverInfo = getServerInfo()
}
if serverInfo != nil {
needsEDNS0Padding = (serverInfo.Proto == stamps.StampProtoTypeDoH || serverInfo.Proto == stamps.StampProtoTypeTLS)
}

packet2, err := msg.PackBuffer(packet)
if err != nil {
return packet, err
return packet, serverInfo, err
}
if needsEDNS0Padding && pluginsState.action == PluginsActionContinue {
padLen := 63 - ((len(packet2) + 63) & 63)
if paddedPacket2, _ := addEDNS0PaddingIfNoneFound(&msg, packet2, padLen); paddedPacket2 != nil {
return paddedPacket2, nil
return paddedPacket2, serverInfo, nil
}
}
return packet2, nil
return packet2, serverInfo, nil
}

func (pluginsState *PluginsState) ApplyResponsePlugins(
Expand All @@ -350,26 +357,28 @@ func (pluginsState *PluginsState) ApplyResponsePlugins(
pluginsState.returnCode = PluginsReturnCodeResponseError
}
removeEDNS0Options(&msg)
pluginsGlobals.RLock()
defer pluginsGlobals.RUnlock()
for _, plugin := range *pluginsGlobals.responsePlugins {
if err := plugin.Eval(pluginsState, &msg); err != nil {
pluginsState.action = PluginsActionDrop
return packet, err
}
if pluginsState.action == PluginsActionReject {
synth := RefusedResponseFromMessage(
&msg,
pluginsGlobals.refusedCodeInResponses,
pluginsGlobals.respondWithIPv4,
pluginsGlobals.respondWithIPv6,
pluginsState.rejectTTL,
)
pluginsState.synthResponse = synth
}
if pluginsState.action != PluginsActionContinue {
break
if len(*pluginsGlobals.responsePlugins) > 0 {
pluginsGlobals.RLock()
for _, plugin := range *pluginsGlobals.responsePlugins {
if err := plugin.Eval(pluginsState, &msg); err != nil {
pluginsState.action = PluginsActionDrop
return packet, err
}
if pluginsState.action == PluginsActionReject {
synth := RefusedResponseFromMessage(
&msg,
pluginsGlobals.refusedCodeInResponses,
pluginsGlobals.respondWithIPv4,
pluginsGlobals.respondWithIPv6,
pluginsState.rejectTTL,
)
pluginsState.synthResponse = synth
}
if pluginsState.action != PluginsActionContinue {
break
}
}
pluginsGlobals.RUnlock()
}
if ttl != nil {
setMaxTTL(&msg, *ttl)
Expand Down
15 changes: 5 additions & 10 deletions dnscrypt-proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -713,17 +713,11 @@ func (proxy *Proxy) processIncomingQuery(
// Initialize plugin state
pluginsState := NewPluginsState(proxy, clientProto, clientAddr, serverProto, start)

// Get server info and initialize parameters
serverName := "-"
needsEDNS0Padding := false
serverInfo := proxy.serversInfo.getOne()
if serverInfo != nil {
serverName = serverInfo.Name
needsEDNS0Padding = (serverInfo.Proto == stamps.StampProtoTypeDoH || serverInfo.Proto == stamps.StampProtoTypeTLS)
}
// Apply query plugins and get server info
query, serverInfo, _ := pluginsState.ApplyQueryPlugins(&proxy.pluginsGlobals, query, func() *ServerInfo {
return proxy.serversInfo.getOne()
})

// Apply query plugins
query, _ = pluginsState.ApplyQueryPlugins(&proxy.pluginsGlobals, query, needsEDNS0Padding)
if !validateQuery(query) {
return response
}
Expand Down Expand Up @@ -754,6 +748,7 @@ func (proxy *Proxy) processIncomingQuery(

// Process query with a DNS server if there's no cached response
if len(response) == 0 && serverInfo != nil {
serverName := serverInfo.Name
pluginsState.serverName = serverName

// Exchange DNS request with the server
Expand Down