dovecot-2.0: Implemented anvil service, which is used to impleme...

dovecot at dovecot.org dovecot at dovecot.org
Wed May 6 04:28:42 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/2e2b957f1cca
changeset: 9235:2e2b957f1cca
user:      Timo Sirainen <tss at iki.fi>
date:      Tue May 05 21:28:34 2009 -0400
description:
Implemented anvil service, which is used to implement mail_max_userip_connections.

diffstat:

42 files changed, 927 insertions(+), 136 deletions(-)
.hgignore                                |    2 
TODO                                     |    4 
configure.in                             |    1 
dovecot-master-example.conf              |   18 ++-
src/anvil/Makefile.am                    |   24 ++++
src/anvil/anvil-connection.c             |  165 +++++++++++++++++++++++++++++
src/anvil/anvil-connection.h             |    9 +
src/anvil/common.h                       |    8 +
src/anvil/connect-limit.c                |  166 ++++++++++++++++++++++++++++++
src/anvil/connect-limit.h                |   15 ++
src/anvil/main.c                         |   42 +++++++
src/imap-login/client.c                  |    2 
src/imap/imap-client.c                   |   15 ++
src/imap/imap-client.h                   |    1 
src/lib-master/master-interface.h        |    9 -
src/lib-master/master-service-settings.c |    2 
src/lib-master/master-service.c          |   17 +++
src/lib-master/master-service.h          |    2 
src/lib-storage/mail-user.c              |    9 +
src/lib-storage/mail-user.h              |    2 
src/login-common/common.h                |    1 
src/login-common/login-settings.c        |    4 
src/login-common/login-settings.h        |    1 
src/login-common/main.c                  |   24 ++++
src/login-common/sasl-server.c           |   47 +++++++-
src/master/Makefile.am                   |    4 
src/master/master-settings.c             |    9 +
src/master/service-anvil.c               |   92 ++++++++++++++++
src/master/service-anvil.h               |    8 +
src/master/service-auth-server.c         |    5 
src/master/service-log.c                 |   44 ++++---
src/master/service-log.h                 |    1 
src/master/service-monitor.c             |   27 +++-
src/master/service-process-notify.c      |  102 ++++++++++++++++++
src/master/service-process-notify.h      |   15 ++
src/master/service-process.c             |  120 ++++++++-------------
src/master/service-process.h             |    2 
src/master/service.c                     |   10 +
src/master/service.h                     |   15 +-
src/pop3-login/client.c                  |    2 
src/pop3/pop3-client.c                   |   16 ++
src/pop3/pop3-client.h                   |    1 

diffs (truncated from 1735 to 300 lines):

diff -r 783a81c3deb7 -r 2e2b957f1cca .hgignore
--- a/.hgignore	Tue May 05 20:26:40 2009 -0400
+++ b/.hgignore	Tue May 05 21:28:34 2009 -0400
@@ -51,9 +51,11 @@ Makefile.in
 
 doc/wiki/*.txt
 doc/wiki/Makefile.am
+src/anvil/anvil
 src/auth/checkpassword-reply
 src/auth/dovecot-auth
 src/config/all-settings.c
+src/config/config
 src/config/doveconf
 src/lda/dovecot-lda
 src/dict/dict
diff -r 783a81c3deb7 -r 2e2b957f1cca TODO
--- a/TODO	Tue May 05 20:26:40 2009 -0400
+++ b/TODO	Tue May 05 21:28:34 2009 -0400
@@ -1,6 +1,6 @@
- - mail_max_userip_connections
+ - move ssl proxying code to lib-master
+ - rawlog is broken because it can't get $HOME etc.
  - dovecot stop, dovecot reload
- - make sure status/log messages which are important get through to the server
  - log prefixes work in a weird way now. failures.c prefixes are used only
    when not doing internal logging. that won't work in future..
  - library dependency tracking still broken. .la changes get noticed,
diff -r 783a81c3deb7 -r 2e2b957f1cca configure.in
--- a/configure.in	Tue May 05 20:26:40 2009 -0400
+++ b/configure.in	Tue May 05 21:28:34 2009 -0400
@@ -2383,6 +2383,7 @@ src/lib-storage/index/raw/Makefile
 src/lib-storage/index/raw/Makefile
 src/lib-storage/index/shared/Makefile
 src/lib-storage/register/Makefile
+src/anvil/Makefile
 src/auth/Makefile
 src/config/Makefile
 src/lda/Makefile
diff -r 783a81c3deb7 -r 2e2b957f1cca dovecot-master-example.conf
--- a/dovecot-master-example.conf	Tue May 05 20:26:40 2009 -0400
+++ b/dovecot-master-example.conf	Tue May 05 21:28:34 2009 -0400
@@ -2,15 +2,29 @@ service config {
   type = config
   executable = config
   user = dovecot
-  drop_priv_before_exec = yes
+
   unix_listener {
     path = config
+    mode = 0666
   }
 }
 
 service log {
   type = log
   executable = log
+  process_limit = 1
+}
+
+service anvil {
+  type = anvil
+  executable = anvil
+  process_limit = 1
+  user = dovecot
+  chroot = empty
+
+  unix_listener {
+    path = anvil
+  }
 }
 
 service auth {
@@ -56,7 +70,6 @@ service imap-login {
 }
 
 service imap {
-  type = auth-destination
   executable = imap
 }
 
@@ -80,7 +93,6 @@ service pop3-login {
 }
 
 service pop3 {
-  type = auth-destination
   executable = pop3
 }
 
diff -r 783a81c3deb7 -r 2e2b957f1cca src/anvil/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/anvil/Makefile.am	Tue May 05 21:28:34 2009 -0400
@@ -0,0 +1,24 @@
+pkglibexecdir = $(libexecdir)/dovecot
+
+pkglibexec_PROGRAMS = anvil
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-settings \
+	-I$(top_srcdir)/src/lib-master
+
+anvil_LDADD = \
+	$(LIBDOVECOT) \
+	$(MODULE_LIBS) \
+	$(RAND_LIBS)
+anvil_DEPENDENCIES = $(LIBDOVECOT)
+
+anvil_SOURCES = \
+	main.c \
+	anvil-connection.c \
+	connect-limit.c
+
+noinst_HEADERS = \
+	anvil-connection.h \
+	common.h \
+	connect-limit.h
diff -r 783a81c3deb7 -r 2e2b957f1cca src/anvil/anvil-connection.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/anvil/anvil-connection.c	Tue May 05 21:28:34 2009 -0400
@@ -0,0 +1,165 @@
+/* Copyright (C) 2009 Dovecot authors, see the included COPYING file */
+
+#include "common.h"
+#include "llist.h"
+#include "istream.h"
+#include "ostream.h"
+#include "master-interface.h"
+#include "connect-limit.h"
+#include "anvil-connection.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#define MAX_INBUF_SIZE 1024
+
+#define ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION 1
+#define ANVIL_CLIENT_PROTOCOL_MINOR_VERSION 0
+
+struct anvil_connection {
+	struct anvil_connection *prev, *next;
+
+	int fd;
+	struct istream *input;
+	struct ostream *output;
+	struct io *io;
+
+	unsigned int version_received:1;
+	unsigned int handshaked:1;
+};
+
+struct anvil_connection *anvil_connections = NULL;
+
+static const char *const *
+anvil_connection_next_line(struct anvil_connection *conn)
+{
+	const char *line;
+
+	line = i_stream_next_line(conn->input);
+	if (line == NULL)
+		return NULL;
+
+	return t_strsplit(line, "\t");
+}
+
+static int
+anvil_connection_request(struct anvil_connection *conn,
+			 const char *const *args, const char **error_r)
+{
+	const char *cmd = args[0];
+	unsigned int count;
+	pid_t pid;
+
+	args++;
+	if (strcmp(cmd, "CONNECT") == 0) {
+		if (args[0] == NULL || args[1] == NULL) {
+			*error_r = "CONNECT: Not enough parameters";
+			return -1;
+		}
+		pid = strtol(args[0], NULL, 10);
+		connect_limit_connect(connect_limit, pid, args[1]);
+		return 0;
+	} else if (strcmp(cmd, "DISCONNECT") == 0) {
+		if (args[0] == NULL || args[1] == NULL) {
+			*error_r = "DISCONNECT: Not enough parameters";
+			return -1;
+		}
+		pid = strtol(args[0], NULL, 10);
+		connect_limit_disconnect(connect_limit, pid, args[1]);
+		return 0;
+	} else if (strcmp(cmd, "KILL") == 0) {
+		if (args[0] == NULL) {
+			*error_r = "KILL: Not enough parameters";
+			return -1;
+		}
+		if (conn->fd != MASTER_LISTEN_FD_FIRST) {
+			*error_r = "KILL sent by a non-master connection";
+			return -1;
+		}
+		pid = strtol(args[0], NULL, 10);
+		connect_limit_disconnect_pid(connect_limit, pid);
+		return 0;
+	} else if (strcmp(cmd, "LOOKUP") == 0) {
+		if (args[0] == NULL) {
+			*error_r = "LOOKUP: Not enough parameters";
+			return -1;
+		}
+		count = connect_limit_lookup(connect_limit, args[0]);
+		(void)o_stream_send_str(conn->output,
+					t_strdup_printf("%u\n", count));
+		return 0;
+	} else {
+		*error_r = t_strconcat("Unknown command: ", cmd, NULL);
+		return -1;
+	}
+}
+
+static void anvil_connection_input(void *context)
+{
+	struct anvil_connection *conn = context;
+	const char *const *args, *line, *error;
+
+	switch (i_stream_read(conn->input)) {
+	case -2:
+		i_error("BUG: Anvil client connection sent too much data");
+                anvil_connection_destroy(conn);
+		return;
+	case -1:
+                anvil_connection_destroy(conn);
+		return;
+	}
+
+	if (!conn->version_received) {
+		line = i_stream_next_line(conn->input);
+		if (line == NULL)
+			return;
+
+		if (strncmp(line, "VERSION\t", 8) != 0 ||
+		    atoi(t_strcut(line + 8, '\t')) !=
+		    ANVIL_CLIENT_PROTOCOL_MAJOR_VERSION) {
+			i_error("Anvil client not compatible with this server "
+				"(mixed old and new binaries?)");
+			anvil_connection_destroy(conn);
+			return;
+		}
+		conn->version_received = TRUE;
+	}
+
+	while ((args = anvil_connection_next_line(conn)) != NULL) {
+		if (args[0] != NULL) {
+			if (anvil_connection_request(conn, args, &error) < 0)
+				i_error("Anvil client input error: %s", error);
+		}
+	}
+}
+
+struct anvil_connection *anvil_connection_create(int fd)
+{
+	struct anvil_connection *conn;
+
+	conn = i_new(struct anvil_connection, 1);
+	conn->fd = fd;
+	conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
+	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
+	conn->io = io_add(fd, IO_READ, anvil_connection_input, conn);
+	DLLIST_PREPEND(&anvil_connections, conn);
+	return conn;
+}
+
+void anvil_connection_destroy(struct anvil_connection *conn)
+{
+	DLLIST_REMOVE(&anvil_connections, conn);
+
+	io_remove(&conn->io);
+	i_stream_destroy(&conn->input);
+	o_stream_destroy(&conn->output);
+	if (close(conn->fd) < 0)
+		i_error("close(anvil conn) failed: %m");
+	i_free(conn);
+}
+
+void anvil_connections_destroy_all(void)
+{
+	while (anvil_connections != NULL)
+		anvil_connection_destroy(anvil_connections);
+}
diff -r 783a81c3deb7 -r 2e2b957f1cca src/anvil/anvil-connection.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/anvil/anvil-connection.h	Tue May 05 21:28:34 2009 -0400
@@ -0,0 +1,9 @@
+#ifndef ANVIL_CONNECTION_H
+#define ANVIL_CONNECTION_H
+
+struct anvil_connection *anvil_connection_create(int fd);
+void anvil_connection_destroy(struct anvil_connection *conn);
+
+void anvil_connections_destroy_all(void);
+
+#endif
diff -r 783a81c3deb7 -r 2e2b957f1cca src/anvil/common.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000


More information about the dovecot-cvs mailing list