|
|
626085 |
From 47ef5ccd0edbff6610badc8c0f543f0e1d18bdc2 Mon Sep 17 00:00:00 2001
|
|
|
7eab74 |
From: Michal Sekletar <msekleta@redhat.com>
|
|
|
7eab74 |
Date: Thu, 4 Aug 2022 11:11:58 +0200
|
|
|
7eab74 |
Subject: [PATCH] resolve: introduce reference counting on DnsStream
|
|
|
7eab74 |
|
|
|
7eab74 |
(cherry picked from commit b30bf55d5c9942f15f27a641c2c34bbb646ec981)
|
|
|
7eab74 |
|
|
|
7eab74 |
Related: #2110544
|
|
|
7eab74 |
|
|
|
7eab74 |
[msekleta: in order to protect against freeing the DnsStream by the
|
|
|
7eab74 |
callback we need to pin it by increasing the reference count. Reference
|
|
|
7eab74 |
counting for DnsStream was introduced in the b30bf55d5c as part of the
|
|
|
7eab74 |
much bigger change. We are very late in RHEL-7 release cycle and we want
|
|
|
7eab74 |
to keep code changes to a minimum, so let's backport just relevant part
|
|
|
7eab74 |
of that commit and leave everything else unchanged.]
|
|
|
7eab74 |
---
|
|
|
7eab74 |
src/resolve/resolved-dns-stream.c | 27 ++++++++++++++++++++------
|
|
|
7eab74 |
src/resolve/resolved-dns-stream.h | 6 +++++-
|
|
|
7eab74 |
src/resolve/resolved-dns-transaction.c | 8 ++++----
|
|
|
7eab74 |
src/resolve/resolved-manager.c | 2 +-
|
|
|
7eab74 |
4 files changed, 31 insertions(+), 12 deletions(-)
|
|
|
7eab74 |
|
|
|
7eab74 |
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
|
|
|
626085 |
index 7f47e7223a..8d898b4819 100644
|
|
|
7eab74 |
--- a/src/resolve/resolved-dns-stream.c
|
|
|
7eab74 |
+++ b/src/resolve/resolved-dns-stream.c
|
|
|
626085 |
@@ -55,8 +55,8 @@ static int dns_stream_complete(DnsStream *s, int error) {
|
|
|
7eab74 |
|
|
|
7eab74 |
if (s->complete)
|
|
|
7eab74 |
s->complete(s, error);
|
|
|
7eab74 |
- else
|
|
|
7eab74 |
- dns_stream_free(s);
|
|
|
7eab74 |
+ else /* the default action if no completion function is set is to close the stream */
|
|
|
7eab74 |
+ dns_stream_unref(s);
|
|
|
7eab74 |
|
|
|
7eab74 |
return 0;
|
|
|
7eab74 |
}
|
|
|
626085 |
@@ -322,10 +322,16 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
|
|
|
7eab74 |
return 0;
|
|
|
7eab74 |
}
|
|
|
7eab74 |
|
|
|
7eab74 |
-DnsStream *dns_stream_free(DnsStream *s) {
|
|
|
7eab74 |
+DnsStream *dns_stream_unref(DnsStream *s) {
|
|
|
7eab74 |
if (!s)
|
|
|
7eab74 |
return NULL;
|
|
|
7eab74 |
|
|
|
7eab74 |
+ assert(s->n_ref > 0);
|
|
|
7eab74 |
+ s->n_ref--;
|
|
|
7eab74 |
+
|
|
|
7eab74 |
+ if (s->n_ref > 0)
|
|
|
7eab74 |
+ return NULL;
|
|
|
7eab74 |
+
|
|
|
7eab74 |
dns_stream_stop(s);
|
|
|
7eab74 |
|
|
|
7eab74 |
if (s->manager) {
|
|
|
626085 |
@@ -338,14 +344,22 @@ DnsStream *dns_stream_free(DnsStream *s) {
|
|
|
7eab74 |
|
|
|
7eab74 |
free(s);
|
|
|
7eab74 |
|
|
|
7eab74 |
- return 0;
|
|
|
7eab74 |
+ return NULL;
|
|
|
7eab74 |
}
|
|
|
7eab74 |
|
|
|
7eab74 |
-DEFINE_TRIVIAL_CLEANUP_FUNC(DnsStream*, dns_stream_free);
|
|
|
7eab74 |
+DnsStream *dns_stream_ref(DnsStream *s) {
|
|
|
7eab74 |
+ if (!s)
|
|
|
7eab74 |
+ return NULL;
|
|
|
7eab74 |
+
|
|
|
7eab74 |
+ assert(s->n_ref > 0);
|
|
|
7eab74 |
+ s->n_ref++;
|
|
|
7eab74 |
+
|
|
|
7eab74 |
+ return s;
|
|
|
7eab74 |
+}
|
|
|
7eab74 |
|
|
|
7eab74 |
int dns_stream_new(Manager *m, DnsStream **ret, DnsProtocol protocol, int fd) {
|
|
|
7eab74 |
static const int one = 1;
|
|
|
7eab74 |
- _cleanup_(dns_stream_freep) DnsStream *s = NULL;
|
|
|
7eab74 |
+ _cleanup_(dns_stream_unrefp) DnsStream *s = NULL;
|
|
|
7eab74 |
int r;
|
|
|
7eab74 |
|
|
|
7eab74 |
assert(m);
|
|
|
626085 |
@@ -358,6 +372,7 @@ int dns_stream_new(Manager *m, DnsStream **ret, DnsProtocol protocol, int fd) {
|
|
|
7eab74 |
if (!s)
|
|
|
7eab74 |
return -ENOMEM;
|
|
|
7eab74 |
|
|
|
7eab74 |
+ s->n_ref = 1;
|
|
|
7eab74 |
s->fd = -1;
|
|
|
7eab74 |
s->protocol = protocol;
|
|
|
7eab74 |
|
|
|
7eab74 |
diff --git a/src/resolve/resolved-dns-stream.h b/src/resolve/resolved-dns-stream.h
|
|
|
7eab74 |
index 46eae31c60..28aee48205 100644
|
|
|
7eab74 |
--- a/src/resolve/resolved-dns-stream.h
|
|
|
7eab74 |
+++ b/src/resolve/resolved-dns-stream.h
|
|
|
7eab74 |
@@ -31,6 +31,7 @@ typedef struct DnsStream DnsStream;
|
|
|
7eab74 |
|
|
|
7eab74 |
struct DnsStream {
|
|
|
7eab74 |
Manager *manager;
|
|
|
7eab74 |
+ int n_ref;
|
|
|
7eab74 |
|
|
|
7eab74 |
DnsProtocol protocol;
|
|
|
7eab74 |
|
|
|
7eab74 |
@@ -59,6 +60,9 @@ struct DnsStream {
|
|
|
7eab74 |
};
|
|
|
7eab74 |
|
|
|
7eab74 |
int dns_stream_new(Manager *m, DnsStream **s, DnsProtocol protocol, int fd);
|
|
|
7eab74 |
-DnsStream *dns_stream_free(DnsStream *s);
|
|
|
7eab74 |
+DnsStream *dns_stream_unref(DnsStream *s);
|
|
|
7eab74 |
+DnsStream *dns_stream_ref(DnsStream *s);
|
|
|
7eab74 |
+
|
|
|
7eab74 |
+DEFINE_TRIVIAL_CLEANUP_FUNC(DnsStream*, dns_stream_unref);
|
|
|
7eab74 |
|
|
|
7eab74 |
int dns_stream_write_packet(DnsStream *s, DnsPacket *p);
|
|
|
7eab74 |
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
|
|
|
7eab74 |
index bc1a90db1b..6fa581b6a9 100644
|
|
|
7eab74 |
--- a/src/resolve/resolved-dns-transaction.c
|
|
|
7eab74 |
+++ b/src/resolve/resolved-dns-transaction.c
|
|
|
7eab74 |
@@ -37,7 +37,7 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) {
|
|
|
7eab74 |
dns_packet_unref(t->received);
|
|
|
7eab74 |
dns_answer_unref(t->cached);
|
|
|
7eab74 |
|
|
|
7eab74 |
- dns_stream_free(t->stream);
|
|
|
7eab74 |
+ dns_stream_unref(t->stream);
|
|
|
7eab74 |
|
|
|
7eab74 |
if (t->scope) {
|
|
|
7eab74 |
LIST_REMOVE(transactions_by_scope, t->scope->transactions, t);
|
|
|
7eab74 |
@@ -114,7 +114,7 @@ static void dns_transaction_stop(DnsTransaction *t) {
|
|
|
7eab74 |
assert(t);
|
|
|
7eab74 |
|
|
|
7eab74 |
t->timeout_event_source = sd_event_source_unref(t->timeout_event_source);
|
|
|
7eab74 |
- t->stream = dns_stream_free(t->stream);
|
|
|
7eab74 |
+ t->stream = dns_stream_unref(t->stream);
|
|
|
7eab74 |
}
|
|
|
7eab74 |
|
|
|
7eab74 |
static void dns_transaction_tentative(DnsTransaction *t, DnsPacket *p) {
|
|
|
7eab74 |
@@ -208,7 +208,7 @@ static int on_stream_complete(DnsStream *s, int error) {
|
|
|
7eab74 |
t = s->transaction;
|
|
|
7eab74 |
p = dns_packet_ref(s->read_packet);
|
|
|
7eab74 |
|
|
|
7eab74 |
- t->stream = dns_stream_free(t->stream);
|
|
|
7eab74 |
+ t->stream = dns_stream_unref(t->stream);
|
|
|
7eab74 |
|
|
|
7eab74 |
if (error != 0) {
|
|
|
7eab74 |
dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES);
|
|
|
7eab74 |
@@ -279,7 +279,7 @@ static int dns_transaction_open_tcp(DnsTransaction *t) {
|
|
|
7eab74 |
|
|
|
7eab74 |
r = dns_stream_write_packet(t->stream, t->sent);
|
|
|
7eab74 |
if (r < 0) {
|
|
|
7eab74 |
- t->stream = dns_stream_free(t->stream);
|
|
|
7eab74 |
+ t->stream = dns_stream_unref(t->stream);
|
|
|
7eab74 |
return r;
|
|
|
7eab74 |
}
|
|
|
7eab74 |
|
|
|
7eab74 |
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
|
|
|
7eab74 |
index 173ab8a148..aa7aa68cab 100644
|
|
|
7eab74 |
--- a/src/resolve/resolved-manager.c
|
|
|
7eab74 |
+++ b/src/resolve/resolved-manager.c
|
|
|
7eab74 |
@@ -1531,7 +1531,7 @@ static int on_llmnr_stream_packet(DnsStream *s) {
|
|
|
7eab74 |
} else
|
|
|
7eab74 |
log_debug("Invalid LLMNR TCP packet.");
|
|
|
7eab74 |
|
|
|
7eab74 |
- dns_stream_free(s);
|
|
|
7eab74 |
+ dns_stream_unref(s);
|
|
|
7eab74 |
return 0;
|
|
|
7eab74 |
}
|
|
|
7eab74 |
|