Cygwin: connect: set connect state for DGRAM sockets
When connect is called on a DGRAM socket, the call to Winsock's connect can immediately return successfully rather than failing with WSAEWOULDBLOCK. Set the connect state to "connected" in this case. Previously the connect state remained "connect_pending" after the successful connection.
This commit is contained in:
parent
ae6e6c3526
commit
2be07f7554
|
@ -785,11 +785,13 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
|
||||||
if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR)
|
if (get_inet_addr_inet (name, namelen, &sst, &namelen) == SOCKET_ERROR)
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
|
||||||
/* Initialize connect state to "connect_pending". State is ultimately set
|
/* Initialize connect state to "connect_pending". In the SOCK_STREAM
|
||||||
to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
|
case, the state is ultimately set to "connected" or "connect_failed" in
|
||||||
event occurs. Note that the underlying OS sockets are always non-blocking
|
wait_for_events when the FD_CONNECT event occurs. Note that the
|
||||||
and a successfully initiated non-blocking Winsock connect always returns
|
underlying OS sockets are always non-blocking in this case and a
|
||||||
WSAEWOULDBLOCK. Thus it's safe to rely on event handling.
|
successfully initiated non-blocking Winsock connect always returns
|
||||||
|
WSAEWOULDBLOCK. Thus it's safe to rely on event handling. For DGRAM
|
||||||
|
sockets, however, connect can return immediately.
|
||||||
|
|
||||||
Check for either unconnected or connect_failed since in both cases it's
|
Check for either unconnected or connect_failed since in both cases it's
|
||||||
allowed to retry connecting the socket. It's also ok (albeit ugly) to
|
allowed to retry connecting the socket. It's also ok (albeit ugly) to
|
||||||
|
@ -801,7 +803,9 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
|
||||||
connect_state (connect_pending);
|
connect_state (connect_pending);
|
||||||
|
|
||||||
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
||||||
if (!is_nonblocking ()
|
if (!res)
|
||||||
|
connect_state (connected);
|
||||||
|
else if (!is_nonblocking ()
|
||||||
&& res == SOCKET_ERROR
|
&& res == SOCKET_ERROR
|
||||||
&& WSAGetLastError () == WSAEWOULDBLOCK)
|
&& WSAGetLastError () == WSAEWOULDBLOCK)
|
||||||
res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
|
res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
|
||||||
|
@ -824,8 +828,7 @@ fhandler_socket_inet::connect (const struct sockaddr *name, int namelen)
|
||||||
Convert to POSIX/Linux compliant EISCONN. */
|
Convert to POSIX/Linux compliant EISCONN. */
|
||||||
else if (err == WSAEINVAL && connect_state () == listener)
|
else if (err == WSAEINVAL && connect_state () == listener)
|
||||||
WSASetLastError (WSAEISCONN);
|
WSASetLastError (WSAEISCONN);
|
||||||
/* Any other error except WSAEALREADY during connect_pending means the
|
/* Any other error except WSAEALREADY means the connect failed. */
|
||||||
connect failed. */
|
|
||||||
else if (connect_state () == connect_pending && err != WSAEALREADY)
|
else if (connect_state () == connect_pending && err != WSAEALREADY)
|
||||||
connect_state (connect_failed);
|
connect_state (connect_failed);
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
|
|
|
@ -914,11 +914,13 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
|
||||||
if (get_socket_type () == SOCK_STREAM)
|
if (get_socket_type () == SOCK_STREAM)
|
||||||
af_local_set_cred ();
|
af_local_set_cred ();
|
||||||
|
|
||||||
/* Initialize connect state to "connect_pending". State is ultimately set
|
/* Initialize connect state to "connect_pending". In the SOCK_STREAM
|
||||||
to "connected" or "connect_failed" in wait_for_events when the FD_CONNECT
|
case, the state is ultimately set to "connected" or "connect_failed" in
|
||||||
event occurs. Note that the underlying OS sockets are always non-blocking
|
wait_for_events when the FD_CONNECT event occurs. Note that the
|
||||||
and a successfully initiated non-blocking Winsock connect always returns
|
underlying OS sockets are always non-blocking in this case and a
|
||||||
WSAEWOULDBLOCK. Thus it's safe to rely on event handling.
|
successfully initiated non-blocking Winsock connect always returns
|
||||||
|
WSAEWOULDBLOCK. Thus it's safe to rely on event handling. For DGRAM
|
||||||
|
sockets, however, connect can return immediately.
|
||||||
|
|
||||||
Check for either unconnected or connect_failed since in both cases it's
|
Check for either unconnected or connect_failed since in both cases it's
|
||||||
allowed to retry connecting the socket. It's also ok (albeit ugly) to
|
allowed to retry connecting the socket. It's also ok (albeit ugly) to
|
||||||
|
@ -930,7 +932,9 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
|
||||||
connect_state (connect_pending);
|
connect_state (connect_pending);
|
||||||
|
|
||||||
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
int res = ::connect (get_socket (), (struct sockaddr *) &sst, namelen);
|
||||||
if (!is_nonblocking ()
|
if (!res)
|
||||||
|
connect_state (connected);
|
||||||
|
else if (!is_nonblocking ()
|
||||||
&& res == SOCKET_ERROR
|
&& res == SOCKET_ERROR
|
||||||
&& WSAGetLastError () == WSAEWOULDBLOCK)
|
&& WSAGetLastError () == WSAEWOULDBLOCK)
|
||||||
res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
|
res = wait_for_events (FD_CONNECT | FD_CLOSE, 0);
|
||||||
|
@ -953,8 +957,7 @@ fhandler_socket_local::connect (const struct sockaddr *name, int namelen)
|
||||||
Convert to POSIX/Linux compliant EISCONN. */
|
Convert to POSIX/Linux compliant EISCONN. */
|
||||||
else if (err == WSAEINVAL && connect_state () == listener)
|
else if (err == WSAEINVAL && connect_state () == listener)
|
||||||
WSASetLastError (WSAEISCONN);
|
WSASetLastError (WSAEISCONN);
|
||||||
/* Any other error except WSAEALREADY during connect_pending means the
|
/* Any other error except WSAEALREADY means the connect failed. */
|
||||||
connect failed. */
|
|
||||||
else if (connect_state () == connect_pending && err != WSAEALREADY)
|
else if (connect_state () == connect_pending && err != WSAEALREADY)
|
||||||
connect_state (connect_failed);
|
connect_state (connect_failed);
|
||||||
set_winsock_errno ();
|
set_winsock_errno ();
|
||||||
|
|
|
@ -12,7 +12,7 @@ Bug Fixes
|
||||||
- Fix values returned by select(2) for shutdown sockets.
|
- Fix values returned by select(2) for shutdown sockets.
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin-developers/2021-April/012092.html
|
Addresses: https://cygwin.com/pipermail/cygwin-developers/2021-April/012092.html
|
||||||
|
|
||||||
- Introduce a new hypotl(3) function not suffering unnecesswry overflows.
|
- Introduce a new hypotl(3) function not suffering unnecessary overflows.
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin/2021-April/248302.html
|
Addresses: https://cygwin.com/pipermail/cygwin/2021-April/248302.html
|
||||||
|
|
||||||
- Fix path handling for paths spanning native symlinks.
|
- Fix path handling for paths spanning native symlinks.
|
||||||
|
@ -25,3 +25,6 @@ Bug Fixes
|
||||||
|
|
||||||
- Handle two race conditions in pseudo console usage.
|
- Handle two race conditions in pseudo console usage.
|
||||||
Addresses: https://cygwin.com/pipermail/cygwin/2021-April/248292.html
|
Addresses: https://cygwin.com/pipermail/cygwin/2021-April/248292.html
|
||||||
|
|
||||||
|
- Fix a bug in recognizing a successful completion of connect(2) on a
|
||||||
|
datagram socket.
|
||||||
|
|
Loading…
Reference in New Issue