Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should I wait for ports to clear between attacks? #718

Open
jtlapp opened this issue Nov 9, 2024 · 0 comments
Open

Should I wait for ports to clear between attacks? #718

jtlapp opened this issue Nov 9, 2024 · 0 comments

Comments

@jtlapp
Copy link

jtlapp commented Nov 9, 2024

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)
	}
@jtlapp jtlapp changed the title Should I be waiting for ports to clear between attacks? Should I wait for ports to clear between attacks? Nov 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant