feat(net): enhance Linux compatibility for socket operations#1818
feat(net): enhance Linux compatibility for socket operations#1818fslongjin wants to merge 2 commits intoDragonOS-Community:masterfrom
Conversation
fslongjin
commented
Mar 16, 2026
- Implement dual-stack rule validation for bound IPv6 sockets
- Add auto-binding for unbound TCP sockets on listen() call
- Improve backlog handling for INADDR_ANY listeners across interfaces
- Fix socketpair error code mapping for unsupported families
- Implement dual-stack rule validation for bound IPv6 sockets - Add auto-binding for unbound TCP sockets on listen() call - Improve backlog handling for INADDR_ANY listeners across interfaces - Fix socketpair error code mapping for unsupported families Signed-off-by: longjin <longjin@DragonOS.org>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85ee6f0c32
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let new_listen = socket::inet::BoundInner::bind_on_iface( | ||
| new_listen_smoltcp_socket(listen_addr)?, | ||
| iface.clone(), |
There was a problem hiding this comment.
Keep port-owning listener first for INADDR_ANY
This branch inserts non-primary interface listeners into inners before the original bound listener, but Listening::close() still frees the bound TCP port via self.inners[0].iface().port_manager().unbind_port(...), which assumes index 0 owns the reservation. On multi-interface INADDR_ANY listeners, close will unbind the wrong iface and leak the actual port binding on the primary iface, so subsequent bind/listen on the same port can fail with EADDRINUSE.
Useful? React with 👍 / 👎.
| let nic_id = b.iface().nic_id(); | ||
| if !registered_ifaces.contains(&nic_id) { | ||
| b.iface().common().register_tcp_listen_port(port, backlog); | ||
| b.iface().common().bind_socket(me.clone()); |
There was a problem hiding this comment.
Unbind listener from every iface during teardown
Registering the listening socket on each unique iface here is not matched by symmetric unregistration: close/shutdown paths only call unbind_socket() through a single iface (inner.iface() / inners[0]). For INADDR_ANY listeners spanning multiple interfaces, extra IfaceCommon::bounds entries remain after close, causing leaked socket references and repeated stale notifications on those interfaces.
Useful? React with 👍 / 👎.
- Fix port unbinding to use last inner socket instead of first - Add socket unbinding to all interface cleanup loops for listening sockets - Prevent double unbinding for non-listening socket states Signed-off-by: longjin <longjin@DragonOS.org>