From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id B88FD3858D28; Fri, 22 Mar 2024 14:34:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B88FD3858D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1711118098; bh=J0XBl3Pj334ma4lAB//OXXu3EXgR97Wyw6i71eEY9ow=; h=From:To:Subject:Date:From; b=LxeFhLkZ1RsGsOeMvD5z6sdzkb7+LQsy6P8PEGK1L8VyEVUfh5faZD/Fe+lFT8hvX zHw//h5TJgorGv9z4tjJj0oDuNgbKOkqDk10muNfIVn6edGb+p7N2cTERHfJ9SqaPh mwT9luh+3wzhbK9ZZBiGEg+4Gh6UFjWdaspKwTsY= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/main] Cygwin: //server: check existence of server with getaddrinfo X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/main X-Git-Oldrev: 290843bbdab6853fff6ba4105c8faac43c621430 X-Git-Newrev: 8d2c1b4ce68608251860bc9a7c5b6f5762110dd1 Message-Id: <20240322143458.B88FD3858D28@sourceware.org> Date: Fri, 22 Mar 2024 14:34:58 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D8d2c1b4ce68= 608251860bc9a7c5b6f5762110dd1 commit 8d2c1b4ce68608251860bc9a7c5b6f5762110dd1 Author: Corinna Vinschen AuthorDate: Fri Mar 22 15:34:29 2024 +0100 Commit: Corinna Vinschen CommitDate: Fri Mar 22 15:34:29 2024 +0100 Cygwin: //server: check existence of server with getaddrinfo =20 Checking server existence by trying to enumerate its shares may result in 2 minutes delay until some internal timeout is hit. =20 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. =20 Signed-off-by: Corinna Vinschen 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/ne= tdrive.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" =20 +#define USE_SYS_TYPES_FD_SET #include #include #include +#include =20 #include #include @@ -94,23 +96,14 @@ struct netdriveinf { DIR *dir; int err; - bool test_only; HANDLE sem; }; =20 static inline int -hresult_to_errno (HRESULT wres, bool test_only =3D 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 =3D=3D E_NOTIMPL || wres =3D=3D E_ACCESSDENIED)) - return 0; if (((ULONG) wres & 0xffff0000) =3D=3D (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; } =20 - if (len =3D=3D 2 || ndi->test_only) + if (len =3D=3D 2) { - wres =3D netitem_enum->Reset (); - - if (FAILED (wres) || ndi->test_only) - { - ndi->err =3D hresult_to_errno (wres, ndi->test_only); - netitem_enum->Release (); - netparent->Release (); - goto out; - } - + netitem_enum->Reset (); /* Don't look at me! =20 Network discovery is very unreliable and the list of machines @@ -244,9 +228,9 @@ out: } =20 static DWORD -create_thread_and_wait (DIR *dir, bool test_only) +create_thread_and_wait (DIR *dir) { - netdriveinf ndi =3D { dir, 0, test_only, + netdriveinf ndi =3D { dir, 0, CreateSemaphore (&sec_none_nih, 0, 2, NULL) }; =20 cygthread *thr =3D new cygthread (thread_netdrive, &ndi, "netdrive"); @@ -262,9 +246,22 @@ fhandler_netdrive::exists () if (strlen (get_name ()) =3D=3D 2) return virt_rootdir; =20 - DIR dir =3D { 0 }; - dir.__d_dirname =3D (char *) get_name (); - int ret =3D 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 =3D GetAddrInfoW (name + 2, NULL, NULL, &ai); + if (!ret) + FreeAddrInfoW (ai); =20 return ret ? virt_none : virt_directory; } @@ -295,7 +292,7 @@ fhandler_netdrive::opendir (int fd) int ret; =20 dir =3D fhandler_virtual::opendir (fd); - if (dir && (ret =3D create_thread_and_wait (dir, false))) + if (dir && (ret =3D create_thread_and_wait (dir))) { free (dir->__d_dirname); free (dir->__d_dirent);