if (!s->read_packet || s->n_read < sizeof(s->read_size) + s->read_packet->size)
f |= EPOLLIN;
+#if ENABLE_DNS_OVER_TLS
+ /* For handshake and clean closing purposes, TLS can override requested events */
+ if (s->dnstls_events)
+ f = s->dnstls_events;
+#endif
+
return sd_event_source_set_io_events(s->io_event_source, f);
}
if (s->encrypted) {
r = dnstls_stream_on_io(s);
- if (r == DNSTLS_STREAM_CLOSED || r == -EAGAIN)
+ if (r == DNSTLS_STREAM_CLOSED)
return 0;
- else if (r < 0)
+ else if (r == -EAGAIN)
+ return dns_stream_update_io(s);
+ else if (r < 0) {
return dns_stream_complete(s, -r);
+ } else {
+ r = dns_stream_update_io(s);
+ if (r < 0)
+ return r;
+ }
}
#endif
if (stream->dnstls_data.shutdown) {
r = gnutls_bye(stream->dnstls_data.session, GNUTLS_SHUT_RDWR);
- if (r == GNUTLS_E_AGAIN)
+ if (r == GNUTLS_E_AGAIN) {
+ stream->dnstls_events = gnutls_record_get_direction(stream->dnstls_data.session) == 1 ? EPOLLOUT : EPOLLIN;
return -EAGAIN;
- else if (r < 0)
+ } else if (r < 0)
log_debug("Failed to invoke gnutls_bye: %s", gnutls_strerror(r));
+ stream->dnstls_events = 0;
stream->dnstls_data.shutdown = false;
dns_stream_unref(stream);
return DNSTLS_STREAM_CLOSED;
} else if (stream->dnstls_data.handshake < 0) {
stream->dnstls_data.handshake = gnutls_handshake(stream->dnstls_data.session);
- if (stream->dnstls_data.handshake == GNUTLS_E_AGAIN)
+ if (stream->dnstls_data.handshake == GNUTLS_E_AGAIN) {
+ stream->dnstls_events = gnutls_record_get_direction(stream->dnstls_data.session) == 1 ? EPOLLOUT : EPOLLIN;
return -EAGAIN;
- else if (stream->dnstls_data.handshake < 0) {
+ } else if (stream->dnstls_data.handshake < 0) {
log_debug("Failed to invoke gnutls_handshake: %s", gnutls_strerror(stream->dnstls_data.handshake));
if (gnutls_error_is_fatal(stream->dnstls_data.handshake))
return -ECONNREFUSED;
}
+
+ stream->dnstls_events = 0;
}
return 0;