Commit da4989d
fix(socket): auto-bind an unbound TCP socket on listen() (X3)
listen() on a socket with no prior bind() built a TcpSession on
the invalid local port 0 — a broken listener. The backlog planned
to reject this with EINVAL, but that contradicts Linux, which
auto-binds an unbound TCP socket to an ephemeral port on listen()
(inet_csk_listen_start -> get_port with port 0). Per the
Linux-parity north star, mirror the auto-bind instead of the
deviation.
TcpSocket.listen() now, when the socket is unbound (local port not
in 1..65535), picks an ephemeral port via pick_local_port() and
re-registers the socket before starting the listener — the same
unregister/pick/register dance bind() uses. A socket already bound
to a specific port keeps it.
Not a breaking change: the examples all bind() before listen(), so
none needed updating (the reason the EINVAL variant was flagged as
example-breaking).
Tests-first: listen() on an unbound socket auto-binds an ephemeral
port and registers the listener; listen() on a bound socket keeps
its port and does not re-pick. Verified red (port stayed 0) before
the fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 457fffc commit da4989d
3 files changed
Lines changed: 72 additions & 6 deletions
File tree
- docs/refactor
- packages/pytcp/pytcp
- runtime/socket
- tests/unit/runtime/socket
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
181 | | - | |
182 | | - | |
| 181 | + | |
| 182 | + | |
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| |||
274 | 274 | | |
275 | 275 | | |
276 | 276 | | |
277 | | - | |
278 | | - | |
| 277 | + | |
| 278 | + | |
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
| |||
323 | 323 | | |
324 | 324 | | |
325 | 325 | | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
326 | 336 | | |
327 | 337 | | |
328 | 338 | | |
329 | | - | |
330 | | - | |
| 339 | + | |
331 | 340 | | |
332 | 341 | | |
333 | 342 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
766 | 766 | | |
767 | 767 | | |
768 | 768 | | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
769 | 779 | | |
770 | 780 | | |
771 | 781 | | |
| |||
Lines changed: 47 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
569 | 569 | | |
570 | 570 | | |
571 | 571 | | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
572 | 619 | | |
573 | 620 | | |
574 | 621 | | |
| |||
0 commit comments