From 859d215b7e006e5fc60f686ec976e997e35d169b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 21 Feb 2018 21:40:01 +0100 Subject: Cygwin: split out fhandler_socket into inet and local classes First cut, still incomplete * fhandler_socket is now base class for other socket classes * fhandler_socket_inet handles AF_INET and AF_INET6 sockets * fhandler_socket_local handles AF_LOCAL/AF_UNIX sockets * finally get rid of fdsock by using set_socket_handle in accept4 * align file-related calls (fstat, fstatvfs, fchown, fchmod, facl) to Linux. Signed-off-by: Corinna Vinschen --- winsup/cygwin/net.cc | 140 --------------------------------------------------- 1 file changed, 140 deletions(-) (limited to 'winsup/cygwin/net.cc') diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 0d853327e..e849b04cc 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -500,146 +500,6 @@ cygwin_getprotobynumber (int number) return dup_ent (getprotobynumber (number)); } -#ifndef SIO_BASE_HANDLE -#define SIO_BASE_HANDLE _WSAIOR(IOC_WS2,34) -#endif - -bool -fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc) -{ - fd = build_fh_dev (*dev); - if (!fd.isopen ()) - return false; - - /* Usually sockets are inheritable IFS objects. Unfortunately some virus - scanners or other network-oriented software replace normal sockets - with their own kind, which is running through a filter driver called - "layered service provider" (LSP). - - LSP sockets are not kernel objects. They are typically not marked as - inheritable, nor are they IFS handles. They are in fact not inheritable - to child processes, and it does not help to mark them inheritable via - SetHandleInformation. Subsequent socket calls in the child process fail - with error 10038, WSAENOTSOCK. - - There's a neat way to workaround these annoying LSP sockets. WSAIoctl - allows to fetch the underlying base socket, which is a normal, inheritable - IFS handle. So we fetch the base socket, duplicate it, and close the - original socket. Now we have a standard IFS socket which (hopefully) - works as expected. - - If that doesn't work for some reason, mark the sockets for duplication - via WSADuplicateSocket/WSASocket. This requires to start the child - process in SUSPENDED state so we only do this if really necessary. */ - DWORD flags; - bool fixup = false; - if (!GetHandleInformation ((HANDLE) soc, &flags) - || !(flags & HANDLE_FLAG_INHERIT)) - { - int ret; - SOCKET base_soc; - DWORD bret; - - fixup = true; - debug_printf ("LSP handle: %p", soc); - ret = WSAIoctl (soc, SIO_BASE_HANDLE, NULL, 0, (void *) &base_soc, - sizeof (base_soc), &bret, NULL, NULL); - if (ret) - debug_printf ("WSAIoctl: %u", WSAGetLastError ()); - else if (base_soc != soc) - { - if (GetHandleInformation ((HANDLE) base_soc, &flags) - && (flags & HANDLE_FLAG_INHERIT)) - { - if (!DuplicateHandle (GetCurrentProcess (), (HANDLE) base_soc, - GetCurrentProcess (), (PHANDLE) &base_soc, - 0, TRUE, DUPLICATE_SAME_ACCESS)) - debug_printf ("DuplicateHandle failed, %E"); - else - { - closesocket (soc); - soc = base_soc; - fixup = false; - } - } - } - } - fd->set_io_handle ((HANDLE) soc); - if (!((fhandler_socket *) fd)->init_events ()) - return false; - if (fixup) - ((fhandler_socket *) fd)->init_fixup_before (); - fd->set_flags (O_RDWR | O_BINARY); - debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name (), soc); - - /* Raise default buffer sizes (instead of WinSock default 8K). - - 64K appear to have the best size/performance ratio for a default - value. Tested with ssh/scp on Vista over Gigabit LAN. - - NOTE. If the SO_RCVBUF size exceeds 65535(*), and if the socket is - connected to a remote machine, then calling WSADuplicateSocket on - fork/exec fails with WinSock error 10022, WSAEINVAL. Fortunately - we don't use WSADuplicateSocket anymore, rather we just utilize - handle inheritance. An explanation for this weird behaviour would - be nice, though. - - NOTE 2. Testing on x86_64 (Vista, 2008 R2, W8) indicates that - this is no problem on 64 bit. So we set the default buffer size to - the default values in current 3.x Linux versions. - - NOTE 3. Setting the window size to 65535 results in extremely bad - performance for apps that send data in multiples of Kb, as they - eventually end up sending 1 byte on the network and naggle + delay - ack kicks in. For example, iperf on a 10Gb network gives only 10 - Mbits/sec with a 65535 send buffer. We want this to be a multiple - of 1k, but since 64k breaks WSADuplicateSocket we use 63Kb. - - NOTE 4. Tests with iperf uncover a problem in setting the SO_RCVBUF - and SO_SNDBUF sizes. Windows is using autotuning since Windows Vista. - Manually setting SO_RCVBUF/SO_SNDBUF disables autotuning and leads to - inferior send/recv performance in scenarios with larger RTTs, as is - basically standard when accessing the internet. For a discussion, - see https://cygwin.com/ml/cygwin-patches/2017-q1/msg00010.html. - - (*) Maximum normal TCP window size. Coincidence? */ -#ifdef __x86_64__ - ((fhandler_socket *) fd)->rmem () = 212992; - ((fhandler_socket *) fd)->wmem () = 212992; -#else - ((fhandler_socket *) fd)->rmem () = 64512; - ((fhandler_socket *) fd)->wmem () = 64512; -#endif -#if 0 /* See NOTE 4 above. */ - int size; - - if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF, - (char *) &((fhandler_socket *) fd)->rmem (), sizeof (int))) - { - debug_printf ("setsockopt(SO_RCVBUF) failed, %u", WSAGetLastError ()); - if (::getsockopt (soc, SOL_SOCKET, SO_RCVBUF, - (char *) &((fhandler_socket *) fd)->rmem (), - (size = sizeof (int), &size))) - system_printf ("getsockopt(SO_RCVBUF) failed, %u", WSAGetLastError ()); - } - if (::setsockopt (soc, SOL_SOCKET, SO_SNDBUF, - (char *) &((fhandler_socket *) fd)->wmem (), sizeof (int))) - { - debug_printf ("setsockopt(SO_SNDBUF) failed, %u", WSAGetLastError ()); - if (::getsockopt (soc, SOL_SOCKET, SO_SNDBUF, - (char *) &((fhandler_socket *) fd)->wmem (), - (size = sizeof (int), &size))) - system_printf ("getsockopt(SO_SNDBUF) failed, %u", WSAGetLastError ()); - } -#endif - /* A unique ID is necessary to recognize fhandler entries which are - duplicated by dup(2) or fork(2). This is used in BSD flock calls - to identify the descriptor. */ - ((fhandler_socket *) fd)->set_unique_id (); - - return true; -} - /* exported as socket: POSIX.1-2001, POSIX.1-2008, 4.4BSD */ extern "C" int cygwin_socket (int af, int type, int protocol) -- cgit v1.2.3