Skip to content

Commit 8f025a8

Browse files
committed
Reduced number of global variables, and added support for cs and sc flags with find max bandwidth option
- Reduced global variables to 2 variables, all others are scoped local variables. - initConns function takes client and server addresses as input (along with pathAlgo and interactive for choosing the paths while setting up the addresses), and returns the connections 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 8f025a8

File tree

1 file changed

+124
-113
lines changed

1 file changed

+124
-113
lines changed

bwtester/bwtestclient/bwtestclient.go

Lines changed: 124 additions & 113 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,78 @@ func main() {
338336
sciondPath = sciond.GetDefaultSCIONDPath(nil)
339337
}
340338

341-
initConns()
339+
// initalize the addresses before passing them
340+
serverDCAddr, clientDCAddr = &snet.Addr{}, &snet.Addr{}
341+
CCConn, DCConn, err = initConns(serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr, pathAlgo, interactive)
342+
if err != nil {
343+
Check(err)
344+
}
342345

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

359+
fmt.Println("\nTest parameters:")
360+
fmt.Println("clientDCAddr -> serverDCAddr", clientDCAddr, "->", serverDCAddr)
361+
fmt.Printf("client->server: %d seconds, %d bytes, %d packets\n",
362+
int(clientBwp.BwtestDuration/time.Second), clientBwp.PacketSize, clientBwp.NumPackets)
363+
fmt.Printf("server->client: %d seconds, %d bytes, %d packets\n",
364+
int(serverBwp.BwtestDuration/time.Second), serverBwp.PacketSize, serverBwp.NumPackets)
365+
366+
if maxBandwidth {
367+
findMaxBandwidth(CCConn, DCConn, serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr, serverBwp, clientBwp)
346368
} 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-
},
369+
370+
singleRun(CCConn, DCConn, serverBwp, clientBwp,
371+
func() {
372+
Check(fmt.Errorf("Error, could not receive a server response, MaxTries attempted without success."))
373+
},
370374
func() {
371375
Check(fmt.Errorf("Error, could not fetch server results, MaxTries attempted without success."))
372376
})
373377
}
374378
}
375379

376-
func findMaxBandwidth() {
380+
func findMaxBandwidth(CCConn, DCConn snet.Conn, serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr *snet.Addr,
381+
serverBwp, clientBwp BwtestParameters) {
377382
var (
378-
clientOldBw, serverOldBw, clientThreshold, serverThreshold int64
379-
serverMax, clientMax bool
380-
finished bool
383+
clientOldBw, serverOldBw int64
384+
clientThreshold, serverThreshold int64
385+
serverMax, clientMax bool
386+
finished bool
381387
// run is used to hold the number of the current run.
382388
run uint16
383389
)
384390

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

388395
for !finished {
389-
390396
run++
391397
fmt.Println(strings.Repeat("#", 50))
392398
fmt.Println("Run: ", run)
393399

394400
DCConn = resetConn(DCConn, clientDCAddr, serverDCAddr)
395401

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-
}
402+
// calculate the new number of packets to send based on
403+
serverBwp.NumPackets = (serverBw * int64(serverBwp.BwtestDuration/time.Second)) / (serverBwp.PacketSize * 8)
404+
clientBwp.NumPackets = (clientBw * int64(clientBwp.BwtestDuration/time.Second)) / (clientBwp.PacketSize * 8)
411405

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

416-
res, sres, failed := singleRun(func() {
410+
res, sres, failed := singleRun(CCConn, DCConn, serverBwp, clientBwp, func() {
417411
handleSCError(&serverMax, &clientMax, &serverBw, &clientBw,
418412
&serverOldBw, &clientOldBw, &serverThreshold, &clientThreshold)
419413
}, func() {
@@ -424,20 +418,20 @@ func findMaxBandwidth() {
424418
//resetCCConn()
425419
CCConn = resetConn(CCConn, clientCCAddr, serverCCAddr)
426420
} 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)
421+
ach := 8 * serverBwp.PacketSize * res.CorrectlyReceived / int64(serverBwp.BwtestDuration/time.Second)
431422
handleBandwidth(&serverMax, &serverBw, &serverOldBw, &serverThreshold, ach, "server -> client")
423+
424+
ach = 8 * clientBwp.PacketSize * sres.CorrectlyReceived / int64(clientBwp.BwtestDuration/time.Second)
425+
handleBandwidth(&clientMax, &clientBw, &clientOldBw, &clientThreshold, ach, "client -> server")
432426
}
433427

434428
// Check if we found the maximum bandwidth for the client and the server
435429
finished = clientMax && serverMax
436430
time.Sleep(time.Second)
437431
}
438432

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")
433+
fmt.Println("Max server -> client available bandwidth: ", float64(serverBw)/1e6, " Mbps")
434+
fmt.Println("Max client -> server available bandwidth: ", float64(clientBw)/1e6, " Mbps")
441435
os.Exit(0)
442436
}
443437

@@ -554,7 +548,10 @@ func decreaseBandwidth(currentBandwidth, threshold, achievedBandwidth, oldBandwi
554548
// initConns sets up the paths to the server, initializes the Control Channel
555549
// connection, sets up the Data connection addresses, starts the Data Channel
556550
// connection, then it updates packet size.
557-
func initConns() {
551+
func initConns(serverCCAddr, serverDCAddr, clientCCAddr, clientDCAddr *snet.Addr, pathAlgo string, interactive bool) (CCConn,
552+
DCConn snet.Conn, err error) {
553+
var pathEntry *sciond.PathReplyEntry
554+
558555
// Setup the paths and
559556
if !serverCCAddr.IA.Eq(clientCCAddr.IA) {
560557
if interactive {
@@ -580,17 +577,18 @@ func initConns() {
580577

581578
// Control channel connection
582579
CCConn, err = snet.DialSCION(overlayType, clientCCAddr, serverCCAddr)
583-
Check(err)
584-
580+
if err != nil {
581+
return
582+
}
585583
// 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()
584+
clientPort := uint((CCConn.LocalAddr()).(*snet.Addr).Host.L4.Port())
585+
serverPort := serverCCAddr.Host.L4.Port()
588586

589587
//Address of client data channel (DC)
590-
clientDCAddr = &snet.Addr{IA: clientCCAddr.IA, Host: &addr.AppAddr{
588+
*clientDCAddr = snet.Addr{IA: clientCCAddr.IA, Host: &addr.AppAddr{
591589
L3: clientCCAddr.Host.L3, L4: addr.NewL4UDPInfo(uint16(clientPort) + 1)}}
592590
// Address of server data channel (DC)
593-
serverDCAddr = &snet.Addr{IA: serverCCAddr.IA, Host: &addr.AppAddr{
591+
*serverDCAddr = snet.Addr{IA: serverCCAddr.IA, Host: &addr.AppAddr{
594592
L3: serverCCAddr.Host.L3, L4: addr.NewL4UDPInfo(serverPort + 1)}}
595593

596594
// Set path on data connection
@@ -604,18 +602,22 @@ func initConns() {
604602

605603
//Data channel connection
606604
DCConn, err = snet.DialSCION(overlayType, clientDCAddr, serverDCAddr)
607-
Check(err)
608-
605+
if err != nil {
606+
return
607+
}
609608
// update default packet size to max MTU on the selected path
610609
if pathEntry != nil {
611610
InferedPktSize = int64(pathEntry.Path.Mtu)
612611
} else {
613612
// use default packet size when within same AS and pathEntry is not set
614613
InferedPktSize = DefaultPktSize
615614
}
615+
616+
return
616617
}
617618

618619
func resetConn(conn snet.Conn, localAddress, remoteAddress *snet.Addr) snet.Conn {
620+
var err error
619621
_ = conn.Close()
620622

621623
// give it time to close the connection before trying to open it again
@@ -632,7 +634,11 @@ func resetConn(conn snet.Conn, localAddress, remoteAddress *snet.Addr) snet.Conn
632634
// It should be called right after setting up the flags to start the test.
633635
// Returns the bandwidth test results and a boolean to indicate a
634636
//// failure in the measurements (when max tries is reached).
635-
func startTest() (*BwtestResult, bool) {
637+
func startTest(CCConn, DCConn snet.Conn, serverBwp, clientBwp BwtestParameters,
638+
receiveDone chan struct{}) (*BwtestResult, bool) {
639+
var tzero time.Time
640+
var err error
641+
636642
t := time.Now()
637643
expFinishTimeSend := t.Add(serverBwp.BwtestDuration + MaxRTT + GracePeriodSend)
638644
expFinishTimeReceive := t.Add(clientBwp.BwtestDuration + MaxRTT + StragglerWaitPeriod)
@@ -713,7 +719,10 @@ func startTest() (*BwtestResult, bool) {
713719
// (See normalRun for an example).
714720
// Returns the bandwidth test results and a boolean to indicate a
715721
// failure in the measurements (when max tries is reached).
716-
func fetchResults() (*BwtestResult, bool) {
722+
func fetchResults(CCConn snet.Conn, clientBwp BwtestParameters) (*BwtestResult, bool) {
723+
var tzero time.Time
724+
var err error
725+
717726
pktbuf := make([]byte, 2000)
718727
var numtries int64 = 0
719728
sres := &BwtestResult{NumPacketsReceived: -1,
@@ -796,7 +805,7 @@ func printResults(res *BwtestResult, bwp BwtestParameters) {
796805
ach := 8 * bwp.PacketSize * res.CorrectlyReceived / int64(bwp.BwtestDuration/time.Second)
797806
fmt.Printf("Attempted bandwidth: %d bps / %.3f Mbps\n", att, float64(att)/1e6)
798807
fmt.Printf("Achieved bandwidth: %d bps / %.3f Mbps\n", ach, float64(ach)/1e6)
799-
loss := float32(bwp.NumPackets-res.CorrectlyReceived) * 100 / float32(serverBwp.NumPackets)
808+
loss := float32(bwp.NumPackets-res.CorrectlyReceived) * 100 / float32(bwp.NumPackets)
800809
fmt.Println("Loss rate:", loss, "%")
801810
variance := res.IPAvar
802811
average := res.IPAavg
@@ -808,8 +817,10 @@ func printResults(res *BwtestResult, bwp BwtestParameters) {
808817

809818
// singleRun runs a single bandwidth test based in the clientBwp and serverBwp.
810819
// 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()
820+
func singleRun(CCConn, DCConn snet.Conn, serverBwp, clientBwp BwtestParameters, scError,
821+
csError func()) (res, sres *BwtestResult, failed bool) {
822+
receiveDone := make(chan struct{})
823+
res, failed = startTest(CCConn, DCConn, serverBwp, clientBwp, receiveDone)
813824
if failed {
814825
scError()
815826
return
@@ -822,7 +833,7 @@ func singleRun(scError, csError func()) (res, sres *BwtestResult, failed bool) {
822833
printResults(res, serverBwp)
823834

824835
// Fetch results from server
825-
sres, failed = fetchResults()
836+
sres, failed = fetchResults(CCConn, clientBwp)
826837
if failed {
827838
csError()
828839
return

0 commit comments

Comments
 (0)