Closed Bug 104138 Opened 24 years ago Closed 24 years ago

Mozilla leaves TCP sockets in CLOSE_WAIT/FIN_WAIT_2 forever

Categories

(Core :: Networking, defect)

x86
Linux
defect
Not set
critical

Tracking

()

RESOLVED DUPLICATE of bug 97833

People

(Reporter: ralston, Assigned: neeti)

References

()

Details

From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010917 BuildID: 2001091712 If Mozilla is using the HTTP keep-alive option, the remote server will hold its TCP connection open after Mozilla has finished downloading. This is correct behavior. After Mozilla has loaded the page, unless the user goes to a new location, Mozilla will not make any further requests to the server. After a timeout period (20 to 30 seconds, usually), the server will close its end of the TCP socket. This is correct behavior. When the server closes its end of the TCP socket, the following actions take place: 1. The server OS sends a FIN packet to the client, and moves its socket to the FIN_WAIT_1 state. 2. The client OS receives the FIN packet. It replies with an ACK packet, and moves its socket to the CLOSE_WAIT state. 3. The server OS receives the ACK packet from the client, and moves its socket to the FIN_WAIT_2 state. Now, the steps that SHOULD happen next, but DO NOT HAPPEN, are: 4. Mozilla realizes that there is new data waiting to be read from its socket to the server. It reads from the socket, receives EOF, and realizes that the server closed the socket. Therefore, Mozilla closes its end of the socket. 5. The client OS, upon processing the close, sends a FIN packet to the server and moves its socket to the LAST_ACK state. 6. The server OS receives the FIN packet from the client, replies with an ACK packet, moves its socket to the TIME_WAIT state, waits for 2*MSL, and then moves its socket to the CLOSED state and tears down its TCB. 7. The client OS receives the ACK packet from the server, moves its socket to the CLOSED state, and tears down its TCB. But steps 4 through 7 never happen, because Mozilla isn't paying any attention to its socket to the server. Quitting Mozilla will cause it to close its end of the socket, and I think that browsing to other sites will eventually cause Mozilla to close its socket, but without any intervention, Mozilla will never close its end of the socket. On the server, the socket sits in FIT_WAIT_2 forever; on the client, the socket sits in CLOSE_WAIT forever. This acts as a denial-of-service attack on web servers. If Mozilla is sitting on keep-alive connections to servers, it MUST detect when the servers close their ends of the sockets, and MUST close its end of the sockets IMMEDIATELY. To do otherwise is to violate RFC793. Waiting until the user quits or browses to a different site before checking to see if any of Mozilla's sockets need to be closed is not acceptable. Reproducible: Always Steps to Reproduce: Go to any web page on any server that supports http keep-alive requests. Netscape (all versions, to my knowledge) also suffers from this bug. I *think* (but am not certain) that some Mozilla builds did not have the bug, but 0.9.4 (build ID 2001091712) clearly does.
Reporter: Can you retest this with a more recent build ? (bug 94811 is fixed...)
This is still broken as of build 2001101008. Bug 94811 fixes the problem that Mozilla wasn't cleaning up CLOSE_WAIT sockets at all; now, Mozilla cleans up CLOSE_WAIT sockets whenever new sockets are opened. The problem is, that's not good enough. Mozilla must detect when sockets move to the CLOSE_WAIT state and clean them up as soon as that happens. Otherwise, a user is tying up resources on the server simply by not leaving the current page. If you have a lot of idling clients, then this turns into a denial-of-service attack (albeit an intentional one) on the server. As Tomi Leppikangas remarked in bug 94811 on 2001-08-22 14:13, Mozilla needs some sort of time-based (or event-based) cleanup routine. E.g.: a time-based solution would be to poll() all sockets (e.g., once per second). I dunno enough about the guts of Mozilla to know if an event-based cleanup routine would be possible--you'd need something equivalent to performing a poll() (or equivalent) on every single socket/descriptor, plus all X events. I suspect not...
Errr, that should read "albeit an UNintentional one", not "albeit an intentional one". Duh.
*** This bug has been marked as a duplicate of 97833 ***
Status: UNCONFIRMED → RESOLVED
Closed: 24 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.