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

Windows: refused connections will not immediately fail #969

Closed
RealDolos opened this issue Jul 25, 2017 · 1 comment
Closed

Windows: refused connections will not immediately fail #969

RealDolos opened this issue Jul 25, 2017 · 1 comment
Assignees

Comments

@RealDolos
Copy link

On Windows, select() will not mark a writefd socket if a connect()ion fails, e.g. because the peer refused the connection, but instead mark an exceptfd.

This is documented behavior:

If a socket is processing a connect call (nonblocking), failure of the connect attempt is indicated in exceptfds (application must then call getsockopt SO_ERROR to determine the error value to describe why the failure occurred).

aria2 does not check exceptfds (at all), leading aria2 to missing that error and only canceling the download once the regular timeout expires but not immediately after the connection actually broke.

On *nix, connect()ion failures are indicated by marking the writefd instead, so there it works.

This actually makes it work, but no idea what else it broke. It just uses the same writefd set as exceptfds as well.

--- a/src/SelectEventPoll.cc
+++ b/src/SelectEventPoll.cc
@@ -167,42 +167,37 @@ SelectEventPoll::~SelectEventPoll()
 #endif // __MINGW32__
 }
 
 void SelectEventPoll::poll(const struct timeval& tv)
 {
   fd_set rfds;
   fd_set wfds;
 
   memcpy(&rfds, &rfdset_, sizeof(fd_set));
   memcpy(&wfds, &wfdset_, sizeof(fd_set));
-#ifdef __MINGW32__
-  fd_set efds;
-  FD_ZERO(&efds);
-  FD_SET(dummySocket_, &efds);
-#endif // __MINGW32__
 #ifdef ENABLE_ASYNC_DNS
 
   for (auto& i : nameResolverEntries_) {
     auto& entry = i.second;
     int fd = entry.getFds(&rfds, &wfds);
     // TODO force error if fd == 0
     if (fdmax_ < fd) {
       fdmax_ = fd;
     }
   }
 
 #endif // ENABLE_ASYNC_DNS
   int retval;
   do {
     struct timeval ttv = tv;
 #ifdef __MINGW32__
-    retval = select(fdmax_ + 1, &rfds, &wfds, &efds, &ttv);
+    retval = select(fdmax_ + 1, &rfds, &wfds, &wfds, &ttv);
 #else // !__MINGW32__
     retval = select(fdmax_ + 1, &rfds, &wfds, nullptr, &ttv);
 #endif // !__MINGW32__
   } while (retval == -1 && errno == EINTR);
   if (retval > 0) {
     for (auto& i : socketEntries_) {
       auto& e = i.second;
       int events = 0;
       if (FD_ISSET(e.getSocket(), &rfds)) {
         events |= EventPoll::EVENT_READ;
@nmaier
Copy link
Collaborator

nmaier commented Jul 31, 2017

Can repo

@nmaier nmaier self-assigned this Jul 31, 2017
nmaier added a commit that referenced this issue Jul 31, 2017
winsock notifies connect() failures on exceptfds instead of writefds.
Fixes GH-969
@nmaier nmaier closed this as completed in 1fe6cc7 Aug 28, 2017
vijayanandnandam pushed a commit to vijayanandnandam/aria2 that referenced this issue Mar 3, 2018
winsock notifies connect() failures on exceptfds instead of writefds.
Fixes aria2GH-969
Fixes aria2GH-975
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

No branches or pull requests

2 participants