smtp-server-connection.c revision 479f238c944ecf94f05008cf14e48225743c9feb
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenconst char *const smtp_server_state_names[] = {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid smtp_server_connection_debug(struct smtp_server_connection *conn,
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen const char *format, ...)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid smtp_server_connection_error(struct smtp_server_connection *conn,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const char *format, ...)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainensmtp_server_connection_input(struct connection *_conn);
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainensmtp_server_connection_output(struct smtp_server_connection *conn);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainensmtp_server_connection_disconnect(struct smtp_server_connection *conn,
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainensmtp_server_connection_update_stats(struct smtp_server_connection *conn)
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen conn->stats.input = conn->conn.input->v_offset;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen conn->stats.output = conn->conn.output->offset;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainensmtp_server_connection_get_stats(struct smtp_server_connection *conn)
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainenvoid smtp_server_connection_input_halt(struct smtp_server_connection *conn)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid smtp_server_connection_input_resume(struct smtp_server_connection *conn)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* only resume when we actually can */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (conn->input_locked || conn->input_broken ||
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* is queued command still blocking input? */
043c8a96a035379bcba04f487d58457beefdfcaaTimo Sirainen /* restore input handler */
043c8a96a035379bcba04f487d58457beefdfcaaTimo Sirainen conn->conn.io = io_add_istream(conn->conn.input,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid smtp_server_connection_input_lock(struct smtp_server_connection *conn)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid smtp_server_connection_input_unlock(struct smtp_server_connection *conn)
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainenvoid smtp_server_connection_input_capture(struct smtp_server_connection *conn,
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen smtp_server_input_callback_t *callback, void *context)
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen i_assert(!conn->input_broken && !conn->disconnected);
20b136f04257b0ba338e49f31a999c0d4b243647Timo Sirainen conn->conn.io = io_add_istream(conn->conn.input, *callback, context);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainensmtp_server_connection_update_rawlog(struct smtp_server_connection *conn)
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainensmtp_server_connection_streams_changed(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen smtp_command_parser_set_stream(conn->smtp_parser, conn->conn.input);
e22b857e838fe118de3f78513aad6a3c6f4306b3Timo Sirainen o_stream_set_flush_callback(conn->conn.output,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen o_stream_set_flush_pending(conn->conn.output, TRUE);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid smtp_server_connection_set_streams(struct smtp_server_connection *conn,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct istream *input, struct ostream *output)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen struct ostream *old_output = conn->conn.output;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen o_stream_set_no_error_handling(conn->conn.output, TRUE);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainensmtp_server_connection_idle_timeout(struct smtp_server_connection *conn)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid smtp_server_connection_timeout_stop(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen smtp_server_connection_debug(conn, "Timeout stop");
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenvoid smtp_server_connection_timeout_start(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen smtp_server_connection_debug(conn, "Timeout start");
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenvoid smtp_server_connection_timeout_reset(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainensmtp_server_connection_timeout_update(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct smtp_server_command *cmd = conn->command_queue_head;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* command updates timeout internally */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen case SMTP_SERVER_COMMAND_STATE_SUBMITTED_REPLY:
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen case SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY:
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainensmtp_server_connection_ready(struct smtp_server_connection *conn)
af3f857bb3166ed99595e11a9d18e5b5cc670e1aTimo Sirainen conn->smtp_parser = smtp_command_parser_init(conn->conn.input,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen o_stream_set_flush_callback(conn->conn.output,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* RFC 4954, Section 4:
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen Should the client successfully complete the exchange, the
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen SMTP server issues a 235 reply. */
ff01c351d308504551048039304725d578978c2eTimo Sirainen "235 2.7.0 Logged in.");
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (i_stream_get_data_size(conn->conn.input) > 0)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenstatic void smtp_server_connection_destroy(struct connection *_conn)
ff01c351d308504551048039304725d578978c2eTimo Sirainen smtp_server_connection_disconnect(conn, NULL);
ff01c351d308504551048039304725d578978c2eTimo Sirainensmtp_server_connection_handle_command(struct smtp_server_connection *conn,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen struct smtp_server_connection *tmp_conn = conn;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen cmd = smtp_server_command_new(tmp_conn, cmd_name, cmd_params);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (!smtp_server_connection_unref(&tmp_conn)) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* the command start callback managed to get this connection
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (cmd != NULL && conn->command_queue_head == cmd)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainenint smtp_server_connection_ssl_init(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen smtp_server_connection_debug(conn, "Starting SSL handshake");
ff01c351d308504551048039304725d578978c2eTimo Sirainen /* recreate rawlog after STARTTLS */
ff01c351d308504551048039304725d578978c2eTimo Sirainen "Couldn't initialize SSL server for %s: %s",
ff01c351d308504551048039304725d578978c2eTimo Sirainen if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen "SSL handshake failed: %s",
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen ssl_iostream_get_last_error(conn->ssl_iostream));
c9dea5c23355dea35c6fa423de69f6507852efe4Timo Sirainen conn->set.capabilities &= ~SMTP_CAPABILITY_STARTTLS;
ff01c351d308504551048039304725d578978c2eTimo Sirainensmtp_server_connection_handle_input(struct smtp_server_connection *conn)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* check whether we are continuing a command */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen pending_command = (conn->command_queue_tail->state ==
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* parse commands */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen while ((ret = smtp_command_parse_next(conn->smtp_parser,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen &cmd_name, &cmd_params, &error_code, &error)) > 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* previous command is now fully read and ready
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen smtp_server_command_ready_to_reply(pending_command);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen "Received new command: %s %s",
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* handle command
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen cmd may be destroyed after this */
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen if (!smtp_server_connection_handle_command(conn,
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen /* client indicated it will close after this command;
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen stop trying to read more. */
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen pending_command = (conn->command_queue_tail->state ==
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen int stream_errno = conn->conn.input->stream_errno;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen if (stream_errno != 0 && stream_errno != EPIPE &&
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "Connection lost: read(%s) failed: %s",
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "Read failure");
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen "Connection lost: Remote disconnected");
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen /* no pending commands; close */
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen "Remote closed connection");
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen /* unfinished command; close */
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen "Remote closed connection unexpectedly");
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen /* a command is still processing;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen only drop input io for now */
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen /* fall through */
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen /* Command data size exceeds the absolute limit;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen i.e. beyond which we don't even want to skip
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen data anymore. The command error is usually
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen already submitted by the application and sent
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen to the client. */
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen "Command data size exceeds absolute limit");
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen "Command data ended prematurely");
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen !smtp_command_parser_pending_data(conn->smtp_parser)) {
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen /* previous command is now fully read and ready to
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen smtp_server_command_ready_to_reply(pending_command);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void smtp_server_connection_input(struct connection *_conn)
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen if (conn->ssl_start && conn->ssl_iostream == NULL) {
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen if (smtp_server_connection_ssl_init(conn) < 0) {
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen "SSL Initialization failed");
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen conn->callbacks->conn_cmd_input_pre != NULL) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen conn->callbacks->conn_cmd_input_pre(conn->context);
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen conn->callbacks->conn_cmd_input_post != NULL) {
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen conn->callbacks->conn_cmd_input_post(conn->context);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenbool smtp_server_connection_pending_command_data(
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen return smtp_command_parser_pending_data(conn->smtp_parser);
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen * Command reply handling
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainensmtp_server_connection_next_reply(struct smtp_server_connection *conn)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen unsigned int i;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* no commands pending */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "No more commands pending");
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (cmd->state < SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen i_assert(cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY &&
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen /* send command replies */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen // FIXME: handle LMTP DATA command with enormous number of recipients;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen // i.e. don't keep filling output stream with replies indefinitely.
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen reply = array_idx_modifiable(&cmd->replies, i);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen cmd->state = SMTP_SERVER_COMMAND_STATE_PROCESSING;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen if (smtp_server_reply_send(reply, &error) < 0) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen "Write failure");
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "Failed to send reply: "
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "Remote disconnected");
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "Remote closed connection");
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen if (cmd->state == SMTP_SERVER_COMMAND_STATE_PROCESSING)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid smtp_server_connection_cork(struct smtp_server_connection *conn)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid smtp_server_connection_uncork(struct smtp_server_connection *conn)
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainensmtp_server_connection_send_replies(struct smtp_server_connection *conn)
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen /* send more replies until no more replies remain, the output
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen blocks again, or the connection is closed */
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen while (!conn->disconnected && smtp_server_connection_next_reply(conn));
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* accept more commands if possible */
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenint smtp_server_connection_flush(struct smtp_server_connection *conn)
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen "Connection lost: write(%s) failed: %s",
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen "Write failure");
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen "Connection lost: Remote disconnected");
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen "Remote closed connection unexpectedly");
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainensmtp_server_connection_output(struct smtp_server_connection *conn)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen "Sending replies");
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen if ((ret=smtp_server_connection_flush(conn)) > 0) {
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen if (!conn->corked && conn->conn.output != NULL)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen "Trigger output");
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen o_stream_set_flush_pending(conn->conn.output, TRUE);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstatic struct connection_settings smtp_server_connection_set = {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenstatic const struct connection_vfuncs smtp_server_connection_vfuncs = {
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen return connection_list_init(&smtp_server_connection_set,
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainenstatic struct smtp_server_connection * ATTR_NULL(5, 6)
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainensmtp_server_connection_alloc(struct smtp_server *server,
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen const struct smtp_server_settings *set, int fd_in, int fd_out,
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen const struct ip_addr *remote_ip, in_port_t remote_port,
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen const struct smtp_server_callbacks *callbacks, void *context)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen static unsigned int id = 0;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen pool = pool_alloconly_create("smtp server", 512);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen conn = p_new(pool, struct smtp_server_connection, 1);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* merge settings with global server settings */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0')
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen conn->set.rawlog_dir = p_strdup(pool, set->rawlog_dir);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen if (set->hostname != NULL && *set->hostname != '\0')
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen conn->set.hostname = p_strdup(pool, set->hostname);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen conn->set.max_bad_commands = set->max_bad_commands;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen smtp_command_limits_merge(&conn->set.command_limits,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen p_strarray_dup(pool, set->xclient_extensions);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen conn->set.auth_optional || set->auth_optional;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen conn->set.param_extensions || set->param_extensions;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen conn->set.debug = conn->set.debug || set->debug;
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen if (remote_ip != NULL && remote_ip->family != 0) {
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen } else if (fd_in != fd_out || net_getpeername(fd_in,
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen /* tty connection probably */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen /* ip / ip6 */
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_error("net_set_send_buffer_size(%"PRIuSIZE_T") failed: %m",
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_error("net_set_recv_buffer_size(%"PRIuSIZE_T") failed: %m",
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainenstatic const char *
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainensmtp_server_connection_get_name(struct smtp_server_connection *conn)
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen /* get a name for this connection */
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen name = t_strdup_printf("unix [%u]", conn->id);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen name = t_strdup_printf("unix:pid=%u,uid=%u [%u]",
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen conn->remote_pid, conn->remote_uid, conn->id);
a1761856683b4bf745eb4e32cefabeb851efb301Timo Sirainen net_ip2addr(&conn->remote_ip), conn->remote_port, conn->id);
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen net_ip2addr(&conn->remote_ip), conn->remote_port, conn->id);
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainensmtp_server_connection_create(struct smtp_server *server,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const struct ip_addr *remote_ip, in_port_t remote_port,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen const struct smtp_server_callbacks *callbacks, void *context)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* halt input until started */
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen smtp_server_connection_debug(conn, "Connection created");
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainensmtp_server_connection_create_from_streams(struct smtp_server *server,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen struct istream *input, struct ostream *output,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen const struct ip_addr *remote_ip, in_port_t remote_port,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen const struct smtp_server_callbacks *callbacks, void *context)
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen conn = smtp_server_connection_alloc(server, set,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen connection_init_from_streams(server->conn_list,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* halt input until started */
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen smtp_server_connection_debug(conn, "Connection created");
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainenvoid smtp_server_connection_ref(struct smtp_server_connection *conn)
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainenstatic const char *
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen const char *err;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen !ssl_iostream_is_handshaked(conn->ssl_iostream)) {
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen err = ssl_iostream_get_last_error(conn->ssl_iostream);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return io_stream_get_disconnect_reason(conn->conn.input,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainensmtp_server_connection_disconnect(struct smtp_server_connection *conn,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen reason = smtp_server_connection_get_disconnect_reason(conn);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen smtp_server_connection_debug(conn, "Disconnected: %s", reason);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* preserve statistics */
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen smtp_command_parser_deinit(&conn->smtp_parser);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen conn->callbacks->conn_disconnect(conn->context,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenbool smtp_server_connection_unref(struct smtp_server_connection **_conn)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen smtp_server_connection_disconnect(conn, NULL);
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen smtp_server_connection_debug(conn, "Connection destroy");
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen /* drop transaction */
return FALSE;
const char *fmt, ...)
T_BEGIN {
} T_END;
T_BEGIN {
} T_END;
bool ssl_start)
if (ssl_start)
bool ssl_secured)
if (pdata_len > 0) {
const char *reason)
struct smtp_server_helo_data *
enum smtp_server_state
return NULL;
return FALSE;
enum smtp_protocol
case SMTP_PROTOCOL_SMTP:
case SMTP_PROTOCOL_LMTP:
i_unreached();
struct smtp_server_transaction *
return NULL;