log-connection.c revision 5f5870385cff47efd2f58e7892f251cf13761528
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2005-2012 Dovecot authors, see the included COPYING file */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* pid -> struct log_client* */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic struct log_connection *log_connections = NULL;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic ARRAY_DEFINE(logs_by_fd, struct log_connection *);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic struct log_client *log_client_get(struct log_connection *log, pid_t pid)
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen client = hash_table_lookup(log->clients, POINTER_CAST(pid));
1b4441e3e6f9e78ebeae8218de971959cd55bf60Timo Sirainen hash_table_insert(log->clients, POINTER_CAST(pid), client);
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainenstatic void log_client_free(struct log_connection *log,
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen hash_table_remove(log->clients, POINTER_CAST(pid));
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic void log_parse_option(struct log_connection *log,
dbb1fb1c51727e2050792f8c333b212e22a36d69Timo Sirainen (void)net_addr2ip(failure->text + 3, &client->ip);
dbb1fb1c51727e2050792f8c333b212e22a36d69Timo Sirainen else if (strncmp(failure->text, "prefix=", 7) == 0) {
6789ed17e7ca4021713507baf0dcf6979bb42e0cTimo Sirainen const struct failure_context *ctx, time_t log_time,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenclient_log_fatal(struct log_connection *log, struct log_client *client,
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen const char *line, time_t log_time, const struct tm *tm)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen client_log_ctx(log, &failure_ctx, log_time, prefix,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenlog_parse_master_line(const char *line, time_t log_time, const struct tm *tm)
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen const char *p, *p2;
c36ec256c1bd1abe1c12e792cf64f0b7e3b3135aTimo Sirainen unsigned int count;
86ad841251a38aa9ffcf4db4ee2c9fd449121bcbTimo Sirainen if (p == NULL || (p2 = strchr(++p, ' ')) == NULL) {
86ad841251a38aa9ffcf4db4ee2c9fd449121bcbTimo Sirainen i_error("Received invalid input from master: %s", line);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen if (service_fd >= (int)count || logs[service_fd] == NULL) {
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen i_error("Received master input for invalid service_fd %d: %s",
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainen client = hash_table_lookup(log->clients, POINTER_CAST(pid));
4bab017ff69d6877253dde54b5a5f1f3f5e92fdfTimo Sirainen /* we haven't seen anything important from this client.
4bab017ff69d6877253dde54b5a5f1f3f5e92fdfTimo Sirainen it's not an error. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen client_log_fatal(log, client, line + 6, log_time, tm);
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen } else if (strncmp(line, "DEFAULT-FATAL ", 14) == 0) {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* If the client has logged a fatal/panic, don't log this
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen client_log_fatal(log, client, line + 14, log_time, tm);
823af4a2cc4e2ce90d12f9ec362160546aa4c4b8Timo Sirainen i_error("Received unknown command from master: %s", line);
e8a59a1671127f87e2d22f42e84c572f28299d81Timo Sirainenlog_it(struct log_connection *log, const char *line,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen prefix = client != NULL && client->prefix != NULL ?
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen client_log_ctx(log, &failure_ctx, log_time, prefix, failure.text);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainenstatic int log_connection_handshake(struct log_connection *log)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const unsigned char *data;
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen /* this isn't a handshake */
0206dc57f2c04da69599dea5816235cfeb2b897aMartti Rannanjärvi data = i_stream_get_data(log->input, &size);
d052dcfff0c96a0af17a3158e51f709edf4b93a1Timo Sirainen if (handshake.log_magic != MASTER_LOG_MAGIC) {
bc15c6934f69be09cca1e9f87f9dc344f77e8b7cTimo Sirainen /* this isn't a handshake */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (handshake.prefix_len > size - sizeof(handshake)) {
b2723d68898e4a6a6e6ba2a06926dcaa1911daf5Timo Sirainen log->default_prefix = i_strndup(data + sizeof(handshake),
424633d1a1e22139a5ab9345f807a89d0792ead3Timo Sirainen i_stream_skip(log->input, sizeof(handshake) + handshake.prefix_len);
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen if (strcmp(log->default_prefix, MASTER_LOG_PREFIX_NAME) == 0) {
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen if (log->listen_fd != MASTER_LISTEN_FD_FIRST) {
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen i_error("Received master prefix in handshake "
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainenstatic void log_connection_input(struct log_connection *log)
struct log_connection *
return log;
void log_connections_init(void)
void log_connections_deinit(void)