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