Re: [exim] Rate Limit Message Relaying

Top Page
Delete this message
Reply to this message
Author: Kirill Miazine
Date:  
To: exim-users
Subject: Re: [exim] Rate Limit Message Relaying
* Kirill Miazine [2004-12-19 18:12]:
> > >Write a daemon (in a language you feel comfortable with) that implements
> > >the logic you are describing. Exim can communicate with that daemon
> > >using ${readsocket}.
> > >
> > I have no idea how to do that - but it would be nice to have.
>
> I don't want to someone that answers with bare suggestions, so I provide
> a simple solution as well. Perl is my prefered language and POE is a
> great framework, so my solution is using POE.


If you are more comfortable with Python, here comes an example in Python
(using Twisted):

=== start ===
#!/local/bin/python

import os
import time

from twisted.internet import reactor
from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineOnlyReceiver

stats = {}
class RelayLimit(LineOnlyReceiver):
    delimiter = '\n'
    def lineReceived(self, line):
        host = line.strip()
        now = int(time.time())
        global stats
        # new or expired, reset counter and allow
        if not stats.has_key(host) or stats[host][0] + 3600 < now:
            stats[host] = [now, 1]
            self.sendLine('no')
        # limit reached, just deny
        elif stats[host][1] > 99:
            self.sendLine('yes')
        # limit not reached, increment counter and allow
        else:
            stats[host][1] += 1
            self.sendLine('no')
        self.transport.loseConnection()


try:
    os.unlink('/tmp/relay.sock')
except OSError:
    pass


rl = Factory()
rl.protocol = RelayLimit
reactor.listenUNIX('/tmp/relay.sock', rl, 10)

reactor.run()
=== end ===

Bye
Kirill

--
Drive defensively. Buy a tank.