diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2024-03-22 15:34:29 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2024-03-22 15:34:29 +0100 |
commit | 8d2c1b4ce68608251860bc9a7c5b6f5762110dd1 (patch) | |
tree | e11b8494a35df9e922331e84cbb41d5fb8d522d2 /winsup | |
parent | 290843bbdab6853fff6ba4105c8faac43c621430 (diff) | |
download | newlib-8d2c1b4ce68608251860bc9a7c5b6f5762110dd1.zip newlib-8d2c1b4ce68608251860bc9a7c5b6f5762110dd1.tar.gz newlib-8d2c1b4ce68608251860bc9a7c5b6f5762110dd1.tar.bz2 |
Cygwin: //server: check existence of server with getaddrinfo
Checking server existence by trying to enumerate its shares
may result in 2 minutes delay until some internal timeout is hit.
In the light that every network is an IP network anyway these
days, let's try with a simple getaddrinfo() call. This is usually
back in 3 secs even if the server doesn't exist, and it's usually
back in 8 secs if the DNS server can't be connected. This is the
fastest method I found to check server existence yet.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/fhandler/netdrive.cc | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/winsup/cygwin/fhandler/netdrive.cc b/winsup/cygwin/fhandler/netdrive.cc index 4f080ef..1eff816 100644 --- a/winsup/cygwin/fhandler/netdrive.cc +++ b/winsup/cygwin/fhandler/netdrive.cc @@ -15,9 +15,11 @@ details. */ #include "cygheap.h" #include "cygthread.h" +#define USE_SYS_TYPES_FD_SET #include <shobjidl.h> #include <shlobj.h> #include <lm.h> +#include <ws2tcpip.h> #include <stdlib.h> #include <dirent.h> @@ -94,23 +96,14 @@ struct netdriveinf { DIR *dir; int err; - bool test_only; HANDLE sem; }; static inline int -hresult_to_errno (HRESULT wres, bool test_only = false) +hresult_to_errno (HRESULT wres) { if (SUCCEEDED (wres)) return 0; - /* IEnumShellItems::Reset returns E_NOTIMPL when called for share - enumeration. However, if the machine doesn't exist, the Win32 - error ERROR_BAD_NETPATH (converted into a HRESULT) is returned. In - test_only mode, we exploit this. Also, E_ACCESSDENIED is a funny - one. It means, the machine exists, you just have no right to - access the share list, or SMB doesn't run. */ - if (test_only && (wres == E_NOTIMPL || wres == E_ACCESSDENIED)) - return 0; if (((ULONG) wres & 0xffff0000) == (ULONG) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0)) return geterrno_from_win_error ((ULONG) wres & 0xffff); @@ -174,18 +167,9 @@ thread_netdrive (void *arg) goto out; } - if (len == 2 || ndi->test_only) + if (len == 2) { - wres = netitem_enum->Reset (); - - if (FAILED (wres) || ndi->test_only) - { - ndi->err = hresult_to_errno (wres, ndi->test_only); - netitem_enum->Release (); - netparent->Release (); - goto out; - } - + netitem_enum->Reset (); /* Don't look at me! Network discovery is very unreliable and the list of machines @@ -244,9 +228,9 @@ out: } static DWORD -create_thread_and_wait (DIR *dir, bool test_only) +create_thread_and_wait (DIR *dir) { - netdriveinf ndi = { dir, 0, test_only, + netdriveinf ndi = { dir, 0, CreateSemaphore (&sec_none_nih, 0, 2, NULL) }; cygthread *thr = new cygthread (thread_netdrive, &ndi, "netdrive"); @@ -262,9 +246,22 @@ fhandler_netdrive::exists () if (strlen (get_name ()) == 2) return virt_rootdir; - DIR dir = { 0 }; - dir.__d_dirname = (char *) get_name (); - int ret = create_thread_and_wait (&dir, true); + wchar_t name[MAX_PATH]; + struct addrinfoW *ai; + INT ret; + + /* Hopefully we are allowed to assume an IP network with existing name + resolution these days. Therefore, just try to resolve the name + into IP addresses. This may take up to about 3 secs if the name + doesn't exist, or about 8 secs if DNS is unavailable. + + Don't ask for "tsclient", it doesn't resolve. Just assume it exists. */ + if (!strcmp (get_name () + 2, "tsclient")) + return virt_directory; + sys_mbstowcs (name, CYG_MAX_PATH, get_name ()); + ret = GetAddrInfoW (name + 2, NULL, NULL, &ai); + if (!ret) + FreeAddrInfoW (ai); return ret ? virt_none : virt_directory; } @@ -295,7 +292,7 @@ fhandler_netdrive::opendir (int fd) int ret; dir = fhandler_virtual::opendir (fd); - if (dir && (ret = create_thread_and_wait (dir, false))) + if (dir && (ret = create_thread_and_wait (dir))) { free (dir->__d_dirname); free (dir->__d_dirent); |