After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 317431 - xmlNanoHTTPConnectHost() may block for a long time on Windows 98
xmlNanoHTTPConnectHost() may block for a long time on Windows 98
Status: RESOLVED FIXED
Product: libxml2
Classification: Platform
Component: general
2.6.22
Other All
: Normal normal
: ---
Assigned To: Daniel Veillard
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2005-09-28 13:23 UTC by Kolja Nowak
Modified: 2005-10-17 10:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Use getaddrinfo() also when SUPPORT_IP6 is *NOT* defined (3.56 KB, patch)
2005-09-28 13:24 UTC, Kolja Nowak
needs-work Details | Review
Use only getaddrinfo() when HAVE_GETADDRINFO and _WIN32 are defined (3.56 KB, patch)
2005-09-30 09:33 UTC, Kolja Nowak
none Details | Review
Use getaddrinfo() only when compiling for Windows using MSVC with recent Platform SDK (3.73 KB, patch)
2005-10-12 11:46 UTC, Kolja Nowak
committed Details | Review

Description Kolja Nowak 2005-09-28 13:23:07 UTC
If xmlNanoHTTPConnectHost() is called with a numeric IP address as host name and
no DNS is available, it blocks for a long time on Windows 98 First Edition.

This is caused by the gethostbyname() function. On current versions of Windows,
this function skips the DNS lookup for numeric IP addresses. But on Windows 98
First Edition the function blocks until the DNS lookup has failed.

An easy sollution would be to replace gethostbyname() with getaddrinfo(), which
is available on Windows 98 First Edition and which behaves well in the
illustrated case.

The function xmlNanoHTTPConnectHost() currently contains code to use
getaddrinfo() instead of gethostbyname(), but this code is only compiled if
HAVE_GETADDRINFO and SUPPORT_IP6 are both defined.

In my patch below, I have rearranged the code to allow getaddrinfo() to be used
also when SUPPORT_IP6 is not defined.

Additionaly, I have changed wsockcompat.h to include a required header and to
define HAVE_GETADDRINFO on Windows.
Comment 1 Kolja Nowak 2005-09-28 13:24:02 UTC
Created attachment 52774 [details] [review]
Use getaddrinfo() also when SUPPORT_IP6 is *NOT* defined
Comment 2 Daniel Veillard 2005-09-28 13:54:40 UTC
I dislike the fact that the patch changes the working code on the other
OSes. At this point I would rather get a patch that is limited to 
that version of windows. I don't know how to check for just that platform
though.
  getaddrinfo seems to be POSIX  1003.1-2003, i.e. recent
while gethostbyname is BSD 4.3 and has been around forever. I don't want
to raise portability issue just because one version of Windows 98 has a
bug in its implementation of gethostbyname().

Daniel 
Comment 3 Kolja Nowak 2005-09-29 09:33:29 UTC
Hi Daniel,

thanks for your fast reply. About the portability issues:

I've tested getaddrinfo() on all Windows platforms starting from Windows 95 (95,
98FE, 98SE, ME, 2000, XP), and I can run specific tests on those platforms if
you want me to. Additionaly, Mircrosoft urges developers to use getaddrinfo()
instead of gethostbyname(), as stated here:

http://msdn.microsoft.com/library/en-us/winsock/winsock/gethostbyname_2.asp

From my experience with such recomondations I would say, on Windows platforms
you will be much better off switching to the new function, because Microsoft
doesn't care anymore about problems with the old function.

What about using getaddrinfo() only on Windows platforms (or when SUPPORT_IP6 is
defined, like before)?
Comment 4 Daniel Veillard 2005-09-29 09:44:18 UTC
> What about using getaddrinfo() only on Windows platforms (or when SUPPORT_IP6 is
> defined, like before)?

  Sounds fine, I think the __WIN__ (or __WIN32__) macro can be used as tests
then for the patch like in other parts of the libxml2 code.

Daniel
Comment 5 Kolja Nowak 2005-09-30 09:33:13 UTC
Created attachment 52849 [details] [review]
Use only getaddrinfo() when HAVE_GETADDRINFO and _WIN32 are defined
Comment 6 Kolja Nowak 2005-09-30 09:35:26 UTC
Hi Daniel,

here comes a new patch. Non-Windows-platforms still use exactly (*) the same
logic to decide whether to use gethostbyname() or getaddrinfo(), but if _WIN32
*and* HAVE_GETADDRINFO are defined, only getaddrinfo() will be used. Sadly, this
has required more #ifdef's than my first patch.

I've kept the dependency on HAVE_GETADDRINFO to make reverting to the old state
on Windows easy by removing the define from wsockcompat.h, for example if this
should be made a configure option.

(*) One thing my patch changes for Non-Windows-platforms:

If SUPPORT_IP6 is defined, but HAVE_GETADDRINFO is *not*, the following
(simplified) code was produced:

if (have_ip6 ()) {
  h = gethostbyname (...);
  for (... all entries in h ...) {
    if (h->h_addrtype == AF_INET)
      // try to connect
    else if(have_ip6 () && (h->h_addrtype == AF_INET6))
      // try to connect
  }
}

I think the outer if() clause is useless, because availability of AF_INET6
sockets is tested again at the point where the address family is checked. The
outer if() effectively breaks the entire function if libxml2 is compiled whith
SUPPORT_IP6 but is executed on a system without support for AF_INET6 sockets.

So I've assumed this was not intended and removed the outer if() in this special
case.
Comment 7 Rob Richards 2005-10-07 02:47:25 UTC
This isnt going to work unless building with VC7 or above as getaddrinfo is not
defined in ws2tcpip.h for VC6 (which also no longer supported is what many of us
out there still use - and new Platform SDKs no longer will work with it). Looks
like some other projects out there have custom addrinfo.h headers for this, but
unless this is something that's going to be applied for other OSes, I dont think
it's worth it.
Comment 8 Kolja Nowak 2005-10-07 07:12:46 UTC
Oh, I didn't knew that VC6 does not have getaddrinfo().

What about an option in win32\configure.js to explicitly turn on HAVE_GETADDRINFO? 
Comment 9 Rob Richards 2005-10-07 11:20:36 UTC
That would be much better solution default disabled of course - (no idea about
mingw and borland addrinfo support).
Comment 10 Kolja Nowak 2005-10-12 11:46:53 UTC
Created attachment 53364 [details] [review]
Use getaddrinfo() only when compiling for Windows using MSVC with recent Platform SDK

I've asked Igor Zlatkovic about adding an option to win32\configure.js. He
dislikes this solution because he doesn't want to bloat configure.js with
options which are not relevant for all builds.

But I've thought it would be even smarter to auto-detect whether the Platform
SDK headers provide getaddrinfo():

#include <ws2tcpip.h>
#if defined(_MSC_VER) && defined(AI_PASSIVE) && \
    defined(AI_CANONNAME) && defined(AI_NUMERICHOST)
#define HAVE_GETADDRINFO
#endif

This solution only uses getaddrinfo() if the associated parameter flags are
defined (which indicates we are using a recent Platform SDK) and the Microsoft
C Compiler is used. I've tested this with VC6 and VC7.

What do you think about this solution?
Comment 11 Daniel Veillard 2005-10-12 13:33:25 UTC
Unless Rob objects it seems you should have nailed it down, though
I'm a bit surprized by how you try to detect this is a "recent" version ...

Daniel

Comment 12 Kolja Nowak 2005-10-12 13:54:36 UTC
Hi Daniel,

great! 

About detecting the "recent" version:

the "AI_*" defines are used to assemble a bitmask which controls behaviour of
getaddrinfo(). They are described in RFC2553 together with getaddrinfo() and its
associated parameter structures. 

I have assumed they will be defined always together with a prototype of
getaddrinfo() and associated parameter structures, otherwise getaddrinfo() would
be useless. The other way arround, they will never occur without getaddrinfo(),
because they are used only by this function.

Additionally, I have grep'ed trough recent and earlier versions of Windows
Platform SDK headers, to see if my assumptions where correct.

And to be completely on the safe side, I also check if we are compiling using
MSVC, because Bob said he has "no idea about mingw and borland support". (Maybe
this check could be ommited to let users of other compilers benefit from this
patch?)
Comment 13 Rob Richards 2005-10-13 14:20:03 UTC
Patch looks and works fine for me now. Checked the headers a bit more and it
looks like detection might be able to be simplified using:
#if defined(GetAddrInfo)
Comment 14 Kolja Nowak 2005-10-13 14:34:42 UTC
Hi Rob,

First, I had the same idea, because 
-> http://msdn.microsoft.com/library/en-us/winsock/winsock/getaddrinfo_2.asp
wrote: "Macros in the Winsock header file define the mixed-case function name
GetAddrInfo to getaddrinfo; either spelling is acceptable." 

But I can't find "GetAddrInfo" anywhere in my SDK headers. Also the following
test code
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #if defined(GetAddrInfo)
 #error GetAddrInfo is defined!
 #endif
does compile without error for me. 

I'm wondering about this, maybe Microsoft has introduced the mixed-case variant
in a very recent fixpack of VC7 which I haven't applied yet. Therefor I came up
with my test of "AI_*" flags.

Just out of curiosity, can you tell me in which header you have found "GetAddrInfo"?
Comment 15 Rob Richards 2005-10-13 14:46:42 UTC
in ws2tcpip.h - defined as GetAddrInfoW for unicode and GetAddrInfoA otherwise
Comment 16 Kolja Nowak 2005-10-13 15:02:31 UTC
I compared my headers with installations on the systems of my colleagues, they
have GetAddrInfo in ws2tcpip.h, I don't have. I have VC7.0.x, they have 7.1.x.

Personally, I have no problem with "#if defined(GetAddrInfo)", I will upgrade my
system anyway. But testing for "AI_*" may help users of VC7.0.x to benefit from
this patch.

I think you should decide what you prefer, I have no strong preference.

Comment 17 Rob Richards 2005-10-13 23:15:29 UTC
Fixed in CVS. Used GetAddrInfo as i'ts simpler and VC7.0.x can always use newer
Platform SDK to support this.
Comment 18 Kolja Nowak 2005-10-14 06:52:24 UTC
Great, thanks for your support.

Am I supposed to do anything further with this bug, for example testing and then
changing to CLOSED, or what is the usual way to deal with this?
Comment 19 Daniel Veillard 2005-10-14 13:42:13 UTC
I usually CLOSE bug which are FIXED when doing a new release.
However if you could try the CVS version (or the CVS snapshot)
to confirm that would be great :-)

Daniel
Comment 20 Kolja Nowak 2005-10-17 10:41:59 UTC
I've tested a snapshot from 2005-10-14 and it works fine.