getsockopt() allows you to get the socket error; this allows setsockopt to set the error. This is primarily for testing, although I've got a use on a different platform with a network proxy.
Details
Build & install. I wrote a small server that does
static void set_error(int connection, int errnum) { int kr = setsockopt(connection, SOL_SOCKET, SO_ERROR, &errnum, sizeof(int)); if (kr == -1) { warn("Could not set socket error to %d", errnum); } }
on demand, and ensures the socket gets the error.
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
I'm sure this is useful, but I'd be a bit nervous about kernel code that somehow assumes that so_error can't be set. That is, it might become possible for userspace to trigger unexpected behaviour. I don't have anything concrete to point to though.
I also note that so_error is not locked consistently among different protocols (there are lots of unlocked reads, etc.), so it's hard to see whether taking SO_LOCK() here is sufficient.
I was paranoid about the lock, as is only correct.
I did a quick glance through the kernel code and wasn't too worried about so_error changing -- getsockopt will clear it if you get the error -- but one thing this _does_ allow you to do is change the error that would be reported if it hasn't been checked yet.
I'm still skeptical that this is safe, especially given that it can be used to clear an existing error. I would, at the very least, disallow the use of this option to set so_error = 0.
If you call getsockopt with SO_ERROR, it clears out so_error, so the ability to asynchronously clear the error already exists, and hasn't broken things.
There are protocols that would never set so_error. As we go away from sosend_generic/soreceive_generic, number of such protocols will grow. So the protocol itself asserts that its so_error is 0 always. Handling magic setting from the userland will complicate things. I understand this can be useful for some debugging or instrumenting fail scenarios, but I'm really reluctant on having that in the main branch.
My actual use case (on a different OS) was for a proxy.
What protocols require that so_error always be 0?