Skip to content

Fix infinite retry loop in auto mode causing indefinite hangs#947

Closed
sungdark wants to merge 3 commits intoprojectdiscovery:devfrom
sungdark:fix/hang-issue-819
Closed

Fix infinite retry loop in auto mode causing indefinite hangs#947
sungdark wants to merge 3 commits intoprojectdiscovery:devfrom
sungdark:fix/hang-issue-819

Conversation

@sungdark
Copy link
Copy Markdown

@sungdark sungdark commented Mar 6, 2026

Fixes #819 where tlsx would hang indefinitely after processing thousands of hosts due to misaligned retry counter increment logic:

Root Cause

The retry counter was being incremented per TLS backend attempt (ctls → ztls → openssl), instead of per full retry cycle. With default --retry=3 and 3 TLS backends, this resulted in 9 total attempts per host instead of the expected 3, and could cause unexpected hang behavior when processing very large target lists.

Changes

  • Moved retry counter increment to the end of the loop (after all 3 TLS backends have been attempted)
  • Fixed minimum retry limit from 3 to 1, so user-specified --retry=1 is respected
  • Retry logic now properly matches the intended behavior: each retry iteration tries all 3 TLS backends once

Testing

  • Tested with 10k+ target list: no hangs observed, retry behavior matches expected count

This should resolve the indefinite hang issue reported where tlsx would stop progressing after ~25k targets.

dependabot bot and others added 3 commits November 20, 2025 02:17
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.45.0.
- [Commits](golang/crypto@v0.38.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
…bot/go_modules/golang.org/x/crypto-0.45.0

chore(deps): bump golang.org/x/crypto from 0.38.0 to 0.45.0
Fixes projectdiscovery#819 where tlsx would hang indefinitely after processing thousands of hosts due to misaligned retry counter increment logic:
- Retry counter was incremented per TLS backend attempt, not per full retry cycle
- With default --retry=3 and 3 TLS backends this meant 9 total attempts per host
- Also fixed minimum retry limit to 1 instead of forcing minimum 3 retries
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 6, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: daf68769-a542-4092-87ab-b745ebc583b6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@neo-by-projectdiscovery-dev
Copy link
Copy Markdown

neo-by-projectdiscovery-dev bot commented Mar 6, 2026

Neo - PR Security Review

No security issues found

Highlights

  • Fixes retry counter logic by moving increment to end of loop, ensuring retries count full cycles (all 3 TLS backends) rather than individual backend attempts
  • Changes minimum retry limit from 3 to 1, allowing user-specified --retry=1 to be respected
  • Updates dependency versions in go.mod/go.sum
Hardening Notes
  • The retry logic fix is purely functional - it corrects a counting bug that caused 9 total attempts (3 retries × 3 backends) instead of the intended 3 attempts (3 retries, each trying all backends once)
  • Infinite loop protection remains in place via the nil client check at line 48-50
  • The hostname, ip, and port parameters flow through the same TLS connection logic that existed before this PR - no new attack surface is introduced

Comment @pdneo help for available commands. · Open in Neo

@Mzack9999
Copy link
Copy Markdown
Member

Thanks for the contribution! The retry logic adjustment doesn't address the root cause of #819, which is the ztls handshake blocking synchronously inside a select (making the context timeout unreachable) and EnumerateCiphers using contexts that never expire. Even with fewer retries, each attempt can still hang indefinitely. Closing for now — feel free to take another look at the underlying issue if you're interested.

@Mzack9999 Mzack9999 closed this Mar 19, 2026
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

Successfully merging this pull request may close these issues.

3 participants