From 652ba568c6624bf40d735645f029d83d21bdeaa6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 21 Jan 2019 17:57:43 +0100 Subject: [PATCH] stream: track type of DnsStream object We use stream objects in four different cases: let's track them. This in particular allows us to make sure the limit on outgoing streams cannot be exhausted by having incoming streams as this means we can neatly separate the counters for all four types. --- src/resolve/resolved-dns-stream.c | 11 ++++++++--- src/resolve/resolved-dns-stream.h | 12 +++++++++++- src/resolve/resolved-dns-stub.c | 2 +- src/resolve/resolved-dns-transaction.c | 7 +++++-- src/resolve/resolved-llmnr.c | 2 +- src/resolve/resolved-manager.h | 2 +- 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c index e29c970d51..ebafaa529c 100644 --- a/src/resolve/resolved-dns-stream.c +++ b/src/resolve/resolved-dns-stream.c @@ -437,7 +437,7 @@ static DnsStream *dns_stream_free(DnsStream *s) { if (s->manager) { LIST_REMOVE(streams, s->manager->dns_streams, s); - s->manager->n_dns_streams--; + s->manager->n_dns_streams[s->type]--; } #if ENABLE_DNS_OVER_TLS @@ -462,6 +462,7 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(DnsStream, dns_stream, dns_stream_free); int dns_stream_new( Manager *m, DnsStream **ret, + DnsStreamType type, DnsProtocol protocol, int fd, const union sockaddr_union *tfo_address) { @@ -471,9 +472,13 @@ int dns_stream_new( assert(m); assert(ret); + assert(type >= 0); + assert(type < _DNS_STREAM_TYPE_MAX); + assert(protocol >= 0); + assert(protocol < _DNS_PROTOCOL_MAX); assert(fd >= 0); - if (m->n_dns_streams > DNS_STREAMS_MAX) + if (m->n_dns_streams[type] > DNS_STREAMS_MAX) return -EBUSY; s = new(DnsStream, 1); @@ -508,7 +513,7 @@ int dns_stream_new( (void) sd_event_source_set_description(s->timeout_event_source, "dns-stream-timeout"); LIST_PREPEND(streams, m->dns_streams, s); - m->n_dns_streams++; + m->n_dns_streams[type]++; s->manager = m; s->fd = fd; diff --git a/src/resolve/resolved-dns-stream.h b/src/resolve/resolved-dns-stream.h index f18fc919e7..2c6d9c00b9 100644 --- a/src/resolve/resolved-dns-stream.h +++ b/src/resolve/resolved-dns-stream.h @@ -5,6 +5,15 @@ typedef struct DnsStream DnsStream; +typedef enum DnsStreamType { + DNS_STREAM_LOOKUP, /* Outgoing connection to a classic DNS server */ + DNS_STREAM_LLMNR_SEND, /* Outgoing LLMNR TCP lookup */ + DNS_STREAM_LLMNR_RECV, /* Incoming LLMNR TCP lookup */ + DNS_STREAM_STUB, /* Incoming DNS stub connection */ + _DNS_STREAM_TYPE_MAX, + _DNS_STREAM_TYPE_INVALID = -1, +} DnsStreamType; + #include "resolved-dns-packet.h" #include "resolved-dns-transaction.h" #include "resolved-manager.h" @@ -25,6 +34,7 @@ struct DnsStream { Manager *manager; unsigned n_ref; + DnsStreamType type; DnsProtocol protocol; int fd; @@ -66,7 +76,7 @@ struct DnsStream { LIST_FIELDS(DnsStream, streams); }; -int dns_stream_new(Manager *m, DnsStream **s, DnsProtocol protocol, int fd, const union sockaddr_union *tfo_address); +int dns_stream_new(Manager *m, DnsStream **s, DnsStreamType type, DnsProtocol protocol, int fd, const union sockaddr_union *tfo_address); #if ENABLE_DNS_OVER_TLS int dns_stream_connect_tls(DnsStream *s, void *tls_session); #endif diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c index a00716cd85..39ce42d155 100644 --- a/src/resolve/resolved-dns-stub.c +++ b/src/resolve/resolved-dns-stub.c @@ -471,7 +471,7 @@ static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void return -errno; } - r = dns_stream_new(m, &stream, DNS_PROTOCOL_DNS, cfd, NULL); + r = dns_stream_new(m, &stream, DNS_STREAM_STUB, DNS_PROTOCOL_DNS, cfd, NULL); if (r < 0) { safe_close(cfd); return r; diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 4a2d2ccbde..075dfac01b 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -554,9 +554,10 @@ static uint16_t dns_port_for_feature_level(DnsServerFeatureLevel level) { } static int dns_transaction_emit_tcp(DnsTransaction *t) { - _cleanup_close_ int fd = -1; _cleanup_(dns_stream_unrefp) DnsStream *s = NULL; + _cleanup_close_ int fd = -1; union sockaddr_union sa; + DnsStreamType type; int r; assert(t); @@ -582,6 +583,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { else fd = dns_scope_socket_tcp(t->scope, AF_UNSPEC, NULL, t->server, dns_port_for_feature_level(t->current_feature_level), &sa); + type = DNS_STREAM_LOOKUP; break; case DNS_PROTOCOL_LLMNR: @@ -607,6 +609,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { fd = dns_scope_socket_tcp(t->scope, family, &address, NULL, LLMNR_PORT, &sa); } + type = DNS_STREAM_LLMNR_SEND; break; default: @@ -617,7 +620,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { if (fd < 0) return fd; - r = dns_stream_new(t->scope->manager, &s, t->scope->protocol, fd, &sa); + r = dns_stream_new(t->scope->manager, &s, type, t->scope->protocol, fd, &sa); if (r < 0) return r; diff --git a/src/resolve/resolved-llmnr.c b/src/resolve/resolved-llmnr.c index dfa55c577c..d73f86560d 100644 --- a/src/resolve/resolved-llmnr.c +++ b/src/resolve/resolved-llmnr.c @@ -295,7 +295,7 @@ static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *u return -errno; } - r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd, NULL); + r = dns_stream_new(m, &stream, DNS_STREAM_LLMNR_RECV, DNS_PROTOCOL_LLMNR, cfd, NULL); if (r < 0) { safe_close(cfd); return r; diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index 06c76f6014..72171f8c97 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -54,7 +54,7 @@ struct Manager { unsigned n_dns_queries; LIST_HEAD(DnsStream, dns_streams); - unsigned n_dns_streams; + unsigned n_dns_streams[_DNS_STREAM_TYPE_MAX]; /* Unicast dns */ LIST_HEAD(DnsServer, dns_servers);