* 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.