#include <openssl/bio.h>
#include <openssl/err.h>
+#include "io-util.h"
#include "resolved-dns-stream.h"
#include "resolved-dnstls.h"
-#include "io-util.h"
-
DEFINE_TRIVIAL_CLEANUP_FUNC(SSL*, SSL_free);
DEFINE_TRIVIAL_CLEANUP_FUNC(BIO*, BIO_free);
assert(stream);
assert(stream->encrypted);
- if (stream->dnstls_data.write_buffer->length > 0) {
+ if (stream->dnstls_data.buffer_offset < stream->dnstls_data.write_buffer->length) {
assert(stream->dnstls_data.write_buffer->data);
struct iovec iov[1];
- iov[0] = IOVEC_MAKE(stream->dnstls_data.write_buffer->data,
- stream->dnstls_data.write_buffer->length);
+ iov[0] = IOVEC_MAKE(stream->dnstls_data.write_buffer->data + stream->dnstls_data.buffer_offset,
+ stream->dnstls_data.write_buffer->length - stream->dnstls_data.buffer_offset);
ss = dns_stream_writev(stream, iov, 1, DNS_STREAM_WRITE_TLS_DATA);
if (ss < 0) {
if (ss == -EAGAIN)
return ss;
} else {
- stream->dnstls_data.write_buffer->length -= ss;
- stream->dnstls_data.write_buffer->data += ss;
+ stream->dnstls_data.buffer_offset += ss;
- if (stream->dnstls_data.write_buffer->length > 0) {
+ if (stream->dnstls_data.buffer_offset < stream->dnstls_data.write_buffer->length) {
stream->dnstls_events |= EPOLLOUT;
return -EAGAIN;
+ } else {
+ BIO_reset(SSL_get_wbio(stream->dnstls_data.ssl));
+ stream->dnstls_data.buffer_offset = 0;
}
}
}
int error, r;
assert(stream);
+ assert(stream->manager);
assert(server);
rb = BIO_new_socket(stream->fd, 0);
return -ENOMEM;
BIO_get_mem_ptr(wb, &stream->dnstls_data.write_buffer);
+ stream->dnstls_data.buffer_offset = 0;
- s = SSL_new(server->dnstls_data.ctx);
+ s = SSL_new(stream->manager->dnstls_data.ctx);
if (!s)
return -ENOMEM;
}
stream->encrypted = true;
+ stream->dnstls_data.ssl = TAKE_PTR(s);
r = dnstls_flush_write_buffer(stream);
- if (r < 0 && r != -EAGAIN)
+ if (r < 0 && r != -EAGAIN) {
+ SSL_free(TAKE_PTR(stream->dnstls_data.ssl));
return r;
-
- stream->dnstls_data.ssl = TAKE_PTR(s);
+ }
return 0;
}
return ss;
}
-void dnstls_server_init(DnsServer *server) {
+void dnstls_server_free(DnsServer *server) {
assert(server);
- server->dnstls_data.ctx = SSL_CTX_new(TLS_client_method());
- if (server->dnstls_data.ctx) {
- SSL_CTX_set_min_proto_version(server->dnstls_data.ctx, TLS1_2_VERSION);
- SSL_CTX_set_options(server->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
- }
+ if (server->dnstls_data.session)
+ SSL_SESSION_free(server->dnstls_data.session);
}
-void dnstls_server_free(DnsServer *server) {
- assert(server);
+void dnstls_manager_init(Manager *manager) {
+ int r;
+ assert(manager);
- if (server->dnstls_data.ctx)
- SSL_CTX_free(server->dnstls_data.ctx);
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ manager->dnstls_data.ctx = SSL_CTX_new(TLS_client_method());
+ if (manager->dnstls_data.ctx) {
+ SSL_CTX_set_min_proto_version(manager->dnstls_data.ctx, TLS1_2_VERSION);
+ SSL_CTX_set_options(manager->dnstls_data.ctx, SSL_OP_NO_COMPRESSION);
+ }
+}
- if (server->dnstls_data.session)
- SSL_SESSION_free(server->dnstls_data.session);
+void dnstls_manager_free(Manager *manager) {
+ assert(manager);
+
+ if (manager->dnstls_data.ctx)
+ SSL_CTX_free(manager->dnstls_data.ctx);
}