]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-smtp: client: Allow enabling the LMTP per-RCPT DATA reply behavior for ESMTP...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Thu, 18 Oct 2018 00:15:07 +0000 (02:15 +0200)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Mon, 29 Oct 2018 16:42:52 +0000 (17:42 +0100)
This is non-standard.

src/lib-smtp/smtp-client-private.h
src/lib-smtp/smtp-client-transaction.c
src/lib-smtp/smtp-client-transaction.h
src/lib-smtp/smtp-submit.c
src/lib-smtp/test-smtp-client-errors.c
src/lib-smtp/test-smtp-payload.c
src/lmtp/lmtp-proxy.c
src/submission/submission-backend-relay.c

index 5f5da079673eee65abb33e196b06ca6fefd028cd..9c3d45a82c06b41f3263e06c840740699b33836f 100644 (file)
@@ -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;
index 28e457170ddd861fce6823ca5137b4253ae582d9..f882f43d0bd196d2e66ad4773640927bc8e92959 100644 (file)
@@ -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);
                }
index d5f88ff2d46426a51a58bd542642ac22c8fbd01c..06399ec25f1663f767c6a3c1cf749d32a17d0aec 100644 (file)
@@ -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);
index dbdce28b1c92ae4e004fd343195f5c34b9830cb4..f6f8fe94599a43223d952434d244e30ceac26507 100644 (file)
@@ -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) {
index 7673916f2241e602dcc0f2d4d3391812b84dc6d3..9a31fff6d9719cd69f36f62262952608edc56461 100644 (file)
@@ -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,
index a3fe0137ca71cf498f30aa3338f4367ed494709d..e2d7260f6411d12b3a23d54070daea0247e6c76a 100644 (file)
@@ -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;
index fdfd2b13039a21aac1c15814f43a147bc659a1f2..0b317a9fb8d01239e6266d69efad5117f0b85ff4 100644 (file)
@@ -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);
 
index b1eb42f988f5358ae1c92f94a1729bd7f1b6bb05..a3d107f61caca9d47e8aac09c9af62fda61c7ecc 100644 (file)
@@ -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(