baudehlo/Haraka — pull request #152 by yogieric (2012-01-23 06:49:32+00:00)
Title: Fix clamd send_data infinite loop on linux

Before 9147e00b, clamd.js would cause haraka to give up due to exceeding
maximum stack depth. After it, haraka appears to infinite loop and somehow
get killed.

The problem is that socket.write's callback is not called immediately.
According to http://nodejs.org/docs/v0.4.9/api/net.html#socket.write, there
is no requirement that it is called immediately. Thus, what happens is
socket.write(len,...) returns true, but data_marker is not incremented and
send_data simply infinite loops.

Note that socket.write is apparently called immediately on my Lion OS X
system. It simply is not called immediately on my Debian squeeze 6.0.2
kernel 2.6.32-5 x86_64 system running node v0.6.8 installed from source.

Note that I modeled the send_data clamd.js on the one in smtp_proxy.js.
It does not use socket.write callbacks at all (& thus avoids any assumption
about whether they happen immediately or not).

----

Note: I added some logging to the current clamd.js to verify that socket.write was returning true but not calling its callback immediately -- the behavior difference on OS X versus linux & the fact that nobody has reported this problem was a bit hard to believe. The logging, however, bore out the problem. I logged once "send_data 1" at the top of the loop and once "send_data 2" at the bottom of the loop counting (cnt) the number of times "send_data 2" was called. Clearly the callback was not getting called because data_marker never got incremented. Works fine on OS X.

[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 1 data_marker: 0
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 2 cnt 1 data_marker: 0 wrote_all: true
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 1 data_marker: 0
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 2 cnt 2 data_marker: 0 wrote_all: true
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 1 data_marker: 0
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 2 cnt 3 data_marker: 0 wrote_all: true
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 1 data_marker: 0
[DEBUG] [F0DC651E-84EC-452D-AE07-F67CB529AB3B.1] [clamd] send_data 2 cnt 4 data_marker: 0 wrote_all: true