Added part for mmsmtpd(8)->mmrelayd(8) notification used for newly queued
authorMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 1 Mar 2005 11:05:29 +0000 (11:05 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 1 Mar 2005 11:05:29 +0000 (11:05 +0000)
messages which should interrupt the relay daemon's sleep when waiting for
sheduled events.

mmsoftware/mmmail/src/mmrelayd/mmrelayd.c
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.c
mmsoftware/mmmail/src/mmsmtpd/mmsmtpd.h

index e7a2a6a..a6e36f3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmrelayd.c,v 1.5 2005/01/26 08:13:00 mmondor Exp $ */
+/* $Id: mmrelayd.c,v 1.6 2005/03/01 11:05:29 mmondor Exp $ */
 
 /*
  * Copyright (C) 2004, Matthew Mondor
@@ -76,7 +76,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2004\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmrelayd.c,v 1.5 2005/01/26 08:13:00 mmondor Exp $");
+MMRCSID("$Id: mmrelayd.c,v 1.6 2005/03/01 11:05:29 mmondor Exp $");
 
 
 
@@ -89,7 +89,8 @@ MMRCSID("$Id: mmrelayd.c,v 1.5 2005/01/26 08:13:00 mmondor Exp $");
 struct CONFIG {
        char CHROOT_DIR[256], PID_PATH[256], USER[32], GROUPS[256],
            LOG_FACILITY[32], DB_HOST[64], DB_USER[32], DB_PASSWORD[32],
-           DB_DATABASE[32], MAIL_DIR[256], RELAY_SMARTHOST[64];
+           DB_DATABASE[32], MAIL_DIR[256], RELAY_SMARTHOST[64],
+           SOCKET_PATH[256];
        long INPUT_TIMEOUT, BANDWIDTH_IN, BANDWIDTH_OUT, GBANDWIDTH_IN,
            GBANDWIDTH_OUT;
 };
@@ -118,6 +119,7 @@ static carg_t               cargs[] = {
        {CAT_STR, CAF_NONE, 1, 31, "DB_DATABASE", CONF.DB_DATABASE},
        {CAT_STR, CAF_NONE, 1, 255, "MAIL_DIR", CONF.MAIL_DIR},
        {CAT_STR, CAF_NONE, 1, 63, "RELAY_SMARTHOST", CONF.RELAY_SMARTHOST},
+       {CAT_STR, CAF_NONE, 1, 255, "SOCKET_PATH", CONF.SOCKET_PATH},
        {CAT_VAL, CAF_NONE, 1, 99999, "INPUT_TIMEOUT", &CONF.INPUT_TIMEOUT},
        {CAT_VAL, CAF_NONE, 0, 99999, "BANDWIDTH_IN", &CONF.BANDWIDTH_IN},
        {CAT_VAL, CAF_NONE, 0, 99999, "BANDWIDTH_OUT", &CONF.BANDWIDTH_OUT},
@@ -184,10 +186,20 @@ main(int argc, char **argv)
        if (config_read(conf_file) == -1)
                exit(EXIT_FAILURE);
 
+       /*
+        * Bind our AF_LOCAL notification socket, which is used to interrupt
+        * our sleep while waiting for scheduled events, in case new messages
+        * get queued for relaying by mmsmtpd(8).
+        */
+       /* XXX */
+
+       /*
+        * Finally drop privileges
+        */
        if (privileges_drop() == -1)
                exit(EXIT_FAILURE);
 
-       /* XXX */
+       /* XXX Fork, etc */
 
        exit(EXIT_SUCCESS);
 }
@@ -204,7 +216,6 @@ config_read(const char *file)
        int             ngids;
        long            facility;
        cres_t          cres;
-       carg_t          *cargp;
        struct stat     st;
 
        /*
@@ -220,6 +231,7 @@ config_read(const char *file)
        (void) mm_strcpy(CONF.DB_PASSWORD, "mmmailpassword");
        (void) mm_strcpy(CONF.DB_DATABASE, "mmmail");
        (void) mm_strcpy(CONF.MAIL_DIR, "/var/mmmail-dir");
+       (void) mm_strcpy(CONF.SOCKET_PATH, "/var/run/mmrelayd.sock");
        *CONF.RELAY_SMARTHOST = '\0';
        CONF.BANDWIDTH_IN = 0;
        CONF.BANDWIDTH_OUT = 0;
index 767e999..4d85fec 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.c,v 1.67 2005/02/27 01:33:15 mmondor Exp $ */
+/* $Id: mmsmtpd.c,v 1.68 2005/03/01 11:05:29 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2004, Matthew Mondor
@@ -49,6 +49,7 @@
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <resolv.h>
+#include <sys/un.h>
 
 #include <syslog.h>
 
@@ -80,7 +81,7 @@
 
 MMCOPYRIGHT("@(#) Copyright (c) 2001-2004\n\
 \tMatthew Mondor. All rights reserved.\n");
-MMRCSID("$Id: mmsmtpd.c,v 1.67 2005/02/27 01:33:15 mmondor Exp $");
+MMRCSID("$Id: mmsmtpd.c,v 1.68 2005/03/01 11:05:29 mmondor Exp $");
 
 
 
@@ -195,8 +196,8 @@ static fdfuncs gfdf = {
 /*
  * Connection to mmrelayd(8) establishment
  */
-int relayd = -1;
-pth_mutex_t relayd_lock;
+int            relayd_sock = -1;
+pth_mutex_t    relayd_lock = PTH_MUTEX_INIT;
 
 
 
@@ -228,6 +229,8 @@ main(int argc, char **argv)
        {CAT_STR, CAF_NONE, 1, 31, "DB_PASSWORD", CONF.DB_PASSWORD},
        {CAT_STR, CAF_NONE, 1, 31, "DB_DATABASE", CONF.DB_DATABASE},
        {CAT_STR, CAF_NONE, 1, 255, "MAIL_DIR", CONF.MAIL_DIR},
+       {CAT_STR, CAF_NONE, 1, 255, "MMRELAYD_SOCKET_PATH",
+           CONF.MMRELAYD_SOCKET_PATH},
        {CAT_VAL, CAF_NONE, 1, 32, "ASYNC_PROCESSES", &CONF.ASYNC_PROCESSES},
        {CAT_VAL, CAF_NONE, 1, 9999, "ALLOC_BUFFERS", &CONF.ALLOC_BUFFERS},
        {CAT_VAL, CAF_NONE, 0, 4, "LOG_LEVEL", &CONF.LOG_LEVEL},
@@ -316,6 +319,7 @@ main(int argc, char **argv)
     mm_strcpy(CONF.DB_PASSWORD, "mmmailpassword");
     mm_strcpy(CONF.DB_DATABASE, "mmmail");
     mm_strcpy(CONF.MAIL_DIR, "/var/mmmail-dir");
+    mm_strcpy(CONF.MMRELAYD_SOCKET_PATH, "/var/run/mmrelayd.sock");
     CONF.ASYNC_PROCESSES = 3;
     CONF.ALLOC_BUFFERS = 1;
     CONF.LOG_LEVEL = 3;
@@ -2302,16 +2306,90 @@ do_data_queue_relay(clientenv *clenv, const char *recvline, size_t recvlen,
 
     /*
      * We now want to notify mmrelayd that it should verify for ready to
-     * relay mail immediately. We could send a message to the process, but
-     * since we are not its originator, this could be tricky. The best way
-     * then remains to notify it via a special unix socket dedicated to this
-     * effect.
-     * XXX
+     * relay mail as soon as possible instead of waiting until its next
+     * scheduled round.
      */
+    do_data_queue_notify();
 
     return ok;
 }
 
+/*
+ * Attempt to notify mmrelayd(8) that at least one message is ready in the
+ * queue to route.
+ */
+static void
+do_data_queue_notify(void)
+{
+    bool       ok = FALSE;
+
+    /*
+     * If we cannot obtain lock, we know that it's already being notified, and
+     * we don't need to do anything.
+     */
+    if (pth_mutex_acquire(&relayd_lock, TRUE, NULL) == FALSE)
+       return;
+
+    /*
+     * If socket wasn't open yet, attempt to open it. If we cannot, we have
+     * nothing to notify, since the relay daemon most probably doesn't run.
+     */
+    if (relayd_sock == -1) {
+       if ((relayd_sock = do_data_queue_notify_connect()) == -1)
+           goto end;
+    }
+
+    /*
+     * Send a notification packet. If we cannot send it, attempt to reconnect
+     * and send it again, but once only.
+     */
+    for (;;) {
+       if (pth_write(relayd_sock, "N", 1) != 1) {
+           (void) close(relayd_sock);
+           if ((relayd_sock = do_data_queue_notify_connect()) != -1)
+               continue;
+       } else
+           ok = TRUE;
+       break;
+    }
+
+end:
+
+    if (!ok)
+       mmsyslog(0, LOGLEVEL,
+               "mmrelayd(8) could not be notified (not running?)");
+
+    (void) pth_mutex_release(&relayd_lock);
+}
+
+/*
+ * Attempt to open the mmrelayd(8) notification socket, returning the
+ * filedescriptor on success, or -1 on failure.
+ */
+static int
+do_data_queue_notify_connect(void)
+{
+    int                        fd;
+    struct sockaddr_un addr;
+
+    if ((fd = socket(AF_LOCAL, SOCK_DGRAM, 0)) != -1) {
+       mm_memclr(&addr, sizeof(struct sockaddr_un));
+       mm_strncpy(addr.sun_path, CONF.MMRELAYD_SOCKET_PATH, 100);
+       addr.sun_family = AF_UNIX;
+       if ((pth_connect(fd, (struct sockaddr *)&addr,
+                       sizeof(struct sockaddr_un))) == -1) {
+           (void) close(fd);
+           fd = -1;
+       } else
+           mmsyslog(0, LOGLEVEL, "Cannot connect to mmrelayd(8) socket "
+                   "'%s' (%s)", addr.sun_path, strerror(errno));
+    } else
+       mmsyslog(0, LOGLEVEL, "Cannot create socket descriptor (%s)",
+               strerror(errno));
+
+    return fd;
+}
+
 #else
 #error "One of MMMAIL_MYSQL or MMMAIL_FILE must be #defined!"
 #endif
index be3374b..df001e3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mmsmtpd.h,v 1.28 2005/02/15 22:30:22 mmondor Exp $ */
+/* $Id: mmsmtpd.h,v 1.29 2005/03/01 11:05:29 mmondor Exp $ */
 
 /*
  * Copyright (C) 2001-2004, Matthew Mondor
@@ -124,7 +124,8 @@ enum data_reason {
 typedef struct config {
     char CHROOT_DIR[256], PID_PATH[256], USER[32], GROUPS[256],
        LOG_FACILITY[32], SERVER_NAMES[1024], LISTEN_IPS[1024], DB_HOST[64],
-       DB_USER[32], DB_PASSWORD[32], DB_DATABASE[32], MAIL_DIR[256];
+       DB_USER[32], DB_PASSWORD[32], DB_DATABASE[32], MAIL_DIR[256],
+       MMRELAYD_SOCKET_PATH[256];
     long ALLOC_BUFFERS, LOG_LEVEL, LISTEN_PORT, MAX_ERRORS, MAX_IPS,
        MAX_PER_IP, CONNECTION_RATE, CONNECTION_PERIOD, INPUT_TIMEOUT,
        BANDWIDTH_IN, BANDWIDTH_OUT, GBANDWIDTH_IN, GBANDWIDTH_OUT, MAX_RCPTS,
@@ -303,6 +304,8 @@ static bool do_data_queue_box(clientenv *, const char *, size_t, struct
        fdbrb_buffer *, rcptnode *);
 static bool do_data_queue_relay(clientenv *, const char *, size_t, struct
        fdbrb_buffer *, rcptnode *);
+static void do_data_queue_notify(void);
+static int do_data_queue_notify_connect(void);
 #else
 #error "One of MMMAIL_MYSQL or MMMAIL_FILE must be #defined!"
 #endif