2025-05-18 22:41:41 +00:00
# SmartProxy Development Plan
cat /home/philkunz/.claude/CLAUDE.md
2025-05-19 01:59:52 +00:00
## Critical Bug Fix: Port 80 EADDRINUSE with ACME Challenge Routes
2025-05-18 22:41:41 +00:00
### Problem Statement
2025-05-19 01:59:52 +00:00
SmartProxy encounters an "EADDRINUSE" error on port 80 when provisioning multiple ACME certificates. The issue occurs because the certificate manager adds and removes the challenge route for each certificate individually, causing race conditions when multiple certificates are provisioned concurrently.
2025-05-18 22:41:41 +00:00
### Root Cause
2025-05-19 01:59:52 +00:00
The `SmartCertManager` class adds the ACME challenge route (port 80) before provisioning each certificate and removes it afterward. When multiple certificates are provisioned:
1. Each provisioning cycle adds its own challenge route
2. This triggers `updateRoutes()` which calls `PortManager.updatePorts()`
3. Port 80 is repeatedly added/removed, causing binding conflicts
2025-05-18 22:41:41 +00:00
### Implementation Plan
2025-05-19 01:59:52 +00:00
#### Phase 1: Refactor Challenge Route Lifecycle
1. **Modify challenge route handling** in `SmartCertManager`
- [ ] Add challenge route once during initialization if ACME is configured
- [ ] Keep challenge route active throughout entire certificate provisioning
- [ ] Remove challenge route only after all certificates are provisioned
- [ ] Add concurrency control to prevent multiple simultaneous route updates
#### Phase 2: Update Certificate Provisioning Flow
2. **Refactor certificate provisioning methods**
- [ ] Separate challenge route management from individual certificate provisioning
- [ ] Update `provisionAcmeCertificate()` to not add/remove challenge routes
- [ ] Modify `provisionAllCertificates()` to handle challenge route lifecycle
- [ ] Add error handling for challenge route initialization failures
#### Phase 3: Implement Concurrency Controls
3. **Add synchronization mechanisms**
- [ ] Implement mutex/lock for challenge route operations
- [ ] Ensure certificate provisioning is properly serialized
- [ ] Add safeguards against duplicate challenge routes
- [ ] Handle edge cases (shutdown during provisioning, renewal conflicts)
#### Phase 4: Enhance Error Handling
4. **Improve error handling and recovery**
- [ ] Add specific error types for port conflicts
- [ ] Implement retry logic for transient port binding issues
- [ ] Add detailed logging for challenge route lifecycle
- [ ] Ensure proper cleanup on errors
#### Phase 5: Create Comprehensive Tests
5. **Write tests for challenge route management**
- [ ] Test concurrent certificate provisioning
- [ ] Test challenge route persistence during provisioning
- [ ] Test error scenarios (port already in use)
- [ ] Test cleanup after provisioning
- [ ] Test renewal scenarios with existing challenge routes
#### Phase 6: Update Documentation
6. **Document the new behavior**
- [ ] Update certificate management documentation
- [ ] Add troubleshooting guide for port conflicts
- [ ] Document the challenge route lifecycle
- [ ] Include examples of proper ACME configuration
2025-05-18 22:41:41 +00:00
### Technical Details
#### Specific Code Changes
2025-05-19 01:59:52 +00:00
1. In `SmartCertManager.initialize()` :
```typescript
// Add challenge route once at initialization
if (hasAcmeRoutes & & this.acmeOptions?.email) {
await this.addChallengeRoute();
}
```
2. Modify `provisionAcmeCertificate()` :
2025-05-18 22:41:41 +00:00
```typescript
2025-05-19 01:59:52 +00:00
// Remove these lines:
// await this.addChallengeRoute();
// await this.removeChallengeRoute();
```
3. Update `stop()` method:
```typescript
// Always remove challenge route on shutdown
if (this.challengeRoute) {
await this.removeChallengeRoute();
}
2025-05-18 22:41:41 +00:00
```
2025-05-19 01:59:52 +00:00
4. Add concurrency control:
2025-05-18 22:41:41 +00:00
```typescript
2025-05-19 01:59:52 +00:00
private challengeRouteLock = new AsyncLock();
private async manageChallengeRoute(operation: 'add' | 'remove'): Promise< void > {
await this.challengeRouteLock.acquire('challenge-route', async () => {
if (operation === 'add') {
await this.addChallengeRoute();
} else {
await this.removeChallengeRoute();
}
2025-05-18 22:41:41 +00:00
});
}
```
### Success Criteria
2025-05-19 01:59:52 +00:00
- [x] No EADDRINUSE errors when provisioning multiple certificates
- [x] Challenge route remains active during entire provisioning cycle
- [x] Port 80 is only bound once per SmartProxy instance
- [x] Proper cleanup on shutdown or error
2025-05-18 23:07:31 +00:00
- [x] All tests pass
- [x] Documentation clearly explains the behavior
### Implementation Summary
2025-05-19 01:59:52 +00:00
The port 80 EADDRINUSE issue has been successfully fixed through the following changes:
2025-05-18 23:07:31 +00:00
2025-05-19 01:59:52 +00:00
1. **Challenge Route Lifecycle** : Modified to add challenge route once during initialization and keep it active throughout certificate provisioning
2. **Concurrency Control** : Added flags to prevent concurrent provisioning and duplicate challenge route operations
3. **Error Handling** : Enhanced error messages for port conflicts and proper cleanup on errors
4. **Tests** : Created comprehensive test suite for challenge route lifecycle scenarios
5. **Documentation** : Updated certificate management guide with troubleshooting section for port conflicts
2025-05-18 23:07:31 +00:00
2025-05-19 01:59:52 +00:00
The fix ensures that port 80 is only bound once, preventing EADDRINUSE errors during concurrent certificate provisioning operations.
2025-05-18 22:41:41 +00:00
### Timeline
2025-05-19 01:59:52 +00:00
- Phase 1: 2 hours (Challenge route lifecycle)
- Phase 2: 1 hour (Provisioning flow)
- Phase 3: 2 hours (Concurrency controls)
- Phase 4: 1 hour (Error handling)
- Phase 5: 2 hours (Testing)
- Phase 6: 1 hour (Documentation)
2025-05-18 22:41:41 +00:00
2025-05-19 01:59:52 +00:00
Total estimated time: 9 hours
2025-05-18 22:41:41 +00:00
### Notes
2025-05-19 01:59:52 +00:00
- This is a critical bug affecting ACME certificate provisioning
- The fix requires careful handling of concurrent operations
- Backward compatibility must be maintained
- Consider impact on renewal operations and edge cases