fix: make ztls handshake timeout interruptible#967
fix: make ztls handshake timeout interruptible#967drmabus wants to merge 2 commits intoprojectdiscovery:mainfrom
Conversation
Handshake() was executed inline inside a select, making the timeout ineffective. This change moves the handshake into a goroutine and properly races ctx.Done() against the result.
Neo - PR Security ReviewNo security issues found Highlights
Comment |
WalkthroughtlsHandshakeWithTimeout now runs the TLS handshake in a goroutine, sending the handshake error to a channel and returning directly from the select branches; deferred channel close and the extra post-select receive were removed. tls.ErrCertsOnly is still mapped to nil before returning. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
pkg/tlsx/ztls/ztls.go (1)
327-338: Fix is correct; prefererrors.Is()for error comparison.The change correctly moves the handshake into a goroutine, allowing
ctx.Done()to properly race against the handshake result. The buffered channel (size 1) ensures the goroutine won't block when timeout occurs.However, using direct equality for error comparison at line 335 is less idiomatic and won't catch wrapped errors. Consider using
errors.Is():♻️ Suggested improvement
case err := <-errChan: - if err == tls.ErrCertsOnly { + if errors.Is(err, tls.ErrCertsOnly) { err = nil } return err🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/tlsx/ztls/ztls.go` around lines 327 - 338, Replace the direct error equality check against tls.ErrsOnly in the handshake goroutine result with errors.Is to correctly detect wrapped errors: inside the select case that receives err from errChan (the handshake launched with tlsConn.Handshake()), change the comparison `if err == tls.ErrCertsOnly` to `if errors.Is(err, tls.ErrCertsOnly)` and ensure the package imports the standard "errors" package if not already present so wrapped errors are handled properly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@pkg/tlsx/ztls/ztls.go`:
- Around line 327-338: Replace the direct error equality check against
tls.ErrsOnly in the handshake goroutine result with errors.Is to correctly
detect wrapped errors: inside the select case that receives err from errChan
(the handshake launched with tlsConn.Handshake()), change the comparison `if err
== tls.ErrCertsOnly` to `if errors.Is(err, tls.ErrCertsOnly)` and ensure the
package imports the standard "errors" package if not already present so wrapped
errors are handled properly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 10059aa3-b6f3-4f3c-98f6-cc8a20fe2195
📒 Files selected for processing (1)
pkg/tlsx/ztls/ztls.go
|
updated to use errors.Is for proper wrapped error handling. |
|
Thanks for the contribution! This has been resolved by #949 which was merged into dev. Your fix correctly identified the synchronous handshake issue, but didn't address the goroutine leak on timeout (needs |
/claim #819
Closes #819
Handshake() was previously executed inline inside a select, which prevented ctx.Done() from interrupting the TLS handshake and made timeouts ineffective.
This change moves the handshake into a goroutine and properly races ctx.Done() against the handshake result.
Changes
Notes
A test failure was observed due to a nil pointer dereference after a handshake error in the existing test logic, which appears unrelated to this change.
Summary by CodeRabbit