Current File : //usr/local/apps/dovecot/include/dovecot/smtp-client-private.h |
#ifndef SMTP_CLIENT_PRIVATE_H
#define SMTP_CLIENT_PRIVATE_H
#include "connection.h"
#include "smtp-common.h"
#include "smtp-params.h"
#include "smtp-client.h"
#include "smtp-client-command.h"
#include "smtp-client-transaction.h"
#include "smtp-client-connection.h"
#define SMTP_CLIENT_DATA_CHUNK_SIZE IO_BLOCK_SIZE
struct smtp_client_command {
pool_t pool;
int refcount;
struct event *event;
struct smtp_client_command *prev, *next;
buffer_t *data;
unsigned int send_pos;
const char *name;
enum smtp_client_command_flags flags;
struct smtp_client_connection *conn;
enum smtp_client_command_state state;
unsigned int replies_expected;
unsigned int replies_seen;
struct istream *stream;
uoff_t stream_size;
struct smtp_reply *delayed_failure;
smtp_client_command_callback_t *callback;
void *context;
void (*abort_callback)(void *context);
void *abort_context;
void (*sent_callback)(void *context);
void *sent_context;
bool has_stream:1;
bool stream_dot:1;
bool stream_finished:1;
bool ehlo:1;
bool locked:1;
bool plug:1;
bool failed:1;
bool aborting:1;
bool delay_failure:1;
bool delaying_failure:1;
bool event_finished:1;
};
struct smtp_client_transaction_mail {
pool_t pool;
struct smtp_client_transaction *trans;
struct smtp_client_transaction_mail *prev, *next;
struct smtp_address *mail_from;
struct smtp_params_mail mail_params;
smtp_client_command_callback_t *mail_callback;
void *context;
struct smtp_client_command *cmd_mail_from;
};
struct smtp_client_transaction_rcpt {
pool_t pool;
struct smtp_client_transaction *trans;
struct event *event;
struct smtp_client_transaction_rcpt *prev, *next;
struct smtp_address *rcpt_to;
struct smtp_params_rcpt rcpt_params;
smtp_client_command_callback_t *rcpt_callback;
void *context;
smtp_client_command_callback_t *data_callback;
void *data_context;
struct smtp_client_command *cmd_rcpt_to;
bool external_pool:1;
bool queued:1;
bool finished:1;
};
struct smtp_client_transaction {
pool_t pool;
int refcount;
struct event *event;
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;
struct smtp_client_command *cmd_plug, *cmd_last;
struct smtp_reply *failure, *mail_failure, *data_failure;
struct smtp_client_transaction_mail *mail_head, *mail_tail;
struct smtp_client_transaction_mail *mail_send;
struct smtp_client_transaction_rcpt *rcpts_queue_head, *rcpts_queue_tail;
struct smtp_client_transaction_rcpt *rcpts_send;
struct smtp_client_transaction_rcpt *rcpts_head, *rcpts_tail;
struct smtp_client_transaction_rcpt *rcpts_data;
unsigned int rcpts_queue_count;
unsigned int rcpts_count;
unsigned int rcpts_total;
unsigned int rcpts_aborted;
unsigned int rcpts_denied;
unsigned int rcpts_failed;
unsigned int rcpts_succeeded;
struct istream *data_input;
smtp_client_command_callback_t *data_callback;
void *data_context;
smtp_client_command_callback_t *reset_callback;
void *reset_context;
smtp_client_transaction_callback_t *callback;
void *context;
struct smtp_client_transaction_times times;
unsigned int finish_timeout_msecs;
struct timeout *to_finish, *to_send;
bool immediate:1;
bool sender_accepted:1;
bool data_provided:1;
bool reset:1;
bool finished:1;
bool submitting:1;
bool failing:1;
bool submitted_data:1;
};
struct smtp_client_login_callback {
smtp_client_command_callback_t *callback;
void *context;
};
struct smtp_client_connection {
struct connection conn;
pool_t pool;
int refcount;
struct event *event;
struct smtp_client *client;
enum smtp_protocol protocol;
const char *path, *host;
in_port_t port;
enum smtp_client_connection_ssl_mode ssl_mode;
int connect_errno;
struct smtp_client_settings set;
char *password;
ARRAY(struct smtp_client_capability_extra) extra_capabilities;
pool_t cap_pool;
struct {
enum smtp_capability standard;
ARRAY(struct smtp_capability_extra) extra;
const char **auth_mechanisms;
const char **xclient_args;
uoff_t size;
/* Lists of custom MAIL/RCPT parameters supported by peer. These
arrays always end in NULL pointer once created. */
ARRAY_TYPE(const_string) mail_param_extensions;
ARRAY_TYPE(const_string) rcpt_param_extensions;
} caps;
struct smtp_reply_parser *reply_parser;
struct smtp_reply reply;
unsigned int xclient_replies_expected;
struct dns_lookup *dns_lookup;
struct dsasl_client *sasl_client;
char *sasl_ir;
struct smtp_client_command *cmd_auth;
struct timeout *to_connect, *to_trans, *to_commands, *to_cmd_fail;
struct io *io_cmd_payload;
struct istream *raw_input;
struct ostream *raw_output, *dot_output;
struct ssl_iostream_context *ssl_ctx;
struct ssl_iostream *ssl_iostream;
enum smtp_client_connection_state state;
pool_t state_pool;
struct {
struct smtp_reply *login_reply;
} state_data;
ARRAY(struct smtp_client_login_callback) login_callbacks;
/* commands pending in queue to be sent */
struct smtp_client_command *cmd_send_queue_head, *cmd_send_queue_tail;
unsigned int cmd_send_queue_count;
/* commands that have been (mostly) sent, waiting for response */
struct smtp_client_command *cmd_wait_list_head, *cmd_wait_list_tail;
unsigned int cmd_wait_list_count;
/* commands that have failed before submission */
struct smtp_client_command *cmd_fail_list;
/* command sending data stream */
struct smtp_client_command *cmd_streaming;
/* active transactions */
struct smtp_client_transaction *transactions_head, *transactions_tail;
unsigned int ips_count, prev_connect_idx;
struct ip_addr *ips;
bool host_is_ip:1;
bool old_smtp:1;
bool authenticated:1;
bool xclient_sent:1;
bool connect_failed:1;
bool connect_succeeded:1;
bool handshake_failed:1;
bool corked:1;
bool sent_quit:1;
bool sending_command:1;
bool reset_needed:1;
bool failing:1;
bool destroying:1;
bool closed:1;
};
struct smtp_client {
pool_t pool;
struct smtp_client_settings set;
struct event *event;
struct ioloop *ioloop;
struct ssl_iostream_context *ssl_ctx;
struct connection_list *conn_list;
};
/*
* Command
*/
void smtp_client_command_free(struct smtp_client_command *cmd);
int smtp_client_command_send_more(struct smtp_client_connection *conn);
int smtp_client_command_input_reply(struct smtp_client_command *cmd,
const struct smtp_reply *reply);
void smtp_client_command_drop_callback(struct smtp_client_command *cmd);
void smtp_client_command_fail(struct smtp_client_command **_cmd,
unsigned int status, const char *error);
void smtp_client_command_fail_reply(struct smtp_client_command **_cmd,
const struct smtp_reply *reply);
void smtp_client_commands_list_abort(struct smtp_client_command *cmds_list,
unsigned int cmds_list_count);
void smtp_client_commands_list_fail_reply(
struct smtp_client_command *cmds_list, unsigned int cmds_list_count,
const struct smtp_reply *reply);
void smtp_client_commands_abort_delayed(struct smtp_client_connection *conn);
void smtp_client_commands_fail_delayed(struct smtp_client_connection *conn);
/*
* Transaction
*/
void smtp_client_transaction_connection_result(
struct smtp_client_transaction *trans,
const struct smtp_reply *reply);
void smtp_client_transaction_connection_destroyed(
struct smtp_client_transaction *trans);
void smtp_client_transaction_switch_ioloop(
struct smtp_client_transaction *trans);
/*
* Connection
*/
struct connection_list *smtp_client_connection_list_init(void);
void smtp_client_connection_send_xclient(struct smtp_client_connection *conn);
void smtp_client_connection_fail(struct smtp_client_connection *conn,
unsigned int status, const char *error,
const char *user_error) ATTR_NULL(3);
void smtp_client_connection_handle_output_error(
struct smtp_client_connection *conn);
void smtp_client_connection_trigger_output(
struct smtp_client_connection *conn);
void smtp_client_connection_start_cmd_timeout(
struct smtp_client_connection *conn);
void smtp_client_connection_update_cmd_timeout(
struct smtp_client_connection *conn);
void smtp_client_connection_add_transaction(
struct smtp_client_connection *conn,
struct smtp_client_transaction *trans);
void smtp_client_connection_abort_transaction(
struct smtp_client_connection *conn,
struct smtp_client_transaction *trans);
void smtp_client_connection_next_transaction(
struct smtp_client_connection *conn,
struct smtp_client_transaction *trans);
/*
* Client
*/
int smtp_client_init_ssl_ctx(struct smtp_client *client, const char **error_r);
#endif