瀏覽代碼

dialplan: basic safety for concurent rpc reload

- reported by GH #1874

(cherry picked from commit 99d5da8d595961063249f871a5d150474fa6f317)
(cherry picked from commit 567c5b91ff0de3237d4dc98138675f19e152bcf5)
(cherry picked from commit 6b7a4735339bbb0cfa7919d160d064f3729e8e97)
Daniel-Constantin Mierla 6 年之前
父節點
當前提交
e9ecbdc328
共有 1 個文件被更改,包括 24 次插入0 次删除
  1. 24 0
      src/modules/dialplan/dialplan.c

+ 24 - 0
src/modules/dialplan/dialplan.c

@@ -80,6 +80,8 @@ dp_param_p default_par2 = NULL;
 int dp_fetch_rows = 1000;
 int dp_match_dynamic = 0;
 
+static time_t *dp_rpc_reload_time = NULL;
+
 static param_export_t mod_params[]={
 	{ "db_url",			PARAM_STR,	&dp_db_url },
 	{ "table_name",		PARAM_STR,	&dp_table_name },
@@ -174,6 +176,13 @@ static int mod_init(void)
 		return -1;
 	}
 
+	dp_rpc_reload_time = shm_malloc(sizeof(time_t));
+	if(dp_rpc_reload_time == NULL) {
+		SHM_MEM_ERROR;
+		return -1;
+	}
+	*dp_rpc_reload_time = 0;
+
 	return 0;
 }
 
@@ -191,6 +200,10 @@ static void mod_destroy(void)
 		shm_free(default_par2);
 		default_par2 = NULL;
 	}
+	if(dp_rpc_reload_time!=NULL) {
+		shm_free(dp_rpc_reload_time);
+		dp_rpc_reload_time = 0;
+	}
 	destroy_data();
 }
 
@@ -475,6 +488,17 @@ static const char* dialplan_rpc_reload_doc[2] = {
  */
 static void dialplan_rpc_reload(rpc_t* rpc, void* ctx)
 {
+	if(dp_rpc_reload_time==NULL) {
+		LM_ERR("not ready for reload\n");
+		rpc->fault(ctx, 500, "Not ready for reload");
+		return;
+	}
+	if(*dp_rpc_reload_time!=0 && *dp_rpc_reload_time > time(NULL) - 5) {
+		LM_ERR("ongoing reload\n");
+		rpc->fault(ctx, 500, "ongoing reload");
+		return;
+	}
+	*dp_rpc_reload_time = time(NULL);
 	if (dp_connect_db() < 0) {
 		LM_ERR("failed to reload rules fron database (db connect)\n");
 		rpc->fault(ctx, 500, "DB Connection Error");