From 6f0bbbfb987c00e79a9eea460b0436c76928983f Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 15 Feb 2019 19:35:10 -0600 Subject: [PATCH 1/2] Debug some issues with the state machine that tracks idle connections in link.go --- src/yggdrasil/link.go | 26 ++++++++++++++++++-------- src/yggdrasil/switch.go | 1 + 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/yggdrasil/link.go b/src/yggdrasil/link.go index be98dd9..ad4b1fa 100644 --- a/src/yggdrasil/link.go +++ b/src/yggdrasil/link.go @@ -216,6 +216,8 @@ func (intf *linkInterface) handler() error { case signalReady <- struct{}{}: default: } + intf.link.core.log.Debugf("Sending packet to %s: %s, source %s", + strings.ToUpper(intf.info.linkType), themString, intf.info.local) } } }() @@ -235,18 +237,21 @@ func (intf *linkInterface) handler() error { recvTimer := time.NewTimer(recvTime) defer util.TimerStop(recvTimer) for { + intf.link.core.log.Debugf("State of %s: %s, source %s :: isAlive %t isReady %t sendTimerRunning %t recvTimerRunning %t", + strings.ToUpper(intf.info.linkType), themString, intf.info.local, + isAlive, isReady, sendTimerRunning, recvTimerRunning) select { case gotMsg, ok := <-signalAlive: if !ok { return } - if !isAlive { - isAlive = true - if !isReady { - // (Re-)enable in the switch - isReady = true - intf.link.core.switchTable.idleIn <- intf.peer.port - } + util.TimerStop(recvTimer) + recvTimerRunning = false + isAlive = true + if !isReady { + // (Re-)enable in the switch + intf.link.core.switchTable.idleIn <- intf.peer.port + isReady = true } if gotMsg && !sendTimerRunning { // We got a message @@ -255,6 +260,10 @@ func (intf *linkInterface) handler() error { sendTimer.Reset(sendTime) sendTimerRunning = true } + if !gotMsg { + intf.link.core.log.Debugf("Received ack from %s: %s, source %s", + strings.ToUpper(intf.info.linkType), themString, intf.info.local) + } case sentMsg, ok := <-signalSent: // Stop any running ack timer if !ok { @@ -273,12 +282,13 @@ func (intf *linkInterface) handler() error { if !ok { return } - if !isAlive || !isReady { + if !isAlive { // Disable in the switch isReady = false } else { // Keep enabled in the switch intf.link.core.switchTable.idleIn <- intf.peer.port + isReady = true } case <-sendTimer.C: // We haven't sent anything, so signal a send of a 0 packet to let them know we're alive diff --git a/src/yggdrasil/switch.go b/src/yggdrasil/switch.go index 9d1f870..a2877eb 100644 --- a/src/yggdrasil/switch.go +++ b/src/yggdrasil/switch.go @@ -780,6 +780,7 @@ func (t *switchTable) doWorker() { t.queues.bufs = make(map[string]switch_buffer) // Packets per PacketStreamID (string) idle := make(map[switchPort]struct{}) // this is to deduplicate things for { + t.core.log.Debugf("Switch state: idle = %d, buffers = %d", len(idle), len(t.queues.bufs)) select { case bytes := <-t.packetIn: // Try to send it somewhere (or drop it if it's corrupt or at a dead end) From 957248b3dded3133cea5d134f1eb1a0bed68c36a Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 15 Feb 2019 20:23:28 -0600 Subject: [PATCH 2/2] add twolink test for namespaces with multiple links with different bandwidth --- misc/run-twolink-test | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 misc/run-twolink-test diff --git a/misc/run-twolink-test b/misc/run-twolink-test new file mode 100755 index 0000000..987b6de --- /dev/null +++ b/misc/run-twolink-test @@ -0,0 +1,33 @@ +#!/bin/bash + +# Connects nodes in two namespaces by two links with different bandwidth (10mbit and 100mbit) + +ip netns add node1 +ip netns add node2 + +ip link add veth11 type veth peer name veth21 +ip link set veth11 netns node1 up +ip link set veth21 netns node2 up + +ip link add veth12 type veth peer name veth22 +ip link set veth12 netns node1 up +ip link set veth22 netns node2 up + +ip netns exec node1 tc qdisc add dev veth11 root tbf rate 10mbit burst 8192 latency 1ms +ip netns exec node2 tc qdisc add dev veth21 root tbf rate 10mbit burst 8192 latency 1ms + +ip netns exec node1 tc qdisc add dev veth12 root tbf rate 100mbit burst 8192 latency 1ms +ip netns exec node2 tc qdisc add dev veth22 root tbf rate 100mbit burst 8192 latency 1ms + +echo '{AdminListen: "unix://node1.sock"}' | ip netns exec node1 env PPROFLISTEN=localhost:6060 ./yggdrasil -logging "info,warn,error,debug" -useconf &> node1.log & +echo '{AdminListen: "unix://node2.sock"}' | ip netns exec node2 env PPROFLISTEN=localhost:6060 ./yggdrasil -logging "info,warn,error,debug" -useconf &> node2.log & + +echo "Started, to continue you should (possibly w/ sudo):" +echo "kill" $(jobs -p) +wait + +ip netns delete node1 +ip netns delete node2 + +ip link delete veth11 +ip link delete veth12