-
Notifications
You must be signed in to change notification settings - Fork 23
/
irtt_server.go
183 lines (166 loc) · 7.46 KB
/
irtt_server.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package irtt
import (
"os"
"os/signal"
"strings"
"syscall"
flag "github.com/ogier/pflag"
)
func serverUsage() {
setBufio()
printf("Options:")
printf("--------")
printf("")
printf("-b addresses bind addresses (default \"%s\"), comma separated list of:", strings.Join(DefaultBindAddrs, ","))
printf(" :port (unspecified address with port, use with care)")
printf(" host (host with default port %s, see Host formats below)", DefaultPort)
printf(" host:port (host with specified port, see Host formats below)")
printf(" %%iface (all addresses on interface iface with default port %s)", DefaultPort)
printf(" %%iface:port (all addresses on interface iface with port)")
printf(" note: iface strings may contain * to match multiple interfaces")
printf("-d duration max test duration, or 0 for no maximum")
printf(" (default %s, see Duration units below)", DefaultMaxDuration)
printf("-i interval min send interval, or 0 for no minimum")
printf(" (default %s, see Duration units below)", DefaultMinInterval)
printf("-l length max packet length (default %d), or 0 for no maximum", DefaultMaxLength)
printf(" numbers too small will cause test packets to be dropped")
printf("--hmac=key add HMAC with key (0x for hex) to all packets, provides:")
printf(" dropping of all packets without a correct HMAC")
printf(" protection for server against unauthorized discovery and use")
if syslogSupport {
printf("--syslog=uri log events to syslog (default don't use syslog)")
printf(" URI format: scheme://host:port/tag, examples:")
printf(" local: log to local syslog, default tag irtt")
printf(" local:/irttsrv: log to local syslog, tag irttsrv")
printf(" udp://logsrv:514/irttsrv: UDP to logsrv:514, tag irttsrv")
printf(" tcp://logsrv:8514/: TCP to logsrv:8514, default tag irtt")
}
printf("--timeout=dur timeout for closing connections if no requests received")
printf(" 0 means no timeout (not recommended on public servers)")
printf(" max client interval will be restricted to timeout/%d", maxIntervalTimeoutFactor)
printf(" (default %s, see Duration units below)", DefaultServerTimeout)
printf("--pburst=# packet burst allowed before enforcing minimum interval")
printf(" (default %d)", DefaultPacketBurst)
printf("--fill=fill payload fill if not requested (default %s)", DefaultServerFiller.String())
printf(" none: echo client payload (insecure on public servers)")
for _, ffac := range FillerFactories {
printf(" %s", ffac.Usage)
}
printf("--allow-fills= comma separated patterns of fill requests to allow (default %s)", strings.Join(DefaultAllowFills, ","))
printf(" fills see options for --fill")
printf(" allowing non-random fills insecure on public servers")
printf(" use --allow-fills=\"\" to disallow all fill requests")
printf(" note: patterns may contain * for matching")
printf("--tstamp=modes timestamp modes to allow (default %s)", DefaultAllowStamp)
printf(" none: don't allow timestamps")
printf(" single: allow a single timestamp (send, receive or midpoint)")
printf(" dual: allow dual timestamps")
printf("--no-dscp don't allow setting dscp (default %t)", !DefaultAllowDSCP)
printf("-4 IPv4 only")
printf("-6 IPv6 only")
printf("--set-src-ip set source IP address on all outgoing packets from listeners")
printf(" on unspecified IP addresses (use for more reliable reply")
printf(" routing, but increases per-packet heap allocations)")
printf("--ecn Ship ECN bits to be logged by the client. Forces --set-src-ip, disables UDP replies")
printf("--thread lock request handling goroutines to OS threads")
printf("-h show help")
printf("-v show version")
printf("")
hostUsage()
printf("")
durationUsage()
}
// runServerCLI runs the server command line interface.
func runServerCLI(args []string) {
// server flags
fs := flag.NewFlagSet("server", 0)
fs.Usage = func() {
usageAndExit(serverUsage, exitCodeBadCommandLine)
}
var baddrsStr = fs.StringP("b", "b", strings.Join(DefaultBindAddrs, ","), "bind addresses")
var maxDuration = fs.DurationP("d", "d", DefaultMaxDuration, "max duration")
var minInterval = fs.DurationP("i", "i", DefaultMinInterval, "min interval")
var maxLength = fs.IntP("l", "l", DefaultMaxLength, "max length")
var allowTimestampStr = fs.String("tstamp", DefaultAllowStamp.String(), "allow timestamp")
var hmacStr = fs.String("hmac", defaultHMACKey, "HMAC key")
var syslogStr *string
if syslogSupport {
syslogStr = fs.String("syslog", "", "syslog uri")
}
var timeout = fs.Duration("timeout", DefaultServerTimeout, "timeout")
var packetBurst = fs.Int("pburst", DefaultPacketBurst, "packet burst")
var fillStr = fs.String("fill", DefaultServerFiller.String(), "fill")
var allowFillsStr = fs.String("allow-fills", strings.Join(DefaultAllowFills, ","), "sfill")
var ipv4 = fs.BoolP("4", "4", false, "IPv4 only")
var ipv6 = fs.BoolP("6", "6", false, "IPv6 only")
var ttl = fs.Int("ttl", DefaultTTL, "IP time to live")
var noDSCP = fs.Bool("no-dscp", !DefaultAllowDSCP, "no DSCP")
var setSrcIP = fs.Bool("set-src-ip", DefaultSetSrcIP, "set source IP")
var ecn = fs.Bool("ecn", DefaultSetECN, "enable ECN capture - disables UDP replies from server")
var lockOSThread = fs.Bool("thread", DefaultThreadLock, "thread")
var version = fs.BoolP("version", "v", false, "version")
fs.Parse(args)
// start profiling, if enabled in build
if profileEnabled {
defer startProfile("./server.pprof").Stop()
}
// version
if *version {
runVersion(args)
os.Exit(0)
}
// determine IP version
ipVer := IPVersionFromBooleans(*ipv4, *ipv6, DualStack)
// parse allow stamp string
allowStamp, err := ParseAllowStamp(*allowTimestampStr)
exitOnError(err, exitCodeBadCommandLine)
// parse fill
filler, err := NewFiller(*fillStr)
exitOnError(err, exitCodeBadCommandLine)
// parse HMAC key
var hmacKey []byte
if *hmacStr != "" {
hmacKey, err = decodeHexOrNot(*hmacStr)
exitOnError(err, exitCodeBadCommandLine)
}
// create event handler with console handler as default
handler := &MultiHandler{[]Handler{&consoleHandler{}}}
// add syslog event handler
if syslogStr != nil && *syslogStr != "" {
sh, err := newSyslogHandler(*syslogStr)
exitOnError(err, exitCodeRuntimeError)
handler.AddHandler(sh)
}
// create server config
cfg := NewServerConfig()
cfg.Addrs = strings.Split(*baddrsStr, ",")
cfg.MaxDuration = *maxDuration
cfg.MinInterval = *minInterval
cfg.AllowStamp = allowStamp
cfg.HMACKey = hmacKey
cfg.Timeout = *timeout
cfg.PacketBurst = *packetBurst
cfg.MaxLength = *maxLength
cfg.Filler = filler
cfg.AllowFills = strings.Split(*allowFillsStr, ",")
cfg.AllowDSCP = !*noDSCP
cfg.TTL = *ttl
cfg.Handler = handler
cfg.IPVersion = ipVer
cfg.SetSrcIP = *setSrcIP || *ecn
cfg.ThreadLock = *lockOSThread
// create server
s := NewServer(cfg)
// install signal handler to stop server
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
go func() {
sig := <-sigs
printf("%s", sig)
s.Shutdown()
sig = <-sigs
os.Exit(exitCodeDoubleSignal)
}()
err = s.ListenAndServe()
exitOnError(err, exitCodeRuntimeError)
}