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.
This commit is contained in:
Lennart Poettering 2019-01-21 17:57:43 +01:00
parent 57bdb749b8
commit 652ba568c6
6 changed files with 27 additions and 9 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);