diff options
Diffstat (limited to 'src/resolve/resolved-dns-stream.c')
-rw-r--r-- | src/resolve/resolved-dns-stream.c | 45 |
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; +} |