b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#ifndef SMTP_CLIENT_PRIVATE_H
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#define SMTP_CLIENT_PRIVATE_H
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "connection.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-common.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-params.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-client.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-client-command.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-client-transaction.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#include "smtp-client-connection.h"
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#define SMTP_CLIENT_DATA_CHUNK_SIZE IO_BLOCK_SIZE
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct smtp_client_command {
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int refcount;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *prev, *next;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch buffer_t *data;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int send_pos;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const char *name;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_client_command_flags flags;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_client_command_state state;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int replies_expected;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int replies_seen;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct istream *stream;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch uoff_t stream_size;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void (*abort_callback)(void *context);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *abort_context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
11142fd53e4dcd6e54322dc40b6bd42753a8b304Stephan Bosch void (*sent_callback)(void *context);
11142fd53e4dcd6e54322dc40b6bd42753a8b304Stephan Bosch void *sent_context;
11142fd53e4dcd6e54322dc40b6bd42753a8b304Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool has_stream:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool stream_dot:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool ehlo:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool locked:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool plug:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool aborting:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch};
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct smtp_client_transaction_rcpt {
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_address *rcpt_to;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_params_rcpt rcpt_params;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *rcpt_callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *data_callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *cmd_rcpt_to;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool failed:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch};
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct smtp_client_transaction {
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch int refcount;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *prev, *next;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_address *mail_from;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_params_mail mail_params;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_client_transaction_state state;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *cmd_mail_from, *cmd_data;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *cmd_plug, *cmd_last;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_reply *failure;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *mail_from_callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *mail_from_context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch ARRAY(struct smtp_client_transaction_rcpt *) rcpts, rcpts_pending;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int rcpts_next_send_idx;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int rcpt_next_data_idx;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct istream *data_input;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *data_callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *data_context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_transaction_callback_t *callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction_times times;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int finish_timeout_msecs;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct timeout *to_finish, *to_send;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
85a18b9917057acd6f1f718541adc0c7d149f6eeStephan Bosch bool data_provided:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool finished:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool submitted_data:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch};
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct smtp_client_connection {
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct connection conn;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch int refcount;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client *client;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int id;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch char *label;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_protocol protocol;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const char *host;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch in_port_t port;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_client_connection_ssl_mode ssl_mode;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_settings set;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch char *password;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_capability capabilities;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t cap_pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const char **cap_auth_mechanisms;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const char **cap_xclient_args;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch uoff_t cap_size;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_reply_parser *reply_parser;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_reply reply;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct dns_lookup *dns_lookup;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct dsasl_client *sasl_client;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct timeout *to_connect, *to_trans, *to_commands;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct istream *raw_input;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct ostream *raw_output, *dot_output;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
5db9891a9dee031ee3e4dfb74c95d5136c5f771aStephan Bosch struct ssl_iostream_context *ssl_ctx;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct ssl_iostream *ssl_iostream;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch enum smtp_client_connection_state state;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch smtp_client_command_callback_t *login_callback;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch void *login_context;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch /* commands pending in queue to be sent */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *cmd_send_queue_head, *cmd_send_queue_tail;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int cmd_send_queue_count;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch /* commands that have been sent, waiting for response */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_command *cmd_wait_list_head, *cmd_wait_list_tail;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int cmd_wait_list_count;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch /* active transactions */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *transactions_head, *transactions_tail;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int ips_count, prev_connect_idx;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct ip_addr *ips;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool old_smtp:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool authenticated:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool initial_xclient_sent:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool connect_failed:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool handshake_failed:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool corked:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool sent_quit:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool sending_command:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool reset_needed:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool destroying:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch bool closed:1;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch};
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct smtp_client {
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch pool_t pool;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_settings set;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct ioloop *ioloop;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct ssl_iostream_context *ssl_ctx;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct connection_list *conn_list;
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch};
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch/*
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch * Command
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_command_free(struct smtp_client_command *cmd);
52cb7a947c02678218c5e4d859e03aa35d54cda9Stephan Boschint smtp_client_command_send_more(struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschint smtp_client_command_input_reply(struct smtp_client_command *cmd,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const struct smtp_reply *reply);
bd06411e6f2ffc9e0122824ba4edb774bb40c26fStephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_command_fail(struct smtp_client_command **_cmd,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int status, const char *error);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_command_fail_reply(struct smtp_client_command **_cmd,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const struct smtp_reply *reply);
2dd20833b86743fe1e45c5af06d9c5f2549126e3Stephan Bosch
2dd20833b86743fe1e45c5af06d9c5f2549126e3Stephan Boschvoid smtp_client_commands_list_abort(struct smtp_client_command *cmds_list,
2dd20833b86743fe1e45c5af06d9c5f2549126e3Stephan Bosch unsigned int cmds_list_count);
bd06411e6f2ffc9e0122824ba4edb774bb40c26fStephan Boschvoid smtp_client_commands_list_fail_reply(
bd06411e6f2ffc9e0122824ba4edb774bb40c26fStephan Bosch struct smtp_client_command *cmds_list, unsigned int cmds_list_count,
bd06411e6f2ffc9e0122824ba4edb774bb40c26fStephan Bosch const struct smtp_reply *reply);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch/*
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch * Transaction
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_transaction_connection_result(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch const struct smtp_reply *reply);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_transaction_switch_ioloop(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch/*
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch * Connection
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch */
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschstruct connection_list *smtp_client_connection_list_init(void);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschconst char *
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschsmpt_client_connection_label(struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_fail(struct smtp_client_connection *conn,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch unsigned int status, const char *error);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
a02b8d9eed3636518cc5ffce8d1045f9808f24e4Stephan Boschvoid smtp_client_connection_handle_output_error(
a02b8d9eed3636518cc5ffce8d1045f9808f24e4Stephan Bosch struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_trigger_output(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_start_cmd_timeout(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_update_cmd_timeout(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_add_transaction(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_abort_transaction(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Boschvoid smtp_client_connection_next_transaction(
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_connection *conn,
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch struct smtp_client_transaction *trans);
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch
419c83155744e62e690ae731b153c59314554826Stephan Bosch/*
419c83155744e62e690ae731b153c59314554826Stephan Bosch * Client
419c83155744e62e690ae731b153c59314554826Stephan Bosch */
419c83155744e62e690ae731b153c59314554826Stephan Bosch
419c83155744e62e690ae731b153c59314554826Stephan Boschint smtp_client_init_ssl_ctx(struct smtp_client *client, const char **error_r);
419c83155744e62e690ae731b153c59314554826Stephan Bosch
b3888944586654b4aa069e0db31f998e0ed8b414Stephan Bosch#endif