]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lmtp: Increase user's concurrency limit already after RCPT TO.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Jun 2016 11:09:01 +0000 (14:09 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 29 Jun 2016 15:36:41 +0000 (18:36 +0300)
This way it's not possible for a lot of mails to arrive to user concurrently
and bypass the lmtp_user_concurrency_limit.

src/lmtp/client.c
src/lmtp/client.h
src/lmtp/commands.c

index 8f9d704c998e9eb5657a39d7ab154a3e1caf20b8..5650b412123ff301c1104ae599c990ef9eb6f3ea 100644 (file)
@@ -343,6 +343,19 @@ void client_disconnect(struct client *client, const char *prefix,
        client->disconnected = TRUE;
 }
 
+void client_rcpt_anvil_disconnect(const struct mail_recipient *rcpt)
+{
+       const struct mail_storage_service_input *input;
+
+       if (!rcpt->anvil_connect_sent)
+               return;
+
+       input = mail_storage_service_user_get_input(rcpt->service_user);
+       master_service_anvil_send(master_service, t_strconcat(
+               "DISCONNECT\t", my_pid, "\t", master_service_get_name(master_service),
+               "/", input->username, "\n", NULL));
+}
+
 void client_state_reset(struct client *client, const char *state_name)
 {
        struct mail_recipient *const *rcptp;
@@ -354,6 +367,7 @@ void client_state_reset(struct client *client, const char *state_name)
                array_foreach_modifiable(&client->state.rcpt_to, rcptp) {
                        if ((*rcptp)->anvil_query != NULL)
                                anvil_client_query_abort(anvil, &(*rcptp)->anvil_query);
+                       client_rcpt_anvil_disconnect(*rcptp);
                        mail_storage_service_user_free(&(*rcptp)->service_user);
                }
        }
index 9a2117df26a11caf0905159d246e975e9832dc5a..fe91244a6e0a281dd3df4f8f039f62abf079fd50 100644 (file)
@@ -15,6 +15,7 @@ struct mail_recipient {
        struct lmtp_recipient_params params;
 
        struct anvil_query *anvil_query;
+       bool anvil_connect_sent;
        struct mail_storage_service_user *service_user;
 };
 
@@ -88,6 +89,7 @@ void client_destroy(struct client *client, const char *prefix,
 void client_disconnect(struct client *client, const char *prefix,
                       const char *reason);
 void client_io_reset(struct client *client);
+void client_rcpt_anvil_disconnect(const struct mail_recipient *rcpt);
 void client_state_reset(struct client *client, const char *state_name);
 void client_state_set(struct client *client, const char *name, const char *args);
 const char *client_remote_id(struct client *client);
index 737740e9942b0a3251d8aa27a1af04bbfbd3e85c..71ca799c41cea0da19bf46d4c43ff3a00da81e0f 100644 (file)
@@ -599,6 +599,7 @@ static void rcpt_anvil_lookup_callback(const char *reply, void *context)
 {
        struct mail_recipient *rcpt = context;
        struct client *client = rcpt->client;
+       const struct mail_storage_service_input *input;
        unsigned int parallel_count;
 
        i_assert(rcpt->anvil_query != NULL);
@@ -612,6 +613,12 @@ static void rcpt_anvil_lookup_callback(const char *reply, void *context)
 
        if (parallel_count < client->lmtp_set->lmtp_user_concurrency_limit) {
                client_send_line(client, "250 2.1.5 OK");
+
+               rcpt->anvil_connect_sent = TRUE;
+               input = mail_storage_service_user_get_input(rcpt->service_user);
+               master_service_anvil_send(master_service, t_strconcat(
+                       "CONNECT\t", my_pid, "\t", master_service_get_name(master_service),
+                       "/", input->username, "\n", NULL));
                array_append(&client->state.rcpt_to, &rcpt, 1);
        } else {
                client_send_line(client, ERRSTR_TEMP_USERDB_FAIL_PREFIX
@@ -875,11 +882,6 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt,
        dctx.save_dest_mail = array_count(&client->state.rcpt_to) > 1 &&
                client->state.first_saved_mail == NULL;
 
-       if (client->lmtp_set->lmtp_user_concurrency_limit > 0) {
-               master_service_anvil_send(master_service, t_strconcat(
-                       "CONNECT\t", my_pid, "\t", master_service_get_name(master_service),
-                       "/", username, "\n", NULL));
-       }
        if (mail_deliver(&dctx, &storage) == 0) {
                if (dctx.dest_mail != NULL) {
                        i_assert(client->state.first_saved_mail == NULL);
@@ -908,11 +910,7 @@ client_deliver(struct client *client, const struct mail_recipient *rcpt,
                                 rcpt->address);
                ret = -1;
        }
-       if (client->lmtp_set->lmtp_user_concurrency_limit > 0) {
-               master_service_anvil_send(master_service, t_strconcat(
-                       "DISCONNECT\t", my_pid, "\t", master_service_get_name(master_service),
-                       "/", username, "\n", NULL));
-       }
+       client_rcpt_anvil_disconnect(rcpt);
        return ret;
 }