Просмотр исходного кода

client_quic: fix race condition.

Nick Peng 4 месяцев назад
Родитель
Сommit
d9d274c0f6

+ 6 - 6
src/dns_client/client_quic.c

@@ -317,7 +317,7 @@ int _dns_client_create_socket_quic(struct dns_server_info *server_info, const ch
 		goto errout;
 	}
 
-	tlog(TLOG_DEBUG, "quic server %s connecting.\n", server_info->ip);
+	tlog(TLOG_DEBUG, "quic server %s:%d connecting.\n", server_info->ip, server_info->port);
 
 	return 0;
 errout:
@@ -388,7 +388,7 @@ static int _dns_client_process_quic_poll(struct dns_server_info *server_info)
 		pthread_mutex_unlock(&server_info->lock);
 
 		if (poll_item_count <= 0) {
-			SSL_handle_events(server_info->ssl);
+			_ssl_do_handevent(server_info);
 			break;
 		}
 
@@ -493,7 +493,7 @@ int _dns_client_process_quic(struct dns_server_info *server_info, struct epoll_e
 				ret = 0;
 			}
 			pthread_mutex_unlock(&server_info->lock);
-			tlog(TLOG_DEBUG, "quic server %s peer close", server_info->ip);
+			tlog(TLOG_DEBUG, "quic server %s:%d peer close", server_info->ip, server_info->port);
 			return ret;
 		}
 
@@ -530,7 +530,7 @@ int _dns_client_process_quic(struct dns_server_info *server_info, struct epoll_e
 			if (send_len < 0) {
 				if (errno == EAGAIN) {
 					epoll_events = EPOLLIN | EPOLLOUT;
-					SSL_handle_events(server_info->ssl);
+					_ssl_do_handevent(server_info);
 				}
 			}
 
@@ -637,8 +637,8 @@ int _dns_client_send_quic_data(struct dns_query_struct *query, struct dns_server
 		goto out;
 	}
 
-	/* run hand shake */
-	SSL_handle_events(server_info->ssl);
+	/* run quic handevent */
+	_ssl_do_handevent(server_info);
 
 	SSL *quic_stream = SSL_new_stream(server_info->ssl, 0);
 	if (quic_stream == NULL) {

+ 33 - 28
src/dns_client/client_socket.c

@@ -31,23 +31,26 @@
 
 int _dns_client_create_socket(struct dns_server_info *server_info)
 {
+	int ret = -1;
+	pthread_mutex_lock(&server_info->lock);
 	time(&server_info->last_send);
 	time(&server_info->last_recv);
 
 	if (server_info->fd > 0) {
+		pthread_mutex_unlock(&server_info->lock);
 		return -1;
 	}
 
 	if (server_info->type == DNS_SERVER_UDP) {
-		return _dns_client_create_socket_udp(server_info);
+		ret = _dns_client_create_socket_udp(server_info);
 	} else if (server_info->type == DNS_SERVER_MDNS) {
-		return _dns_client_create_socket_udp_mdns(server_info);
+		ret = _dns_client_create_socket_udp_mdns(server_info);
 	} else if (server_info->type == DNS_SERVER_TCP) {
-		return _dns_client_create_socket_tcp(server_info);
+		ret = _dns_client_create_socket_tcp(server_info);
 	} else if (server_info->type == DNS_SERVER_TLS) {
 		struct client_dns_server_flag_tls *flag_tls = NULL;
 		flag_tls = &server_info->flags.tls;
-		return _dns_client_create_socket_tls(server_info, flag_tls->hostname, flag_tls->alpn);
+		ret = _dns_client_create_socket_tls(server_info, flag_tls->hostname, flag_tls->alpn);
 	} else if (server_info->type == DNS_SERVER_QUIC) {
 		struct client_dns_server_flag_tls *flag_tls = NULL;
 		const char *alpn = "doq";
@@ -55,11 +58,11 @@ int _dns_client_create_socket(struct dns_server_info *server_info)
 		if (flag_tls->alpn[0] != 0) {
 			alpn = flag_tls->alpn;
 		}
-		return _dns_client_create_socket_quic(server_info, flag_tls->hostname, alpn);
+		ret = _dns_client_create_socket_quic(server_info, flag_tls->hostname, alpn);
 	} else if (server_info->type == DNS_SERVER_HTTPS) {
 		struct client_dns_server_flag_https *flag_https = NULL;
 		flag_https = &server_info->flags.https;
-		return _dns_client_create_socket_tls(server_info, flag_https->hostname, flag_https->alpn);
+		ret = _dns_client_create_socket_tls(server_info, flag_https->hostname, flag_https->alpn);
 	} else if (server_info->type == DNS_SERVER_HTTP3) {
 		struct client_dns_server_flag_https *flag_https = NULL;
 		const char *alpn = "h3";
@@ -67,19 +70,32 @@ int _dns_client_create_socket(struct dns_server_info *server_info)
 		if (flag_https->alpn[0] != 0) {
 			alpn = flag_https->alpn;
 		}
-		return _dns_client_create_socket_quic(server_info, flag_https->hostname, alpn);
+		ret = _dns_client_create_socket_quic(server_info, flag_https->hostname, alpn);
 	} else {
-		return -1;
+		ret = -1;
 	}
 
-	return 0;
+	pthread_mutex_unlock(&server_info->lock);
+
+	return ret;
 }
 
 void _dns_client_close_socket_ext(struct dns_server_info *server_info, int no_del_conn_list)
 {
+	dns_server_status server_status = DNS_SERVER_STATUS_DISCONNECTED;
+
+	pthread_mutex_lock(&server_info->lock);
+	server_status = server_info->status;
+	server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
+
+	/* remove fd from epoll */
+	if (server_info->fd > 0) {
+		epoll_ctl(client.epoll_fd, EPOLL_CTL_DEL, server_info->fd, NULL);
+	}
+
 	if (server_info->ssl) {
 		/* Shutdown ssl */
-		if (server_info->status == DNS_SERVER_STATUS_CONNECTED) {
+		if (server_status == DNS_SERVER_STATUS_CONNECTED) {
 			_ssl_shutdown(server_info);
 		}
 
@@ -87,7 +103,6 @@ void _dns_client_close_socket_ext(struct dns_server_info *server_info, int no_de
 			struct dns_conn_stream *conn_stream = NULL;
 			struct dns_conn_stream *tmp = NULL;
 
-			pthread_mutex_lock(&server_info->lock);
 			list_for_each_entry_safe(conn_stream, tmp, &server_info->conn_stream_list, server_list)
 			{
 				if (conn_stream->quic_stream) {
@@ -106,41 +121,31 @@ void _dns_client_close_socket_ext(struct dns_server_info *server_info, int no_de
 				list_del_init(&conn_stream->server_list);
 				_dns_client_conn_stream_put(conn_stream);
 			}
-
-			pthread_mutex_unlock(&server_info->lock);
 		}
-
+		
 		SSL_free(server_info->ssl);
 		server_info->ssl = NULL;
 		server_info->ssl_write_len = -1;
 	}
-
+	
 	if (server_info->bio_method) {
 		BIO_meth_free(server_info->bio_method);
 		server_info->bio_method = NULL;
 	}
-
-	if (server_info->fd <= 0) {
-		return;
-	}
-
-	/* remove fd from epoll */
-	if (server_info->fd > 0) {
-		epoll_ctl(client.epoll_fd, EPOLL_CTL_DEL, server_info->fd, NULL);
-	}
-
+	
 	if (server_info->proxy) {
 		proxy_conn_free(server_info->proxy);
 		server_info->proxy = NULL;
-	} else {
+	} else if (server_info->fd > 0) {
 		close(server_info->fd);
 	}
-
+	
 	server_info->fd = -1;
-	server_info->status = DNS_SERVER_STATUS_DISCONNECTED;
 	/* update send recv time */
 	time(&server_info->last_send);
 	time(&server_info->last_recv);
+
+	pthread_mutex_unlock(&server_info->lock);
 	tlog(TLOG_DEBUG, "server %s:%d closed.", server_info->ip, server_info->port);
 }
 

+ 5 - 4
src/dns_client/client_tcp.c

@@ -24,6 +24,7 @@
 
 #include "client_socket.h"
 #include "client_tcp.h"
+#include "client_tls.h"
 #include "server_info.h"
 
 #include <net/if.h>
@@ -287,7 +288,7 @@ int _dns_client_process_tcp(struct dns_server_info *server_info, struct epoll_ev
 				ret = 0;
 			}
 			pthread_mutex_unlock(&client.server_list_lock);
-			tlog(TLOG_DEBUG, "peer close, %s", server_info->ip);
+			tlog(TLOG_DEBUG, "peer close, %s:%d", server_info->ip, server_info->port);
 			return ret;
 		}
 
@@ -423,10 +424,10 @@ void _dns_client_check_tcp(void)
 #ifdef OSSL_QUIC1_VERSION
 		if (server_info->type == DNS_SERVER_QUIC || server_info->type == DNS_SERVER_HTTP3) {
 			if (server_info->ssl) {
-				SSL_handle_events(server_info->ssl);
+				_ssl_do_handevent(server_info);
 				if (SSL_get_shutdown(server_info->ssl) != 0) {
 					_dns_client_close_socket_ext(server_info, 1);
-					tlog(TLOG_DEBUG, "quick server %s shutdown.", server_info->ip);
+					tlog(TLOG_DEBUG, "quick server %s:%d shutdown.", server_info->ip, server_info->port);
 				}
 			}
 		}
@@ -434,7 +435,7 @@ void _dns_client_check_tcp(void)
 
 		if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
 			if (server_info->last_recv + DNS_TCP_CONNECT_TIMEOUT < now) {
-				tlog(TLOG_DEBUG, "server %s connect timeout.", server_info->ip);
+				tlog(TLOG_DEBUG, "server %s:%d connect timeout.", server_info->ip, server_info->port);
 				_dns_client_close_socket(server_info);
 			}
 		} else if (server_info->status == DNS_SERVER_STATUS_CONNECTED) {

+ 32 - 8
src/dns_client/client_tls.c

@@ -40,10 +40,11 @@
 static ssize_t _ssl_read_ext(struct dns_server_info *server, SSL *ssl, void *buff, int num)
 {
 	ssize_t ret = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || buff == NULL || ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
-	pthread_mutex_lock(&server->lock);
 	ret = SSL_read(ssl, buff, num);
 	pthread_mutex_unlock(&server->lock);
 	return ret;
@@ -53,11 +54,12 @@ static ssize_t _ssl_write_ext2(struct dns_server_info *server, SSL *ssl, const v
 {
 	ssize_t ret = 0;
 	size_t written = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || buff == NULL || ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&server->lock);
 #ifdef OSSL_QUIC1_VERSION
 	ret = SSL_write_ex2(ssl, buff, num, flags, &written);
 #else
@@ -75,11 +77,12 @@ static ssize_t _ssl_write_ext2(struct dns_server_info *server, SSL *ssl, const v
 int _ssl_shutdown(struct dns_server_info *server)
 {
 	int ret = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || server->ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&server->lock);
 	ret = SSL_shutdown(server->ssl);
 	pthread_mutex_unlock(&server->lock);
 	return ret;
@@ -88,11 +91,12 @@ int _ssl_shutdown(struct dns_server_info *server)
 static int _ssl_get_error_ext(struct dns_server_info *server, SSL *ssl, int ret)
 {
 	int err = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&server->lock);
 	err = SSL_get_error(ssl, ret);
 	pthread_mutex_unlock(&server->lock);
 	return err;
@@ -106,24 +110,43 @@ static int _ssl_get_error(struct dns_server_info *server, int ret)
 static int _ssl_do_handshake(struct dns_server_info *server)
 {
 	int err = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || server->ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&server->lock);
 	err = SSL_do_handshake(server->ssl);
 	pthread_mutex_unlock(&server->lock);
 	return err;
 }
 
-static int _ssl_session_reused(struct dns_server_info *server)
+int _ssl_do_handevent(struct dns_server_info *server)
 {
 	int err = 0;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || server->ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return SSL_ERROR_SYSCALL;
 	}
+#ifdef OSSL_QUIC1_VERSION
+	err = SSL_handle_events(server->ssl);
+#else
+	err = SSL_ERROR_SYSCALL;
+#endif
+	pthread_mutex_unlock(&server->lock);
+	return err;
+}
 
+static int _ssl_session_reused(struct dns_server_info *server)
+{
+	int err = 0;
 	pthread_mutex_lock(&server->lock);
+	if (server == NULL || server->ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
+		return SSL_ERROR_SYSCALL;
+	}
+
 	err = SSL_session_reused(server->ssl);
 	pthread_mutex_unlock(&server->lock);
 	return err;
@@ -132,11 +155,12 @@ static int _ssl_session_reused(struct dns_server_info *server)
 static SSL_SESSION *_ssl_get1_session(struct dns_server_info *server)
 {
 	SSL_SESSION *ret = NULL;
+	pthread_mutex_lock(&server->lock);
 	if (server == NULL || server->ssl == NULL) {
+		pthread_mutex_unlock(&server->lock);
 		return NULL;
 	}
 
-	pthread_mutex_lock(&server->lock);
 	ret = SSL_get1_session(server->ssl);
 	pthread_mutex_unlock(&server->lock);
 	return ret;
@@ -962,7 +986,7 @@ int _dns_client_process_tls(struct dns_server_info *server_info, struct epoll_ev
 	}
 
 	if (server_info->status == DNS_SERVER_STATUS_CONNECTING) {
-		/* do SSL hand shake */
+		/* do SSL handshake */
 		ret = _ssl_do_handshake(server_info);
 		if (ret <= 0) {
 			memset(&fd_event, 0, sizeof(fd_event));

+ 2 - 0
src/dns_client/client_tls.h

@@ -47,6 +47,8 @@ SSL_CTX *_ssl_ctx_get(int is_quic);
 
 int _ssl_shutdown(struct dns_server_info *server);
 
+int _ssl_do_handevent(struct dns_server_info *server);
+
 #ifdef __cplusplus
 }
 #endif /*__cplusplus */

+ 1 - 1
src/dns_client/client_udp.c

@@ -273,7 +273,7 @@ static int _dns_client_process_udp_proxy(struct dns_server_info *server_info, st
 			ret = 0;
 		}
 		pthread_mutex_unlock(&server_info->lock);
-		tlog(TLOG_DEBUG, "peer close, %s", server_info->ip);
+		tlog(TLOG_DEBUG, "peer close, %s:%d", server_info->ip, server_info->port);
 		return ret;
 	}
 

+ 43 - 4
src/dns_plugin.c

@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
 
 struct dns_plugin_ops {
 	struct list_head list;
@@ -51,6 +52,7 @@ struct dns_plugin {
 
 struct dns_plugins {
 	struct list_head list;
+	pthread_rwlock_t lock;
 	DECLARE_HASHTABLE(plugin, 4);
 };
 
@@ -64,10 +66,11 @@ int smartdns_plugin_func_server_recv(struct dns_packet *packet, unsigned char *i
 	struct dns_plugin_ops *chain = NULL;
 	int ret = 0;
 
-	if (is_plugin_init == 0) {
+	if (unlikely(is_plugin_init == 0)) {
 		return 0;
 	}
 
+	pthread_rwlock_rdlock(&plugins.lock);
 	list_for_each_entry(chain, &plugins.list, list)
 	{
 		if (!chain->ops.server_recv) {
@@ -76,9 +79,11 @@ int smartdns_plugin_func_server_recv(struct dns_packet *packet, unsigned char *i
 
 		ret = chain->ops.server_recv(packet, inpacket, inpacket_len, local, local_len, from, from_len);
 		if (ret != 0) {
+			pthread_rwlock_unlock(&plugins.lock);
 			return ret;
 		}
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return 0;
 }
@@ -87,10 +92,11 @@ void smartdns_plugin_func_server_complete_request(struct dns_request *request)
 {
 	struct dns_plugin_ops *chain = NULL;
 
-	if (is_plugin_init == 0) {
+	if (unlikely(is_plugin_init == 0)) {
 		return;
 	}
 
+	pthread_rwlock_rdlock(&plugins.lock);
 	list_for_each_entry(chain, &plugins.list, list)
 	{
 		if (!chain->ops.server_query_complete) {
@@ -99,6 +105,7 @@ void smartdns_plugin_func_server_complete_request(struct dns_request *request)
 
 		chain->ops.server_query_complete(request);
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return;
 }
@@ -107,10 +114,11 @@ void smartdns_plugin_func_server_log_callback(smartdns_log_level level, const ch
 {
 	struct dns_plugin_ops *chain = NULL;
 
-	if (is_plugin_init == 0) {
+	if (unlikely(is_plugin_init == 0)) {
 		return;
 	}
 
+	pthread_rwlock_rdlock(&plugins.lock);
 	list_for_each_entry(chain, &plugins.list, list)
 	{
 		if (!chain->ops.server_log) {
@@ -119,6 +127,7 @@ void smartdns_plugin_func_server_log_callback(smartdns_log_level level, const ch
 
 		chain->ops.server_log(level, msg, msg_len);
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return;
 }
@@ -133,7 +142,9 @@ int smartdns_operations_register(const struct smartdns_operations *operations)
 	}
 
 	memcpy(&chain->ops, operations, sizeof(struct smartdns_operations));
+	pthread_rwlock_wrlock(&plugins.lock);
 	list_add_tail(&chain->list, &plugins.list);
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return 0;
 }
@@ -143,14 +154,17 @@ int smartdns_operations_unregister(const struct smartdns_operations *operations)
 	struct dns_plugin_ops *chain = NULL;
 	struct dns_plugin_ops *tmp = NULL;
 
+	pthread_rwlock_wrlock(&plugins.lock);
 	list_for_each_entry_safe(chain, tmp, &plugins.list, list)
 	{
 		if (memcmp(&chain->ops, operations, sizeof(struct smartdns_operations)) == 0) {
 			list_del(&chain->list);
+			pthread_rwlock_unlock(&plugins.lock);
 			free(chain);
 			return 0;
 		}
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return -1;
 }
@@ -161,12 +175,15 @@ static struct dns_plugin *_dns_plugin_get(const char *plugin_file)
 	unsigned int key = 0;
 
 	key = hash_string(plugin_file);
+	pthread_rwlock_rdlock(&plugins.lock);
 	hash_for_each_possible(plugins.plugin, plugin, node, key)
 	{
 		if (strncmp(plugin->file, plugin_file, PATH_MAX - 1) == 0) {
+			pthread_rwlock_unlock(&plugins.lock);
 			return plugin;
 		}
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return NULL;
 }
@@ -254,10 +271,21 @@ static struct dns_plugin *_dns_plugin_new(const char *plugin_file)
 	return plugin;
 }
 
+static int _dns_plugin_remove_locked(struct dns_plugin *plugin)
+{
+	_dns_plugin_unload_library(plugin);
+	hash_del(&plugin->node);
+	free(plugin);
+
+	return 0;
+}
+
 static int _dns_plugin_remove(struct dns_plugin *plugin)
 {
 	_dns_plugin_unload_library(plugin);
+	pthread_rwlock_wrlock(&plugins.lock);
 	hash_del(&plugin->node);
+	pthread_rwlock_unlock(&plugins.lock);
 	free(plugin);
 
 	return 0;
@@ -323,11 +351,13 @@ static int _dns_plugin_remove_all_ops(void)
 	struct dns_plugin_ops *chain = NULL;
 	struct dns_plugin_ops *tmp = NULL;
 
+	pthread_rwlock_wrlock(&plugins.lock);
 	list_for_each_entry_safe(chain, tmp, &plugins.list, list)
 	{
 		list_del(&chain->list);
 		free(chain);
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return 0;
 }
@@ -338,10 +368,12 @@ static int _dns_plugin_remove_all(void)
 	struct hlist_node *tmp = NULL;
 	unsigned int key = 0;
 
+	pthread_rwlock_wrlock(&plugins.lock);
 	hash_for_each_safe(plugins.plugin, key, tmp, plugin, node)
 	{
-		_dns_plugin_remove(plugin);
+		_dns_plugin_remove_locked(plugin);
 	}
+	pthread_rwlock_unlock(&plugins.lock);
 
 	return -1;
 }
@@ -354,6 +386,10 @@ int dns_server_plugin_init(void)
 
 	hash_init(plugins.plugin);
 	INIT_LIST_HEAD(&plugins.list);
+	if (pthread_rwlock_init(&plugins.lock, NULL) != 0) {
+		tlog(TLOG_ERROR, "init plugin rwlock failed.");
+		return -1;
+	}
 	is_plugin_init = 1;
 	return 0;
 }
@@ -366,6 +402,9 @@ void dns_server_plugin_exit(void)
 
 	_dns_plugin_remove_all_ops();
 	_dns_plugin_remove_all();
+
+	pthread_rwlock_destroy(&plugins.lock);
+	is_plugin_init = 0;
 	return;
 }
 

+ 8 - 4
src/dns_server/server_tls.c

@@ -34,11 +34,12 @@
 static ssize_t _ssl_read(struct dns_server_conn_tls_client *conn, void *buff, int num)
 {
 	ssize_t ret = 0;
+	pthread_mutex_lock(&conn->ssl_lock);
 	if (conn == NULL || buff == NULL) {
+		pthread_mutex_unlock(&conn->ssl_lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&conn->ssl_lock);
 	ret = SSL_read(conn->ssl, buff, num);
 	pthread_mutex_unlock(&conn->ssl_lock);
 	return ret;
@@ -47,11 +48,12 @@ static ssize_t _ssl_read(struct dns_server_conn_tls_client *conn, void *buff, in
 static ssize_t _ssl_write(struct dns_server_conn_tls_client *conn, const void *buff, int num)
 {
 	ssize_t ret = 0;
+	pthread_mutex_lock(&conn->ssl_lock);
 	if (conn == NULL || buff == NULL || conn->ssl == NULL) {
+		pthread_mutex_unlock(&conn->ssl_lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&conn->ssl_lock);
 	ret = SSL_write(conn->ssl, buff, num);
 	pthread_mutex_unlock(&conn->ssl_lock);
 	return ret;
@@ -60,11 +62,12 @@ static ssize_t _ssl_write(struct dns_server_conn_tls_client *conn, const void *b
 static int _ssl_get_error(struct dns_server_conn_tls_client *conn, int ret)
 {
 	int err = 0;
+	pthread_mutex_lock(&conn->ssl_lock);
 	if (conn == NULL || conn->ssl == NULL) {
+		pthread_mutex_unlock(&conn->ssl_lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&conn->ssl_lock);
 	err = SSL_get_error(conn->ssl, ret);
 	pthread_mutex_unlock(&conn->ssl_lock);
 	return err;
@@ -73,11 +76,12 @@ static int _ssl_get_error(struct dns_server_conn_tls_client *conn, int ret)
 static int _ssl_do_accept(struct dns_server_conn_tls_client *conn)
 {
 	int err = 0;
+	pthread_mutex_lock(&conn->ssl_lock);
 	if (conn == NULL || conn->ssl == NULL) {
+		pthread_mutex_unlock(&conn->ssl_lock);
 		return SSL_ERROR_SYSCALL;
 	}
 
-	pthread_mutex_lock(&conn->ssl_lock);
 	err = SSL_accept(conn->ssl);
 	pthread_mutex_unlock(&conn->ssl_lock);
 	return err;

+ 1 - 0
src/utils/daemon.c

@@ -296,6 +296,7 @@ int create_pid_file(const char *pid_file)
 		goto errout;
 	}
 
+	ftruncate(fd, 0);
 	snprintf(buff, TMP_BUFF_LEN_32, "%d\n", getpid());
 
 	if (write(fd, buff, strnlen(buff, TMP_BUFF_LEN_32)) < 0) {