dovecot-2.0-sslstream: *-login: Use new anvil library to do asyn...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:56:05 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/e99c02873d8c
changeset: 10267:e99c02873d8c
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Nov 06 13:57:43 2009 -0500
description:
*-login: Use new anvil library to do async anvil lookups.

diffstat:

3 files changed, 63 insertions(+), 64 deletions(-)
src/login-common/common.h      |    2 
src/login-common/main.c        |   33 +++++---------
src/login-common/sasl-server.c |   92 +++++++++++++++++++++-------------------

diffs (222 lines):

diff -r 8ebf82849077 -r e99c02873d8c src/login-common/common.h
--- a/src/login-common/common.h	Fri Nov 06 13:57:04 2009 -0500
+++ b/src/login-common/common.h	Fri Nov 06 13:57:43 2009 -0500
@@ -18,7 +18,7 @@ extern struct auth_client *auth_client;
 extern struct auth_client *auth_client;
 extern struct master_auth *master_auth;
 extern bool closing_down;
-extern int anvil_fd;
+extern struct anvil_client *anvil;
 
 extern const struct login_settings *global_login_settings;
 extern void **global_other_settings;
diff -r 8ebf82849077 -r e99c02873d8c src/login-common/main.c
--- a/src/login-common/main.c	Fri Nov 06 13:57:04 2009 -0500
+++ b/src/login-common/main.c	Fri Nov 06 13:57:43 2009 -0500
@@ -10,6 +10,7 @@
 #include "master-service.h"
 #include "master-interface.h"
 #include "client-common.h"
+#include "anvil-client.h"
 #include "auth-client.h"
 #include "ssl-proxy.h"
 #include "login-proxy.h"
@@ -21,7 +22,7 @@ struct auth_client *auth_client;
 struct auth_client *auth_client;
 struct master_auth *master_auth;
 bool closing_down;
-int anvil_fd = -1;
+struct anvil_client *anvil;
 
 const struct login_settings *global_login_settings;
 void **global_other_settings;
@@ -104,19 +105,10 @@ static void auth_connect_notify(struct a
                 clients_notify_auth_connected();
 }
 
-static int anvil_connect(void)
-{
-#define ANVIL_HANDSHAKE "VERSION\tanvil\t1\t0\n"
-	int fd;
-
-	fd = net_connect_unix_with_retries("anvil", 5000);
-	if (fd == -1)
-		i_fatal("net_connect_unix(anvil) failed: %m");
-	net_set_nonblock(fd, FALSE);
-
-	if (write(fd, ANVIL_HANDSHAKE, strlen(ANVIL_HANDSHAKE)) < 0)
-		i_fatal("write(anvil) failed: %m");
-	return fd;
+static bool anvil_reconnect_callback(void)
+{
+	master_service_stop_new_connections(master_service);
+	return FALSE;
 }
 
 static void main_preinit(bool allow_core_dumps)
@@ -147,8 +139,11 @@ static void main_preinit(bool allow_core
 	i_assert(strcmp(global_login_settings->ssl, "no") == 0 ||
 		 ssl_initialized);
 
-	if (global_login_settings->mail_max_userip_connections > 0)
-		anvil_fd = anvil_connect();
+	if (global_login_settings->mail_max_userip_connections > 0) {
+		anvil = anvil_client_init("anvil", anvil_reconnect_callback);
+		if (anvil_client_connect(anvil, TRUE) < 0)
+			i_fatal("Couldn't connect to anvil");
+	}
 
 	restrict_access_by_env(NULL, TRUE);
 	if (allow_core_dumps)
@@ -187,10 +182,8 @@ static void main_deinit(void)
 	clients_deinit();
 	master_auth_deinit(&master_auth);
 
-	if (anvil_fd != -1) {
-		if (close(anvil_fd) < 0)
-			i_error("close(anvil) failed: %m");
-	}
+	if (anvil != NULL)
+		anvil_client_deinit(&anvil);
 }
 
 int main(int argc, char *argv[])
diff -r 8ebf82849077 -r e99c02873d8c src/login-common/sasl-server.c
--- a/src/login-common/sasl-server.c	Fri Nov 06 13:57:04 2009 -0500
+++ b/src/login-common/sasl-server.c	Fri Nov 06 13:57:43 2009 -0500
@@ -8,6 +8,7 @@
 #include "write-full.h"
 #include "strescape.h"
 #include "str-sanitize.h"
+#include "anvil-client.h"
 #include "auth-client.h"
 #include "ssl-proxy.h"
 #include "master-service.h"
@@ -21,6 +22,11 @@
 #define ERR_TOO_MANY_USERIP_CONNECTIONS \
 	"Maximum number of connections from user+IP exceeded " \
 	"(mail_max_userip_connections)"
+
+struct anvil_request {
+	struct client *client;
+	unsigned int auth_pid, auth_id;
+};
 
 const struct auth_mech_desc *
 sasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r)
@@ -98,9 +104,9 @@ master_auth_callback(const struct master
 	call_client_callback(client, sasl_reply, data, NULL);
 }
 
-static void
-master_send_request(struct client *client, struct auth_client_request *request)
-{
+static void master_send_request(struct anvil_request *anvil_request)
+{
+	struct client *client = anvil_request->client;
 	struct master_auth_request req;
 	const unsigned char *data;
 	const char *cookie;
@@ -110,8 +116,8 @@ master_send_request(struct client *clien
 	buf = buffer_create_dynamic(pool_datastack_create(), 256);
 
 	memset(&req, 0, sizeof(req));
-	req.auth_pid = auth_client_request_get_server_pid(request);
-	req.auth_id = auth_client_request_get_id(request);
+	req.auth_pid = anvil_request->auth_pid;
+	req.auth_id = anvil_request->auth_id;
 	req.local_ip = client->local_ip;
 	req.remote_ip = client->ip;
 	req.client_pid = getpid();
@@ -132,39 +138,44 @@ master_send_request(struct client *clien
 			    master_auth_callback, client, &client->master_tag);
 }
 
-static bool anvil_has_too_many_connections(struct client *client)
-{
-	const char *ident;
-	char buf[64];
-	ssize_t ret;
-
-	if (client->virtual_user == NULL)
-		return FALSE;
-	if (client->set->mail_max_userip_connections == 0)
-		return FALSE;
-
-	ident = t_strconcat("LOOKUP\t", login_protocol, "/",
+static void anvil_lookup_callback(const char *reply, void *context)
+{
+	struct anvil_request *req = context;
+	struct client *client = req->client;
+
+	if (reply == NULL ||
+	    strtoul(reply, NULL, 10) < client->set->mail_max_userip_connections)
+		master_send_request(req);
+	else {
+		client->authenticating = FALSE;
+		call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED,
+				     ERR_TOO_MANY_USERIP_CONNECTIONS, NULL);
+	}
+	i_free(req);
+}
+
+static void
+anvil_check_too_many_connections(struct client *client,
+				 struct auth_client_request *request)
+{
+	struct anvil_request *req;
+	const char *query;
+
+	req = i_new(struct anvil_request, 1);
+	req->client = client;
+	req->auth_pid = auth_client_request_get_server_pid(request);
+	req->auth_id = auth_client_request_get_id(request);
+
+	if (client->virtual_user == NULL ||
+	    client->set->mail_max_userip_connections == 0) {
+		anvil_lookup_callback(NULL, req);
+		return;
+	}
+
+	query = t_strconcat("LOOKUP\t", login_protocol, "/",
 			    net_ip2addr(&client->ip), "/",
-			    str_tabescape(client->virtual_user), "\n", NULL);
-	if (write_full(anvil_fd, ident, strlen(ident)) < 0) {
-		if (errno == EPIPE) {
-			/* anvil process was probably recreated, don't bother
-			   logging an error about losing connection to it */
-			return FALSE;
-		}
-		i_fatal("write(anvil) failed: %m");
-	}
-	ret = read(anvil_fd, buf, sizeof(buf)-1);
-	if (ret < 0)
-		i_fatal("read(anvil) failed: %m");
-	else if (ret == 0)
-		i_fatal("read(anvil) failed: EOF");
-	if (buf[ret-1] != '\n')
-		i_fatal("anvil lookup failed: Invalid input in reply");
-	buf[ret-1] = '\0';
-
-	return strtoul(buf, NULL, 10) >=
-		client->set->mail_max_userip_connections;
+			    str_tabescape(client->virtual_user), NULL);
+	anvil_client_query(anvil, query, anvil_lookup_callback, req);
 }
 
 static void
@@ -209,13 +220,8 @@ authenticate_callback(struct auth_client
 			client->authenticating = FALSE;
 			call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
 					     NULL, args);
-		} else if (anvil_has_too_many_connections(client)) {
-			client->authenticating = FALSE;
-			call_client_callback(client,
-					SASL_SERVER_REPLY_MASTER_FAILED,
-					ERR_TOO_MANY_USERIP_CONNECTIONS, NULL);
 		} else {
-			master_send_request(client, request);
+			anvil_check_too_many_connections(client, request);
 		}
 		break;
 	case AUTH_REQUEST_STATUS_FAIL:


More information about the dovecot-cvs mailing list