diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 959a8c789..0c0aa654a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2014-08-19 Corinna Vinschen + + * fhandler.h (enum conn_state): Add "connect_credxchg" state. + (class fhandler_socket): Grant another bit to connect_state flag. + * fhandler_socket.cc (fhandler_socket::af_local_connect): Rearrange + variable definition. Set connect_state to connect_credxchg. + (fhandler_socket::af_local_accept): Ditto. + (fhandler_socket::recv_internal): Accept connect_credxchg on connection + oriented AF_LOCAL sockets as well to allow the credential exchange. + Extend comment to explain. + 2014-08-19 Corinna Vinschen * autoload.cc: Replace WNet[...]A with WNet[...]W imports. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 616068599..173e531ba 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -75,10 +75,11 @@ enum dirent_states enum conn_state { unconnected = 0, - connect_pending = 1, - connected = 2, - listener = 3, - connect_failed = 4 + connect_credxchg = 1, + connect_pending = 2, + connected = 3, + listener = 4, + connect_failed = 5 }; enum line_edit_status @@ -529,7 +530,7 @@ class fhandler_socket: public fhandler_base unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */ unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */ unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */ - unsigned connect_state : 2; + unsigned connect_state : 3; public: status_flags () : async_io (0), saw_shutdown_read (0), saw_shutdown_write (0), diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 779508b8c..59c002c03 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -396,12 +396,14 @@ fhandler_socket::af_local_send_cred () int fhandler_socket::af_local_connect () { + bool orig_async_io, orig_is_nonblocking; + /* This keeps the test out of select. */ if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM) return 0; debug_printf ("af_local_connect called"); - bool orig_async_io, orig_is_nonblocking; + connect_state (connect_credxchg); af_local_setblocking (orig_async_io, orig_is_nonblocking); if (!af_local_send_secret () || !af_local_recv_secret () || !af_local_send_cred () || !af_local_recv_cred ()) @@ -418,8 +420,10 @@ fhandler_socket::af_local_connect () int fhandler_socket::af_local_accept () { - debug_printf ("af_local_accept called"); bool orig_async_io, orig_is_nonblocking; + + debug_printf ("af_local_accept called"); + connect_state (connect_credxchg); af_local_setblocking (orig_async_io, orig_is_nonblocking); if (!af_local_recv_secret () || !af_local_send_secret () || !af_local_recv_cred () || !af_local_send_cred ()) @@ -1402,8 +1406,14 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg) int orig_namelen = wsamsg->namelen; /* Windows event handling does not check for the validity of the desired - flags so we have to do it here. */ - if (get_socket_type () == SOCK_STREAM && connect_state () != connected) + flags so we have to do it here. + The check goes like this: + STREAM sockets must be either connected, or they are AF_LOCAL + sockets in the pre-connected credential exchange phase. + All other states are disallowed. */ + if (get_socket_type () == SOCK_STREAM && connect_state () != connected + && (get_addr_family () != AF_LOCAL + || connect_state () != connect_credxchg)) { WSASetLastError (WSAENOTCONN); set_winsock_errno ();