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

Using the PASV command can leave the opened socket hanging open permantently #434

Closed
dani-garcia opened this issue Oct 13, 2022 · 6 comments · Fixed by #436
Closed

Using the PASV command can leave the opened socket hanging open permantently #434

dani-garcia opened this issue Oct 13, 2022 · 6 comments · Fixed by #436

Comments

@dani-garcia
Copy link
Contributor

When a client uses the PASV command, but doesn't connect to the returned port (because of flaky internet or a faulty FTP implementation), the opened TCP listener gets stuck permanently open without a timeout. This can exhaust all the available passive ports, given enough time.

This is the current implementation, the socket will remain open unless someone tries to connect to it.

// Open the data connection in a new task and process it.
// We cannot await this since we first need to let the client know where to connect :-)
tokio::spawn(async move {
if let Ok((socket, _socket_addr)) = listener.accept().await {
datachan::spawn_processing(logger, session, socket).await;
}
});

I've tested the code changing it to the following and it works, but I'm not sure if it should be configurable with idle_session_timeout, a new option, or simply hardcoded:

    // Open the data connection in a new task and process it.
    // We cannot await this since we first need to let the client know where to connect :-)
    tokio::spawn(async move {
        if let Ok(Ok((socket, _socket_addr))) = tokio::time::timeout(std::time::Duration::from_secs(30), listener.accept()).await {
            datachan::spawn_processing(logger, session, socket).await
        }
    });
@robklg
Copy link
Contributor

robklg commented Oct 23, 2022

Hi, @dani-garcia sorry for the late response. Thanks for this find and the suggested fix! We will discuss this in our standup.

@hannesdejager
Copy link
Collaborator

@dani-garcia We can just hard-code it for now. We can add an option for it at a later stage. This setting would be different from idle_session_timeout which would normally be quite larger and pertains to the control channel instead.

Would you like to make an MR or should we take it from here?

@dani-garcia
Copy link
Contributor Author

I can open a PR with the changes yeah, do you think the 30 seconds value is a good default for it?

I assume clients would normally connect immediately so the value could be reduced to 10 seconds or less, but maybe we prefer to be a bit more conservative at first.

@hannesdejager
Copy link
Collaborator

@dani-garcia Thanks!! lets make it 15.

@dani-garcia
Copy link
Contributor Author

Done #436

hannesdejager added a commit that referenced this issue Oct 26, 2022
We didn't log anything when the client's connection to the data port did
not succeed.

Relates to #434
hannesdejager added a commit that referenced this issue Oct 26, 2022
We didn't log anything when the client's connection to the data port did
not succeed.

Relates to #434
@hannesdejager
Copy link
Collaborator

@dani-garcia Thank you for your contribution. I just made a release that also includes this change.

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 a pull request may close this issue.

3 participants