You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
libkernel: connect() on a listening TCP socket returns the host error instead of EOPNOTSUPP; fix branch ready #6923
connect() on a listening TCP socket returns the host error (EINVAL on Windows, EISCONN on Linux) instead of EOPNOTSUPP (45). FreeBSD 11.4 soconnectat fails any socket that has SO_ACCEPTCONN set with EOPNOTSUPP. A program that connects its own listener (a probe, or a retry loop that reuses the descriptor) tests for 45 on the console and sees a different number here.
Fix branch: https://github.com/husseinkad/AnyPS5/tree/fix/socket-connect-listener-eopnotsupp (two commits; it merges cleanly into current main; libkernel/Socket/src/Udp.cpp, the new test tests/GuestSocketConnectListening.cpp registered in the libkernel CMakeLists.txt). For stream sockets, connect now queries SO_ACCEPTCONN after the address has been read and validated (FreeBSD's kern_connect copies the address in before soconnect, so a null or short address still fails first) and returns EOPNOTSUPP for a listener, before the family check.
Checks:
The new test fails on main (abort, errno 22) and passes with the change; the 18-test socket group passes.
Probed against main on loopback: a valid address on a listener gives 45 for IPv4, IPv6 on an IPv6 listener, an IPv6 address on an IPv4 listener, a nonblocking listener, and after shutdown; connect(listener, NULL, 16) gives 14 and a one-byte address gives the same error as a plain socket, as in FreeBSD's order. Non-listening TCP is unchanged (NULL gives 14, a refused connect gives 61, a second connect gives 56, and a connect to the listener from another socket works), and UDP is unchanged. accept keeps working after every failed connect on the listener. In a 3,000-sequence fuzz, 351 connect results changed from main (156 from 22, 147 from 47, 48 from 14), all on listeners.
Three independent reviews. The first found the check ran before address validation (null address gave 45), fixed in the second commit. check_conventions.py is clean and pr_overlap.py found no overlap; it conflicts only textually (adjacent insertions) with my listen auto-bind fix and the port-zero fix, and keeping both sides resolves it.
Not covered: addresses that Address() rejects with 47 (an AF_UNIX family byte, family 0 or 255, a 4-byte-long IPv4 address) still return 47 on a listener where FreeBSD would return 45; a length of 1 returns 14 for plain and listening sockets where FreeBSD gives EINVAL (22), which the sockaddr length checks in #4920 would change. The Linux error code was read from the kernel source, not run. Only Windows was built and run.
Activity