-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Question
I've noticed that when an attack completes, many ports remain in the "established" or "time wait" states for some time afterward.
Should I be waiting for these ports to become available again between attacks? I know that I don't have to, but I'm worried that the number of ports in use at the start of an attack will affect the benchmark for the attack.
If so, what is the appropriate way to accomplish this? I've written the following code, but my program eventually hits Postgres on the local machine, which subsequently keeps ports open. That makes this approach untenable unless I hard-code initialPortsInUse to the number of ports Postgres seems to subsequently keep open. I'd rather have Vegeta wait for all the ports it knowns it opened to free.
func WaitForPortsToClear(initialPortsInUse uint) {
timeWaitPortsCount, establishedPortsCount := getPortsInUseCounts()
for timeWaitPortsCount+establishedPortsCount > initialPortsInUse {
time.Sleep(time.Second)
timeWaitPortsCount, establishedPortsCount = getPortsInUseCounts()
}
}
func getPortsInUseCounts() (timeWaitCount, establishedCount uint) {
data, err := os.ReadFile("/proc/net/tcp")
if err != nil {
panic(err)
}
// Skip header line
lines := strings.Split(string(data), "\n")[1:]
// Column 4 contains the connection state in hex
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) >= 4 {
state := fields[3]
switch state {
case "06":
timeWaitCount++
case "01":
establishedCount++
}
}
}
return timeWaitCount, establishedCount
}Here's my attack:
attacker := vegeta.NewAttacker(
vegeta.Workers(uint64(br.testConfig.WorkerCount)),
vegeta.Connections(br.testConfig.MaxConnections),
vegeta.Timeout(time.Duration(br.testConfig.RequestTimeoutSeconds)*time.Second),
vegeta.KeepAlive(true),
)
rateLimiter := vegeta.Rate{Freq: rate, Per: time.Second}
duration := time.Duration(durationSeconds) * time.Second
var metrics vegeta.Metrics
for res := range attacker.Attack(targetProvider, rateLimiter, duration, "") {
br.logger.Log(res.Code, string(res.Body))
metrics.Add(res)
}