static gboolean afsocket_sd_restore_kept_alive_connections(AFSocketSourceDriver *self) { GlobalConfig *cfg = log_pipe_get_config(&self->super.super.super); /* fetch persistent connections first */ if (self->connections_kept_alive_accross_reloads) { GList *p = NULL; self->connections = cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, FALSE)); self->num_connections = 0; for (p = self->connections; p; p = p->next) { afsocket_sc_set_owner((AFSocketSourceConnection *) p->data, self); if (log_pipe_init((LogPipe *) p->data)) { self->num_connections++; } else { AFSocketSourceConnection *sc = (AFSocketSourceConnection *)p->data; self->connections = g_list_remove(self->connections, sc); afsocket_sd_kill_connection((AFSocketSourceConnection *)sc); } } } return TRUE; }
static gboolean afsocket_sd_process_connection(AFSocketSourceDriver *self, GSockAddr *client_addr, GSockAddr *local_addr, gint fd) { gchar buf[MAX_SOCKADDR_STRING], buf2[MAX_SOCKADDR_STRING]; #if SYSLOG_NG_ENABLE_TCP_WRAPPER if (client_addr && (client_addr->sa.sa_family == AF_INET #if SYSLOG_NG_ENABLE_IPV6 || client_addr->sa.sa_family == AF_INET6 #endif )) { struct request_info req; request_init(&req, RQ_DAEMON, "syslog-ng", RQ_FILE, fd, 0); fromhost(&req); if (hosts_access(&req) == 0) { msg_error("Syslog connection rejected by tcpd", evt_tag_str("client", g_sockaddr_format(client_addr, buf, sizeof(buf), GSA_FULL)), evt_tag_str("local", g_sockaddr_format(local_addr, buf2, sizeof(buf2), GSA_FULL)), NULL); return FALSE; } } #endif if (self->num_connections >= self->max_connections) { msg_error("Number of allowed concurrent connections reached, rejecting connection", evt_tag_str("client", g_sockaddr_format(client_addr, buf, sizeof(buf), GSA_FULL)), evt_tag_str("local", g_sockaddr_format(local_addr, buf2, sizeof(buf2), GSA_FULL)), evt_tag_int("max", self->max_connections), NULL); return FALSE; } else { AFSocketSourceConnection *conn; conn = afsocket_sc_new(client_addr, fd, self->super.super.super.cfg); afsocket_sc_set_owner(conn, self); if (log_pipe_init(&conn->super)) { afsocket_sd_add_connection(self, conn); self->num_connections++; log_pipe_append(&conn->super, &self->super.super.super); } else { log_pipe_unref(&conn->super); return FALSE; } } return TRUE; }
gboolean afsocket_sd_init(LogPipe *s) { AFSocketSourceDriver *self = (AFSocketSourceDriver *) s; gint sock; gboolean res = FALSE; GlobalConfig *cfg = log_pipe_get_config(s); if (!log_src_driver_init_method(s)) return FALSE; if (!afsocket_sd_apply_transport(self)) return FALSE; g_assert(self->transport); g_assert(self->bind_addr); if ((self->flags & (AFSOCKET_STREAM + AFSOCKET_WNDSIZE_INITED)) == AFSOCKET_STREAM) { /* distribute the window evenly between each of our possible * connections. This is quite pessimistic and can result in very low * window sizes. Increase that but warn the user at the same time */ self->reader_options.super.init_window_size /= self->max_connections; if (self->reader_options.super.init_window_size < 100) { msg_warning("WARNING: window sizing for tcp sources were changed in syslog-ng 3.3, the configuration value was divided by the value of max-connections(). The result was too small, clamping to 100 entries. Ensure you have a proper log_fifo_size setting to avoid message loss.", evt_tag_int("orig_log_iw_size", self->reader_options.super.init_window_size), evt_tag_int("new_log_iw_size", 100), evt_tag_int("min_log_fifo_size", 100 * self->max_connections), NULL); self->reader_options.super.init_window_size = 100; } self->flags |= AFSOCKET_WNDSIZE_INITED; } log_reader_options_init(&self->reader_options, cfg, self->super.super.group); /* fetch persistent connections first */ if ((self->flags & AFSOCKET_KEEP_ALIVE)) { GList *p; self->connections = cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, FALSE)); for (p = self->connections; p; p = p->next) { afsocket_sc_set_owner((AFSocketSourceConnection *) p->data, self); log_pipe_init((LogPipe *) p->data, NULL); } } /* ok, we have connection list, check if we need to open a listener */ sock = -1; if (self->flags & AFSOCKET_STREAM) { if (self->flags & AFSOCKET_KEEP_ALIVE) { /* NOTE: this assumes that fd 0 will never be used for listening fds, * main.c opens fd 0 so this assumption can hold */ sock = GPOINTER_TO_UINT(cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, TRUE))) - 1; } if (sock == -1) { if (!afsocket_sd_acquire_socket(self, &sock)) return self->super.super.optional; if (sock == -1 && !afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.super.optional; } /* set up listening source */ if (listen(sock, self->listen_backlog) < 0) { msg_error("Error during listen()", evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); close(sock); return FALSE; } if (self->setup_socket && !self->setup_socket(self, sock)) { close(sock); return FALSE; } self->fd = sock; afsocket_sd_start_watches(self); res = TRUE; } else { if (!self->connections) { if (!afsocket_sd_acquire_socket(self, &sock)) return self->super.super.optional; if (sock == -1 && !afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.super.optional; } self->fd = -1; if (!self->setup_socket(self, sock)) { close(sock); return FALSE; } /* we either have self->connections != NULL, or sock contains a new fd */ if (self->connections || afsocket_sd_process_connection(self, NULL, self->bind_addr, sock)) res = TRUE; } return res; }
gboolean afsocket_sd_init(LogPipe *s) { AFSocketSourceDriver *self = (AFSocketSourceDriver *) s; gint sock; gboolean res = FALSE; GlobalConfig *cfg = log_pipe_get_config(s); #if ENABLE_SSL if (self->flags & AFSOCKET_REQUIRE_TLS && !self->tls_context) { msg_error("Transport TLS was specified, but TLS related parameters missing", NULL); return FALSE; } #endif if (!self->bind_addr) { msg_error("No bind address set;", NULL); } log_reader_options_init(&self->reader_options, cfg, self->super.group); /* fetch persistent connections first */ if ((self->flags & AFSOCKET_KEEP_ALIVE)) { GList *p; self->connections = cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, FALSE), NULL, NULL); for (p = self->connections; p; p = p->next) { afsocket_sc_set_owner((AFSocketSourceConnection *) p->data, self); } } /* ok, we have connection list, check if we need to open a listener */ sock = -1; if (self->flags & AFSOCKET_STREAM) { GSource *source; if (self->flags & AFSOCKET_KEEP_ALIVE) { /* NOTE: this assumes that fd 0 will never be used for listening fds, * main.c opens fd 0 so this assumption can hold */ sock = GPOINTER_TO_UINT(cfg_persist_config_fetch(cfg, afsocket_sd_format_persist_name(self, TRUE), NULL, NULL)) - 1; } if (sock == -1) { if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.optional; } /* set up listening source */ if (listen(sock, self->listen_backlog) < 0) { msg_error("Error during listen()", evt_tag_errno(EVT_TAG_OSERROR, errno), NULL); close(sock); return FALSE; } if (self->setup_socket && !self->setup_socket(self, sock)) { close(sock); return FALSE; } self->fd = sock; source = g_listen_source_new(self->fd); /* the listen_source references us, which is freed when the source is deleted */ log_pipe_ref(s); g_source_set_callback(source, afsocket_sd_accept, self, (GDestroyNotify) log_pipe_unref); self->source_id = g_source_attach(source, NULL); g_source_unref(source); res = TRUE; } else { if (!self->connections) { if (!afsocket_open_socket(self->bind_addr, !!(self->flags & AFSOCKET_STREAM), &sock)) return self->super.optional; } self->fd = -1; if (!self->setup_socket(self, sock)) { close(sock); return FALSE; } /* we either have self->connections != NULL, or sock contains a new fd */ if (self->connections || afsocket_sd_process_connection(self, NULL, self->bind_addr, sock)) res = TRUE; } return res; }