Browse code

ndb_redis: new param to control the verbosity of some log messages

Daniel-Constantin Mierla authored on 04/07/2022 13:20:30
Showing 1 changed files
... ...
@@ -56,6 +56,7 @@ extern int redis_disable_time_param;
56 56
 extern int redis_allowed_timeouts_param;
57 57
 extern int redis_flush_on_reconnect_param;
58 58
 extern int redis_allow_dynamic_nodes_param;
59
+extern int ndb_redis_debug;
59 60
 
60 61
 /* backwards compatibility with hiredis < 0.12 */
61 62
 #if (HIREDIS_MAJOR == 0) && (HIREDIS_MINOR < 12)
... ...
@@ -198,8 +199,8 @@ int redisc_init(void)
198 199
 									}
199 200
 								}
200 201
 							}
201
-							LM_DBG("slave for %s: %s:%d\n", sentinel_group,
202
-									addr, port);
202
+							LOG(ndb_redis_debug, "slave for %s: %s:%d\n",
203
+									sentinel_group, addr, port);
203 204
 						}
204 205
 					}
205 206
 				}
... ...
@@ -207,15 +208,15 @@ int redisc_init(void)
207 208
 		}
208 209
 
209 210
 		if(sock != 0) {
210
-			LM_DBG("Connecting to unix socket: %s\n", unix_sock_path);
211
+			LOG(ndb_redis_debug, "Connecting to unix socket: %s\n", unix_sock_path);
211 212
 			rsrv->ctxRedis = redisConnectUnixWithTimeout(unix_sock_path,
212 213
 					tv_conn);
213 214
 		} else {
214
-			LM_DBG("Connecting to %s:%d\n", addr, port);
215
+			LOG(ndb_redis_debug, "Connecting to %s:%d\n", addr, port);
215 216
 			rsrv->ctxRedis = redisConnectWithTimeout(addr, port, tv_conn);
216 217
 		}
217 218
 
218
-		LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis);
219
+		LOG(ndb_redis_debug, "rsrv->ctxRedis = %p\n", rsrv->ctxRedis);
219 220
 
220 221
 		if(!rsrv->ctxRedis) {
221 222
 			LM_ERR("Failed to create REDIS-Context.\n");
... ...
@@ -390,18 +391,21 @@ redisc_server_t *redisc_get_server(str *name)
390 391
 	unsigned int hname;
391 392
 
392 393
 	hname = get_hash1_raw(name->s, name->len);
393
-	LM_DBG("Hash %u (%.*s)\n", hname, name->len, name->s);
394
+	LOG(ndb_redis_debug, "Hash %u (%.*s)\n", hname, name->len, name->s);
394 395
 	rsrv=_redisc_srv_list;
395 396
 	while(rsrv!=NULL)
396 397
 	{
397 398
 		LM_DBG("Entry %u (%.*s)\n", rsrv->hname,
398 399
 				rsrv->sname->len, rsrv->sname->s);
399 400
 		if(rsrv->hname==hname && rsrv->sname->len==name->len
400
-				&& strncmp(rsrv->sname->s, name->s, name->len)==0)
401
+				&& strncmp(rsrv->sname->s, name->s, name->len)==0) {
402
+			LOG(ndb_redis_debug, "Using entry %u (%.*s)\n", rsrv->hname,
403
+				rsrv->sname->len, rsrv->sname->s);
401 404
 			return rsrv;
405
+		}
402 406
 		rsrv=rsrv->next;
403 407
 	}
404
-	LM_DBG("No entry found.\n");
408
+	LOG(ndb_redis_debug, "No entry found.\n");
405 409
 	return NULL;
406 410
 }
407 411
 
... ...
@@ -497,7 +501,7 @@ int redisc_reconnect_server(redisc_server_t *rsrv)
497 501
 						strncpy(addr, res->element[0]->str,
498 502
 								res->element[0]->len + 1);
499 503
 						port = atoi(res->element[1]->str);
500
-						LM_DBG("sentinel replied: %s:%d\n", addr, port);
504
+						LOG(ndb_redis_debug, "sentinel replied: %s:%d\n", addr, port);
501 505
 					}
502 506
 				}
503 507
 				else {
... ...
@@ -520,7 +524,7 @@ int redisc_reconnect_server(redisc_server_t *rsrv)
520 524
 								}
521 525
 							}
522 526
 						}
523
-						LM_DBG("slave for %s: %s:%d\n", sentinel_group,
527
+						LOG(ndb_redis_debug, "slave for %s: %s:%d\n", sentinel_group,
524 528
 								addr, port);
525 529
 					}
526 530
 				}
... ...
@@ -689,7 +693,7 @@ int redisc_create_pipelined_message(redisc_server_t *rsrv)
689 693
 
690 694
 	if (rsrv->ctxRedis->err)
691 695
 	{
692
-		LM_DBG("Reconnecting server because of error %d: \"%s\"",
696
+		LOG(ndb_redis_debug, "Reconnecting server because of error %d: \"%s\"",
693 697
 				rsrv->ctxRedis->err,rsrv->ctxRedis->errstr);
694 698
 		if (redisc_reconnect_server(rsrv))
695 699
 		{
... ...
@@ -868,10 +872,10 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv)
868 872
 			name.len = snprintf(buffername, sizeof(buffername), "%.*s:%i",
869 873
 					addr.len, addr.s, port);
870 874
 			name.s = buffername;
871
-			LM_DBG("Name of new connection: %.*s\n", name.len, name.s);
875
+			LOG(ndb_redis_debug, "Name of new connection: %.*s\n", name.len, name.s);
872 876
 			rsrv_new = redisc_get_server(&name);
873 877
 			if(rsrv_new) {
874
-				LM_DBG("Reusing Connection\n");
878
+				LOG(ndb_redis_debug, "Reusing connection\n");
875 879
 				*rsrv = rsrv_new;
876 880
 				return 1;
877 881
 			} else if(redis_allow_dynamic_nodes_param) {
... ...
@@ -908,8 +912,8 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv)
908 912
 						*rsrv = rsrv_new;
909 913
 						/* Need to connect to the new server now */
910 914
 						if(redisc_reconnect_server(rsrv_new) == 0) {
911
-							LM_DBG("Connected to the new server with name: "
912
-								   "%.*s\n",
915
+							LOG(ndb_redis_debug, "Connected to the new server"
916
+									" with name: %.*s\n",
913 917
 									name.len, name.s);
914 918
 							return 1;
915 919
 						} else {
... ...
@@ -1159,13 +1163,14 @@ again:
1159 1163
 	/* null reply, reconnect and try again */
1160 1164
 	if(rsrv->ctxRedis->err)
1161 1165
 	{
1162
-		LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr);
1166
+		LOG(ndb_redis_debug, "Redis error: %s\n", rsrv->ctxRedis->errstr);
1163 1167
 	}
1164 1168
 
1165 1169
 	if(res)
1166 1170
 	{
1167 1171
 		if (check_cluster_reply(res, &rsrv)) {
1168 1172
 			freeReplyObject(res);
1173
+			LOG(ndb_redis_debug, "Retrying the command directly\n");
1169 1174
 			goto again;
1170 1175
 		}
1171 1176
 		return res;
... ...
@@ -1173,10 +1178,12 @@ again:
1173 1178
 
1174 1179
 	if(redisc_reconnect_server(rsrv)==0)
1175 1180
 	{
1181
+		LOG(ndb_redis_debug, "Trying to reconnect to server\n");
1176 1182
 		res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen);
1177 1183
 		if (res) {
1178 1184
 			if (check_cluster_reply(res, &rsrv)) {
1179 1185
 				freeReplyObject(res);
1186
+				LOG(ndb_redis_debug, "Retrying the command after reconnect\n");
1180 1187
 				goto again;
1181 1188
 			}
1182 1189
 		}
... ...
@@ -1264,6 +1271,7 @@ int redisc_free_reply(str *name)
1264 1271
 	}
1265 1272
 
1266 1273
 	/* reply entry not found. */
1274
+	LOG(ndb_redis_debug, "reply entry not found: %.*s\n", name->len, name->s);
1267 1275
 	return -1;
1268 1276
 }
1269 1277
 
Browse code

ndb_redis: clean up response on moved reply with cluster mode on

Daniel-Constantin Mierla authored on 04/07/2022 12:08:27
Showing 1 changed files
... ...
@@ -1165,6 +1165,7 @@ again:
1165 1165
 	if(res)
1166 1166
 	{
1167 1167
 		if (check_cluster_reply(res, &rsrv)) {
1168
+			freeReplyObject(res);
1168 1169
 			goto again;
1169 1170
 		}
1170 1171
 		return res;
... ...
@@ -1175,6 +1176,7 @@ again:
1175 1176
 		res = redisCommandArgv(rsrv->ctxRedis, argc, argv, argvlen);
1176 1177
 		if (res) {
1177 1178
 			if (check_cluster_reply(res, &rsrv)) {
1179
+				freeReplyObject(res);
1178 1180
 				goto again;
1179 1181
 			}
1180 1182
 		}
Browse code

ndb_redis: wrap if block in curly braces

- GH #3012

Daniel-Constantin Mierla authored on 08/02/2022 07:19:03
Showing 1 changed files
... ...
@@ -39,8 +39,10 @@
39 39
 
40 40
 #include "redis_client.h"
41 41
 
42
-#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); \
43
-		if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;})
42
+#define redisCommandNR(a...) (int)({ \
43
+		void *__tmp; __tmp = redisCommand(a); \
44
+		if (__tmp) { freeReplyObject(__tmp); }; \
45
+		__tmp ? 0 : -1;})
44 46
 
45 47
 static redisc_server_t * _redisc_srv_list=NULL;
46 48
 
Browse code

ndb_redis: fix SIGSEGV in redisc_check_auth

- Added the check for NULL pointer. When TCP session to redis reset,
redisCommand function can return NULL pointer.

Dennis Yurasov authored on 24/08/2021 14:15:24 • Victor Seva committed on 26/08/2021 09:25:29
Showing 1 changed files
... ...
@@ -1269,6 +1269,10 @@ int redisc_check_auth(redisc_server_t *rsrv, char *pass)
1269 1269
 	int retval = 0;
1270 1270
 
1271 1271
 	reply = redisCommand(rsrv->ctxRedis, "AUTH %s", pass);
1272
+	if(!reply) {
1273
+		LM_ERR("Redis authentication error\n");
1274
+		return -1;
1275
+	}
1272 1276
 	if (reply->type == REDIS_REPLY_ERROR) {
1273 1277
 		LM_ERR("Redis authentication error\n");
1274 1278
 		retval = -1;
Browse code

ndb_redis: add result check when reconnecting

Reported and provided solution by @kritarthh

follow-up #2461

Victor Seva authored on 02/03/2021 14:16:02
Showing 1 changed files
... ...
@@ -1059,6 +1059,11 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1059 1059
 			if(redisc_reconnect_server(rsrv)==0)
1060 1060
 			{
1061 1061
 				rpl->rplRedis = redisvCommand(rsrv->ctxRedis, cmd->s, ap4);
1062
+				if(rpl->rplRedis == NULL)
1063
+				{
1064
+					redis_count_err_and_disable(rsrv);
1065
+					goto error_exec;
1066
+				}
1062 1067
 			} else {
1063 1068
 				LM_ERR("unable to reconnect to redis server: %.*s\n",
1064 1069
 						srv->len, srv->s);
Browse code

ndb_redis: set message level to debug on reconnect

* logging error makes no sense here since there's going
to be a reconnection afterwards

Victor Seva authored on 27/11/2020 11:22:52
Showing 1 changed files
... ...
@@ -1011,7 +1011,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1011 1011
 		/* null reply, reconnect and try again */
1012 1012
 		if(rsrv->ctxRedis->err)
1013 1013
 		{
1014
-			LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr);
1014
+			LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr);
1015 1015
 		}
1016 1016
 		if(redisc_reconnect_server(rsrv)==0)
1017 1017
 		{
... ...
@@ -1054,7 +1054,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1054 1054
 			/* null reply, reconnect and try again */
1055 1055
 			if(rsrv->ctxRedis->err)
1056 1056
 			{
1057
-				LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr);
1057
+				LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr);
1058 1058
 			}
1059 1059
 			if(redisc_reconnect_server(rsrv)==0)
1060 1060
 			{
... ...
@@ -1152,7 +1152,7 @@ again:
1152 1152
 	/* null reply, reconnect and try again */
1153 1153
 	if(rsrv->ctxRedis->err)
1154 1154
 	{
1155
-		LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr);
1155
+		LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr);
1156 1156
 	}
1157 1157
 
1158 1158
 	if(res)
Browse code

ndb_redis: set message level to debug on exec

* logging error makes no sense here since there's going
to be a reconnection afterwards

> ERROR: ndb_redis [redis_client.c:903]: redisc_exec_argv(): Redis error: Server closed the connection

Victor Seva authored on 23/09/2020 07:01:43
Showing 1 changed files
... ...
@@ -770,7 +770,7 @@ int redisc_exec_pipelined(redisc_server_t *rsrv)
770 770
 		/* null reply, reconnect and try again */
771 771
 		if (rsrv->ctxRedis->err)
772 772
 		{
773
-			LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr);
773
+			LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr);
774 774
 		}
775 775
 		if (redisc_create_pipelined_message(rsrv) == 0)
776 776
 		{
Browse code

ndb_redis: fix cluster support

fixes #2461 related #2300

Victor Seva authored on 21/09/2020 07:49:25
Showing 1 changed files
... ...
@@ -1032,13 +1032,6 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1032 1032
 		}
1033 1033
 	}
1034 1034
 
1035
-	LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type);
1036
-	if(rpl->rplRedis->type == REDIS_REPLY_ERROR) {
1037
-		LM_ERR("Redis error:%.*s\n",
1038
-			(int)rpl->rplRedis->len, rpl->rplRedis->str);
1039
-		goto error_exec;
1040
-	}
1041
-
1042 1035
 	if (check_cluster_reply(rpl->rplRedis, &rsrv)) {
1043 1036
 		LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis);
1044 1037
 		if(rsrv->ctxRedis==NULL)
... ...
@@ -1073,14 +1066,15 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1073 1066
 				goto error_exec;
1074 1067
 			}
1075 1068
 		}
1069
+	}
1076 1070
 
1077
-		LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type);
1078
-		if(rpl->rplRedis->type == REDIS_REPLY_ERROR) {
1079
-			LM_ERR("Redis error:%.*s\n",
1080
-				(int)rpl->rplRedis->len, rpl->rplRedis->str);
1081
-			goto error_exec;
1082
-		}
1071
+	LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type);
1072
+	if(rpl->rplRedis->type == REDIS_REPLY_ERROR) {
1073
+		LM_ERR("Redis error:%.*s\n",
1074
+			(int)rpl->rplRedis->len, rpl->rplRedis->str);
1075
+		goto error_exec;
1083 1076
 	}
1077
+
1084 1078
 	STR_ZTOV(cmd->s[cmd->len], c);
1085 1079
 	rsrv->disable.consecutive_errors = 0;
1086 1080
 	va_end(ap);
Browse code

ndb_redis: add sentinel support to reconnection logic

- cc8e621 added sentinel support in initial redis connection.

- this commit replicates the logic into reconnection function.

Carlos Cruz authored on 08/05/2020 15:37:30
Showing 1 changed files
... ...
@@ -408,8 +408,11 @@ redisc_server_t *redisc_get_server(str *name)
408 408
  */
409 409
 int redisc_reconnect_server(redisc_server_t *rsrv)
410 410
 {
411
-	char addr[256], pass[256], unix_sock_path[256];
412
-	unsigned int port, db, sock = 0, haspass = 0;
411
+	char addr[256], pass[256], unix_sock_path[256], sentinel_group[256];
412
+	unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1;
413
+	char sentinels[MAXIMUM_SENTINELS][256];
414
+	uint8_t sentinels_count = 0;
415
+	int i, row;
413 416
 	param_t *pit = NULL;
414 417
 	struct timeval tv_conn;
415 418
 	struct timeval tv_cmd;
... ...
@@ -442,6 +445,84 @@ int redisc_reconnect_server(redisc_server_t *rsrv)
442 445
 		} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) {
443 446
 			snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s);
444 447
 			haspass = 1;
448
+		} else if(pit->name.len==14 && strncmp(pit->name.s,
449
+					"sentinel_group", 14)==0) {
450
+			snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s",
451
+					pit->body.len, pit->body.s);
452
+		} else if(pit->name.len==15 && strncmp(pit->name.s,
453
+					"sentinel_master", 15)==0) {
454
+			if(str2int(&pit->body, &sentinel_master) < 0)
455
+				sentinel_master = 1;
456
+		} else if(pit->name.len==8 && strncmp(pit->name.s,
457
+					"sentinel", 8)==0) {
458
+			if( sentinels_count < MAXIMUM_SENTINELS ){
459
+				snprintf(sentinels[sentinels_count],
460
+						sizeof(sentinels[sentinels_count])-1, "%.*s",
461
+						pit->body.len, pit->body.s);
462
+				sentinels_count++;
463
+			}
464
+			else {
465
+				LM_ERR("too many sentinels, maximum %d supported.\n",
466
+						MAXIMUM_SENTINELS);
467
+				return -1;
468
+			}
469
+		}
470
+	}
471
+
472
+	// if sentinels are provided, we need to connect to them and retrieve the redis server
473
+	// address / port
474
+	if(sentinels_count > 0) {
475
+		for(i= 0; i< sentinels_count; i++) {
476
+			char *sentinelAddr = sentinels[i];
477
+			char *pos;
478
+			redisContext *redis;
479
+			redisReply *res, *res2;
480
+
481
+			port = 6379;
482
+			if( (pos = strchr(sentinelAddr, ':')) != NULL ) {
483
+				port = atoi(pos+1);
484
+				pos[i] = '\0';
485
+			}
486
+
487
+			redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn);
488
+			if( redis ) {
489
+				if(sentinel_master != 0) {
490
+					res = redisCommand(redis,
491
+							"SENTINEL get-master-addr-by-name %s",
492
+							sentinel_group);
493
+					if( res && (res->type == REDIS_REPLY_ARRAY)
494
+							&& (res->elements == 2) ) {
495
+						strncpy(addr, res->element[0]->str,
496
+								res->element[0]->len + 1);
497
+						port = atoi(res->element[1]->str);
498
+						LM_DBG("sentinel replied: %s:%d\n", addr, port);
499
+					}
500
+				}
501
+				else {
502
+					res = redisCommand(redis, "SENTINEL slaves %s",
503
+							sentinel_group);
504
+					if( res && (res->type == REDIS_REPLY_ARRAY) ) {
505
+						for(row = 0; row< res->elements; row++){
506
+							res2 = res->element[row];
507
+							for(i= 0; i< res2->elements; i+= 2) {
508
+								if( strncmp(res2->element[i]->str,
509
+											"ip", 2) == 0 ) {
510
+									strncpy(addr, res2->element[i+1]->str,
511
+											res2->element[i+1]->len);
512
+									addr[res2->element[i+1]->len] = '\0';
513
+								}
514
+								else if( strncmp(res2->element[i]->str,
515
+											"port", 4) == 0) {
516
+									port = atoi(res2->element[i+1]->str);
517
+									break;
518
+								}
519
+							}
520
+						}
521
+						LM_DBG("slave for %s: %s:%d\n", sentinel_group,
522
+								addr, port);
523
+					}
524
+				}
525
+			}
445 526
 		}
446 527
 	}
447 528
 
Browse code

ndb_redis: redis_cmd() check reply type to detect command errors

fix #2300

Victor Seva authored on 05/05/2020 12:20:07
Showing 1 changed files
... ...
@@ -950,6 +950,14 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
950 950
 			goto error_exec;
951 951
 		}
952 952
 	}
953
+
954
+	LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type);
955
+	if(rpl->rplRedis->type == REDIS_REPLY_ERROR) {
956
+		LM_ERR("Redis error:%.*s\n",
957
+			(int)rpl->rplRedis->len, rpl->rplRedis->str);
958
+		goto error_exec;
959
+	}
960
+
953 961
 	if (check_cluster_reply(rpl->rplRedis, &rsrv)) {
954 962
 		LM_DBG("rsrv->ctxRedis = %p\n", rsrv->ctxRedis);
955 963
 		if(rsrv->ctxRedis==NULL)
... ...
@@ -984,6 +992,13 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
984 992
 				goto error_exec;
985 993
 			}
986 994
 		}
995
+
996
+		LM_DBG("rpl->rplRedis->type:%d\n", rpl->rplRedis->type);
997
+		if(rpl->rplRedis->type == REDIS_REPLY_ERROR) {
998
+			LM_ERR("Redis error:%.*s\n",
999
+				(int)rpl->rplRedis->len, rpl->rplRedis->str);
1000
+			goto error_exec;
1001
+		}
987 1002
 	}
988 1003
 	STR_ZTOV(cmd->s[cmd->len], c);
989 1004
 	rsrv->disable.consecutive_errors = 0;
Browse code

ndb_redis: use the core macros for ending string value with '\0' and to restore

Daniel-Constantin Mierla authored on 27/04/2020 13:06:10
Showing 1 changed files
... ...
@@ -542,9 +542,7 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...)
542 542
 		LM_ERR("no redis reply id found: %.*s\n", res->len, res->s);
543 543
 		goto error_cmd;
544 544
 	}
545
-
546
-	c = cmd->s[cmd->len];
547
-	cmd->s[cmd->len] = '\0';
545
+	STR_VTOZ(cmd->s[cmd->len], c);
548 546
 	rsrv->piped.commands[rsrv->piped.pending_commands].len = redisvFormatCommand(
549 547
 			&rsrv->piped.commands[rsrv->piped.pending_commands].s,
550 548
 			cmd->s,
... ...
@@ -557,7 +555,7 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...)
557 555
 	rsrv->piped.replies[rsrv->piped.pending_commands]=rpl;
558 556
 	rsrv->piped.pending_commands++;
559 557
 
560
-	cmd->s[cmd->len] = c;
558
+	STR_ZTOV(cmd->s[cmd->len], c);
561 559
 	va_end(ap);
562 560
 	return 0;
563 561
 
... ...
@@ -883,8 +881,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
883 881
 		goto error;
884 882
 	}
885 883
 
886
-	c = cmd->s[cmd->len];
887
-	cmd->s[cmd->len] = '\0';
884
+	STR_VTOZ(cmd->s[cmd->len], c);
888 885
 
889 886
 	rsrv = redisc_get_server(srv);
890 887
 	if(rsrv==NULL)
... ...
@@ -949,7 +946,7 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
949 946
 			redis_count_err_and_disable(rsrv);
950 947
 			LM_ERR("unable to reconnect to redis server: %.*s\n",
951 948
 					srv->len, srv->s);
952
-			cmd->s[cmd->len] = c;
949
+			STR_ZTOV(cmd->s[cmd->len], c);
953 950
 			goto error_exec;
954 951
 		}
955 952
 	}
... ...
@@ -983,12 +980,12 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
983 980
 			} else {
984 981
 				LM_ERR("unable to reconnect to redis server: %.*s\n",
985 982
 						srv->len, srv->s);
986
-				cmd->s[cmd->len] = c;
983
+				STR_ZTOV(cmd->s[cmd->len], c);
987 984
 				goto error_exec;
988 985
 			}
989 986
 		}
990 987
 	}
991
-	cmd->s[cmd->len] = c;
988
+	STR_ZTOV(cmd->s[cmd->len], c);
992 989
 	rsrv->disable.consecutive_errors = 0;
993 990
 	va_end(ap);
994 991
 	va_end(ap2);
... ...
@@ -1000,12 +997,12 @@ int redisc_exec(str *srv, str *res, str *cmd, ...)
1000 997
 	return 0;
1001 998
 
1002 999
 error_exec:
1003
-	cmd->s[cmd->len] = c;
1000
+	STR_ZTOV(cmd->s[cmd->len], c);
1004 1001
 	ret = -1;
1005 1002
 	goto error;
1006 1003
 
1007 1004
 srv_disabled:
1008
-	cmd->s[cmd->len] = c;
1005
+	STR_ZTOV(cmd->s[cmd->len], c);
1009 1006
 	ret = -2;
1010 1007
 	goto error;
1011 1008
 
Browse code

ndb_redis: small spelling fix: lenght -> length

Henning Westerholt authored on 24/03/2019 18:20:21
Showing 1 changed files
... ...
@@ -1019,12 +1019,12 @@ error:
1019 1019
 
1020 1020
 /**
1021 1021
  * Executes a redis command.
1022
- * Command is coded using a vector of strings, and a vector of lenghts.
1022
+ * Command is coded using a vector of strings, and a vector of lengths.
1023 1023
  *
1024 1024
  * @param rsrv Pointer to a redis_server_t structure.
1025 1025
  * @param argc number of elements in the command vector.
1026 1026
  * @param argv vector of zero terminated strings forming the command.
1027
- * @param argvlen vector of command string lenghts or NULL.
1027
+ * @param argvlen vector of command string lengths or NULL.
1028 1028
  * @return redisReply structure or NULL if there was an error.
1029 1029
  */
1030 1030
 redisReply* redisc_exec_argv(redisc_server_t *rsrv, int argc, const char **argv,
Browse code

ndb_redis: fix compilation warnings

> warning: field precision should have type 'int', but argument has type 'size_t' (aka 'unsigned long') [-Wformat]

Victor Seva authored on 19/12/2018 23:04:54
Showing 1 changed files
... ...
@@ -758,7 +758,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv)
758 758
 	char spec_new[100];
759 759
 
760 760
 	if(redis_cluster_param) {
761
-		LM_DBG("Redis replied: \"%.*s\"\n", reply->len, reply->str);
761
+		LM_DBG("Redis replied: \"%.*s\"\n", (int)reply->len, reply->str);
762 762
 		if((reply->len > 7) && (strncmp(reply->str, "MOVED", 5) == 0)) {
763 763
 			port = 6379;
764 764
 			if(strchr(reply->str, ':') > 0) {
... ...
@@ -769,7 +769,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv)
769 769
 				LM_DBG("Port \"%.*s\" [%i] => %i\n", tmpstr.len, tmpstr.s,
770 770
 						tmpstr.len, port);
771 771
 			} else {
772
-				LM_ERR("No Port in REDIS MOVED Reply (%.*s)\n", reply->len,
772
+				LM_ERR("No Port in REDIS MOVED Reply (%.*s)\n", (int)reply->len,
773 773
 						reply->str);
774 774
 				return 0;
775 775
 			}
... ...
@@ -778,7 +778,7 @@ int check_cluster_reply(redisReply *reply, redisc_server_t **rsrv)
778 778
 				addr.s = strchr(reply->str + 6, ' ') + 1;
779 779
 				LM_DBG("Host \"%.*s\" [%i]\n", addr.len, addr.s, addr.len);
780 780
 			} else {
781
-				LM_ERR("No Host in REDIS MOVED Reply (%.*s)\n", reply->len,
781
+				LM_ERR("No Host in REDIS MOVED Reply (%.*s)\n", (int)reply->len,
782 782
 						reply->str);
783 783
 				return 0;
784 784
 			}
Browse code

ndb_redis: replaced printf with dbg, formatted sentinel code and long lines

Daniel-Constantin Mierla authored on 24/09/2018 17:49:38
Showing 1 changed files
... ...
@@ -39,7 +39,8 @@
39 39
 
40 40
 #include "redis_client.h"
41 41
 
42
-#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;})
42
+#define redisCommandNR(a...) (int)({ void *__tmp; __tmp = redisCommand(a); \
43
+		if (__tmp) freeReplyObject(__tmp); __tmp ? 0 : -1;})
43 44
 
44 45
 static redisc_server_t * _redisc_srv_list=NULL;
45 46
 
... ...
@@ -93,7 +94,7 @@ int redisc_init(void)
93 94
 	{
94 95
 		char sentinels[MAXIMUM_SENTINELS][256];
95 96
 		uint8_t sentinels_count = 0;
96
-		
97
+
97 98
 		port = 6379;
98 99
 		db = 0;
99 100
 		haspass = 0;
... ...
@@ -106,10 +107,12 @@ int redisc_init(void)
106 107
 		for (pit = rsrv->attrs; pit; pit=pit->next)
107 108
 		{
108 109
 			if(pit->name.len==4 && strncmp(pit->name.s, "unix", 4)==0) {
109
-				snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", pit->body.len, pit->body.s);
110
+				snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s",
111
+						pit->body.len, pit->body.s);
110 112
 				sock = 1;
111 113
 			} else if(pit->name.len==4 && strncmp(pit->name.s, "addr", 4)==0) {
112
-				snprintf(addr, sizeof(addr)-1, "%.*s", pit->body.len, pit->body.s);
114
+				snprintf(addr, sizeof(addr)-1, "%.*s",
115
+						pit->body.len, pit->body.s);
113 116
 			} else if(pit->name.len==4 && strncmp(pit->name.s, "port", 4)==0) {
114 117
 				if(str2int(&pit->body, &port) < 0)
115 118
 					port = 6379;
... ...
@@ -117,25 +120,33 @@ int redisc_init(void)
117 120
 				if(str2int(&pit->body, &db) < 0)
118 121
 					db = 0;
119 122
 			} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) {
120
-				snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s);
123
+				snprintf(pass, sizeof(pass)-1, "%.*s",
124
+						pit->body.len, pit->body.s);
121 125
 				haspass = 1;
122
-			} else if(pit->name.len==14 && strncmp(pit->name.s, "sentinel_group", 14)==0) {
123
-				snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", pit->body.len, pit->body.s);
124
-			} else if(pit->name.len==15 && strncmp(pit->name.s, "sentinel_master", 15)==0) {
126
+			} else if(pit->name.len==14 && strncmp(pit->name.s,
127
+						"sentinel_group", 14)==0) {
128
+				snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s",
129
+						pit->body.len, pit->body.s);
130
+			} else if(pit->name.len==15 && strncmp(pit->name.s,
131
+						"sentinel_master", 15)==0) {
125 132
 				if(str2int(&pit->body, &sentinel_master) < 0)
126 133
 					sentinel_master = 1;
127
-			} else if(pit->name.len==8 && strncmp(pit->name.s, "sentinel", 8)==0) {
134
+			} else if(pit->name.len==8 && strncmp(pit->name.s,
135
+						"sentinel", 8)==0) {
128 136
 				if( sentinels_count < MAXIMUM_SENTINELS ){
129
-					snprintf(sentinels[sentinels_count], sizeof(sentinels[sentinels_count])-1, "%.*s", pit->body.len, pit->body.s);
137
+					snprintf(sentinels[sentinels_count],
138
+							sizeof(sentinels[sentinels_count])-1, "%.*s",
139
+							pit->body.len, pit->body.s);
130 140
 					sentinels_count++;
131 141
 				}
132 142
 				else {
133
-					LM_ERR("too many sentinels, maximum %d supported.\n", MAXIMUM_SENTINELS);
143
+					LM_ERR("too many sentinels, maximum %d supported.\n",
144
+							MAXIMUM_SENTINELS);
134 145
 					return -1;
135 146
 				}
136 147
 			}
137 148
 		}
138
-		
149
+
139 150
 		// if sentinels are provided, we need to connect to them and retrieve the redis server
140 151
 		// address / port
141 152
 		if(sentinels_count > 0) {
... ...
@@ -144,46 +155,49 @@ int redisc_init(void)
144 155
 				char *pos;
145 156
 				redisContext *redis;
146 157
 				redisReply *res, *res2;
147
-				
158
+
148 159
 				port = 6379;
149 160
 				if( (pos = strchr(sentinelAddr, ':')) != NULL ) {
150 161
 					port = atoi(pos+1);
151 162
 					pos[i] = '\0';
152 163
 				}
153
-				
164
+
154 165
 				redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn);
155 166
 				if( redis ) {
156 167
 					if(sentinel_master != 0) {
157
-						res = redisCommand(redis, "SENTINEL get-master-addr-by-name %s", sentinel_group);
158
-						if( res && (res->type == REDIS_REPLY_ARRAY) && (res->elements == 2) ) {
159
-							strncpy(addr, res->element[0]->str, res->element[0]->len + 1);
168
+						res = redisCommand(redis,
169
+								"SENTINEL get-master-addr-by-name %s",
170
+								sentinel_group);
171
+						if( res && (res->type == REDIS_REPLY_ARRAY)
172
+								&& (res->elements == 2) ) {
173
+							strncpy(addr, res->element[0]->str,
174
+									res->element[0]->len + 1);
160 175
 							port = atoi(res->element[1]->str);
161
-							
162
-							
163
-							printf("sentinel replied: %s:%d\n", addr, port);
176
+							LM_DBG("sentinel replied: %s:%d\n", addr, port);
164 177
 						}
165 178
 					}
166 179
 					else {
167
-						res = redisCommand(redis, "SENTINEL slaves %s", sentinel_group);
180
+						res = redisCommand(redis, "SENTINEL slaves %s",
181
+								sentinel_group);
168 182
 						if( res && (res->type == REDIS_REPLY_ARRAY) ) {
169
-							
170 183
 							for(row = 0; row< res->elements; row++){
171 184
 								res2 = res->element[row];
172
-								
173 185
 								for(i= 0; i< res2->elements; i+= 2) {
174
-									if( strncmp(res2->element[i]->str, "ip", 2) == 0 ) {
175
-										strncpy(addr, res2->element[i+1]->str, res2->element[i+1]->len);
186
+									if( strncmp(res2->element[i]->str,
187
+												"ip", 2) == 0 ) {
188
+										strncpy(addr, res2->element[i+1]->str,
189
+												res2->element[i+1]->len);
176 190
 										addr[res2->element[i+1]->len] = '\0';
177 191
 									}
178
-									else if( strncmp(res2->element[i]->str, "port", 4) == 0) {
192
+									else if( strncmp(res2->element[i]->str,
193
+												"port", 4) == 0) {
179 194
 										port = atoi(res2->element[i+1]->str);
180 195
 										break;
181 196
 									}
182 197
 								}
183
-								
184 198
 							}
185
-							
186
-							printf("slave for %s: %s:%d\n", sentinel_group, addr, port);
199
+							LM_DBG("slave for %s: %s:%d\n", sentinel_group,
200
+									addr, port);
187 201
 						}
188 202
 					}
189 203
 				}
... ...
@@ -206,7 +220,8 @@ int redisc_init(void)
206 220
 			goto err;
207 221
 		}
208 222
 		if (rsrv->ctxRedis->err) {
209
-			LM_ERR("Failed to create REDIS returned an error: %s\n", rsrv->ctxRedis->errstr);
223
+			LM_ERR("Failed to create REDIS returned an error: %s\n",
224
+					rsrv->ctxRedis->errstr);
210 225
 			goto err2;
211 226
 		}
212 227
 		if ((haspass != 0) && redisc_check_auth(rsrv, pass)) {
... ...
@@ -218,11 +233,14 @@ int redisc_init(void)
218 233
 			goto err2;
219 234
 		}
220 235
 		if (redisCommandNR(rsrv->ctxRedis, "PING")) {
221
-			LM_ERR("Failed to send PING (REDIS returned %s).\n", rsrv->ctxRedis->errstr);
236
+			LM_ERR("Failed to send PING (REDIS returned %s).\n",
237
+					rsrv->ctxRedis->errstr);
222 238
 			goto err2;
223 239
 		}
224
-		if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, "SELECT %i", db)) {
225
-			LM_ERR("Failed to send \"SELECT %i\" (REDIS returned \"%s\", and not in cluster mode).\n", db, rsrv->ctxRedis->errstr);
240
+		if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis,
241
+					"SELECT %i", db)) {
242
+			LM_ERR("Failed to send \"SELECT %i\" (REDIS returned \"%s\","
243
+					" and not in cluster mode).\n", db, rsrv->ctxRedis->errstr);
226 244
 			goto err2;
227 245
 		}
228 246
 	}
... ...
@@ -374,7 +392,8 @@ redisc_server_t *redisc_get_server(str *name)
374 392
 	rsrv=_redisc_srv_list;
375 393
 	while(rsrv!=NULL)
376 394
 	{
377
-		LM_DBG("Entry %u (%.*s)\n", rsrv->hname, rsrv->sname->len, rsrv->sname->s);
395
+		LM_DBG("Entry %u (%.*s)\n", rsrv->hname,
396
+				rsrv->sname->len, rsrv->sname->s);
378 397
 		if(rsrv->hname==hname && rsrv->sname->len==name->len
379 398
 				&& strncmp(rsrv->sname->s, name->s, name->len)==0)
380 399
 			return rsrv;
... ...
@@ -409,7 +428,8 @@ int redisc_reconnect_server(redisc_server_t *rsrv)
409 428
 	for (pit = rsrv->attrs; pit; pit=pit->next)
410 429
 	{
411 430
 		if(pit->name.len==4 && strncmp(pit->name.s, "unix", 4)==0) {
412
-			snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s", pit->body.len, pit->body.s);
431
+			snprintf(unix_sock_path, sizeof(unix_sock_path)-1, "%.*s",
432
+					pit->body.len, pit->body.s);
413 433
 			sock = 1;
414 434
 		} else if(pit->name.len==4 && strncmp(pit->name.s, "addr", 4)==0) {
415 435
 			snprintf(addr, sizeof(addr)-1, "%.*s", pit->body.len, pit->body.s);
... ...
@@ -447,7 +467,8 @@ int redisc_reconnect_server(redisc_server_t *rsrv)
447 467
 		goto err2;
448 468
 	if (redisCommandNR(rsrv->ctxRedis, "PING"))
449 469
 		goto err2;
450
-	if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis, "SELECT %i", db))
470
+	if ((redis_cluster_param == 0) && redisCommandNR(rsrv->ctxRedis,
471
+				"SELECT %i", db))
451 472
 		goto err2;
452 473
 	if (redis_flush_on_reconnect_param)
453 474
 		if (redisCommandNR(rsrv->ctxRedis, "FLUSHALL"))
... ...
@@ -511,7 +532,8 @@ int redisc_append_cmd(str *srv, str *res, str *cmd, ...)
511 532
 	}
512 533
 	if (rsrv->piped.pending_commands >= MAXIMUM_PIPELINED_COMMANDS)
513 534
 	{
514
-		LM_ERR("Too many pipelined commands, maximum is %d\n",MAXIMUM_PIPELINED_COMMANDS);
535
+		LM_ERR("Too many pipelined commands, maximum is %d\n",
536
+				MAXIMUM_PIPELINED_COMMANDS);
515 537
 		goto error_cmd;
516 538
 	}
517 539
 	rpl = redisc_get_reply(res);
... ...
@@ -586,17 +608,21 @@ int redisc_create_pipelined_message(redisc_server_t *rsrv)
586 608
 
587 609
 	if (rsrv->ctxRedis->err)
588 610
 	{
589
-		LM_DBG("Reconnecting server because of error %d: \"%s\"",rsrv->ctxRedis->err,rsrv->ctxRedis->errstr);
611
+		LM_DBG("Reconnecting server because of error %d: \"%s\"",
612
+				rsrv->ctxRedis->err,rsrv->ctxRedis->errstr);
590 613
 		if (redisc_reconnect_server(rsrv))
591 614
 		{
592
-			LM_ERR("unable to reconnect to REDIS server: %.*s\n", rsrv->sname->len,rsrv->sname->s);
615
+			LM_ERR("unable to reconnect to REDIS server: %.*s\n",
616
+					rsrv->sname->len,rsrv->sname->s);
593 617
 			return -1;
594 618
 		}
595 619
 	}
596 620
 
597 621
 	for (i=0;i<rsrv->piped.pending_commands;i++)
598 622
 	{
599
-		if (redis_append_formatted_command(rsrv->ctxRedis,rsrv->piped.commands[i].s,rsrv->piped.commands[i].len) != REDIS_OK)
623
+		if (redis_append_formatted_command(rsrv->ctxRedis,
624
+					rsrv->piped.commands[i].s,rsrv->piped.commands[i].len)
625
+						!= REDIS_OK)
600 626
 		{
601 627
 			LM_ERR("Error while appending command %d",i);
602 628
 			return -1;
... ...
@@ -642,7 +668,8 @@ int redisc_exec_pipelined(redisc_server_t *rsrv)
642 668
 	}
643 669
 	if(rsrv->ctxRedis==NULL)
644 670
 	{
645
-		LM_ERR("no redis context for server: %.*s\n", rsrv->sname->len,rsrv->sname->s);
671
+		LM_ERR("no redis context for server: %.*s\n",
672
+				rsrv->sname->len,rsrv->sname->s);
646 673
 		goto error_exec;
647 674
 	}
648 675
 
... ...
@@ -694,7 +721,8 @@ int redisc_exec_pipelined(redisc_server_t *rsrv)
694 721
 			freeReplyObject(rpl->rplRedis);
695 722
 			rpl->rplRedis = NULL;
696 723
 		}
697
-		if (redisGetReplyFromReader(rsrv->ctxRedis, (void**) &rpl->rplRedis) != REDIS_OK)
724
+		if (redisGetReplyFromReader(rsrv->ctxRedis, (void**) &rpl->rplRedis)
725
+				!= REDIS_OK)
698 726
 		{
699 727
 			LM_ERR("Unable to read reply\n");
700 728
 			continue;
... ...
@@ -1181,7 +1209,8 @@ int redis_check_server(redisc_server_t *rsrv)
1181 1209
 	{
1182 1210
 		if (get_ticks() > rsrv->disable.restore_tick)
1183 1211
 		{
1184
-			LM_NOTICE("REDIS server %.*s re-enabled",rsrv->sname->len,rsrv->sname->s);
1212
+			LM_NOTICE("REDIS server %.*s re-enabled",
1213
+					rsrv->sname->len, rsrv->sname->s);
1185 1214
 			rsrv->disable.disabled = 0;
1186 1215
 			rsrv->disable.consecutive_errors = 0;
1187 1216
 		}
... ...
@@ -1205,7 +1234,8 @@ int redis_count_err_and_disable(redisc_server_t *rsrv)
1205 1234
 	{
1206 1235
 		rsrv->disable.disabled=1;
1207 1236
 		rsrv->disable.restore_tick=get_ticks() + redis_disable_time_param;
1208
-		LM_WARN("REDIS server %.*s disabled for %d seconds",rsrv->sname->len,rsrv->sname->s,redis_disable_time_param);
1237
+		LM_WARN("REDIS server %.*s disabled for %d seconds", rsrv->sname->len,
1238
+				rsrv->sname->s, redis_disable_time_param);
1209 1239
 		return 1;
1210 1240
 	}
1211 1241
 	return 0;
... ...
@@ -1246,7 +1276,8 @@ void print_redis_reply(int log_level, redisReply *rpl,int offset)
1246 1276
 		LOG(log_level,"%sinteger reply: %lld", padding, rpl->integer);
1247 1277
 		break;
1248 1278
 	case REDIS_REPLY_ARRAY:
1249
-		LOG(log_level,"%sarray reply with %d elements", padding, (int)rpl->elements);
1279
+		LOG(log_level,"%sarray reply with %d elements", padding,
1280
+				(int)rpl->elements);
1250 1281
 		for (i=0; i < rpl->elements; i++)
1251 1282
 		{
1252 1283
 			LOG(log_level,"%selement %d:",padding,i);
Browse code

ndb_redis: fix error introduced commit in 95cfa343857e4: 'for' loop initial decl.

- fix error related to sentinel patch, introduced in commit 95cfa343857e4
- error: 'for' loop initial declarations are only allowed in C99 mode

Henning Westerholt authored on 10/04/2018 05:34:36
Showing 1 changed files
... ...
@@ -71,6 +71,7 @@ int redisc_init(void)
71 71
 	char addr[256], pass[256], unix_sock_path[256], sentinel_group[256];
72 72
 
73 73
 	unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1;
74
+	int i, row;
74 75
 	redisc_server_t *rsrv=NULL;
75 76
 	param_t *pit = NULL;
76 77
 	struct timeval tv_conn;
... ...
@@ -138,7 +139,7 @@ int redisc_init(void)
138 139
 		// if sentinels are provided, we need to connect to them and retrieve the redis server
139 140
 		// address / port
140 141
 		if(sentinels_count > 0) {
141
-			for(int i= 0; i< sentinels_count; i++) {
142
+			for(i= 0; i< sentinels_count; i++) {
142 143
 				char *sentinelAddr = sentinels[i];
143 144
 				char *pos;
144 145
 				redisContext *redis;
... ...
@@ -166,10 +167,10 @@ int redisc_init(void)
166 167
 						res = redisCommand(redis, "SENTINEL slaves %s", sentinel_group);
167 168
 						if( res && (res->type == REDIS_REPLY_ARRAY) ) {
168 169
 							
169
-							for(int row = 0; row< res->elements; row++){
170
+							for(row = 0; row< res->elements; row++){
170 171
 								res2 = res->element[row];
171 172
 								
172
-								for(int i= 0; i< res2->elements; i+= 2) {
173
+								for(i= 0; i< res2->elements; i+= 2) {
173 174
 									if( strncmp(res2->element[i]->str, "ip", 2) == 0 ) {
174 175
 										strncpy(addr, res2->element[i+1]->str, res2->element[i+1]->len);
175 176
 										addr[res2->element[i+1]->len] = '\0';
Browse code

ndb_redis: adds support for sentinel

Julien Ammous authored on 03/04/2018 12:08:53
Showing 1 changed files
... ...
@@ -68,9 +68,9 @@ int redis_append_formatted_command(redisContext *c, const char *cmd, size_t len)
68 68
  */
69 69
 int redisc_init(void)
70 70
 {
71
-	char addr[256], pass[256], unix_sock_path[256];
71
+	char addr[256], pass[256], unix_sock_path[256], sentinel_group[256];
72 72
 
73
-	unsigned int port, db, sock = 0, haspass = 0;
73
+	unsigned int port, db, sock = 0, haspass = 0, sentinel_master = 1;
74 74
 	redisc_server_t *rsrv=NULL;
75 75
 	param_t *pit = NULL;
76 76
 	struct timeval tv_conn;
... ...
@@ -90,6 +90,9 @@ int redisc_init(void)
90 90
 
91 91
 	for(rsrv=_redisc_srv_list; rsrv; rsrv=rsrv->next)
92 92
 	{
93
+		char sentinels[MAXIMUM_SENTINELS][256];
94
+		uint8_t sentinels_count = 0;
95
+		
93 96
 		port = 6379;
94 97
 		db = 0;
95 98
 		haspass = 0;
... ...
@@ -115,6 +118,74 @@ int redisc_init(void)
115 118
 			} else if(pit->name.len==4 && strncmp(pit->name.s, "pass", 4)==0) {
116 119
 				snprintf(pass, sizeof(pass)-1, "%.*s", pit->body.len, pit->body.s);
117 120
 				haspass = 1;
121
+			} else if(pit->name.len==14 && strncmp(pit->name.s, "sentinel_group", 14)==0) {
122
+				snprintf(sentinel_group, sizeof(sentinel_group)-1, "%.*s", pit->body.len, pit->body.s);
123
+			} else if(pit->name.len==15 && strncmp(pit->name.s, "sentinel_master", 15)==0) {
124
+				if(str2int(&pit->body, &sentinel_master) < 0)
125
+					sentinel_master = 1;
126
+			} else if(pit->name.len==8 && strncmp(pit->name.s, "sentinel", 8)==0) {
127
+				if( sentinels_count < MAXIMUM_SENTINELS ){
128
+					snprintf(sentinels[sentinels_count], sizeof(sentinels[sentinels_count])-1, "%.*s", pit->body.len, pit->body.s);
129
+					sentinels_count++;
130
+				}
131
+				else {
132
+					LM_ERR("too many sentinels, maximum %d supported.\n", MAXIMUM_SENTINELS);
133
+					return -1;
134
+				}
135
+			}
136
+		}
137
+		
138
+		// if sentinels are provided, we need to connect to them and retrieve the redis server
139
+		// address / port
140
+		if(sentinels_count > 0) {
141
+			for(int i= 0; i< sentinels_count; i++) {
142
+				char *sentinelAddr = sentinels[i];
143
+				char *pos;
144
+				redisContext *redis;
145
+				redisReply *res, *res2;
146
+				
147
+				port = 6379;
148
+				if( (pos = strchr(sentinelAddr, ':')) != NULL ) {
149
+					port = atoi(pos+1);
150
+					pos[i] = '\0';
151
+				}
152
+				
153
+				redis = redisConnectWithTimeout(sentinelAddr, port, tv_conn);
154
+				if( redis ) {
155
+					if(sentinel_master != 0) {
156
+						res = redisCommand(redis, "SENTINEL get-master-addr-by-name %s", sentinel_group);
157
+						if( res && (res->type == REDIS_REPLY_ARRAY) && (res->elements == 2) ) {
158
+							strncpy(addr, res->element[0]->str, res->element[0]->len + 1);
159
+							port = atoi(res->element[1]->str);
160
+							
161
+							
162
+							printf("sentinel replied: %s:%d\n", addr, port);
163
+						}