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.
This commit is contained in:
Corinna Vinschen
2014-10-11 18:28:04 +00:00
parent a85ab1d482
commit 697b9afe00
5 changed files with 74 additions and 4 deletions

View File

@ -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);