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
Our default socket configuration is a little different than the classic BSD defaults. Are we making the right choices?
SO_REUSEADDR on non-Windows, SO_EXCLUSIVEADDR on Windows: almost certainly correct for listening sockets. More dubious but mostly harmless for client sockets. (See also Handling of SO_REUSEADDR and friends #39)
On Windows the other option would be to leave both SO_REUSEADDR and SO_EXCLUSIVEADDR unset, which gives (a) the preferred TIME_WAIT semantics (same as setting SO_REUSEADDR on a Unix system), but also (b) weird socket hijacking issues. (This is what libuv does, e.g.) For now our reasoning is "when in doubt, err on the side of security", but really it would be better to make an actual decision :-). And it's not clear what the best trade-off here is. On recent versions of Windows (including I think all the versions Python officially supports), you can only hijack sockets belonging to the same user, which under the traditional Unix security model would be no big deal – if the process belongs to the same user you could also ptrace it or whatever, and we already have countermeasures against anyone setting SO_REUSEADDR by accident. So maybe the security issue is not worth worrying about in practice. But Windows is not Unix, and even on Unix the traditional security model is not what it used to be (e.g. you probably can't ptrace random other processes these days!), so ... I'm not confident I understand the risks.
There's also the option of pushing this into the higher-level networking interface (High-level networking interface #73), where it knows whether or not it's dealing with a listening socket.
IPV6_V6ONLY unset: The important thing is to have a consistent default, because this varies across environments in practice. And I guess unset is a little better than set because it simplifies ipv6 support in simple cases?
TCP_NODELAY set: I'm not sure if this is a good idea or not. asyncio sets it by default as well. My suspicion is that having TCP_NODELAY set is a good idea for most serious protocols (latency is important, Nagle sucks for that, most protocols aren't telnet, and hopefully most serious implementations are not hitting the OS with lots of tiny writes and relying on it to fix things up). But Nagle also serves as a safety belt for low-effort implementations, which are the ones that are least likely to override defaults...
TCP_NOTSENT_LOWAT set to 16 KiB: well, it's... not obviously wrong? Here we're breaking new ground, so we'll have to see how it goes in practice. This is quite a complicated issue; see TCP_NOTSENT_LOWAT umbrella issue #76.
The text was updated successfully, but these errors were encountered:
maybe there's a remaining question of what to do about V6ONLY for client sockets, but I'm pretty sure open_tcp_stream winds up DTRT there by trying IPv4 and IPv6 connections separately
Our default socket configuration is a little different than the classic BSD defaults. Are we making the right choices?
SO_REUSEADDR
on non-Windows,SO_EXCLUSIVEADDR
on Windows: almost certainly correct for listening sockets. More dubious but mostly harmless for client sockets. (See also Handling of SO_REUSEADDR and friends #39)On Windows the other option would be to leave both
SO_REUSEADDR
andSO_EXCLUSIVEADDR
unset, which gives (a) the preferredTIME_WAIT
semantics (same as settingSO_REUSEADDR
on a Unix system), but also (b) weird socket hijacking issues. (This is what libuv does, e.g.) For now our reasoning is "when in doubt, err on the side of security", but really it would be better to make an actual decision :-). And it's not clear what the best trade-off here is. On recent versions of Windows (including I think all the versions Python officially supports), you can only hijack sockets belonging to the same user, which under the traditional Unix security model would be no big deal – if the process belongs to the same user you could alsoptrace
it or whatever, and we already have countermeasures against anyone settingSO_REUSEADDR
by accident. So maybe the security issue is not worth worrying about in practice. But Windows is not Unix, and even on Unix the traditional security model is not what it used to be (e.g. you probably can'tptrace
random other processes these days!), so ... I'm not confident I understand the risks.There's also the option of pushing this into the higher-level networking interface (High-level networking interface #73), where it knows whether or not it's dealing with a listening socket.
IPV6_V6ONLY
unset: The important thing is to have a consistent default, because this varies across environments in practice. And I guess unset is a little better than set because it simplifies ipv6 support in simple cases?TCP_NODELAY
set: I'm not sure if this is a good idea or not.asyncio
sets it by default as well. My suspicion is that havingTCP_NODELAY
set is a good idea for most serious protocols (latency is important, Nagle sucks for that, most protocols aren't telnet, and hopefully most serious implementations are not hitting the OS with lots of tiny writes and relying on it to fix things up). But Nagle also serves as a safety belt for low-effort implementations, which are the ones that are least likely to override defaults...TCP_NOTSENT_LOWAT
set to 16 KiB: well, it's... not obviously wrong? Here we're breaking new ground, so we'll have to see how it goes in practice. This is quite a complicated issue; see TCP_NOTSENT_LOWAT umbrella issue #76.The text was updated successfully, but these errors were encountered: