Skip to content

raspberrypi: implement setsockopt(SOL_SOCKET, SO_REUSEADDR) #9084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 26, 2024

Conversation

jepler
Copy link

@jepler jepler commented Mar 25, 2024

untested

edit by @dhalbert:
Fixes #9081.

@anecdata
Copy link
Member

anecdata commented Mar 26, 2024

Adafruit CircuitPython 9.0.0-2-g1ad5a73eb5 on 2024-03-25; Raspberry Pi Pico W with rp2040
+
latest release adafruit_httpserver 4.5.6

...works fine, no exceptions.

A number of resets of the server didn't yield any exceptions. We can test the no-reuse case pending the question above. I'm not sure how to reliably trigger the address in use exception though (that may become apparent by clearing SOF_REUSEADDR).

@jepler jepler requested a review from anecdata March 26, 2024 12:48
@anecdata
Copy link
Member

anecdata commented Mar 26, 2024

With today's artifact and same latest release of the adafruit_httpserver library, I get OSError: [Errno 112] EADDRINUSE upon bind by default when the server is interrupted (^C) and restarted (^D). This code is in the library server.py:

        if implementation.version >= (9,) or implementation.name != "circuitpython":
            sock.setsockopt(socket_source.SOL_SOCKET, socket_source.SO_REUSEADDR, 1)

But if I change it to sock.setsockopt(socket_source.SOL_SOCKET, socket_source.SO_REUSEADDR, 0), then there is no EADDRINUSE exception. Backwards (I think?), but not sure why.

(btw, I'm using httpserver_simpletest_manual.py from the library repo)

memcmp() returns -1, 0 or 1 to denote the relative ordering of the two
buffers. So, the computation would actually set `enable = 0`
in the case where `value` had the same bits set as "one" and `enable = 1`
in the case where `value` had any other bits.

By changing the compared buffer to be `zero`, `enable` gets a true value
whenever the value is NOT exactly 0 (e.g., it's 1, 7, -1, ...),
correcting the sense of enable vs disable.

Thanks to @anecdata for testing and finding this problem, which previously
would have affected the nodelay flag as well.
Copy link
Member

@anecdata anecdata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.SO_REUSEADDR, 1 now prevents EADDRINUSE and allows the server to immediately re-bind, and .SO_REUSEADDR, 0 raises EADDRINUSE when attempting to re-bind within the timeout. Thanks, @jepler !

@jepler jepler merged commit 7d30ef3 into adafruit:9.0.x Mar 26, 2024
22 checks passed
@jepler jepler deleted the rpi-setsockopt-90x branch March 26, 2024 21:06
@jepler
Copy link
Author

jepler commented Mar 26, 2024

really appreciated the testing @anecdata !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants