in server.go [264:325]
func srvrRunUDPPacketHandler(conn *net.UDPConn) {
// This local map aids in efficiency to look up a test based on client's IP
// address. We could use createOrGetTest but that takes a global lock.
tests := make(map[string]*ethrTest)
// For UDP, allocate buffer that can accomodate largest UDP datagram.
readBuffer := make([]byte, 64*1024)
n, remoteIP, err := 0, new(net.UDPAddr), error(nil)
// This function handles UDP tests that came from clients that are no longer
// sending any traffic. This is poor man's garbage collection to ensure the
// server doesn't end up printing dormant client related statistics as UDP
// has no reliable way to detect if client is active or not.
go func() {
for {
time.Sleep(100 * time.Millisecond)
for k, v := range tests {
ui.printDbg("Found Test from server: %v, time: %v", k, v.lastAccess)
// At 200ms of no activity, mark the test in-active so stats stop
// printing.
if time.Since(v.lastAccess) > (200 * time.Millisecond) {
v.isDormant = true
}
// At 2s of no activity, delete the test by assuming that client
// has stopped.
if time.Since(v.lastAccess) > (2 * time.Second) {
ui.printDbg("Deleting UDP test from server: %v, lastAccess: %v", k, v.lastAccess)
safeDeleteTest(v)
delete(tests, k)
}
}
}
}()
for err == nil {
n, remoteIP, err = conn.ReadFromUDP(readBuffer)
if err != nil {
ui.printDbg("Error receiving data from UDP for bandwidth test: %v", err)
continue
}
ethrUnused(remoteIP)
ethrUnused(n)
server, port, _ := net.SplitHostPort(remoteIP.String())
test, found := tests[server]
if !found {
test, isNew := createOrGetTest(server, UDP, All)
if test != nil {
tests[server] = test
}
if isNew {
ui.printDbg("Creating UDP test from server: %v, lastAccess: %v", server, time.Now())
ui.emitTestHdr()
}
}
if test != nil {
test.isDormant = false
test.lastAccess = time.Now()
atomic.AddUint64(&test.testResult.pps, 1)
atomic.AddUint64(&test.testResult.bw, uint64(n))
} else {
ui.printDbg("Unable to create test for UDP traffic on port %s from %s port %s", gEthrPortStr, server, port)
}
}
}