Why Postfix always complain "unexpected EOF" with my own tcp_table program?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Why Postfix always complain "unexpected EOF" with my own tcp_table program?

Zhang Huangbin
Dear all,

I wrote a simple daemon service in Python, it's used in Postfix transport_maps like this:

transport_maps = tcp:127.0.0.1:1234

It always returns '200 my_transport\n' as described in Postfix manual page tcp_table(5), but Postfix always complains "unexpected EOF" like below:

Jul 27 22:51:53 d7 postfix/trivial-rewrite[4260]: warning: read TCP map reply from 127.0.0.1:1234: unexpected EOF (Success)

This Python daemon server uses 'asynchat' module, and return '200 my_transport\n' with 'async_chat.push()' method like this:

self.push('200 my_transport\n')

Any idea why Postfix always complain "unexpected EOF"?

Thanks for your time.
Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

John Fawcett-4
On 28/07/13 08:27, Zhang Huangbin wrote:

> Dear all,
>
> I wrote a simple daemon service in Python, it's used in Postfix transport_maps like this:
>
> transport_maps = tcp:127.0.0.1:1234
>
> It always returns '200 my_transport\n' as described in Postfix manual page tcp_table(5), but Postfix always complains "unexpected EOF" like below:
>
> Jul 27 22:51:53 d7 postfix/trivial-rewrite[4260]: warning: read TCP map reply from 127.0.0.1:1234: unexpected EOF (Success)
>
> This Python daemon server uses 'asynchat' module, and return '200 my_transport\n' with 'async_chat.push()' method like this:
>
> self.push('200 my_transport\n')
>
> Any idea why Postfix always complain "unexpected EOF"?
>
> Thanks for your time.
There may be something in your code that strips out \n before sending to
Postfix. Postfix gives this message
when the string it receives does not end in \n.

John

Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

Wietse Venema
In reply to this post by Zhang Huangbin
Zhang Huangbin:

> Dear all,
>
> I wrote a simple daemon service in Python, it's used in Postfix transport_maps like this:
>
> transport_maps = tcp:127.0.0.1:1234
>
> It always returns '200 my_transport\n' as described in Postfix manual page tcp_table(5), but Postfix always complains "unexpected EOF" like below:
>
> Jul 27 22:51:53 d7 postfix/trivial-rewrite[4260]: warning: read TCP map reply from 127.0.0.1:1234: unexpected EOF (Success)
>
> This Python daemon server uses 'asynchat' module, and return '200 my_transport\n' with 'async_chat.push()' method like this:
>
> self.push('200 my_transport\n')
>
> Any idea why Postfix always complain "unexpected EOF"?

1) Use a network sniffer to see what Python actually sends. You may
   assume that your program sends \n, but Postfix does not receive \n.

2) Unrelated to this bug: closing the connection after one request
   is inefficient.

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

Sam Flint


On Jul 28, 2013 7:25 AM, "Wietse Venema" <[hidden email]> wrote:
>
> Zhang Huangbin:
> > Dear all,
> >
> > I wrote a simple daemon service in Python, it's used in Postfix transport_maps like this:
> >
> > transport_maps = tcp:127.0.0.1:1234
> >
> > It always returns '200 my_transport\n' as described in Postfix manual page tcp_table(5), but Postfix always complains "unexpected EOF" like below:
> >
> > Jul 27 22:51:53 d7 postfix/trivial-rewrite[4260]: warning: read TCP map reply from 127.0.0.1:1234: unexpected EOF (Success)
> >
> > This Python daemon server uses 'asynchat' module, and return '200 my_transport\n' with 'async_chat.push()' method like this:
> >
> > self.push('200 my_transport\n')
> >
> > Any idea why Postfix always complain "unexpected EOF"?
>
> 1) Use a network sniffer to see what Python actually sends. You may
>    assume that your program sends \n, but Postfix does not receive \n.
>
> 2) Unrelated to this bug: closing the connection after one request
>    is inefficient.

But is it the fact that he closes the connection? Keep in mind that any time a network connection is closed it sends EOF.   Could it be that Postfix wants to keep a constant connection?

Sam

>         Wietse

Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

Zhang Huangbin
In reply to this post by Wietse Venema


On Sunday, July 28, 2013 at 8:24 PM, Wietse Venema wrote:

>
> 1) Use a network sniffer to see what Python actually sends. You may
> assume that your program sends \n, but Postfix does not receive \n.


Thanks Wietse, and John.
I think this is the root cause, will try a network sniffer later.
> 2) Unrelated to this bug: closing the connection after one request
> is inefficient.


My program closes the connection immediately.


Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

Wietse Venema
Zhang Huangbin:

> On Sunday, July 28, 2013 at 8:24 PM, Wietse Venema wrote:
>
> > 1) Use a network sniffer to see what Python actually sends. You may
> > assume that your program sends \n, but Postfix does not receive \n.
>
> Thanks Wietse, and John.
> I think this is the root cause, will try a network sniffer later.
> > 2) Unrelated to this bug: closing the connection after one request
> > is inefficient.
>
> My program closes the connection immediately.

Caution: it is not a good idea to close a connection immediately
after writing data to it.  Some TCP/IP implementations may discard
unsent data when a connection is closed.

In Postfix, I avoid "write-close" bugs by keeping a connection open
until the receiver closes it (with of course a time limit that
forces the connection to be closed when things take too long).

        Wietse
Reply | Threaded
Open this post in threaded view
|

Re: Why Postfix always complain "unexpected EOF" with my own tcp_table program?

King Cao
You can enable the debug mode of postfix smtp daemon (http://www.postfix.org/DEBUG_README.html). Then you can see the request and response which postfix talked with your tcp_table script.

PS:
  From the postfix source code, it seems postfix has not received any response from your tcp_table.  However postfix will retry 10 times for such scenario (sleep 1 sec before each retry).


2013/7/28 Wietse Venema <[hidden email]>
Zhang Huangbin:
> On Sunday, July 28, 2013 at 8:24 PM, Wietse Venema wrote:
>
> > 1) Use a network sniffer to see what Python actually sends. You may
> > assume that your program sends \n, but Postfix does not receive \n.
>
> Thanks Wietse, and John.
> I think this is the root cause, will try a network sniffer later.
> > 2) Unrelated to this bug: closing the connection after one request
> > is inefficient.
>
> My program closes the connection immediately.

Caution: it is not a good idea to close a connection immediately
after writing data to it.  Some TCP/IP implementations may discard
unsent data when a connection is closed.

In Postfix, I avoid "write-close" bugs by keeping a connection open
until the receiver closes it (with of course a time limit that
forces the connection to be closed when things take too long).

        Wietse