public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin/main] Cygwin: //server: check existence of server with getaddrinfo
@ 2024-03-22 14:34 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2024-03-22 14:34 UTC (permalink / raw)
  To: cygwin-cvs

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-22 14:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-22 14:34 [newlib-cygwin/main] Cygwin: //server: check existence of server with getaddrinfo Corinna Vinschen

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).