-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
97 lines (82 loc) · 3.69 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"fmt"
"log"
"math"
"os"
"path"
"gitlab.lrz.de/protocol-design-sose-2022-team-0/sanft/client"
"gitlab.lrz.de/protocol-design-sose-2022-team-0/sanft/server"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
host = kingpin.Arg("host", "The host to request from (hostname or IPv4 address).").ResolvedIP()
serverMode = kingpin.Flag("server", "Server mode: accept incoming requests from any host. Operate in client mode if “-s” is not specified.").Short('s').Default("false").Bool()
port = kingpin.Flag("port", "Specify the port number to use (use 1337 as default if not given).").Default("1337").Short('t').Int()
markovP = kingpin.Flag("p", "Specify the loss probabilities for the Markov chain model.").Short('p').Default("0").Float64()
markovQ = kingpin.Flag("q", "Specify the loss probabilities for the Markov chain model.").Short('q').Default("0").Float64()
fileDir = kingpin.Flag("file-dir", "Server: Specify the directory containing the files that the server should serve. Client: Specify the directory where the requested files will be saved").Short('d').Default("./").ExistingDir()
chunkSize = kingpin.Flag("chunk-size", "The chunk size advertised and used by the server.").Default("4048").Int()
maxChunksInACR = kingpin.Flag("max-chunks-in-acr", "The maximum number of chunks in an ACR allowed by the server.").Default("128").Int()
rateIncrease = kingpin.Flag("rate-increase", "Amount that the server sending rate should be increased in packet per second.").Default("256").Float64()
files = kingpin.Arg("files", "The name of the file(s) to fetch.").Default("").Strings()
)
func main() {
kingpin.Parse()
// check that p and q are valid
if *markovP > 1 || *markovP < 0 || *markovQ > 1 || *markovQ < 0 {
fmt.Println("error: p and/or q values for the markov chain are invalid")
os.Exit(1)
}
if *host == nil {
fmt.Println("error: When running in client mode, a server IP/hostname must be provided! When running in server mode a host ip must be provided!")
os.Exit(1)
}
fmt.Printf("Host: %s, Server Mode: %t, port: %d, markovP: %f markovQ: %f, file-dir: %s, files: %s\n", *host, *serverMode, *port, *markovP, *markovQ, *fileDir, *files)
fmt.Println("files: ", *files)
if *serverMode { /* server mode */
// replace empty path with "." and add trailing "/"
if *fileDir == "" {
*fileDir = "./"
}
folder := *fileDir
if folder[len(folder)-1] != '/' {
folder = folder + "/"
}
// Protocol specification limitations
if *chunkSize == 0 || *chunkSize > 65517 {
fmt.Println("error: Chunk size must be non-zero and no larger than 65517")
os.Exit(1)
}
// Avoid an overflow when casting to uint16
if *maxChunksInACR == 0 || *maxChunksInACR > math.MaxUint16 {
fmt.Printf("error: max-chunks-in-acr must be non-zero and no larger than %d\n", math.MaxUint16)
os.Exit(1)
}
log.Println("Starting server")
s, err := server.Init(*host, *port, folder, uint16(*chunkSize), uint16(*maxChunksInACR),
*markovP, *markovQ, *rateIncrease)
if err != nil {
log.Panicf(`Error creating server: %v`, err)
}
defer s.Conn.Close()
close := make(chan bool)
s.Listen(close)
} else { /* client mode */
if len(*files) < 1 {
fmt.Println("error: When running in client mode, at least one file URI must be provided!")
os.Exit(1)
}
clientConfig := client.DefaultConfig
clientConfig.MarkovP = *markovP
clientConfig.MarkovQ = *markovQ
// Request files sequentially
for _, file := range *files {
localFileName := path.Join(*fileDir, file)
err := client.RequestFile(*host, *port, file, localFileName, &clientConfig)
if err != nil {
fmt.Printf("File request for %q failed: %v\n", file, err)
}
}
}
}