Skip to content

Commit e59c4a7

Browse files
committed
docs: add socket address uniqueness validation issue spec
- Document tracker behavior: UDP/TCP port sharing is allowed by design - Add comprehensive issue specification for socket address validation - Issue #255: Add Socket Address Uniqueness Validation for Tracker Configuration - Implementation follows TDD approach with unit tests - Uses std::net::SocketAddr (standard library) - Error types colocated with producing types - Estimated effort: ~8 hours across 4 phases
1 parent c4ddc49 commit e59c4a7

File tree

2 files changed

+750
-0
lines changed

2 files changed

+750
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Tracker Allows UDP and TCP Trackers on Same Port
2+
3+
**Issue Date**: December 23, 2025
4+
**Affected Component**: Torrust Tracker Application (`torrust/tracker:develop`)
5+
**Status**: Documented - Behavior by design (UDP and TCP are different protocols)
6+
7+
## Problem Description
8+
9+
The Torrust Tracker application **allows** both a UDP tracker and an HTTP (TCP) tracker to bind to the same port number when using the wildcard IP address (`0.0.0.0`).
10+
11+
Example configuration that is accepted:
12+
13+
```toml
14+
[[udp_trackers]]
15+
bind_address = "0.0.0.0:7070"
16+
17+
[[http_trackers]]
18+
bind_address = "0.0.0.0:7070"
19+
```
20+
21+
Both trackers start successfully:
22+
23+
```text
24+
2025-12-23T16:06:08.094597Z INFO UDP TRACKER: Starting on: 0.0.0.0:7070
25+
2025-12-23T16:06:08.094660Z INFO UDP TRACKER: Started on: udp://0.0.0.0:7070
26+
2025-12-23T16:06:08.094818Z INFO HTTP TRACKER: Starting on: http://0.0.0.0:7070
27+
2025-12-23T16:06:08.094894Z INFO HTTP TRACKER: Started on: http://0.0.0.0:7070
28+
```
29+
30+
## Root Cause
31+
32+
This behavior is **technically correct** from an operating system perspective:
33+
34+
- **UDP and TCP are different transport protocols**
35+
- The OS maintains separate port spaces for UDP and TCP
36+
- A UDP socket on port 7070 does not conflict with a TCP socket on port 7070
37+
- Both can coexist and operate independently
38+
39+
The tracker application simply requests socket bindings from the OS, and the OS allows both because they use different protocol stacks.
40+
41+
## Impact
42+
43+
### Positive Impact
44+
45+
- Technically valid configuration that works correctly
46+
- Allows advanced users to intentionally share port numbers across protocols
47+
- No runtime errors or crashes
48+
49+
### Potential Confusion
50+
51+
While technically valid, this configuration is **likely unintentional** in most use cases:
52+
53+
1. **User Intent**: Users typically expect different services to use different port numbers
54+
2. **Port Management**: Makes it harder to manage and document which services use which ports
55+
3. **Firewall Rules**: May complicate firewall configurations when UDP and TCP use same port
56+
4. **Monitoring**: Can be confusing when monitoring port usage and service health
57+
5. **Documentation**: Requires careful documentation to explain which protocol uses which port
58+
59+
### When This is Valid
60+
61+
Scenarios where sharing ports across protocols makes sense:
62+
63+
- **Testing**: Quick testing with limited port ranges
64+
- **Cloud Environments**: Some cloud providers have port restrictions
65+
- **Container Environments**: Port mapping limitations in container orchestration
66+
- **Intentional Design**: User specifically wants to use same port for both protocols
67+
68+
## Current Behavior in Deployer
69+
70+
The deployer currently **allows** this configuration because:
71+
72+
1. The tracker accepts it without error
73+
2. Both services start and run successfully
74+
3. No deployment failures occur
75+
4. The configuration is technically valid
76+
77+
## Recommended Approach
78+
79+
### For the Tracker Repository
80+
81+
**No changes recommended** - the current behavior is correct. UDP and TCP are different protocols and can legitimately share port numbers.
82+
83+
If the tracker maintainers want to prevent this, they could add an optional validation check with a configuration flag to warn users about port sharing across protocols.
84+
85+
### For the Deployer Repository
86+
87+
**Consider adding validation** with appropriate context:
88+
89+
1. **Strict Mode** (default): Prevent same port across any tracker types
90+
91+
- Reject: UDP tracker + HTTP tracker on same port
92+
- Reject: UDP tracker + API on same port
93+
- Reject: HTTP tracker + API on same port
94+
- Allow: Different IPs on same port (e.g., `192.168.1.10:7070` + `192.168.1.20:7070`)
95+
96+
2. **Permissive Mode** (opt-in via flag): Allow port sharing across different protocols
97+
98+
- Allow: UDP tracker + HTTP tracker on same port (different protocols)
99+
- Reject: Two UDP trackers on same port (same protocol)
100+
- Reject: Two HTTP trackers on same port (same protocol)
101+
- Reject: HTTP tracker + API on same port (both are TCP)
102+
103+
3. **Warning Mode**: Accept the configuration but warn the user
104+
- Display informational message about port sharing
105+
- Suggest different ports for clarity
106+
- Proceed with deployment
107+
108+
## Validation Rules
109+
110+
The deployer should validate socket address uniqueness based on:
111+
112+
```text
113+
Socket Address = IP + Port + Protocol
114+
```
115+
116+
### Invalid Configurations (Same Protocol + Same Socket)
117+
118+
**Two UDP trackers on same IP:Port**:
119+
120+
```toml
121+
[[udp_trackers]]
122+
bind_address = "0.0.0.0:7070"
123+
124+
[[udp_trackers]]
125+
bind_address = "0.0.0.0:7070" # INVALID: Same protocol, same IP, same port
126+
```
127+
128+
**Two HTTP trackers on same IP:Port**:
129+
130+
```toml
131+
[[http_trackers]]
132+
bind_address = "0.0.0.0:7070"
133+
134+
[[http_trackers]]
135+
bind_address = "0.0.0.0:7070" # INVALID: Same protocol, same IP, same port
136+
```
137+
138+
**HTTP tracker and API on same IP:Port** (both use TCP):
139+
140+
```toml
141+
[[http_trackers]]
142+
bind_address = "0.0.0.0:7070"
143+
144+
[http_api]
145+
bind_address = "0.0.0.0:7070" # INVALID: Both are TCP, same IP, same port
146+
```
147+
148+
### Valid Configurations
149+
150+
**UDP and HTTP on same port** (different protocols):
151+
152+
```toml
153+
[[udp_trackers]]
154+
bind_address = "0.0.0.0:7070" # UDP protocol
155+
156+
[[http_trackers]]
157+
bind_address = "0.0.0.0:7070" # TCP protocol - VALID but potentially confusing
158+
```
159+
160+
**Same port, different IPs**:
161+
162+
```toml
163+
[[http_trackers]]
164+
bind_address = "192.168.1.10:7070"
165+
166+
[[http_trackers]]
167+
bind_address = "192.168.1.20:7070" # VALID: Different IP addresses
168+
```
169+
170+
**Different ports, same protocol**:
171+
172+
```toml
173+
[[http_trackers]]
174+
bind_address = "0.0.0.0:7070"
175+
176+
[[http_trackers]]
177+
bind_address = "0.0.0.0:8080" # VALID: Different ports
178+
```
179+
180+
## Testing Evidence
181+
182+
### Test Configuration
183+
184+
File: `envs/bug-test-duplicate-port.json`
185+
186+
```json
187+
{
188+
"tracker": {
189+
"udp_trackers": [
190+
{
191+
"bind_address": "0.0.0.0:7070"
192+
}
193+
],
194+
"http_trackers": [
195+
{
196+
"bind_address": "0.0.0.0:7070"
197+
}
198+
]
199+
}
200+
}
201+
```
202+
203+
### Test Results
204+
205+
**Deployment**: ✅ SUCCESS
206+
207+
- Provision: Completed
208+
- Configure: Completed
209+
- Release: Completed
210+
- Run: Completed
211+
212+
**Tracker Startup**: ✅ SUCCESS
213+
214+
```bash
215+
$ docker logs tracker 2>&1 | grep -E "(UDP TRACKER|HTTP TRACKER).*Started"
216+
2025-12-23T16:06:08.094660Z INFO UDP TRACKER: Started on: udp://0.0.0.0:7070
217+
2025-12-23T16:06:08.094894Z INFO HTTP TRACKER: Started on: http://0.0.0.0:7070
218+
```
219+
220+
**Service Status**: ✅ HEALTHY
221+
222+
```bash
223+
$ docker compose ps
224+
NAME STATUS
225+
tracker Up 2 minutes (healthy)
226+
```
227+
228+
**Health Checks**: ✅ PASSING
229+
230+
- UDP tracker responding on port 7070
231+
- HTTP tracker responding on port 7070
232+
- No port binding conflicts
233+
- No application errors
234+
235+
## References
236+
237+
- [Tracker Configuration Schema](https://github.com/torrust/torrust-tracker/blob/develop/docs/config.md)
238+
- [UDP Tracker Implementation](https://github.com/torrust/torrust-tracker/tree/develop/packages/udp-tracker)
239+
- [HTTP Tracker Implementation](https://github.com/torrust/torrust-tracker/tree/develop/packages/http-tracker)
240+
- [OS Socket Binding Documentation](https://man7.org/linux/man-pages/man2/bind.2.html)
241+
- Test Environment: `envs/bug-test-duplicate-port.json`
242+
- Test Date: December 23, 2025
243+
244+
## Conclusion
245+
246+
The tracker's behavior is **correct by design** - UDP and TCP can share port numbers because they are different protocols. However, the deployer **should add validation** to prevent potentially confusing configurations, especially for users who may not understand the protocol-level distinction.
247+
248+
The validation should focus on preventing:
249+
250+
1. Same protocol + same IP + same port (actual conflicts)
251+
2. Optionally warn about cross-protocol port sharing (clarity)

0 commit comments

Comments
 (0)