connection.c revision ddaf416216a83e71bc1bfc1b6faf2ead9d774613
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
01230de017cd273de41143d88e9c18df1243ae8aTimo Sirainenstatic void connection_idle_timeout(struct connection *conn)
1f9d1bedae25d86f26c239055c5487499dfeeb58Timo Sirainen conn->disconnect_reason = CONNECTION_DISCONNECT_IDLE_TIMEOUT;
f37ecd72aad9b806aae83f71bacafdce32146945Timo Sirainenstatic void connection_connect_timeout(struct connection *conn)
e2bdca8201e4aa1cd31332ffbdd4c6eef9151d5eTimo Sirainen conn->disconnect_reason = CONNECTION_DISCONNECT_CONNECT_TIMEOUT;
32b78da5dfbbf6a06b3dbdc9278c60b55714f9bcTimo Sirainenvoid connection_input_default(struct connection *conn)
f7423cbbd9dea363a5df18ebb96da055a977ae79Timo Sirainen case 0: /* allow calling this function for buffered input */
4d4d6d4745682790c20d759ba93dbea46b812c5dTimo Sirainen while (!input->closed && (line = i_stream_next_line(input)) != NULL) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen conn->disconnect_reason = CONNECTION_DISCONNECT_DEINIT;
d6b3cfd855c0eebed68be50d3111de1b5a6afeb0Timo Sirainenint connection_verify_version(struct connection *conn,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *const *args)
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen /* VERSION <tab> service_name <tab> major version <tab> minor version */
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen str_to_uint(args[2], &recv_major_version) < 0 ||
e0740628f6ca05f4bc79a9d8a90b650f4d38d4d0Timo Sirainen str_to_uint(args[3], &conn->minor_version) < 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_error("%s didn't reply with a valid VERSION line: %s",
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen if (strcmp(args[1], conn->list->set.service_name_in) != 0) {
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen i_error("%s: Connected to wrong socket type. "
86791365b10f45982c88e70f2eb94fd6c3fea151Timo Sirainen "We want '%s', but received '%s'", conn->name,
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen if (recv_major_version != conn->list->set.major_version) {
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen i_error("%s: Socket supports major version %u, "
ccf50662cc02b5e703039a4ff7f91a4470e25b71Timo Sirainen "but we support only %u (mixed old and new binaries?)",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenint connection_input_line_default(struct connection *conn, const char *line)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char *const *args;
1ffb2afe6d7e8860a2231a4827078cf2ef9c22cdTimo Sirainen if (connection_verify_version(conn, args) < 0)
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen if (args[0] == NULL && !conn->list->set.allow_empty_args_input) {
0161376aac025266d8654577c4b9ce371ffc87eaTimo Sirainen i_error("%s: Unexpectedly received empty line", conn->name);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic void connection_init_streams(struct connection *conn)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct connection_settings *set = &conn->list->set;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen conn->version_received = set->major_version == 0;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen conn->input = i_stream_create_unix(conn->fd_in,
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen conn->io = io_add_istream(conn->input, *conn->list->v.input, conn);
275385a2ecc58e41dc7df3ce3cd943caaa58c4d1Timo Sirainen conn->io = io_add(conn->fd_in, IO_READ, *conn->list->v.input, conn);
57397188558fcd1a9e24dbbbd2952eac9c45c20dTimo Sirainen conn->output = o_stream_create_unix(conn->fd_out,
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen conn->output = o_stream_create_fd(conn->fd_out,
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen o_stream_set_no_error_handling(conn->output, TRUE);
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen o_stream_set_finish_via_child(conn->output, FALSE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen conn->to = timeout_add(set->input_idle_timeout_secs*1000,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (set->major_version != 0 && !set->dont_send_version) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen o_stream_nsend_str(conn->output, t_strdup_printf(
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen "VERSION\t%s\t%u\t%u\n", set->service_name_out,
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainenstatic void connection_client_connected(struct connection *conn, bool success)
if (!success) {
int fd;
i_unreached();
unsigned int msecs =
i_unreached();
return t_strdup_printf(
struct connection_list *
return list;