summaryrefslogtreecommitdiffstats
path: root/src/resolve/resolved-dns-stream.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/resolve/resolved-dns-stream.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
index 95fbb56..dd3da7b 100644
--- a/src/resolve/resolved-dns-stream.c
+++ b/src/resolve/resolved-dns-stream.c
@@ -195,7 +195,7 @@ static int dns_stream_identify(DnsStream *s) {
/* Make sure all packets for this connection are sent on the same interface */
r = socket_set_unicast_if(s->fd, s->local.sa.sa_family, s->ifindex);
if (r < 0)
- log_debug_errno(errno, "Failed to invoke IP_UNICAST_IF/IPV6_UNICAST_IF: %m");
+ log_debug_errno(r, "Failed to invoke IP_UNICAST_IF/IPV6_UNICAST_IF: %m");
}
s->identified = true;
@@ -454,7 +454,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
if (progressed && s->timeout_event_source) {
r = sd_event_source_set_time_relative(s->timeout_event_source, DNS_STREAM_ESTABLISHED_TIMEOUT_USEC);
if (r < 0)
- log_warning_errno(errno, "Couldn't restart TCP connection timeout, ignoring: %m");
+ log_warning_errno(r, "Couldn't restart TCP connection timeout, ignoring: %m");
}
return 0;
@@ -593,3 +593,44 @@ void dns_stream_detach(DnsStream *s) {
dns_server_unref_stream(s->server);
}
+
+DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
+ dns_stream_hash_ops,
+ void,
+ trivial_hash_func,
+ trivial_compare_func,
+ dns_stream_unref);
+
+int dns_stream_disconnect_all(Manager *m) {
+ _cleanup_(set_freep) Set *closed = NULL;
+ int r;
+
+ assert(m);
+
+ /* Terminates all TCP connections (called after system suspend for example, to speed up recovery) */
+
+ log_info("Closing all remaining TCP connections.");
+
+ bool restart;
+ do {
+ restart = false;
+
+ LIST_FOREACH(streams, s, m->dns_streams) {
+ r = set_ensure_put(&closed, &dns_stream_hash_ops, s);
+ if (r < 0)
+ return log_oom();
+ if (r > 0) {
+ /* Haven't seen this one before. Close it. */
+ dns_stream_ref(s);
+ (void) dns_stream_complete(s, ECONNRESET);
+
+ /* This might have a ripple effect, let's hence no look at the list further,
+ * but scan from the beginning again */
+ restart = true;
+ break;
+ }
+ }
+ } while (restart);
+
+ return 0;
+}