Compare commits

...

2 Commits

Author SHA1 Message Date
Piotr F. Mieszkowski 95069c06a7 Add config parameter to set DATA size limit
Expose a new parameter: [daemon]max_data_bytes, to limit Lacre's memory
usage and allow processing of messages larger than 32MB (which is the
default limit).
2022-10-29 20:35:21 +02:00
Piotr F. Mieszkowski 91969dbfbb Re-use the same Event Loop for each coroutine
Function asyncio.run creates a new event loop each time it's called and
executes coroutine in that new loop.  However, we want all our coroutines to
be executed from the same event loop, so we acquire a loop when lacre.daemon
starts and then use it to execute them later.

See: Disroot/gpg-lacre#109
2022-10-29 16:54:58 +02:00
3 changed files with 24 additions and 8 deletions

View File

@ -83,6 +83,11 @@ config = /etc/gpg-lacre-logging.conf
host = 127.0.0.1
port = 10025
# Maximum size (in bytes) of message body, i.e. data provided after DATA
# message. Following value comes from aiosmtpd module's default for this
# setting.
max_data_bytes = 33554432
[relay]
# the relay settings to use for Postfix
# gpg-mailgate will submit email to this relay after it is done processing

View File

@ -47,17 +47,22 @@ class MailEncryptionProxy:
except TypeError as te:
LOG.exception("Got exception while processing", exc_info=te)
return RESULT_ERROR
except:
LOG.exception('Unexpected exception caught, bouncing message')
return RESULT_ERROR
ellapsed = (time.process_time() - start) * 1000
LOG.info(f'Message delivered in {ellapsed:.2f} ms')
return RESULT_OK
def _init_controller(keys: kcache.KeyRing, tout: float = 5):
def _init_controller(keys: kcache.KeyRing, max_body_bytes=None, tout: float = 5):
proxy = MailEncryptionProxy(keys)
host, port = conf.daemon_params()
LOG.info(f"Initialising a mail Controller at {host}:{port}")
return Controller(proxy, hostname=host, port=port, ready_timeout=tout)
return Controller(proxy, hostname=host, port=port,
ready_timeout=tout,
data_size_limit=max_body_bytes)
def _init_reloader(keyring_dir: str, reloader) -> kcache.KeyringModificationListener:
@ -88,8 +93,12 @@ def _main():
_validate_config()
keyring_path = conf.get_item('gpg', 'keyhome')
keyring = kcache.KeyRing(keyring_path)
controller = _init_controller(keyring)
max_data_bytes = int(conf.get_item('daemon', 'max_data_bytes', 2**25))
loop = asyncio.get_event_loop()
keyring = kcache.KeyRing(keyring_path, loop)
controller = _init_controller(keyring, max_data_bytes)
reloader = _init_reloader(keyring_path, keyring)
LOG.info(f'Watching keyring directory {keyring_path}...')
@ -99,7 +108,7 @@ def _main():
controller.start()
try:
asyncio.run(_sleep())
loop.run_until_complete(_sleep())
except KeyboardInterrupt:
LOG.info("Finishing...")
except:

View File

@ -9,7 +9,7 @@ import lacre.config as conf
import logging
from os import stat
from watchdog.events import FileSystemEventHandler, FileSystemEvent
from asyncio import Semaphore, run
from asyncio import Semaphore, create_task, get_event_loop
import copy
import GnuPG
@ -73,12 +73,13 @@ class KeyRing:
fingerprint=>email maps.
"""
def __init__(self, path: str):
def __init__(self, path: str, loop=None):
"""Initialise the adapter."""
self._path = path
self._keys = self._load_and_sanitize()
self._sema = Semaphore()
self._last_mod = None
self._loop = loop or get_event_loop()
def _load_and_sanitize(self):
keys = self._load_keyring_from(self._path)
@ -96,7 +97,8 @@ class KeyRing:
def load(self):
"""Load keyring, replacing any previous contents of the cache."""
LOG.debug('Reloading keys...')
run(self._load())
tsk = create_task(self._load(), 'LoadTask')
self._loop.run_until_complete(tsk)
async def _load(self):
last_mod = self._read_mod_time()