From: Aki Tuomi Date: Thu, 16 Aug 2018 07:32:38 +0000 (+0300) Subject: dns: Use connection.c X-Git-Tag: 2.3.9~1524 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e5f30e7144c41b302a2f21c9b7992ea8d8493dd;p=thirdparty%2Fdovecot%2Fcore.git dns: Use connection.c This enables processing multiple requests at a time. --- diff --git a/src/dns/dns-client.c b/src/dns/dns-client.c index 53a41be7ff..8c3a6bd47a 100644 --- a/src/dns/dns-client.c +++ b/src/dns/dns-client.c @@ -1,38 +1,34 @@ /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "ioloop.h" #include "istream.h" #include "ostream.h" +#include "array.h" +#include "strfuncs.h" +#include "connection.h" #include "restrict-access.h" #include "master-service.h" #include -struct dns_client { - int fd; - struct istream *input; - struct ostream *output; - struct io *io; -}; - -#define MAX_INBUF_SIZE 1024 -#define MAX_OUTBUF_SIZE (1024*64) -#define INPUT_TIMEOUT_MSECS (1000*10) - -static struct dns_client *dns_client = NULL; - -static void dns_client_destroy(struct dns_client **client); +static struct connection_list *dns_clients = NULL; -static int dns_client_input_line(struct dns_client *client, const char *line) +static int dns_client_input_args(struct connection *client, const char *const *args) { struct ip_addr *ips, ip; const char *name; unsigned int i, ips_count; int ret; - if (str_begins(line, "IP\t")) { - ret = net_gethostbyname(line + 3, &ips, &ips_count); + if (strcmp(args[0], "QUIT") == 0) { + return -1; + } else if (args[1] == NULL) { + i_error("Got empty request"); + return -1; + } + + if (strcmp(args[0], "IP") == 0) { + ret = net_gethostbyname(args[1], &ips, &ips_count); if (ret == 0 && ips_count == 0) { /* shouldn't happen, but fix it anyway.. */ ret = EAI_NONAME; @@ -44,12 +40,13 @@ static int dns_client_input_line(struct dns_client *client, const char *line) o_stream_nsend_str(client->output, t_strdup_printf("0 %u\n", ips_count)); for (i = 0; i < ips_count; i++) { + const char *ip = net_ip2addr(&ips[i]); o_stream_nsend_str(client->output, t_strconcat( net_ip2addr(&ips[i]), "\n", NULL)); } } - } else if (str_begins(line, "NAME\t")) { - if (net_addr2ip(line+5, &ip) < 0) + } else if (strcmp(args[0], "NAME") == 0) { + if (net_addr2ip(args[1], &ip) < 0) o_stream_nsend_str(client->output, "-1\n"); else if ((ret = net_gethostbyaddr(&ip, &name)) != 0) { o_stream_nsend_str(client->output, @@ -58,74 +55,37 @@ static int dns_client_input_line(struct dns_client *client, const char *line) o_stream_nsend_str(client->output, t_strdup_printf("0 %s\n", name)); } - } else if (strcmp(line, "QUIT") == 0) { - return -1; } else { o_stream_nsend_str(client->output, "Unknown command\n"); } - if (client->output->overflow) - return -1; - return 0; -} - -static void dns_client_input(struct dns_client *client) -{ - const char *line; - int ret = 0; - - o_stream_cork(client->output); - while ((line = i_stream_read_next_line(client->input)) != NULL) { - if (dns_client_input_line(client, line) < 0) { - ret = -1; - break; - } - } - o_stream_uncork(client->output); - - if (client->input->eof || client->input->stream_errno != 0 || ret < 0) - dns_client_destroy(&client); -} - -static struct dns_client *dns_client_create(int fd) -{ - struct dns_client *client; - - client = i_new(struct dns_client, 1); - client->fd = fd; - client->input = i_stream_create_fd(fd, MAX_INBUF_SIZE); - client->output = o_stream_create_fd(fd, MAX_OUTBUF_SIZE); - o_stream_set_no_error_handling(client->output, TRUE); - client->io = io_add(fd, IO_READ, dns_client_input, client); - return client; + return 1; } -static void dns_client_destroy(struct dns_client **_client) +static void dns_client_destroy(struct connection *client) { - struct dns_client *client = *_client; - - *_client = NULL; - - io_remove(&client->io); - i_stream_destroy(&client->input); - o_stream_destroy(&client->output); - if (close(client->fd) < 0) - i_error("close() failed: %m"); + connection_deinit(client); i_free(client); - - dns_client = NULL; master_service_client_connection_destroyed(master_service); } -static void client_connected(struct master_service_connection *conn) -{ - if (dns_client != NULL) { - i_error("dns-client must be configured with client_limit=1"); - return; - } +static const struct connection_vfuncs dns_client_vfuncs = { + .input_args = dns_client_input_args, + .destroy = dns_client_destroy +}; + +static const struct connection_settings dns_client_set = { + .dont_send_version = TRUE, + .input_max_size = (size_t)-1, + .output_max_size = (size_t)-1 +}; - master_service_client_connection_accept(conn); - dns_client = dns_client_create(conn->fd); +static void client_connected(struct master_service_connection *master_conn) +{ + struct connection *conn = i_new(struct connection, 1); + master_service_client_connection_accept(master_conn); + connection_init_server(dns_clients, conn, master_conn->name, + master_conn->fd, master_conn->fd); } int main(int argc, char *argv[]) @@ -140,9 +100,13 @@ int main(int argc, char *argv[]) master_service_init_finish(master_service); + /* setup connection list */ + dns_clients = connection_list_init(&dns_client_set, &dns_client_vfuncs); + master_service_run(master_service, client_connected); - if (dns_client != NULL) - dns_client_destroy(&dns_client); + + /* disconnect all clients */ + connection_list_deinit(&dns_clients); master_service_deinit(&master_service); return 0;