Closed Bug 208287 Opened 21 years ago Closed 14 years ago

PAC: IsInNet can cause lengthy UI hangs

Categories

(Core :: Networking, defect)

defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: maartengeurts, Unassigned)

References

()

Details

Attachments

(1 file)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030529
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030529

typing a wrong url i.e. http:/a/garbarge.com freezes browser

Reproducible: Always

Steps to Reproduce:
1. In the proxy preferences i set the automatic proxy configuration script.
2. In the adress bar i type an invalid http: request, or an invalid site that
does not have hte http:// prefix.


Actual Results:  
complete mozilla browser freeze. 

Expected Results:  
No freeze, let other tabs/browser windows continue what they were doing. just
freeze the windows with the wrong "look like an url but not exactlty."

or give some kind of error.

Note 1: This bug was was visible to me in 1.4b since this was the first version
where NTLM support is available.

Note: internet explorer (6) behaves the same, but it times out after some time
(hmm...)

Note: if i do not use the automatic proxy configuration, but type in the url of
the current proxy in ip format (144.a.b.c)  it gives an correct error message.
(This could be a problem in the scripting engine under automatic configuration ?)
Attached the automatic configuration script.
yikes. that is one bloated PAC file.

I would guess that you are dying in the javascript execution.

What exactly are you typing. For example, a hostname that does not exist
(nonexist.mozilla.org)?

Darin: is there a better way of isolating this?
Component: Networking: HTTP → Networking
QA Contact: httpqa → pacqa
Summary: automatic proxy configuration can cause freeze → PAC: can cause freeze
If i type :
http://a
evertything goes ok. (it says correctly host not found)
if i type 
a
evertything goes ok. (it says correctly host not found)
if i type 
a. 
The browser freezes. 
Note that i removed the "automatically add "www" and ".com" setting. 


I did some testing with my pac script.If i modify the script and remove the
IsInnet() part in the start it works as expected: (Host a. not found in a popup)
So it freezes on isinNet. 

The bug stays: the PAC script should not freeze the entire browser, only the
current connections.

Later i found out this bug is NOT ALWAYS reproducable. It has to do with
something in out network that resolves (??DNS queries??) slowly. When i files
this bug it was always reproducable. Later (with the same mozilla installation)
mozilla only frooze for half a second. 
yeah, the problem is that IsInNet function needs to synchronously resolve the
given hostname, so Mozilla ends up locking up the main thread (the thread which
handles browser UI) until the DNS query completes.  Since DNS queries can have
relatively large timeouts (on the order of a minute), this can make the user
think the browser has completely locked up.  Unfortunately, there is little we
can do about this problem, with the exception that it would be nice if
synchronous DNS queries could be canceled by the user.  We could put up a modal
dialog with some sort of status message and a cancel button (if the DNS query
was taking more than X seconds).  Such UI work isn't going to happen for
sometime unfortunately.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: PAC: can cause freeze → PAC: IsInNet can cause lengthy UI hangs
Target Milestone: --- → Future
I don't know if we should do a lot to encourage the use of DNS-calling PAC
functions. Ari Luotonen, the designer of PAC, had said on occassion that he
wanted to end-of-life these functions because the failure conditions caused
excessive delays. Many PAC file writers do not understand DNS well enought to
understand the pitfalls. I saw one large bank call isResolvable() for every
request behind a internal-only DNS server. (If the hostname is not resolvable,
THEN go to the proxy server...)

Probably some better documentation on writing PAC files would be a more useful
solution.
hmm... i see your point, but since it is part of the PAC spec, and since it is
widely used, it would seem like a good idea to do whatever we can to make the
browser UI not hang.  i don't think it would be too much work to implement, but
i also don't think it is critical enough to get high priority either.  probably
this bug will just sit around for a while until someone has time to implement
it.  as for the documentation approach, that should still happen.  but, getting
information out to everyone is not exactly trivial either.
Duplicate of bug 174733 
DNS: hangs on lookups and at various stages of making tcp connections
This bug shouldn't just be considered a straight duplicate of bug 174733.  It is
true that both bugs stem from the same problem: very poor single-threaded DNS
design, locking up the entire browser during a DNS query.  As others have
pointed out, this is hopefully being rewritten for 1.6.

I believe that this bug should remain open to address the PAC issue.  If this
issue magically goes away when DNS is fixed in 1.6, that will be great, but this
bug should stay open until then.
Suggest Keywords: hang nsenterprise verified1.5 verified1.6 clean-report

This happens on dnsDomainIs calls as well. Even simple calls such as:
  dnsDomainIs(host, ".domain.local")
will cause the UI to freeeze for several seconds.  Source of the proxy.pac is
not an issue.

Test proxy.pac:
function FindProxyForURL(url, host)
{
  if (dnsDomainIs(host, ".domain.local"))
    return "DIRECT";
  else
    return "PROXY 127.0.0.1:8118; DIRECT";
}
Darin landed a re-write, effective in 1.6a, so 1.6 and later should perform
better in some regards.

There are still several ways bad PAC writting can slow down your system.
Keywords: clean-report
(In reply to comment #10)
> Darin landed a re-write, effective in 1.6a, so 1.6 and later should perform
> better in some regards.
> 
> There are still several ways bad PAC writting can slow down your system.

This still happens with 1.6 and 1.7b:  use of dnsDomainIs results in complete UI
freeze of 5-10 seconds (non updating windows and background, no response from
mozilla task).  So whatever Darin changed, it unfortunatly did not affect this.  

System test done on WinXP, 2,8 GHz, 512 MB no other apps running.  Tested with
Mozilla 1.6 and 1.7b as well as Firebird 0.8.  Removal ov dnsDomainIs(host,
".domain.local") in the "if" call removed the UI freeze problem.
Duncan:

Thinking about this further, PAC probably cannot send more than one DNS query at
a time (based on the nature of the script activity). The improvement from the
re-write might have been minimal.

However, I think this bug has started to drift. dnsDomainIs() should not cause
the types of delays that isInNet() would, dnsDomainIs() does some string
comparisons. I've started running my mozilla sessions w/ PAC files for
diagnostic testing, and I have not seen delays as you have described. If this
persists in a 1.7b or later build, lets open a new bug.
*** Bug 207652 has been marked as a duplicate of this bug. ***
Finally I've tracked down the same problem on my Linux box here. I'm using
Mozilla, Galeon and Epiphany, all suffer the same long delay. IT is quite good
demonstratable on EBay when loading large list of offered articles.

As soon as I remove the isInNet() call from the PAC everything works fine again.
With that call the UI most times (! but not always) freezes for up to nearly 1
minute.

As described below, this seems to come from a synchronous DNS lookup. I can't
understand why waiting for a new page to come blocks the whole UI? At least
since tabbed browsing is available, I thought every page is loaded and displayed
by a seperate thread. And this should eliminate this problem. Even if DNS lookup
is synchronous.

Even if "using isInNet()" is not good practice and the warning for an DNS lookup
for every URL is in the documentation, "isInNet()" is a very handy function and
should not be removed or discouraged. For _every_ URL and every img tag a DNS
lookup is necessary (probably by the Proxy-Server). So it is no problem to do a
DNS lookup by the browser too. BTW: are the results from isInNet() cached somewhere?

The problem is here for Kernel 2.4 and 2.6. (BTW: I've enabled IPv6). I've
installed the mozilla-browser 1.6-5 Debian package (and others).
> I thought every page is loaded and displayed by a seperate thread

the layout code is not threadsafe.
*** Bug 248545 has been marked as a duplicate of this bug. ***
*** Bug 233366 has been marked as a duplicate of this bug. ***
*** Bug 267023 has been marked as a duplicate of this bug. ***
I find no trick in the script in attachment. 
See bug:240759 (maybe not the right bug cannot find it there were 2 versions of
the patch :(
It is a DNS cache problem.
I bet there is a famine problem in the fifo algorythm and then even host
resolution is affected that should be why proxies are affected too.
Should I ask for bug:240759 to be reopened or should i fill a new bug report.
I can just try and unbug bug:240759 's patch.
The problem has occured since bug: have been closed and is apparent because of
stability of 1.7 braunch and last trunk of mozilla suite
*** Bug 298310 has been marked as a duplicate of this bug. ***
A bit surprised that bug 298310 has been marked as a duplicate of this bug - at
least my report was about browser hangs independent of whether it was a valid
DNS address or not - only by using IP's seemed to "dodge" the problem. But hey,
you are the guys plowing the source :-). Just wanted to comment that, if this
action perhaps was an error.
> independent of whether it was a valid DNS address or not

to find out whether it's valid, a DNS request has to be made, no? and that is
what hangs the browser.
Depends on: 240759
Assignee: darin → nobody
QA Contact: pacqa → networking
Target Milestone: Future → ---
i had to work around this by adding all internal domains to the proxy.pac (boring, but works) and using regexp url checks for the situations where someone puts the IP directly (shExpMatch)
Can I bypass the problem by using a local DNS server on my PC??

Can I bypass the problem by using a local proxy (es. Privoxy) on my PC??
>Can I bypass the problem by using a local DNS server on my PC??

No, it blocks trying to find the DNS, and its the remote DNS server, authority for the zone/domain that you want that is taking longer to respond.
The local dns would cache more queries and so may solve later queries to the same zone/domain, but you will get this on the firsts DNS resquests for each new zone/domain

>Can I bypass the problem by using a local proxy (es. Privoxy) on my PC??

if you are using the IsInNet, no... the browser is waiting for the result of the DNS do know what the result of IsInNet, to know what proxy will use (even if in the end you will only use one)

the only workaround that i found is to remove the IsInNet and test for other things, like checking for isPlainHostName, checking the local domains, then check if the regexp of the url have my ip address range
all this tests are fast and dont use the DNS... this works but its a pain and might not even be possible for some requirements

the but here is the freeze of ALL browser, instead of just the page that is waiting for the DNS

ps: the OS should be set to ALL
yes, of course it hangs all windows/tabs. it's all the same thread.
OS: Windows 2000 → All
Hardware: PC → All
I did some timings using dnsResolve(), which seems to be what isInNet() calls if it's passed a host name rather than an IP address.

On my system, it takes almost exactly 15 seconds to give up trying to resolve a host name that doesn't exist (one where an nslookup on the Windows command line would say "DNS request timed out" rather than returning an IP address).  During this time, Ethereal/Wireshark shows 8 attempts to resolve that name.

Why would Firefox be re-trying the request?  If it gave up after the first attempt failed, the effect would be reduced substantially.

In the mean time, at least I've learned of the problems with isInNet, so I'll use a single call to dnsResolve() then pass the IP address result to each isInNet() test.
It looks like my proxy is really broken.  When I set timeout to 30 seconds in nslookup, it still times out without receiving any response from the server.

After running Wireshark a while longer, I do finally get a matching response from the DNS server, a "server failure" (SERVFAIL?) after about 90 seconds.

I think the "multiple attempts to resolve the name" are the TCP/IP stack resending the same packet, as the DNS Transaction ID stays the same for 5 packets, I can't see an ACK, and the timings are 0, 1, 2, 4, 8, which looks like TCP/IP exponential back-off.

It would be nice if Firefox handled this better, but it's clear where the real problem lies!
(In reply to comment #28)

> It would be nice if Firefox handled this better, but it's clear where the real
> problem lies!

Nope
Too many people reported the problem - that means Firefox expectations are wrong period

Interesting, I see this behavior at work all the time. Would be really nice to have a fix for this for 1.9.1.
Flags: wanted1.9.1?
Related to bug 235853.
Can someone please mark this a dup of bug 235853 as after checking it looks the same
Depends on: 235853
Blocks: 309582
With the new version of Firefox (Mozilla/5.0 (Windows;
U; Windows NT 5.1; fr; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1), it seems
there are no more freeze.

Anyone can confirm this?
No longer blocks: 309582
I agree, didn't see this problem for a while.
reporter appears to be gone, and two WFM.
=> WFM
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → WORKSFORME
Flags: wanted1.9.1?
The possible solution for people with this problem could be:


( SOURCE: http://www.websense.com/content/support/library/web/v76/pac_file_best_practices/PAC_best_pract.aspx )


dnsResolve()
Resolves hostnames to an IP address. This function can be used to reduce the number of DNS lookups.
Example:
var resolved_ip = dnsResolve(host);
if (isInNet(resolved_ip, "10.0.0.0", "255.0.0.0") ||
isInNet(resolved_ip, "172.16.0.0", "255.240.0.0") ||
isInNet(resolved_ip, "192.168.0.0", "255.255.0.0") ||
isInNet(resolved_ip, "127.0.0.0", "255.255.255.0"))
return "DIRECT"; 

CB.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: