From: Timo Sirainen Date: Wed, 29 Jun 2016 11:09:01 +0000 (+0300) Subject: lmtp: Increase user's concurrency limit already after RCPT TO. X-Git-Tag: 2.2.25.rc1~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f36ac996f90947eba0adcf389d9fa688fe6aa74f;p=thirdparty%2Fdovecot%2Fcore.git lmtp: Increase user's concurrency limit already after RCPT TO. This way it's not possible for a lot of mails to arrive to user concurrently and bypass the lmtp_user_concurrency_limit. --- diff --git a/src/lmtp/client.c b/src/lmtp/client.c index 8f9d704c99..5650b41212 100644 --- a/src/lmtp/client.c +++ b/src/lmtp/client.c @@ -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); } } diff --git a/src/lmtp/client.h b/src/lmtp/client.h index 9a2117df26..fe91244a6e 100644 --- a/src/lmtp/client.h +++ b/src/lmtp/client.h @@ -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); diff --git a/src/lmtp/commands.c b/src/lmtp/commands.c index 737740e994..71ca799c41 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -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; }