Working on portmaster restructure
This commit is contained in:
@@ -27,6 +27,7 @@ type NameRecord struct {
|
||||
Ns []string
|
||||
Extra []string
|
||||
TTL int64
|
||||
Filtered bool
|
||||
}
|
||||
|
||||
func makeNameRecordKey(domain string, question string) string {
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/Safing/portbase/database"
|
||||
"github.com/Safing/portbase/log"
|
||||
"github.com/Safing/portmaster/network/netutils"
|
||||
"github.com/Safing/portmaster/status"
|
||||
)
|
||||
|
||||
@@ -76,26 +77,6 @@ func Resolve(fqdn string, qtype dns.Type, securityLevel uint8) *RRCache {
|
||||
// timed := time.Now()
|
||||
// defer log.Tracef("intel: took %s to get resolve %s%s", time.Now().Sub(timed).String(), fqdn, qtype.String())
|
||||
|
||||
// handle request for localhost
|
||||
if fqdn == "localhost." {
|
||||
var rr dns.RR
|
||||
var err error
|
||||
switch uint16(qtype) {
|
||||
case dns.TypeA:
|
||||
rr, err = dns.NewRR("localhost. 17 IN A 127.0.0.1")
|
||||
case dns.TypeAAAA:
|
||||
rr, err = dns.NewRR("localhost. 17 IN AAAA ::1")
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &RRCache{
|
||||
Answer: []dns.RR{rr},
|
||||
}
|
||||
}
|
||||
|
||||
// check cache
|
||||
rrCache, err := GetRRCache(fqdn, qtype)
|
||||
if err != nil {
|
||||
@@ -322,6 +303,14 @@ func tryResolver(resolver *Resolver, lastFailBoundary int64, fqdn string, qtype
|
||||
return nil, false
|
||||
}
|
||||
resolver.Initialized.SetToIf(false, true)
|
||||
|
||||
// remove localhost entries, remove LAN entries if server is in global IP space.
|
||||
if resolver.ServerIPScope == netutils.Global {
|
||||
rrCache.FilterEntries(true, false, false)
|
||||
} else {
|
||||
rrCache.FilterEntries(true, true, false)
|
||||
}
|
||||
|
||||
return rrCache, true
|
||||
}
|
||||
|
||||
@@ -368,11 +357,11 @@ func query(resolver *Resolver, fqdn string, qtype dns.Type) (*RRCache, error) {
|
||||
}
|
||||
|
||||
new := &RRCache{
|
||||
Domain: fqdn,
|
||||
Domain: fqdn,
|
||||
Question: qtype,
|
||||
Answer: reply.Answer,
|
||||
Ns: reply.Ns,
|
||||
Extra: reply.Extra,
|
||||
Answer: reply.Answer,
|
||||
Ns: reply.Ns,
|
||||
Extra: reply.Extra,
|
||||
}
|
||||
|
||||
// TODO: check if reply.Answer is valid
|
||||
|
||||
@@ -26,6 +26,7 @@ type Resolver struct {
|
||||
ServerType string
|
||||
ServerAddress string
|
||||
ServerIP net.IP
|
||||
ServerIPScope int8
|
||||
ServerPort uint16
|
||||
VerifyDomain string
|
||||
Source string
|
||||
@@ -151,6 +152,7 @@ configuredServersLoop:
|
||||
ServerType: parts[0],
|
||||
ServerAddress: parts[1],
|
||||
ServerIP: ip,
|
||||
ServerIPScope: netutils.ClassifyAddress(ip),
|
||||
ServerPort: port,
|
||||
LastFail: &lastFail,
|
||||
Source: "config",
|
||||
@@ -205,6 +207,7 @@ assignedServersLoop:
|
||||
ServerType: "dns",
|
||||
ServerAddress: urlFormatAddress(nameserver.IP, 53),
|
||||
ServerIP: nameserver.IP,
|
||||
ServerIPScope: netutils.ClassifyAddress(nameserver.IP),
|
||||
ServerPort: 53,
|
||||
LastFail: &lastFail,
|
||||
Source: "dhcp",
|
||||
@@ -213,7 +216,7 @@ assignedServersLoop:
|
||||
}
|
||||
new.clientManager = newDNSClientManager(new)
|
||||
|
||||
if netutils.IPIsLocal(nameserver.IP) && len(nameserver.Search) > 0 {
|
||||
if netutils.IPIsLAN(nameserver.IP) && len(nameserver.Search) > 0 {
|
||||
// only allow searches for local resolvers
|
||||
var newSearch []string
|
||||
for _, value := range nameserver.Search {
|
||||
@@ -236,7 +239,7 @@ assignedServersLoop:
|
||||
// make list with local resolvers
|
||||
localResolvers = make([]*Resolver, 0)
|
||||
for _, resolver := range globalResolvers {
|
||||
if resolver.ServerIP != nil && netutils.IPIsLocal(resolver.ServerIP) {
|
||||
if resolver.ServerIP != nil && netutils.IPIsLAN(resolver.ServerIP) {
|
||||
localResolvers = append(localResolvers, resolver)
|
||||
}
|
||||
}
|
||||
|
||||
110
intel/rrcache.go
110
intel/rrcache.go
@@ -3,9 +3,13 @@
|
||||
package intel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Safing/portbase/log"
|
||||
"github.com/Safing/portmaster/network/netutils"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
@@ -22,6 +26,7 @@ type RRCache struct {
|
||||
updated int64
|
||||
servedFromCache bool
|
||||
requestingNew bool
|
||||
Filtered bool
|
||||
}
|
||||
|
||||
// Clean sets all TTLs to 17 and sets cache expiry with specified minimum.
|
||||
@@ -77,6 +82,7 @@ func (m *RRCache) ToNameRecord() *NameRecord {
|
||||
Domain: m.Domain,
|
||||
Question: m.Question.String(),
|
||||
TTL: m.TTL,
|
||||
Filtered: m.Filtered,
|
||||
}
|
||||
|
||||
// stringify RR entries
|
||||
@@ -130,6 +136,7 @@ func GetRRCache(domain string, question dns.Type) (*RRCache, error) {
|
||||
}
|
||||
}
|
||||
|
||||
rrCache.Filtered = nameRecord.Filtered
|
||||
rrCache.servedFromCache = true
|
||||
return rrCache, nil
|
||||
}
|
||||
@@ -146,19 +153,104 @@ func (m *RRCache) RequestingNew() bool {
|
||||
|
||||
// Flags formats ServedFromCache and RequestingNew to a condensed, flag-like format.
|
||||
func (m *RRCache) Flags() string {
|
||||
switch {
|
||||
case m.servedFromCache && m.requestingNew:
|
||||
return " [CR]"
|
||||
case m.servedFromCache:
|
||||
return " [C]"
|
||||
case m.requestingNew:
|
||||
return " [R]" // should never enter this state, but let's leave it here, just in case
|
||||
default:
|
||||
return ""
|
||||
var s string
|
||||
if m.servedFromCache {
|
||||
s += "C"
|
||||
}
|
||||
if m.requestingNew {
|
||||
s += "R"
|
||||
}
|
||||
if m.Filtered {
|
||||
s += "F"
|
||||
}
|
||||
|
||||
if s != "" {
|
||||
return fmt.Sprintf(" [%s]", s)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// IsNXDomain returnes whether the result is nxdomain.
|
||||
func (m *RRCache) IsNXDomain() bool {
|
||||
return len(m.Answer) == 0
|
||||
}
|
||||
|
||||
// Duplicate returns a duplicate of the cache. slices are not copied, but referenced.
|
||||
func (m *RRCache) Duplicate() *RRCache {
|
||||
return &RRCache{
|
||||
Domain: m.Domain,
|
||||
Question: m.Question,
|
||||
Answer: m.Answer,
|
||||
Ns: m.Ns,
|
||||
Extra: m.Extra,
|
||||
TTL: m.TTL,
|
||||
updated: m.updated,
|
||||
servedFromCache: m.servedFromCache,
|
||||
requestingNew: m.requestingNew,
|
||||
Filtered: m.Filtered,
|
||||
}
|
||||
}
|
||||
|
||||
// FilterEntries filters resource records according to the given permission scope.
|
||||
func (m *RRCache) FilterEntries(internet, lan, host bool) {
|
||||
var filtered bool
|
||||
|
||||
m.Answer, filtered = filterEntries(m, m.Answer, internet, lan, host)
|
||||
if filtered {
|
||||
m.Filtered = true
|
||||
}
|
||||
m.Extra, filtered = filterEntries(m, m.Extra, internet, lan, host)
|
||||
if filtered {
|
||||
m.Filtered = true
|
||||
}
|
||||
}
|
||||
|
||||
func filterEntries(m *RRCache, entries []dns.RR, internet, lan, host bool) (filteredEntries []dns.RR, filtered bool) {
|
||||
filteredEntries = make([]dns.RR, 0, len(entries))
|
||||
var classification int8
|
||||
var deletedEntries []string
|
||||
|
||||
entryLoop:
|
||||
for _, rr := range entries {
|
||||
|
||||
classification = -1
|
||||
switch v := rr.(type) {
|
||||
case *dns.A:
|
||||
classification = netutils.ClassifyAddress(v.A)
|
||||
case *dns.AAAA:
|
||||
classification = netutils.ClassifyAddress(v.AAAA)
|
||||
}
|
||||
|
||||
if classification >= 0 {
|
||||
switch {
|
||||
case !internet && classification == netutils.Global:
|
||||
filtered = true
|
||||
deletedEntries = append(deletedEntries, rr.String())
|
||||
continue entryLoop
|
||||
case !lan && (classification == netutils.SiteLocal || classification == netutils.LinkLocal):
|
||||
filtered = true
|
||||
deletedEntries = append(deletedEntries, rr.String())
|
||||
continue entryLoop
|
||||
case !host && classification == netutils.HostLocal:
|
||||
filtered = true
|
||||
deletedEntries = append(deletedEntries, rr.String())
|
||||
continue entryLoop
|
||||
}
|
||||
}
|
||||
|
||||
filteredEntries = append(filteredEntries, rr)
|
||||
}
|
||||
|
||||
if len(deletedEntries) > 0 {
|
||||
log.Infof("intel: filtered DNS replies for %s%s: %s (Settings: Int=%v LAN=%v Host=%v)",
|
||||
m.Domain,
|
||||
m.Question.String(),
|
||||
strings.Join(deletedEntries, ", "),
|
||||
internet,
|
||||
lan,
|
||||
host,
|
||||
)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user