> Why does everybody use tcp ports instead of file sockets for local communication?
In my experience it's because Windows and mac developers aren't aware of local file sockets. Windows API, in particular, doesn't have a similar concept if I recall.
On the most popular UNIX-like operating system, Linux, there's are literally zero references to UDS to mean UNIX domain sockets.
$ sudo mandb
$ man -K UDS
The point is that acronyms that are not context appropriate and/or very uncommon are quite annoying to come across. I guess it was worth saving a dozen bytes not to write the full thing in the first place.
Wow, interesting - I didn't know that. That is very cool... no more special handling for windows in cross platform handling then it sounds like (at least for UDS).
I guess I'm ignorant then! When I looked up domain sockets and so on it turned out to be different APIs for different OS:s, and it's significantly nicer to rely on a single API surface from the std lib. Maybe it's a habit thing as well, but to me pipes are more esoteric and harder to find docs about than network sockets.
Sure, but all these services listening on ports, sometimes not even bound to localhost is just shitty. There's no authentication. and it's actually a huge contributor to database dumped online. Besides the security, ease of selecting a path vs a free port, it's also faster
> you can chdir to the directory before bind/connect
Since working directory is per-process not per-thread, this seems a great way to introduce race condition bugs. It also basically rules it out for anything meant to be used as a library or framework.
Working directory can be changed on a per-thread basis on Mac with pthread_chdir_np, and on Linux you can create a thread with the clone syscall and without the CLONE_FS flag to avoid sharing working directory with the rest of the process. I don't know about Windows.
One could fork a subprocess, chdir()+socket() there, then pass the socket back to parent over another socket (opened maybe with socketpair().) Should work on any Unix-like which supports SCM_RIGHTS (which is almost everybody, apparently even obscure platforms like AIX, IBM i, z/OS). But not Windows, which doesn't (at least not yet, they may add it at some point.)
Makes one really wish there was a bindat() call:
int bindat(int sockfd, const struct sockaddr *addr, socklen_t addrlen, int dirfd);
or maybe funixsockat:
int funixsockat(int type, int dirfd, const char * name);
which would combine socket() and bind() in a single call
In Windows we actually have a way to set the parent directory for a UDS bind or connect, via a socket ioctl. It’s not documented yet, but it’s in the header.
Is anybody trying to lift that limitation? It seems like an obvious target for kernel devs to tackle.
If Linux and *BSD did it (especially if they adopted a mutually compatible implementation), the POSIX standardisation team (Austin Group) would likely be interested in adding it to POSIX, and Windows/macOS/AIX/etc will likely follow their example sooner or later.
Linux has an extension that allows an arbitrary string that is not tied to the filesystem. This makes it easier to stay within the limit or you can crypto hash an arbitrarily long string down to 108 chars.
Even though you lose the filesystem-based security, you can still use SO_PEERCRED or getpeereid and validate the caller's UID is what you expect, something which Linux doesn't support on localhost TCP sockets. Requiring the client's UID (and maybe GID too) to be the same as your own is a sane default for services intended for per-user usage.
For many applications it is enough. For others, such as placing a UDS in a user's home directory or temp folder, it may not be. Often times you don't know ahead of time what the path may be.
They are ephemeral, they hold no data after being closed and backups of them aren't useful. Only the name is needed, therefore a tmpfs is the place to store them.
tcp ports are much more versatile, you can expose it to the outside world as opposed to unix sockets. Now exposing an nfs server to the outside can lead to interesting possibilities: for example you can implement a local fuse file system which can be mounted remotely through the NFS. It's highly not recommended at this moment because there's no authentication implemented
It’s not almost enough for all developers to not just simply bind to 0.0.0.0.
It’s not well known enough, looking at the recent thread where people are amazed that the i notation is simply a 32bit number van can be used like that. Or even http://0xd1d8e6f0
For example, even if you do vind to localhost, anyone on your system can access your service. Let’s say an electron is running on port 5555. A guest user on your system can just access the electron app.
If this app happens to be vscode, you now have full access.
It’s just plain stupid. You basically nuked multi user security. Better run dos then
In practice these problems occur, but more rarely than you're implying.
First, many of the systems that local-use-only-but-served-via-TCP-on-localhost apps use are not multi user. VS Code is a good example; I'd hazard that the vast majority of installs thereof are on systems that don't have simultaneous users logged in.
Second, many localhost-tcp apps do use authentication of a sort; this is simple to set up via a secret that is pre-shared at application installation time.
Third, it's easily possible to use ip[tables] to restrict loopback traffic based on conditions that include user ID or group ID. I'm not sure how many people take advantage of this capability, since doing so reliably would probably imply the "server" component having root so it could impose firewally restrictions on loopback users at startup time.
In my experience it's because Windows and mac developers aren't aware of local file sockets. Windows API, in particular, doesn't have a similar concept if I recall.