X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Fresolve%2Fresolved-dnstls-openssl.c;h=22d579a7f7777fe0c0446bbe326bb0a07d005c8f;hp=f269e4d6487fd6dd0621c3aa41767bc52459404f;hb=71a681ae50175a569bf832d2615fd11994c41d73;hpb=c81872157980e42bff0e2e9f0f9136875b57f67b diff --git a/src/resolve/resolved-dnstls-openssl.c b/src/resolve/resolved-dnstls-openssl.c index f269e4d6487..22d579a7f77 100644 --- a/src/resolve/resolved-dnstls-openssl.c +++ b/src/resolve/resolved-dnstls-openssl.c @@ -20,12 +20,12 @@ static int dnstls_flush_write_buffer(DnsStream *stream) { 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) @@ -33,12 +33,14 @@ static int dnstls_flush_write_buffer(DnsStream *stream) { 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; } } } @@ -52,6 +54,7 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { int error, r; assert(stream); + assert(stream->manager); assert(server); rb = BIO_new_socket(stream->fd, 0); @@ -63,8 +66,9 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { 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; @@ -86,12 +90,13 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) { } 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; } @@ -332,22 +337,33 @@ ssize_t dnstls_stream_read(DnsStream *stream, void *buf, size_t count) { 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); +int 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 (server->dnstls_data.session) - SSL_SESSION_free(server->dnstls_data.session); + if (!manager->dnstls_data.ctx) + return -ENOMEM; + + 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); + + return 0; +} + +void dnstls_manager_free(Manager *manager) { + assert(manager); + + if (manager->dnstls_data.ctx) + SSL_CTX_free(manager->dnstls_data.ctx); }