Modify

Opened 7 years ago

Closed 5 years ago

Last modified 4 years ago

#7742 closed defect (obsolete)

uhttpd doesn't seem to take any action on network timeout nor closed socket

Reported by: ddiaz@… Owned by: developers
Priority: normal Milestone: Chaos Calmer 15.05
Component: base system Version: Backfire 10.03
Keywords: uhttpd network timeout Cc:

Description

Problem Description

It seems that uhttpd hangs forever under some circumstances. I can easily reproduce the issue using IE 8 under Windows XP, but not under Windows 7 nor any other browser. This is on a custom application based on OpenWRT, where the web interface executes several CGIs using AJAX.

I tried to debug the issue adding some printfs to the uhttpd code. I also ran strace and wireshark. It seems that for some reason IE tries to close the socket in the middle of a transaction and uhttpd doesn't take any action. I can see that uhttpd recurrently goes through the select call in uh_tcp_send(), right after receiving a SIGPIPE. The select call returns 0 (timeout), then uh_tcp_send returns -1, but the calling code does nothing about it and continues trying to send output to the client. At the same time when receiving the SIGPIPE signal, I can see a RST packet on the Wireshark output.

The same combination of html/javascript/cgi works perfectly using busybox' htppd.

I'm attaching the strace and filtered wireshark outputs.

Attachments (4)

bug.pcap (5.1 KB) - added by ddiaz@… 7 years ago.
Wireshark output
strace.txt (81.3 KB) - added by ddiaz@… 7 years ago.
strace output
uhttpd-disconnect-handling.patch (2.7 KB) - added by jow 7 years ago.
Stricter return value handling
strace2.txt (2.1 KB) - added by ddiaz@… 7 years ago.
Strace output

Download all attachments as: .zip

Change History (20)

Changed 7 years ago by ddiaz@…

Wireshark output

Changed 7 years ago by ddiaz@…

strace output

comment:1 follow-up: Changed 7 years ago by jow

What version exactly?

comment:2 in reply to: ↑ 1 Changed 7 years ago by anonymous

Replying to jow:

What version exactly?

Version 9, SVN revision 21121

comment:3 follow-up: Changed 7 years ago by jow

Can you try rev 13 please? I'll prepare a patch to do more strict checking in uhttpd-file.c in the meanwhile. I just like to know whether the behaviour persists.

comment:4 in reply to: ↑ 3 Changed 7 years ago by ddiaz@…

Replying to jow:

Can you try rev 13 please? I'll prepare a patch to do more strict checking in uhttpd-file.c in the meanwhile. I just like to know whether the behaviour persists.

I have read the changelogs until rev 13, and it doesn't seem to be fixed, but I will try it anyway.

comment:5 Changed 7 years ago by ddiaz@…

I was able to reproduce the problem using version 13.

However, I did notice that the issue somehow seems to depend on the state of the PC I'm accessing the web page from, because at first I couldn't reproduce the issue again and I had to try on a second PC and it showed up inmediately.

Regards.

comment:6 follow-up: Changed 7 years ago by jow

  • Resolution set to fixed
  • Status changed from new to closed

I was able to trigger the descriped issue by using some specially crafted perl script that closed the socket connection prematurely (right after receiving the header).

I protected most send calls now so that the calling code drops out of the processing loop. Please try the changes added in r22602 and reopen this ticket if you still see issues.

comment:7 in reply to: ↑ 6 Changed 7 years ago by anonymous

  • Resolution fixed deleted
  • Status changed from closed to reopened

Thanks a lot for the quick fix.

It works, sort of. Now it is not hanging forever, but it is only dropping out of the processing loop after the network timeout occurs. It would be even better if the code would handle the socket closure inmediately. You already know that the socket is closed, so there is no reason to wait for the timeout to handle it. One possible way to do this without catching SIGPIPE is to add the network socket to the read set, and if it triggers the select and the read fails, then the socket is closed. But I don't know how you would handle actual data arriving from the client at that moment.

comment:8 Changed 7 years ago by jow

So its pausing in recv() now... or in select() ?

comment:9 Changed 7 years ago by anonymous

select()

comment:10 Changed 7 years ago by jow

I need an strace, cannot reproduce it here.

comment:11 Changed 7 years ago by jow

I noticed some gaps. If a disconnect occurs after the last header line got send, the loops is not aborted and the httpd will stall in select() right before sending the first chunk of body data.

Please try the attached patch. I'll try to do some more agressive tests tomorrow.

Changed 7 years ago by jow

Stricter return value handling

Changed 7 years ago by ddiaz@…

Strace output

comment:12 Changed 7 years ago by ddiaz@…

I applied the patch, but the issue persists.

I've attached a new strace output to show what's happening. It's still waiting for the network timeout to occur after the socket closes and a SIGPIPE is triggered. It should leave the processing loop inmediately at that moment, instead of waiting.

comment:13 Changed 7 years ago by jeromepoulin@…

Could those 2 be related? /ticket/7904.html

comment:14 Changed 6 years ago by Bastian Bittorf <bittorf@…>

we see the same issue. IMHO the server doesn't leave it's blocking state, if there are several concurrent connections. our workaround is to restart the server. we can reproduce it especially with newer macintosh's

comment:15 Changed 5 years ago by nbd

  • Resolution set to obsolete
  • Status changed from reopened to closed

comment:16 Changed 4 years ago by jow

  • Milestone changed from Backfire 10.03.2 to Chaos Calmer (trunk)

Milestone Backfire 10.03.2 deleted

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.