From 27cc57dbbc91220c982155e53826f7ca524e0ca8 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sun, 24 Nov 2019 18:24:17 -0600 Subject: [PATCH 1/3] attempt to prevent incorrect idle notification in switch, needs testing --- src/yggdrasil/link.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/yggdrasil/link.go b/src/yggdrasil/link.go index 1710e20..10a3145 100644 --- a/src/yggdrasil/link.go +++ b/src/yggdrasil/link.go @@ -64,6 +64,7 @@ type linkInterface struct { closeTimer *time.Timer // Fires when the link has been idle so long we need to close it inSwitch bool // True if the switch is tracking this link stalled bool // True if we haven't been receiving any response traffic + unstalled bool // False if an idle notification to the switch hasn't been sent because we stalled (or are first starting up) } func (l *link) init(c *Core) error { @@ -324,11 +325,15 @@ func (intf *linkInterface) notifySent(size int, isLinkTraffic bool) { // Notify the switch that we're ready for more traffic, assuming we're not in a stalled state func (intf *linkInterface) _notifySwitch() { - if !intf.inSwitch && !intf.stalled { - intf.inSwitch = true - intf.link.core.switchTable.Act(intf, func() { - intf.link.core.switchTable._idleIn(intf.peer.port) - }) + if !intf.inSwitch { + if intf.stalled { + intf.unstalled = false + } else { + intf.inSwitch = true + intf.link.core.switchTable.Act(intf, func() { + intf.link.core.switchTable._idleIn(intf.peer.port) + }) + } } } @@ -362,7 +367,9 @@ func (intf *linkInterface) notifyRead(size int) { intf.stallTimer = nil } intf.stalled = false - intf._notifySwitch() + if !intf.unstalled { + intf._notifySwitch() + } if size > 0 && intf.stallTimer == nil { intf.stallTimer = time.AfterFunc(keepAliveTime, intf.notifyDoKeepAlive) } From 3e0799551835c7b1846605bd88ae8a133c00c4ee Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sun, 24 Nov 2019 18:53:58 -0600 Subject: [PATCH 2/3] it helps to actually set the flag... --- src/yggdrasil/link.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/yggdrasil/link.go b/src/yggdrasil/link.go index 10a3145..cd40a9e 100644 --- a/src/yggdrasil/link.go +++ b/src/yggdrasil/link.go @@ -369,6 +369,7 @@ func (intf *linkInterface) notifyRead(size int) { intf.stalled = false if !intf.unstalled { intf._notifySwitch() + intf.unstalled = true } if size > 0 && intf.stallTimer == nil { intf.stallTimer = time.AfterFunc(keepAliveTime, intf.notifyDoKeepAlive) From 98339cdc3f89cc4342c5e7ef0624dc440ff8a4ac Mon Sep 17 00:00:00 2001 From: Arceliar Date: Mon, 25 Nov 2019 17:40:58 -0600 Subject: [PATCH 3/3] possible fix if monotonic time resolution is related to packet reordering --- src/yggdrasil/switch.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index ba30758..ab888a7 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -808,12 +808,12 @@ func (t *switchTable) _handleIdle(port switchPort) bool { packet := buf.packets[0] coords := switch_getPacketCoords(packet.bytes) priority := float64(now.Sub(packet.time)) / float64(buf.size) - if priority > bestPriority && t.portIsCloser(coords, port) { + if priority >= bestPriority && t.portIsCloser(coords, port) { best = streamID bestPriority = priority } } - if bestPriority != 0 { + if best != "" { buf := t.queues.bufs[best] var packet switch_packetInfo // TODO decide if this should be LIFO or FIFO