diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-10-11 22:28:04 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-10-11 22:28:04 +0400 |
commit | 697b9afe00c21df9fc74c748ea35113b4b37c4b4 (patch) | |
tree | fd3a5755a6880643d192ebb7043dd501dedd1505 /winsup/cygwin/net.cc | |
parent | a85ab1d48243778e745b8f04b3eb67b8c13a64ad (diff) |
Add setsockopt(sd, SOL_SOCKET, SO_PEERCRED, NULL, 0) to disable
initial handshake on AF_LOCAL sockets.
* fhandler.h (class fhandler_socket): Add no_getpeereid status flag.
(fhandler_socket::af_local_set_no_getpeereid): New prototype.
* fhandler_socket.cc (fhandler_socket::af_local_connect): Skip handshake
if no_getpeereid is set. Add debug output.
(fhandler_socket::af_local_accept): Likewise.
(fhandler_socket::af_local_set_no_getpeereid): New function.
(fhandler_socket::af_local_copy): Copy no_getpeereid.
(fhandler_socket::getpeereid): Fail if no_getpeereid is set.
* net.cc (cygwin_setsockopt): Add SO_PEERCRED for AF_LOCAL/SOCK_STREAM
sockets. Add comment to explain why we need it.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
Diffstat (limited to 'winsup/cygwin/net.cc')
-rw-r--r-- | winsup/cygwin/net.cc | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index b6c0f7257..a01dbedf1 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -810,6 +810,25 @@ cygwin_setsockopt (int fd, int level, int optname, const void *optval, fhandler_socket *fh = get (fd); if (!fh) __leave; + + /* Switch off the AF_LOCAL handshake and thus SO_PEERCRED handling + for AF_LOCAL/SOCK_STREAM sockets. This allows to handle special + situations in which connect is called before a listening socket + accepts connections. + FIXME: In the long run we should find a more generic solution which + doesn't require a blocking handshake in accept/connect to exchange + SO_PEERCRED credentials. */ + if (level == SOL_SOCKET && optname == SO_PEERCRED) + { + if (optval || optlen + || fh->get_addr_family () != AF_LOCAL + || fh->get_socket_type () != SOCK_STREAM) + set_errno (EINVAL); + else + res = fh->af_local_set_no_getpeereid (); + __leave; + } + /* Old applications still use the old WinSock1 IPPROTO_IP values. */ if (level == IPPROTO_IP && CYGWIN_VERSION_CHECK_FOR_USING_WINSOCK1_VALUES) optname = convert_ws1_ip_optname (optname); |