public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] Cygwin: //server: check existence of server with getaddrinfo Date: Fri, 22 Mar 2024 14:34:58 +0000 (GMT) [thread overview] Message-ID: <20240322143458.B88FD3858D28@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=8d2c1b4ce68608251860bc9a7c5b6f5762110dd1 commit 8d2c1b4ce68608251860bc9a7c5b6f5762110dd1 Author: Corinna Vinschen <corinna@vinschen.de> AuthorDate: Fri Mar 22 15:34:29 2024 +0100 Commit: Corinna Vinschen <corinna@vinschen.de> CommitDate: Fri Mar 22 15:34:29 2024 +0100 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> Diff: --- winsup/cygwin/fhandler/netdrive.cc | 51 ++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/winsup/cygwin/fhandler/netdrive.cc b/winsup/cygwin/fhandler/netdrive.cc index 4f080efb0e1a..1eff8166a739 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);
reply other threads:[~2024-03-22 14:34 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240322143458.B88FD3858D28@sourceware.org \ --to=corinna@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).