fix(session): resolve race conditions #151

Merged
bagas merged 4 commits from fix/session-race-conditions into staging 2026-07-17 22:22:25 +07:00
Owner

Summary

Comprehensive fixes for race conditions, concurrency bugs, and a critical session handling bug across the session package and its child packages.

Changes

Bug Fix: waitForTCPIPForward fails on non-tcpip-forward global requests

  • Changed waitForTCPIPForward() from a single select to a for loop that drains non-tcpip-forward requests gracefully
  • Non-tcpip-forward requests now receive a false reply and the function continues waiting for the actual forward request
  • The 500ms timeout resets after each request to handle slow clients with multiple early requests
  • Updated and added tests to cover the new behavior: Wrong_Request_Type_Then_Timeout, Multiple_Non-Forward_Requests_Then_Success, Timeout_After_Non-Forward_Requests

Race Condition Fixes

  • Added sync.RWMutex to the forwarder struct to protect concurrent field access
  • Fixed data race in forwarder setters (SetType(), SetForwardedPort(), SetListener()) by adding Lock()/Unlock() protection
  • Fixed data race in forwarder getters (TunnelType(), ForwardedPort(), Listener()) by adding RLock()/RUnlock() protection
  • Added sync.RWMutex to the slug struct to protect concurrent field access
  • Fixed data race in slug.Set() by adding Lock()/Unlock() protection
  • Fixed data race in slug.String() by adding RLock()/RUnlock() protection

Concurrency Safety Improvements

  • Changed OpenForwardedChannel() to use f.ForwardedPort() getter instead of direct field access
  • Fixed Close() in forwarder to use f.Listener() getter consistently instead of accessing f.listener directly
  • Fixed data race in HandleTCPForward() where the goroutine running tcpServer.Serve(listener) wrote to the outer err variable from the enclosing function scope
  • Changed err = tcpServer.Serve(listener) to if err := tcpServer.Serve(listener) so the goroutine uses a local variable
## Summary Comprehensive fixes for race conditions, concurrency bugs, and a critical session handling bug across the session package and its child packages. ## Changes ### Bug Fix: waitForTCPIPForward fails on non-tcpip-forward global requests - Changed `waitForTCPIPForward()` from a single select to a for loop that drains non-tcpip-forward requests gracefully - Non-tcpip-forward requests now receive a false reply and the function continues waiting for the actual forward request - The 500ms timeout resets after each request to handle slow clients with multiple early requests - Updated and added tests to cover the new behavior: Wrong_Request_Type_Then_Timeout, Multiple_Non-Forward_Requests_Then_Success, Timeout_After_Non-Forward_Requests ### Race Condition Fixes - Added sync.RWMutex to the forwarder struct to protect concurrent field access - Fixed data race in forwarder setters (`SetType()`, `SetForwardedPort()`, `SetListener()`) by adding `Lock()`/`Unlock()` protection - Fixed data race in forwarder getters (`TunnelType()`, `ForwardedPort()`, `Listener()`) by adding `RLock()`/`RUnlock()` protection - Added sync.RWMutex to the slug struct to protect concurrent field access - Fixed data race in `slug.Set()` by adding `Lock()`/`Unlock()` protection - Fixed data race in `slug.String()` by adding `RLock()`/`RUnlock()` protection ### Concurrency Safety Improvements - Changed `OpenForwardedChannel()` to use `f.ForwardedPort()` getter instead of direct field access - Fixed `Close()` in forwarder to use `f.Listener()` getter consistently instead of accessing `f.listener` directly - Fixed data race in `HandleTCPForward()` where the goroutine running `tcpServer.Serve(listener)` wrote to the outer err variable from the enclosing function scope - Changed err = `tcpServer.Serve(listener)` to `if err := tcpServer.Serve(listener)` so the goroutine uses a local variable
bagas added 4 commits 2026-07-16 21:00:51 +07:00
fix: race condition for err variable at session package
Tests / Run Tests (pull_request) Successful in 3m10s
Docker Build and Push / Run Tests (push) Successful in 3m16s
Docker Build and Push / Build and Push Docker Image (push) Successful in 15m8s
198147c676
bagas merged commit 6fd25387f7 into staging 2026-07-17 22:22:25 +07:00
bagas deleted branch fix/session-race-conditions 2026-07-18 18:16:15 +07:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bagas/tunnel-please#151