From: Stephan Bosch Date: Thu, 18 Oct 2018 00:15:07 +0000 (+0200) Subject: lib-smtp: client: Allow enabling the LMTP per-RCPT DATA reply behavior for ESMTP... X-Git-Tag: 2.3.9~1116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad9247768a2a6df6490a024bb3a0f79ca4618804;p=thirdparty%2Fdovecot%2Fcore.git lib-smtp: client: Allow enabling the LMTP per-RCPT DATA reply behavior for ESMTP transactions. This is non-standard. --- diff --git a/src/lib-smtp/smtp-client-private.h b/src/lib-smtp/smtp-client-private.h index 5f5da07967..9c3d45a82c 100644 --- a/src/lib-smtp/smtp-client-private.h +++ b/src/lib-smtp/smtp-client-private.h @@ -95,6 +95,7 @@ struct smtp_client_transaction { struct smtp_client_transaction *prev, *next; struct smtp_client_connection *conn; + enum smtp_client_transaction_flags flags; enum smtp_client_transaction_state state; struct smtp_client_command *cmd_data, *cmd_rset; diff --git a/src/lib-smtp/smtp-client-transaction.c b/src/lib-smtp/smtp-client-transaction.c index 28e457170d..f882f43d0b 100644 --- a/src/lib-smtp/smtp-client-transaction.c +++ b/src/lib-smtp/smtp-client-transaction.c @@ -270,17 +270,22 @@ smtp_client_transaction_debug(struct smtp_client_transaction *trans, #undef smtp_client_transaction_create_empty struct smtp_client_transaction * -smtp_client_transaction_create_empty(struct smtp_client_connection *conn, - unsigned int flags ATTR_UNUSED, +smtp_client_transaction_create_empty( + struct smtp_client_connection *conn, + enum smtp_client_transaction_flags flags, smtp_client_transaction_callback_t *callback, void *context) { struct smtp_client_transaction *trans; pool_t pool; + if (conn->protocol == SMTP_PROTOCOL_LMTP) + flags |= SMTP_CLIENT_TRANSACTION_FLAG_REPLY_PER_RCPT; + pool = pool_alloconly_create("smtp transaction", 4096); trans = p_new(pool, struct smtp_client_transaction, 1); trans->refcount = 1; trans->pool = pool; + trans->flags = flags; trans->callback = callback; trans->context = context; @@ -297,7 +302,7 @@ struct smtp_client_transaction * smtp_client_transaction_create(struct smtp_client_connection *conn, const struct smtp_address *mail_from, const struct smtp_params_mail *mail_params, - unsigned int flags ATTR_UNUSED, + enum smtp_client_transaction_flags flags, smtp_client_transaction_callback_t *callback, void *context) { struct smtp_client_transaction *trans; @@ -877,13 +882,12 @@ static void smtp_client_transaction_data_cb(const struct smtp_reply *reply, struct smtp_client_transaction *trans) { - struct smtp_client_connection *conn = trans->conn; - i_assert(!trans->reset); smtp_client_transaction_ref(trans); - if (conn->protocol == SMTP_PROTOCOL_LMTP && + if (HAS_ALL_BITS(trans->flags, + SMTP_CLIENT_TRANSACTION_FLAG_REPLY_PER_RCPT) && trans->cmd_data != NULL && /* NULL when failed early */ trans->rcpts_data == NULL && trans->rcpts_count > 0) { smtp_client_command_set_replies(trans->cmd_data, @@ -896,7 +900,8 @@ smtp_client_transaction_data_cb(const struct smtp_reply *reply, if (rcpt->data_callback != NULL) rcpt->data_callback(reply, rcpt->data_context); rcpt->data_callback = NULL; - if (conn->protocol == SMTP_PROTOCOL_LMTP) + if (HAS_ALL_BITS(trans->flags, + SMTP_CLIENT_TRANSACTION_FLAG_REPLY_PER_RCPT)) break; } if (trans->rcpts_data != NULL) { @@ -1190,8 +1195,6 @@ smtp_client_transaction_submit(struct smtp_client_transaction *trans, static void smtp_client_transaction_try_complete(struct smtp_client_transaction *trans) { - struct smtp_client_connection *conn = trans->conn; - if (trans->rcpts_queue_count > 0) { /* Not all RCPT replies have come in yet */ smtp_client_transaction_debug( @@ -1235,7 +1238,8 @@ smtp_client_transaction_try_complete(struct smtp_client_transaction *trans) if (trans->cmd_data == NULL) return; - if (conn->protocol == SMTP_PROTOCOL_LMTP) { + if (HAS_ALL_BITS(trans->flags, + SMTP_CLIENT_TRANSACTION_FLAG_REPLY_PER_RCPT)) { smtp_client_command_set_replies(trans->cmd_data, trans->rcpts_count); } diff --git a/src/lib-smtp/smtp-client-transaction.h b/src/lib-smtp/smtp-client-transaction.h index d5f88ff2d4..06399ec25f 100644 --- a/src/lib-smtp/smtp-client-transaction.h +++ b/src/lib-smtp/smtp-client-transaction.h @@ -9,6 +9,10 @@ struct smtp_client_transaction; struct smtp_client_transaction_mail; struct smtp_client_transaction_rcpt; +enum smtp_client_transaction_flags { + SMTP_CLIENT_TRANSACTION_FLAG_REPLY_PER_RCPT = BIT(0), +}; + enum smtp_client_transaction_state { SMTP_CLIENT_TRANSACTION_STATE_NEW = 0, SMTP_CLIENT_TRANSACTION_STATE_PENDING, @@ -36,25 +40,27 @@ smtp_client_transaction_callback_t(void *context); MAIL FROM command) */ struct smtp_client_transaction * smtp_client_transaction_create_empty( - struct smtp_client_connection *conn, unsigned int flags, + struct smtp_client_connection *conn, + enum smtp_client_transaction_flags flags, smtp_client_transaction_callback_t *callback, void *context) ATTR_NULL(4); -#define smtp_client_transaction_create_empty(conn, callback, context) \ - smtp_client_transaction_create_empty(conn, \ - 0 + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ +#define smtp_client_transaction_create_empty(conn, flags, callback, context) \ + smtp_client_transaction_create_empty(conn, flags + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (smtp_client_transaction_callback_t *)callback, context) /* Create a new transaction, including the parameters for the MAIL FROM command */ struct smtp_client_transaction * smtp_client_transaction_create(struct smtp_client_connection *conn, const struct smtp_address *mail_from, - const struct smtp_params_mail *mail_params, unsigned int flags, + const struct smtp_params_mail *mail_params, + enum smtp_client_transaction_flags flags, smtp_client_transaction_callback_t *callback, void *context) ATTR_NULL(2, 3, 6); #define smtp_client_transaction_create(conn, \ - mail_from, mail_params, callback, context) \ - smtp_client_transaction_create(conn, mail_from, mail_params, \ - 0 + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + mail_from, mail_params, flags, callback, context) \ + smtp_client_transaction_create(conn, mail_from, mail_params, flags + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (smtp_client_transaction_callback_t *)callback, context) void smtp_client_transaction_ref(struct smtp_client_transaction *trans); diff --git a/src/lib-smtp/smtp-submit.c b/src/lib-smtp/smtp-submit.c index dbdce28b1c..f6f8fe9459 100644 --- a/src/lib-smtp/smtp-submit.c +++ b/src/lib-smtp/smtp-submit.c @@ -316,7 +316,7 @@ smtp_submit_send_host(struct smtp_submit *subm) SMTP_PROTOCOL_SMTP, host, port, ssl_mode, NULL); smtp_trans = smtp_client_transaction_create(smtp_conn, - subm->mail_from, NULL, smtp_submit_send_host_finished, subm); + subm->mail_from, NULL, 0, smtp_submit_send_host_finished, subm); smtp_client_connection_unref(&smtp_conn); array_foreach(&subm->rcpt_to, rcptp) { diff --git a/src/lib-smtp/test-smtp-client-errors.c b/src/lib-smtp/test-smtp-client-errors.c index 7673916f22..9a31fff6d9 100644 --- a/src/lib-smtp/test-smtp-client-errors.c +++ b/src/lib-smtp/test-smtp-client-errors.c @@ -742,7 +742,7 @@ test_client_broken_payload( SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0], SMTP_CLIENT_SSL_MODE_NONE, NULL); strans = smtp_client_transaction_create(sconn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_broken_payload_finished, NULL); smtp_client_connection_unref(&sconn); @@ -801,7 +801,7 @@ test_client_broken_payload_later( SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[0], SMTP_CLIENT_SSL_MODE_NONE, NULL); strans = smtp_client_transaction_create(sconn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_broken_payload_finished, NULL); smtp_client_connection_unref(&sconn); @@ -1025,7 +1025,7 @@ test_client_connection_lost_submit(struct _connection_lost *ctx, SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index], SMTP_CLIENT_SSL_MODE_NONE, NULL); strans = smtp_client_transaction_create(sconn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_connection_lost_finished, pctx); smtp_client_connection_unref(&sconn); @@ -1360,7 +1360,7 @@ test_client_unexpected_reply_submit(struct _unexpected_reply *ctx, SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index], SMTP_CLIENT_SSL_MODE_NONE, NULL); pctx->trans = smtp_client_transaction_create(pctx->conn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_unexpected_reply_finished, pctx); smtp_client_connection_connect(pctx->conn, test_client_unexpected_reply_login_cb, (void *)pctx); @@ -2476,7 +2476,7 @@ test_client_authentication_failed_submit(struct _authentication_failed *ctx, SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index], SMTP_CLIENT_SSL_MODE_NONE, &smtp_set); pctx->trans = smtp_client_transaction_create(pctx->conn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_authentication_failed_finished, pctx); smtp_client_connection_connect(pctx->conn, test_client_authentication_failed_login_cb, (void *)pctx); @@ -2749,7 +2749,7 @@ test_client_transaction_timeout_submit(struct _transaction_timeout *ctx, SMTP_PROTOCOL_SMTP, net_ip2addr(&bind_ip), bind_ports[index], SMTP_CLIENT_SSL_MODE_NONE, NULL); pctx->trans = smtp_client_transaction_create(pctx->conn, - SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, + SMTP_ADDRESS_LITERAL("sender", "example.com"), NULL, 0, test_client_transaction_timeout_finished, pctx); smtp_client_transaction_set_timeout(pctx->trans, 1000); smtp_client_transaction_start(pctx->trans, diff --git a/src/lib-smtp/test-smtp-payload.c b/src/lib-smtp/test-smtp-payload.c index a3fe0137ca..e2d7260f64 100644 --- a/src/lib-smtp/test-smtp-payload.c +++ b/src/lib-smtp/test-smtp-payload.c @@ -727,7 +727,8 @@ static void test_client_continue(void *dummy ATTR_UNUSED) tctrans->trans = smtp_client_transaction_create(tctrans->conn, SMTP_ADDRESS_LITERAL("user", "example.com"), - &mail_params, test_client_transaction_finish, tctrans); + &mail_params, 0, + test_client_transaction_finish, tctrans); smtp_client_connection_unref(&tctrans->conn); rcpts = tctrans->files_idx % 10 + 1; diff --git a/src/lmtp/lmtp-proxy.c b/src/lmtp/lmtp-proxy.c index fdfd2b1303..0b317a9fb8 100644 --- a/src/lmtp/lmtp-proxy.c +++ b/src/lmtp/lmtp-proxy.c @@ -263,7 +263,7 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy, smtp_client_connection_connect(lmtp_conn, NULL, NULL); conn->lmtp_trans = smtp_client_transaction_create(lmtp_conn, - trans->mail_from, &trans->params, + trans->mail_from, &trans->params, 0, lmtp_proxy_connection_finish, conn); smtp_client_connection_unref(&lmtp_conn); diff --git a/src/submission/submission-backend-relay.c b/src/submission/submission-backend-relay.c index b1eb42f988..a3d107f61c 100644 --- a/src/submission/submission-backend-relay.c +++ b/src/submission/submission-backend-relay.c @@ -159,7 +159,7 @@ backend_relay_trans_start(struct submission_backend *_backend, if (backend->trans == NULL) { backend->trans_started = TRUE; backend->trans = smtp_client_transaction_create( - backend->conn, path, params, + backend->conn, path, params, 0, backend_relay_trans_finished, backend); smtp_client_transaction_set_immediate(backend->trans, TRUE); smtp_client_transaction_start( @@ -452,7 +452,7 @@ backend_relay_cmd_mail(struct submission_backend *_backend, /* start client transaction */ backend->trans_started = TRUE; backend->trans = smtp_client_transaction_create( - backend->conn, data->path, &data->params, + backend->conn, data->path, &data->params, 0, backend_relay_trans_finished, backend); smtp_client_transaction_set_immediate(backend->trans, TRUE); smtp_client_transaction_start(backend->trans, @@ -540,7 +540,8 @@ backend_relay_cmd_rcpt(struct submission_backend *_backend, if (backend->trans == NULL) { backend->trans = smtp_client_transaction_create_empty( - backend->conn, backend_relay_trans_finished, backend); + backend->conn, 0, + backend_relay_trans_finished, backend); smtp_client_transaction_set_immediate(backend->trans, TRUE); } rcpt_cmd->relay_rcpt = smtp_client_transaction_add_pool_rcpt(