This started out as "why is net/linux-nx-client broken for FreeBSD 6.x," but turns out to have far deeper implications. It should come as no surprise there's a lot of code out there that invokes system calls that might fail, and makes certain assumptions about how such failures will be reported. Sources intended to be cross-platform sometimes need to make allowances for differing implementations; e.g. some "System V- derived" environments may not behave identically to "BSD-derived" ones. However, once the characteristics of a particular platform are established, they're expected to remain essentially immutable. On those rare occasions where it's deemed necessary to modify an ABI, extreme care must be taken to do so as non- destructively as possible. Mitigation strategies may take many forms, such as creating additional sysent[] vectors, or providing compatibility knobs. This PR is about what happens when an executable attempts to set TCP_NODELAY on a UNIX protocol socket. This is, of course, a "stupid" thing for an program to attempt. It can't possibly succeed, and software developers Should Know Better. However, it happens in The Real World, and we need to respect that. On FreeBSD 4.x/5.x and Linux 2.4.x/2.6.x, the specific error reported in this case is [EOPNOTSUPP]. Mac OS X 10.4.x and DragonFly are also in this camp. OpenBSD, Solaris 8/9, and Mac OS X 10.3.x return [ENOPROTOOPT] instead. The descriptions of both error codes in the intro(2) manual page would tend to suggest either one is plausible in this situation, and Real World code that's intended to be "reasonably portable" typically treats either one identically. The lone dissenter had been NetBSD, which, beginning with their 1.4 release, picked [EINVAL]. In The Early Days of UNIX (when there just weren't that many error codes defined), that might have been a logical choice. I claim it's not a wise one today. Shortly before FreeBSD 6.0 was released, some well-meaning, but reckless, soul made the terrible mistake of inflicting NetBSD's braindamage upon uipc_ctloutput(), and this appears to be the result of src/kern/uipc_usrreq.c CVS Revision 1.153: "Check sopt_level in uipc_ctloutput() and return early if it is non-zero. This prevents unintended consequnces[sic] when an application calls things like setsockopt(x, SOL_SOCKET, SO_REUSEADDR, ...) on a Unix domain socket." I understand why it was put in there, and what it was intended to accomplish, but it's too heavy-handed--especially considering its adverse impact on anything using compat4x, compat5x, or the Linuxulator. It's also inconsistent with what's documented on the setsockopt(2) and unix(4) man pages for 6.2-RELEASE. The documentation is fine; it's the kernel that needs to conform. I'm proposing simply modifying the return value to be [EOPNOTSUPP]. I've tested this change using a patched kernel, and it unbroke all of the legacy FreeBSD executables and Linux binaries I tried. Fix: [This is for 6.2-RELEASE; -CURRENT is similar, except there's no UNP_LOCK()] How-To-Repeat: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> main(int argc, char *argv[]) { register int s; int v; if ((s=socket(PF_UNIX, SOCK_STREAM, 0))<0) { perror("socket"); exit(1); } v=1; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const void *)&v, (socklen_t)sizeof v)<0) { perror("TCP_NODELAY"); (void)fflush(stderr); } (void)close(s); exit(0); }
Responsible Changed From-To: freebsd-bugs->kmacy Interoperability should always be worked towards where it is easy to maintain.
Responsible Changed From-To: kmacy->freebsd-net kmacy has asked for all of his PRs to be reassigned back to the pool.
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>