mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-09-26 19:51:10 +08:00

I measured the performance penalty of the 725-entry blocklist, and it clocks in a 3% to 12%. I want to replace the painful for-loop with a map, assuming the map works more quickly.
93 lines
3.2 KiB
Go
93 lines
3.2 KiB
Go
package main_test
|
|
|
|
import (
|
|
"net"
|
|
"os/exec"
|
|
"strconv"
|
|
"time"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
. "github.com/onsi/gomega/gbytes"
|
|
. "github.com/onsi/gomega/gexec"
|
|
"golang.org/x/net/dns/dnsmessage"
|
|
)
|
|
|
|
var _ = Describe("speed", func() {
|
|
var serverCmd *exec.Cmd
|
|
var serverSession *Session
|
|
var port = getFreePort()
|
|
var flags []string
|
|
|
|
JustBeforeEach(func() {
|
|
flags = append(flags, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist-test.txt")
|
|
serverCmd = exec.Command(serverPath, flags...)
|
|
serverSession, err = Start(serverCmd, GinkgoWriter, GinkgoWriter)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
// takes 0.455s to start up on macOS Big Sur 3.7 GHz Quad Core 22-nm Xeon E5-1620v2 processor (2013 Mac Pro)
|
|
// takes 1.312s to start up on macOS Big Sur 2.0GHz quad-core 10th-generation Intel Core i5 processor (2020 13" MacBook Pro)
|
|
// 10 seconds should be long enough for slow container-on-a-VM-with-shared-core
|
|
Eventually(serverSession.Err, 10).Should(Say("Ready to answer queries"))
|
|
})
|
|
AfterEach(func() {
|
|
serverSession.Terminate()
|
|
Eventually(serverSession).Should(Exit())
|
|
})
|
|
When("we want test the throughput", func() {
|
|
var loopbackAddr *net.UDPAddr
|
|
var conn *net.UDPConn
|
|
var msg dnsmessage.Message
|
|
const numQueries = 5000 // set to 123456 when testing
|
|
const minThroughput = 1000
|
|
|
|
BeforeEach(func() {
|
|
loopbackAddr, err = net.ResolveUDPAddr("udp", "localhost:"+strconv.Itoa(port))
|
|
Expect(err).ToNot(HaveOccurred())
|
|
conn, err = net.DialUDP("udp", nil, loopbackAddr)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
})
|
|
It("runs "+strconv.Itoa(numQueries)+" queries and the throughput is > "+strconv.Itoa(minThroughput)+" queries/sec", func() {
|
|
msg = dnsmessage.Message{
|
|
Questions: []dnsmessage.Question{
|
|
{
|
|
Name: dnsmessage.MustNewName("127-0-0-1.sslip.io."),
|
|
Type: dnsmessage.TypeA,
|
|
Class: dnsmessage.ClassINET,
|
|
},
|
|
},
|
|
}
|
|
responseBuf := make([]byte, 512)
|
|
queryBuf, err := msg.Pack()
|
|
Expect(err).ToNot(HaveOccurred())
|
|
startTime := time.Now()
|
|
// The queries/second is conservative, realistically should be higher
|
|
// - queries are done sequentially, not in parallel
|
|
// - each query includes an overhead of 4 Expect()
|
|
// current max queries is 2047/second (ns-ovh.sslip.io.)
|
|
// ~27k Apple M4
|
|
// ~19k Apple M2
|
|
// ~8k vSphere Xeon D-1736 2.7GHz
|
|
// ~6k AWS Graviton T2
|
|
// ~5k Azure Xeon E5-2673 v4 @ 2.30GHz
|
|
|
|
// blocklist exacts a 3% - 11% penalty
|
|
// with `-quiet` and 4-entry blocklist on M4
|
|
// ~32k-34k
|
|
// with 725 entry blocklist
|
|
// ~30k-31k
|
|
for i := 0; i < numQueries; i += 1 {
|
|
bytesWritten, err := conn.Write(queryBuf)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(bytesWritten).To(Equal(len(queryBuf)))
|
|
bytesRead, err := conn.Read(responseBuf)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
Expect(bytesRead).To(Equal(52)) // The A record response "127.0.0.1" is 52 bytes
|
|
}
|
|
elapsedSeconds := time.Since(startTime).Seconds()
|
|
Eventually(serverSession.Err).Should(Say(`TypeA 127-0-0-1\.sslip\.io\. \? 127\.0\.0\.1`))
|
|
//fmt.Fprintf(os.Stderr, "Queries/second: %.2f\n", float64(numQueries)/elapsedSeconds)
|
|
Expect(float64(numQueries) / elapsedSeconds).Should(BeNumerically(">", minThroughput))
|
|
})
|
|
})
|
|
})
|