1 #ifndef SMTP_CLIENT_PRIVATE_H 2 #define SMTP_CLIENT_PRIVATE_H 3 4 #include "connection.h" 5 6 #include "smtp-common.h" 7 #include "smtp-params.h" 8 #include "smtp-client.h" 9 #include "smtp-client-command.h" 10 #include "smtp-client-transaction.h" 11 #include "smtp-client-connection.h" 12 13 #define SMTP_CLIENT_BASE_LINE_LENGTH_LIMIT 512 14 #define SMTP_CLIENT_DATA_CHUNK_SIZE IO_BLOCK_SIZE 15 16 struct smtp_client_command { 17 pool_t pool; 18 int refcount; 19 struct event *event; 20 21 struct smtp_client_command *prev, *next; 22 23 buffer_t *data; 24 unsigned int send_pos; 25 const char *name; 26 27 enum smtp_client_command_flags flags; 28 29 struct smtp_client_connection *conn; 30 enum smtp_client_command_state state; 31 unsigned int replies_expected; 32 unsigned int replies_seen; 33 34 struct istream *stream; 35 uoff_t stream_size; 36 37 struct smtp_reply *delayed_failure; 38 39 smtp_client_command_callback_t *callback; 40 void *context; 41 42 void (*abort_callback)(void *context); 43 void *abort_context; 44 45 void (*sent_callback)(void *context); 46 void *sent_context; 47 48 bool has_stream:1; 49 bool stream_dot:1; 50 bool stream_finished:1; 51 bool ehlo:1; 52 bool locked:1; 53 bool plug:1; 54 bool failed:1; 55 bool aborting:1; 56 bool delay_failure:1; 57 bool delaying_failure:1; 58 bool event_finished:1; 59 }; 60 61 struct smtp_client_transaction_mail { 62 pool_t pool; 63 struct smtp_client_transaction *trans; 64 65 struct smtp_client_transaction_mail *prev, *next; 66 67 struct smtp_address *mail_from; 68 struct smtp_params_mail mail_params; 69 70 smtp_client_command_callback_t *mail_callback; 71 void *context; 72 73 struct smtp_client_command *cmd_mail_from; 74 }; 75 76 struct smtp_client_transaction_rcpt { 77 pool_t pool; 78 struct smtp_client_transaction *trans; 79 struct event *event; 80 81 struct smtp_client_transaction_rcpt *prev, *next; 82 83 struct smtp_address *rcpt_to; 84 struct smtp_params_rcpt rcpt_params; 85 86 smtp_client_command_callback_t *rcpt_callback; 87 void *context; 88 89 smtp_client_command_callback_t *data_callback; 90 void *data_context; 91 92 struct smtp_client_command *cmd_rcpt_to; 93 94 bool external_pool:1; 95 bool queued:1; 96 bool finished:1; 97 }; 98 99 struct smtp_client_transaction { 100 pool_t pool; 101 int refcount; 102 struct event *event; 103 104 struct smtp_client_transaction *prev, *next; 105 106 struct smtp_client_connection *conn; 107 enum smtp_client_transaction_flags flags; 108 109 enum smtp_client_transaction_state state; 110 struct smtp_client_command *cmd_data, *cmd_rset; 111 struct smtp_client_command *cmd_plug, *cmd_last; 112 struct smtp_reply *failure, *mail_failure, *data_failure; 113 114 struct smtp_client_transaction_mail *mail_head, *mail_tail; 115 struct smtp_client_transaction_mail *mail_send; 116 117 struct smtp_client_transaction_rcpt *rcpts_queue_head, *rcpts_queue_tail; 118 struct smtp_client_transaction_rcpt *rcpts_send; 119 struct smtp_client_transaction_rcpt *rcpts_head, *rcpts_tail; 120 struct smtp_client_transaction_rcpt *rcpts_data; 121 unsigned int rcpts_queue_count; 122 unsigned int rcpts_count; 123 124 unsigned int rcpts_total; 125 unsigned int rcpts_aborted; 126 unsigned int rcpts_denied; 127 unsigned int rcpts_failed; 128 unsigned int rcpts_succeeded; 129 130 struct istream *data_input; 131 smtp_client_command_callback_t *data_callback; 132 void *data_context; 133 134 smtp_client_command_callback_t *reset_callback; 135 void *reset_context; 136 137 smtp_client_transaction_callback_t *callback; 138 void *context; 139 140 struct smtp_client_transaction_times times; 141 142 unsigned int finish_timeout_msecs; 143 struct timeout *to_finish, *to_send; 144 145 bool immediate:1; 146 bool sender_accepted:1; 147 bool data_provided:1; 148 bool reset:1; 149 bool finished:1; 150 bool submitting:1; 151 bool failing:1; 152 bool submitted_data:1; 153 }; 154 155 struct smtp_client_login_callback { 156 smtp_client_command_callback_t *callback; 157 void *context; 158 }; 159 160 struct smtp_client_connection { 161 struct connection conn; 162 pool_t pool; 163 int refcount; 164 struct event *event; 165 166 struct smtp_client *client; 167 168 enum smtp_protocol protocol; 169 const char *path, *host; 170 in_port_t port; 171 enum smtp_client_connection_ssl_mode ssl_mode; 172 173 int connect_errno; 174 175 struct smtp_client_settings set; 176 char *password; 177 ARRAY(struct smtp_client_capability_extra) extra_capabilities; 178 179 pool_t cap_pool; 180 struct { 181 enum smtp_capability standard; 182 ARRAY(struct smtp_capability_extra) extra; 183 const char **auth_mechanisms; 184 const char **xclient_args; 185 uoff_t size; 186 187 /* Lists of custom MAIL/RCPT parameters supported by peer. These 188 arrays always end in NULL pointer once created. */ 189 ARRAY_TYPE(const_string) mail_param_extensions; 190 ARRAY_TYPE(const_string) rcpt_param_extensions; 191 } caps; 192 193 struct smtp_reply_parser *reply_parser; 194 struct smtp_reply reply; 195 unsigned int xclient_replies_expected; 196 197 struct dns_lookup *dns_lookup; 198 struct dsasl_client *sasl_client; 199 struct timeout *to_connect, *to_trans, *to_commands, *to_cmd_fail; 200 struct io *io_cmd_payload; 201 202 struct istream *raw_input; 203 struct ostream *raw_output, *dot_output; 204 205 struct ssl_iostream_context *ssl_ctx; 206 struct ssl_iostream *ssl_iostream; 207 208 enum smtp_client_connection_state state; 209 pool_t state_pool; 210 struct { 211 struct smtp_reply *login_reply; 212 } state_data; 213 214 ARRAY(struct smtp_client_login_callback) login_callbacks; 215 216 /* commands pending in queue to be sent */ 217 struct smtp_client_command *cmd_send_queue_head, *cmd_send_queue_tail; 218 unsigned int cmd_send_queue_count; 219 /* commands that have been (mostly) sent, waiting for response */ 220 struct smtp_client_command *cmd_wait_list_head, *cmd_wait_list_tail; 221 unsigned int cmd_wait_list_count; 222 /* commands that have failed before submission */ 223 struct smtp_client_command *cmd_fail_list; 224 /* command sending data stream */ 225 struct smtp_client_command *cmd_streaming; 226 227 /* active transactions */ 228 struct smtp_client_transaction *transactions_head, *transactions_tail; 229 230 unsigned int ips_count, prev_connect_idx; 231 struct ip_addr *ips; 232 233 bool host_is_ip:1; 234 bool old_smtp:1; 235 bool authenticated:1; 236 bool xclient_sent:1; 237 bool connect_failed:1; 238 bool connect_succeeded:1; 239 bool handshake_failed:1; 240 bool corked:1; 241 bool sent_quit:1; 242 bool sending_command:1; 243 bool reset_needed:1; 244 bool failing:1; 245 bool destroying:1; 246 bool closed:1; 247 }; 248 249 struct smtp_client { 250 pool_t pool; 251 252 struct smtp_client_settings set; 253 254 struct event *event; 255 struct ioloop *ioloop; 256 struct ssl_iostream_context *ssl_ctx; 257 258 struct connection_list *conn_list; 259 }; 260 261 /* 262 * Command 263 */ 264 265 void smtp_client_command_free(struct smtp_client_command *cmd); 266 int smtp_client_command_send_more(struct smtp_client_connection *conn); 267 int smtp_client_command_input_reply(struct smtp_client_command *cmd, 268 const struct smtp_reply *reply); 269 270 void smtp_client_command_drop_callback(struct smtp_client_command *cmd); 271 272 void smtp_client_command_fail(struct smtp_client_command **_cmd, 273 unsigned int status, const char *error); 274 void smtp_client_command_fail_reply(struct smtp_client_command **_cmd, 275 const struct smtp_reply *reply); 276 277 void smtp_client_commands_list_abort(struct smtp_client_command *cmds_list, 278 unsigned int cmds_list_count); 279 void smtp_client_commands_list_fail_reply( 280 struct smtp_client_command *cmds_list, unsigned int cmds_list_count, 281 const struct smtp_reply *reply); 282 283 void smtp_client_commands_abort_delayed(struct smtp_client_connection *conn); 284 void smtp_client_commands_fail_delayed(struct smtp_client_connection *conn); 285 286 /* 287 * Transaction 288 */ 289 290 void smtp_client_transaction_connection_result( 291 struct smtp_client_transaction *trans, 292 const struct smtp_reply *reply); 293 void smtp_client_transaction_connection_destroyed( 294 struct smtp_client_transaction *trans); 295 296 void smtp_client_transaction_switch_ioloop( 297 struct smtp_client_transaction *trans); 298 299 /* 300 * Connection 301 */ 302 303 struct connection_list *smtp_client_connection_list_init(void); 304 305 void smtp_client_connection_send_xclient(struct smtp_client_connection *conn); 306 307 void smtp_client_connection_fail(struct smtp_client_connection *conn, 308 unsigned int status, const char *error); 309 310 void smtp_client_connection_handle_output_error( 311 struct smtp_client_connection *conn); 312 void smtp_client_connection_trigger_output( 313 struct smtp_client_connection *conn); 314 315 void smtp_client_connection_start_cmd_timeout( 316 struct smtp_client_connection *conn); 317 void smtp_client_connection_update_cmd_timeout( 318 struct smtp_client_connection *conn); 319 320 void smtp_client_connection_add_transaction( 321 struct smtp_client_connection *conn, 322 struct smtp_client_transaction *trans); 323 void smtp_client_connection_abort_transaction( 324 struct smtp_client_connection *conn, 325 struct smtp_client_transaction *trans); 326 void smtp_client_connection_next_transaction( 327 struct smtp_client_connection *conn, 328 struct smtp_client_transaction *trans); 329 330 /* 331 * Client 332 */ 333 334 int smtp_client_init_ssl_ctx(struct smtp_client *client, const char **error_r); 335 336 #endif 337