Live data from Hacker News

Hooray for the Sockets Interface

blog.apnic.net

31–40 of 86 posts

Re: Hooray for the Sockets Interface

#31
post #7

The socket interface using IP addresses instead of DNS names is widely considered to be a major mistake.

I disagree with this. Separating lookup from connect(2) or sendmsg(2) is cleaner. If an application doesn't care about the difference, most people are using higher level APIs built on top anyway, and most of those will provide a quick way to hide DNS details from you.

It's not just about separating lookup and connect: the fundamental stream abstraction is a point-to-point connection. It's possible to construct one-to-many connections on top of that, but it adds a lot of complexity on both sides. Doing it the other way around (emulating one-to-one connections on top of a one-to-many abstraction) means burdening simple connections with a lot of unnecessary complexity.

Re: Hooray for the Sockets Interface

#32
post #27
post #10

I have two complaints about sockets: 1, bidirectional sockets probably should've been ≥2 fd's, not 1. 2, non-blocking semantics and poll/select suck. Can't blame anyone in 1983 for not getting "async I/O" right since we're still struggling; at least now we have some decent answers (like io_uring on Linux.)

Windows NT had overlapped IO decades before Linux. The Microsoft kernel team were alright.

Windows NT had many things decades before Linux, I've gotten used to it. There are things Windows has that I still sort of wish Linux had, I mentioned one of them just last night (RDP fast user switching/session roaming.)

If we're just strictly talking about low level things, another good one would be synchronization primitives, which I guess we now have some of in Linux verbatim at this point, if only for the sake of emulation. (And of course futex2.)

Re: Hooray for the Sockets Interface

#33

Earlier quoted context omitted.

https://blog.ipspace.net/2009/08/what-went-wrong-socket-api/ A DNS name can have a LOT of A records associated but a socket has to pick one. This is a severe limitation.

> This is a severe limitation. Rather, it is a feature.

How so?

Re: Hooray for the Sockets Interface

#34
post #10

I have two complaints about sockets: 1, bidirectional sockets probably should've been ≥2 fd's, not 1. 2, non-blocking semantics and poll/select suck. Can't blame anyone in 1983 for not getting "async I/O" right since we're still struggling; at least now we have some decent answers (like io_uring on Linux.)

3, fds should have been UUIDs

Re: Hooray for the Sockets Interface

#35
post #20

Earlier quoted context omitted.

Absolutely not. You can have sockets without DNS. You can pick whatever strategy you want when there are multiple A records. You can use SRV records instead. And most importantly imo, it mirrors the listening API.

Raw addresses could have been an advanced option, rather than a requirement for every program.

I feel like this wouldn’t be a problem if we had decent APIs for name resolution (separate from sockets) instead.

The ones we have suck or are non-standard.

Re: Hooray for the Sockets Interface

#36
post #19

Earlier quoted context omitted.

A socket has to pick one, but your application doesn’t. You can hedge your bets and open a connection and send data to _all_ of them, and pick whichever returns faster. This of course requires you to know about the application-layer protocol. For HTTP, you need to restrict this strategy to GET methods, for example. Hence why it can’t be part of the socket interface. You can always build higher level abstractions on t…

You absolutely can establish multiple TCP connections for POST methods. You just can't send any _data_. This is even used by browsers, this trick even has a slightly creepy name: "Happy Eyeballs".

That’s true for HTTP.

TCP does not require that the act of connecting must be pure, so you cannot indiscriminately apply Happy Eyeballs at the socket API level.

Re: Hooray for the Sockets Interface

#37
post #10

I have two complaints about sockets: 1, bidirectional sockets probably should've been ≥2 fd's, not 1. 2, non-blocking semantics and poll/select suck. Can't blame anyone in 1983 for not getting "async I/O" right since we're still struggling; at least now we have some decent answers (like io_uring on Linux.)

3, fds should have been UUIDs

fds should have been IPv6 addresses. I will not elaborate on why or how.

Re: Hooray for the Sockets Interface

#38
post #10

I have two complaints about sockets: 1, bidirectional sockets probably should've been ≥2 fd's, not 1. 2, non-blocking semantics and poll/select suck. Can't blame anyone in 1983 for not getting "async I/O" right since we're still struggling; at least now we have some decent answers (like io_uring on Linux.)

> non-blocking semantics and poll/select suck.

I'd argue that it's not that the semantics suck, it's that there are too many of them. We have O_NONBLOCK, multiple multiplexers (for sane reasons--I don't begrudge 1980s folks for not thinking about fd set size and copy overhead for select(2) either), and others. What's worse, they don't all work with all FDs--not only are regular files not nonblock-able in the same way that sockets are, but all sorts of other FD-exposed capabilities (signalfds, timerfds, memfds, pidfds) do or don't support nonblocking semantics and multiplexing in all sorts of weird ways.

If those old system designers had stuck with keeping the async IO syscall space small (e.g. "you only get select/poll" or "you only get read(fds) and read_noblock(fds, timeout)") and consistent (by drawing a hard line at "if you expose something as an FD, it must support all APIs that generically handle FDs"), we would have ended up in a better place. Sure, that would have slowed down some implementations (e.g. vfs drivers), but would also have massively sped up development against a lot of these APIs.

Ah, well, hindsight is 20/20 I guess.

Re: Hooray for the Sockets Interface

#39
post #7

Earlier quoted context omitted.

I disagree with this. Separating lookup from connect(2) or sendmsg(2) is cleaner. If an application doesn't care about the difference, most people are using higher level APIs built on top anyway, and most of those will provide a quick way to hide DNS details from you.

https://blog.ipspace.net/2009/08/what-went-wrong-socket-api/ A DNS name can have a LOT of A records associated but a socket has to pick one. This is a severe limitation.

I'd actually say that the original sin of the socket API was taking DNS in higher-level connect methods at all. Users should have to separate the act of address lookup from the act of opening a connection every time (and could write the 5loc utility function to hide that split if they want).

I say that not out of purity concerns, but because of how DNS and TCP work. DNS multirecord selection (or not) should be up to the user. DNS timeouts should be surfaced granularly and differently from e.g. TCP SYNACK timeouts. Once a TCP stream is open, if a novice user opened it conceptually to a domain rather than an address, there's no intuitively correct answer to what happens if the domain's resolution changes while the socket's connected.

Re: Hooray for the Sockets Interface

#40
post #19

Earlier quoted context omitted.

You absolutely can establish multiple TCP connections for POST methods. You just can't send any _data_. This is even used by browsers, this trick even has a slightly creepy name: "Happy Eyeballs".

That’s true for HTTP. TCP does not require that the act of connecting must be pure, so you cannot indiscriminately apply Happy Eyeballs at the socket API level.

I suppose, but the number of applications for whom a successfully-negotiated bare socket connection (with no TLS or data exchanged) is side-effectful to the point that this causes problems is pretty darn small. I'm sure there are some terrifying counterexamples, but they have to be part of a tiny minority, right?

More concerning is the risk of exhausting server socket resources when probe-based connects don't hang up quickly if they don't want to use a connections. Lots of servers/load balancers aren't well-tuned to force-close connections if the first byte doesn't arrive within a short time.

Post reply on HN