mirror of
https://github.com/safing/portmaster
synced 2025-09-04 11:39:29 +00:00
Fix nameserver takeover loop
This commit is contained in:
parent
11893a780a
commit
b2a1956e5c
1 changed files with 46 additions and 9 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
"github.com/safing/portbase/modules"
|
"github.com/safing/portbase/modules"
|
||||||
|
@ -13,13 +14,20 @@ import (
|
||||||
"github.com/safing/portmaster/network/state"
|
"github.com/safing/portmaster/network/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var commonResolverIPs = []net.IP{
|
var (
|
||||||
net.IPv4zero,
|
commonResolverIPs = []net.IP{
|
||||||
net.IPv4(127, 0, 0, 1), // default
|
net.IPv4zero,
|
||||||
net.IPv4(127, 0, 0, 53), // some resolvers on Linux
|
net.IPv4(127, 0, 0, 1), // default
|
||||||
net.IPv6zero,
|
net.IPv4(127, 0, 0, 53), // some resolvers on Linux
|
||||||
net.IPv6loopback,
|
net.IPv6zero,
|
||||||
}
|
net.IPv6loopback,
|
||||||
|
}
|
||||||
|
|
||||||
|
// lastKilledPID holds the PID of the last killed conflicting service.
|
||||||
|
// It is only accessed by checkForConflictingService, which is only called by
|
||||||
|
// the nameserver worker.
|
||||||
|
lastKilledPID int
|
||||||
|
)
|
||||||
|
|
||||||
func checkForConflictingService(ip net.IP, port uint16) error {
|
func checkForConflictingService(ip net.IP, port uint16) error {
|
||||||
// Evaluate which IPs to check.
|
// Evaluate which IPs to check.
|
||||||
|
@ -32,14 +40,16 @@ func checkForConflictingService(ip net.IP, port uint16) error {
|
||||||
|
|
||||||
// Check if there is another resolver when need to take over.
|
// Check if there is another resolver when need to take over.
|
||||||
var killed int
|
var killed int
|
||||||
|
var killingFailed bool
|
||||||
ipsToCheckLoop:
|
ipsToCheckLoop:
|
||||||
for _, resolverIP := range ipsToCheck {
|
for _, resolverIP := range ipsToCheck {
|
||||||
pid, err := takeover(resolverIP, port)
|
pid, err := takeover(resolverIP, port)
|
||||||
switch {
|
switch {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
// Log the error and let the worker try again.
|
// Log the error and let the worker try again.
|
||||||
log.Infof("nameserver: could not stop conflicting service: %s", err)
|
log.Infof("nameserver: failed to stop conflicting service: %s", err)
|
||||||
return nil
|
killingFailed = true
|
||||||
|
break ipsToCheckLoop
|
||||||
case pid != 0:
|
case pid != 0:
|
||||||
// Conflicting service identified and killed!
|
// Conflicting service identified and killed!
|
||||||
killed = pid
|
killed = pid
|
||||||
|
@ -47,10 +57,35 @@ ipsToCheckLoop:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify user of failed killing or repeated kill.
|
||||||
|
if killingFailed || (killed != 0 && killed == lastKilledPID) {
|
||||||
|
// Notify the user that we failed to kill something.
|
||||||
|
notifications.Notify(¬ifications.Notification{
|
||||||
|
EventID: "namserver:failed-to-kill-conflicting-service",
|
||||||
|
Type: notifications.Error,
|
||||||
|
Title: "Failed to Stop Conflicting DNS Client",
|
||||||
|
Message: "The Portmaster failed to stop a conflicting DNS client to gain required system integration. If there is another DNS Client (Nameserver; Resolver) on this device, please disable it.",
|
||||||
|
ShowOnSystem: true,
|
||||||
|
AvailableActions: []*notifications.Action{
|
||||||
|
{
|
||||||
|
ID: "ack",
|
||||||
|
Text: "OK",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Text: "Open Docs",
|
||||||
|
Type: notifications.ActionTypeOpenURL,
|
||||||
|
Payload: "https://docs.safing.io/portmaster/install/status/software-compatibility",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Check if something was killed.
|
// Check if something was killed.
|
||||||
if killed == 0 {
|
if killed == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
lastKilledPID = killed
|
||||||
|
|
||||||
// Notify the user that we killed something.
|
// Notify the user that we killed something.
|
||||||
notifications.Notify(¬ifications.Notification{
|
notifications.Notify(¬ifications.Notification{
|
||||||
|
@ -76,6 +111,8 @@ ipsToCheckLoop:
|
||||||
})
|
})
|
||||||
|
|
||||||
// Restart nameserver via service-worker logic.
|
// Restart nameserver via service-worker logic.
|
||||||
|
// Wait shortly so that the other process can shut down.
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
return fmt.Errorf("%w: stopped conflicting name service with pid %d", modules.ErrRestartNow, killed)
|
return fmt.Errorf("%w: stopped conflicting name service with pid %d", modules.ErrRestartNow, killed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue