mirror of
https://github.com/safing/portmaster
synced 2025-09-01 18:19:12 +00:00
Use separate DNSRequestContext struct for adding DNS context to connections
This commit is contained in:
parent
49767d4c4a
commit
b9b33ed2b3
6 changed files with 59 additions and 42 deletions
|
@ -263,10 +263,10 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw
|
|||
|
||||
// Create new record for this IP.
|
||||
record := resolver.ResolvedDomain{
|
||||
Domain: q.FQDN,
|
||||
RRCache: rrCache,
|
||||
Resolver: rrCache.Resolver,
|
||||
Expires: rrCache.Expires,
|
||||
Domain: q.FQDN,
|
||||
Resolver: rrCache.Resolver,
|
||||
DNSRequestContext: rrCache.ToDNSRequestContext(),
|
||||
Expires: rrCache.Expires,
|
||||
}
|
||||
|
||||
// Resolve all CNAMEs in the correct order and add the to the record.
|
||||
|
|
|
@ -141,6 +141,12 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
|||
// Once we decided on the connection we might need to save it to the database,
|
||||
// so we defer that check for now.
|
||||
defer func() {
|
||||
// Add metadata to connection.
|
||||
if rrCache != nil {
|
||||
conn.DNSContext = rrCache.ToDNSRequestContext()
|
||||
conn.Resolver = rrCache.Resolver
|
||||
}
|
||||
|
||||
switch conn.Verdict {
|
||||
// We immediately save blocked, dropped or failed verdicts so
|
||||
// they pop up in the UI.
|
||||
|
@ -222,27 +228,19 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
|||
}
|
||||
}
|
||||
// Handle special cases.
|
||||
if rrCache == nil {
|
||||
switch {
|
||||
case rrCache == nil:
|
||||
tracer.Warning("nameserver: received successful, but empty reply from resolver")
|
||||
return reply(nsutil.ServerFailure("internal error: empty reply"))
|
||||
}
|
||||
|
||||
// Add dns context and resolver to connection.
|
||||
conn.DNSContext = rrCache
|
||||
conn.Resolver = rrCache.Resolver
|
||||
|
||||
// Return now if NXDomain.
|
||||
if rrCache.RCode == dns.RcodeNameError {
|
||||
case rrCache.RCode == dns.RcodeNameError:
|
||||
// Return now if NXDomain.
|
||||
return reply(nsutil.NxDomain("no answer found (NXDomain)"))
|
||||
}
|
||||
|
||||
// Check with firewall again after resolving.
|
||||
tracer.Trace("nameserver: deciding on resolved dns")
|
||||
rrCache = firewall.FilterResolvedDNS(ctx, conn, q, rrCache)
|
||||
|
||||
// Add dns context and resolver to connection.
|
||||
conn.DNSContext = rrCache
|
||||
conn.Resolver = rrCache.Resolver
|
||||
|
||||
// Check again if there is a responder from the firewall.
|
||||
if responder, ok := conn.Reason.Context.(nsutil.Responder); ok {
|
||||
tracer.Infof("nameserver: handing over request for %s to special filter responder: %s", q.ID(), conn.Reason.Msg)
|
||||
|
|
|
@ -145,7 +145,7 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
|||
ProcessContext ProcessContext
|
||||
// DNSContext holds additional information about the DNS request that was
|
||||
// probably used to resolve the IP of this connection.
|
||||
DNSContext *resolver.RRCache
|
||||
DNSContext *resolver.DNSRequestContext
|
||||
// TunnelContext holds additional information about the tunnel that this
|
||||
// connection is using.
|
||||
TunnelContext interface{}
|
||||
|
@ -333,7 +333,7 @@ func NewConnectionFromFirstPacket(pkt packet.Packet) *Connection {
|
|||
|
||||
var scope string
|
||||
var resolverInfo *resolver.ResolverInfo
|
||||
var dnsContext *resolver.RRCache
|
||||
var dnsContext *resolver.DNSRequestContext
|
||||
|
||||
if inbound {
|
||||
|
||||
|
@ -365,7 +365,7 @@ func NewConnectionFromFirstPacket(pkt packet.Packet) *Connection {
|
|||
scope = lastResolvedDomain.Domain
|
||||
entity.Domain = lastResolvedDomain.Domain
|
||||
entity.CNAME = lastResolvedDomain.CNAMEs
|
||||
dnsContext = lastResolvedDomain.RRCache
|
||||
dnsContext = lastResolvedDomain.DNSRequestContext
|
||||
resolverInfo = lastResolvedDomain.Resolver
|
||||
removeOpenDNSRequest(proc.Pid, lastResolvedDomain.Domain)
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ type ResolvedDomain struct {
|
|||
// information.
|
||||
Resolver *ResolverInfo
|
||||
|
||||
// RRCache holds the DNS response that was received for this domain.
|
||||
RRCache *RRCache
|
||||
// DNSRequestContext holds the DNS request context.
|
||||
DNSRequestContext *DNSRequestContext
|
||||
|
||||
// Expires holds the timestamp when this entry expires.
|
||||
// This does not mean that the entry may not be used anymore afterwards,
|
||||
|
|
39
resolver/rr_context.go
Normal file
39
resolver/rr_context.go
Normal file
|
@ -0,0 +1,39 @@
|
|||
package resolver
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// DNSRequestContext is a static structure to add information to DNS request connections.
|
||||
type DNSRequestContext struct {
|
||||
Domain string
|
||||
Question string
|
||||
RCode string
|
||||
|
||||
ServedFromCache bool
|
||||
RequestingNew bool
|
||||
IsBackup bool
|
||||
Filtered bool
|
||||
|
||||
Modified time.Time
|
||||
Expires time.Time
|
||||
}
|
||||
|
||||
// ToDNSRequestContext returns a new DNSRequestContext of the RRCache.
|
||||
func (rrCache *RRCache) ToDNSRequestContext() *DNSRequestContext {
|
||||
return &DNSRequestContext{
|
||||
Domain: rrCache.Domain,
|
||||
Question: rrCache.Question.String(),
|
||||
RCode: dns.RcodeToString[rrCache.RCode],
|
||||
|
||||
ServedFromCache: rrCache.ServedFromCache,
|
||||
RequestingNew: rrCache.RequestingNew,
|
||||
IsBackup: rrCache.IsBackup,
|
||||
Filtered: rrCache.Filtered,
|
||||
|
||||
Modified: time.Unix(rrCache.Modified, 0),
|
||||
Expires: time.Unix(rrCache.Expires, 0),
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package resolver
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
@ -45,25 +44,6 @@ type RRCache struct {
|
|||
Modified int64
|
||||
}
|
||||
|
||||
func (rrCache *RRCache) MarshalJSON() ([]byte, error) {
|
||||
var record = struct {
|
||||
RRCache
|
||||
|
||||
Question string
|
||||
RCode string
|
||||
Modified time.Time
|
||||
Expires time.Time
|
||||
}{
|
||||
RRCache: *rrCache,
|
||||
Question: rrCache.Question.String(),
|
||||
RCode: dns.RcodeToString[rrCache.RCode],
|
||||
Modified: time.Unix(rrCache.Modified, 0),
|
||||
Expires: time.Unix(rrCache.Expires, 0),
|
||||
}
|
||||
|
||||
return json.Marshal(record)
|
||||
}
|
||||
|
||||
// ID returns the ID of the RRCache consisting of the domain and question type.
|
||||
func (rrCache *RRCache) ID() string {
|
||||
return rrCache.Domain + rrCache.Question.String()
|
||||
|
|
Loading…
Add table
Reference in a new issue