[Dovecot] LTMP Proxy fails when backend server connection refused
Version: 2.1.9
Connecting directly to the proxy server on the LMTP port, issue lhlo, mail from, rcpt to, data. After the . closing of data, it just hangs there. The logs on the proxy server show:
Sep 27 19:55:12 proxy1 dovecot: lmtp(9398): Connect from 69.8.2.71 Sep 27 19:55:24 proxy1 dovecot: lmtp(9398): Error: lmtp client: connect(lmtp, 7025) failed: Connection refused
root 9398 1102 0 19:53 ? 00:00:00 dovecot/lmtp
The proxy server is hard coded (not director in this case). I purposefully shut it down to see how the system would handle failures. Unfortunately, it appears that the process just hangs there. For fun, I tried a separate protocol lmtp option in the config to try proxy_timeout. It made no difference. Missing some error handling?
protocol lmtp { passdb { driver = static args = proxy=y host=%s nopassword=y proxy_timeout=120 } }
Jack
On 9/27/2012 3:30 PM, Jack Bates wrote:
Version: 2.1.9
Connecting directly to the proxy server on the LMTP port, issue lhlo, mail from, rcpt to, data. After the . closing of data, it just hangs there. The logs on the proxy server show:
Looking at dovecot's proxy code.
Calls to connect_connect_ip do not return an error when the server isn't there. This may be expected, but it is what determines failure/OK in the LMTP code. The log entry is performed by lmtp_client_wait_connect callback.
In the standard client-common-auth.c code, the error returned for a failure is
- syslog error is reported by proxy_wait_connect() callback
- error to client is returned by an error in proxy_input()
In the lmtp code, we issue a "250 2.1.5 OK". Right after, the lmtp_client_wait_connect() callback is called and issues the connection refused error. However, we've already approved the rcpt.
I am not sure which method we really want in the lmtp proxy. Should it be failing at the initial rcpt command or after the data command. Currently, though I haven't checked yet, we don't appear to be detecting the input failure and handling the data command correctly since we've already allowed the rcpt to proceed without a backend proxy available.
Jack
On 9/28/2012 11:37 AM, Jack Bates wrote:
Version: 2.1.9
Connecting directly to the proxy server on the LMTP port, issue lhlo, mail from, rcpt to, data. After the . closing of data, it just hangs there. The logs on the proxy server show: I am not sure which method we really want in the lmtp proxy. Should it be failing at the initial rcpt command or after the data command. Currently, though I haven't checked yet, we don't appear to be detecting the input failure and handling the data command correctly since we've already allowed the rcpt to proceed without a backend
On 9/27/2012 3:30 PM, Jack Bates wrote: proxy available.
Further testing shows that the connection fails are normally handled after the DATA block. It works perfectly if you only fail one recipient. If all recipients are failed, the code locks up instead of telling the client that they are all failed.
Now to find out where between lmtp_client_fail() and some other part of the code, we aren't treating it right. :(
Jack
On 9/28/2012 12:44 PM, Jack Bates wrote:
On 9/28/2012 11:37 AM, Jack Bates wrote:
On 9/27/2012 3:30 PM, Jack Bates wrote:
Version: 2.1.9
Connecting directly to the proxy server on the LMTP port, issue lhlo, mail from, rcpt to, data. After the . closing of data, it just hangs there. The logs on the proxy server show:
Further testing shows that the connection fails are normally handled after the DATA block. It works perfectly if you only fail one recipient. If all recipients are failed, the code locks up instead of telling the client that they are all failed.
Now to find out where between lmtp_client_fail() and some other part of the code, we aren't treating it right. :(
It appears that the callbacks for the proxy connections are handled in the ioloop stuff. If you have at least one valid proxy session open, then proxy_try_finish will get called and all the replies are sent. The problem appears to be if all backend proxy sessions are bad (ie single recipient, proxy server down), there is nothing for ioloop to callback to. proxy_try_finish will never get called, and we end up locking up at epoll_wait as there are no events for us to process.
Code needs to be written to handle the special case of us not having any proxy callbacks as they are all bad.
Jack
On 9/28/2012 3:12 PM, Jack Bates wrote:
Code needs to be written to handle the special case of us not having any proxy callbacks as they are all bad.
Timo, please check and approve. This was diff'd on 2.1.10 on my test server (2.1.9 and 2.1.10 at least had this callback issue).
*** lmtp-proxy.c-orig 2012-09-28 20:17:36.138916678 +0000 --- lmtp-proxy.c 2012-09-28 20:18:12.241940780 +0000
*** 300,303 **** --- 300,304 ---- lmtp_client_send(conn->client, conn->data_input); lmtp_client_send_more(conn->client); }
}lmtp_proxy_try_finish(proxy);
ie, call lmtp_proxy_try_finish once. If all is bad, this will wrap us up. If we have valid proxies, it'll probably not finish and we'll return to waiting on callbacks. I'm not sure of any blocking restrictions. I just know it works.
mail from:<joe> 250 2.1.0 OK rcpt to:<JOE> 250 2.1.5 OK data 354 OK
test . 451 4.4.0 Remote server not answering (connect) mail from:<joe> 250 2.1.0 OK rcpt to:<joe> 250 2.1.5 OK rcpt to:<test> 250 2.1.5 OK data 354 OK
test . 451 4.4.0 Remote server not answering (connect) 250 2.0.0 <test> CYKfHcsHZlBcCAAALhEySA Saved
mail from:<joe> 250 2.1.0 OK rcpt to:<test> 250 2.1.5 OK data 354 OK
test . 250 2.0.0 <test> EYKfHcsHZlBcCAAALhEySA Saved
Jack
On 28.9.2012, at 23.29, Jack Bates wrote:
On 9/28/2012 3:12 PM, Jack Bates wrote:
Code needs to be written to handle the special case of us not having any proxy callbacks as they are all bad.
Timo, please check and approve. This was diff'd on 2.1.10 on my test server (2.1.9 and 2.1.10 at least had this callback issue).
*** lmtp-proxy.c-orig 2012-09-28 20:17:36.138916678 +0000 --- lmtp-proxy.c 2012-09-28 20:18:12.241940780 +0000
*** 300,303 **** --- 300,304 ---- lmtp_client_send(conn->client, conn->data_input); lmtp_client_send_more(conn->client); }
}lmtp_proxy_try_finish(proxy);
Looks ok. Added: http://hg.dovecot.org/dovecot-2.1/rev/38727d3e90ec
participants (2)
-
Jack Bates
-
Timo Sirainen