Skip to content

Commit a1bf40c

Browse files
committed
- Reduced global variables to 2 variables, all others are scoped local
variables. - initConns function takes client and server control channel address as input (along with pathAlgo and interactive for choosing the paths while setting up the addresses), and returns the connections, the data channel addresses, and an error. - find max bandwidth option can be used with the 'cs' and/or the 'sc' flags to set the duration, packet sizes, and starting bandwidth for the test. If the flags are not set, default values are used
1 parent 2cbe5f5 commit a1bf40c

File tree

1 file changed

+120
-111
lines changed

1 file changed

+120
-111
lines changed

bwtester/bwtestclient/bwtestclient.go

Lines changed: 120 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -37,44 +37,6 @@ const (
3737
var (
3838
InferedPktSize int64
3939
overlayType string
40-
41-
sciondPath string
42-
sciondFromIA bool
43-
dispatcherPath string
44-
clientCCAddrStr string
45-
serverCCAddrStr string
46-
clientPort uint
47-
serverPort uint16
48-
// Address of client control channel (CC)
49-
clientCCAddr *snet.Addr
50-
// Address of server control channel (CC)
51-
serverCCAddr *snet.Addr
52-
// Control channel connection
53-
CCConn snet.Conn
54-
55-
// Address of client data channel (DC)
56-
clientDCAddr *snet.Addr
57-
// Address of server data channel (DC)
58-
serverDCAddr *snet.Addr
59-
// Data channel connection
60-
DCConn snet.Conn
61-
62-
clientBwpStr string
63-
clientBwp BwtestParameters
64-
serverBwpStr string
65-
serverBwp BwtestParameters
66-
interactive bool
67-
pathAlgo string
68-
useIPv6 bool
69-
70-
err error
71-
tzero time.Time // initialized to "zero" time
72-
73-
receiveDone chan struct{} // used to signal when the HandleDCConnReceive goroutine has completed
74-
75-
maxBandwidth bool
76-
77-
pathEntry *sciond.PathReplyEntry
7840
)
7941

8042
func prepareAESKey() []byte {
@@ -279,6 +241,40 @@ func getPacketCount(count string) int64 {
279241
}
280242

281243
func main() {
244+
var (
245+
sciondPath string
246+
sciondFromIA bool
247+
dispatcherPath string
248+
clientCCAddrStr string
249+
serverCCAddrStr string
250+
clientPort uint
251+
252+
// Control channel connection
253+
CCConn snet.Conn
254+
// Address of client control channel (CC)
255+
clientCCAddr *snet.Addr
256+
// Address of server control channel (CC)
257+
serverCCAddr *snet.Addr
258+
259+
// Address of client data channel (DC)
260+
clientDCAddr *snet.Addr
261+
// Address of server data channel (DC)
262+
serverDCAddr *snet.Addr
263+
// Data channel connection
264+
DCConn snet.Conn
265+
266+
clientBwpStr string
267+
clientBwp BwtestParameters
268+
serverBwpStr string
269+
serverBwp BwtestParameters
270+
interactive bool
271+
pathAlgo string
272+
useIPv6 bool
273+
274+
maxBandwidth bool
275+
276+
err error
277+
)
282278
flag.StringVar(&sciondPath, "sciond", "", "Path to sciond socket")
283279
flag.BoolVar(&sciondFromIA, "sciondFromIA", false, "SCIOND socket path from IA address:ISD-AS")
284280
flag.StringVar(&dispatcherPath, "dispatcher", "/run/shm/dispatcher/default.sock",
@@ -291,7 +287,11 @@ func main() {
291287
flag.BoolVar(&interactive, "i", false, "Interactive mode")
292288
flag.StringVar(&pathAlgo, "pathAlgo", "", "Path selection algorithm / metric (\"shortest\", \"mtu\")")
293289
flag.BoolVar(&useIPv6, "6", false, "Use IPv6")
294-
flag.BoolVar(&maxBandwidth, "findMax", false, "Find the maximum bandwidth achievable")
290+
flag.BoolVar(&maxBandwidth, "findMax", false, "Find the maximum bandwidth achievable.\nYou can"+
291+
"use the flags \"cs\" and \"sc\" to set the parameters along with initial bandwidth to test on the link.\n"+
292+
"The other parameters will be fixed except for the packet count which will change in every run.\nThe higher"+
293+
" the duration of the test, the more accurate the results, but it will take longer to find the "+
294+
"maximum bandwidth.")
295295

296296
flag.Parse()
297297
flagset := make(map[string]bool)
@@ -304,8 +304,6 @@ func main() {
304304
os.Exit(0)
305305
}
306306

307-
receiveDone = make(chan struct{})
308-
309307
if useIPv6 {
310308
overlayType = "udp6"
311309
} else {
@@ -338,82 +336,76 @@ func main() {
338336
sciondPath = sciond.GetDefaultSCIONDPath(nil)
339337
}
340338

341-
initConns()
339+
CCConn, DCConn, serverDCAddr, clientDCAddr, err = initConns(serverCCAddr, clientCCAddr, pathAlgo, interactive)
340+
if err != nil {
341+
Check(err)
342+
}
342343

343-
if maxBandwidth {
344-
findMaxBandwidth()
344+
if !flagset["cs"] && flagset["sc"] { // Only one direction set, used same for reverse
345+
clientBwpStr = serverBwpStr
346+
fmt.Println("Only sc parameter set, using same values for cs")
347+
}
348+
clientBwp = parseBwtestParameters(clientBwpStr)
349+
clientBwp.Port = clientDCAddr.Host.L4.Port()
350+
if !flagset["sc"] && flagset["cs"] { // Only one direction set, used same for reverse
351+
serverBwpStr = clientBwpStr
352+
fmt.Println("Only cs parameter set, using same values for sc")
353+
}
354+
serverBwp = parseBwtestParameters(serverBwpStr)
355+
serverBwp.Port = serverDCAddr.Host.L4.Port()
345356

357+
fmt.Println("\nTest parameters:")
358+
fmt.Println("clientDCAddr -> serverDCAddr", clientDCAddr, "->", serverDCAddr)
359+
fmt.Printf("client->server: %d seconds, %d bytes, %d packets\n",
360+
int(clientBwp.BwtestDuration/time.Second), clientBwp.PacketSize, clientBwp.NumPackets)
361+
fmt.Printf("server->client: %d seconds, %d bytes, %d packets\n",
362+
int(serverBwp.BwtestDuration/time.Second), serverBwp.PacketSize, serverBwp.NumPackets)
363+
364+
if maxBandwidth {
365+
findMaxBandwidth(CCConn, DCConn, serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr, serverBwp, clientBwp)
346366
} else {
347-
if !flagset["cs"] && flagset["sc"] { // Only one direction set, used same for reverse
348-
clientBwpStr = serverBwpStr
349-
fmt.Println("Only sc parameter set, using same values for cs")
350-
}
351-
clientBwp = parseBwtestParameters(clientBwpStr)
352-
clientBwp.Port = uint16(clientPort + 1)
353-
if !flagset["sc"] && flagset["cs"] { // Only one direction set, used same for reverse
354-
serverBwpStr = clientBwpStr
355-
fmt.Println("Only cs parameter set, using same values for sc")
356-
}
357-
serverBwp = parseBwtestParameters(serverBwpStr)
358-
serverBwp.Port = serverPort + 1
359-
360-
fmt.Println("\nTest parameters:")
361-
fmt.Println("clientDCAddr -> serverDCAddr", clientDCAddr, "->", serverDCAddr)
362-
fmt.Printf("client->server: %d seconds, %d bytes, %d packets\n",
363-
int(clientBwp.BwtestDuration/time.Second), clientBwp.PacketSize, clientBwp.NumPackets)
364-
fmt.Printf("server->client: %d seconds, %d bytes, %d packets\n",
365-
int(serverBwp.BwtestDuration/time.Second), serverBwp.PacketSize, serverBwp.NumPackets)
366-
367-
singleRun(func() {
368-
Check(fmt.Errorf("Error, could not receive a server response, MaxTries attempted without success."))
369-
},
367+
368+
singleRun(CCConn, DCConn, serverBwp, clientBwp,
369+
func() {
370+
Check(fmt.Errorf("Error, could not receive a server response, MaxTries attempted without success."))
371+
},
370372
func() {
371373
Check(fmt.Errorf("Error, could not fetch server results, MaxTries attempted without success."))
372374
})
373375
}
374376
}
375377

376-
func findMaxBandwidth() {
378+
func findMaxBandwidth(CCConn, DCConn snet.Conn, serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr *snet.Addr,
379+
serverBwp, clientBwp BwtestParameters) {
377380
var (
378-
clientOldBw, serverOldBw, clientThreshold, serverThreshold int64
379-
serverMax, clientMax bool
380-
finished bool
381+
clientOldBw, serverOldBw int64
382+
clientThreshold, serverThreshold int64
383+
serverMax, clientMax bool
384+
finished bool
381385
// run is used to hold the number of the current run.
382386
run uint16
383387
)
384388

385-
// set the server and client bandwidth in the beginning to 512kbps
386-
serverBw, clientBw := int64(512e3), int64(512e3)
389+
// Calculate from bandwidth parameters from the user
390+
serverBw := (serverBwp.NumPackets * serverBwp.PacketSize * 8) / int64(serverBwp.BwtestDuration/time.Second)
391+
clientBw := (clientBwp.NumPackets * clientBwp.PacketSize * 8) / int64(clientBwp.BwtestDuration/time.Second)
387392

388393
for !finished {
389-
390394
run++
391395
fmt.Println(strings.Repeat("#", 50))
392396
fmt.Println("Run: ", run)
393397

394398
DCConn = resetConn(DCConn, clientDCAddr, serverDCAddr)
395399

396-
// Use the maximum duration to get more accurate results
397-
clientBwp = BwtestParameters{
398-
BwtestDuration: MaxDuration,
399-
PacketSize: InferedPktSize,
400-
NumPackets: (clientBw * 10) / (InferedPktSize * 8),
401-
PrgKey: prepareAESKey(),
402-
Port: uint16(clientPort + 1),
403-
}
404-
serverBwp = BwtestParameters{
405-
BwtestDuration: MaxDuration,
406-
PacketSize: InferedPktSize,
407-
NumPackets: (serverBw * 10) / (InferedPktSize * 8),
408-
PrgKey: prepareAESKey(),
409-
Port: serverPort + 1,
410-
}
400+
// calculate the new number of packets to send based on
401+
serverBwp.NumPackets = (serverBw * int64(serverBwp.BwtestDuration/time.Second)) / (serverBwp.PacketSize * 8)
402+
clientBwp.NumPackets = (clientBw * int64(clientBwp.BwtestDuration/time.Second)) / (clientBwp.PacketSize * 8)
411403

412-
fmt.Println("\nTest parameters:")
413-
fmt.Printf("client->server: %.3f Mbps\n", float64(clientBw)/1e6)
404+
fmt.Println("\nBandwidth values:")
414405
fmt.Printf("server->client: %.3f Mbps\n", float64(serverBw)/1e6)
406+
fmt.Printf("client->server: %.3f Mbps\n", float64(clientBw)/1e6)
415407

416-
res, sres, failed := singleRun(func() {
408+
res, sres, failed := singleRun(CCConn, DCConn, serverBwp, clientBwp, func() {
417409
handleSCError(&serverMax, &clientMax, &serverBw, &clientBw,
418410
&serverOldBw, &clientOldBw, &serverThreshold, &clientThreshold)
419411
}, func() {
@@ -424,20 +416,20 @@ func findMaxBandwidth() {
424416
//resetCCConn()
425417
CCConn = resetConn(CCConn, clientCCAddr, serverCCAddr)
426418
} else {
427-
ach := 8 * clientBwp.PacketSize * sres.CorrectlyReceived / int64(clientBwp.BwtestDuration/time.Second)
428-
handleBandwidth(&clientMax, &clientBw, &clientOldBw, &clientThreshold, ach, "client -> server")
429-
430-
ach = 8 * serverBwp.PacketSize * res.CorrectlyReceived / int64(serverBwp.BwtestDuration/time.Second)
419+
ach := 8 * serverBwp.PacketSize * res.CorrectlyReceived / int64(serverBwp.BwtestDuration/time.Second)
431420
handleBandwidth(&serverMax, &serverBw, &serverOldBw, &serverThreshold, ach, "server -> client")
421+
422+
ach = 8 * clientBwp.PacketSize * sres.CorrectlyReceived / int64(clientBwp.BwtestDuration/time.Second)
423+
handleBandwidth(&clientMax, &clientBw, &clientOldBw, &clientThreshold, ach, "client -> server")
432424
}
433425

434426
// Check if we found the maximum bandwidth for the client and the server
435427
finished = clientMax && serverMax
436428
time.Sleep(time.Second)
437429
}
438430

439-
fmt.Println("Max client to server available bandwidth: ", float64(clientBw)/1e6, " Mbps")
440-
fmt.Println("Max server to client available bandwidth: ", float64(serverBw)/1e6, " Mbps")
431+
fmt.Println("Max server -> client available bandwidth: ", float64(serverBw)/1e6, " Mbps")
432+
fmt.Println("Max client -> server available bandwidth: ", float64(clientBw)/1e6, " Mbps")
441433
os.Exit(0)
442434
}
443435

@@ -554,7 +546,10 @@ func decreaseBandwidth(currentBandwidth, threshold, achievedBandwidth, oldBandwi
554546
// initConns sets up the paths to the server, initializes the Control Channel
555547
// connection, sets up the Data connection addresses, starts the Data Channel
556548
// connection, then it updates packet size.
557-
func initConns() {
549+
func initConns(serverCCAddr, clientCCAddr *snet.Addr, pathAlgo string, interactive bool) (CCConn,
550+
DCConn snet.Conn, serverDCAddr, clientDCAddr *snet.Addr, err error) {
551+
var pathEntry *sciond.PathReplyEntry
552+
558553
// Setup the paths and
559554
if !serverCCAddr.IA.Eq(clientCCAddr.IA) {
560555
if interactive {
@@ -580,11 +575,12 @@ func initConns() {
580575

581576
// Control channel connection
582577
CCConn, err = snet.DialSCION(overlayType, clientCCAddr, serverCCAddr)
583-
Check(err)
584-
578+
if err != nil {
579+
return
580+
}
585581
// get the port used by clientCC after it bound to the dispatcher (because it might be 0)
586-
clientPort = uint((CCConn.LocalAddr()).(*snet.Addr).Host.L4.Port())
587-
serverPort = serverCCAddr.Host.L4.Port()
582+
clientPort := uint((CCConn.LocalAddr()).(*snet.Addr).Host.L4.Port())
583+
serverPort := serverCCAddr.Host.L4.Port()
588584

589585
//Address of client data channel (DC)
590586
clientDCAddr = &snet.Addr{IA: clientCCAddr.IA, Host: &addr.AppAddr{
@@ -604,18 +600,22 @@ func initConns() {
604600

605601
//Data channel connection
606602
DCConn, err = snet.DialSCION(overlayType, clientDCAddr, serverDCAddr)
607-
Check(err)
608-
603+
if err != nil {
604+
return
605+
}
609606
// update default packet size to max MTU on the selected path
610607
if pathEntry != nil {
611608
InferedPktSize = int64(pathEntry.Path.Mtu)
612609
} else {
613610
// use default packet size when within same AS and pathEntry is not set
614611
InferedPktSize = DefaultPktSize
615612
}
613+
614+
return
616615
}
617616

618617
func resetConn(conn snet.Conn, localAddress, remoteAddress *snet.Addr) snet.Conn {
618+
var err error
619619
_ = conn.Close()
620620

621621
// give it time to close the connection before trying to open it again
@@ -632,7 +632,11 @@ func resetConn(conn snet.Conn, localAddress, remoteAddress *snet.Addr) snet.Conn
632632
// It should be called right after setting up the flags to start the test.
633633
// Returns the bandwidth test results and a boolean to indicate a
634634
//// failure in the measurements (when max tries is reached).
635-
func startTest() (*BwtestResult, bool) {
635+
func startTest(CCConn, DCConn snet.Conn, serverBwp, clientBwp BwtestParameters,
636+
receiveDone chan struct{}) (*BwtestResult, bool) {
637+
var tzero time.Time
638+
var err error
639+
636640
t := time.Now()
637641
expFinishTimeSend := t.Add(serverBwp.BwtestDuration + MaxRTT + GracePeriodSend)
638642
expFinishTimeReceive := t.Add(clientBwp.BwtestDuration + MaxRTT + StragglerWaitPeriod)
@@ -713,7 +717,10 @@ func startTest() (*BwtestResult, bool) {
713717
// (See normalRun for an example).
714718
// Returns the bandwidth test results and a boolean to indicate a
715719
// failure in the measurements (when max tries is reached).
716-
func fetchResults() (*BwtestResult, bool) {
720+
func fetchResults(CCConn snet.Conn, clientBwp BwtestParameters) (*BwtestResult, bool) {
721+
var tzero time.Time
722+
var err error
723+
717724
pktbuf := make([]byte, 2000)
718725
var numtries int64 = 0
719726
sres := &BwtestResult{NumPacketsReceived: -1,
@@ -796,7 +803,7 @@ func printResults(res *BwtestResult, bwp BwtestParameters) {
796803
ach := 8 * bwp.PacketSize * res.CorrectlyReceived / int64(bwp.BwtestDuration/time.Second)
797804
fmt.Printf("Attempted bandwidth: %d bps / %.3f Mbps\n", att, float64(att)/1e6)
798805
fmt.Printf("Achieved bandwidth: %d bps / %.3f Mbps\n", ach, float64(ach)/1e6)
799-
loss := float32(bwp.NumPackets-res.CorrectlyReceived) * 100 / float32(serverBwp.NumPackets)
806+
loss := float32(bwp.NumPackets-res.CorrectlyReceived) * 100 / float32(bwp.NumPackets)
800807
fmt.Println("Loss rate:", loss, "%")
801808
variance := res.IPAvar
802809
average := res.IPAavg
@@ -808,8 +815,10 @@ func printResults(res *BwtestResult, bwp BwtestParameters) {
808815

809816
// singleRun runs a single bandwidth test based in the clientBwp and serverBwp.
810817
// The test parameters should be set before using this function.
811-
func singleRun(scError, csError func()) (res, sres *BwtestResult, failed bool) {
812-
res, failed = startTest()
818+
func singleRun(CCConn, DCConn snet.Conn, serverBwp, clientBwp BwtestParameters, scError,
819+
csError func()) (res, sres *BwtestResult, failed bool) {
820+
receiveDone := make(chan struct{})
821+
res, failed = startTest(CCConn, DCConn, serverBwp, clientBwp, receiveDone)
813822
if failed {
814823
scError()
815824
return
@@ -822,7 +831,7 @@ func singleRun(scError, csError func()) (res, sres *BwtestResult, failed bool) {
822831
printResults(res, serverBwp)
823832

824833
// Fetch results from server
825-
sres, failed = fetchResults()
834+
sres, failed = fetchResults(CCConn, clientBwp)
826835
if failed {
827836
csError()
828837
return

0 commit comments

Comments
 (0)