From 3f2f5e03534271a3c5e1d7d3592e55bc36b50fc3 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Tue, 31 Oct 2017 01:12:44 +0100 Subject: [PATCH] lmtp: proxy: Restructured proxy so that it has direct access to struct client. This avoids the hassle of initializing using struct lmtp_proxy_settings and uselessly reallocating stuff that is already persisted in struct client. Moved the proxy from alloconly pool to default pool in the process. The amount of allocated stuff will diminish further in subsequent commits. --- src/lmtp/lmtp-proxy.c | 138 +++++++++++++++++++----------------------- src/lmtp/lmtp-proxy.h | 10 --- 2 files changed, 62 insertions(+), 86 deletions(-) diff --git a/src/lmtp/lmtp-proxy.c b/src/lmtp/lmtp-proxy.c index 8637be7187..21aad788de 100644 --- a/src/lmtp/lmtp-proxy.c +++ b/src/lmtp/lmtp-proxy.c @@ -37,8 +37,8 @@ struct lmtp_proxy_rcpt_settings { struct lmtp_proxy_recipient { struct lmtp_proxy_connection *conn; - const struct smtp_address *address; - const char *reply; + struct smtp_address *address; + char *reply; unsigned int idx; bool rcpt_to_failed:1; @@ -48,6 +48,7 @@ struct lmtp_proxy_recipient { struct lmtp_proxy_connection { struct lmtp_proxy *proxy; struct lmtp_proxy_rcpt_settings set; + char *host; struct smtp_client_transaction *lmtp_trans; struct istream *data_input; @@ -58,10 +59,8 @@ struct lmtp_proxy_connection { }; struct lmtp_proxy { - pool_t pool; - const struct smtp_address *mail_from; - struct smtp_params_mail mail_params; - struct lmtp_proxy_settings set; + struct client *client; + struct smtp_server_transaction *trans; struct smtp_client *lmtp_client; @@ -72,7 +71,6 @@ struct lmtp_proxy { struct timeout *to_finish; struct istream *data_input; - struct ostream *client_output; unsigned int max_timeout_msecs; @@ -92,79 +90,74 @@ lmtp_proxy_data_cb(const struct smtp_reply *reply, */ static struct lmtp_proxy * -lmtp_proxy_init(const struct lmtp_proxy_settings *set, - struct ostream *client_output) +lmtp_proxy_init(struct client *client) { struct smtp_client_settings lmtp_set; struct lmtp_proxy *proxy; - pool_t pool; - - i_assert(set->proxy_ttl > 0); - o_stream_ref(client_output); - - pool = pool_alloconly_create("lmtp proxy", 1024); - proxy = p_new(pool, struct lmtp_proxy, 1); - proxy->pool = pool; - proxy->client_output = client_output; - proxy->set.my_hostname = p_strdup(pool, set->my_hostname); - proxy->set.session_id = p_strdup(pool, set->session_id); - proxy->set.source_ip = set->source_ip; - proxy->set.source_port = set->source_port; - proxy->set.proxy_ttl = set->proxy_ttl; + + i_assert(client->proxy_ttl > 1); + + proxy = i_new(struct lmtp_proxy, 1); + proxy->client = client; i_array_init(&proxy->rcpt_to, 32); i_array_init(&proxy->connections, 32); i_zero(&lmtp_set); - lmtp_set.my_hostname = set->my_hostname; + lmtp_set.my_hostname = client->my_domain; lmtp_set.dns_client_socket_path = dns_client_socket_path; - lmtp_set.proxy_data.source_ip = set->source_ip; - lmtp_set.proxy_data.source_port = set->source_port; - lmtp_set.proxy_data.ttl_plus_1 = set->proxy_ttl; + lmtp_set.proxy_data.source_ip = client->remote_ip; + lmtp_set.proxy_data.source_port = client->remote_port; + lmtp_set.proxy_data.ttl_plus_1 = client->proxy_ttl + 1; if (lmtp_set.proxy_data.ttl_plus_1 == 0) lmtp_set.proxy_data.ttl_plus_1 = LMTP_PROXY_DEFAULT_TTL + 1; else lmtp_set.proxy_data.ttl_plus_1--; proxy->lmtp_client = smtp_client_init(&lmtp_set); + return proxy; } -static void lmtp_proxy_connections_deinit(struct lmtp_proxy *proxy) +static void +lmtp_proxy_recipient_deinit(struct lmtp_proxy_recipient *rcpt) { - struct lmtp_proxy_connection *const *conns; - - array_foreach(&proxy->connections, conns) { - struct lmtp_proxy_connection *conn = *conns; + i_free(rcpt->address); + i_free(rcpt->reply); + i_free(rcpt); +} - if (conn->lmtp_trans != NULL) - smtp_client_transaction_destroy(&conn->lmtp_trans); - } +static void +lmtp_proxy_connection_deinit(struct lmtp_proxy_connection *conn) +{ + if (conn->lmtp_trans != NULL) + smtp_client_transaction_destroy(&conn->lmtp_trans); + timeout_remove(&conn->to); + i_stream_unref(&conn->data_input); + i_free(conn->host); + i_free(conn); } void lmtp_proxy_deinit(struct lmtp_proxy **_proxy) { struct lmtp_proxy *proxy = *_proxy; + struct lmtp_proxy_recipient *const *rcpts; + struct lmtp_proxy_connection *const *conns; *_proxy = NULL; - lmtp_proxy_connections_deinit(proxy); + array_foreach(&proxy->rcpt_to, rcpts) + lmtp_proxy_recipient_deinit(*rcpts); + + array_foreach(&proxy->connections, conns) + lmtp_proxy_connection_deinit(*conns); + smtp_client_deinit(&proxy->lmtp_client); i_stream_unref(&proxy->data_input); - o_stream_unref(&proxy->client_output); timeout_remove(&proxy->to_finish); array_free(&proxy->rcpt_to); array_free(&proxy->connections); - pool_unref(&proxy->pool); -} - -static void -lmtp_proxy_mail_from(struct lmtp_proxy *proxy, - const struct smtp_address *address, - const struct smtp_params_mail *params) -{ - proxy->mail_from = smtp_address_clone(proxy->pool, address); - smtp_params_mail_copy(proxy->pool, &proxy->mail_params, params); + i_free(proxy); } static void @@ -177,17 +170,19 @@ lmtp_proxy_mail_cb(const struct smtp_reply *proxy_reply ATTR_UNUSED, static void lmtp_proxy_connection_finish(struct lmtp_proxy_connection *conn) { + struct lmtp_proxy *proxy = conn->proxy; + conn->finished = TRUE; conn->lmtp_trans = NULL; - timeout_remove(&conn->to); - i_stream_unref(&conn->data_input); - lmtp_proxy_try_finish(conn->proxy); + + lmtp_proxy_try_finish(proxy); } static struct lmtp_proxy_connection * lmtp_proxy_get_connection(struct lmtp_proxy *proxy, const struct lmtp_proxy_rcpt_settings *set) { + struct client *client = proxy->client; struct smtp_client_connection *lmtp_conn; struct lmtp_proxy_connection *const *conns, *conn; const char *host = (set->hostip.family == 0 ? @@ -204,11 +199,12 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy, return conn; } - conn = p_new(proxy->pool, struct lmtp_proxy_connection, 1); + conn = i_new(struct lmtp_proxy_connection, 1); conn->proxy = proxy; conn->set.protocol = set->protocol; conn->set.hostip = set->hostip; - conn->set.host = p_strdup(proxy->pool, host); + conn->host = i_strdup(host); + conn->set.host = conn->host; conn->set.port = set->port; conn->set.timeout_msecs = set->timeout_msecs; array_append(&proxy->connections, &conn, 1); @@ -219,7 +215,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, - proxy->mail_from, &proxy->mail_params, + client->state.mail_from, &client->state.mail_params, lmtp_proxy_connection_finish, conn); smtp_client_connection_unref(&lmtp_conn); @@ -233,18 +229,19 @@ lmtp_proxy_get_connection(struct lmtp_proxy *proxy, static bool lmtp_proxy_send_data_replies(struct lmtp_proxy *proxy) { + struct client *client = proxy->client; struct lmtp_proxy_recipient *const *rcpt; unsigned int i, count; - o_stream_cork(proxy->client_output); + o_stream_cork(client->output); rcpt = array_get(&proxy->rcpt_to, &count); for (i = proxy->next_data_reply_idx; i < count; i++) { if (!(rcpt[i]->rcpt_to_failed || rcpt[i]->data_reply_received)) break; - o_stream_nsend_str(proxy->client_output, + o_stream_nsend_str(client->output, t_strconcat(rcpt[i]->reply, "\r\n", NULL)); } - o_stream_uncork(proxy->client_output); + o_stream_uncork(client->output); proxy->next_data_reply_idx = i; return i == count; @@ -411,7 +408,6 @@ static void lmtp_proxy_rcpt_cb(const struct smtp_reply *proxy_reply, struct lmtp_proxy_recipient *rcpt) { - struct lmtp_proxy_connection *conn = rcpt->conn; string_t *reply; i_assert(rcpt->reply == NULL); @@ -419,7 +415,7 @@ lmtp_proxy_rcpt_cb(const struct smtp_reply *proxy_reply, reply = t_str_new(128); lmtp_proxy_write_reply(reply, proxy_reply); - rcpt->reply = p_strdup(conn->proxy->pool, str_c(reply)); + rcpt->reply = i_strdup(str_c(reply)); rcpt->rcpt_to_failed = !smtp_reply_is_success(proxy_reply); } @@ -522,20 +518,9 @@ int lmtp_proxy_rcpt(struct client *client, pool_unref(&auth_pool); return -1; } - if (client->proxy == NULL) { - struct lmtp_proxy_settings proxy_set; - - i_zero(&proxy_set); - proxy_set.my_hostname = client->my_domain; - proxy_set.session_id = client->state.session_id; - proxy_set.source_ip = client->remote_ip; - proxy_set.source_port = client->remote_port; - proxy_set.proxy_ttl = client->proxy_ttl-1; - - client->proxy = lmtp_proxy_init(&proxy_set, client->output); - lmtp_proxy_mail_from(client->proxy, client->state.mail_from, - &client->state.mail_params); - } + + if (client->proxy == NULL) + client->proxy = lmtp_proxy_init(client); conn = lmtp_proxy_get_connection(client->proxy, &set); if (conn->failed) { @@ -545,10 +530,10 @@ int lmtp_proxy_rcpt(struct client *client, return -1; } - rcpt = p_new(client->proxy->pool, struct lmtp_proxy_recipient, 1); + rcpt = i_new(struct lmtp_proxy_recipient, 1); rcpt->idx = array_count(&client->proxy->rcpt_to); rcpt->conn = conn; - rcpt->address = smtp_address_clone(client->proxy->pool, address); + rcpt->address = smtp_address_clone(default_pool, address); array_append(&client->proxy->rcpt_to, &rcpt, 1); smtp_client_transaction_add_rcpt(conn->lmtp_trans, @@ -569,6 +554,7 @@ lmtp_proxy_data_cb(const struct smtp_reply *proxy_reply, struct lmtp_proxy_recipient *rcpt) { struct lmtp_proxy_connection *conn = rcpt->conn; + struct client *client = conn->proxy->client; const struct smtp_client_transaction_times *times = smtp_client_transaction_get_times(conn->lmtp_trans); string_t *reply; @@ -584,11 +570,11 @@ lmtp_proxy_data_cb(const struct smtp_reply *proxy_reply, reply = t_str_new(128); lmtp_proxy_write_reply(reply, proxy_reply); - rcpt->reply = p_strdup(conn->proxy->pool, str_c(reply)); + rcpt->reply = i_strdup(str_c(reply)); rcpt->data_reply_received = TRUE; msg = t_str_new(128); - str_printfa(msg, "%s: ", conn->proxy->set.session_id); + str_printfa(msg, "%s: ", client->state.session_id); if (smtp_reply_is_success(proxy_reply)) str_append(msg, "Sent message to"); else diff --git a/src/lmtp/lmtp-proxy.h b/src/lmtp/lmtp-proxy.h index f2e83780dc..6e7ff10446 100644 --- a/src/lmtp/lmtp-proxy.h +++ b/src/lmtp/lmtp-proxy.h @@ -12,16 +12,6 @@ struct smtp_address; struct lmtp_proxy; struct client; -struct lmtp_proxy_settings { - const char *my_hostname; - const char *session_id; - - /* the original client's IP/port that connected to the proxy */ - struct ip_addr source_ip; - in_port_t source_port; - unsigned int proxy_ttl; -}; - typedef void lmtp_proxy_finish_callback_t(void *context); void lmtp_proxy_deinit(struct lmtp_proxy **proxy);