From 6cfd91839f7c91c04283d4cdf99f4f56eeb5b78a Mon Sep 17 00:00:00 2001 From: David Fifield Date: Sun, 1 Aug 2021 23:05:07 -0600 Subject: [PATCH] Don't consider timer and nextReq until stash and outgoing are empty. When the timer is expired, we want to continue packing as long as additional packets are available with zero waiting. I'm not sure about deferring the nextReq break, but we expect packet packing to be a quick operation. --- dnstt-server/main.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/dnstt-server/main.go b/dnstt-server/main.go index 04f03b0..41b6f1d 100644 --- a/dnstt-server/main.go +++ b/dnstt-server/main.go @@ -587,24 +587,26 @@ func sendLoop(dnsConn net.PacketConn, ttConn *turbotunnel.QueuePacketConn, ch <- timer := time.NewTimer(maxResponseDelay) for { var p []byte + unstash := ttConn.Unstash(rec.ClientID) + outgoing := ttConn.OutgoingQueue(rec.ClientID) + // Prioritize taking a packet first from the + // stash, then from the outgoing queue, then + // finally check for the expiration of the timer + // or for a receive on ch (indicating a new + // query that we must respond to). select { - // Check the nextRec, timer, and stash cases - // before considering the OutgoingQueue case. - // Only if all these cases fail do we enter the - // default arm, where they are checked again in - // addition to OutgoingQueue. - case nextRec = <-ch: - // If there's another response waiting - // to be sent, wait no longer for a - // payload for this one. - case <-timer.C: - case p = <-ttConn.Unstash(rec.ClientID): + case p = <-unstash: default: select { - case nextRec = <-ch: - case <-timer.C: - case p = <-ttConn.Unstash(rec.ClientID): - case p = <-ttConn.OutgoingQueue(rec.ClientID): + case p = <-unstash: + case p = <-outgoing: + default: + select { + case p = <-unstash: + case p = <-outgoing: + case <-timer.C: + case nextRec = <-ch: + } } } // We wait for the first packet in a bundle