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
multi: implement wait using winsock events #5634
Conversation
Thanks, I will take a look later this week. This reminds me of a similar issue and solution I had with |
f62a6dc
to
8805a4b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
One thing which we missed last time: This makes curl itself depend on WinSock2 for the first time. Currently it is theoretically possible to still run curl on versions older than Windows 95 (NT 3.5), but with this change curl requires at least Windows 98 (NT 4.0) or Windows 95 (NT 3.5) with the WinSocks2 addon package. I don't know if these historic Windows versions still matter to us. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I don't think requiring WinSock 2 is a problem as we require the February 2003 Platform SDK anyway, which doesn't support anything older than Windows 95, and Windows NT before 3.5 didn't support WinSock at all.
Side note: this means we can also get rid of some Lines 1343 to 1392 in 0f55269
|
@bagder Do you approve giving this another try for this release? |
If we can't reproduce what @rmja described I'd say go for it. |
I agree with @jay. It would be good to get a test case added that would reproduce the previous bug and see that it no longer does... |
I will try to turn the example given by @rmja into a test case, to make sure we catch this error in the future. |
Let me know if you can produce a prerelease build, then I can test to see if it works or not. |
Regarding the test case I wanted to create: we already have many FTP and SFTP upload test cases in our testsuite, so the use case should already be covered. The only problem is: we are currently not running SCP/SFTP tests on any Windows CI since I migrated my builds from buildbot to Azure Pipelines. I lost libssh2 support on the way and it is still on my ToDo list to bring that back. In the mean time I would like to ask @rmja and @RadMission to check if this PR still has the problem for them. The Windows CI jobs for this PR successfully ran all the relevant HTTP and FTP upload tests at least, so if there is still any problem, I guess it is with SCP/SFTP. Please help us test this PR manually for now. Thanks in advance! |
I will be happy to test this on Windows if you can send a link to a downloadable build. |
Okay, I can probably provide a debug build tomorrow. |
@rmja attached you will find a debug build created with mingw-w64 from this PR on current curl and libssh2 master. I was successfully able to do an SFTP upload with this build: |
@mback2k My test suite fails with this build - I get SSL_CONNECT_ERROR when I do easy_perform. The curl builds that I have used until now has openssl and libcrypto as dependencies. I have of cause extracted all the files in the zip you provided, but is there any other dependency that I need to include for this build to work correctly? |
@rmja that build is just using libssh2 (with Windows-native WinCNG crypto backend) and curl (with Windows-native Schannel TLS backend). So it should work on recent Windows (>= Vista) without any additional dependencies except this mingw-w64 |
Here is the outline of handle configuration. I have to proxy as the target server is IP filtered.
|
Sorry, I did not compare my results to
The testing I did was running The comparison to FileZilla was just a side note. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot comment on the code as this uses lots of Windows magic that I don't know anything about.
I think the least positive thing with this code is the extreme amount new #ifdefs
it adds, since it really creates a maze. Unfortunately I can't say I have any immediate ideas on how to remedy that.
If the code builds and doesn't cause regressions I'm fine with the change as I think it improves curl on Windows.
lib/multi.c
Outdated
struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK]; | ||
struct pollfd *ufds = &a_few_on_stack[0]; | ||
bool ufds_malloc = FALSE; | ||
#else | ||
int already_writable = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just use a bool
for this instead ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rcombs would you mind applying my patch above, since it also addresses this?
if(select((int)sockbunch[i] + 1, NULL, &writefds, NULL, | ||
&timeout) == 1) | ||
already_writable++; | ||
mask |= FD_WRITE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe this code could be made into a separate sub-function as the exact same logic is done again further down?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rcombs would you mind applying my patch above, since it also addresses this by using existing macros?
I requested your review in order to get a general approval to do this change since it broke curl in the past. 😉
Yes, I also thought whether it would be better to just create a new Windows-specific wait function and use that instead. What do you think?
We are not sure about this yet, as we are waiting on feedback from @rmja once he is available again (see #5633 (comment)). |
Patch overall looks good, but are the |
@rcombs I think they are due to the fact that |
This avoids using a pair of TCP ports to provide wakeup functionality for every multi instance on Windows, where socketpair() is emulated using a TCP socket on loopback which could in turn lead to socket resource exhaustion. A previous version of this patch failed to account for how in Winsock, FD_WRITE is set only once when writing becomes possible and not again until after a send has failed due to the buffer filling. This contrasts to how FD_READ and FD_OOB continue to be set until the conditions they refer to no longer apply. This meant that if a user wrote some data to a socket, but not enough data to completely fill its send buffer, then waited on that socket to become writable, we'd erroneously stall until their configured timeout rather than returning immediately. This version of the patch addresses that issue by checking each socket we're waiting on to become writable with select() before the wait, and zeroing the timeout if it's already writable. Improved-By: Marc Hoersken <info@marc-hoersken.de>
Alright, rebased and re-pushed with @mback2k's changes applied; think we should be good to go now. |
@rcombs thanks, I will merge this once the release has cooled of a little and we can be sure there is no bugfix release needed. |
Check readiness of all sockets before waiting on them to avoid locking in case the one-time event FD_WRITE was already consumed by a previous wait operation. More information about WinSock network events: https://docs.microsoft.com/en-us/windows/win32/api/ winsock2/nf-winsock2-wsaeventselect#return-value Closes #5634
Update the ifdef-jungle to check for WinSock version 2. Follow up to curl#5634
Update the ifdef-jungle to check for WinSock version 2. Introduce version specific WinSock defines to ease checking. Follow up to curl#5634
IPv6, telnet and now also the multi API require WinSock version 2 which is available starting with Windows 95. Therefore we think it is time to drop support for version 1. Reviewed-by: Marcel Raad Reviewed-by: Jay Satiro Reviewed-by: Daniel Stenberg Reviewed-by: Viktor Szakats Follow up to #5634 Closes #5854
Repeat of #5397, but this time with #5631 fixed. In theory, anyway; I haven't had a chance to test this out on a Windows machine myself yet. Also not sure how to add a test (particularly one for something that takes longer than it should, but otherwise finishes correctly).