From c53a87b8d93537af0ad6c0f63bca23c4bea488bf Mon Sep 17 00:00:00 2001 From: Nick Peng Date: Sun, 31 Jan 2021 03:04:17 +0800 Subject: [PATCH] SSL: reduce memory usage. --- src/dns_client.c | 72 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/src/dns_client.c b/src/dns_client.c index 37c2297..6c01530 100644 --- a/src/dns_client.c +++ b/src/dns_client.c @@ -184,6 +184,9 @@ struct dns_client { struct list_head dns_server_list; struct dns_server_group *default_group; + SSL_CTX *ssl_ctx; + int ssl_verify_skip; + /* query list */ pthread_mutex_t dns_request_lock; struct list_head dns_request_list; @@ -872,6 +875,47 @@ static int _dns_client_set_trusted_cert(SSL_CTX *ssl_ctx) return 0; } +SSL_CTX *_ssl_ctx_get(void) +{ + pthread_mutex_lock(&client.server_list_lock); + SSL_CTX *ssl_ctx = client.ssl_ctx; + if (ssl_ctx) { + pthread_mutex_unlock(&client.server_list_lock); + return ssl_ctx; + } + +#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) + ssl_ctx = SSL_CTX_new(TLS_client_method()); +#else + ssl_ctx = SSL_CTX_new(SSLv23_client_method()); +#endif + + if (ssl_ctx == NULL) { + tlog(TLOG_ERROR, "init ssl failed."); + goto errout; + } + + SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT); + SSL_CTX_sess_set_cache_size(ssl_ctx, DNS_MAX_SERVERS); + if (_dns_client_set_trusted_cert(ssl_ctx) != 0) { + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL); + client.ssl_verify_skip = 1; + } + + client.ssl_ctx = ssl_ctx; + pthread_mutex_unlock(&client.server_list_lock); + return client.ssl_ctx; +errout: + + pthread_mutex_unlock(&client.server_list_lock); + if (ssl_ctx) { + SSL_CTX_free(ssl_ctx); + } + + return NULL; +} + /* add dns server information */ static int _dns_client_server_add(char *server_ip, char *server_host, int port, dns_server_type_t server_type, struct client_dns_server_flags *flags) @@ -973,24 +1017,14 @@ static int _dns_client_server_add(char *server_ip, char *server_host, int port, /* if server type is TLS, create ssl context */ if (server_type == DNS_SERVER_TLS || server_type == DNS_SERVER_HTTPS) { -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) - server_info->ssl_ctx = SSL_CTX_new(TLS_client_method()); -#else - server_info->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); -#endif - + server_info->ssl_ctx = _ssl_ctx_get(); if (server_info->ssl_ctx == NULL) { tlog(TLOG_ERROR, "init ssl failed."); goto errout; } - SSL_CTX_set_options(server_info->ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); - SSL_CTX_set_session_cache_mode(server_info->ssl_ctx, SSL_SESS_CACHE_CLIENT); - SSL_CTX_sess_set_cache_size(server_info->ssl_ctx, 32); - if (_dns_client_set_trusted_cert(server_info->ssl_ctx) != 0) { - tlog(TLOG_WARN, "disable check certificate for %s.", server_info->ip); + if (client.ssl_verify_skip) { server_info->skip_check_cert = 1; - SSL_CTX_set_verify(server_info->ssl_ctx, SSL_VERIFY_NONE, NULL); } } @@ -1035,11 +1069,6 @@ errout: fast_ping_stop(server_info->ping_host); } - if (server_info->ssl_ctx) { - SSL_CTX_free(server_info->ssl_ctx); - server_info->ssl_ctx = NULL; - } - pthread_mutex_destroy(&server_info->lock); free(server_info); } @@ -1125,10 +1154,7 @@ static void _dns_client_server_close(struct dns_server_info *server_info) server_info->ssl_session = NULL; } - if (server_info->ssl_ctx) { - SSL_CTX_free(server_info->ssl_ctx); - server_info->ssl_ctx = NULL; - } + server_info->ssl_ctx = NULL; } /* remove all servers information */ @@ -3315,4 +3341,8 @@ void dns_client_exit(void) pthread_mutex_destroy(&client.server_list_lock); pthread_mutex_destroy(&client.domain_map_lock); + if (client.ssl_ctx) { + SSL_CTX_free(client.ssl_ctx); + client.ssl_ctx = NULL; + } }