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