Browse code

core: pvapi - reinitialize _pv_print_buffer_index when adjusting the slots

- GH #2798

Daniel-Constantin Mierla authored on 27/07/2021 14:52:12
Showing 1 changed files
... ...
@@ -2147,6 +2147,7 @@ int pv_init_buffer(void)
2147 2147
 			_pv_print_buffer_slots, _pv_print_buffer_size);
2148 2148
 	_pv_print_buffer_slots_active = _pv_print_buffer_slots;
2149 2149
 	_pv_print_buffer_size_active = _pv_print_buffer_size;
2150
+	_pv_print_buffer_index = 0;
2150 2151
 
2151 2152
 	return 0;
2152 2153
 }
... ...
@@ -2168,6 +2169,7 @@ void pv_destroy_buffer(void)
2168 2169
 	pkg_free(_pv_print_buffer);
2169 2170
 	_pv_print_buffer_slots_active = 0;
2170 2171
 	_pv_print_buffer_size_active = 0;
2172
+	_pv_print_buffer_index = 0;
2171 2173
 	_pv_print_buffer = NULL;
2172 2174
 }
2173 2175
 
... ...
@@ -2177,8 +2179,9 @@ void pv_destroy_buffer(void)
2177 2179
 int pv_reinit_buffer(void)
2178 2180
 {
2179 2181
 	if(_pv_print_buffer_size==_pv_print_buffer_size_active
2180
-			&& _pv_print_buffer_slots==_pv_print_buffer_slots_active)
2182
+			&& _pv_print_buffer_slots==_pv_print_buffer_slots_active) {
2181 2183
 		return 0;
2184
+	}
2182 2185
 	pv_destroy_buffer();
2183 2186
 	return pv_init_buffer();
2184 2187
 }
Browse code

core: renamed core init list of pvs

- similar name is used in pv_core.c

Daniel-Constantin Mierla authored on 22/12/2020 20:15:12
Showing 1 changed files
... ...
@@ -2061,7 +2061,7 @@ tr_export_t* tr_lookup_class(str *tclass)
2061 2061
  * core PVs, initialization and destroy APIs
2062 2062
  ********************************************************/
2063 2063
 
2064
-static pv_export_t _core_pvs[] = {
2064
+static pv_export_t _core_init_pvs[] = {
2065 2065
 	{{"null", (sizeof("null")-1)}, /* */
2066 2066
 		PVT_NULL, pv_get_null, 0,
2067 2067
 		0, 0, 0, 0},
... ...
@@ -2085,7 +2085,7 @@ int pv_init_api(void)
2085 2085
 	strcpy(pv_str_null_buf, PV_STR_NULL_VAL);
2086 2086
 	pv_str_null.s = pv_str_null_buf;
2087 2087
 
2088
-	if(register_pvars_mod("core", _core_pvs)<0)
2088
+	if(register_pvars_mod("core", _core_init_pvs)<0)
2089 2089
 		return -1;
2090 2090
 	return 0;
2091 2091
 }
Browse code

core: PV_IDX_NONE to point that pv had no index

if index is 0 there were no way to know if the index was there

$x_hdr(A) = "value" needs to append a value
$(x_hdr(A)[0]) = "value" needs to set the value

pv_parse_spec(str *s, pv_spec_p p) was always setting p->pvp.pvi.type
to 0 == PV_IDX_INT

Victor Seva authored on 29/05/2020 13:31:28
Showing 1 changed files
... ...
@@ -857,6 +857,7 @@ char* pv_parse_spec2(str *in, pv_spec_p e, int silent)
857 857
 	tr = 0;
858 858
 	pvstate = 0;
859 859
 	memset(e, 0, sizeof(pv_spec_t));
860
+	e->pvp.pvi.type = PV_IDX_NONE;
860 861
 	p = in->s;
861 862
 	p++;
862 863
 	if(*p==PV_LNBRACKET)
... ...
@@ -1369,6 +1370,12 @@ int pv_get_spec_index(struct sip_msg* msg, pv_param_p ip, int *idx, int *flags)
1369 1370
 		*idx = ip->pvi.u.ival;
1370 1371
 		return 0;
1371 1372
 	}
1373
+	if(ip->pvi.type == PV_IDX_NONE)
1374
+	{
1375
+		*flags = PV_IDX_NONE;
1376
+		*idx = ip->pvi.u.ival;
1377
+		return 0;
1378
+	}
1372 1379
 
1373 1380
 	/* pvar */
1374 1381
 	if(pv_get_spec_value(msg, (pv_spec_p)ip->pvi.u.dval, &tv)!=0)
Browse code

core: pv - function to get the size of the value for strings with vars

- added silent mode for printing strings with vars

Daniel-Constantin Mierla authored on 30/10/2019 17:26:34
Showing 1 changed files
... ...
@@ -1426,18 +1426,22 @@ int pv_set_spec_value(struct sip_msg* msg, pv_spec_p sp, int op,
1426 1426
 /**
1427 1427
  *
1428 1428
  */
1429
-int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1429
+int pv_printf_mode(sip_msg_t* msg, pv_elem_t *list, int mode, char *buf, int *len)
1430 1430
 {
1431 1431
 	int n;
1432 1432
 	pv_value_t tok;
1433 1433
 	pv_elem_p it;
1434 1434
 	char *cur;
1435 1435
 
1436
-	if(msg==NULL || list==NULL || buf==NULL || len==NULL)
1436
+	if(msg==NULL || list==NULL || buf==NULL || len==NULL) {
1437
+		LM_DBG("invalid parameters\n");
1437 1438
 		return -1;
1439
+	}
1438 1440
 
1439
-	if(*len <= 0)
1441
+	if(*len <= 0) {
1442
+		LM_DBG("invalid value for output buffer size\n");
1440 1443
 		return -1;
1444
+	}
1441 1445
 
1442 1446
 	*buf = '\0';
1443 1447
 	cur = buf;
... ...
@@ -1454,8 +1458,10 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1454 1458
 				n += it->text.len;
1455 1459
 				cur += it->text.len;
1456 1460
 			} else {
1457
-				LM_ERR("no more space for text value - printed:%d token:%d buffer:%d\n",
1461
+				if(likely(mode)) {
1462
+					LM_ERR("no more space for text value - printed:%d token:%d buffer:%d\n",
1458 1463
 						n, it->text.len, *len);
1464
+				}
1459 1465
 				goto overflow;
1460 1466
 			}
1461 1467
 		}
... ...
@@ -1474,8 +1480,10 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1474 1480
 					cur += tok.rs.len;
1475 1481
 				}
1476 1482
 			} else {
1477
-				LM_ERR("no more space for spec value - printed:%d token:%d buffer:%d\n",
1483
+				if(likely(mode)) {
1484
+					LM_ERR("no more space for spec value - printed:%d token:%d buffer:%d\n",
1478 1485
 						n, tok.rs.len, *len);
1486
+				}
1479 1487
 				goto overflow;
1480 1488
 			}
1481 1489
 		}
... ...
@@ -1484,8 +1492,10 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1484 1492
 	goto done;
1485 1493
 
1486 1494
 overflow:
1487
-	LM_ERR("buffer overflow -- increase the buffer size...\n");
1488
-	return -1;
1495
+	if(likely(mode)) {
1496
+		LM_ERR("buffer overflow -- increase the buffer size...\n");
1497
+	}
1498
+	return -2;
1489 1499
 
1490 1500
 done:
1491 1501
 #ifdef EXTRA_DEBUG
... ...
@@ -1496,6 +1506,47 @@ done:
1496 1506
 	return 0;
1497 1507
 }
1498 1508
 
1509
+/**
1510
+ *
1511
+ */
1512
+int pv_printf(sip_msg_t* msg, pv_elem_t *list, char *buf, int *len)
1513
+{
1514
+	return pv_printf_mode(msg, list, 1, buf, len);
1515
+}
1516
+
1517
+/**
1518
+ *
1519
+ */
1520
+int pv_printf_size(sip_msg_t* msg, pv_elem_t *list)
1521
+{
1522
+	int n;
1523
+	pv_value_t tok;
1524
+	pv_elem_t *it;
1525
+
1526
+	if(msg==NULL || list==NULL) {
1527
+		return -1;
1528
+	}
1529
+
1530
+	n = 0;
1531
+	for (it=list; it; it=it->next) {
1532
+		/* count the static text */
1533
+		if(it->text.s && it->text.len>0) {
1534
+			n += it->text.len;
1535
+		}
1536
+		/* count the value of the specifier */
1537
+		if(it->spec!=NULL && it->spec->type!=PVT_NONE
1538
+				&& pv_get_spec_value(msg, it->spec, &tok)==0)
1539
+		{
1540
+			if(tok.flags&PV_VAL_NULL) {
1541
+				tok.rs = pv_str_null;
1542
+			}
1543
+			n += tok.rs.len;
1544
+		}
1545
+	}
1546
+
1547
+	return n;
1548
+}
1549
+
1499 1550
 /**
1500 1551
  *
1501 1552
  */
Browse code

core: pv - increased the size for vars and transformations tables

Daniel-Constantin Mierla authored on 19/07/2019 07:50:21
Showing 1 changed files
... ...
@@ -40,8 +40,8 @@
40 40
 #include "pvapi.h"
41 41
 #include "pvar.h"
42 42
 
43
-#define PV_TABLE_SIZE	64  /*!< pseudo-variables table size */
44
-#define TR_TABLE_SIZE	32  /*!< transformations table size */
43
+#define PV_TABLE_SIZE	512  /*!< pseudo-variables table size */
44
+#define TR_TABLE_SIZE	256  /*!< transformations table size */
45 45
 
46 46
 
47 47
 void tr_destroy(trans_t *t);
Browse code

core: pv - exposed the function to return the str empty static variable

Daniel-Constantin Mierla authored on 21/05/2019 12:55:53
Showing 1 changed files
... ...
@@ -695,6 +695,14 @@ str *pv_get_null_str(void)
695 695
 	return &pv_str_null;
696 696
 }
697 697
 
698
+/**
699
+ *
700
+ */
701
+str *pv_get_empty_str(void)
702
+{
703
+	return &pv_str_empty;
704
+}
705
+
698 706
 /**
699 707
  *
700 708
  */
Browse code

core: pv - define the string printed for null value

- added function to return the str null value

Daniel-Constantin Mierla authored on 14/05/2019 09:02:49
Showing 1 changed files
... ...
@@ -674,7 +674,8 @@ static char pv_str_empty_buf[2];
674 674
 static char pv_str_null_buf[8];
675 675
 
676 676
 static str pv_str_empty  = { "", 0 };
677
-static str pv_str_null   = { "<null>", 6 };
677
+#define PV_STR_NULL_VAL	"<null>"
678
+static str pv_str_null   = { PV_STR_NULL_VAL, sizeof(PV_STR_NULL_VAL)-1 };
678 679
 int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
679 680
 {
680 681
 	if(res==NULL)
... ...
@@ -686,6 +687,14 @@ int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
686 687
 	return 0;
687 688
 }
688 689
 
690
+/**
691
+ *
692
+ */
693
+str *pv_get_null_str(void)
694
+{
695
+	return &pv_str_null;
696
+}
697
+
689 698
 /**
690 699
  *
691 700
  */
... ...
@@ -2007,7 +2016,7 @@ int pv_init_api(void)
2007 2016
 	pv_str_empty_buf[0] = '\0';
2008 2017
 	pv_str_empty_buf[1] = '\0';
2009 2018
 	pv_str_empty.s = pv_str_empty_buf;
2010
-	strcpy(pv_str_null_buf, "<null>");
2019
+	strcpy(pv_str_null_buf, PV_STR_NULL_VAL);
2011 2020
 	pv_str_null.s = pv_str_null_buf;
2012 2021
 
2013 2022
 	if(register_pvars_mod("core", _core_pvs)<0)
Browse code

core: adjust the value for _pv_cache_counter

- reported by GH #1948

Daniel-Constantin Mierla authored on 13/05/2019 10:40:24
Showing 1 changed files
... ...
@@ -287,6 +287,7 @@ int pv_cache_drop(void)
287 287
 					pvi->spec.pvp.pvn.nfree((void*)(&pvi->spec.pvp.pvn));
288 288
 				}
289 289
 				pkg_free(pvi);
290
+				_pv_cache_counter--;
290 291
 				return 1;
291 292
 			}
292 293
 			pvp = pvi;
... ...
@@ -309,6 +310,7 @@ int pv_cache_drop(void)
309 310
 					pvi->spec.pvp.pvn.nfree((void*)(&pvi->spec.pvp.pvn));
310 311
 				}
311 312
 				pkg_free(pvi);
313
+				_pv_cache_counter--;
312 314
 				return 1;
313 315
 			}
314 316
 			pvp = pvi;
... ...
@@ -364,6 +366,7 @@ pv_spec_t* pv_cache_add(str *name)
364 366
 	pvn->pvid = pvid;
365 367
 	pvn->next = _pv_cache[pvid%PV_CACHE_SIZE];
366 368
 	_pv_cache[pvid%PV_CACHE_SIZE] = pvn;
369
+	_pv_cache_counter++;
367 370
 
368 371
 	LM_DBG("pvar [%.*s] added in cache\n", name->len, name->s);
369 372
 	return &pvn->spec;
Browse code

core: log printed size, current token size and buffer size for pv printf overflow

Daniel-Constantin Mierla authored on 13/02/2019 08:42:08
Showing 1 changed files
... ...
@@ -1434,7 +1434,8 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1434 1434
 				n += it->text.len;
1435 1435
 				cur += it->text.len;
1436 1436
 			} else {
1437
-				LM_ERR("no more space for text [%d]\n", it->text.len);
1437
+				LM_ERR("no more space for text value - printed:%d token:%d buffer:%d\n",
1438
+						n, it->text.len, *len);
1438 1439
 				goto overflow;
1439 1440
 			}
1440 1441
 		}
... ...
@@ -1453,7 +1454,8 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
1453 1454
 					cur += tok.rs.len;
1454 1455
 				}
1455 1456
 			} else {
1456
-				LM_ERR("no more space for spec value\n");
1457
+				LM_ERR("no more space for spec value - printed:%d token:%d buffer:%d\n",
1458
+						n, tok.rs.len, *len);
1457 1459
 				goto overflow;
1458 1460
 			}
1459 1461
 		}
Browse code

core: use generic PKG_MEM_ERROR, SHM_ERROR and _CRITICAL helper defines in core

- refactoring of the core to use generic PKG_MEM_ERROR, SHM_ERROR,
PKG_MEM_CRITICAL, SHM_MEM_CRITICAL and SYS_MEM_ERROR helper defines
- unify many different error messages in different spellings
- add a few missing error handler for allocation errors after (found
with a complete review of all memory allocation functions in core)
- no other functional changes, change has been reviewed two times

Henning Westerholt authored on 23/12/2018 21:31:03
Showing 1 changed files
... ...
@@ -236,7 +236,7 @@ int pv_table_add(pv_export_t *e)
236 236
 	pvn = (pv_item_t*)pkg_malloc(sizeof(pv_item_t));
237 237
 	if(pvn==0)
238 238
 	{
239
-		LM_ERR("no more memory\n");
239
+		PKG_MEM_ERROR;
240 240
 		return -1;
241 241
 	}
242 242
 	memset(pvn, 0, sizeof(pv_item_t));
... ...
@@ -347,7 +347,7 @@ pv_spec_t* pv_cache_add(str *name)
347 347
 	pvn = (pv_cache_t*)pkg_malloc(sizeof(pv_cache_t) + name->len + 1);
348 348
 	if(pvn==0)
349 349
 	{
350
-		LM_ERR("no more memory\n");
350
+		PKG_MEM_ERROR;
351 351
 		return NULL;
352 352
 	}
353 353
 	memset(pvn, 0, sizeof(pv_cache_t) + name->len + 1);
... ...
@@ -756,7 +756,7 @@ int pv_parse_index(pv_spec_p sp, str *in)
756 756
 		nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
757 757
 		if(nsp==NULL)
758 758
 		{
759
-			LM_ERR("no more memory\n");
759
+			PKG_MEM_ERROR;
760 760
 			return -1;
761 761
 		}
762 762
 		s = pv_parse_spec(in, nsp);
... ...
@@ -1133,8 +1133,10 @@ int pv_parse_format(str *in, pv_elem_p *el)
1133 1133
 	if(in->len == 0)
1134 1134
 	{
1135 1135
 		*el = pkg_malloc(sizeof(pv_elem_t));
1136
-		if(*el == NULL)
1136
+		if(*el == NULL) {
1137
+			PKG_MEM_ERROR;
1137 1138
 			goto error;
1139
+		}
1138 1140
 		memset(*el, 0, sizeof(pv_elem_t));
1139 1141
 		(*el)->text = *in;
1140 1142
 		return 0;
... ...
@@ -1148,8 +1150,10 @@ int pv_parse_format(str *in, pv_elem_p *el)
1148 1150
 	{
1149 1151
 		e0 = e;
1150 1152
 		e = pkg_malloc(sizeof(pv_elem_t));
1151
-		if(!e)
1153
+		if(!e) {
1154
+			PKG_MEM_ERROR;
1152 1155
 			goto error;
1156
+		}
1153 1157
 		memset(e, 0, sizeof(pv_elem_t));
1154 1158
 		n++;
1155 1159
 		if(*el == NULL)
... ...
@@ -1244,7 +1248,7 @@ int pv_parse_avp_name(pv_spec_p sp, str *in)
1244 1248
 		nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
1245 1249
 		if(nsp==NULL)
1246 1250
 		{
1247
-			LM_ERR("no more memory\n");
1251
+			PKG_MEM_ERROR;
1248 1252
 			return -1;
1249 1253
 		}
1250 1254
 		s = pv_parse_spec(in, nsp);
... ...
@@ -1515,7 +1519,7 @@ pvname_list_t* parse_pvname_list(str *in, unsigned int type)
1515 1519
 		al = (pvname_list_t*)pkg_malloc(sizeof(pvname_list_t));
1516 1520
 		if(al==NULL)
1517 1521
 		{
1518
-			LM_ERR("no more memory!\n");
1522
+			PKG_MEM_ERROR;
1519 1523
 			goto error;
1520 1524
 		}
1521 1525
 		memset(al, 0, sizeof(pvname_list_t));
... ...
@@ -1646,7 +1650,7 @@ static inline trans_t* tr_new(void)
1646 1650
 	t = (trans_t*)pkg_malloc(sizeof(trans_t));
1647 1651
 	if(t == NULL)
1648 1652
 	{
1649
-		LM_ERR("no more private memory\n");
1653
+		PKG_MEM_ERROR;
1650 1654
 		return NULL;
1651 1655
 	}
1652 1656
 	memset(t, 0, sizeof(trans_t));
... ...
@@ -1875,7 +1879,7 @@ int tr_table_add(tr_export_t *e)
1875 1879
 	trn = (tr_item_t*)pkg_malloc(sizeof(tr_item_t));
1876 1880
 	if(trn==0)
1877 1881
 	{
1878
-		LM_ERR("no more memory\n");
1882
+		PKG_MEM_ERROR;
1879 1883
 		return -1;
1880 1884
 	}
1881 1885
 	memset(trn, 0, sizeof(tr_item_t));
... ...
@@ -2045,7 +2049,7 @@ int pv_init_buffer(void)
2045 2049
 		(char**)pkg_malloc(_pv_print_buffer_slots*sizeof(char*));
2046 2050
 	if(_pv_print_buffer==NULL)
2047 2051
 	{
2048
-		LM_ERR("cannot init PV print buffer slots\n");
2052
+		PKG_MEM_ERROR;
2049 2053
 		return -1;
2050 2054
 	}
2051 2055
 	memset(_pv_print_buffer, 0, _pv_print_buffer_slots*sizeof(char*));
... ...
@@ -2055,7 +2059,7 @@ int pv_init_buffer(void)
2055 2059
 			(char*)pkg_malloc(_pv_print_buffer_size*sizeof(char));
2056 2060
 		if(_pv_print_buffer[i]==NULL)
2057 2061
 		{
2058
-			LM_ERR("cannot init PV print buffer slot[%d]\n", i);
2062
+			PKG_MEM_ERROR;
2059 2063
 			return -1;
2060 2064
 		}
2061 2065
 	}
Browse code

core: pv - default number of buffer slots set to 40

- it was 10
- allow handling more chained evaluations in large strings

Daniel-Constantin Mierla authored on 07/06/2018 08:10:36
Showing 1 changed files
... ...
@@ -2025,7 +2025,7 @@ static char **_pv_print_buffer = NULL;
2025 2025
 static int _pv_print_buffer_size  = PV_DEFAULT_PRINT_BUFFER_SIZE;
2026 2026
 static int _pv_print_buffer_size_active  = 0;
2027 2027
 /* 6 mod params + 4 direct usage from mods */
2028
-#define PV_DEFAULT_PRINT_BUFFER_SLOTS 10
2028
+#define PV_DEFAULT_PRINT_BUFFER_SLOTS 40
2029 2029
 static int _pv_print_buffer_slots = PV_DEFAULT_PRINT_BUFFER_SLOTS;
2030 2030
 static int _pv_print_buffer_slots_active = 0;
2031 2031
 static int _pv_print_buffer_index = 0;
Browse code

core: pvapi - set prev variable when dropping from cache

Daniel-Constantin Mierla authored on 08/12/2017 07:57:59
Showing 1 changed files
... ...
@@ -289,6 +289,7 @@ int pv_cache_drop(void)
289 289
 				pkg_free(pvi);
290 290
 				return 1;
291 291
 			}
292
+			pvp = pvi;
292 293
 			pvi = pvi->next;
293 294
 		}
294 295
 	}
... ...
@@ -310,6 +311,7 @@ int pv_cache_drop(void)
310 311
 				pkg_free(pvi);
311 312
 				return 1;
312 313
 			}
314
+			pvp = pvi;
313 315
 			pvi = pvi->next;
314 316
 		}
315 317
 	}
Browse code

core: pv - use active values for pv buffer slots and size

- during startup, param value and active can be different, up to the
moment when the config is completely loaded

Daniel-Constantin Mierla authored on 04/12/2017 08:21:54
Showing 1 changed files
... ...
@@ -2105,7 +2105,8 @@ char* pv_get_buffer(void)
2105 2105
 	char *p;
2106 2106
 
2107 2107
 	p = _pv_print_buffer[_pv_print_buffer_index];
2108
-	_pv_print_buffer_index = (_pv_print_buffer_index+1)%_pv_print_buffer_slots;
2108
+	_pv_print_buffer_index = (_pv_print_buffer_index+1)
2109
+			% _pv_print_buffer_slots_active;
2109 2110
 
2110 2111
 	return p;
2111 2112
 }
... ...
@@ -2115,7 +2116,7 @@ char* pv_get_buffer(void)
2115 2116
  */
2116 2117
 int pv_get_buffer_size(void)
2117 2118
 {
2118
-	return _pv_print_buffer_size;
2119
+	return _pv_print_buffer_size_active;
2119 2120
 }
2120 2121
 
2121 2122
 /**
... ...
@@ -2123,7 +2124,7 @@ int pv_get_buffer_size(void)
2123 2124
  */
2124 2125
 int pv_get_buffer_slots(void)
2125 2126
 {
2126
-	return _pv_print_buffer_slots;
2127
+	return _pv_print_buffer_slots_active;
2127 2128
 }
2128 2129
 
2129 2130
 /**
Browse code

core: pv - new parameters to control the size of pv cache

- pv_cache_limit - the limit how many pv declarations in the cache
after which an action is taken. Default value is 2048
- pv_cache_action - specify what action to be done when the size
of pv cache is exceeded. If 0, print an warning log message when
the limit is exceeded. If 1, warning log messages is printed and
the cache systems tries to drop a $sht(...) declaration. Default is 0

This tries to cope better with the situation of declaring too many
variables when using kemi scripts

Daniel-Constantin Mierla authored on 21/11/2017 10:02:38
Showing 1 changed files
... ...
@@ -59,6 +59,8 @@ static int _pv_table_set = 0;
59 59
 
60 60
 static pv_cache_t* _pv_cache[PV_CACHE_SIZE];
61 61
 static int _pv_cache_set = 0;
62
+static int _pv_cache_counter = 0;
63
+static int _pv_cache_drop_index = 0;
62 64
 
63 65
 /**
64 66
  *
... ...
@@ -254,6 +256,67 @@ done:
254 256
 	return 0;
255 257
 }
256 258
 
259
+/**
260
+ *
261
+ */
262
+int pv_cache_drop(void)
263
+{
264
+	int i;
265
+	pv_cache_t *pvp;
266
+	pv_cache_t *pvi;
267
+
268
+	if(_pv_cache_set==0) {
269
+		LM_DBG("PV cache not initialized\n");
270
+		return 0;
271
+	}
272
+	/* round-robin on slots to find a $sht(...) to drop */
273
+	_pv_cache_drop_index = (_pv_cache_drop_index + 1) % PV_CACHE_SIZE;
274
+	for(i=_pv_cache_drop_index; i<PV_CACHE_SIZE; i++) {
275
+		pvi = _pv_cache[i];
276
+		pvp = NULL;
277
+		while(pvi) {
278
+			if(pvi->pvname.len>5 && strncmp(pvi->pvname.s, "$sht(", 5)==0) {
279
+				LM_DBG("dropping from pv cache [%d]: %.*s\n", i,
280
+						pvi->pvname.len, pvi->pvname.s);
281
+				if(pvp) {
282
+					pvp->next = pvi->next;
283
+				} else {
284
+					_pv_cache[i] = pvi->next;
285
+				}
286
+				if(pvi->spec.pvp.pvn.nfree) {
287
+					pvi->spec.pvp.pvn.nfree((void*)(&pvi->spec.pvp.pvn));
288
+				}
289
+				pkg_free(pvi);
290
+				return 1;
291
+			}
292
+			pvi = pvi->next;
293
+		}
294
+	}
295
+	for(i=0; i<_pv_cache_drop_index; i++) {
296
+		pvi = _pv_cache[i];
297
+		pvp = NULL;
298
+		while(pvi) {
299
+			if(pvi->pvname.len>5 && strncmp(pvi->pvname.s, "$sht(", 5)==0) {
300
+				LM_DBG("dropping from pv cache [%d]: %.*s\n", i,
301
+						pvi->pvname.len, pvi->pvname.s);
302
+				if(pvp) {
303
+					pvp->next = pvi->next;
304
+				} else {
305
+					_pv_cache[i] = pvi->next;
306
+				}
307
+				if(pvi->spec.pvp.pvn.nfree) {
308
+					pvi->spec.pvp.pvn.nfree((void*)(&pvi->spec.pvp.pvn));
309
+				}
310
+				pkg_free(pvi);
311
+				return 1;
312
+			}
313
+			pvi = pvi->next;
314
+		}
315
+	}
316
+	LM_WARN("no suitable variable found to drop from pv cache\n");
317
+	return 0;
318
+}
319
+
257 320
 /**
258 321
  *
259 322
  */
... ...
@@ -268,6 +331,16 @@ pv_spec_t* pv_cache_add(str *name)
268 331
 		LM_DBG("PV cache not initialized, doing it now\n");
269 332
 		pv_init_cache();
270 333
 	}
334
+	if(_pv_cache_counter+1>=cfg_get(core, core_cfg, pv_cache_limit)) {
335
+		if(_pv_cache_counter+1==cfg_get(core, core_cfg, pv_cache_limit)) {
336
+			LM_WARN("pv cache limit is going to be exceeded"
337
+					" - pkg memory may get filled with pv declarations\n");
338
+		} else {
339
+			if(cfg_get(core, core_cfg, pv_cache_action)==1) {
340
+				pv_cache_drop();
341
+			}
342
+		}
343
+	}
271 344
 	pvid = get_hash1_raw(name->s, name->len);
272 345
 	pvn = (pv_cache_t*)pkg_malloc(sizeof(pv_cache_t) + name->len + 1);
273 346
 	if(pvn==0)
Browse code

core: pv - increased the size for pv and transformation hash tables

Daniel-Constantin Mierla authored on 21/11/2017 09:12:07
Showing 1 changed files
... ...
@@ -40,8 +40,8 @@
40 40
 #include "pvapi.h"
41 41
 #include "pvar.h"
42 42
 
43
-#define PV_TABLE_SIZE	32  /*!< pseudo-variables table size */
44
-#define TR_TABLE_SIZE	16  /*!< transformations table size */
43
+#define PV_TABLE_SIZE	64  /*!< pseudo-variables table size */
44
+#define TR_TABLE_SIZE	32  /*!< transformations table size */
45 45
 
46 46
 
47 47
 void tr_destroy(trans_t *t);
Browse code

core: pvapi - remove useless condition

Daniel-Constantin Mierla authored on 27/07/2017 07:08:24
Showing 1 changed files
... ...
@@ -1096,8 +1096,6 @@ int pv_parse_format(str *in, pv_elem_p *el)
1096 1096
 			goto error;
1097 1097
 		p0 = p + len;
1098 1098
 
1099
-		if(p0==NULL)
1100
-			goto error;
1101 1099
 		if(*p0 == '\0')
1102 1100
 			break;
1103 1101
 		p = p0;
Browse code

core: pvapi - added free_pvname_list()

Daniel-Constantin Mierla authored on 21/07/2017 06:44:37
Showing 1 changed files
... ...
@@ -1470,6 +1470,19 @@ error:
1470 1470
 	return NULL;
1471 1471
 }
1472 1472
 
1473
+/**
1474
+ *
1475
+ */
1476
+void free_pvname_list(pvname_list_t* head)
1477
+{
1478
+	pvname_list_t* al;
1479
+
1480
+	while(head) {
1481
+		al = head;
1482
+		head=head->next;
1483
+		pkg_free(al);
1484
+	}
1485
+}
1473 1486
 
1474 1487
 
1475 1488
 /** destroy the content of pv_spec_t structure.
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,2063 @@
1
+/*
2
+ * Copyright (C) 2001-2003 FhG Fokus
3
+ *
4
+ * This file is part of Kamailio, a free SIP server.
5
+ *
6
+ * Kamailio is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version
10
+ *
11
+ * Kamailio is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
+ */
20
+
21
+/*!
22
+ * \file
23
+ * \brief Kamailio core :: PV API specification
24
+ * \ingroup core
25
+ * Module: \ref core
26
+ */
27
+
28
+
29
+#include <stdio.h>
30
+#include <string.h>
31
+#include <sys/types.h>
32
+#include <unistd.h>
33
+
34
+#include "mem/mem.h"
35
+#include "mem/shm_mem.h"
36
+#include "ut.h"
37
+#include "dprint.h"
38
+#include "hashes.h"
39
+#include "route.h"
40
+#include "pvapi.h"
41
+#include "pvar.h"
42
+
43
+#define PV_TABLE_SIZE	32  /*!< pseudo-variables table size */
44
+#define TR_TABLE_SIZE	16  /*!< transformations table size */
45
+
46
+
47
+void tr_destroy(trans_t *t);
48
+void tr_free(trans_t *t);
49
+
50
+typedef struct _pv_item
51
+{
52
+	pv_export_t pve;
53
+	unsigned int pvid;
54
+	struct _pv_item *next;
55
+} pv_item_t, *pv_item_p;
56
+
57
+static pv_item_t* _pv_table[PV_TABLE_SIZE];
58
+static int _pv_table_set = 0;
59
+
60
+static pv_cache_t* _pv_cache[PV_CACHE_SIZE];
61
+static int _pv_cache_set = 0;
62
+
63
+/**
64
+ *
65
+ */
66
+void pv_init_table(void)
67
+{
68
+	memset(_pv_table, 0, sizeof(pv_item_t*)*PV_TABLE_SIZE);
69
+	_pv_table_set = 1;
70
+}
71
+
72
+/**
73
+ *
74
+ */
75
+void pv_init_cache(void)
76
+{
77
+	memset(_pv_cache, 0, sizeof(pv_cache_t*)*PV_CACHE_SIZE);
78
+	_pv_cache_set = 1;
79
+}
80
+
81
+/**
82
+ *
83
+ */
84
+pv_cache_t **pv_cache_get_table(void)
85
+{
86
+	if(_pv_cache_set==1) return _pv_cache;
87
+	return NULL;
88
+}
89
+
90
+/**
91
+ * @brief Check if a char is valid according to the PV syntax
92
+ * @param c checked char
93
+ * @return 1 if char is valid, 0 if not valid
94
+ */
95
+static int is_pv_valid_char(char c)
96
+{
97
+	if((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z')
98
+			|| (c=='_') || (c=='.') || (c=='?') /* ser $? */)
99
+		return 1;
100
+	return 0;
101
+}
102
+
103
+/**
104
+ *
105
+ */
106
+int pv_locate_name(str *in)
107
+{
108
+	int i;
109
+	int pcount;
110
+
111
+	if(in==NULL || in->s==NULL || in->len<2)
112
+	{
113
+		LM_ERR("bad parameters\n");
114
+		return -1;
115
+	}
116
+
117
+	if(in->s[0]!=PV_MARKER)
118
+	{
119
+		LM_ERR("missing pv marker [%.*s]\n", in->len, in->s);
120
+		return -1;
121
+	}
122
+	if(in->s[1]==PV_MARKER)
123
+	{
124
+		return 2;
125
+	}
126
+	pcount = 0;
127
+	if(in->s[1]==PV_LNBRACKET)
128
+	{
129
+		/* name with parenthesis: $(...) */
130
+		pcount = 1;
131
+		for(i=2; i<in->len; i++)
132
+		{
133
+			if(in->s[i]==PV_LNBRACKET)
134
+				pcount++;
135
+			else if(in->s[i]==PV_RNBRACKET)
136
+				pcount--;
137
+			if(pcount==0)
138
+				return i+1;
139
+		}
140
+		/* non-closing name parenthesis */
141
+		LM_ERR("non-closing name parenthesis [%.*s]\n",in->len,in->s);
142
+		return -1;
143
+	}
144
+
145
+	/* name without parenthesis: $xyz(...) */
146
+	for(i=1; i<in->len; i++)
147
+	{
148
+		if(!is_pv_valid_char(in->s[i]))
149
+		{
150
+			if(in->s[i]==PV_LNBRACKET)
151
+			{
152
+				/* inner-name parenthesis */
153
+				pcount = 1;
154
+				break;
155
+			} else {
156
+				return i;
157
+			}
158
+		}
159
+	}
160
+	if(pcount==0)
161
+		return i;
162
+
163
+	i++;
164
+	for( ; i<in->len; i++)
165
+	{
166
+		if(in->s[i]==PV_LNBRACKET)
167
+			pcount++;
168
+		else if(in->s[i]==PV_RNBRACKET)
169
+			pcount--;
170
+		if(pcount==0)
171
+			return i+1;
172
+	}
173
+	/* non-closing inner-name parenthesis */
174
+	LM_ERR("non-closing inner-name parenthesis [%.*s]\n",in->len,in->s);
175
+	return -1;
176
+}
177
+
178
+/**
179
+ *
180
+ */
181
+int pv_table_add(pv_export_t *e)
182
+{
183
+	char *p;
184
+	str  *in;
185
+	pv_item_t *pvi = NULL;
186
+	pv_item_t *pvj = NULL;
187
+	pv_item_t *pvn = NULL;
188
+	int found;
189
+	unsigned int pvid;
190
+
191
+	if(e==NULL || e->name.s==NULL || e->getf==NULL || e->type==PVT_NONE)
192
+	{
193
+		LM_ERR("invalid parameters\n");
194
+		return -1;
195
+	}
196
+
197
+	if(_pv_table_set==0)
198
+	{
199
+		LM_DBG("PV table not initialized, doing it now\n");
200
+		pv_init_table();
201
+	}
202
+	in = &(e->name);
203
+	p = in->s;
204
+	while(is_in_str(p,in) && is_pv_valid_char(*p))
205
+		p++;
206
+	if(is_in_str(p,in))
207
+	{
208
+		LM_ERR("invalid char [%c] in [%.*s]\n", *p, in->len, in->s);
209
+		return -1;
210
+	}
211
+	found = 0;
212
+	//pvid = get_hash1_raw(in->s, in->len);
213
+	pvid = get_hash1_raw(in->s, in->len);
214
+
215
+	pvi = _pv_table[pvid%PV_TABLE_SIZE];
216
+	while(pvi)
217
+	{
218
+		if(pvi->pvid > pvid)
219
+			break;
220
+		if(pvi->pve.name.len==in->len)
221
+		{
222
+			found = strncmp(pvi->pve.name.s, in->s, in->len);
223
+
224
+			if(found==0)
225
+			{
226
+				LM_ERR("pvar [%.*s] already exists\n", in->len, in->s);
227
+				return -1;
228
+			}
229
+		}
230
+		pvj = pvi;
231
+		pvi = pvi->next;
232
+	}
233
+
234
+	pvn = (pv_item_t*)pkg_malloc(sizeof(pv_item_t));
235
+	if(pvn==0)
236
+	{
237
+		LM_ERR("no more memory\n");
238
+		return -1;
239
+	}
240
+	memset(pvn, 0, sizeof(pv_item_t));
241
+	memcpy(&(pvn->pve), e, sizeof(pv_export_t));
242
+	pvn->pvid = pvid;
243
+
244
+	if(pvj==0)
245
+	{
246
+		pvn->next = _pv_table[pvid%PV_TABLE_SIZE];
247
+		_pv_table[pvid%PV_TABLE_SIZE] = pvn;
248
+		goto done;
249
+	}
250
+	pvn->next = pvj->next;
251
+	pvj->next = pvn;
252
+
253
+done:
254
+	return 0;
255
+}
256
+
257
+/**
258
+ *
259
+ */
260
+pv_spec_t* pv_cache_add(str *name)
261
+{
262
+	pv_cache_t *pvn;
263
+	unsigned int pvid;
264
+	char *p;
265
+
266
+	if(_pv_cache_set==0)
267
+	{
268
+		LM_DBG("PV cache not initialized, doing it now\n");
269
+		pv_init_cache();
270
+	}
271
+	pvid = get_hash1_raw(name->s, name->len);
272
+	pvn = (pv_cache_t*)pkg_malloc(sizeof(pv_cache_t) + name->len + 1);
273
+	if(pvn==0)
274
+	{
275
+		LM_ERR("no more memory\n");
276
+		return NULL;
277
+	}
278
+	memset(pvn, 0, sizeof(pv_cache_t) + name->len + 1);
279
+	pvn->pvname.len = name->len;
280
+	pvn->pvname.s = (char*)pvn + sizeof(pv_cache_t);
281
+	memcpy(pvn->pvname.s, name->s, name->len);
282
+	p = pv_parse_spec(&pvn->pvname, &pvn->spec);
283
+
284
+	if(p==NULL)
285
+	{
286
+		pkg_free(pvn);
287
+		return NULL;
288
+	}
289
+	pvn->pvid = pvid;
290
+	pvn->next = _pv_cache[pvid%PV_CACHE_SIZE];
291
+	_pv_cache[pvid%PV_CACHE_SIZE] = pvn;
292
+
293
+	LM_DBG("pvar [%.*s] added in cache\n", name->len, name->s);
294
+	return &pvn->spec;
295
+}
296
+
297
+/**
298
+ *
299
+ */
300
+pv_spec_t* pv_cache_lookup(str *name)
301
+{
302
+	pv_cache_t *pvi;
303
+	unsigned int pvid;
304
+	int found;
305
+
306
+	if(_pv_cache_set==0)
307
+		return NULL;
308
+
309
+	pvid = get_hash1_raw(name->s, name->len);
310
+	pvi = _pv_cache[pvid%PV_CACHE_SIZE];
311
+	while(pvi)
312
+	{
313
+		if(pvi->pvid == pvid) {
314
+			if(pvi->pvname.len==name->len)
315
+			{
316
+				found = strncmp(pvi->pvname.s, name->s, name->len);
317
+
318
+				if(found==0)
319
+				{
320
+					LM_DBG("pvar [%.*s] found in cache\n",
321
+							name->len, name->s);
322
+					return &pvi->spec;
323
+				}
324
+			}
325
+		}
326
+		pvi = pvi->next;
327