Skip to content
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

[3.3] Enable server socket reuseAddress option before binding #15239

Open
wants to merge 1 commit into
base: 3.3
Choose a base branch
from

Conversation

zrlw
Copy link
Contributor

@zrlw zrlw commented Mar 14, 2025

What is the purpose of the change?

try to fix #15238
sometimes the port got from NetUtils#getAvailablePort could not be bound directly because the port status is still TIME-WAIT as getAvailablePort closed it without setting SO_REUSEADDR option.

Checklist

  • Make sure there is a GitHub_issue field for the change.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in dubbo samples project.
  • Make sure gitHub actions can pass. Why the workflow is failing and how to fix it?

@codecov-commenter
Copy link

codecov-commenter commented Mar 14, 2025

Codecov Report

Attention: Patch coverage is 72.22222% with 5 lines in your changes missing coverage. Please review.

Project coverage is 60.78%. Comparing base (d3b1e1f) to head (cba2c7b).
Report is 15 commits behind head on 3.3.

Files with missing lines Patch % Lines
...n/java/org/apache/dubbo/common/utils/NetUtils.java 73.33% 2 Missing and 2 partials ⚠️
...ng/transport/netty/NettyPortUnificationServer.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                3.3   #15239      +/-   ##
============================================
- Coverage     60.79%   60.78%   -0.01%     
- Complexity    10892    10894       +2     
============================================
  Files          1885     1885              
  Lines         86082    86102      +20     
  Branches      12895    12898       +3     
============================================
+ Hits          52331    52341      +10     
- Misses        28303    28316      +13     
+ Partials       5448     5445       -3     
Flag Coverage Δ
integration-tests 33.09% <50.00%> (-0.06%) ⬇️
samples-tests 29.23% <33.33%> (+0.04%) ⬆️
unit-tests 58.92% <72.22%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@oxsean
Copy link
Contributor

oxsean commented Mar 14, 2025

Is it possible to add some tests?

@zrlw
Copy link
Contributor Author

zrlw commented Mar 16, 2025

Is it possible to add some tests?

the results of these codes vary with os and jdk version,

ServerSocket serverSocket = new ServerSocket(port);
assertFalse(serverSocket.getReuseAddress());

passed if running on win10 + compiled by jdk8,
failed if running on linux + compiled by jdk17 as serverSocket.getReuseAddress() returns true.
i doubt there should have unified solution.

@zrlw zrlw force-pushed the 3.3-feature-setReuseAddressOption branch from fd08802 to c0ce2a7 Compare March 17, 2025 01:38
@zrlw zrlw changed the title [3.3] Set socket reuse address option to true [3.3] Enable server socket ReuseAddress option before binding Mar 17, 2025
@zrlw zrlw force-pushed the 3.3-feature-setReuseAddressOption branch from c0ce2a7 to d4b785c Compare March 17, 2025 01:43
@zrlw zrlw changed the title [3.3] Enable server socket ReuseAddress option before binding [3.3] Enable server socket reuseAddress option before binding Mar 17, 2025
@zrlw
Copy link
Contributor Author

zrlw commented Mar 17, 2025

see SO_REUSEADDR at java.net.StandardSocketOptions,

Re-use address.
An implementation allows this socket option to be set before the socket is bound or connected. Changing the value of this socket option after the socket is bound has no effect. The default value of this socket option is system dependent.

SO_REUSEADDR
since the default value of SO_REUSEADDR is always true on some system, I didn't think of how to write appropriate testing case.

    @Test
    void testRepeatedStatusChecking() {
        int port = NetUtils.getAvailablePort();
        for (int i = 0; i < 1000; i++) {
            assertFalse(NetUtils.isPortInUsed(port));
        }
    } 

@zrlw
Copy link
Contributor Author

zrlw commented Mar 17, 2025

setReuseAddress
Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state.

try (ServerSocket ignored = new ServerSocket(i)) {
try (ServerSocket serverSocket = new ServerSocket()) {
// SO_REUSEADDR should be enabled before bind.
serverSocket.setReuseAddress(true);
Copy link
Member

Choose a reason for hiding this comment

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

Are there any systems which cannot support such configuration or will throw exception here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if an error occurs, or the socket is closed, SocketException will be thrown here.

Copy link
Contributor Author

@zrlw zrlw Mar 18, 2025

Choose a reason for hiding this comment

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

i see. Embedded, real time system, or old Unix ( before 1980?) might not support SO_REUSEADDR. added condition check before setting it.

try (ServerSocket serverSocket = new ServerSocket()) {
serverSocket.setReuseAddress(true);
reuseAddressSupported = true;
} catch (IOException e) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
} catch (IOException e) {
} catch (Throwable ignore) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

@zrlw zrlw force-pushed the 3.3-feature-setReuseAddressOption branch from 8b08a99 to e15ba4d Compare March 19, 2025 02:06
@zrlw
Copy link
Contributor Author

zrlw commented Mar 19, 2025

there are still somethings need to be revised, the port 39119 opened by NettyTransporterTest#shouldAbleToBindNetty4 does not be closed after testing.
[updated] fixed it.
https://github.com/apache/dubbo/actions/runs/13937299977/job/39007599423
port39119
testConnection
test

@zrlw zrlw force-pushed the 3.3-feature-setReuseAddressOption branch from e15ba4d to cba2c7b Compare March 19, 2025 04:14
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.

[Bug] sometimes the port got from NetUtils#getAvailablePort could not be bound directly
4 participants