Router doesn't listen op IPv6 addresses with wildcard configuration
Bug Overview
When I configure a listener with *:8080 unitd only listens on 0.0.0.0:8080 and not on :::8080.
The documentation states the following: A wildcard that matches any host IPs on the port: *:80
Expected Behavior
unitd listens on all configured IP addresses.
Steps to Reproduce the Bug
Minimal configuration example:
{
"listeners": {
"*:8080": {
"pass": "routes"
},
"0.0.0.0:8081": {
"pass": "routes"
},
"[::]:8081": {
"pass": "routes"
}
},
"routes": [
{
"match": {
"uri": [
"/*"
]
},
"action": {
"return": 200
}
}
]
}
netstat -plunt | grep unit
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 10435/unit: router
tcp 0 0 0.0.0.0:8081 0.0.0.0:* LISTEN 10435/unit: router
tcp6 0 0 :::8081 :::* LISTEN 10435/unit: router
# curl -I http://127.0.0.1:8081/
HTTP/1.1 200 OK
Server: Unit/1.34.1
Date: Tue, 04 Feb 2025 15:40:21 GMT
Content-Length: 0
# curl -I http://[::1]:8081/
HTTP/1.1 200 OK
Server: Unit/1.34.1
Date: Tue, 04 Feb 2025 15:40:25 GMT
Content-Length: 0
# curl -I http://127.0.0.1:8080/
HTTP/1.1 200 OK
Server: Unit/1.34.1
Date: Tue, 04 Feb 2025 15:40:30 GMT
Content-Length: 0
# curl -I http://[::1]:8080/
curl: (7) Failed to connect to ::1 port 8080 after 0 ms: Couldn't connect to server
Environment Details
- Target deployment platform: Linux Docker container
- Target OS: Ubuntu 24.04
- Version of this project or specific commit: 1.34.1
- Version of any relevant project languages: -
Additional Context
No response
When I configure a listener with *:8080 unitd only listens on 0.0.0.0:8080 and not on :::8080.
Indeed.
The documentation states the following: A wildcard that matches any host IPs on the port: *:80
What it really means is it listens on the 'unspecified address', of course this address is different for IPv4 & IPv6.
Now I suppose it could be interpreted to mean listen on the 'unspecified address' of both IPv4 & IPv6. But then it's current meaning could also be argued as correct as *:80 would not be how to specify an IPv6 address + port due to the address/port separator being a :. Now, [*]:8080 isn't valid in Unit, but then [::]:8080 is only one extra character.
It was also possibly thought it better to keep IPv4 and IPv6 address specifications separate, precisely so that *:8080 would only listen on IPv4 and not present Unit on IPv6 (perhaps unknowingly).
For that reason I'm not sure we'd change its behaviour now...
So as you discovered to have Unit listen on port 8080 on both IPv4 & IPv6, you will need two listen directives (actually this is same as for nginx).
Where for IPv4 you can use either * or 0.0.0.0.
Thank you for the clarification. I think it would be helpful to have a way to specify a listen address with a "real wildcard" that allows for IPv4 and IPv6 listening, just to remove duplication in the configuration (se the linked MR). For now I will use two listeners.
If we were to implement this, probably something simply like :port would be best so as not to change existing behaviour...