Skip to content

Commit

Permalink
Allocate one filter per IP or SCION client
Browse files Browse the repository at this point in the history
  • Loading branch information
marcfrei committed Apr 5, 2024
1 parent a5d9efc commit 0ce2eb3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 41 deletions.
3 changes: 2 additions & 1 deletion core/client/client_ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type IPClient struct {
cRxTime ntp.Time64
sRxTime ntp.Time64
}
filter filter
}

type ipClientMetrics struct {
Expand Down Expand Up @@ -327,7 +328,7 @@ func (c *IPClient) measureClockOffsetIP(ctx context.Context, log *zap.Logger, mt
if c.Raw {
offset = off
} else {
offset = filter(log, reference, t0, t1, t2, t3)
offset = c.filter.do(log, reference, t0, t1, t2, t3)
}

if c.Histo != nil {
Expand Down
4 changes: 2 additions & 2 deletions core/client/client_scion.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"example.com/scion-time/net/udp"
)


type SCIONClient struct {
DSCP uint8
InterleavedMode bool
Expand All @@ -53,6 +52,7 @@ type SCIONClient struct {
cRxTime ntp.Time64
sRxTime ntp.Time64
}
filter filter
}

type scionClientMetrics struct {
Expand Down Expand Up @@ -558,7 +558,7 @@ func (c *SCIONClient) measureClockOffsetSCION(ctx context.Context, log *zap.Logg
if c.Raw {
offset = off
} else {
offset = filter(log, reference, t0, t1, t2, t3)
offset = c.filter.do(log, reference, t0, t1, t2, t3)
}

if c.Histo != nil {
Expand Down
75 changes: 37 additions & 38 deletions core/client/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package client

import (
"math"
"sync"
"time"

"go.uber.org/zap"
Expand All @@ -11,17 +10,16 @@ import (
"example.com/scion-time/core/timebase"
)

type filterContext struct {
type filterState struct {
epoch uint64
alo, amid, ahi float64
alolo, ahihi float64
navg float64
}

var (
filters = make(map[string]filterContext)
filtersMu = sync.Mutex{}
)
type filter struct {
state map[string]filterState
}

func combine(lo, mid, hi time.Duration, trust float64) (offset time.Duration, weight float64) {
offset = mid
Expand All @@ -32,76 +30,77 @@ func combine(lo, mid, hi time.Duration, trust float64) (offset time.Duration, we
return
}

func filter(log *zap.Logger, reference string, cTxTime, sRxTime, sTxTime, cRxTime time.Time) (
func (f *filter) do(log *zap.Logger, reference string, cTxTime, sRxTime, sTxTime, cRxTime time.Time) (
offset time.Duration) {

// Based on Ntimed by Poul-Henning Kamp, https://github.com/bsdphk/Ntimed

var weight float64

filtersMu.Lock()
f := filters[reference]
fs := f.state[reference]

lo := timemath.Seconds(cTxTime.Sub(sRxTime))
hi := timemath.Seconds(cRxTime.Sub(sTxTime))
mid := (lo + hi) / 2

if f.epoch != timebase.Epoch() {
f.epoch = timebase.Epoch()
f.alo = 0.0
f.amid = 0.0
f.ahi = 0.0
f.alolo = 0.0
f.ahihi = 0.0
f.navg = 0.0
if fs.epoch != timebase.Epoch() {
fs.epoch = timebase.Epoch()
fs.alo = 0.0
fs.amid = 0.0
fs.ahi = 0.0
fs.alolo = 0.0
fs.ahihi = 0.0
fs.navg = 0.0
}

const (
filterAverage = 20.0
filterThreshold = 3.0
)

if f.navg < filterAverage {
f.navg += 1.0
if fs.navg < filterAverage {
fs.navg += 1.0
}

var loNoise, hiNoise float64
if f.navg > 2.0 {
loNoise = math.Sqrt(f.alolo - f.alo*f.alo)
hiNoise = math.Sqrt(f.ahihi - f.ahi*f.ahi)
if fs.navg > 2.0 {
loNoise = math.Sqrt(fs.alolo - fs.alo*fs.alo)
hiNoise = math.Sqrt(fs.ahihi - fs.ahi*fs.ahi)
}

loLim := f.alo - loNoise*filterThreshold
hiLim := f.ahi + hiNoise*filterThreshold
loLim := fs.alo - loNoise*filterThreshold
hiLim := fs.ahi + hiNoise*filterThreshold

var branch int
failLo := lo < loLim
failHi := hi > hiLim
if failLo && failHi {
branch = 1
} else if f.navg > 3.0 && failLo {
mid = f.amid + (hi - f.ahi)
} else if fs.navg > 3.0 && failLo {
mid = fs.amid + (hi - fs.ahi)
branch = 2
} else if f.navg > 3.0 && failHi {
mid = f.amid + (lo - f.alo)
} else if fs.navg > 3.0 && failHi {
mid = fs.amid + (lo - fs.alo)
branch = 3
} else {
branch = 4
}

r := f.navg
if f.navg > 2.0 && branch != 4 {
r := fs.navg
if fs.navg > 2.0 && branch != 4 {
r *= r
}

f.alo += (lo - f.alo) / r
f.amid += (mid - f.amid) / r
f.ahi += (hi - f.ahi) / r
f.alolo += (lo*lo - f.alolo) / r
f.ahihi += (hi*hi - f.ahihi) / r
fs.alo += (lo - fs.alo) / r
fs.amid += (mid - fs.amid) / r
fs.ahi += (hi - fs.ahi) / r
fs.alolo += (lo*lo - fs.alolo) / r
fs.ahihi += (hi*hi - fs.ahihi) / r

filters[reference] = f
filtersMu.Unlock()
if f.state == nil {
f.state = make(map[string]filterState)
}
f.state[reference] = fs

trust := 1.0

Expand All @@ -114,7 +113,7 @@ func filter(log *zap.Logger, reference string, cTxTime, sRxTime, sTxTime, cRxTim
zap.Float64("mid [s]", mid),
zap.Float64("hi [s]", hi),
zap.Float64("loLim [s]", loLim),
zap.Float64("amid [s]", f.amid),
zap.Float64("amid [s]", fs.amid),
zap.Float64("hiLim [s]", hiLim),
zap.Float64("offset [s]", timemath.Seconds(offset)),
zap.Float64("weight", weight),
Expand Down

0 comments on commit 0ce2eb3

Please sign in to comment.