lmtp-proxy.c revision e298a331a43bf0073b5209233fce2f021021f80d
/* Copyright (c) 2009-2015 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "istream-sized.h"
#include "ostream.h"
#include "str.h"
#include "time-util.h"
#include "lmtp-client.h"
#include "lmtp-proxy.h"
#define LMTP_MAX_LINE_LEN 1024
struct lmtp_proxy_recipient {
struct lmtp_proxy_connection *conn;
const char *address;
const char *reply;
unsigned int idx;
unsigned int rcpt_to_failed:1;
unsigned int data_reply_received:1;
};
struct lmtp_proxy_connection {
struct lmtp_proxy *proxy;
struct lmtp_proxy_rcpt_settings set;
struct lmtp_client *client;
struct istream *data_input;
unsigned int finished:1;
unsigned int failed:1;
};
struct lmtp_proxy {
const char *mail_from;
struct lmtp_proxy_settings set;
unsigned int next_data_reply_idx;
struct istream *data_input;
struct ostream *client_output;
unsigned int max_timeout_msecs;
void *finish_context;
unsigned int finished:1;
};
static void lmtp_conn_finish(void *context);
struct lmtp_proxy *
struct ostream *client_output)
{
struct lmtp_proxy *proxy;
return proxy;
}
{
struct lmtp_proxy_connection *const *conns;
}
}
{
}
{
}
static struct lmtp_proxy_connection *
const struct lmtp_proxy_rcpt_settings *set)
{
struct lmtp_client_settings client_set;
return conn;
}
return conn;
}
{
struct lmtp_proxy_recipient *const *rcpt;
unsigned int i, count;
break;
}
proxy->next_data_reply_idx = i;
return i == count;
}
{
}
{
/* DATA command hasn't been sent yet */
return;
}
if (!lmtp_proxy_send_data_replies(proxy)) {
/* we can't received reply from all clients yet */
return;
}
/* do the actual finishing in a timeout handler, since the finish
callback causes the proxy to be destroyed and the code leading up
to this function can be called from many different places. it's
easier this way rather than having all the callers check if the
proxy was already destroyed. */
proxy);
}
}
static void lmtp_conn_finish(void *context)
{
}
static void
{
}
static void
{
const struct lmtp_client_times *times =
/* reset timeout in case there are a lot of RCPT TOs */
switch (result) {
case LMTP_CLIENT_RESULT_OK:
break;
break;
}
switch (result) {
case LMTP_CLIENT_RESULT_OK:
/* the problem isn't with the proxy, it's with the remote side.
so the remote side will log an error, while for us this is
just an info event */
break;
break;
}
}
const struct lmtp_proxy_rcpt_settings *set)
{
struct lmtp_proxy_connection *conn;
struct lmtp_proxy_recipient *rcpt;
return -1;
return 0;
}
{
const char *line;
" (timeout while waiting for reply to %s) <%s>",
}
{
struct lmtp_proxy_connection *const *conns;
i_error("i_stream_get_size(data_input) failed: %s",
}
/* create the data_input streams first */
/* this connection had already failed */
continue;
}
else
}
/* now that all the streams are created, start reading them
(reading them earlier could have caused the data_input parent's
offset to change) */
}
}
/* finish if all of the connections have already failed */
}