Troubleshooting Connection Timeouts and Implementing Retry Logic in Patator
Patator employs a dual-layer timeout strategy combining UNIX signal alarms with module-level socket timeouts, paired with a configurable retry loop that supports linear back-off and user-defined conditional triggers.
When brute-forcing services across unreliable networks, handling intermittent failures is critical. The Patator framework implements robust troubleshooting connection timeouts and implementing retry logic mechanisms directly in its core controller located in src/patator/patator.py. These features ensure that transient network issues do not terminate valid attack sequences while preventing infinite loops on permanently offline hosts.
Global Timeout Configuration and Signal-Based Enforcement
Patator exposes a global --timeout parameter (defined at line 826) that controls how long the framework waits for a single payload attempt. Internally, the Controller class stores this value and activates a UNIX-specific alarm mechanism through the enable_alarm method found around line 647.
When a payload executes, the controller invokes signal.alarm(self.timeout) before calling the module's execute method. If the operation exceeds the specified duration, the raise_timeout handler (line 643) interrupts execution by raising a TimeoutError. This signal-based approach ensures that hanging connections cannot block the consumer thread indefinitely.
The alarm is automatically cleared in the exception handling block (lines 1406-1419), where the framework constructs a generic failure Response and optionally invokes the module's reset method to purge persistent connections.
Module-Level Socket Timeouts
Beyond the controller-level alarm, Patator propagates the timeout value to underlying network libraries to ensure consistent behavior. Each module forwards the timeout argument to its specific implementation:
- HTTP module: Sets
pycurl.TIMEOUT(line 3275) - SSH/FTP modules: Pass timeout to
socket.create_connection()or library constructors likeFTP(timeout=int(timeout))
This dual enforcement ensures that even on platforms where signal alarms are unavailable, the underlying socket operations respect the user-defined limits.
Configurable Retry Logic with Linear Back-Off
Patator implements implementing retry logic through a dedicated retry loop in the consumer thread (starting at line 1399). The --max-retries option (default 4, defined at line 827) controls how many additional attempts occur after an initial failure.
The retry mechanism operates as follows:
- Initialize
try_countat 0 - Check condition:
if try_count <= self.max_retries or self.max_retries < 0: - On failure, increment counter and sleep for
try_count * 0.1seconds (lines 1424-1425) - If the module exposes a
resetmethod, invoke it to close stale connections (lines 1421-1422) - Repeat until success or limit reached
Setting --max-retries -1 enables unlimited retries, useful when probing intermittently available services.
# Basic usage with 10-second timeout and 3 retries
patator ssh_login host=10.0.0.1 user=FILE0 0=users.txt password=FILE1 \
--timeout 10 --max-retries 3
Dynamic Retry Actions for Conditional Logic
Users can define granular retry conditions using the -x retry: action syntax. When specified, Patator evaluates response conditions (status codes, error messages) and injects the 'retry' action into the processing pipeline.
The lookup_actions function parses these rules, and the report_progress method handles them in the consume loop (around lines 1450-1454). When 'retry' appears in the action set, the loop continues without marking the payload as completed, subject to the global retry limit.
# Retry only on 5xx HTTP errors, fail immediately on 4xx
patator http_login host=10.0.0.1 user=FILE0 0=users.txt \
-x retry:code=5[0-9]{2} --max-retries 3 --timeout 10
# Retry specifically on connection timeout messages
patator ftp_login host=10.0.0.1 user=admin password=FILE0 \
-x retry:mesg='timed out' --timeout 5 --max-retries 5
Cross-Platform Timeout Behavior
On UNIX systems, both the signal alarm and module-level timeouts operate simultaneously, providing redundant protection. On Windows, the enable_alarm function becomes a no-op because Python's signal module lacks SIGALRM support. However, troubleshooting connection timeouts remains effective through module-level socket timeouts, ensuring consistent cross-platform behavior.
Summary
- Patator uses UNIX
signal.alarminenable_alarmto enforce per-payload timeouts, falling back to socket timeouts on Windows. - The
--timeoutparameter controls both the controller alarm and module-level network calls (e.g.,pycurl.TIMEOUT). - Retry logic supports configurable limits via
--max-retries(including unlimited with-1) and linear back-off viasleep(try_count * .1). - Failed attempts automatically trigger module
resetmethods to clear persistent connections. - Dynamic
-x retry:actions allow conditional retries based on response codes or messages.
Frequently Asked Questions
How does Patator handle timeouts on Windows without SIGALRM support?
On Windows, Patator disables the signal alarm mechanism (enable_alarm becomes a no-op), but module-level socket timeouts remain fully functional. Each module passes the --timeout value directly to underlying libraries like socket.create_connection() or pycurl, ensuring connections still terminate after the specified duration.
What is the maximum number of retries Patator allows?
Patator defaults to 4 retries per payload, but you can configure this via --max-retries. Setting the value to -1 enables unlimited retries, causing the consumer loop to continue indefinitely until the payload succeeds or the process is manually terminated.
Can I retry only on specific HTTP status codes while failing immediately on others?
Yes, use the conditional retry action syntax: -x retry:code=5[0-9]{2} retries only on 5xx server errors, while -x retry:mesg='Connection refused' retries on specific error messages. This integrates with the dynamic action system in report_progress (lines 1450-1454), allowing fine-grained control over which failures warrant retry attempts.
Why does Patator implement a back-off sleep between retries?
The framework sleeps for try_count * 0.1 seconds between attempts to prevent aggressive polling that could overwhelm unresponsive services or trigger rate limiting. This linear back-off gives temporary network issues time to resolve while keeping the brute-force process moving forward.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →