Autor: Jack Bailey Data: Para: exim-users Assunto: Re: [exim] Exim gets constantly the same mail,
sent from our customer (gagabay)
Philip Hazel wrote: > On Mon, 2 Apr 2007, Jack Bailey wrote:
>
>
>> I took a look at this awhile back and it's possible to detect far end
>> disconnections by setting the socket to async IO. The idea is arrange
>> for Unix to send the process a signal when IO is pending on the socket,
>> but it also works for disconnects. It goes something like this:
>>
>> flag = 1;
>> ioctl(sockfd, FIOASYNC, &flag);
>> flag = getpid();
>> setpgid(0, 0);
>> ioctl(sockfd, SIOCSPGRP, &flag);
>>
>> I tested a hack similar to this with exim-4.66 on Solaris 10 and CentOS
>> 4.4. Works great.
>>
>
> I took a look at that, and indeed, it is a way of detecting "something
> has happened on this socket", where the something might be "it's gone
> away" or it might be "there's some input waiting to be read". I was
> wondering how to distinguish the two, when the lightbulb went on over
> my head...
>
> As this is happening at the point where Exim is about to issue a 250
> "OK, I've got your message" response, *both* those situations are
> errors. What should be the case is that the connection is still present,
> but there is no input waiting - the client should be waiting for the
> response.
>
> In fact, the two cases can be distinguished by trying to read the next
> character (and since an error is going to be generated and nothing more
> accepted on the socket, the character can be ignored).
>
> Then it struck me that there is no need to mess with signals. A simple
> call to select() can also detect this situation. I have therefore
> implemented code to do this (with some extra features for the "input
> sent too soon" case, because of buffering), and my tests seem to show
> that it works nicely, with and without TLS.
>
> For the "socket gone away" case, Exim just discards the message and logs
> the event. For the "input sent too soon" case, Exim sends a 550
> response, then discards the message and closes the socket.
Thanks for this. I am anxious to see how it affects inbound mail from
Hotmail/MSN, the source of most of the reports I get.
As a local_scan() user/implementer, I have two points of interest in
monitoring the connection: before local_scan() and during local_scan().
You obviously have before local_scan() covered. What about during? I
spent some time reading the code, and it appears the value of the socket
descriptor is unknown/unknowable from there. (As I'm writing this I'm
thinking about adding a for() loop to see if I can find it). Would it
be possible to write a local_scan() function that does the select()?
The test I just finished has local_scan() create a process that catches
SIGIO before running any of its filter code. When SIGIO arrives, the
process stops whatever it's doing and silently abandons the message.
The advantage to using signals is their asynchronous nature and that
they're a form of interprocess communication. I like the idea of
select(), but I don't see a good way to make it work here. I'm
certainly open to ideas.