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.3.0.rc1~3399 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=553a131eddb46d97967fd9610408b7f0829eab6f;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 ff83042377..e922958be2 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 702fc8ef10..856a7d468c 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 298a2ae4bd..f97ea9fc9f 100644 --- a/src/lmtp/commands.c +++ b/src/lmtp/commands.c @@ -607,6 +607,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); @@ -620,6 +621,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 @@ -884,11 +891,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); @@ -917,11 +919,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; }