commit b334fc80bdfd47b8e0099fda769b148e7fb00b14
parent 3dd1bce69f1e8a4c58e32f00ebef05ed8f852b1a
Author: Christoph Lohmann <20h@r-36.net>
Date: Mon, 17 Aug 2020 11:28:27 +0200
Only start bmf when there is content.
* Reduce resource usage by tenfold.
* Solve problem of bmf instances not killed when there was only helo.
Diffstat:
bmf-milter.c | | | 200 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
1 file changed, 126 insertions(+), 74 deletions(-)
diff --git a/bmf-milter.c b/bmf-milter.c
@@ -39,83 +39,32 @@ struct Priv {
#define MLFIPRIV ((struct Priv *) smfi_getpriv(ctx))
-sfsistat
-mlfi_cleanup(SMFICTX *ctx, int iseom)
-{
- struct Priv *priv = MLFIPRIV;
- int retcode = -1;
-
- if (dodebug)
- fprintf(stderr, "mlfi_cleanup\n");
-
- if (priv == NULL)
- return SMFIS_CONTINUE;
- if (dodebug)
- fprintf(stderr, "cleanup: closing execpipe[1]\n");
- close(priv->execpipe[1]);
- priv->execpipe[1] = -1;
- if (dodebug)
- fprintf(stderr, "cleanup: waitpid\n");
- waitpid(priv->execpid, &retcode, 0);
- if (dodebug)
- fprintf(stderr, "cleanup: retcode = %d\n", retcode);
-
- /*
- * smfi_addheader is only allowed in eom.
- */
- if (iseom) {
- if (retcode == 0) {
- if (smfi_addheader(ctx, "X-Spam-Flag",
- " YES") == MI_FAILURE) {
- if (dodebug)
- fprintf(stderr, "x-spam-flag failed\n");
- }
- }
- if (smfi_addheader(ctx, "X-BMF-Processed",
- " YES") == MI_FAILURE) {
- if (dodebug)
- fprintf(stderr, "x-bmf-processed failed\n");
- }
- }
-
- return SMFIS_CONTINUE;
-}
-
-sfsistat
-mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
-{
- if (dodebug)
- fprintf(stderr, "mlfi_connect(%s)\n", hostname);
-
- return SMFIS_CONTINUE;
-}
-
-sfsistat
-mlfi_helo(SMFICTX *ctx, char *helohost)
+int
+start_bmf(SMFICTX *ctx)
{
struct Priv *priv;
char *ident, *bmfargs[6];
int pid, nullfd, argp;
if (dodebug)
- fprintf(stderr, "mlfi_helo(%s)\n", helohost);
+ fprintf(stderr, "start_bmf()\n");
if (donothing) {
smfi_setpriv(ctx, NULL);
- return SMFIS_CONTINUE;
+ return 1;
}
- priv = malloc(sizeof *priv);
+ priv = malloc(sizeof(*priv));
if (priv == NULL)
- return SMFIS_CONTINUE;
- memset(priv, '\0', sizeof *priv);
+ return 1;
+ memset(priv, '\0', sizeof(*priv));
smfi_setpriv(ctx, priv);
if (pipe(priv->execpipe) < 0) {
free(priv);
smfi_setpriv(ctx, NULL);
- return SMFIS_CONTINUE;
+ return 1;
}
switch ((pid = fork())) {
@@ -160,11 +109,79 @@ mlfi_helo(SMFICTX *ctx, char *helohost)
smfi_setpriv(ctx, NULL);
break;
default:
+ if (dodebug)
+ fprintf(stderr, "start_bmf(pid = %d)\n", pid);
priv->execpid = pid;
close(priv->execpipe[0]);
break;
}
+ return 0;
+}
+
+sfsistat
+mlfi_cleanup(SMFICTX *ctx, int iseom)
+{
+ struct Priv *priv = MLFIPRIV;
+ int retcode = -1;
+
+ if (dodebug)
+ fprintf(stderr, "mlfi_cleanup(iseom = %d)\n", iseom);
+
+ if (priv == NULL)
+ return SMFIS_CONTINUE;
+ if (dodebug)
+ fprintf(stderr, "mlfi_cleanup(closing execpipe[1])\n");
+ close(priv->execpipe[1]);
+ priv->execpipe[1] = -1;
+ if (dodebug)
+ fprintf(stderr, "mlfi_cleanup(waitpid)\n");
+ waitpid(priv->execpid, &retcode, 0);
+ if (dodebug)
+ fprintf(stderr, "mlfi_cleanup(retcode = %d)\n", retcode);
+
+ /*
+ * smfi_addheader is only allowed in eom.
+ */
+ if (iseom) {
+ if (retcode == 0) {
+ if (smfi_addheader(ctx, "X-Spam-Flag",
+ " YES") == MI_FAILURE) {
+ if (dodebug) {
+ fprintf(stderr,
+ "mlfi_cleanup(x-spam-flag failed)\n");
+ }
+ }
+ }
+ if (smfi_addheader(ctx, "X-BMF-Processed",
+ " YES") == MI_FAILURE) {
+ if (dodebug) {
+ fprintf(stderr,
+ "mlfi_cleanup(x-bmf-processed failed)\n");
+ }
+ }
+ }
+
+ return SMFIS_CONTINUE;
+}
+
+sfsistat
+mlfi_connect(SMFICTX *ctx, char *hostname, _SOCK_ADDR *hostaddr)
+{
+ if (dodebug)
+ fprintf(stderr, "mlfi_connect(%s)\n", hostname);
+
+ return SMFIS_CONTINUE;
+}
+
+sfsistat
+mlfi_helo(SMFICTX *ctx, char *helohost)
+{
+ if (dodebug)
+ fprintf(stderr, "mlfi_helo(%s)\n", helohost);
+
+ smfi_setpriv(ctx, NULL);
+
return SMFIS_CONTINUE;
}
@@ -176,6 +193,11 @@ mlfi_envfrom(SMFICTX *ctx, char *argv[])
if (dodebug)
fprintf(stderr, "mlfi_envfrom(%s)\n", argv[0]);
+ if (priv == NULL) {
+ if (start_bmf(ctx))
+ return SMFIS_CONTINUE;
+ priv = MLFIPRIV;
+ }
dprintf(priv->execpipe[1], "From: %s\n", argv[0]);
return SMFIS_CONTINUE;
@@ -187,8 +209,13 @@ mlfi_envrcpt(SMFICTX *ctx, char *argv[])
struct Priv *priv = MLFIPRIV;
if (dodebug)
- fprintf(stderr, "mfli_envrcpt(%s)\n", argv[0]);
+ fprintf(stderr, "mlfi_envrcpt(%s)\n", argv[0]);
+ if (priv == NULL) {
+ if (start_bmf(ctx))
+ return SMFIS_CONTINUE;
+ priv = MLFIPRIV;
+ }
dprintf(priv->execpipe[1], "To: %s\n", argv[0]);
return SMFIS_CONTINUE;
@@ -202,7 +229,12 @@ mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
if (dodebug)
fprintf(stderr, "mlfi_header(%s = '%s')\n", headerf, headerv);
- dprintf(priv->execpipe[1], "%s: %s\n", headerf, headerv);
+ if (priv == NULL) {
+ if (start_bmf(ctx))
+ return SMFIS_CONTINUE;
+ priv = MLFIPRIV;
+ }
+ dprintf(priv->execpipe[1], "%s:%s\n", headerf, headerv);
return SMFIS_CONTINUE;
}
@@ -213,8 +245,13 @@ mlfi_eoh(SMFICTX *ctx)
struct Priv *priv = MLFIPRIV;
if (dodebug)
- fprintf(stderr, "mlfi_eoh\n");
+ fprintf(stderr, "mlfi_eoh()\n");
+ if (priv == NULL) {
+ if (start_bmf(ctx))
+ return SMFIS_CONTINUE;
+ priv = MLFIPRIV;
+ }
dprintf(priv->execpipe[1], "\r\n");
return SMFIS_CONTINUE;
@@ -229,6 +266,11 @@ mlfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t bodylen)
if (dodebug)
fprintf(stderr, "mlfi_body(%ld bytes)\n", bodylen);
+ if (priv == NULL) {
+ if (start_bmf(ctx))
+ return SMFIS_CONTINUE;
+ priv = MLFIPRIV;
+ }
for (int written = 0, rw = 0; written < bodylen; written += rw)
rw = write(priv->execpipe[1], bodyp+written, bodylen-written);
@@ -239,7 +281,7 @@ sfsistat
mlfi_eom(SMFICTX *ctx)
{
if (dodebug)
- fprintf(stderr, "mlfi_eom\n");
+ fprintf(stderr, "mlfi_eom()\n");
return mlfi_cleanup(ctx, 1);
}
@@ -248,7 +290,7 @@ sfsistat
mlfi_abort(SMFICTX *ctx)
{
if (dodebug)
- fprintf(stderr, "mlfi_abort\n");
+ fprintf(stderr, "mlfi_abort()\n");
return mlfi_cleanup(ctx, 0);
}
@@ -259,22 +301,26 @@ mlfi_close(SMFICTX *ctx)
struct Priv *priv = MLFIPRIV;
if (dodebug)
- fprintf(stderr, "mlfi_close\n");
+ fprintf(stderr, "mlfi_close()\n");
if (priv != NULL) {
if (priv->execpipe[1] > 0) {
- if (dodebug)
- fprintf(stderr, "Close execpipe[1]\n");
+ if (dodebug) {
+ fprintf(stderr,
+ "mlfi_close(close execpipe[1])\n");
+ }
close(priv->execpipe[1]);
}
if (priv->execpid > 0) {
- if (dodebug)
- fprintf(stderr, "Kill pid %d.\n", priv->execpid);
+ if (dodebug) {
+ fprintf(stderr,
+ "mlfi_close(kill pid %d)\n", priv->execpid);
+ }
kill(priv->execpid, SIGKILL);
waitpid(priv->execpid, NULL, 0);
}
if (dodebug)
- fprintf(stderr, "Free priv\n");
+ fprintf(stderr, "mlfi_close(free priv)\n");
free(priv);
smfi_setpriv(ctx, NULL);
}
@@ -294,7 +340,7 @@ mlfi_negotiate(SMFICTX *ctx,
unsigned long *pf3)
{
if (dodebug)
- fprintf(stderr, "mlfi_negotiate\n");
+ fprintf(stderr, "mlfi_negotiate()\n");
/* milter actions */
*pf0 = 0;
@@ -464,17 +510,23 @@ main(int argc, char *argv[])
}
if (gr != NULL) {
- if (setgroups(1, &gr->gr_gid) != 0 || setgid(gr->gr_gid) != 0)
+ if (setgroups(1, &gr->gr_gid) != 0 || setgid(gr->gr_gid) != 0) {
+ perror("setgroups");
return -1;
+ }
}
if (us != NULL) {
if (gr == NULL) {
if (setgroups(1, &us->pw_gid) != 0 ||
- setgid(us->pw_gid) != 0)
+ setgid(us->pw_gid) != 0) {
+ perror("setgroups");
return -1;
+ }
}
- if (setuid(us->pw_uid) != 0)
+ if (setuid(us->pw_uid) != 0) {
+ perror("setuid");
return -1;
+ }
}
if (smfi_setconn(conndef) == MI_FAILURE) {