mirror of
https://github.com/safing/portmaster
synced 2025-09-02 02:29:12 +00:00
Merge pull request #1272 from safing/fix/connection-handling
Fix connection handlings
This commit is contained in:
commit
93756e5fd8
25 changed files with 211 additions and 137 deletions
|
@ -16,7 +16,7 @@ var (
|
|||
module *modules.Module
|
||||
|
||||
selfcheckTask *modules.Task
|
||||
selfcheckTaskRetryAfter = 5 * time.Second
|
||||
selfcheckTaskRetryAfter = 15 * time.Second
|
||||
|
||||
// selfCheckIsFailing holds whether or not the self-check is currently
|
||||
// failing. This helps other failure systems to not make noise when there is
|
||||
|
@ -34,7 +34,7 @@ var (
|
|||
|
||||
// selfcheckFailThreshold holds the threshold of how many times the selfcheck
|
||||
// must fail before it is reported.
|
||||
const selfcheckFailThreshold = 5
|
||||
const selfcheckFailThreshold = 10
|
||||
|
||||
func init() {
|
||||
module = modules.Register("compat", prep, start, stop, "base", "network", "interception", "netenv", "notifications")
|
||||
|
@ -60,7 +60,7 @@ func start() error {
|
|||
Schedule(time.Now().Add(selfcheckTaskRetryAfter))
|
||||
|
||||
module.NewTask("clean notify thresholds", cleanNotifyThreshold).
|
||||
Repeat(10 * time.Minute)
|
||||
Repeat(1 * time.Hour)
|
||||
|
||||
return module.RegisterEventHook(
|
||||
netenv.ModuleName,
|
||||
|
|
|
@ -236,7 +236,7 @@ func (issue *appIssue) notify(proc *process.Process) {
|
|||
}
|
||||
|
||||
const (
|
||||
notifyThresholdMinIncidents = 11
|
||||
notifyThresholdMinIncidents = 10
|
||||
notifyThresholdResetAfter = 2 * time.Minute
|
||||
)
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ var (
|
|||
systemIntegrationCheckDialNet = fmt.Sprintf("ip4:%d", uint8(SystemIntegrationCheckProtocol))
|
||||
systemIntegrationCheckDialIP = SystemIntegrationCheckDstIP.String()
|
||||
systemIntegrationCheckPackets = make(chan packet.Packet, 1)
|
||||
systemIntegrationCheckWaitDuration = 40 * time.Second
|
||||
systemIntegrationCheckWaitDuration = 45 * time.Second
|
||||
|
||||
// DNSCheckInternalDomainScope is the domain scope to use for dns checks.
|
||||
DNSCheckInternalDomainScope = ".self-check." + resolver.InternalSpecialUseDomain
|
||||
dnsCheckReceivedDomain = make(chan string, 1)
|
||||
dnsCheckWaitDuration = 40 * time.Second
|
||||
dnsCheckWaitDuration = 45 * time.Second
|
||||
dnsCheckAnswerLock sync.Mutex
|
||||
dnsCheckAnswer net.IP
|
||||
)
|
||||
|
|
|
@ -224,7 +224,7 @@ func authorizeApp(ar *api.Request) (interface{}, error) {
|
|||
Title: "An app requests access to the Portmaster",
|
||||
Message: "Allow " + appName + " (" + proc.Profile().LocalProfile().Name + ") to query and modify the Portmaster?\n\nBinary: " + proc.Path,
|
||||
ShowOnSystem: true,
|
||||
Expires: time.Now().Add(time.Minute).UnixNano(),
|
||||
Expires: time.Now().Add(time.Minute).Unix(),
|
||||
AvailableActions: []*notifications.Action{
|
||||
{
|
||||
ID: "allow",
|
||||
|
|
|
@ -45,6 +45,7 @@ func filterDNSSection(
|
|||
ip = v.AAAA
|
||||
default:
|
||||
// add non A/AAAA entries
|
||||
// TODO: Add support for dns.SVCB and dns.HTTPS
|
||||
goodEntries = append(goodEntries, rr)
|
||||
continue
|
||||
}
|
||||
|
@ -257,6 +258,32 @@ func UpdateIPsAndCNAMEs(q *resolver.Query, rrCache *resolver.RRCache, conn *netw
|
|||
|
||||
case *dns.AAAA:
|
||||
ips = append(ips, v.AAAA)
|
||||
|
||||
case *dns.SVCB:
|
||||
if len(v.Target) >= 2 { // Ignore "" and ".".
|
||||
cnames[v.Hdr.Name] = v.Target
|
||||
}
|
||||
for _, pair := range v.Value {
|
||||
switch svcbParam := pair.(type) {
|
||||
case *dns.SVCBIPv4Hint:
|
||||
ips = append(ips, svcbParam.Hint...)
|
||||
case *dns.SVCBIPv6Hint:
|
||||
ips = append(ips, svcbParam.Hint...)
|
||||
}
|
||||
}
|
||||
|
||||
case *dns.HTTPS:
|
||||
if len(v.Target) >= 2 { // Ignore "" and ".".
|
||||
cnames[v.Hdr.Name] = v.Target
|
||||
}
|
||||
for _, pair := range v.Value {
|
||||
switch svcbParam := pair.(type) {
|
||||
case *dns.SVCBIPv4Hint:
|
||||
ips = append(ips, svcbParam.Hint...)
|
||||
case *dns.SVCBIPv6Hint:
|
||||
ips = append(ips, svcbParam.Hint...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -105,7 +105,7 @@ int BPF_PROG(udp_sendmsg, struct sock *sk, struct msghdr *msg, size_t len) {
|
|||
struct sock_common *skc = &sk->__sk_common;
|
||||
|
||||
// Create a key for the map and set all the nececery information.
|
||||
struct sk_key key = {0};
|
||||
struct sk_key key = {0};
|
||||
key.protocol = PROTOCOL_UDP;
|
||||
key.src_ip[0] = skc->skc_rcv_saddr;
|
||||
key.dst_ip[0] = skc->skc_daddr;
|
||||
|
@ -134,7 +134,7 @@ int BPF_PROG(udp_recvmsg, struct sock *sk, struct msghdr *msg, size_t len, int f
|
|||
struct sock_common *skc = &sk->__sk_common;
|
||||
|
||||
// Create a key for the map and set all the nececery information.
|
||||
struct sk_key key = {0};
|
||||
struct sk_key key = {0};
|
||||
key.protocol = PROTOCOL_UDP;
|
||||
key.src_ip[0] = skc->skc_rcv_saddr;
|
||||
key.dst_ip[0] = skc->skc_daddr;
|
||||
|
|
|
@ -76,7 +76,7 @@ int BPF_PROG(tcp_connect, struct sock *sk) {
|
|||
tcp_info->ipVersion = 6;
|
||||
}
|
||||
|
||||
// Send event
|
||||
// Send event
|
||||
bpf_ringbuf_submit(tcp_info, 0);
|
||||
return 0;
|
||||
};
|
||||
|
@ -95,15 +95,15 @@ int BPF_PROG(udp_v4_connect, struct sock *sk) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Allocate space for the event.
|
||||
// Allocate space for the event.
|
||||
struct Event *udp_info;
|
||||
udp_info = bpf_ringbuf_reserve(&pm_connection_events, sizeof(struct Event), 0);
|
||||
if (!udp_info) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read PID
|
||||
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||
// Read PID (Careful: This is the Thread Group ID in kernel speak!)
|
||||
udp_info->pid = __builtin_bswap32((u32)(bpf_get_current_pid_tgid() >> 32));
|
||||
|
||||
// Set src and dist ports
|
||||
udp_info->sport = __builtin_bswap16(sk->__sk_common.skc_num);
|
||||
|
@ -119,7 +119,7 @@ int BPF_PROG(udp_v4_connect, struct sock *sk) {
|
|||
// Set protocol. No way to detect udplite for ipv4
|
||||
udp_info->protocol = UDP;
|
||||
|
||||
// Send event
|
||||
// Send event
|
||||
bpf_ringbuf_submit(udp_info, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -138,21 +138,21 @@ int BPF_PROG(udp_v6_connect, struct sock *sk) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Make sure its udp6 socket
|
||||
// Make sure its udp6 socket
|
||||
struct udp6_sock *us = bpf_skc_to_udp6_sock(sk);
|
||||
if (!us) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate space for the event.
|
||||
// Allocate space for the event.
|
||||
struct Event *udp_info;
|
||||
udp_info = bpf_ringbuf_reserve(&pm_connection_events, sizeof(struct Event), 0);
|
||||
if (!udp_info) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read PID
|
||||
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||
// Read PID (Careful: This is the Thread Group ID in kernel speak!)
|
||||
udp_info->pid = __builtin_bswap32((u32)(bpf_get_current_pid_tgid() >> 32));
|
||||
|
||||
// Set src and dist ports
|
||||
udp_info->sport = __builtin_bswap16(sk->__sk_common.skc_num);
|
||||
|
@ -176,7 +176,7 @@ int BPF_PROG(udp_v6_connect, struct sock *sk) {
|
|||
udp_info->protocol = UDPLite;
|
||||
}
|
||||
|
||||
// Send event
|
||||
// Send event
|
||||
bpf_ringbuf_submit(udp_info, 0);
|
||||
return 0;
|
||||
}
|
|
@ -628,9 +628,9 @@ func bandwidthUpdateHandler(ctx context.Context) error {
|
|||
return nil
|
||||
case bwUpdate := <-interception.BandwidthUpdates:
|
||||
if bwUpdate != nil {
|
||||
updateBandwidth(ctx, bwUpdate)
|
||||
// DEBUG:
|
||||
// log.Debugf("filter: bandwidth update: %s", bwUpdate)
|
||||
updateBandwidth(ctx, bwUpdate)
|
||||
} else {
|
||||
return errors.New("received nil bandwidth update from interception")
|
||||
}
|
||||
|
@ -653,6 +653,8 @@ func updateBandwidth(ctx context.Context, bwUpdate *packet.BandwidthUpdate) {
|
|||
// Do not wait for connections that are locked.
|
||||
// TODO: Use atomic operations for updating bandwidth stats.
|
||||
if !conn.TryLock() {
|
||||
// DEBUG:
|
||||
// log.Warningf("filter: failed to lock connection for bandwidth update: %s", conn)
|
||||
return
|
||||
}
|
||||
defer conn.Unlock()
|
||||
|
@ -675,7 +677,7 @@ func updateBandwidth(ctx context.Context, bwUpdate *packet.BandwidthUpdate) {
|
|||
if err := netquery.DefaultModule.Store.UpdateBandwidth(
|
||||
ctx,
|
||||
conn.HistoryEnabled,
|
||||
conn.Process().GetID(),
|
||||
conn.Process().GetKey(),
|
||||
conn.ID,
|
||||
conn.BytesReceived,
|
||||
conn.BytesSent,
|
||||
|
|
18
go.mod
18
go.mod
|
@ -1,11 +1,11 @@
|
|||
module github.com/safing/portmaster
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/agext/levenshtein v1.2.3
|
||||
github.com/cilium/ebpf v0.11.0
|
||||
github.com/coreos/go-iptables v0.6.0
|
||||
github.com/coreos/go-iptables v0.7.0
|
||||
github.com/florianl/go-conntrack v0.4.0
|
||||
github.com/florianl/go-nfqueue v1.3.1
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
|
@ -16,9 +16,9 @@ require (
|
|||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/jackc/puddle/v2 v2.2.1
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/oschwald/maxminddb-golang v1.11.0
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
github.com/safing/jess v0.3.1
|
||||
github.com/safing/portbase v0.17.0
|
||||
github.com/safing/portbase v0.17.1
|
||||
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626
|
||||
github.com/safing/spn v0.6.10
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
|
@ -28,10 +28,10 @@ require (
|
|||
github.com/tannerryan/ring v1.1.2
|
||||
github.com/tevino/abool v1.2.0
|
||||
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1
|
||||
golang.org/x/net v0.12.0
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
|
||||
golang.org/x/net v0.13.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/sys v0.10.0
|
||||
golang.org/x/sys v0.11.0
|
||||
zombiezen.com/go/sqlite v0.13.0
|
||||
)
|
||||
|
||||
|
@ -89,12 +89,12 @@ require (
|
|||
golang.org/x/crypto v0.11.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.11.0 // indirect
|
||||
golang.org/x/tools v0.11.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 // indirect
|
||||
modernc.org/libc v1.24.1 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.6.0 // indirect
|
||||
modernc.org/sqlite v1.24.0 // indirect
|
||||
modernc.org/sqlite v1.25.0 // indirect
|
||||
)
|
||||
|
|
30
go.sum
30
go.sum
|
@ -36,8 +36,8 @@ github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y=
|
|||
github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
|
||||
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
|
||||
github.com/coreos/go-iptables v0.7.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
|
@ -186,8 +186,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx
|
|||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0=
|
||||
github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -208,6 +208,8 @@ github.com/safing/portbase v0.15.2/go.mod h1:5bHi99fz7Hh/wOsZUOI631WF9ePSHk57c4f
|
|||
github.com/safing/portbase v0.16.2/go.mod h1:mzNCWqPbO7vIYbbK5PElGbudwd2vx4YPNawymL8Aro8=
|
||||
github.com/safing/portbase v0.17.0 h1:RsDzbCGxRIbgaArri3y7MZskfxytEvvkzJpiboDUERQ=
|
||||
github.com/safing/portbase v0.17.0/go.mod h1:eKCRqsfMFLVhNpd2sY/fKvnbuk+LrIYnQEZCg1i86Ho=
|
||||
github.com/safing/portbase v0.17.1 h1:q2aNHjJw4aoqTqKOxZpxRhYCciHw1exZ7lfGuB78i1E=
|
||||
github.com/safing/portbase v0.17.1/go.mod h1:1cVgDZIsPiqM5b+K88Kshir5PGIvsftYkx7y1x925+8=
|
||||
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626 h1:olc/REnUdpJN/Gmz8B030OxLpMYxyPDTrDILNEw0eKs=
|
||||
github.com/safing/portmaster-android/go v0.0.0-20230605085256-6abf4c495626/go.mod h1:abwyAQrZGemWbSh/aCD9nnkp0SvFFf/mGWkAbOwPnFE=
|
||||
github.com/safing/spn v0.6.10 h1:4fFBb7UvUzoCcOSd8immOz1Buiuasy5C1/lxfVFacBQ=
|
||||
|
@ -307,8 +309,8 @@ golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0
|
|||
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
|
||||
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
|
@ -338,8 +340,8 @@ golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||
golang.org/x/net v0.0.0-20220107192237-5cfca573fb4d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY=
|
||||
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -391,8 +393,8 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
@ -408,8 +410,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
|
||||
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
||||
golang.org/x/tools v0.11.1 h1:ojD5zOW8+7dOGzdnNgersm8aPfcDjhMp12UfG93NIMc=
|
||||
golang.org/x/tools v0.11.1/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -438,7 +440,7 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
|||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
|
||||
modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.24.0 h1:EsClRIWHGhLTCX44p+Ri/JLD+vFGo0QGjasg2/F9TlI=
|
||||
modernc.org/sqlite v1.24.0/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
|
||||
modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
|
||||
zombiezen.com/go/sqlite v0.13.0 h1:iEeyVqcm3fk5PCA8OQBhBxPnqrP4yYuVJBF+XZpSnOE=
|
||||
zombiezen.com/go/sqlite v0.13.0/go.mod h1:Ht/5Rg3Ae2hoyh1I7gbWtWAl89CNocfqeb/aAMTkJr4=
|
||||
|
|
|
@ -60,6 +60,7 @@ type Entity struct { //nolint:maligned
|
|||
IP net.IP
|
||||
|
||||
// IPScope holds the network scope of the IP.
|
||||
// For DNS requests, this signifies in which scope the DNS request was resolved.
|
||||
IPScope netutils.IPScope
|
||||
|
||||
// Country holds the country the IP address (ASN) is
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
var hostname string
|
||||
|
||||
func handleRequestAsWorker(w dns.ResponseWriter, query *dns.Msg) {
|
||||
err := module.RunWorker("dns request", func(ctx context.Context) error {
|
||||
err := module.RunWorker("handle dns request", func(ctx context.Context) error {
|
||||
return handleRequest(ctx, w, query)
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -187,6 +187,13 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
|||
if rrCache != nil {
|
||||
conn.DNSContext = rrCache.ToDNSRequestContext()
|
||||
conn.Resolver = rrCache.Resolver
|
||||
conn.Entity.IPScope = rrCache.Resolver.IPScope
|
||||
} else {
|
||||
// Get resolvers for this query to determine the resolving scope.
|
||||
resolvers, _, _ := resolver.GetResolversInScope(ctx, q)
|
||||
if len(resolvers) > 0 {
|
||||
conn.Entity.IPScope = resolvers[0].Info.IPScope
|
||||
}
|
||||
}
|
||||
|
||||
switch conn.Verdict.Active {
|
||||
|
@ -297,11 +304,14 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
|
|||
return reply(nsutil.ServerFailure("internal error: empty reply"))
|
||||
case rrCache.RCode == dns.RcodeNameError:
|
||||
// Try alternatives domain names for unofficial domain spaces.
|
||||
rrCache = checkAlternativeCaches(ctx, q)
|
||||
if rrCache == nil {
|
||||
altRRCache := checkAlternativeCaches(ctx, q)
|
||||
if altRRCache != nil {
|
||||
rrCache = altRRCache
|
||||
} else {
|
||||
// Return now if NXDomain.
|
||||
return reply(nsutil.NxDomain("no answer found (NXDomain)"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Check with firewall again after resolving.
|
||||
|
|
|
@ -2,8 +2,6 @@ package netquery
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -395,12 +393,8 @@ func (db *Database) MarkAllHistoryConnectionsEnded(ctx context.Context) error {
|
|||
// UpdateBandwidth updates bandwidth data for the connection and optionally also writes
|
||||
// the bandwidth data to the history database.
|
||||
func (db *Database) UpdateBandwidth(ctx context.Context, enableHistory bool, processKey string, connID string, bytesReceived uint64, bytesSent uint64) error {
|
||||
data := connID + "-" + processKey
|
||||
hash := sha256.Sum256([]byte(data))
|
||||
dbConnID := hex.EncodeToString(hash[:])
|
||||
|
||||
params := map[string]any{
|
||||
":id": dbConnID,
|
||||
":id": makeNqIDFromParts(processKey, connID),
|
||||
}
|
||||
|
||||
parts := []string{}
|
||||
|
@ -481,6 +475,12 @@ func (db *Database) Save(ctx context.Context, conn Conn, enableHistory bool) err
|
|||
// and save some CPU cycles for the user
|
||||
dbNames := []DatabaseName{LiveDatabase}
|
||||
|
||||
// TODO: Should we only add ended connection to the history database to save
|
||||
// a couple INSERTs per connection?
|
||||
// This means we need to write the current live DB to the history DB on
|
||||
// shutdown in order to be able to pick the back up after a restart.
|
||||
|
||||
// Save to history DB if enabled.
|
||||
if enableHistory {
|
||||
dbNames = append(dbNames, HistoryDatabase)
|
||||
}
|
||||
|
|
|
@ -100,35 +100,42 @@ func (mng *Manager) HandleFeed(ctx context.Context, feed <-chan *network.Connect
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
if !conn.DataIsComplete() {
|
||||
continue
|
||||
}
|
||||
|
||||
model, err := convertConnection(conn)
|
||||
if err != nil {
|
||||
log.Errorf("netquery: failed to convert connection %s to sqlite model: %s", conn.ID, err)
|
||||
func() {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
continue
|
||||
}
|
||||
if !conn.DataIsComplete() {
|
||||
return
|
||||
}
|
||||
|
||||
// DEBUG:
|
||||
// log.Tracef("netquery: updating connection %s", conn.ID)
|
||||
model, err := convertConnection(conn)
|
||||
if err != nil {
|
||||
log.Errorf("netquery: failed to convert connection %s to sqlite model: %s", conn.ID, err)
|
||||
|
||||
if err := mng.store.Save(ctx, *model, conn.HistoryEnabled); err != nil {
|
||||
log.Errorf("netquery: failed to save connection %s in sqlite database: %s", conn.ID, err)
|
||||
return
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
// DEBUG:
|
||||
// log.Tracef("netquery: updating connection %s", conn.ID)
|
||||
|
||||
// we clone the record metadata from the connection
|
||||
// into the new model so the portbase/database layer
|
||||
// can handle NEW/UPDATE correctly.
|
||||
cloned := conn.Meta().Duplicate()
|
||||
// Save to netquery database.
|
||||
// Do not include internal connections in history.
|
||||
if err := mng.store.Save(ctx, *model, conn.HistoryEnabled && !conn.Internal); err != nil {
|
||||
log.Errorf("netquery: failed to save connection %s in sqlite database: %s", conn.ID, err)
|
||||
return
|
||||
}
|
||||
|
||||
// push an update for the connection
|
||||
if err := mng.pushConnUpdate(ctx, *cloned, *model); err != nil {
|
||||
log.Errorf("netquery: failed to push update for conn %s via database system: %s", conn.ID, err)
|
||||
}
|
||||
// we clone the record metadata from the connection
|
||||
// into the new model so the portbase/database layer
|
||||
// can handle NEW/UPDATE correctly.
|
||||
cloned := conn.Meta().Duplicate()
|
||||
|
||||
// push an update for the connection
|
||||
if err := mng.pushConnUpdate(ctx, *cloned, *model); err != nil {
|
||||
log.Errorf("netquery: failed to push update for conn %s via database system: %s", conn.ID, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -155,18 +162,16 @@ func (mng *Manager) pushConnUpdate(_ context.Context, meta record.Meta, conn Con
|
|||
}
|
||||
|
||||
// convertConnection converts conn to the local representation used
|
||||
// to persist the information in SQLite. convertConnection attempts
|
||||
// to lock conn and may thus block for some time.
|
||||
// to persist the information in SQLite.
|
||||
// The caller must hold the lock to the given network.Connection.
|
||||
func convertConnection(conn *network.Connection) (*Conn, error) {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
direction := "outbound"
|
||||
if conn.Inbound {
|
||||
direction = "inbound"
|
||||
}
|
||||
|
||||
c := Conn{
|
||||
ID: genConnID(conn),
|
||||
ID: makeNqIDFromConn(conn),
|
||||
External: conn.External,
|
||||
IPVersion: conn.IPVersion,
|
||||
IPProtocol: conn.IPProtocol,
|
||||
|
@ -265,6 +270,13 @@ func convertConnection(conn *network.Connection) (*Conn, error) {
|
|||
return &c, nil
|
||||
}
|
||||
|
||||
func genConnID(conn *network.Connection) string {
|
||||
return conn.ID + "-" + conn.Process().GetID()
|
||||
// makeNqIDFromConn creates a netquery connection ID from the network connection.
|
||||
func makeNqIDFromConn(conn *network.Connection) string {
|
||||
return makeNqIDFromParts(conn.Process().GetKey(), conn.ID)
|
||||
}
|
||||
|
||||
// makeNqIDFromParts creates a netquery connection ID from the given network
|
||||
// connection ID and the process key.
|
||||
func makeNqIDFromParts(processKey string, netConnID string) string {
|
||||
return processKey + "-" + netConnID
|
||||
}
|
||||
|
|
|
@ -89,8 +89,8 @@ func (m *module) prepare() error {
|
|||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: "netquery/query",
|
||||
MimeType: "application/json",
|
||||
Read: api.PermitUser,
|
||||
Write: api.PermitUser,
|
||||
Read: api.PermitUser, // Needs read+write as the query is sent using POST data.
|
||||
Write: api.PermitUser, // Needs read+write as the query is sent using POST data.
|
||||
BelongsTo: m.Module,
|
||||
HandlerFunc: queryHander.ServeHTTP,
|
||||
Name: "Query Connections",
|
||||
|
@ -102,7 +102,6 @@ func (m *module) prepare() error {
|
|||
if err := api.RegisterEndpoint(api.Endpoint{
|
||||
Path: "netquery/charts/connection-active",
|
||||
MimeType: "application/json",
|
||||
Read: api.PermitUser,
|
||||
Write: api.PermitUser,
|
||||
BelongsTo: m.Module,
|
||||
HandlerFunc: chartHandler.ServeHTTP,
|
||||
|
@ -116,7 +115,6 @@ func (m *module) prepare() error {
|
|||
Path: "netquery/history/clear",
|
||||
MimeType: "application/json",
|
||||
Write: api.PermitUser,
|
||||
Read: api.PermitUser,
|
||||
BelongsTo: m.Module,
|
||||
HandlerFunc: func(w http.ResponseWriter, r *http.Request) {
|
||||
var body struct {
|
||||
|
|
|
@ -325,8 +325,9 @@ func NewConnectionFromDNSRequest(ctx context.Context, fqdn string, cnames []stri
|
|||
Scope: fqdn,
|
||||
PID: proc.Pid,
|
||||
Entity: &intel.Entity{
|
||||
Domain: fqdn,
|
||||
CNAME: cnames,
|
||||
Domain: fqdn,
|
||||
CNAME: cnames,
|
||||
IPScope: netutils.Global, // Assign a global IP scope as default.
|
||||
},
|
||||
process: proc,
|
||||
ProcessContext: getProcessContext(ctx, proc),
|
||||
|
@ -367,8 +368,9 @@ func NewConnectionFromExternalDNSRequest(ctx context.Context, fqdn string, cname
|
|||
Scope: fqdn,
|
||||
PID: process.NetworkHostProcessID,
|
||||
Entity: &intel.Entity{
|
||||
Domain: fqdn,
|
||||
CNAME: cnames,
|
||||
Domain: fqdn,
|
||||
CNAME: cnames,
|
||||
IPScope: netutils.Global, // Assign a global IP scope as default.
|
||||
},
|
||||
process: remoteHost,
|
||||
ProcessContext: getProcessContext(ctx, remoteHost),
|
||||
|
@ -782,15 +784,6 @@ func (conn *Connection) SetFirewallHandler(handler FirewallHandler) {
|
|||
return
|
||||
}
|
||||
|
||||
// Start packet handler worker when first handler is set.
|
||||
if conn.firewallHandler == nil {
|
||||
// start handling
|
||||
module.StartWorker("packet handler", conn.packetHandlerWorker)
|
||||
}
|
||||
|
||||
// Set new handler.
|
||||
conn.firewallHandler = handler
|
||||
|
||||
// Initialize packet queue, if needed.
|
||||
conn.pktQueueLock.Lock()
|
||||
defer conn.pktQueueLock.Unlock()
|
||||
|
@ -798,6 +791,14 @@ func (conn *Connection) SetFirewallHandler(handler FirewallHandler) {
|
|||
conn.pktQueue = make(chan packet.Packet, 100)
|
||||
conn.pktQueueActive = true
|
||||
}
|
||||
|
||||
// Start packet handler worker when new handler is set.
|
||||
if conn.firewallHandler == nil {
|
||||
module.StartWorker("packet handler", conn.packetHandlerWorker)
|
||||
}
|
||||
|
||||
// Set new handler.
|
||||
conn.firewallHandler = handler
|
||||
}
|
||||
|
||||
// UpdateFirewallHandler sets the firewall handler if it already set and the
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"golang.org/x/exp/slices"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/nameserver/nsutil"
|
||||
|
@ -18,6 +19,13 @@ import (
|
|||
var (
|
||||
openDNSRequests = make(map[string]*Connection) // key: <pid>/fqdn
|
||||
openDNSRequestsLock sync.Mutex
|
||||
|
||||
supportedDomainToIPRecordTypes = []uint16{
|
||||
dns.TypeA,
|
||||
dns.TypeAAAA,
|
||||
dns.TypeSVCB,
|
||||
dns.TypeHTTPS,
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -30,6 +38,13 @@ const (
|
|||
openDNSRequestLimit = 3 * time.Second
|
||||
)
|
||||
|
||||
// IsSupportDNSRecordType returns whether the given DSN RR type is supported
|
||||
// by the network package, as in the requests are specially handled and can be
|
||||
// "merged" into the resulting connection.
|
||||
func IsSupportDNSRecordType(rrType uint16) bool {
|
||||
return slices.Contains[[]uint16, uint16](supportedDomainToIPRecordTypes, rrType)
|
||||
}
|
||||
|
||||
func getDNSRequestCacheKey(pid int, fqdn string, qType uint16) string {
|
||||
return strconv.Itoa(pid) + "/" + fqdn + dns.Type(qType).String()
|
||||
}
|
||||
|
@ -39,28 +54,28 @@ func removeOpenDNSRequest(pid int, fqdn string) {
|
|||
defer openDNSRequestsLock.Unlock()
|
||||
|
||||
// Delete PID-specific requests.
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(pid, fqdn, dns.TypeA))
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(pid, fqdn, dns.TypeAAAA))
|
||||
for _, dnsType := range supportedDomainToIPRecordTypes {
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(pid, fqdn, dnsType))
|
||||
}
|
||||
|
||||
// If process is known, also check for non-attributed requests.
|
||||
if pid != process.UnidentifiedProcessID {
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(process.UnidentifiedProcessID, fqdn, dns.TypeA))
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(process.UnidentifiedProcessID, fqdn, dns.TypeAAAA))
|
||||
for _, dnsType := range supportedDomainToIPRecordTypes {
|
||||
delete(openDNSRequests, getDNSRequestCacheKey(process.UnidentifiedProcessID, fqdn, dnsType))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SaveOpenDNSRequest saves a dns request connection that was allowed to proceed.
|
||||
func SaveOpenDNSRequest(q *resolver.Query, rrCache *resolver.RRCache, conn *Connection) {
|
||||
// Only save requests that actually went out to reduce clutter.
|
||||
if rrCache == nil || rrCache.ServedFromCache {
|
||||
// Only save requests that actually went out (or triggered an async resolve) to reduce clutter.
|
||||
if rrCache == nil || (rrCache.ServedFromCache && !rrCache.RequestingNew) {
|
||||
return
|
||||
}
|
||||
|
||||
// Try to "merge" A and AAAA requests into the resulting connection.
|
||||
// Try to "merge" supported requests into the resulting connection.
|
||||
// Save others immediately.
|
||||
switch uint16(q.QType) {
|
||||
case dns.TypeA, dns.TypeAAAA:
|
||||
default:
|
||||
if !IsSupportDNSRecordType(uint16(q.QType)) {
|
||||
conn.Save()
|
||||
return
|
||||
}
|
||||
|
@ -68,18 +83,12 @@ func SaveOpenDNSRequest(q *resolver.Query, rrCache *resolver.RRCache, conn *Conn
|
|||
openDNSRequestsLock.Lock()
|
||||
defer openDNSRequestsLock.Unlock()
|
||||
|
||||
// Check if there is an existing open DNS requests for the same domain/type.
|
||||
// If so, save it now and replace it with the new request.
|
||||
key := getDNSRequestCacheKey(conn.process.Pid, conn.Entity.Domain, uint16(q.QType))
|
||||
if existingConn, ok := openDNSRequests[key]; ok {
|
||||
// End previous request and save it.
|
||||
existingConn.Lock()
|
||||
existingConn.Ended = conn.Started
|
||||
existingConn.Unlock()
|
||||
existingConn.Save()
|
||||
}
|
||||
// Do not check for an existing open DNS request, as duplicates in such quick
|
||||
// succession are not worth keeping.
|
||||
// DNS queries are usually retried pretty quick.
|
||||
|
||||
// Save to open dns requests.
|
||||
key := getDNSRequestCacheKey(conn.process.Pid, conn.Entity.Domain, uint16(q.QType))
|
||||
openDNSRequests[key] = conn
|
||||
}
|
||||
|
||||
|
@ -103,12 +112,15 @@ func writeOpenDNSRequestsToDB() {
|
|||
|
||||
threshold := time.Now().Add(-openDNSRequestLimit).Unix()
|
||||
for id, conn := range openDNSRequests {
|
||||
conn.Lock()
|
||||
if conn.Ended < threshold {
|
||||
conn.Save()
|
||||
delete(openDNSRequests, id)
|
||||
}
|
||||
conn.Unlock()
|
||||
func() {
|
||||
conn.Lock()
|
||||
defer conn.Unlock()
|
||||
|
||||
if conn.Ended < threshold {
|
||||
conn.Save()
|
||||
delete(openDNSRequests, id)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -314,10 +314,10 @@ func loadProcess(ctx context.Context, key string, pInfo *processInfo.Process) (*
|
|||
return process, nil
|
||||
}
|
||||
|
||||
// GetID returns the key that is used internally to identify the process.
|
||||
// The ID consists of the PID and the start time of the process as reported by
|
||||
// GetKey returns the key that is used internally to identify the process.
|
||||
// The key consists of the PID and the start time of the process as reported by
|
||||
// the system.
|
||||
func (p *Process) GetID() string {
|
||||
func (p *Process) GetKey() string {
|
||||
return p.processKey
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portbase/database"
|
||||
"github.com/safing/portbase/database/record"
|
||||
|
@ -170,7 +171,7 @@ func (info *IPInfo) Save() error {
|
|||
}
|
||||
|
||||
// Calculate and set cache expiry.
|
||||
var expires int64 = 86400 // Minimum TTL of one day.
|
||||
expires := time.Now().Unix() + 86400 // Minimum TTL of one day.
|
||||
for _, rd := range info.ResolvedDomains {
|
||||
if rd.Expires > expires {
|
||||
expires = rd.Expires
|
||||
|
|
|
@ -293,11 +293,19 @@ func startAsyncQuery(ctx context.Context, q *Query, currentRRCache *RRCache) {
|
|||
|
||||
// Set flag and log that we are refreshing this entry.
|
||||
currentRRCache.RequestingNew = true
|
||||
log.Tracer(ctx).Tracef(
|
||||
"resolver: cache for %s will expire in %s, refreshing async now",
|
||||
q.ID(),
|
||||
time.Until(time.Unix(currentRRCache.Expires, 0)).Round(time.Second),
|
||||
)
|
||||
if currentRRCache.Expired() {
|
||||
log.Tracer(ctx).Tracef(
|
||||
"resolver: cache for %s has expired %s ago, refreshing async now",
|
||||
q.ID(),
|
||||
time.Since(time.Unix(currentRRCache.Expires, 0)).Round(time.Second),
|
||||
)
|
||||
} else {
|
||||
log.Tracer(ctx).Tracef(
|
||||
"resolver: cache for %s will expire in %s, refreshing async now",
|
||||
q.ID(),
|
||||
time.Until(time.Unix(currentRRCache.Expires, 0)).Round(time.Second),
|
||||
)
|
||||
}
|
||||
|
||||
// resolve async
|
||||
module.StartWorker("resolve async", func(asyncCtx context.Context) error {
|
||||
|
|
|
@ -130,8 +130,8 @@ func upgradeSystemIntegrationFileContents(
|
|||
}
|
||||
|
||||
// Check if we are allowed to upgrade from the existing file.
|
||||
if !slices.Contains[string](permittedUpgradeHashes, existingHexSum) {
|
||||
return fmt.Errorf("%s at %s %w, as it is not a previously published version and cannot be automatically upgraded - try installing again", name, filePath, ErrRequiresManualUpgrade)
|
||||
if !slices.Contains[[]string, string](permittedUpgradeHashes, existingHexSum) {
|
||||
return fmt.Errorf("%s at %s (sha256:%s) %w, as it is not a previously published version and cannot be automatically upgraded - try installing again", name, filePath, existingHexSum, ErrRequiresManualUpgrade)
|
||||
}
|
||||
|
||||
// Start with upgrade!
|
||||
|
|
Loading…
Add table
Reference in a new issue