Page MenuHomeFreeBSD

Allow setting socket error
Needs ReviewPublic

Authored by sef on Jun 16 2024, 10:13 AM.
Tags
None
Referenced Files
F93764858: D45602.diff
Thu, Sep 12, 8:39 AM
Unknown Object (File)
Sun, Sep 8, 3:39 PM
Unknown Object (File)
Sun, Sep 8, 12:36 PM
Unknown Object (File)
Sun, Sep 8, 8:50 AM
Unknown Object (File)
Sat, Sep 7, 8:16 PM
Unknown Object (File)
Mon, Sep 2, 3:18 PM
Unknown Object (File)
Sun, Aug 18, 6:19 PM
Unknown Object (File)
Aug 5 2024, 5:57 PM
Subscribers

Details

Summary

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.

Test Plan

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

sef requested review of this revision.Jun 16 2024, 10:13 AM

I forgot to edit the man page.

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.

Any comments or reviews? ๐Ÿ˜„

In D45602#1042628, @sef wrote:

Any comments or reviews? ๐Ÿ˜„

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?