#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