Feature/systemd query events (#1728)

* [service] Subscribe to systemd-resolver events

* [service] Add disabled state to the resolver

* [service] Add ETW DNS event listener

* [service] DNS listener refactoring

* [service] Add windows core dll project

* [service] DNSListener refactoring, small bugfixes

* [service] Change dns bypass rule

* [service] Update gitignore

* [service] Remove shim from integration module

* [service] Add DNS packet analyzer

* [service] Add self-check in dns monitor

* [service] Fix go linter errors

* [CI] Add github workflow for the windows core dll

* [service] Minor fixes to the dns monitor
This commit is contained in:
Vladimir Stoilov
2024-11-27 17:10:47 +02:00
committed by GitHub
parent 943b9b7859
commit 1a1bc14804
41 changed files with 1668 additions and 51 deletions

View File

@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"runtime"
"sync"
"sync/atomic"
"time"
@@ -18,6 +19,7 @@ import (
"github.com/safing/portmaster/service/netenv"
"github.com/safing/portmaster/service/network/netutils"
"github.com/safing/portmaster/service/network/packet"
"github.com/safing/portmaster/service/network/reference"
"github.com/safing/portmaster/service/process"
_ "github.com/safing/portmaster/service/process/tags"
"github.com/safing/portmaster/service/resolver"
@@ -542,6 +544,23 @@ func (conn *Connection) GatherConnectionInfo(pkt packet.Packet) (err error) {
// Try again with the global scope, in case DNS went through the system resolver.
ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String())
}
if runtime.GOOS == "windows" && err != nil {
// On windows domains may come with delay.
if module.instance.Resolver().IsDisabled() && conn.shouldWaitForDomain() {
// Flush the dns listener buffer and try again.
for i := range 4 {
_ = module.instance.DNSMonitor().Flush()
ipinfo, err = resolver.GetIPInfo(resolver.IPInfoProfileScopeGlobal, pkt.Info().RemoteIP().String())
if err == nil {
log.Tracer(pkt.Ctx()).Debugf("network: found domain from dnsmonitor after %d tries", i+1)
break
}
time.Sleep(5 * time.Millisecond)
}
}
}
if err == nil {
lastResolvedDomain := ipinfo.MostRecentDomain()
if lastResolvedDomain != nil {
@@ -869,3 +888,17 @@ func (conn *Connection) String() string {
return fmt.Sprintf("%s -> %s", conn.process, conn.Entity.IP)
}
}
func (conn *Connection) shouldWaitForDomain() bool {
// Should wait for Global Unicast, outgoing and not ICMP connections
switch {
case conn.Entity.IPScope != netutils.Global:
return false
case conn.Inbound:
return false
case reference.IsICMP(conn.Entity.Protocol):
return false
}
return true
}